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").
Creating exercises with answers dependent on previous answers
by Bruce Yoshiwara - Number of replies: 2
In reply to Bruce Yoshiwara
Re: Creating exercises with answers dependent on previous answers
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();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.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;
#########################
# Answer evaluation
$showPartialCorrectAnswers = 1;
ANS( $multians->cmp() );
ENDDOCUMENT();
##### end PG code ########
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();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.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;
#########################
# Answer evaluation
$showPartialCorrectAnswers = 1;
ANS( $multians->cmp() );
ENDDOCUMENT();
##### end PG code ########
In reply to Paul Pearson
Re: Creating exercises with answers dependent on previous answers
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(
allowBlankAnswers => 1,
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.");
next ANSWER;
}
}
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);
}
}
return @score;
}
);
It seems to work.
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(
allowBlankAnswers => 1,
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.");
next ANSWER;
}
}
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);
}
}
return @score;
}
);
It seems to work.