I thought it might be possible to add 'constants' rather than 'strings' to the context, which worked except for the fact that the answer preview shows up using strings while what is entered shows up as decimals (try the code below to see what I mean). What concerns me about the code below is that it appears that the 'reduceConstants' flag is being ignored.

Best regards,

Paul Pearson

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

DOCUMENT();

loadMacros(

"PGstandard.pl",

"MathObjects.pl",

"PGcourse.pl",

);

TEXT(beginproblem());

$showPartialCorrectAnswers = 1;

Context("Interval");

Context()->constants->add('alpha'=>Real(pi/2),'beta'=>Real(2.236213));

Context()->flags->set(

reduceConstants => 0,

reduceConstantFunctions => 0,

);

Context()->constants->set( alpha => {keepName => 1},beta => {keepName => 1});

$answer = Compute("{alpha,beta}");

Context()->texStrings;

BEGIN_TEXT

Using set notation, what is the set of the first two letters of the

Greek alphabet?

\{ ans_rule(40) \}

END_TEXT

Context()->normalStrings;

ANS( $answer->cmp(requireParenMatch => 1) );

ENDDOCUMENT();

`keepName`

and `requireParenMatch`

values aren't needed, since these are the default, so they do nothing. Also, the `reduceConstants`

settings are not needed, either.
These only affect Formula objects, and (since everything is constant), your answer is a Set, not a Formula, so it is shown numerically (the Set doesn't know how it got its values, only what the values are).
In order to show the student answer symbolically, you need to use `formatStudentAnswers => "parsed"`

so that they are shown as formulas rather than constants.

I'd also recommend adding a `TeX`

rendering to the constants so that their names are displayed better.

My version of the relevant part of Paul's code would be

Context("Interval"); Context()->constants->add( alpha => pi/2, beta => 2.236213, ); Context()->constants->set( alpha => {TeX => '\text{alpha}'}, beta => {TeX => '\text{beta}'}, ); Context()->flags->set(formatStudentAnswer => "parsed"); $answer = Compute("{alpha,beta}"); Context()->texStrings; BEGIN_TEXT Using set notation, what is the set of the first two letters of the Greek alphabet? \{ans_rule(40)\} END_TEXT Context()->normalStrings; ANS($answer->cmp);Note that there are still some subtle issues, here. First, since alpha and beta are treated as numbers, students could enter things like

`{sqrt(alpha^2),beta}`

and still get it right (not that anyone would enter this). Second, you won't get any error message for something like `{alpha+1,beta}`

. Third, if you entered `{alpha,x}`

you'd get an error about your second value not being a number (which is misleading, since you aren't asking the student to enter numbers).
So it works for the most part, but can give some in appropriate error messages.

It is also possible to do as you ask, and use a list of words. But handling the delimiters is a bit tricky (harder than it should be). Here is one approach:

Context()->strings->add( alpha => {caseSensitive => 1}, beta => {caseSensitive => 1}, ); Context()->parens->set("{" => {type => "List", removable => 0}); $answer = Compute("{alpha,beta}"); Context()->texStrings; BEGIN_TEXT Using set notation, what is the set of the first two letters of the Greek alphabet? \{ans_rule(40)\} END_TEXT Context()->normalStrings; ANS($answer->cmp( list_type=>"set", removeParens=>0, implicitList=>0, showParenHints=>1 ));In this case, we add alpha and beta as words (that must be in lower case -- you may want to change that if you don't care about using "Alpha" for "alpha"), and makes

`{`

produce lists, and not be removable. (Usually, if delimiters contain only one element, they are removed, as they are acting like parentheses in that case.)
In the answer checker, we set `removeParens => 0`

to prevent the outermost list parentheses from being removed from the correct answer automatically (list answers usually don't have delimiters), `implicitList => 0`

(so that parentheses aren't added to an answer that is a single word), and `showParenHints => a`

so there is a message about problems with the parentheses.

This prevents the problems we had in Paul's case of using the words as numbers. One slight problem here is that if you enter `{alpha,x}`

you are told that entries in a list must be the same type (we would like it to have called it a set rather than a list), and if you enter just `{x}`

it is marked wrong with no message.

Note that you also can't use unions or other set operations in this case, as you could in Paul's case. (Whereas Paul was using numbers to fake words, we are using lists to fake sets, so you will have to decide which set of problems you are willing to accept).

Hope that helps.

Davide

ANS($answer->cmp( list_type=>"set", removeParens=>0, implicitList=>0, showParenHints=>1, showLengthHints => 0, )->withPostFilter(AnswerHints( sub { my ($correct,$student) = @_; foreach my $name ($student->value) {return 1 if $name == $Country[$I1]} return 0; } => "Close ... but remember ${BBOLD}less than ${DOLLAR}1.25 $EBOLD", sub { my ($correct,$student) = @_; my %used = (); foreach my $name ($student->value) { return 1 if $used{$name}; $used{$name} = 1; } return 0 } => "Countries should only be included once in your set" )) );While checking this, I realized that my approach didn't produce a warning if you used the same country more than once, so I've included a message for that as well.

Hope that does what you want.

Davide

No, AnswerHints won't change the message if there already is one (unless you tell it to). See the answerHints.pl POD documentation for details.Does the postFilter automatically disable / override all messages then?