## WeBWorK Problems

### Help needed fixing local problem

by Sean Fitzpatrick -
Number of replies: 5

We have some local problems that were written by summer students a couple of years ago.

One is not working properly. My problem authoring skills are minimal at the best of times, and this one appears to use a custom answer checker (possibly in Perl?).

The question asks for a non-diagonal matrix with a given determinant. If done correctly, it is marked as such. If a student enters a diagonal matrix with the requested determinant, it gets marked wrong. (Good, though it's too bad they didn't put in a feedback message pointing out what's wrong.)

The main problem: anything with the wrong determinant gets marked correct! So the only way you get this wrong is if you have a diagonal matrix with the correct determinant. Is there an easy way to modify the answer checker to verify the determinant? Here's the code:

DOCUMENT();

"PGstandard.pl",

"MathObjects.pl",

# Used to provide contextual help for how to type answers.

# Provides greater control over the layout of the problem.

"PGML.pl",

# Used for course-specific initializations.

"PGcourse.pl",

);

TEXT(beginproblem());

#############################

#  Setup

# Used for handling matrix problems.

Context("Matrix");

#-ULETH-#

# ans : the random value of the determinant for the question.

# M : A solution matrix used to verify a student answer or act as a solution set.

$ans = non_zero_random(-10,10,1);$M = Matrix([

[$ans,6,1,9], [0,1,3,4], [0,0,1,6], [0,0,0,1], ]); #-ENDULETH-# ############################# # Main text #-ULETH-# BEGIN_PGML ###Enter a non-diagonal 4x4 matrix with a determinant of [$ans].

[A =] [@ $M->ans_array(5) @]* [@ AnswerFormatHelp("matrices") @]* END_PGML #-ENDULETH-# #-ULETH-#$showPartialCorrectAnswers = 0;

ANS( $M->cmp( checker => sub { my ($M,$student,$ansHash) = @_;

my ($sdet)=$student->det();

return ($sdet !=$ans or $student->is_symmetric ? 0 : 1); } )); #-ENDULETH-# ############################# # Solution #-ULETH-# BEGIN_PGML_SOLUTION SOLUTION: One possible solution is [A = [$M]].

We know that the determinant of any upper triangular matrix is the product of the element along the diagonal. So by placing [[$ans]] anywhere on the diagonal and filling the upper half of the matrix with any numbers (since they do not effect the determinant). END_PGML_SOLUTION COMMENT(' Randomization provides 19 different possible versions of this question.<BR> Includes a solution set.<BR> Recommended Settings:<BR> - Weight: 2<BR> - Max attempts: Unlimited<BR> - Show me another: -2<BR> - Rerandomize after: Default<BR> Made from a ULETH template.<BR> '); #-ENDULETH-# ENDDOCUMENT(); In reply to Sean Fitzpatrick ### Re: Help needed fixing local problem by Nathan Wallach - Attached is a file which should do what the problem intends and give feedback messages. In reply to Nathan Wallach ### Re: Help needed fixing local problem by Nathan Wallach - A correct version now attached. Sorry, I did not test carefully before. In reply to Sean Fitzpatrick ### Re: Help needed fixing local problem by Alex Jordan - The instructions are: ###Enter a non-diagonal 4x4 matrix with a determinant of [$ans].

Those three octothorpes make that line an h3 in HTML output. That seems inappropriate, and I might suggest removing them. But anyway, the determinant is supposed to equal $ans. But in the answer checker there is: return ($sdet != $ans or$student->is_symmetric ? 0 : 1);

I see a few things with this. One, it appears to be using is_symmetric as a proxy for being diagonal, but that is going block some symmetric non-diagonal answers form being accepted. Also I'm think the trinary logic operator A?B:C has higher precedence than "or", so you'd want it like:

return (($sdet !=$ans or $student->is_symmetric) ? 0 : 1); It seems unnecessary to use the ?: operator. It could be: return (($sdet == $ans) and not($student->is_symmetric));

But still, it's checking for symmetry, not diagonalness. I don't see a method for quickly checking if a matrix is diagonal. You could write a nested loop to check every element and ensure there are 0s off the diagonal. Something like:

my $isDiagonal = 1; for my$i (1..4) {
for my $j (1..4) {$isDiagonal = 0 if (($i !=$j) and ($student->element($i,$j) != 0)); last() unless$isDiagonal;
};
last() unless $isDiagonal; } return (!$isDiagonal and ($sdet ==$ans));

This is untested. Might have typos and/or logical errors in my thinking as I type.

### Re: Help needed fixing local problem

by Sean Fitzpatrick -
Thanks to you both for the quick help! The trouble with hiring summer students: some of them do a great job, and some of them leave behind buggy code that you don't discover until years later.