WeBWorK Problems

Multi answer problems with blank vector or matrix answer fields

Multi answer problems with blank vector or matrix answer fields

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();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.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();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.pl",
);


TEXT(beginproblem());

Context('Numeric');

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

# MultiAnswer object

$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();

In reply to Christian Stahn

Re: Multi answer problems with blank vector or matrix answer fields

by Davide Cervone -
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.
In reply to Davide Cervone

Re: Multi answer problems with blank vector or matrix answer fields

by Christian Stahn -
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.