## WeBWorK Problems

### writing sequential problems

by Michael Gage -
Number of replies: 4
Hi Ken,
 I'm moving this question to the forum since there is a lot of interest
in writing sequential problems
(or compound problems or multipart problems -- we don't have a firm
naming convention yet).
It is posted at
http://wwrk.maa.org/moodle/mod/forum/discuss.php?d=349
You can set your preferences for this forum so that you are emailed whenever it is updated by going to http://wwrk.maa.org/moodle/mod/forum/view.php?f=3
and then choosing "subscribe to this forum".particular Karen Clark at TCNJ (who leads the AIM-WeBWorK work group on
sequential problems)and Davide Cervone have made contributions. I think the timing
is write and several people are interested in exploring the best way(s)
to construct these problems.
 As a starting point view the wiki document at
 http://webwork.maa.org/wiki/SequentialProblems
--Mike

 On Jun 19, 2008, at 10:03 AM, Kenneth Appel wrote:
 Mike,
 I am trying to make what I used to call a sequential problem. In this
case, I want 11 answers before I check to see if the
last is correct before going on. I get a type of error that I do not
understand. There seem to be several possibility.
 perhaps A change in WeBWorK in the last few years means I should have
done something differently now than then.
-- there have been a number of changes and I expect that we can do
better than our original approaches to
writing sequential problems.
 Here it is
Ken

set6: Problem 1
 This set is visible to students.
 Error messages
Not a CODE reference at line 76 of [TMPL]/msprobs6/ldintro.pg
Error details
 Problem1
ERROR caught by Translator while processing problem
file:msprobs6/ldintro.pg
****************
Not a CODE reference at line 76 of [TMPL]/msprobs6/ldintro.pg
****************
 ------Input Read
1 #DESCRIPTION
2 #ENDDESCRIPTION
3
4 DOCUMENT();
5 loadMacros(
6 &quot;PG.pl&quot;,
7 &quot;PGbasicmacros.pl&quot;,
8 &quot;PGchoicemacros.pl&quot;,
9 &quot;PGanswermacros.pl&quot;,
10 &quot;PGgraphmacros.pl&quot;,
11 &quot;PGauxiliaryFunctions.pl&quot;,
12 );
13 TEXT(&amp;beginproblem());
14 $showPartialCorrectAnswers = 1; 15$ans2=2*13;
16 $ans3=3*13;  17$ans4=4*13;
18 $ans5=5*13;  19$ans6=6*13;
20 $ans7=7*13;  21$ans8=8*13;
22 $ans9=9*13; 23$ans10=52;
24 $ans11=4; 25 BEGIN_TEXT 26$PAR
27 Long division may look complicated because a number of ideas are
combined to
28 make the work efficient. We will start by doing extra steps so that
it will
29 be easier to see what is happening.
30 $PAR 31 We will divide the number 6257 by 13. Remember that our answer will be a quotient and a remainder. The quotient will be the largest number of 13's in 6257. The remainder will be what remains after subtracting as many 13's as we can from 6257. 32$PAR
33 What we do is to find our quotient one digit at a time. This time we
will make a
34 $$help\ list$$ but after a bit of practice you will probably decide
that you don't need one. Our help list will consist of the multiples of
13 up to $$9\times 13$$
35 $PAR 36 Help List 37$BR
38 $$2\times 13=$$\{ans_rule(2)\}
39 $BR 40 $$3\times 13=$$\{ans_rule(2)\} 41$BR
42 $$4\times 13=$$\{ans_rule(2)\}
43 $BR 44 $$5\times 13=$$\{ans_rule(2)\} 45$BR
46 $$6\times 13=$$\{ans_rule(2)\}
47 $BR 48 $$7\times 13=$$\{ans_rule(2)\} 49$BR
50 $$8\times 13=$$\{ans_rule(2)\}
51 $BR 52 $$9\times 13=$$\{ans_rule(2)\} 53$PAR
54 Now that we have our help list, we look at the number 6257. The first
two digits are 62 and it has 2 more digits. So we find number in our
help list
 55 that is the largest number that is not more than 62. That number is
\\{ans_rule(2)\} which is \{ans_rule(1)\}$$\times 13$$. Since there are
2 digits to the right of 62 in the number 6257 this means that
\{ans_rule(2)\}$$00$$ which is \{ans_rule(2)\}$$00\times 13$$ is the
largest multiple of 13 that ends with 00.
 56
57
58
59 $BR$BR \{NAMED_ANS_RULE('first_answer',10) \}
60 END_TEXT
61 &amp;ANS(str_cmp($ans2)); 62 &amp;ANS(str_cmp($ans3));
63 &amp;ANS(str_cmp($ans4)); 64 &amp;ANS(str_cmp($ans5));
 65 &amp;ANS(str_cmp($ans6)); 66 &amp;ANS(str_cmp($ans7));
67 &amp;ANS(str_cmp($ans8)); 68 &amp;ANS(str_cmp($ans9));
69
70 &amp;ANS(str_cmp($ans10)); 71  72$ans_eval1 = str_cmp($ans11); 73 NAMED_ANS(first_answer =&gt;$ans_eval1);
 74 $first_Answer =$inputs_ref-&gt;{first_answer};
75
76 $rh_ans_hash1 = &amp;$ans_eval1($first_Answer); 77 #because it is text it is handled differently 78  79 # Using named answers allows for more control. Any unique label can be   80 # used for an answer.  81 # (see http://cartan.math.rochester.edu/WeBWorKdiscussion/discuss/msgReader$13
82 # for more details on answer evaluator formats and on naming answers
83 # so that you can refer to them later. Look also at the pod
documentation in
 84 # PG.pl and PGbasicmacros.pl which you can also reach at
85 #
http://webwork.math.rochester.edu/docs/techdescription/pglanguage/index.
html)
86
87 # Check to see that the first answer was answered correctly. If it
was then we
 88 # will ask further questions.
89 # We need to know what the answer was named.
90
91 #$rh_ans_hash1 =$ans_eval1-&gt;evaluate($first_Answer); 92  93 # warn pretty_print($rh_ans_hash); # this is useful error technique
 94
95 # The output of each answer evaluator consists of a single %ans_hash
with (at
96 # least) these entries:
97 # $ans_hash{score} -- a number between 0 and 1  98 #$ans_hash{correct_ans} -- The correct answer, as supplied by the
instructor
 99 # $ans_hash{student_ans} -- This is the student's answer  100 #$ans_hash{ans_message} -- Any error message, or hint provided by
101 # the answer evaluator.
102 # $ans_hash{type} -- A string indicating the type of answer evaluator.   103 # -- Some examples:  104 # 'number_with_units'  105 # 'function'  106 # 'frac_number'  107 # 'arith_number'  108 # For more details see   109 # http://cartan.math.rochester.edu/WeBWorKdiscussion/discuss/msgReader$15
110
111 # If they get the first answer right, then we'll ask a second part
to the
112 # question ...
113
114 if (1 == $rh_ans_hash1-&gt;{score} ) {  115  116 # WATCH OUT!!: BEGIN_TEXT and END_TEXT have to be on lines by  117 # themselves and left justified!!! This means you can't indent  118 # this section as you might want to. The placement of BEGIN_TEXT  119 # and END_TEXT is one of the very few formatting requirements in 120 # the PG language. 121  122 BEGIN_TEXT  123$PAR
124 We got here.
125 END_TEXT
126 }
127 END_DOCUMENT

### Re: writing sequential problems

by Michael Gage -
This won't be perfect, but the code below gives you a framework for
writing sequentialProblems. You will need to do to obtain file
"compoundProblem.pl",

and related files from the link on http://webwork.maa.org/wiki/SequentialProblems

Or you can type
cvs update
in the pg/macros directory

Reading the top of that file will give you instructions
on modifications that are possible with this
version of sequential problems.

One of the "features" is that once you have completed one
We'd like to modify that behavior but it may not happen right away.

##DESCRIPTION
## Algebra problem: true or false for inequality
##ENDDESCRIPTION

##KEYWORDS('algebra', 'inequality', 'fraction')

## DBsubject('Algebra')
## DBchapter('Fundamentals')
## DBsection('Real Numbers')
## Date('6/3/2002')
## Author('')
## Institution('')
## TitleText1('Precalculus')
## EditionText1('3')
## AuthorText1('Stewart, Redlin, Watson')
## Section1('1.1')
## Problem1('22')

########################################################################

DOCUMENT();

"PGstandard.pl", # Standard macros for PG language
"MathObjects.pl",
"compoundProblem.pl",
"unionLists.pl",
#"source.pl", # allows code to be displayed on certain sites.
#"PGcourse.pl", # Customization file for the course
);

# Print problem number and point value (weight) for the problem
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1; ##############################################$isProfessor = ($studentLogin eq 'dpvc' ||$studentLogin eq 'professor');

#
# Start a compound problem. See the compoundProblem.pl
# file for more details about the parameters you
# can supply.
#
$cp = new compoundProblem( parts => 3, # the total number of parts in this problem totalAnswers => 4, # total answers in all parts combined parserValues => 1, # make parser objects from student answers allowReset =>$isProfessor, # professors get Reset button for testing
);
$part =$cp->part; # look up the current part

##############################################
#
# Part 1
#

if ($part == 1) { ############################################## ############################################################## # # Setup # # Context("Numeric"); Context()->flags->set(reduceConstants=>0);$ans[2] = Formula("2*13");
$ans[3] = Formula("3*13");$ans[4] = Formula("4*13");
$ans[5] = Formula("5*13");$ans[6] = Formula("6*13");
$ans[7] = Formula("7*13");$ans[8] = Formula("8*13");
$ans[9] = Formula("9*13");$ans[10] = Formula("52");
$ans[11] = Formula("4"); ############################################################## # # Text # # Context()->texStrings; BEGIN_TEXT$PAR
Long division may look complicated because a number of ideas are combined to
make the work efficient. We will start by doing extra steps so that it will
be easier to see what is happening.
$PAR We will divide the number 6257 by 13. Remember that our answer will be a quotient and a remainder. The quotient will be the largest number of 13's in 6257. The remainder will be what remains after subtracting as many 13's as we can from 6257.$PAR
Help List
\{ BeginList("OL")\}
END_TEXT

foreach $j (2..11) { TEXT(EV3(q!$ITEM \$$ans[j] = \$$ \\{ ans_rule(20)\\} ! ));
}

BEGIN_TEXT

\{ EndList("OL") \}
$PAR Now that we have our help list, we look at the number 6257. The first two digits are 62 and it has 2 more digits. So we find number in our help list that is the largest number that is not more than 62. That number is \{ans_rule(2)\} which is \{ans_rule(1)\}$$\times 13$$. Since there are 2 digits to t he right of 62 in the number 6257 this means that \{ans_rule(2)\}$$00$$ which is \{ans_rule(2)\}$$00\times 13$$ is the largest multiple of 13 that ends with 00. END_TEXT Context()->normalStrings; #$BR $BR \{NAMED_ANS_RULE('first_answer',10) \} ############################################################## # # Answers # # Context("LimitedNumeric"); foreach$j (2..11) {
# convert to an object that requires an integer answer
ANS(Real($ans[$j])->cmp);
}
ANS(Real(52)->cmp,Real(4)->cmp,Real(4)->cmp,Real(52)->cmp);

} # End of Part 1

##############################################
#
# Part 2
#

if ($part == 2) {$a = 3;
$b = 4; BEGIN_TEXT Part 2:$PAR
$$a + b$$ = \{ans_rule(10)\}
END_TEXT
$c =$a+$b; ANS(num_cmp($c,mode=>"strict"));

}

##############################################
#
# Part 3
#

if ($part == 3) {$f = Formula("$a x +$b")->reduce;

BEGIN_TEXT
Part: 3:
$PAR Suppose $$f(x) = \{f->TeX\}$$.$BR
Then $$f(2)$$ = \{ans_rule(10)\}.
END_TEXT

ANS($f->eval(x=>2)->cmp); } ############################################## ENDDOCUMENT();  In reply to Michael Gage ### Re: writing sequential problems by Michael Gage - Difficulty 1 is that I do not know how to reset the problem. I am getting around this temporarily by creating a student named tester who is working the problem for the first time. This is a known problem of the current implementation. For the professor you can fix it by changing these lines in the question: ############################################## $isProfessor = ($studentLogin eq 'dpvc' ||$studentLogin eq 'professor');
#
# Start a compound problem. See the compoundProblem.pl
# file for more details about the parameters you
# can supply.
#
$cp = new compoundProblem(  parts => 3, # the total number of parts in this problem  totalAnswers => 4, # total answers in all parts combined  parserValues => 1, # make parser objects from student answers  allowReset =>$isProfessor, # professors get Reset button for testing
);

Changing
allowReset => 1

will give everyone a reset button -- this might be the best compromise for now. Further work needs to be done to determine exactly how one wants a sequential problem to behave.

Should the student be able to see earlier work? to change it? What is the desired behavior?

You can also change the line above:

isProfessor = ($studentLogin eq 'dpvc' ||$studentLogin eq 'professor');

### Re: writing sequential problems

by Darwyn Cook -
Mike,
The link to Bob Byerly's problems in the wiki are not working for me.