WeBWorK Problems

MultiAnswer with Complex context and PGML

MultiAnswer with Complex context and PGML

by Dave Rosoff -
Number of replies: 8
Hi all,

I'm working on a problem that gives the student an equation of the form
(x-h)^2 + (y-k)^2 = r^2
and asks the student to enter one of the form 
abs(z-(h+ki)) = r,
using two blanks separated by an equals sign. I would like the student to be able
to enter the answers in either order, which presently doesn't work, but I can 
live with that. The problem seems to work fine otherwise. However, it is 
throwing some errors I haven't been able to figure out. Here is the source; I paste the errors after. Thanks for any insight you can give.

-Dave

##DESCRIPTION
##  Find a complex equation for a line in the plane.
##ENDDESCRIPTION

##KEYWORDS("complex", "circle")

## DBsubject("Complex analysis")
## DBchapter("Elementary functions")
## DBsection("Polynomials and rational functions")
## Date("01/10/2014")
## Author("Dave Rosoff")
## Institution("College of Idaho")
## TitleText1("Geometry")
## EditionText1("1")
## AuthorText1("Hitchman")
## Section1("4.2")
## Problem1("1")

########################################################################

DOCUMENT();      

loadMacros(
   "PGstandard.pl",     # Standard macros for PG language
   "MathObjects.pl",
   "parserMultiAnswer.pl",
   "PGML.pl",
   #"source.pl",        # allows code to be displayed on certain sites.
   #"PGcourse.pl",      # Customization file for the course
);

# Print problem number and point value (weight) for the problem
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1;

##############################################################
#
#  Setup
#
#

Context("Numeric");
Context()->variables->are(x=>"Real",y=>"Real");
$h = non_zero_random(-10,10);
$k = non_zero_random(-10,10);
$r = non_zero_random(1,7); # circle with center (h,k) and radius r

$rsq = Formula("$r^2");
$circx = Formula("x - $h")->reduce;
$circy = Formula("y - $k")->reduce; # for nice displaying

Context("Complex");

$center = Complex($h,$k); 

$circz = Formula("abs(z - ($center))");

$multians = MultiAnswer($circz, $r)->with(
  checkTypes => 0,
  singleResult => 1,
  checker => sub {
      my ( $correct, $student, $self ) = @_;
      my ( $f1stu, $f2stu ) = @{$student};
      my ( $f1, $f2 ) = @{$correct};
      if ( (( (ref($f1) eq ref($f1stu)) && ($f1 == $f1stu) ) && ( (ref($f2) eq ref($f2stu)) && ($f2 == $f2stu) )) ||
           (( (ref($f1) eq ref($f2stu)) && ($f1 == $f2stu) ) && ( (ref($f2) eq ref($f1stu)) && ($f2 == $f1stu) )) ) {
          return [1,1];
      } else {
          if (( (ref($f1) eq ref($f1stu)) && ($f1 == $f1stu) ) || ( (ref($f2) eq ref($f1stu)) && ($f2 == $f1stu) )) {
              return [1,0];
          } elsif (( (ref($f1) eq ref($f2stu)) && ($f1 == $f2stu) ) || ( (ref($f2) eq ref($f2stu)) && ($f2 == $f2stu) )) {
              return [0,1];
          } else {
              return [0,0];
          }
      }
  }
);

##############################################################
#
#  Text
#
#

BEGIN_PGML

Find the complex equation of the circle [`([$circx])^2 + ([$circy])^2 = [$rsq]`]. Type [`\mathrm{abs}(z)`] for [`\lvert z \rvert`].

[________]{$multians} = [________]{$multians} 
END_PGML

##############################################################
#
#  Answers
#
#

#ANS($multians->cmp);

ENDDOCUMENT();

This throws the following errors:

Warning messages

  • Use of uninitialized value $ans_name in hash element at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1204
  • Use of uninitialized value in scalar assignment at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1453
  • Use of uninitialized value $ans_name in hash element at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1208
  • Use of uninitialized value $ans_name in hash element at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1209
  • Use of uninitialized value $ans_name in concatenation (.) or string at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1226
  • Use of uninitialized value $ans_name in hash element at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1246
  • Use of uninitialized value $_ in hash element at /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm line 225.
  • Use of uninitialized value $name in hash element at /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm line 262.
  • Use of uninitialized value $_ in concatenation (.) or string at /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm line 1637.

In reply to Dave Rosoff

Re: MultiAnswer with Complex context and PGML

by Dave Rosoff -
I have done a little more investigation and the sample problem here behaves the same way.

https://courses1.webwork.maa.org/webwork2/cervone_course/PGML-examples/9/

Perhaps an update is interfering with the extended functionality? Either way I think I can fix this by not using PGML, but other people who like the style of PGML and the convenience of MultiAnswer might appreciate knowing the workaround. Thanks again.

Dave
In reply to Dave Rosoff

Re: MultiAnswer with Complex context and PGML

by Davide Cervone -
It turns out that changes to the code that operates behind the scenes to handle ANS() and the various ans_rule() macros have made a slight change to how these work. In the past, you could use ANS() and ans_rule() in any order (so ANS() could come before ans_rule() if you wanted), but that is no longer true; ans_rule() must come first.

Unfortunately, PGML sometimes did them in the opposite order (in particular, this was the case for MultiAnswer objects). I am attaching a modified version of PGML.pl that fixes the problem, and so works properly with the MultiAnswer object.

If you don't have access to replace this in pg/macros, you can still put it in your course's templates/macros directory, and it will be used instead of the system version.

There are a couple of other issues that I will mention in separate messages.
In reply to Davide Cervone

Re: MultiAnswer with Complex context and PGML

by Michael Gage -
Can you give more details about this? I've recently been using ANS() before ans_rule rather routinely and haven't yet noticed an effect.

For example \{ ANS($f->cmp), ans_rule() \} types of constructions.


In reply to Michael Gage

Re: MultiAnswer with Complex context and PGML

by Davide Cervone -
Well, I noticed that the problem reported by the OP was related to the answer rule name, and when I switched the order in PGML.pl. it resolved the problem. I didn't try to track it down further than that. It probably has to do with how MultiAnswer handles its multiple rules in the case where singleResult is true. These are done through named_ans_rule_extension, and perhaps it is something with the extension or named versions that is problematic. I should not have been so quick to jump to the conclusion I did (it was late and I was trying to get the answer out).
In reply to Dave Rosoff

Re: MultiAnswer with Complex context and PGML

by Davide Cervone -
In addition to the problems with PGML.pl, your problem also pointed out another problem, this time with the Complex object. It turns out that the parentheses in your formula abs(z-($center)) don't get retained properly when the center has a negative complex part. This is due to an error in pg/lib/Parser/Complex.pm. I've attached a corrected version, but you will not be able to use it without having access to the server, as this is not a file that you can override on a course-by-course basis.

If you don't have access to modify and restart the server, you could still work around the problem by making a subclass of the Complex object that overrides the two methods that I have changed. If you need to do that, let me know and I'll show you how.

Edit: There was a typo in the attached file. I have fixed it and uploaded a new copy, so the attached file is now correct.
In reply to Dave Rosoff

Re: MultiAnswer with Complex context and PGML

by Davide Cervone -
I have also made a few changes to your problem file to simplify the checker, display the answers better, and make it possible to enter the answers in either order. Here is the modified version:


    ##DESCRIPTION
    ##  Find a complex equation for a line in the plane.
    ##ENDDESCRIPTION
    
    ##KEYWORDS("complex", "circle")
    
    ## DBsubject("Complex analysis")
    ## DBchapter("Elementary functions")
    ## DBsection("Polynomials and rational functions")
    ## Date("01/10/2014")
    ## Author("Dave Rosoff")
    ## Institution("College of Idaho")
    ## TitleText1("Geometry")
    ## EditionText1("1")
    ## AuthorText1("Hitchman")
    ## Section1("4.2")
    ## Problem1("1")
    
    ########################################################################
    
    DOCUMENT();      
    
    loadMacros(
       "PGstandard.pl",     # Standard macros for PG language
       "MathObjects.pl",
       "parserMultiAnswer.pl",
       "PGML.pl",
       #"source.pl",        # allows code to be displayed on certain sites.
       #"PGcourse.pl",      # Customization file for the course
    );
    
    # Print problem number and point value (weight) for the problem
    TEXT(beginproblem());
    
    # Show which answers are correct and which ones are incorrect
    $showPartialCorrectAnswers = 1;
    
    ##############################################################
    #
    #  Setup
    #
    #
    
    Context("Numeric");
    Context()->variables->are(x=>"Real",y=>"Real");
    $h = non_zero_random(-10,10);
    $k = non_zero_random(-10,10);
    $r = non_zero_random(1,7); # circle with center (h,k) and radius r
    
    $rsq = Formula("$r^2");
    $circx = Formula("x - $h")->reduce;
    $circy = Formula("y - $k")->reduce; # for nice displaying
    
    Context("Complex");
    
    $center = Complex($h,$k);
    
    $circz = Formula("abs(z - ($center))");
    
    $multians = MultiAnswer($circz, Formula($r))->with(
      checkTypes => 0,
      singleResult => 1,
      separator => " = ",
      tex_separator => " = ",
      checker => sub {
          my ($correct,$student,$self) = @_;
          my ($f1stu,$f2stu) = @{$student};
          my ($f1,$f2) = @{$correct};
          return (1,1) if ($f1 == $f1stu && $f2 == $f2stu) || ($f1 == $f2stu && $f2 == $f1stu);
          return (1,0) if $f1 == $f1stu || $f1 == $f2stu;
          return (0,1) if $f2 == $f1stu || $f2 == $f2stu;
          return (0,0);
      }
    );
    
    ##############################################################
    #
    #  Text
    #
    #
    
    BEGIN_PGML
    Find the complex equation of the circle [`([$circx])^2 + ([$circy])^2 = [$rsq]`].
    Type [`\mathrm{abs}(z)`] for [`\lvert z \rvert`].
    
    [________]{$multians} = [________]{$multians} 
    END_PGML
    
    ##############################################################
    #
    #  Answers
    #
    #
    
    #ANS($multians->cmp);
    
    ENDDOCUMENT();

Here, the changes are the following:

  1. Use Formula($r) rather than $r so that the student can enter a formula in either one. Without this, the student must answer a number (not a formula) in the second entry. Note that checkTypes => 0 only means that the type doesn't have to be exactly the same type, but can be a compatible one (according to the answer's typeMatch() method). For a Real, the typeMatch() does not allow a Formula, so even with the checkType => 0, you would get a warning about incompatible types, and your checker would not run.

Add separator => " = ", tex_separator => " = " to the MultiAnswer object. Since you are using singleResult => 1 this will change the default separator from a semi-colon to an equal sign, which makes the result look better.

Simplify the logic of the checker. Since you are only doing equality checks (not calling any methods), you don't have to do type checks on the objects. You know that the types will be compatible for equality checking (since that is what typeMatch() checks for you, and your code only runs when the student answers pass that check).

Hope that helps.

In reply to Davide Cervone

Re: MultiAnswer with Complex context and PGML

by Davide Cervone -
One final note: Students can type |z| to get absolute values. They don't have to use abs() (though they can).
In reply to Davide Cervone

Re: MultiAnswer with Complex context and PGML

by Dave Rosoff -
Hi Davide,

Thanks so much for your comprehensive and very helpful answers! I also appreciate the coding tips. I can make these changes on our server and will report back after I do so.

Dave