unreduced fractions. I suspect that there is
none since this is something that seems only important at the k-12 level.
I think that I would need to start with strict
fraction and then use a gcd subroutine (which I
already have functioning). What I do not know
is how to
1. See if the answer given is a fraction
2. grab that fraction to check to see if it is
reduced.
Ken
Here's a code snippet that used the LimitedNumeric-StructFraction context to force fraction input, and then uses answerHints as a filter to check if the fraction is reduced.
loadMacros("answerHints.pl"); Context("LimitedNumeric-StrictFraction"); ANS(Real("1/2")->cmp->withPostFilter(AnswerHints( sub { my ($correct, $student, $ans) = @_; return 0 if $ans->{isPreview}; my $node = $student->{equation}{tree}; return 0 unless $node->class eq 'DIVIDE'; my ($a,$b) = (abs($node->{lop}->eval),abs($node->{rop}->eval)); my ($ra,$rb) = reduce($a,$b); return $a != $ra || $b != $rb; } => ["Your answer isn't reduced", checkCorrect => 1, score => 0] )));
This answerHint uses a checking subroutine that is called even when the answer is correct (checkCorrect => 1). It does not issue its message if the Preview button was pressed. Otherwise, it looks up the top node of the parsed equation and checks if it is a DIVIDE node. If not, it returns without issuing its message.
If the answer is a division, it looks up the (absolute value of) the numerator and denominator, and reduces them to lowest terms (the reduce() routine is in PGauxiliaryFunction.pl), and checks to see that the student's answer is the same as the reduced one. If not, the message is issued and the score is set to zero in that case (due to score => 0).
Of course, one could package up this AnswerHint() call as a value in a macro file, say filterReducedFaction.pl, containing
loadMacros("answerHints.pl"); @reducedFraction = AnswerHints( sub { my ($correct, $student, $ans) = @_; return 0 if $ans->{isPreview}; my $node = $student->{equation}{tree}; return 0 unless $node->class eq 'DIVIDE'; my ($a,$b) = (abs($node->{lop}->eval),abs($node->{rop}->eval)); my ($ra,$rb) = reduce($a,$b); return $a != $ra || $b != $rb; } => ["Your answer isn't reduced", checkCorrect => 1, score => 0] );and then use
loadMacros("filterReducedFraction.pl"); Context("LimitedNUmeric-StrictFraction"); ANS(Real("1/2")->cmp->withPostFilter(@reducedFraction))instead.
That should do what you ask, I think.
Davide
Thank you very much.
I do not seem to have contextLimitedNumeric-StrictFraction (although I clearly do have contextLimitedNumeric). Where should I get it?
Ken
The upshot is, you should just be able to use Context("LimitedNumeric-StrictFraction") without loading any special macro files.
Davide
It took a couple of days to work it out, but I think it should do what you need. Let me know if you find anything wrong with it; as with any new piece of complicated code, it is easy to overlook something, so there may be errors.
Davide