One thing I would take note of here is how the answer options have been coded in as perl variables, which are then referred to multiple times. If you actually repeat the strings themselves multiple times in the code, there is the opportunity for a typo or something to make them not match.
DOCUMENT(); loadMacros( "PGstandard.pl", "MathObjects.pl", "parserPopUp.pl", "parserOneOf.pl", "PGML.pl", "PGcourse.pl", ); TEXT(beginproblem()); ###################################### $one= "one"; $two = "two"; $three = "three"; $ans = $one; $popup = PopUp(["?", $one, $two, $three], $ans); # It doesn't matter what we put as the "correct answer" here. ###################################### BEGIN_PGML What number is less than three? [@$popup->menu@]* END_PGML ###################################### Context()->strings->add("?"=>{}, $one=>{}, $two=>{}, $three=>{}); ANS(OneOf($one, $two)->cmp()); ENDDOCUMENT();
loadMacros( "PGstandard.pl", "MathObjects.pl", "parserPopUp.pl", "parserOneOf.pl", "PGML.pl", "PGcourse.pl", ); TEXT(beginproblem()); ###################################### @choices = ("?","one", "two", "three"); $popup = PopUp([@choices], $choices[0]); # It doesn't matter which is used as the "correct answer". Context($popup->context); # use the pop-up's context (already has the choices as strings); ###################################### BEGIN_PGML What number is less than three? [@$popup->menu@]* END_PGML ###################################### ANS(OneOf(@choices[1,2])->cmp());
Here, the choices are put into an array, and you can refer to them as
$choices[1]
, $choices[2]
and $choices[3]
, or as a collection, as @choices
. So
PopUp([@choices], $choices[0]);makes a popup with all the choices, using the first one (the question mark) as the correct answer, which (as Alex points out), is never used, since the pop-up's answer checker is not used.
You can refer to a subset of the answers (known as a "slice" of the array) via @slice[1,2]
(note the use of @
rather than $
to refer to the variable, and the use of multiple indices within the square brackets). Thus
OneOf(@choices[1,2])produces a MathObject that takes either of the first two choices ("one" or "two").
Using the array rather than individual variables makes it easier to add and remove entries in the pop-up. For example, if you had five entries in the array and the first 3 were correct, you could use
OneOf(@choices[1..3])You can also mix
..
with commas:
OneOf(@choices[1..3,5])Note that the indices start at 0, which is why having
"?"
as the first entry in the array helps. It means that the indices for the "real" answers are 1, 2, 3, etc.
The final simplification is to set the context to the pop-up's context rather than adding the strings to the current context. The strings have already been added to the context used by the pop-up internally.
parserPopUp.pl
that allows it to be used in PGML more easily. With the new version, you can do
BEGIN_PGML What number is less than three? [_______]{$popup} END_PGMLas you would any other MathObject.