## WeBWorK Problems

### Re: Checking submitted answers into a formula

by Davide Cervone -
Number of replies: 0
Robin is right, the MultiAnswer object is what you want, here. I don't really care for the example from the wiki, however, as the use of ref is not really he right way to do the type checking.

Here is my example of the problem that you requested (where three points are required):

    DOCUMENT();

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

Context("Point");
Parser::BOP::equality->Allow;     # Allow equalities in formulas

$f = Compute("x^2 + y^2 = 1"); # The equation the students must match # # The is the MultiAnswer object, with three correct points # (only used for showing the correct answer). It allows # blank answers, so students can add one point at a # time, and it checks that no two points are equal. #$ma = MultiAnswer("(1,0)","(0,1)","(-1,0)")->with(
function => $f, allowBlankAnswers => 1, checker => sub { my ($correct,$student,$self) = @_;
my @student = @$student; # The array of student answers my$n = scalar(@student);   # How many are in the array
my @correct = (0) x $n; # An array of that many zeros (assume none correct) foreach my$i (0..$n-1) { # Loop through the student answers next unless$student[$i]->classMatch("Point"); # Go on if the answer is blank my ($x,$y) =$student[$i]->value; # Get the x and y coordinates if ($self->{function}->eval(x=>$x,y=>$y)) {     # If the equation is satisfied (1 if equal, 0 if not)
$correct[$i] = 1;                             # Indicate answer is correct
foreach my $j (0..$i-1) {                     # Look through previous points
if ($student[$j] == $student[$i]) {         # If this point equals a previous one
$self->setMessage($i+1,"This point is the same as the ".Value->NameForNumber($j+1)." one");$correct[$i] = 0; # Give a warning and mark incorrect break; # Stop looking through previous points } } } } return @correct; # Return the array indicating which are correct } ); Context()->texStrings; BEGIN_TEXT Three distinct points that lie on $$f$$ are:$BR
\{$ma->ans_rule(15)\}, \{$ma->ans_rule(15)\}, and \{$ma->ans_rule(15)\} END_TEXT Context()->normalStrings; ANS($ma->cmp);

ENDDOCUMENT();

Note that this checker works for any number of points. The checker itself could be packaged into a separate macro file for re-use, if so desired. For example, the macro file could contain
    $points_on_function = sub { my ($correct,$student,$self) = @_;
...
return @correct;
};

then you could use it as
    MultiAnswer("(1,0)","(0,1"),"(-1,0)")->with(
function => $f, allowBlankAnswers => 1, checker =>$points_on_function,
);

In fact, in that case, you could do something like
    sub PointsOnFunction {
my $f = shift; return MultiAnswer(@_)->with( function => Compute($f),

    PointsOnFunction("x^2+y^2=1","(1,0)","(0,1)","(-1,0)");