Does anyone know precisely which elements of WeBWorK authoring won't translate to Gateway?
I ask because I did a massive rewrite, getting rid of ans_array_extension (and learning about MathObjects in the process). However, I'm at the point where the problem works correctly when I try it out in the editor, but I get a weird error message when trying to take it as a GatewayQuiz:
Can't call method "data" on an undefined value at [PG]/lib/Value.pm line 698
Line 698 doesn't contain any executable code, though. WeBWorK is dying inside this code for some reason:
sub good_cs { # good_cs (A, R, r) # basis for column space
my ($A, $R, $r) = @_;
my ($m, $n) = $A->dimensions;
my @a; my $i = 1;
for (my $j = 1; $j <= $n; $j++) {
if ($R -> element ($i, $j) > 0.5) {
for (my $k = 1; $k <= $m; $k++) { $a[$k-1][$i-1] = $A -> element($k, $j); }
$i ++;
}
}
Matrix (@a);
}
Once again, it's only dying when actually taking a quiz.
Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -Line 698 in the current version of [pg]/lib/Value.pm is
$M = $M->data->[$i];of the
extract()
method of the base MathObject class. Since the Matrix element
calls extract
, it looks like one of your element
calls is the culprit.
From the code snippet you give, it appears that you are incrementing $i
inside both loops (over the columns and rows), and use $i
as a row index in the first element()
call. I suspect that $i
is getting too big and is walking off the end of the matrix.
Check that the value of $i
and see if that doesn't get bigger than $m
in your quiz.
Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -For me, I see something like
Can't call method "data" on an undefined value at [PG]/lib/Value.pm line 699 Died within Value::extract called at line 8 of (eval 2919) from within main::testError called at line 11 of (eval 2919)in a section with a heading of "Error Details". It is below the listing of the problem, so look around and you might find more of the error messages below.
Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -Re: Gateway Quiz Problems --- What precisely can't I do?
by D. Brian Walton -Re: Gateway Quiz Problems --- What precisely can't I do?
by D. Brian Walton -Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -Can't locate object method "conjugate" via package "Value::Real" at [PG]/lib/Matrix.pm line 408
Died within Matrix::conj called at line 450 of [PG]/lib/Matrix.pm
from within Matrix::transpose called at line 1902 of [PG]/lib/MatrixReal1.pm
from within MatrixReal1::_transpose called at line 328 of (eval 4111)
from within main::compare_basis called at line 565 of [PG]/lib/AnswerHash.pm
from within AnswerEvaluator::evaluate called at line 1 of (eval 4127)
##KEYWORDS('linear algebra', 'systems of linear equations')
## DBsubject('Linear Algebra')
## Author('Christopher Heckman')
## Institution('Arizona State University')
## Section1('')
## Problem1('')
########################################################################
DOCUMENT();
loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"PGchoicemacros.pl",
"PGanswermacros.pl",
"PGgraphmacros.pl",
"PGmatrixmacros.pl",
"PGnumericalmacros.pl",
"PGauxiliaryFunctions.pl",
"PGmorematrixmacros.pl",
"MathObjects.pl",
"Value.pl",
"parserVectorUtils.pl",
);
TEXT(beginproblem());
$showPartialCorrectAnswers = 1;
Context("Complex");
Context() -> texStrings;
sub matrix2array { # matrix2array (matrix)
my $A = shift;
my ($m, $n) = $A -> dimensions;
my @arr = [(0) x $m] for 1 .. $n;
for (my $i = 0; $i < $m; $i++) { for (my $j = 0; $j < $n; $j++) {
$arr[$j][$i] = Real ($A -> element ($i + 1, $j + 1));
}}
@arr;
}
$A = Matrix ([[1,2],[3,4],[5,6]]);
$B2 = [matrix2array ($A)];
BEGIN_TEXT
Enter a list of vectors.
\{ ans_rule (25) \}
END_TEXT
Context()->normalStrings;
ANS (basis_cmp ($B2));
COMMENT('MathObject version.');
ENDDOCUMENT();
Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -If your matrix entry is ... | Then the conjugate function ... |
Real (0) | crashes |
0 | returns 0 |
Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -This has to do with the fact that there are two implementations for Matrices in WeBWorK: the MathObject matrices that you get with
Context("Matrix")
and the traditional ones you get from the Perl Matrix package. The latter do now know about MathObjects, and since the basis_cmp()
macro uses the traditional matrices, the error you are getting is due to that incompatibility. That is one reason you can't pass a MathObject Matrix to basis_cmp()
directly.You are correct to use the
value()
method of the MathObject Matrix entries to get the perl reals rather than MathObjects. (Note that in your original, the Real()
around the element extraction was redundant, since the Matrix entries are already MathObject Reals).A number of the matrix macros need to be updated to work with MathObject Matrices (or the MathObject Matrices could be updated to include methods that correspond to those older macros).
Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -$rank = random (3, 4);
which means that $rank
is either 3 or 4. The code below that checks for $rank
equal to 1, 2 or 3, and sets up $rs
, $cs
, and $ns
based on that. Note that the cases for 1 and 2 are not needed, so $rank
will never be one of those, and that the case for 4 is missing. Instead, you get the else
blocks, which set all three variables to 0 rather than an array reference.
In the answer section, you pass $rs
and the other variables to basis_cmp()
, which expects an array reference as its argument. In the case where $rank
is 4 (roughly half the time), you will pass basis_cmp()
the value 0 rather than an array reference. The error message you have received indicates that that is what is happening.
It would help to provide the complete error message, which in this case was
Can't use string ("0") as an ARRAY ref while "strict refs" in use at [PG]/lib/Matrix.pm line 305 Died within Matrix::new_from_col_vecs called at line 194 of [PG]/macros/PGmorematrixmacros.pl from within main::BASIS_CMP called at line 169 of [PG]/macros/PGmorematrixmacros.pl from within main::basis_cmp called at line 163 of (eval 10026)Note that this indicates (bottom line) that the originating call was to
basis_cmp()
, so that would have told you where to look first. The obvious thing to check is the values of the arguments passed to basis_cmp()
, which is what I did, and found $rs
equal to 0, an invalid value for basis_cmp()
. Looking back to see where $rs
was set allowed me to see what the problem was.
Note that this is an error produced by Perl itself (the language underlying WeBWorK), and not a message from WeBWorK specifically. It would be difficult to list all the messages that Perl could produce, and harder yet to tell you how to fix the problems. The message already said what was wrong (a 0 was used where an array was expected), and told you where that occurred (in basis_cmp()
). That is about as good as we can expect from the system, in my opinion. I don't see how it could tell you where to look earlier in your code for the true cause of the problem.
Re: Gateway Quiz Problems --- What precisely can't I do?
by Christopher Heckman -Can't use string ("0") as an ARRAY ref
Can't use string ("0") as an ARRAY ref
Re: Gateway Quiz Problems --- What precisely can't I do?
by Davide Cervone -Can't use real (0) as an ARRAY refor something like that.
The error message comes from a line that includes
$vec->[0]where
$vec
is the value you passed to basis_cmp()
(the zero in this case). Perl doesn't have "hard" types like a language such as C++ has, and $code
is what Perl terms a "scalar" value. That could be a number, a string, a reference to an array or an object, or a few other things. Perl will convert between types automatically as needed, so no explicit type coercion is needed in most cases.
The ->
in $vec->[0]
asks Perl to dereference a reference to an object of some kind, and so the scaler $vec
is supposed to be either a reference to an object, or a string that is the name of an object class. (E.g., Value->Error()
is valid because Value
is the name of a class). So Perl tries to make the number 0 into a valid scalar that can be used on the left of ->
. In this case, it can't covert to an object reference, so converts to a string in hopes that the string value will be the name of a class (in Perl, a "package"). but the string 0
is not the name of a class, so you get the error.