WeBWorK Problems

loading custom answer checker from macro file

loading custom answer checker from macro file

by John Sylvester -
Number of replies: 4
The attached file contains a custom answer checker. If I define the
sub in the .pg file by

$mycheckerref = sub { ... };

and call it with

ANS( $Soln->cmp( checker => $mycheckerref));

all is fine. I will use this checker in several problems, so I would
like to include it in a file of macros. I have tried several different
ways with no success.

1) just copy "$mycheckerref = sub { ... };" into the macro file, and
load the file.

2) define a named subroutine with "sub mychecker {...};" and call it with

ANS( $Soln->cmp( checker => mychecker));
or
ANS( $Soln->cmp( checker => &mychecker)); that's an ampersand
or
ANS( $Soln->cmp( checker => mychecker()));

In all these cases, the custom checker is ignored. Even if I define the
subroutine by name as in 2) within the original .pg file, it also is
ignored.

I even tried having the macro file return a reference to the
answerchecker. I assume its my syntax, but I don't know what else to try.

thanks again. I promise this will be the last question for a while.

In reply to John Sylvester

Re: loading custom answer checker from macro file

by Davide Cervone -
Yes, your syntax is wrong.

When you use

sub mychecker {...}
then All three of the ANS() calls all do the same thing: they call mychecker with no parameters and use the result of that call as the value for checker in the cmp() call. MathObjects will ignore the checker value if it is not a code reference, which is shy nothing is happening in this case (since your checker doesn't return a code reference).

What you want to do is pass a reference to mychecker rather than its return value. Normally in Perl you would do

ANS($Soln->cmp(checker => \&mychecker));
but because PG treats \ specially, in a PG problem you must use the non-standard ~~ sequence instead:
ANS($Soln->cmp(checker => ~~&mychecker));
It is for this reason that I prefer to have the code reference stored in s scalar variable (as you have been doing when you used $mychecker). You should be able to do that in an external .pl file stored in your course's templates/macros directory (or in the same directory as the .pg file) that you load using a laodMacros() call. Then you would use
ANS($Soln->cmp(checker => $mychecker));
You don't give the code for how you tried to do this, so I can't tell you where you went wrong, but that certainly can be done, and should work.
In reply to Davide Cervone

Re: loading custom answer checker from macro file

by John Sylvester -
Davide,

Using the reference to the answer checker worked as you suggested. If I can impose upon your good will one more time, could you look at the two attached files and run the .pg file.
and paste in the correct answer as described in the text of the file. It grades the same answer using a checker in the macro file and the same checker defined inside the .pg file. I have done a diff to make sure the code is exactly the same, except for a few lines that generate messages, which seem to be telling me that five lines of code that generate the output I want in the inside checker are returning nothing in the outside checker (the one in the macro file).

Am I missing something, or is this due to some difference in how the code works in the two cases?

Thanks again for all the help.


In reply to John Sylvester

Re: loading custom answer checker from macro file

by Davide Cervone -
is this due to some difference in how the code works in the two cases? Yes, the code works differently in the two situations. PG problems are processed specially by WeBWorK using some pre-processing that handle things like BEGIN_TEXT and similar constructs specially, and that try to make \ work without special handling in TeX strings. But .pl files are just standard Perl, with none of the pre-processing. In particular, this means that \ is not treated specially, and you can use it as you normally would in Perl. (It also means that the non-standard ~~ is not present, so you must use \ instead.)

In practice, that means you may have to change regular expression patterns when you go from a .pg problem file to a .pl macro file. You need to move from ~~ back to the standard \.

I notice that you have

while ($AnswerStr =~ m|c~~d|g) { $numcs++ }
in your .pl file. That needs to be changed to
while ($AnswerStr =~ m|c\d|g) { $numcs++ }
in order to be used in a .pl file.

I have not run the files, but certainly this has to be fixed before the .pl file will work properly, and I suspect that it the only issue.

In reply to Davide Cervone

Re: loading custom answer checker from macro file

by John Sylvester -
Davide,

That did it. Both work identically now. Thank you again.

John