I really thought that I had this question working properly, but noticed that when the value of sin($b) is equal to 1/2, this does not get marked correct. And, because of the Fraction-NoDecimals context, 0.5 is not acceptable.
If any other value for $b is chosen, the question works as needed.
DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"AnswerFormatHelp.pl",
"PGML.pl",
"PGcourse.pl",
"contextFraction.pl",
);
TEXT(beginproblem());
###########################
# Setup
Context("Fraction-NoDecimals");
Context()->functions->enable("sqrt");
Context()->functions->disable("SimpleTrig");
# random integer to choose fraction
$n=random(0,7,1);
# Array of 8 angles for PGML
@latexangle=("90^\circ", "60^\circ" ,"45^\circ" ,"30^\circ", "120^\circ" , "135^\circ", "150^\circ", "180^\circ");
# Selecting angle for PGML
$a = $latexangle[$n] ;
# Array of 8 angles for Compute
@angle=(pi/2, pi/3 ,pi/4 ,pi/6, 2*pi/3, 3*pi/4, 5*pi/6, pi);
# Selecting angle for Compute
$b = $angle[$n] ;
$ans=Compute(sin($b));
###########################
# Main text
BEGIN_PGML
Find the exact value of the trigonometric function.
`sin([$a])`
[_______________]{$ans}
END_PGML
ENDDOCUMENT();
Hi James,
Here's my guess of what's happening (caveat: my understanding of Contexts and MathObjects is partial).
The value of $b in this case is given by a MathObject, so that the call to sin($b) is promoted to a MathObject, which has type context::Fraction::Real. My read of this is that the sine function returns a real value, which is being seen in the Fraction context. We then call Compute() on this value, but because it's already a MathObject no further processing is needed.
Interestingly, if we define $ans with $ans = Compute("sin($b)"), the problem throws the error "You are only allowed to enter fractions, not decimal numbers," which I think makes sense: in this case we're passing Compute a string that has the real value of the sine function at $b, and Compute then tries to process it appropriately in our current context.
I don't see a way to avoid this issue: if we accept that sine is fundamentally real-valued, it's hard to restrict it to a fraction context. My work-around would be to define the answers explicitly:
@sines = ( "1/2", "sqrt(3)/2",... );
and then declare $ans = Compute($sines[$n]). I think that would work.
Gavin
Here's my guess of what's happening (caveat: my understanding of Contexts and MathObjects is partial).
The value of $b in this case is given by a MathObject, so that the call to sin($b) is promoted to a MathObject, which has type context::Fraction::Real. My read of this is that the sine function returns a real value, which is being seen in the Fraction context. We then call Compute() on this value, but because it's already a MathObject no further processing is needed.
Interestingly, if we define $ans with $ans = Compute("sin($b)"), the problem throws the error "You are only allowed to enter fractions, not decimal numbers," which I think makes sense: in this case we're passing Compute a string that has the real value of the sine function at $b, and Compute then tries to process it appropriately in our current context.
I don't see a way to avoid this issue: if we accept that sine is fundamentally real-valued, it's hard to restrict it to a fraction context. My work-around would be to define the answers explicitly:
@sines = ( "1/2", "sqrt(3)/2",... );
and then declare $ans = Compute($sines[$n]). I think that would work.
Gavin
I'll add my thoughts on this, which also come with the caveat that I only 50% know what I'm talking about.
First, when I put your code into an editor using my server, and set $n=6 to get the 150 degree version, I get a problem where I can enter "1/2" and it is counted correct. Also when I check to see the "correct answer" I am shown "1/2", not "0.5" as in your screenshot.
I note there is a relevant-looking commit to contextFractions.pl last year. If you try using an up-to-date contextFractions.pl, does it still mark "1/2" as incorrect?
at https://github.com/openwebwork/pg/commit/a4a6bcc2d2da4c64755a27709c059cbcd6628c7c#diff-190eb1352b4108f4952b5d082bc330af.
As I noted, the "correct answer" appears to me as "1/2", not "0.5". If the angle is, say 135 degrees, then the "correct answer" appears to me as 38613965/54608393, which is a fraction close to sqrt(2)/2. The Fraction context upgrades the decimal to some integer fraction very close to the real it was given. Since you already have an array for all the input angles, you may want to make an array for each of the nicer forms of the output values, like Compute("sqrt(2)/2").
Gavin suggests that the value of $b is a MathObject, but I don't believe that is right. I think that $b is a perl real based on the perl constant pi. And then sin($b) is also a perl real. When you use Compute like this, passing it a perl real instead of a string, the parser never looks at it, because the parser looks at strings. So you end up with a math object here that hasn't been vetted against the parser's check to disallow decimals.
For what it's worth, I think pi is a perl constant with a value that is a MathObject. This conclusion is primarily based on my testing, in which I checked the type of the object sin($b) (by printing out ref()); this is where I got the type context::Fraction::Real for sin($b).
Without doing any further testing, I don't think that Compute() is going to care whether the argument is a perl real or perl string, because perl isn't a typed language and so uses the two interchangeably. I think the only question will be whether it's already a MathObject or not, though it's also possible that Compute() is being very sneaky and making a guess as to whether the value being passed in looks like a real or a string.
All that said, if contextFractions.pl changed in the past year it's likely that I don't have the latest version and so could be seeing the same error that James was (we last upgraded WeBWorK sometime last summer).
Gavin
Without doing any further testing, I don't think that Compute() is going to care whether the argument is a perl real or perl string, because perl isn't a typed language and so uses the two interchangeably. I think the only question will be whether it's already a MathObject or not, though it's also possible that Compute() is being very sneaky and making a guess as to whether the value being passed in looks like a real or a string.
All that said, if contextFractions.pl changed in the past year it's likely that I don't have the latest version and so could be seeing the same error that James was (we last upgraded WeBWorK sometime last summer).
Gavin
Gavin and Alex,
Thanks for responding. I ended up trying what Gavin suggested in his first reply and that seems to be working, although it's not my preference. I'd like to not have to enter each correct value in the array and instead have WW do the calculating. It does get the job done, though.
Alex, could you give some guidance to this:
at https://github.com/openwebwork/pg/commit/a4a6bcc2d2da4c64755a27709c059cbcd6628c7c#diff-190eb1352b4108f4952b5d082bc330af.
We are using version 2.12 and I don't believe anything has been updated beyond this. How would I update?
James
Thanks for responding. I ended up trying what Gavin suggested in his first reply and that seems to be working, although it's not my preference. I'd like to not have to enter each correct value in the array and instead have WW do the calculating. It does get the job done, though.
Alex, could you give some guidance to this:
I note there is a relevant-looking commit to contextFractions.pl last year. If you try using an up-to-date contextFractions.pl, does it still mark "1/2" as incorrect?
We are using version 2.12 and I don't believe anything has been updated beyond this. How would I update?
James
Thanks Gavin, what you say makes sense.
James, do you have direct control of your server? If so, version 2.14 should be released soon and you could upgrade to that. Summer is a good time to try an upgrade.
To check if the patch to contextFractions.pl is relevant here, copy the file from the link below and place it into a course's templates/macros/ folder. Then that course will use that version of contextFractions.pl instead of the one housed in the cetnral macros folder on your server. See if the behavior changes with this problem.
Yes,
Just to be clear,
pi
in your PG problem will produce a MathObject Real (just as i
will produce a MathObject Complex or MathObject Vector, depending on the context). It is not part of native perl.Just to be clear,
Compute()
does check if its argument is already a MathObject, and returns (a copy of) the object in that case (it will not be reprised, and so doesn't need to follow the context rules, which only apply to parsing a string). For everything else, it is essentially treated as a string and parsed by the context rules.