## PREP 2014 Question Authoring - Archived

### force anser to be number

by Joel Trussell -
Number of replies: 12
I know I've seen this but I can't find it now. How do I force the student to enter a number and not a formula. I tried using
$ans = Compute($z1*$z2); with ANS($z3->cmp() );

but that allow the student to enter the value of z1/value of z2

I want the student to compute the quotient and enter that number.

I can disable the * operation but this gives a not very useful error message
"Can't use '*' in this context"

I read the mathObjects page again
but this didn't help.

How do I force the student's answer to be a complex number? and get the msg
"Your answer is not a number (it seems to be a formula returning a number)"
when she enters a formula?

### Re: force anser to be number

by Chrissy Safranski -
I'm not entirely clear on what you're trying to do, and I've never written a problem with complex numbers, but I have an idea anyway.  (I don't let lack of knowledge stop me!)

Note that implied multiplication will also be disabled if you disable * so the expression "$a +$b i" will generate the "Can't use '*' in this context" message due to the multiplication between $b and i. Allowing complex numbers to be entered but not expressions involving them is more complicated than just disabling *. That is why there are contexts like "LimitedComplex" for doing this. In reply to Joel Trussell ### Re: force anser to be number by Davide Cervone - There are some specialized contexts for the situations where you don't want to allow expressions. These are the "Limited" contexts, like "LimitedNumeric", "LimitedComplex", "LimitedVector", "LimitedPolynomial", and so on. These handle disabling the operators, or in some cases just limiting them, and producing error messages for them. In your case, you could use  loadMacros("contextLimitedNumeric.pl"); Context("LimitedNumeric");  to enable the limited context in which only numbers (not formulas) can be entered. Use  Context("LimitedNumeric-List")  if you want to allow commas so that lists of numbers can be entered. There is also  Context("LimitedNumeric-Fraction");  that allows division of integers, and  Context("LimitedNumeric-StrictFraction");  that allows fractions but not decimal numbers (though the contextFraction.pl file is probably better for doing that sort of thing -- LimitedNumeric-StrictFraction was a predecessor to the more fully featured Fraction context). If you are using complex numbers, there are several limited complex contexts. You can require the complex number to be in polar form for example, or force it to be entered in cartesian form. See the POD documentation for contextLimitedComplex.pl for more details. If you want to change the error message, you can do  Context("LimitedNumeric"); Context()->{error}{msg}{"Can't use '%s' in this context"} = "You must enter a number, not an expression or list";  to replace all the "Can't use ..." messages at once. Alter the message to your tastes. In reply to Davide Cervone ### Re: force anser to be number by Joel Trussell - OK - I understand the disallow '*' screwing up the 3j since it is implied and the answer checker will barf. So the limited context looks promising. However, when I use it with my problem - included below - there appears to be a conflict with the ($complexJ) ? "contextComplexJ.pl"  : "",
that I use with all of our engineering problems that allows either i or j for sqrt(-1).
2ND - WHY wouldn't I use LimitedComplex instead of LimitedNumeric?

Finally, I'm still having problems understanding exactly when variables are declared as MathObjects. It seems $a = 2;$b = 3; $c =$a+$b; yields no mathobject but$c = Compute($a+$b) does. In the case of complex numbers, (in a complex context) what about  $a = 2+2j;$b = 3+3j; $c =$a+$b; ? Since the variables are complex are they automatically mathobjects? Thanks for the help and patience. DOCUMENT() ; loadMacros( "PGstandard.pl", "MathObjects.pl", "PGgraphmacros.pl", ($complexJ) ? "contextComplexJ.pl"  : "",
#"contextLimitedNumeric.pl",
"contextLimitedComplex.pl",
"PGcourse.pl"
) ;
#sub i ();  #make i act like the imaginary unit.
$showPartialCorrectAnswers=1; TEXT(beginproblem()) ; #Context("LimitedComplex"); Context("Complex"); # original context with i and j for sqrt(-1) #Context("LimitedNumeric"); # attempt to disallow expressions$z1 =random(1,7,1) + non_zero_random(-7,7,1)*j;
$z2 = random(-7,-1,1) + non_zero_random(-7,7,1)*j;$graph = init_graph(-8, -8, 8, 8,grid=>[16,16],axes=>[0,0]);
$point1 = closed_circle(Re($z1), Im($z1), 'red');$point2 = closed_circle(Re($z2), Im($z2), 'blue');
$graph->stamps($point1,$point2);$z3 = Compute($z1*$z2);
# Context("LimitedComplex");  # putting here after computation still allows expression

#Context()->operators->undefine("*");  # disallow computation in answer
#Context()->{error}{msg}{"Can't use '*' in this context"}
#  = "Enter a complex number, not a formula";
BEGIN_TEXT
$BBOLD Multiplication of complex numbers.$EBOLD
$PAR The product of two complex numbers, $$z_1 = x_1 + j y_1$$ and $$z_2 = x_2 + j y_2$$ is defined by $$z_1 z_2 = (x_1 x_2 - y_1 y_2) + j (x_1 y_2 + x_2 y_1)$$, where the usual rules of multiplication of numbers apply and make use of the fact that $$j^2=-1$$$PAR
Consider the two complex numbers $$z_1 = z1$$ and $$z_2 = z2$$
$PAR Compute the product $$z_1 z_2 =$$\{ans_rule(10)\}.$PAR

<iframe width="420" height="315" src="//www.youtube.com/embed/cWn6g8Qqvs4" frameborder="0" allowfullscreen></iframe>

$BR If the video does not work, \{ htmlLink("http://youtu.be/cWn6g8Qqvs4", "click here to go to YouTube directly.") \} END_TEXT ANS($z3->cmp() );

ENDDOCUMENT() ;

### Re: force anser to be number

by Davide Cervone -
WHY wouldn't I use LimitedComplex instead of LimitedNumeric?

For complex numbers you would use LimitedComplex, not LimitedNumeric. One of your questions asked about numbers like 3*7, and in that case, you would use LimitedNumeric. Also, the title of the question is about numbers.

there appears to be a conflict with the ($complexJ) ? "contextComplexJ.pl" : "" Are you using the newest version of contextComplexJ.pl from the develop branch, or the older one in the master branch? It has been completely rewritten. The older one only operates on the standard Complex context, not other contexts. The new one can be enabled in any context with complex numbers. If you are using the new one, you can add context::ComplexJ->Enable();  after setting the context in order to enable the complex-j functionality. (See example below.) Note that, since you are using j explicitly in your problem, there is no point in conditionally loading contextComplexJ.pl, as the problem will fail without it. The new contextComplexJ.pl is set up to allow you to set your course default in PGcourse.pl without having to modify the problem files themselves, but you have to write your problems using i notation originally in order to allow PGcourse.pl to have proper control over the results. Unfortunately, the LimitedComplex context isn't included in the ones that contextComplexJ.pl modifies automatically, so you need to do that by hand with the command above. Here is one example:  loadMacros( "PGstandard.pl", "MathObjects.pl", "PGgraphmacros.pl", "contextComplexJ.pl", "contextLimitedComplex.pl", "PGcourse.pl", ) ;$showPartialCorrectAnswers=1;
TEXT(beginproblem());

Context("Complex");

$z1 =random(1,7,1) + non_zero_random(-7,7,1)*j;$z2 = random(-7,-1,1) + non_zero_random(-7,7,1)*j;

Context("LimitedComplex-cartesian");
context::ComplexJ->Enable();

$z3 = Compute($z1*$z2); Context()->texStrings; BEGIN_TEXT$BBOLD Multiplication of  complex numbers. $EBOLD$PAR
The product of two complex numbers, $$z_1 = x_1 + j y_1$$
and $$z_2 = x_2 + j y_2$$ is defined by
$$z_1 z_2 = (x_1 x_2 - y_1 y_2) + j (x_1 y_2 + x_2 y_1)$$,
where the usual rules of multiplication of numbers apply and
make use of the fact that $$j^2=-1$$.
$PAR Consider the two complex numbers $$z_1 = z1$$ and $$z_2 = z2$$.$PAR
Compute the product $$z_1 z_2 =$$\{ans_rule(10)\}.
END_TEXT
Context()->normalStrings;

ANS($z3->cmp);  Here, $z1 and $z2 are defined in the standard Complex context, where you can do computation as normal. $z3 is created in the LimitedComplex-cartesian context (Compute() will force the value it is passed to be in the current context), where operations between complex numbers are not allowed (but operations can be used within the real and imaginary parts; use LimitedComplex-cartesian-strict if you want to allow only constants). Note that since $z1*$z2 is performed before being passed to Compute(), there is no problem performing this multiplication.

The error messages from the LimitexComplex contexts will use i rather than j (e.g., "Your answer should be if the form a+bi"), so you may want to use Context()->{error}{msg} to remap those errors to use j instead.

I also added Context()->texStrings; and Context()->normalStrings around your BEGIN_TEXT/END_TEXT block to avoid extra parentheses around the complex numbers when they are inserted into the text.

You should also note that your <if ram> is going to cause problems when students try to get a hardcopy of your homework set. It is never a good idea to insert raw HTML into a problem for that reason. Also, as you write problems, you should always test them in hardcopy to make sure nothing goes wrong (it is easy for the output to work on screen but not in hardcopy).

### Re: force anser to be number

by Joel Trussell -
Are you using the newest version of contextComplexJ.pl from the develop branch, or the older one in the master branch?

How do I know? or better how do I find out?

I copied the revised problem to a new problem, but the error message
Warning -- there may be something wrong with this question. Please inform your instructor including the warning messages below.

### Warning messages

• Constant 'j' already exists at [PG]/lib/Value/Context/Data.pm line 89
• Constant 'j' already exists at [PG]/lib/Value/Context/Data.pm line 89

This may be related to your question on versions.

We're trying to develop our Webwork problems here for use in engineering. I'm having difficulty keeping my various versions and patches consistent. For example, learning to use
($complexJ) ? "contextComplexJ.pl" : "", then inserting the load macro in PGcourse.pl, etc. Given that we want the text and the students to use j but it is OK for them to use i for sqrt(-1), what is the proper macro load. lastly, I understand I can change contexts in the middle of a problem. I don't understand the double call Context("LimitedComplex-cartesian"); context::ComplexJ->Enable(); This would appear to disallow the form rho *exp(j*theta) which is fine for this problem the second line does what? I thought complexJ was a context and this looks like setting two contexts at one time.  Thanks In reply to Joel Trussell ### Re: force anser to be number by Davide Cervone - It seems$a = 2; $b = 3;$c = $a+$b; yields no mathobject but $c = Compute($a+$b) does. In the case of complex numbers, (in a complex context) what about$a = 2+2j; $b = 3+3j;$c = $a+$b; ? Since the variables are complex are they automatically mathobjects?

Yes, you are correct, here. Perl has built-in support for real numbers, and so $a = 2 produces a normal Perl real number. Computations with this will also produce normal Perl reals, so $b = $a + 3 will be a Perl real, not a MathObject. To create a MathObject real, you would do $a = Real(2). Then $a will be a MathObject real, and any computations with it will produce MathObject reals as well. That is, $b = $a + 3 will cause $b to be a MathObject real equivalent to $b = Real(5). Note that Perl reals are promoted to MathObject reals when used in expressions including MathObjects, so you don't have to do $b = $a + Real(5) for example. Perl does not have built-in support for complex numbers, so when you use complex numbers, they are always MathObject complex numbers. The reason $a = 2+3*j produces a MathObject complex is that j is set up to produce the MathObject complex number Complex(0,1). Just like with MathObject reals, when MathObject complex numbers are used in expressions with perl reals, the perl reals are promoted to MathObjects. So the result of 2+3*j is a MathObject complex number because 3*j is a MathObject complex (since j is), and so when 2 is added to that, it produces a MathObject complex as well.

I hope that clarifies the situation.

### Re: force anser to be number

by Davide Cervone -
I assume that
    I tried using
$ans = Compute($z1*$z2); with ANS($z3->cmp() );

really means
    $ans = Compute($z1*$z2); ANS($ans->cmp);

(with $ans rather than $z3).

In any case, note that if $z1 and $z2 are MathObject Complex objects, then there is no need for the Compute(), and you can just do

    $ans =$z1 * $z2; ANS($ans->cmp);