WeBWorK Problems

by Christian Stahn -
Number of replies: 2
Hello,

I have been trying to write a MultiAnswer checker for questions asking for two different instances of a matrix or vector satisfying certain conditions. (For example, the problem could ask for two distinct particular solutions to a linear system, as shown below.) The code should allow blank answers so that students can see whether the first instances they enter are correct.

The code I wrote is based on the MultiAnswerProblems wiki page but so far does not work if one answer is left blank. After some experimenting, I found that:
* if one of the answer fields is left blank, the "checker" routine is not even called, and
* analogous code with numerical answers (also shown below) works fine.

Does anybody know what's going wrong?

Christian

+++++++++++++++++++++++++++++++++++++++++++++
An example with "Matrix" answers: does not work
+++++++++++++++++++++++++++++++++++++++++++++

DOCUMENT();

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

TEXT(beginproblem());

Context('Matrix');

$A = Matrix([ [1,1], [2,2]]);$b = Matrix([
[1],
[2]]);

# two correct particular solutions
$part1 = Matrix([[1],[0]]);$part2 = Matrix([[0],[1]]);

# MultiAnswer object for the two particular solutions

$multians = MultiAnswer($part1, $part2)->with( singleResult => 0, allowBlankAnswers => 1, checker => sub { my ($correct, $student,$self ) = @_;
my ( $x1stu,$x2stu ) = @{$student}; my ($x1, $x2 ) = @{$correct};
my @ret = (0,0);
if ( ref($x1stu) eq ref($x1) ) {
$ret[0] = ( ( ($A*$x1stu) ==$b ) ? 1 : 0);
}
if ( ref($x2stu) eq ref($x2) ) {
$ret[1] = ( ( ($A*$x2stu) ==$b ) ? 1 : 0);
}
return [ @ret ];
}
);

Context()->texStrings;
BEGIN_TEXT
Consider the linear system $$A \vec{x} = b$$.
$BR Enter two particular solutions.$BR
$$\vec{x} =$$
\{ $multians -> ans_array \} and $$\vec{x} =$$ \{$multians -> ans_array \}
$BR END_TEXT Context()->normalStrings; ANS($multians -> cmp);

ENDDOCUMENT();

+++++++++++++++++++++++++++++++++++++++++++++
An example with numerical answers: works fine
+++++++++++++++++++++++++++++++++++++++++++++

DOCUMENT();

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

TEXT(beginproblem());

Context('Numeric');

# two correct particular solutions
$part1 = Compute(2);$part2 = Compute(4);

$multians = MultiAnswer($part1, $part2)->with( singleResult => 0, allowBlankAnswers => 1, checker => sub { my ($correct, $student,$self ) = @_;
my ( $x1stu,$x2stu ) = @{$student}; my ($x1, $x2 ) = @{$correct};
my @ret = (0,0);
if ( ref($x1stu) eq ref($x1) ) {
$ret[0] = ( ( ($x1stu % 2) == 0 ) ? 1 : 0);
}
if ( ref($x2stu) eq ref($x2) ) {
$ret[1] = ( ( ($x2stu % 2) == 0 ) ? 1 : 0);
if ( ref($x1stu) eq ref($x1) ) {
if ( $x1stu ==$x2stu ) {
$ret[1] = 0;$self->setMessage(2,'Your two answers are identical.');
}
}
}
return [ @ret ];
}
);

Context()->texStrings;
BEGIN_TEXT
Enter two distinct even numbers:
$BR \{$multians -> ans_array \} and \{ $multians -> ans_array \} END_TEXT Context()->normalStrings; ANS($multians -> cmp);

ENDDOCUMENT();

It turns out that MultiAnswer's allowBlankAnswers option doesn't work properly when ans_array is used, as you have found out. I had hoped to be able to give you a patch to work around this, but it is more complicated than I had originally thought, and will take some work to fix it.
Thanks for the quick update. I didn't expect an issue requiring major work. In any event, the problems I had in mind would keep almost all of their functionality without allowBlankAnswers (after all, a student could just fill in a fake second matrix / vector to have the first one checked), so I'll go with that simpler approach.