I thought about switching to the unorderedAnswers.pl helper functions but I didn't know how to group the pairs of solutions togethers.
I've also included the code we've been using below.
Thank you!
Patrick Spencer
University of Missouri
DOCUMENT();
loadMacros(
"AnswerFormatHelp.pl",
"MathObjects.pl",
"PeriodicRerandomization.pl",
"PGgraphmacros.pl",
"PGstandard.pl",
"parserMultiAnswer.pl",
"parserPopUp.pl",
);
TEXT(beginproblem());
PeriodicRerandomization("3");
$refreshCachedImages = 1;
$showPartialCorrectAnswers = 1;
#################################################################
# setup contexts and variables
#################################################################
Context("Numeric");
Context()->strings->add("even"=>{}, "e"=>{alias=>"even"},
"odd"=>{}, "o"=>{alias=>"odd"},
"positive"=>{}, "pos"=>{alias=>"positive"}, "p"=>{alias=>"positive"},
"negative"=>{}, "neg"=>{alias=>"negative"}, "n"=>{alias=>"negative"});
Context()->{error}{msg}{"Operands of '*' can't be words"} = " ";
#Context()->{error}{msg}{"Can't convert an Empty Value to a Real Number"} = " ";
$numzeros = random(2,5);
do {
# posszeros = possible zeros?
@posszeros = (-10..10);
# zeros = actual zeros?
@zeros = (1..$numzeros);
for ($i = 0; $i < $numzeros; $i++) {
$zeros[$i] = list_random(@posszeros);
if ($numzeros == 2 || $numzeros == 3) {
$powers[$i] = random(2,3);
} else {
$powers[$i] = random(1,2);
}
$removed = 0;
$count = 0;
do {
if ($posszeros[$count] == $zeros[$i]) {
$tmp = $posszeros[$count];
$posszeros[$count] = $posszeros[scalar(@posszeros)-1];
$posszeros[scalar(@posszeros)-1] = $tmp;
pop(@posszeros);
$removed = 1;
}
$count++;
} until ($removed || $count == scalar(@posszeros));
$removed = 0;
$count = 0;
do {
if ($posszeros[$count] == $zeros[$i]-1) {
$tmp = $posszeros[$count];
$posszeros[$count] = $posszeros[scalar(@posszeros)-1];
$posszeros[scalar(@posszeros)-1] = $tmp;
pop(@posszeros);
$removed = 1;
}
$count++;
} until ($removed || $count == scalar(@posszeros));
$removed = 0;
$count = 0;
do {
if ($posszeros[$count] == $zeros[$i]+1) {
$tmp = $posszeros[$count];
$posszeros[$count] = $posszeros[scalar(@posszeros)-1];
$posszeros[scalar(@posszeros)-1] = $tmp;
pop(@posszeros);
$removed = 1;
}
$count++;
} until ($removed || $count == scalar(@posszeros));
}
$yint = 1;
for ($i = 0; $i < $numzeros; $i++) {
$yint = $yint*((-$zeros[$i])**$powers[$i]);
}
# this sub routine represents what is to be the graphed polynomial
sub poly {
my $x = shift();
$prod = 1;
for ($i = 0; $i < $numzeros; $i++) {
$prod = $prod*(($x - $zeros[$i])**$powers[$i]);
}
return $prod;
};
# sort zeros from low to high;
$swapped = 1;
$count = 0;
while ($swapped) {
$swapped = 0;
$count++;
for ($i = 0; $i < $numzeros - $count; $i++) {
if ($zeros[$i] > $zeros[$i+1]) {
$tmp = $zeros[$i];
$zeros[$i] = $zeros[$i+1];
$zeros[$i+1] = $tmp;
$swapped = 1;
}
}
}
# this next bit is to be sure that the gap between the low or high point
# between zeros and the x-axis is not too small
for ($i = 0; $i < $numzeros-1; $i++) {
$maxs[$i] = 0;
}
for ($j = 0; $j < $numzeros-1; $j++) {
$steps = 100;
$stepsize = ($zeros[$j+1] - $zeros[$j])/$steps;
for ($k = 0; $k < $steps; $k++) {
$tmp = abs(poly($zeros[$j]+$k*$stepsize));
if ($tmp > $maxs[$j]) {
$maxs[$j] = $tmp;
}
}
}
$min = min(@maxs);
$max = max(@maxs);
$scale = random(5,9);
$a = random(-1,1,2)*$scale/max($max);
$tmp1 = abs($min*$a);
$tmp2 = abs($max*$a);
} until (abs($tmp2/$tmp1) < 3*$scale/2);
$expn = sub {
my $x = shift();
$prod = $a;
for ($i = 0; $i < $numzeros; $i++) {
$prod = $prod*(($x - $zeros[$i])**$powers[$i]);
}
return $prod;
};
$minx = min($zeros[0],0)-3;
$miny = -10;
$maxx = max($zeros[$numzeros-1],0)+3;
$maxy = 10;
$gsize = 400;
$graph = init_graph($minx, $miny, $maxx, $maxy, size=>[$gsize,$gsize]);
for ($i = $minx; $i <= $maxx; $i++) {
$graph->moveTo($i,$miny);
$graph->lineTo($i,$maxy,'gray',1);
}
for ($i = $miny; $i <= $maxy; $i++) {
$graph->moveTo($minx,$i);
$graph->lineTo($maxx,$i,'gray',1);
}
$graph->moveTo($minx, 0);
$graph->arrowTo($maxx, 0, 'black', 2);
$graph->arrowTo($minx, 0, 'black', 2);
$graph->moveTo(0, $miny);
$graph->arrowTo(0, $maxy, 'black', 2);
$graph->arrowTo(0, $miny, 'black', 2);
$graph->lb(new Label($maxx-0.1, 0.4, 'x', 'black', 'bottom', 'right'));
$graph->lb(new Label(0.4, $maxy-0.1, 'y', 'black', 'top', 'left'));
for ($i = $minx+1; $i < $maxx; $i++) {
if ($i != 0 && $i % 5 == 0 || $i == 1) {
$graph->lb(new Label($i,-0.1,$i, 'black', 'top','center'));
}
}
for ($i = $miny+1; $i < $maxy; $i++) {
if ($i != 0 && $i % 5 == 0 || $i == 1) {
$graph->lb(new Label(-0.1,$i,$i, 'black', 'middle', 'right'));
}
}
for ($i = 0; $i < $numzeros; $i++) {
$graph->stamps(closed_circle($zeros[$i],0,'blue'));
}
$fun = new Fun($expn, $graph);
$fun->steps(1500);
$fun->domain($minx,$maxx);
$zerosans = List(@zeros);
for ($i = 0; $i < $numzeros; $i++) {
if ($powers[$i] % 2 == 0) {
$mltpy[$i] = "even";
} else {
$mltpy[$i] = "odd";
}
}
for ($i = 0; $i < $numzeros; $i++) {
$answers[2*$i] = $zeros[$i];
$answers[2*$i+1] = $mltpy[$i]
}
$ma = MultiAnswer(@answers)->with(
singleResult => 0,
allowBlankAnswers => 1,
checker => sub {
$num = scalar(@answers);
my ($correct, $student, $self) = @_;
my @ac = @{$correct};
my @st = @{$student};
my @ans = (0..scalar(@ac)/2);
for ($i = 0; $i < $num; $i++) {
$returnans[$i] = 0;
}
for ($i = 0; $i < $num/2; $i++) {
$hasbeenused[$i] = 0;
}
for ($i = 0; $i < scalar(@ac)/2; $i++) {
$ans[$i] = [$ac[2*$i],$ac[2*$i+1]];
}
for ($i = 0; $i < scalar(@ac)/2; $i++) {
for ($j = 0; $j < scalar(@ac)/2; $j++) {
if ($ans[$i][0] == $st[2*$j] && $ans[$i][1] == $st[2*$j+1] && $hasbeenused[$i] != 1) {
$returnans[0][2*$j] = 1;
$returnans[0][2*$j+1] = 1;
$hasbeenused[$i] = 1;
}
}
}
for ($i = 0; $i < $num; $i++) {
$reans[0][$i] = $returnans[0][$i];
}
return @reans;
}
);
$degree = $powers[0];
for ($i = 1; $i < $numzeros; $i++) {
$degree = $degree + $powers[$i];
}
if ($degree % 2 == 0) {
$degreeans = "even";
} else {
$degreeans = "odd";
}
if ($a < 0) {
$leadcoeffans = "negative";
} else {
$leadcoeffans = "positive";
}
$dispzeros = "$zeros[0]";
$dispmults = "$mltpy[0]";
for ($i = 1; $i < $numzeros; $i++) {
$dispzeros = ($dispzeros).", ".($zeros[$i]);
$dispmults = ($dispmults).", ".($mltpy[$i]);
}
$degree = PopUp([" ","even", "odd"], "$degreeans");
$lead_coef_sgn = PopUp([" ","positive", "negative"], "$leadcoeffans");
#################################################################
# state the problem
#################################################################
Context()->texStrings;
BEGIN_TEXT
$PAR
$BCENTER
\{ image(insertGraph($graph), width=>$gsize, height=>$gsize, tex_size=>300 ); \}
$ECENTER
$PAR
Find the following information pertaining to the polynomial, \(f(x)\), graphed above.
$PAR
(a) The zeros of \(f(x)\) are \(x = \) \{ans_rule(15)\} (separate by commas) and
END_TEXT
for ($i = 0; $i < $numzeros; $i++) {
if ($i == $numzeros-2) {
BEGIN_TEXT
$PAR
$SPACE $SPACE $SPACE $SPACE the zero \(x = \) \{$ma->ans_rule(5)\} has \{$ma->ans_rule(5)\} multiplicity and,
$PAR
END_TEXT
} elsif ($i == $numzeros-1) {
BEGIN_TEXT
$PAR
$SPACE $SPACE $SPACE $SPACE the zero \(x = \) \{$ma->ans_rule(5)\} has \{$ma->ans_rule(5)\} multiplicity.
$PAR
END_TEXT
} else {
BEGIN_TEXT
$PAR
$SPACE $SPACE $SPACE $SPACE the zero \(x = \) \{$ma->ans_rule(5)\} has \{$ma->ans_rule(5)\} multiplicity,
$PAR
END_TEXT
}
}
BEGIN_TEXT
$PAR
(b) The degree of \(f(x)\) is \{$degree->menu()\}.
$PAR
(c) The leading coefficient of \(f(x)\) is \{$lead_coef_sgn->menu()\}.
END_TEXT
#################################################################
# check the answer
#################################################################
ANS(Compute($zerosans)->cmp());
ANS($ma->cmp());
ANS($degree->cmp());
ANS($lead_coef_sgn->cmp());
#################################################################
# use PeriodicRerandomization to write the answer and generate a new
# version of the problem
#################################################################
if ($attempts_modp == 0 && $actualAttempts != 0) {
BEGIN_TEXT
$PAR
${BBOLD}Answer:${EBOLD}
$PAR
(a) The zeros are \(x = $dispzeros\) with $dispmults multiplicity, respectively.
$PAR
(b) The degree is $degreeans.
$PAR
(c) The leading coefficient is $leadcoeffans.
$PAR
END_TEXT
} else {
BEGIN_TEXT
$PAR
${BBOLD}Help:${EBOLD} Type ${BBOLD}even${EBOLD} or ${BBOLD}odd${EBOLD} for multiplicities and the degree. Type ${BBOLD}pos${EBOLD} for positive or ${BBOLD}neg${EBOLD} for negative for the leading coefficient. You must have the corresponding multiplicity correct for each zero in order to receive credit!
$BR
END_TEXT
}
Context()->normalStrings;
PeriodicStatus();
ENDDOCUMENT();