PREP 2014 Question Authoring - Archived

Answer checkers with Context("LimitedComplex")

Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
Number of replies: 10
For simple calculations of complex numbers, such as complex conjugation, I want the students to enter 3 + 2i instead of conj(3-2i) but I can't figure out how to use LimitedComplex as a context.

If I put it before I calculate the answers, then it won't let me use conj to calculate the answers. (error is :
Function 'conj' is not allowed in this context; see position 1 of formula at line 53 of (eval 22397) Died within main::Complex called at line 53 of (eval 22397)

)

If I put the context after my calculations by before checking the answers, then
WebWork allows conj(3-2i) as an answer but simply evaluates it and displays the
student's answer as 3 + 2i.

In this particular problem I can 'fix it' by specifically restricting
the use of conj in the context, but I would like to know how to use
LimitedComplex correctly.

Thanks,

## DESCRIPTION
## Complex Variables
## ENDDESCRIPTION

## KEYWORDS('Complex')
## Tagged by mewaggoner

## Date('3Jul2014')
## Author('Murphy Waggoner')
## Institution('Simpson')


DOCUMENT(); # This should be the first executable line in the problem.

######################################
# Preamble

#"PGchoicemacros.pl",
#"PGanswermacros.pl",

loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"MathObjects.pl",
"PGauxiliaryFunctions.pl",
"PGcomplexmacros.pl",
"unionLists.pl",
"contextLimitedComplex.pl"
);


TEXT(beginproblem());

######################################
# Setup
# if I use Context("LimitedComplex"); here the question won't compile
Context("Complex");

# create four complex numbers
$a = Complex( non_zero_random( -5, 5, 1 ), random( 1, 10, 1 ));
$b = Complex( non_zero_random( -5, 5, 1 ), random( -10, -1, 1 ));
$c = Complex( 0, non_zero_random( -5, 5, 1 ));
$d = Complex( non_zero_random( -5, 5, 1 ), 0);

# Create four real numbers
$e = Real(non_zero_random(-5, 5, 1));
$f = Real(random(3, 7, 2));
$g = Real(non_zero_random(-5, 5, 1));
$h = Real(random(0, 9, 1));



# Create a list with the answers for checking later
$answer[0] = Complex("conj($a)");
$answer[1] = Complex("conj($b)");
$answer[2] = Complex("conj($c)");
$answer[3] = Complex("conj($d)");
$answer[4] = Complex("conj($e + (1 - sqrt($f) ) i)");
$answer[5] = Complex("conj($g* i + $h)");
$num_ans = @answer;

# If I put Context("LimitedComplex"); here the student can still
# get the answer right by entering conj(a + bi)
Context()->texStrings;
BEGIN_TEXT
The complex conjugate of a number \(z = a + bi\) is written with a bar over it and is \(\overline{z} = \overline{a + bi} = a - bi\).

$PAR

Find the complex conjugate of each of these numbers. $BR


\{ BeginList('OL',type=>'a') \}

$ITEM \( \overline{$a} = \) \{ans_rule(20)\}
$ITEMSEP
$ITEM \( \overline{$b} = \) \{ans_rule(20)\}
$ITEMSEP
$ITEM \( \overline{$c} = \) \{ans_rule(20)\}
$ITEMSEP
$ITEM \( \overline{$d} = \) \{ans_rule(20)\}
$ITEMSEP
$ITEM \( \overline{ $e + \left(1 - \sqrt{$f}\right)i} = \) \{ans_rule(20)\}
$ITEMSEP
$ITEM \( \overline{$g i + $h} = \) \{ans_rule(20)\}



\{ EndList('OL') \}

END_TEXT

######################################
# End game

# Don't let the students enter complex functions
# Context()->functions->disable('conj');

#Checking solutions

for ( $n = 0; $n <= $num_ans-1; $n++ )
{
ANS($answer[$n]->cmp);
}

#Show the students which answers were correct (...= 1)
$showPartialCorrectAnswers = 1;

######################################
# Done

ENDDOCUMENT(); # This should be the last executable line in the problem.



In reply to Murphy Waggoner

Re: Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
Using cplx_cmp and mode=>'strict' seems to do what I want, but shouldn't I be using cmp instead?

This is a different problem than above (and still being developed.)

DOCUMENT(); # This should be the first executable line in the problem.

loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"MathObjects.pl",
"PGanswermacros.pl",
"PGauxiliaryFunctions.pl",
"PGcomplexmacros.pl",
"unionLists.pl"
);

TEXT(beginproblem());

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

Context("Complex");

# create random variables
$a = non_zero_random( 11, 70, 7 );
$b = non_zero_random( 11, 70, 11 );
$c = non_zero_random( 11, 70, 5);

# Calculate the answers
for ( $n = 0; $n <= 9; $n++ )
{
$answer[$n] = (new Complex(0,1) )**$n;
}



BEGIN_TEXT
Calculate the following:$PAR
(a) \(i^0\ =\) \{ans_rule(5)\} $PAR
(b) \(i^1 =\) \{ans_rule(5)\} $PAR
(c) \(i^2\ =\) \{ans_rule(5)\} $PAR
(d) \(i^3\ =\) \{ans_rule(5)\} $PAR
(e) \(i^4\ =\) \{ans_rule(5)\} $PAR
(f) \(i^5\ =\) \{ans_rule(5)\} $PAR
(g) \(i^6\ =\) \{ans_rule(5)\} $PAR
(h) \(i^7\ =\) \{ans_rule(5)\} $PAR
(i) \(i^8\ =\) \{ans_rule(5)\} $PAR
(j) \(i^9\ =\) \{ans_rule(5)\} $PAR
END_TEXT

# Check answers
# Use cplx_cmp and mode => 'strict' so they can't enter things like i^3

for ( $n = 0; $n <= 9; $n++ )
{
ANS(cplx_cmp( $answer[$n], mode=>'strict' ) );
}

# ANS($answer[$n]->cmp);


$showPartialCorrectAnswers = 1;

ENDDOCUMENT(); # This should be the last executable line in the problem.


In reply to Murphy Waggoner

Re: Answer checkers with Context("LimitedComplex")

by Davide Cervone -
Here are the issues: when you use Context("LimitedComplex") all your computations are done in that context, so you are restricted to its limitations just as a student is. One reason for this is so that the correct answer that you give for the student will actually be something the student can type. Without this, for example, your
    $answer[0] = Complex("conj($a)");
would make the correct answer show as conj(3+2i), which the student could not type. (Remember that Compute() not only computes the value, but also sets the correct answer to be the string you originally used to get the answer.)

The second issue is that adding

    Context("LimitedComplex");
does not affect any existing values, so all the numbers you already created are still in the Complex context. Remember that answers are checked using the context where the correct answer was created (not the currently active context), so switching to LimtedComplex but using ANS() with a value in the Complex context doesn't use the LimitedComplex context. That's why students can still enter conj() in their answers.

So if you need to do computation that the student won't be able to do, do that in Context("Complex") as you are, but you need to move your results from the Complex to the LimitedComplex context. One way to do that is

    Context("Complex");
    $a = Complex(non_zero_random(-5,5,1), random(1,10,1));
    $z = conj($a);
    Context("LimitedComplex");
    $answer = Compute($z->string);
Here you do the computations before setting LimtedComplex, and then call Compute() again to re-parse the answer in the new context.
In reply to Davide Cervone

Re: Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
Which approach ((a) cplx_cmp with strict mode or (b) cmp with revisions you suggest above) would you recommend? Personally I like the code to be clean, and approach (a) is cleaner, but are there other issues that make approach (b) better?

Thanks.

(I'm amused that the (h) got converted to a heart when the code was put into Moodle.)
In reply to Murphy Waggoner

Re: Answer checkers with Context("LimitedComplex")

by Davide Cervone -
I prefer (b) because the cplx_cmp code is one of the last remaining answer checkers that hasn't been converted over to use MathObjects (I thought I had converted it at one point, but apparently not). That means the error messages will not be consistent, and some aspects of syntax will be different (for instance, you can't use |...| for complex norm, or sin^2(z) for the square of the sine of z, etc).

There may also be some issues mixing MathObjects with PGcomplexmacros.pl because both try to define the value if i in your perl code. When MathObjects.pl is loaded, i is defined to be the i from the current Context, and I think that cplx_cmp evaluates the student answer by converting the student's answer to a perl string and evaluating that. That means it will return a MathObject Complex rather than a Math::Complex object (what PGcomplexmacros.pl expects). So that may be a problem as well.
In reply to Davide Cervone

Re: Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
I've been using the LimitedComplex option. It seems to work fine except today I noticed a little quirk that I think I'll warn the students about. It accepted 2 + i but not i + 2. That seems a little picky, but I don't actually used this mode very often, so it is not a big deal and the students can work with it (the error message is pretty clear about what they need to do). In the first few sections of the book, I want to know they can simplify to a + bi, but later when the problems are more complex it is not as important.
In reply to Murphy Waggoner

Re: Answer checkers with Context("LimitedComplex")

by Davide Cervone -
I don't see anything in the LimitedComplex code that would prevent i+2 from working. Can you post a minimal example that shows the problem?

The following example seems to accept both:

DOCUMENT();

loadMacros(
  "PGstandard.pl",
  "contextLimitedComplex.pl"
);

Context("LimitedComplex");

$z = 2+i;

Context()->texStrings;
BEGIN_TEXT
\($z\) = \{$z->ans_rule\}
END_TEXT
Context()->normalStrings();

ANS($z->cmp);

ENDDOCUMENT();
In reply to Davide Cervone

Re: Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
I think I have answered the question about which of LimitedComplex or cplx_cmp is better - there are too many problems with cplx_cmp. I would document them for you if you wish, but for my sanity I have to move forward.

But.....I am having problems with subtraction of complex numbers. Below is the code and attached is what I see. I created a function of the form
f(z) = z^2 + 2z - a

Where a is a complex number with non-zero real and imaginary parts. However
the function gets displayed and evaluated
as f(z) = z^2 + 2z - Re(a) + Im(a)i.

For example, in the image I attached, a = 5 - 3i and so the function should be

f(z) = z^2 + 2z - 5 + 3i

but it is written and evaluated as

f(z) = z^2 + 2z - 5 - 3i

Now, I guess I could have been staring at this way too long, and I
am fully prepared for someone to point out a silly error of my own
instead of WeBWork.

DOCUMENT(); # This should be the first executable line in the problem.

#################################
#Preamble

loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"MathObjects.pl",
"PGcomplexmacros.pl",
"PGanswermacros.pl"
);

TEXT(beginproblem);

################################################
#
# The setup
#

# Set context to Complex for the calculations, but change it to LimitedComplex
# later to make the students simplify the results
Context("Complex");

$z = Complex(non_zero_random(-3,3,1), non_zero_random(-3,3,1));
$a = Complex(non_zero_random(-5,5,1), non_zero_random(-5,5,1));

$f = Formula("(z)^2 + 2*(z) - ($a)");

$ans = $f->eval(z=>$z);

# Convert the answer to LimitedComplex context
# so that the students have to simplify their answer.

Context("LimitedComplex");
$simple_ans= Compute($ans->string);


######################################################################
#
# The problem text
#

Context()->texStrings;
BEGIN_TEXT


$a$BR
Suppose \(f(z) =$f\).
$BR
$BR
Calulate and simplify: \(f($z)\) = \{ans_rule(20)\}.

END_TEXT
Context()->normalStrings;

######################################################################
# End game

# Make the error message something easier for the students to understand
# especially since they haven't seen e^(ai) yet

Context()->{error}{msg}
{"Exponentials can only be of the form 'e^(ai)' in this context"}
= "You must enter a number in the form a + bi";
Context()->{error}{msg}
{"The constant 'i' may appear only once in your formula"}
= "You must enter a number in the form a + bi";

#
# Check the answer


ANS($simple_ans->cmp );

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

ENDDOCUMENT(); # This should be the last executable line in the problem.

Attachment New_Picture_1_.jpg
In reply to Murphy Waggoner

Re: Answer checkers with Context("LimitedComplex")

by Davide Cervone -
The correct answer here actually is -14+9i. When z = -2-3i, z^2 = -5+12i, so z^2+2z = -9+6i, and z^2+2z-a = -14+9i.

The main problem that I see is that the parentheses are missing from the statement of f(z), which should be z^2+2z-(5-3i). This was a bug in MathObjects that was corrected about 6 months ago, so to fix that, you will need to update your copy of PG.
In reply to Davide Cervone

Re: Answer checkers with Context("LimitedComplex")

by Murphy Waggoner -
I have been in contact with our system administrator about updating PG. He's on vacation and will be able to get to it when he gets back next week. Thanks.