## WeBWorK Problems

by Bruce Yoshiwara -
Number of replies: 2
I know the parserMultiAnswer will allow me to create exercises in which students need to fill in a table with appropriate ordered pairs.

I'd like to write exercises that ask students to fill in a two-column table of values based on data not given in tabular form. I prefer not to use a one-column table with ordered pairs as entries.

How do I create a two-column table in which the order of the rows does not affect correctness, and for which students are only inputting a subset of all the possible correct answers?

More generally, how can I create exercises in which the student's answer to part (a) determines the correct responses for the student's answer to part (b) and/or part (c)?

Part (a) might be a number ("Choose a number between 1 and 10"), a point ("Choose any point in the second quadrant"), or a function ("Give an example of a linear function").

by Paul Pearson -
Hi Bruce,

I'm not totally clear on what you want, but I think you should be able to modify the code below to get what you want. You may also want to look into two of the ways to write MultiPart questions at

http://webwork.maa.org/wiki/ProvingTrigIdentities1

http://webwork.maa.org/wiki/ProvingTrigIdentities2
http://webwork.maa.org/viewvc/system/trunk/pg/macros/compoundProblem.pl?revision=6387&view=markup

Best Regards,

Paul

##### begin PG code ########

##################
# Initialization

DOCUMENT();

"PGstandard.pl",
"MathObjects.pl",
"unionTables.pl",
);

TEXT(beginproblem());

##################
# Setup

Context("Numeric");

$a = 2;$b = 4;
$c = 3;$d = 9;

$multians = MultiAnswer($a,$b,$c,$d)->with( singleResult => 0, allowBlankAnswers => 1, checker => sub { my ($correct, $student,$self ) = @_;
my ( $stu11,$stu12, $stu21,$stu22 ) = @{$student}; my ($cor11, $cor12,$cor21, $cor22 ) = @{$correct};

if ( (($cor11==$stu11 && $cor12==$stu12) && ($cor21==$stu21 && $cor22==$stu22)) ||
(($cor21==$stu11 && $cor22==$stu12) && ($cor11==$stu21 && $cor12==$stu22)) )
{
return [1,1,1,1];

} elsif ( (($cor11==$stu11 && $cor12==$stu12) || ($cor21==$stu11 && $cor22==$stu12)) ) {

$self->setMessage(3,"Your second answer is incorrect because..."); return [1,1,0,0]; } elsif ( (($cor11==$stu21 &&$cor12==$stu22) || ($cor21==$stu21 &&$cor22==$stu22)) ) {$self->setMessage(1,"Your first answer is incorrect because...");
return [0,0,1,1];

} else {
return [0,0,0,0];
}
}
);

#########################
# Main text

Context()->texStrings;
BEGIN_TEXT
Enter the points on the parabola $$y = x^2$$
with x-coordinates 2 and 3.
\{
BeginTable().
AlignedRow(["$$\big($$", $multians->ans_rule(10), ",",$multians->ans_rule(10), "$$\big)$$"], separation=>2).
TableSpace(5,25).
AlignedRow(["$$\big($$", $multians->ans_rule(10), ",",$multians->ans_rule(10), "$$\big)$$"], separation=>2).
EndTable();
\}
END_TEXT
Context()->normalStrings;

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

$showPartialCorrectAnswers = 1; ANS($multians->cmp() );

ENDDOCUMENT();

##### end PG code ########

by Bruce Yoshiwara -
Thanks Paul.

I modified your suggestion (and an earlier one from Davide Cervone) to accommodate relatively large tables. So after defining a function $f and the desired number of sets of x and y values that lie on the graph,$ma = MultiAnswer("$ans[0]","$ans[1]",
"$ans[2]","$ans[3]", "$ans[4]","$ans[5]",
"$ans[6]","$ans[7]")->with(
checker => sub {
my ($correct,$student,$ans) = @_; my @score = (0) x scalar(@$correct);
$pairs = scalar(@$correct)/2-1;
ANSWER: foreach my $i (0..$pairs) {
if ($student->[2*$i] ne "" && $student->[2*$i+1] ne "") {
foreach my $j (0..$i-1) {
if ($student->[2*$j] ne "" && $student->[2*$i] == $student->[2*$j]
&& $student->[2*$j+1] ne "" && $student->[2*$i+1] == $student->[2*$j+1])
{
$ma->setMessage(2*$i+1,"This is the same as your ".
$ma->NameForNumber(2*$j+1)." solution.");
my ($x,$y) = ($student->[2*$i]->value, $student->[2*$i+1]->value);
$score[2*$i] = ($f->eval(x=>$x) == $y);$score[2*$i+1] = ($f->eval(x=>$x) ==$y);