### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -```
loadMcaros("PGauxiliaryFunctions.pl");
$a = random(1,60,1);
$b = random(1,60,1);
($p,$q) = reduce($a,$b);
BEGIN_TEXT
\($p/$q\) = \{ans_rule(10)\}
END_TEXT
ANS(Compute("$p/$q")->cmp);
```

should show the correct answer as a fraction in lowest terms. Note that this doesn't force the student to *enter*it that way. The student could still enter an unreduced fraction, or a decimal version, or a decimal that is "close enough".

Just for future reference, something like `$frac = Formula("$a/$b")`

is a bad idea for several reasons. First, the error messages the student gets will say that it is looking for a formula (rather than a number), which can be misleading. Second, the fraction will be turned into a decimal immediately (Formula usually reduces constant expressions, so that you can do things like `Formula("$n x^($n-1)")`

and have it become `3x^2`

when `$n=3`

rather than `3x^(3-1)`

. This behavior can be turned off by

Context()->flags->set(reduceConstants => 0);There is also a flag for

`reduceConstantFunctions`

that could be set to 0 to prevent reducing things like `sqrt(2)`

if you wanted those to be visible in the answer.
Finally, the `Compute()`

function used above both produces an appropriate MathObject for the result, but also sets it up so that the correct answer is the original formula used to compute it, not the final reduced answer. So even though the result of `Compute("$p/$q")`

is a decimal real, the answer string will still be "`$p/$q`

".

Hope that does what you want.

Davide

### Re: Display reduced fraction in problem and as correct answer

by David Winslow -Davide,

That works great with the added line

if($q==1){$ans=$p;} else {$ans=$p/$q;}

in the event gcd($p,$q)=$q to get $ans which will be the correct answer to display better.

Could you explain your remark about the error message further if Formula("$p/$q") is used when a numerical response is expected? What exactly would the student have to enter to even get an error message? The problem which I am modifying only slightly acutally does have

Context()->flags->set(reduceConstants => 0);

but even if I set it to 1, any constant I enter, correct or incorrect, seems to generate no error messages no matter how compicated the entry is.

Thanks,

David

### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -if ($q==1) {$ans=$p;} else {$ans=$p/$q;}but I'm a little confused by this, because

`$ans`

would then be a decimal representation rather than a fraction, and in the case when `$q`

is equal to one, `$ans = $p/$q`

and `$ans = $p`

both produce identical results (the same Perl real value). Do you mean
if ($q == 1) {$ans = Real($p)} else {$ans = Compute("$p/$q")}or something like that? This makes a MathObject for the answer, and in the one case it is just the integer

`$p`

, and the other the decimal equivalent of `$p/$q`

, but set up to show as a fraction when the correct answer is displayed. Both will be MathObjects of class Real, and `Compute()`

is simply used only to get the correct answer to show as a fraction rather than the decimal. It would be possible to use `Compute("$p")`

for the first as well, but that is unnecessarily redundant.
In terms of the error messages, the answer checkers can give a message when the student enters something that is not the correct type of answer. For example, this happens when the student types a scalar when a vector is expected, and so on. The result of `Formula()`

is considered to be a function of whatever variables are used in it. If it doesn't contain any variables, that is still a function, but just a constant-valued function.

A decimal or fraction is considered to be of type "Number", while a `Formula()`

that evaluates to a number would be of type "Formula returning a Number". (Formulas could also return vectors, or points, or complex numbers, etc.) Error messages generated by the student entering an incorrect type of answer would say the problem was looking for a "Formula returning a Number" rather than just a "Number" if you were to use `Formula()`

incorrectly this way. For example, if the student entered a *list* of numbers, e.g., `2,3`

as the answer, this would produce a message like "Your answer doesn't look like a Formula returning a Number (it looks like a List of Numbers)" or something to that effect. This would mislead the student into thinking that they should enter a formula involving x's or t's or something. You would rather see the message "Your answer doesn't look like a Number (it looks like a List of Numbers)", which is what you would get from `Real($a/$b)`

rather than `Formula("$a/$b")`

.

Worse yet, if the student entered something like `3x`

, they would get *no error message at all*, just an indication that the answer is incorrect. That is because WeBWorK thinks the answer is *supposed* to be a formula, so doesn't complain when the student enters one. If you used a Real instead, the student would get the message "Your answer doesn't look like a Number (it looks like a Formula that returns a Number)", and that could help him or her to identify the problem.

It is usually best to use the correct type of object for the answer you are using rather than something else that just looks the same when printed. There are definitely situations where it can make a difference, and they are not always obvious.

Davide

### Re: Display reduced fraction in problem and as correct answer

by David Winslow -Yes, you are correct. The else should have been followed by something like {$ans="$p/$q"}, or if I followed how $ans was given originally in the problem that I am modeling with no redution of the fraction, I guess I would have used

...else {$ans=Formula("$p/$q")}. Then ANS(Compute("$ans")->cmp) would be used to check the answer.

I now understand your objection to using this. When I was entering possible answers, I never left the realm of constants and therefore no errors were being generated of the type you describe. I guess a reason that the Formula object was used in the original problem is how its output is given and can be displayed. This problem has a solution which is displayed when answers are available and the variable $ans is used in the solution. If $ans=Formula("$p/$q") is used, \($ans\) goes to \(\frac{$p}{$q}\) and has a slighlty better display. If I use $ans="$p/$q", then \($ans\) is still okay for display.

David

### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -`Formula()`

now. When you use `$ans=Formula("$p/$q")`

, then you are correct that `ANS(Compute("$ans")->cmp)`

will now give the correct messages, and that is a reasonable solution, especially if you need to use $ans to produce TeX output, as you do later.The real solution will be to implement an actual Fraction MathObject class.

Davide

### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -Hope this makes things easier for you in the future.

Davide

### Re: Display reduced fraction in problem and as correct answer

by Patti Lamm -I am a bit confused as to how contextFraction works. I have the following:

Context()->flags->set(reduceConstants => 0);

$b=3'

$ans_d = Compute("$b pi/4");

...

Context("Fraction-NoDecimals");

Context()->flags->set(formatStudentAnswer=>'parsed');

ANS(Compute($ans_d)->cmp);

This correctly forces the student to type 3 pi/4 or 3*pi/4 and gives the correct error if the student types 3 pi/12 or 3*pi/12 or 2.35619.

However, the correct answer (not the student answer) that appears is: 2.35619. How do I get the correct answer to appear as 3*pi/4 ?

Thanks.

### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -ANS($ans_d->cmp);rather than

ANS(Compute($ans_d)->cmp);Since

`$ans_d`is already a MathObject (it is the result of a

`Compute()`call), so there is no need to use

`Compute()`again.

One of the side-effects of the `Compute()` function is to set the correct answer string to be exactly what you entered, so it would be "3 pi/4" for `$ans_d`. After the second `ComputeIO`, however, the correct answer will be set to (the string version of) the value you entered, and in this case, the string version of the real number is 2.35619, and so that is what is set as the correct answer.

Leaving out the second `Compute()` should do the trick.

Davide

PS, you don't really need to use the Fraction contexts for this. All you are after is not allowing the student to answer decimal numbers, which can be achieved by

Context("Numeric"); Parser::Number::NoDecimals();This affects whatever context is currently in place.

### Re: Display reduced fraction in problem and as correct answer

by Patti Lamm -### Re: Display reduced fraction in problem and as correct answer

by Patti Lamm -Context("Fraction-NoDecimal")

and in another

Context("Fraction-NoDecimals")

### Re: Display reduced fraction in problem and as correct answer

by Davide Cervone -Davide