WeBWorK Problems

Using Student Answers to Calculate Subsequent Answers

Re: Using Student Answers to Calculate Subsequent Answers

by Danny Glin -
Number of replies: 0

I think the sample problem below covers all of the things that you want to accomplish.  I have also attached the pg file.

Using multiAnswer you can extract the student's equation as a MathObject formula, and then use the 'eval' method to evaluate the student's formula at a specific x-value.  I have also included code for setting the tolerance for a single mathObject, rather than for the entire problem.  Let me know if you have any questions about the code.

Some notes about my code:

  • My approach to extracting the slope of the line (taking the derivative) depends on the student's equation being that of a line.  My custom checker marks all three parts wrong if their equation is wrong, so we can be certain (up to tolerance) that they've entered a linear formula if they get the first part right.  If you wanted to give them credit for getting the last two parts right without getting the equation of the line right, you'd have to think more carefully about how to make sure that the student's formula is linear.
  • When doing comparisons inside a custom checker (e.g. using ==), the tolerance is inherited from the object on the left side of the comparison, so $x2calculated == $x2stu will use the tolerance associated with $x2calculated, whereas $x2stu == $x2calculated will use the tolerance associated with $x2stu.
  • An alternate approach for the last part would be to evaluate the student's equation at the student's x-value (i.e. $linestu->eval(x=>$x2stu)), and then compare this to $y2 using your desired tolerance.









################# Setting up the problem goes here.



$m = random(2,6,1);

$b = random(-5,-2,1);

$line = Compute("$m*x+$b")->reduce();

$x1 = random(3,7,1);

$y1 = $line->eval(x=>$x1);

$y2 = random(7,11,1);

$x2 = ($y2-$b)/$m;

$multians = MultiAnswer($line, $y1, $x2)->with(

  singleResult => 0,

  checker => sub {

      my ( $correct, $student, $self ) = @_;

      my ( $linestu, $y1stu, $x2stu ) = @{$student};

      if ($line == $linestu) {

        $result1 = 1;

        $y1calculated = $linestu->eval(x=>$x1);

        if ( $y1calculated == $y1stu ) {

            $result2 = 1;

            } else {

            $result2 = 0;


        $mstu = $linestu->D('x');

        $bstu = $linestu->eval(x=>0);

        $x2calculated = ($y2-$bstu)/($mstu);



        if ($x2calculated == $x2stu) {

            $result3 = 1;

            } else {

            $result3 = 0;


        } else {

        $result1 = 0;

        $result2 = 0;

        $result3 = 0;





Write the equation of [:y= [$line]:].


When [:x=[$x1]:], predict the value of [:y:].


When [:y=[$y2]:], predict the value of [:x:].