WeBWorK Main Forum

subclass2...

subclass2...

by Clinton Ferreira -
Number of replies: 6
In connection with my previous post, I put here what I have so far:

$correct = 5;
$sol = $correct->num_cmp(checker => sub {
 my ($correctgiven, $input) = @_;
 if ($input == $correctgiven) {
 return 5;
 }
 if ($input == -$corretgiven) {
 return -5;
 }
 return $input;
}); #(this is line 35)
But this doesn't work and the error message I get is

Can't call method "cmp" without a package or object
reference at line 35 of [TMPL]/settest/problem1.
I think I might be failing to put my variables in the proper Context() or something. I'm not sure of how to do that in any case.
In reply to Clinton Ferreira

Re: subclass2...

by Davide Cervone -
There are several problems with the code fragment you have given.

First, your correct answer is a plain perl number, not a perl object, and in particular, not a MathObject. You should use

    $correct = Real(5);
for that (being sure to have loaded MathObjects.pl in your loadMacros() call at the top of the file). Next, for a MathObject, you don't use num_cmp or fun_cmp or any of the older answer checkers directly. Instead, you use the cmp method of the MathObject, since it knows its own type, and can tell what type of answer checking you need:
    $correct->cmp(...);

Next, the return value for your checker routine should be 0 or 1, depending on whether the student's answer is correct or not. You seem to be returning the student's answer instead. (Technically, you can give partial credit by giving a decimal value between 0 and 1. I don't remember wether the return value is clipped to that range, but it might be that returning -5 would take AWAY points.)

Finally, that cmp method returns an AnswerEvaluator object, and that needs to be passed to ANS() to make it active. The usual method would be to do something like

    ANS($correct->cmp(...));
So for your case, something like:
    ANS(Real(5)->cmp(checker => sub {
      my ($correct,$student) = @_;
      return $correct == $student || $correct == -$student;
    }));
should do the trick.

There are a number of samples in this discussion forum. See, for example:

    https://webwork.maa.org/moodle/mod/forum/discuss.php?d=5637
    https://webwork.maa.org/moodle/mod/forum/discuss.php?d=4308
    https://webwork.maa.org/moodle/mod/forum/discuss.php?d=5421
    https://webwork.maa.org/moodle/mod/forum/discuss.php?d=5736
You can also look at the pg/macros/answerCustom.pl file for some examples and documentation. See the PG file POD documentation for formatted versions of the comments within the files. There are some sections on MathObjects, for example, that will give you a start (though these files are woefully incomplete). The answerCustom.pl file is documented there, as are all the main PG macro files.

Hope that helps.

Davide

In reply to Davide Cervone

Re: subclass2...

by Clinton Ferreira -
Sorry, it looks like I do have one problem after all. Our version of Webwork doesn't seem to have the MathObject.pl macro. Could you please tell me how to get it and whether older questions already on the system will continue working as they should once I've loaded the macro in.

There are a lot of live questions here and if they suddenly stopped working after installing MathObject.pl, I might not be able to get them working again.

Thanks
In reply to Clinton Ferreira

Re: subclass2...

by Davide Cervone -
The file is MathObjects.pl (plural), so see if you have that. This is really just a renamed version of Parser.pl, and I think the change was made last summer, so you might not have it.

The PG directory is pretty much independent of the rest of WeBWorK, so you probably could update without trouble if you wanted to, but I understand not wanting to do it during the term. You can use Parser.pl for now.

Davide
In reply to Davide Cervone

Re: subclass2...

by Clinton Ferreira -
Here's a specific problem I'm having. I want to ask the students to calculate a formula for the electric field of three charges.

Here's my code

DOCUMENT();

loadMacros("PG.pl",
"PGbasicmacros.pl",
"PGchoicemacros.pl",
"PGanswermacros.pl",
"PGauxiliaryFunctions.pl",
"PGgraphmacros.pl",
"Parser.pl",
);

## Do NOT show partial correct answers
$showPartialCorrectAnswers = 0;
#TEXT(beginproblem());

BEGIN_TEXT

Three identical, positive charges \(+Q\) are placed at the corners of an equilateral triangle of side \(a\). Calculate the magnitude of the electric field at each of the charges.

$PAR

\(|E|\) = \{ans_rule()\}

END_TEXT

ANS(Formula("sqrt(3)*Q/(4*pi*e*a^2)")->cmp(
checker => sub {
my ($correct,$student) = @_;
return $correct == $student;
}
));

ENDDOCUMENT();

and here's the error message it gives

Error messages

Variable 'Q' is not defined in this context; see position 9 of formula at line 36 of [TMPL]/settest/problem2b.pg Died within main::Formula called at line 36 of [TMPL]/settest/problem2b.pg

Error details

 Problem2
ERROR caught by Translator while processing problem file:settest/problem2b.pg
****************
Variable 'Q' is not defined in this context; see position 9 of formula at line 36 of [TMPL]/settest/problem2b.pg
 Died within main::Formula called at line 36 of [TMPL]/settest/problem2b.pg

****************

In reply to Clinton Ferreira

Re: subclass2...

by Davide Cervone -
The problem is that you need to tell WeBWorK that you want to use a variable called Q. To do that, you use
    Context()->variables->add(Q=>'Real');
so that Q is recognized as a variable.

Also, note that your custom checker is not really needed since al it does is exactly what the default checker does. No need to do the quality check yourself unless you are planning to do something more complicated.

Hope that helps out.

Davide