WeBWorK Problems

Can't generate enough valid points for comparison error

Can't generate enough valid points for comparison error

by Paul Seeburger -
Number of replies: 1
Hello,

I am having trouble with a problem I created in WeBWorK 2.9 that does not work properly in the current version of WeBWorK on the U of R server.

It uses bizarro arithmetic to try to be sure students simplify entries in a multianswer construct.

For some reason, even when all answers are correct, I get back the error "" on the multianswer components of the problem every time.

Here is the code for the problem:

## DESCRIPTION
## Differential equation solved using Variation of Parameters
## ENDDESCRIPTION


## DBsubject(Differential equations)
## DBchapter(Higher order differential equations)
## DBsection(Variation of parameters)
## Date(3/12/2015)
## Institution(Monroe Community College)
## Author(Paul Seeburger)
## Level(2)
## KEYWORDS('differential equation','second order','linear','nonhomogeneous','variation of parameters')
## adapted from: IndianaDiffEq/setDiffEQ10Linear2ndOrderNonhom/ur_de_10_16.pg

DOCUMENT() ;

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGmatrixmacros.pl",
"parserPopUp.pl",
"parserMultiAnswer.pl",
"weightedGrader.pl",
"bizarroArithmetic.pl",
"PGunion.pl",
"PGcourse.pl",
#"PGdiffeqmacros.pl"
) ;
############
TEXT(beginproblem()) ;

Context("Numeric");

Context()->variables->are(
't'=>["Real", limits=>[-2,2]], 'y'=>["Real", limits=>[-2,2]]);
#, 'a'=>'Parameter','b'=>'Parameter');
#Context()->variables->remove('x');
Context()->functions->set( atan => {TeX => '\arctan'} );

# root of the characteristic equation
$r = Real(non_zero_random(-5,5,1));
$a = -2*$r;
$b = $r**2;
$c = Real(non_zero_random(-20,20,.5));
$ch = Real("-1*$c/2");
# $e = exp(1);
# $ans = Compute("($c/2)*(($e)**($r*t))");

$showPartialCorrectAnswers = 1 ;

$yp = Compute("e^($r t)($ch ln(t^2 + 1) + $c t arctan(t))")->reduce;


Context("Numeric");

Context()->variables->are(
't'=>["Real", limits=>[-2,2]], 'y'=>["Real", limits=>[-2,2]]);
#Context()->variables->remove('x');
Context()->functions->set( atan => {TeX => '\arctan'} );
#Context()->flags->set( checkUndefinedPoints=>1);

$a11 = Formula("e^($r t)");
#$a11->{test_at} = [[-2],[-1],[0],[1],[2]];
$a12 = Formula("t e^($r t)");
$a21 = Formula("$r e^($r t)");
$a22 = Formula("e^($r t)(1 + $r t)");

$n = Real("2*$r");
$wronskian = Formula("e^($n t)"); #Compute

$b11 = Real("0"); #Formula("0t");
$b12 = Formula("t e^($r t)");
$b21 = Formula("$c e^($r t)/(t^2+1)");
$b22 = Formula("e^($r t)(1 + $r t)");

$n2 = Real("-1*$c");
$w1 = Formula("$n2 t e^($n t)/(t^2+1)"); #Compute

$c11 = Formula("e^($r t)");
$c12 = Real("0"); #Formula("0t");
$c21 = Formula("$r e^($r t)");
$c22 = Formula("$c e^($r t)/(t^2+1)");

$w2 = Formula("$c e^($n t)/(t^2+1)"); #Compute

$u1p = Formula("$n2 t/(t^2+1)"); #Compute
$u2p = Formula("$c/(t^2+1)"); #Compute

$u1 = Formula("$n2/2 * ln(t^2 + 1)")->reduce; #Compute
$u2 = Formula("$c arctan(t)"); #Compute

#$yp = Compute("$ch e^($r t)ln(t^2 + 1) + $c t arctan(t)")->reduce;


$multians1 = MultiAnswer($a11, $a12, $a21, $a22, $wronskian, $b11, $b12, $b21, $b22, $w1, $c11, $c12, $c21, $c22, $w2, $u1p, $u2p, $u1, $u2)->with(

singleResult => 0, # I cannot get this problem to work well with a single result since it would not show students which parts are correct and which are incorrect. Maybe change in the future, once this process is easier.
allowBlankAnswers => 1,
checkTypes => 0,
# The formatting has not been expanded to include the second and third determinants
# This is not important on this problem since we cannot display the problem this way anyway.
format => "<table border='0' cellspacing='20'>
<tr><td> %s </td><td>&nbsp; %s </td> </tr>
<tr><td> %s </td><td>&nbsp; %s </td> </tr>
<tr><td> &nbsp; = %s </td></tr>
</table>",
tex_format => "\left\lbrack\begin{array}{rr} %s & %s \\ %s & %s \end{array}\right\rbrack = %s",

checker => sub {
my ( $correct, $student, $self, $ans) = @_;
my @c = @{$correct};
my @s = @{$student};
my @score = ();

Context()->operators->set(
'/' => {class => 'bizarro::BOP::divide', isCommand => 1},
'/ ' => {class => 'bizarro::BOP::divide', isCommand => 1},
' /' => {class => 'bizarro::BOP::divide', isCommand => 1},
'//' => {class => 'bizarro::BOP::divide', isCommand => 1},
'-' => {class => 'bizarro::BOP::subtract', isCommand => 1},
'- ' => {class => 'bizarro::BOP::subtract', isCommand => 1},
' -' => {class => 'bizarro::BOP::subtract', isCommand => 1},
'*' => {class => 'bizarro::BOP::multiply', isCommand => 1},
'* ' => {class => 'bizarro::BOP::multiply', isCommand => 1},
' *' => {class => 'bizarro::BOP::multiply', isCommand => 1});

$flag = 1;
if ($c[0] == $s[1]) {
$flag = -1;
foreach my $j (0..1) {
$score[$j] = 0;
if ($c[$j]->typeMatch($s[1-$j]) && $c[$j] == $s[1-$j]) { $score[$j] = 1; }
$score[$j+2] = 0;
if ($c[$j+2]->typeMatch($s[1-$j+2]) && $c[$j+2] == $s[1-$j+2]) { $score[$j+2] = 1; }
}
}
else {
foreach my $j (0..3) {
$score[$j] = 0;
if ($c[$j]->typeMatch($s[$j]) && $c[$j] == $s[$j]) { $score[$j] = 1; }
}
}

$student = Formula("$s[4]"); $correct = Formula("$flag*$c[4]")->reduce;
if ($correct != $student) {
$score[4] = 0;
}
else {
Context()->flags->set(bizarroDiv=>1,bizarroSub=>1,bizarroMul=>1);
delete $correct->{test_values}, $student->{test_values};
# Context()->flags->set(limits=>[0.25,0.4]);
if (($correct != $student) || ($student != $correct)) {
$self->setMessage(5, "Your Wronskian answer is correct, but please simplify it further");
$score[4] = 0;
}
# Value->Error("Your Wronskian answer is correct, but please simplify it further") unless (($correct == $student) or ($student == $correct));
else {
$score[4] = 1;
}
Context()->flags->set(bizarroDiv=>0,bizarroSub=>0,bizarroMul=>0);
}

###### Check W1 Determinant contingent on the choices made by student in W above.
$i = 5; # offset
## Check first column is 0, f(x)
$score[$i] = ($c[$i]->typeMatch($s[$i]) && $c[$i] == $s[$i]);
$score[$i+2] = ($c[$i+2]->typeMatch($s[$i+2]) && $c[$i+2] == $s[$i+2]);
## Check second column contingent on student choices made in W above.
$score[$i+1] = ($c[$i+1]->typeMatch($s[$i+1]) && $s[1] == $s[$i+1]);
$score[$i+3] = ($c[$i+3]->typeMatch($s[$i+3]) && $s[3] == $s[$i+3]);
## Check determinant W1
$off = 0;
if ($flag==-1) { $off = 5;}
$student = Formula("$s[$i+4]"); $correct = Formula("$flag*$c[$i+4+$off]")->reduce;
if ($correct != $student) {
$score[$i+4] = 0;
}
else {
Context()->flags->set(bizarroDiv=>1,bizarroMul=>1);
delete $correct->{test_values}, $student->{test_values};
# Context()->flags->set(limits=>[0.25,0.4]);
if (($correct != $student) || ($student != $correct)) {
$self->setMessage($i+5, "Your W1 answer is correct, but please simplify the final determinant expression further");
$score[$i+4] = 0;
}
# Value->Error("Your Wronskian answer is correct, but please simplify it further") unless (($correct == $student) or ($student == $correct));
else {
$score[$i+4] = 1;
}
Context()->flags->set(bizarroDiv=>0,bizarroMul=>0);
}

###### Check W2 Determinant contingent on the choices made by student in W above.
$i = 10; # offset
## Check second column is 0, f(x)
$score[$i+1] = ($c[$i+1]->typeMatch($s[$i+1]) && $c[$i+1] == $s[$i+1]);
$score[$i+3] = ($c[$i+2]->typeMatch($s[$i+2]) && $c[$i+3] == $s[$i+3]);
## Check first column contingent on student choices made in W above.
$score[$i] = ($c[$i]->typeMatch($s[$i]) && $s[0] == $s[$i]);
$score[$i+2] = ($c[$i+2]->typeMatch($s[$i+2]) && $s[2] == $s[$i+2]);
## Check determinant W2

$student = Formula("$s[$i+4]"); $correct = Formula("$flag*$c[$i+4-$off]")->reduce;
if ($correct != $student) {
$score[$i+4] = 0;
}
else {
Context()->flags->set(bizarroDiv=>1,bizarroMul=>1);
delete $correct->{test_values}, $student->{test_values};
## Context()->flags->set(limits=>[0.25,0.4]);
if (($correct != $student) || ($student != $correct)) {
$self->setMessage($i+5, "Your W2 answer is correct, but please simplify the final determinant expression further");
$score[$i+4] = 0;
}
# Value->Error("Your Wronskian answer is correct, but please simplify it further") unless (($correct == $student) or ($student == $correct));
else {
$score[$i+4] = 1;
}
Context()->flags->set(bizarroDiv=>0,bizarroMul=>0);
}

#### Check for u1 prime
$student = Formula("$s[15]");
if ($flag == -1) {
$correct2 = Formula("$c[15]")->reduce;
$correct = Formula("$c[16]")->reduce;
}
else {
$correct2 = Formula("$c[16]")->reduce;
$correct = Formula("$c[15]")->reduce;
}

if ($correct != $student) {
$score[15] = 0;
}
else {
Context()->flags->set(bizarroDiv=>1,bizarroMul=>1);
delete $correct->{test_values}, $student->{test_values};
## Context()->flags->set(limits=>[0.25,0.4]);
if (($correct != $student) || ($student != $correct)) {
$self->setMessage(16, "Your u1' is correct, but please simplify the final expression further");
$score[15] = 0;
}
# Value->Error("Your Wronskian answer is correct, but please simplify it further") unless (($correct == $student) or ($student == $correct));
else {
$score[15] = 1;
}
Context()->flags->set(bizarroDiv=>0,bizarroMul=>0);
}

#### Check for u2 prime
$student = Formula("$s[16]");
if ($correct2 != $student) {
$score[16] = 0;
}
else {
Context()->flags->set(bizarroDiv=>1,bizarroMul=>1);
delete $correct2->{test_values}, $student->{test_values};
## Context()->flags->set(limits=>[0.25,0.4]);
if (($correct2 != $student) || ($student != $correct2)) {
$self->setMessage(17, "Your u2' is correct, but please simplify the final expression further");
$score[16] = 0;
}
else {
$score[16] = 1;
}
Context()->flags->set(bizarroDiv=>0,bizarroMul=>0);
}

#### Check for u1
$student = Formula("$s[17]");
if ($flag == -1) {
$correct2 = Formula("$c[17]")->reduce;
$correct = Formula("$c[18]")->reduce;
}
else {
$correct2 = Formula("$c[18]")->reduce;
$correct = Formula("$c[17]")->reduce;
}
$score[17] = ($student == $correct || $correct == $student);
#### Check for u2
$student = Formula("$s[18]");
$score[18] = ($student == $correct2 || $correct2 == $student);
return [ @score ];
}

);

##################################
# reset the context and get rid of adaptive parameters

Context("Numeric");
Context()->variables->add(
'y' =>'Real','t' =>'Real',
'c1'=>'Real',
'c2'=>'Real',
);
Context()->variables->remove('x');
Context()->variables->set(
'c1'=>{limits=>[2,4]},
'c2'=>{limits=>[2,4]},
'y'=>{limits=>[-2,2]},
't'=>{limits=>[-2,2]}
);

$yhomogeneous = Compute("c1 e^($r t) + c2 t e^($r t)");

Context()->texStrings;
BEGIN_TEXT
Use variation of parameters to find a particular solution to:
\(\quad \displaystyle {y'' + $a y' + $b y = \frac{$c e^{$r t}}{t^2+1}} \).

\{ BeginList('OL',type=>'a') \}
$ITEM Find the most general solution to the
associated homogeneous differential equation.
Use \( c_1 \) and \( c_2 \) in your answer to denote arbitrary constants. $BR
Enter \( c_1 \) as ${BTT}c1${ETT} and \( c_2 \) as ${BTT}c2${ETT}.
$BR
$BR
\( y_c = \)
\{ ans_rule(60) \}
$ITEMSEP
$ITEM Use the two independent solutions of the homogeneous form of the DE to enter the Wronskian determinant, \(W\):

$PAR
$BCENTER
\{
mbox(
"\(W = \mathrm{det} \)",
display_matrix([
[$multians1->ans_rule(20),$multians1->ans_rule(20)],
[$multians1->ans_rule(20),$multians1->ans_rule(20)]], align=>'cc'),
" = ".$SPACE.$multians1->ans_rule(30)
);
\}
$ECENTER
$ITEMSEP
$ITEM Now enter the determinants, \(W_1\) and \(W_2\):

$PAR
$BCENTER
\{
mbox(
"\(W_1 = \mathrm{det} \)",
display_matrix([
[$multians1->ans_rule(20),$multians1->ans_rule(20)],
[$multians1->ans_rule(20),$multians1->ans_rule(20)]], align=>'cc'),
" = ".$SPACE.$multians1->ans_rule(30)
);
\}
$ECENTER
$PAR
$BCENTER
\{
mbox(
"\(W_2 = \mathrm{det} \)",
display_matrix([
[$multians1->ans_rule(20),$multians1->ans_rule(20)],
[$multians1->ans_rule(20),$multians1->ans_rule(20)]], align=>'cc'),
" = ".$SPACE.$multians1->ans_rule(30)
);
\}
$ECENTER
$ITEMSEP
$ITEM Use these results to determine \(u_1^{\prime}\) and \(u_2^\prime\). (Please simplify them. This will make it easier to integrate in the next step.)
$PAR
\(u_1^\prime = \frac{W_1}{W} =\) \{$multians1->ans_rule(30) \}
$PAR
\(u_2^\prime = \frac{W_2}{W} =\) \{$multians1->ans_rule(30) \}
$ITEMSEP
$ITEM Now integrate \(u_1^{\prime}\) to determine \(u_1\),
$PAR
\(u_1 = \int{u_1^\prime\,dt} =\) \{$multians1->ans_rule(30) \} \( + \quad C_1\)
$PAR
and integrate \(u_2^{\prime}\) to determine \(u_2\).
$PAR
\(u_2 = \int{u_2^\prime\,dt} =\) \{$multians1->ans_rule(30) \} \( + \quad C_2\)
$ITEMSEP
$ITEM Finally, enter the simplest form of the particular solution you obtained (not including any terms that are part of the complementary solution to the homogeneous form of this DE).
$PAR
\(y_{p} = \) \{ans_rule(60)\}

\{ EndList('OL') \}
END_TEXT
Context()->normalStrings;

ANS( $yhomogeneous->cmp(
checker => sub {
my ( $correct, $student, $answerHash ) = @_;
my $stu = Formula($student);

################################
# Check for arbitrary constants
#
Value->Error("Is your answer the most general solution?")
if (
Formula($stu->D('c1'))==Formula(0) ||
Formula($stu->D('c2'))==Formula(0)
);

############################################
# Check for linear independence (Wronskian)
#
my $t = Real(1.24);

my $a11 = $stu->eval('c1'=>1,'c2'=>0,t=>$t,y=>0);
my $a12 = $stu->eval('c1'=>0,'c2'=>1,t=>$t,y=>0);
my $a21 = $stu->D('t')->eval('c1'=>1,'c2'=>0,t=>$t,y=>0);
my $a22 = $stu->D('t')->eval('c1'=>0,'c2'=>1,t=>$t,y=>0);

# my $wronskian = $a11*$a22 - $a21*$a12;
# Value->Error("Your functions are not linearly independent or your answer is not complete")
# if ($wronskian==Real(0));

Value->Error("Your functions are not linearly independent or your answer is not complete")
if ($a11 * $a22 == $a21 * $a12);

########################################################
# Check that the student answer is a solution to the DE
#
my $stu1 = Formula($stu->D('t'));
my $stu2 = Formula($stu->D('t','t'));
return (($stu2 + $a*$stu1) == (-1 * $b * $stu));
}));

ANS( $multians1->cmp());

ANS( $yp->cmp() );

ENDDOCUMENT() ;

Please let me know if you have any ideas about where my issue may be.

Thanks!

Paul
In reply to Paul Seeburger

Re: Can't generate enough valid points for comparison error

by Paul Seeburger -
Ok, I found the error in another post from a year ago. I guess there is something to using the exact phrase option in the search on the forums!

In a reply from Alex Jordan to Bruce Yoshiwara, Alex explained that now the definitions of the bizarro arithmetic options need to be on the context BEFORE any objects are created.

It's interesting how this did not used to cause a problem, but it's great to get this figured out!! I am sure it will prove helpful in many other problems too.


Paul