my $v1 = Compute("$student . Vector(1,0,0)");Assuming the student's answer is
<x,0,0>
as in your example, then you will get
my $v1 = Compute("(<x,0,0>) . Vector(1,0,0)");which asks the MathObject library to parse the string
"(<x,0,0>) . Vector(1,0,0)"as it would a student answer. But (as the message indicates) ,
Vector
is not defined in the context, so it complains about that. That is, Vector()
can not be used as part of a student answer, and so can't appear in the string passed to Compute()
. I think you mean
my $v1 = $student . Vector(1,0,0);Since
$student
is already a MathObject, there is no need to turn it into a string and parse it again. And since this is now a perl expression (not a string to be parsed), and Vector()
is defined as a perl function, and since .
has been overloaded to do dot product when one of its operands is a vector, this will do what you want.
Note that i
is predefined as Vector(1,0,0)
, so you can do
my $v1 = $student . i;Also, there is no need to use
Formula()
around $v1
in the next line, as $v1
is already a MathObject, so you can compare it to Formula("y")
directly.
With that in mind, your code could be
Context("Vector"); ANS(Vector(Real(0),Real(0),Formula("x+y"))->cmp( checker => sub { my ($correct,$student,$ansHash) = @_; return ($student . i) == Formula("y"); } ));As for the unexpected value in the "entered" column, it turns out that the MathObject answer checkers will replace the entered value by the formula with highlighting when an error occurs during parsing the student answer. In your case, the
Compute()
caused such an error, and the students answer was replaced by the highlighted formula from that. Since this is due to a programming error in the custom checker, I'm not too worried about that.
DOCUMENT();
loadMacros("PG.pl","PGbasicmacros.pl","PGanswermacros.pl");
loadMacros("MathObjects.pl");
TEXT(beginproblem());
Context('Vector');
BEGIN_TEXT
Answer: \{ ans_rule(30) \}
$BR$BR
Answer: \{ ans_rule(30) \}
END_TEXT
ANS(Vector(Real(0),Real(0),Formula("x+y"))->cmp(
checker => sub {
my ($correct,$student,$ansHash) = @_;
return ($student . i) == Formula("y");
}
));
Context('Numeric');
ANS(Real(0)->cmp);
ENDDOCUMENT();
This gives me a warning. If I remove the "Context('Numeric')'" line, it
is ok. Why?
John
Vector("<0,0,x+y>")
), there is a post-filter for the answer checker that checks to see if the previous answer is equivalent to the current one. The check also calls the custom checker (to find out if the two are equal), and it is that second time through the checker that is causing the problem.
When the checker is run initially, the context is set to the context of the correct answer (so that things like the tolerances, the variable limits, and so on are taken from the correct context). But it turns out that the test against the previous answer doesn't set the context (this is a bug), and so whatever the last context was for the problem is the one that is in effect for the post-filter.
So when you have Context("Numeric"), that makes the custom checker run in Numeric context rather than Vector context, and things like dot product and the vector i
are not defined there.
So one fix is to not use the Context("Numeric")
, as you suggest. Personally, I think that is the right solution, since the context is supposed to be for the whole problem, when possible, and you should only change the context if you really need to. That way, if a student types a vector in the place where a number is used, he or she will get an appropriate message to that effect rather than saying that < is undefined.
Alternatively, you could use
ANS(Vector("<0,0,x+y>")->cmp( checker => sub { my ($correct,$student,$ansHash) = @_; Context($correct->context); return (Vector(1,0,0) . Vector(1,0,0)) == Formula("y"); } ));to get the context set correctly during the second time through.
<1,2,3>
, but can be problematic when the answer is a vector formula. In that case, this only works if the student answers an explicit vector, like <x,y,x+y>
, but will fail if the student enters 3<x,y,x+y>
or <1,0,0>.<x,y,x+y>
. So I recommend using the dot product unless you are using one of the restricted vector contexts that prevents vector formulas.
You can also do
Vector(2,3,5)->extract(1)rather than
(Vector(2,3,5)->value)[0]to get just the first coordinate.
Note also that there is a Complex-Vector
context, so no need to set that up yourself. Just use
Context("Complex-Vector");There are also
Complex-Point
and Complex-Matrix
contexts.