$f1*$f2stu == $f1stu*$f2in the checker for your MultiAnswer object. Note that the correct and student answers are in the LimitedPolynomial context, and so if
$f1
is -8x^6
and $f2stu
is x^2
, then the product is (-8x^6)*(x^2)
, which is not valid in this context, and the error is reported. Similarly for when $f2tu
is -4
.
The solution is to perform those computations in a different context (where they are valid). One way is to set the context and recompute the products, as in
Context("Numeric"); if (Compute("$f1*$f2stu") == Compute("$f1stu*$f2")) { ... }This forces the product to be represented first as a string and then that string is recomputed in the current context (which is now Numeric rather than LimitedPolynomial).
There are a couple of other changed that I would suggest, as well. First, you might want to use the LimitedPolynomial-Strict context rather than just LimitedPolynomial, so that you can't enter things like -4*2*x^6
in place of -8x^6
. If you do that, however, you will need to be more careful about the initial formula for the numerator and denominator, since they no longer can include computations. So something like
$num = Formula((-1*$a*$c)."*x^".($d-$b)); $den = Formula("1");where you do the computations outside the string, would work.
Second, I like that you are using a single result for this, but it is possible to format the student answer more naturally by showing it as a fraction. One way would be to use
format => "(%s)/(%s)", tex_format => "\frac{%s}{%s}",in your MultiAnswer object to get the student's answer shown as a fraction. This is better, and works well for the TeX version, but it means the text version may have extra parentheses, as in
(-8x^6)/(1)
. That is not wrong, but you might want to use
$self->{format} = Compute("$f1stu/$f2stu")->string;within the checker (after setting
Context("Numeric")
first) in order to get a better text output.
Third, you can improve the correct answer output in a similar way. Unfortunately, the MultiAnswer object doesn't use the format
option to set the correct answer (a bug that should be fixed), and because the MultiAnswer object was written before the correct answer was available in TeX form, it doesn't set the value for that, so a little more work needs to be done to make that work. In this case, you need to use
my ( $correct, $student, $self, $ansHash ) = @_;in order to get the AnswerHash as well as the other data, and then use
Context("Numeric"); $correct = Compute("$f1/$f2"); $ansHash->{correct_ans} = $correct->string; $ansHash->{correct_ans_latex_string} = $correct->TeX;to set the correct answer string and LaTeX values. Note, however, that if the student presses the submit button when one or both answers are blank, the checker won't run, and so these values won't be set, and the correct answer will not show the fraction. To resolve that, you can use
allowBlankAnswers => 1,so that your checker will run even for blank answers, and then use
return [0,0] if $f1stu eq "" || $f2stu eq "";after setting the correct answers (and before setting the
format
) to handle the blank answers.
The only remaining time that you won't get fractions is if the student has a syntax error in their answer (and so your checker won't run). But since this is unlikely to occur when the correct answers are being shown, I wouldn't worry about it.
Finally, your error message for simplification can be improved by not setting messages for the individual entry blanks, but using a single error message for the pair, as in the code below.
Here is the pertinent code with all the changes above:
Context("LimitedPolynomial-Strict")->variables->are(x=>"Real"); ... $num = Formula((-1*$a*$c)."*x^".($d-$b)); $den = Formula("1"); $multians = MultiAnswer($num, $den)->with( singleResult => 1, allowBlankAnswers => 1, format => "(%s)/(%s)", tex_format => "\frac{%s}{%s}", checker => sub { my ( $correct, $student, $self, $ansHash ) = @_; my ( $f1stu, $f2stu ) = @{$student}; my ( $f1, $f2 ) = @{$correct}; Context("Numeric"); $correct = Compute("$f1/$f2"); $ansHash->{correct_ans} = $correct->string; $ansHash->{correct_ans_latex_string} = $correct->TeX; return [0,0] if $f1stu eq "" || $f2stu eq ""; $self->{format} = Compute("$f1stu/$f2stu")->string; if ( ( $f1==$f1stu && $f2==$f2stu) || (-$f1==$f1stu && -$f2==$f2stu) ) { return [1,1]; } elsif ( $f1==$f1stu || -$f1==$f1stu) { return [1,0]; } elsif ( $f2==$f2stu || -$f2==$f2stu ) { return [0,1]; } elsif (Compute("$f1*$f2stu") == Compute("$f1stu*$f2")) { $self->context->setError("Your answer should be further simplified"); return; # don't return values here (so message will show) } else { return [0,0]; } } );The rest of the problem is not modified.
Hope that helps.
Davide