WeBWorK Problems

TF context

TF context

by Kenneth Appel -
Number of replies: 14
Davide,
Another item just arose for my wish list. I include it here although it does
not just apply to complex problems.

I used contextTF.pl and, instead of answering with a T or an F, I just
tried a G. My answer was correctly shown as wrong, but I had hoped that
I would have had an error message indicating that I should have put in a T or
an F. No such message came. I wish that there was such a message.
Ken
In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
When I type "G" into a T/F answer in the TF context, I get the message:
    Your answer should be one of F or T
just as I would expect. That is part of the contextString.pl functionality, on which contextTF.pl is based.

Perhaps you aren't really using the TF context? Can you include the code you are using so that I can tell if there is a problem with how you are calling the context?

Davide

PS, I have split this discussion off into a separate one, since it has nothing to do with the compound problems in the other discussion.

In reply to Davide Cervone

Re: contextTF

by Kenneth Appel -
Davide,
I am sending you the code. Please note that I am now working on part 3
and have put an ENDDOCUMENT at the end of part 3. I just move it down as
I proceed. The difficulty is in part 2.
Ken
##DESCRIPTION
## powers extended
##ENDDESCRIPTION
##KEYWORDS('Powers')

## DBsubject('')
## DBchapter('')
## DBsection('')
## Date('')
## Author('')
## Institution('')
## TitleText1('')
## EditionText1('')
## AuthorText1('')
## Section1('')
## Problem1('')

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

DOCUMENT();

loadMacros(
"PGstandard.pl", # Standard macros for PG language
"MathObjects.pl",
"compoundProblem.pl",
"unionLists.pl",
"contextLeadingZero.pl",
"contextTF.pl",
#"source.pl", # allows code to be displayed on certain sites.
#"PGcourse.pl", # Customization file for the course
);

# Print problem number and point value (weight) for the problem
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1;

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

$isProfessor = ($studentLogin eq 'kia' || $studentLogin eq 'professor');

#
# Start a compound problem. See the compoundProblem.pl
# file for more details about the parameters you
# can supply.
#
$cp = new compoundProblem(
parts => 10, # the total number of parts in this problem
totalAnswers => 4, # total answers in all parts combined
parserValues => 1, # make parser objects from student answers
allowReset => $isProfessor, # professors get Reset button for testing
);
$part = $cp->part; # look up the current part

##############################################
#
# Part 1
#

if ($part == 1) {

##############################################
##############################################################
#
# Setup
#
#
Context("LeadingZero");
Context()->flags->set(reduceConstants=>0);
$ans1=1000;
$ans2=20;
$a=random (12,36,4);
$ans3=$a/4;
$b= random(2,6,1);
$ans4=10*$b;
##############################################################
#
# Text
#
#

Context()->texStrings;
BEGIN_TEXT
THIS PROBLEM USES A SYSTEM TO PERMIT PROBLEMS IN WHICH A STUDENT CANNOT SEE
LATER PARTS OF THE PROBLEM UNTIL EARLIER PARTS ARE SATISFACTORILY COMPLETED.
THE SYSTEM IS NOT YET FULLY DEVELOPED AND SEVERAL PEOPLE AT DIFFERENT UNIVERSITIES ARE WORKING ON ELIMINATING THE DIFFICULTIES. THEY EXPECT THAT THE DIFFICULTIES
WILL BE ELIMINATED THIS SUMMER. UNTIL THEN THE PRINCIPAL ANNOYANCE WILL BE THAT
IN LATER PARTS YOU DO NOT HAVE THE OPPORTUNITY TO SUBMIT ANSWERS UNTIL AFTER
BEING TOLD THAT YOU ARE WRONG FOR NOT HAVING SUBMITTING THEN. IF YOU IGNORE THIS
TEMPORARY DIFFICULTY, PROBLEMS OF THIS TYPE WILL BE OTHERWISE CORRECT.
$PAR
The idea of changing units, that is, measuring the same thing using different
units is very important in science.$BR It also presents some ideas
that are very useful in understanding multiplication and division of fractions.
$PAR
First, we will start with a few questions to make sure that you are able to
do such conversions.
$PAR
A packaging plant wants to fill 4000 quarts of milk .$BR
It needs to buy \{ans_rule(3)\} gallons of milk from a dairy farm to do this.
$PAR
Mr. Smith has a five gallon oil container. But he can only buy oil in
quart cans. It will take \{ans_rule(3)\} quarts to fill his oil container.
$PAR
John has $a quarters. He goes to the bank to exchange them for dollar bills.$BR
The bank clerk gives him \{ans_rule(3)\} dollar bills in return.
$PAR
Mary needs dimes for her many stops at parking meters.
She gives the bank clerk $b dollar bills and gets \{ans_rule(3)\} dimes in return.
END_TEXT


Context()->normalStrings;

##############################################################
#
# Answers
#
#
Context("LeadingZero");

ANS(Real($ans1)->cmp );
ANS(Real($ans2)->cmp );
ANS(Real($ans3)->cmp );
ANS(Real($ans4)->cmp );



} # End of Part 1

##############################################
#
# Part 2
#


if ($part == 2) {
Context()->texStrings;
$ans1="F";
$ans2="T";
$ans3="F";
BEGIN_TEXT
Part 2:
$PAR
Now, you should try to understand the pattern of your answers in the first part.
$PAR
For each of the following questions answer
$BR T if the statement is true and
$BR F
if the statement is false.
$PAR
Suppose we have measured something in gallons and we want to find out how many
quarts we have. $BR

We divide the number of gallons by four. [Answer T or F]
\{ans_rule(1)\}
$PAR
Suppose one unit is four times as large (or four times as much) as another
unit. $BR
Then we say that the ratio of the first unit to the second unit is
four.
$BR
More generally, if \(r\) is a number and one unit is \(r\) times as large
as another $BR
then we say that the ratio of the first number to the second
number is \(r\).
$PAR
If a grmph is equal to \(r\) urps and we have 10 urps of shampoo then we have
\(10r\) grmphs of shampoo. \{ans_rule(1)\}
$PAR
If a grmph is equal to \(r\) urps and we have 10 grmphs of shampoo then we have
\(10r\) urps of shampoo. \{ans_rule(1)\}
END_TEXT
Context()->normalStrings;


##############################################################
#
# Answers
#
#
Context("TF");

ANS(str_cmp($ans1));
ANS(str_cmp($ans2));
ANS(str_cmp($ans3));

} # End of Part 2


##############################################
#
# Part 3
#


if ($part == 3) {

Context()->texStrings;
$ans1=2;

$ans2=3;
BEGIN_TEXT
Part 3:
$PAR
If I have 24 eggs then I have \{ans_rule(1)\} dozen eggs.
$PAR
If a grmph is equal to \(r\) urps and I have 3r uprs of shampoo $BR
then I have \{ans_rule(1)\} grmphs of shampoo.


END_TEXT
##############################################################
#
# Answers

Context("LeadingZero");
ANS(Real ($ans1)-> cmp);
ANS(Real ($ans2)-> cmp);
} #end of part 3
ENDDOCUMENT()
##############################################
#
# Part 4
#


if ($part == 4) {

Context()->texStrings;

BEGIN_TEXT
Part 4:
$PAR
=\{ans_rule(4)\}
END_TEXT
##############################################################
#
# Answers

Context("LeadingZero");
ANS( );

} #end of part 4
##############################################
#
# Part 5
#




In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
The problem is that you are using str_cmp() rather than MathObjects, so the TF context never actually comes into play. You should try
    Context("TF");

    ANS(String($ans1)->cmp);
    ANS(String($ans2)->cmp);
    ANS(String($ans3)->cmp);
or better yet, use
    $ans1 = String("F");
originally and then do
    ANS($ans1->cmp);

Note that the traditional answer checkers (like num_cmp(), fun_cmp() and str_cmp()) do not take the current context into account, even when they use MathObjects behind the scenes. In any case, str_cmp() does not use MathObjects at all, so the current context is irrelevant when you use str_cmp.

The contextString.pl file (which is loaded by contextTF.pl) does define string_cmp(), which uses MathObjects and the current context, but looks more like the traditional str_cmp(). You could use that if you prefer.

Finally, as an aside, note that you don't have to use Context()->texStrings and Context()->normalStrings unless you are inserted the value of MathObjects into the BEGIN_TEXT/END_TEXT blocks, which is not true for your problem.

Davide

In reply to Davide Cervone

Re: contextTF

by Kenneth Appel -
Davide,
I tried something that seemed analogous to what you had last shown me and
it did not work. The situation occurs in part3 of the compound problem that had
the TF problem in part 2. Here is the relevant code.

##############################################
#
# Part 3
#


if ($part == 3) {

Context()->texStrings;
$ans1=2;

$ans2=3;
$ans3="sr";
$ans4="t/r";
BEGIN_TEXT
Part 3:
$PAR
If I have 24 eggs then I have \{ans_rule(1)\} dozen eggs.
$PAR
If a grmph is equal to \(r\) urps and I have 3r urps of shampoo $BR
then I have \{ans_rule(1)\} grmphs of shampoo.
$PAR
If a grmph is equal to \(r\) urps and I have \(s\) grmphs of shampoo $BR
then I have \{ans_rule(5)\} urps of shampoo.
$PAR
If a grmph is equal to \(r\) urps and I have \(t\) urps of shampoo $BR
then I have \{ans_rule(5)\} grmphs of shampoo.
END_TEXT
##############################################################
#
# Answers

Context("LeadingZero");
ANS(Real ($ans1)-> cmp);
ANS(Real ($ans2)-> cmp);
Context("String");
ANS(string_cmp($ans3));
ANS(string_cmp($ans4));
} #end of part 3
ENDDOCUMENT()

I tried to use the context String analogously to context TF. I first tried both of
your suggestions for TF but (unless there is an unrelated error causing the
error message) neither worked. The error message was.

String constant 'sr' is not defined in this context at line 6 of (eval 276094) Died within main::String called at line 6 of (eval 276094) from within main::string_cmp called at line 223 of [TMPL]/setteach1/unitchange.pg

Actually, when dealing with a part like this there seems no ideal context.
If I do succeed with any of the contexts I am familiar with, I am sure that I
will at least have to alias rs to sr. Ideally, I would love to see a context
which allows me to define several letters as variables an then work in a version
of numeric or standard numeric. Maybe this is currently possible. Any advice
would be welcomed.
Ken
In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
The problem is that the String context has no predefined strings, so you need to tell it what strings you are expecting to see. (It's not like str_cmp, where everything is allowed.) The reason for this is that the MathObjects parser is supposed to be able to handle strings at the same time as numeric or other expressions, so that you can have problems when a student can answer a number or the string "DNE" when asked for a limit, for example.

See the comments in contextString.pl for how to define strings, or use the parserAutoStrings.pl file to allow strings to be defined automatically when you use them. Now, however, that you will have to put the AutoStrings() call after setting the String context.

Davide
In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
Ideally, I would love to see a context which allows me to define several letters as variables an then work in a version of numeric or standard numeric.

Since your answers are actually formulas rather than strings, that is exactly what you want to do. Again, this is a misuse of string checking, since the answers aren't literal strings, but higher-level objects, in this case, formulas. You correctly realized that you would need to have both rs and sr for answers, but what about r s and s r? Or r*s and s*r? Or r * s and so on? For t/r what about t*(1/r) and (1/r)t?

My point is that using string tests on something other than strings usually is a bad idea.

You are right that what you want is a context with variables r, s, and t and a formula answer. Try:

    Context("Numeric");
    Context()->variables->are(r=>'Real',s=>'Real',t=>'Real');
    ...
    ANS(Formula("rs")->cmp);
    ANS(Formula("t/r")->cmp);

Here, the variables->are() call removes any existing variables (the default x variable) and adds r, s, and t as variables that you can use in your formulas. I think that is what you are looking for.

Davide

In reply to Davide Cervone

Re: contextTF

by Kenneth Appel -
Davide,
The suggestion in your last message exactly satisfied my needs (and did work
for me). Just for my own education I would like to know the difference
between -> and =>. Also, what was the reason that you used r=>'Real' rather
than r=>"Real".

By the way, I could not get the suggestion using parserAutoStrings in your previous message to work. I don't really need it now, but I thought that I had
followed your instructions rather carefully.
Ken
In reply to Kenneth Appel

Re: contextTF

by Kenneth Appel -
Davide,
I now have a working, but not totally satisfactory version of the problem I want. I will give you the code and then ask a couple of questions.


DOCUMENT();

loadMacros(
"PGstandard.pl", # Standard macros for PG language
"MathObjects.pl",
"compoundProblem.pl",
"unionLists.pl",
"contextLeadingZero.pl",
"contextTF.pl",
"parserAutoStrings.pl",
"contextString.pl",
#"source.pl", # allows code to be displayed on certain sites.
#"PGcourse.pl", # Customization file for the course
);

# Print problem number and point value (weight) for the problem
Context()->texStrings;
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1;

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

$isProfessor = ($studentLogin eq 'kia' || $studentLogin eq 'professor');

#
# Start a compound problem. See the compoundProblem.pl
# file for more details about the parameters you
# can supply.
#
$cp = new compoundProblem(
parts => 10, # the total number of parts in this problem
totalAnswers => 4, # total answers in all parts combined
parserValues => 1, # make parser objects from student answers
allowReset => $isProfessor, # professors get Reset button for testing
);
$part = $cp->part; # look up the current part

##############################################
#
# Part 1
#

if ($part == 1) {

##############################################
##############################################################
#
# Setup
#
#
Context("LeadingZero");
Context()->flags->set(reduceConstants=>0);
$ans1=1000;
$ans2=20;
$a=random (12,36,4);
$ans3=$a/4;
$b= random(2,6,1);
$ans4=10*$b;
##############################################################
#
# Text
#
#

Context()->texStrings;
BEGIN_TEXT
THIS PROBLEM USES A SYSTEM TO PERMIT PROBLEMS IN WHICH A STUDENT CANNOT SEE
LATER PARTS OF THE PROBLEM UNTIL EARLIER PARTS ARE SATISFACTORILY COMPLETED.
THE SYSTEM IS NOT YET FULLY DEVELOPED AND SEVERAL PEOPLE AT DIFFERENT UNIVERSITIES ARE WORKING ON ELIMINATING THE DIFFICULTIES. THEY EXPECT
THAT THE DIFFICULTIES
WILL BE ELIMINATED THIS SUMMER. UNTIL THEN THE PRINCIPAL ANNOYANCE WILL BE THAT
IN LATER PARTS YOU DO NOT HAVE THE OPPORTUNITY TO SUBMIT ANSWERS UNTIL AFTER
BEING TOLD THAT YOU ARE WRONG FOR NOT HAVING SUBMITTING THEN. IF YOU IGNORE THIS
TEMPORARY DIFFICULTY, PROBLEMS OF THIS TYPE WILL BE OTHERWISE CORRECT.
$PAR
The idea of changing units, that is, measuring the same thing using different
units is very important in science.$BR It also presents some ideas
that are very useful in understanding multiplication and division of fractions.
$PAR
First, we will start with a few questions to make sure that you are able to
do such conversions.
$PAR
A packaging plant wants to fill 4000 quarts of milk .$BR
It needs to buy \{ans_rule(3)\} gallons of milk from a dairy farm to do this.
$PAR
Mr. Smith has a five gallon oil container. But he can only buy oil in
quart cans. It will take \{ans_rule(3)\} quarts to fill his oil container.
$PAR
John has $a quarters. He goes to the bank to exchange them for dollar bills.$BR
The bank clerk gives him \{ans_rule(3)\} dollar bills in return.
$PAR
Mary needs dimes for her many stops at parking meters.
She gives the bank clerk $b dollar bills and gets \{ans_rule(3)\} dimes in return.
END_TEXT


Context()->normalStrings;

##############################################################
#
# Answers
#
#
Context("LeadingZero");

ANS(Real($ans1)->cmp );
ANS(Real($ans2)->cmp );
ANS(Real($ans3)->cmp );
ANS(Real($ans4)->cmp );



} # End of Part 1

##############################################
#
# Part 2
#


if ($part == 2) {
Context()->texStrings; #Note the context here
$ans1=String("F");
$ans2=String("F");
$ans3=String("T");
BEGIN_TEXT
Part 2:
$PAR
Now, you should try to understand the pattern of your answers in the first part.
$PAR
For each of the following questions answer
$BR T if the statement is true and
$BR F
if the statement is false.
$PAR
Suppose we have measured something in gallons and we want to find out how many
quarts we have. $BR
We divide the number of gallons by four. [Answer T or F]
\{ans_rule(1)\}
$PAR
Suppose one unit is four times as large (or four times as much) as another
unit. $BR
Then we say that the ratio of the first unit to the second unit is
four.
$BR
More generally, if \(r\) is a number and one unit is \(r\) times as large
as another $BR
then we say that the ratio of the first number to the second
number is \(r\).
$PAR
If a grmph is equal to \(r\) urps and we have 10 grmphs of shampoo then we have
\(10r\) urps of shampoo. \{ans_rule(1)\}
$PAR
If a grmph is equal to \(r\) urps and we have 10 grmphs of shampoo then we have
\(10r\) urps of shampoo. \{ans_rule(1)\}
END_TEXT



##############################################################
#
# Answers
#
#
Context("TF");

ANS($ans1->cmp);
ANS($ans2->cmp);
ANS($ans3->cmp);

} # End of Part 2


##############################################
#
# Part 3
#


if ($part == 3) {


$ans1=2;

$ans2=3;


BEGIN_TEXT
Part 3:
$PIf I have 24 eggs then I have \{ans_rule(1)\} dozen eggs.
$PAR
If a grmph is equal to \(r\) urps and I have 3r urps of shampoo $BR
then I have \{ans_rule(1)\} grmphs of shampoo.
$PAR
If a grmph is equal to \(r\) urps and I have \(s\) grmphs of shampoo $BR
then I have \{ans_rule(5)\} urps of shampoo.
$PAR
If a grmph is equal to \(r\) urps and I have \(t\) urps of shampoo $BR
then I have \{ans_rule(5)\} grmphs of shampoo.
END_TEXT
##############################################################
#
# Answers

Context("LeadingZero");
ANS(Real ($ans1)-> cmp);
ANS(Real ($ans2)-> cmp);


Context("Numeric");
Context()->variables->are(r=>'Real',s=>'Real',t=>'Real');

ANS(Formula("rs")->cmp);
ANS(Formula("t/r")->cmp);
} #end of part 3

##############################################
#
# Part 4
#


if ($part == 4) {

Context("TF"); #Note This works but the context I used in part 2 was rejected
although, as far as I can see the situations are identical. Why?
$ans1=String("F");
$ans2=String("T");
$ans3=String("T");
$ans4=String("F");
$ans5=String("T");
$ans6=String("F");
BEGIN_TEXT
Part 4:
$PAR
Now, let's try to understand the pattern of the things we have seen.
$BR The true-false questions below will check whether you do understand them.
$PAR
Suppose you know that there are 5 zigs in each queep. Use this knowledge in
answering the following questions.
$PAR
If a frammus is 10 zigs then you multiply 10 by 5 to get the
number of queeps in a frammus (answer T or F). \{ans_rule(1)\}
$PAR
If a frammus is 10 zigs then you divide 10 by 5 to get the
number of queeps in a frammus (answer T or F). \{ans_rule(1)\}
$PAR
Each zig is \(\frac {1}{5}\) of a queep (answer T or F). \{ans_rule(1)\}
$PAR
Each zig is 5 queeps (answer T or F). \{ans_rule(1)\}
$PAR
If a greebo is 20 zigs then you multiply 20 by \(\frac {1}{5}\) to get
the number of queeps in a greebo (answer T or F). \{ans_rule(1)\}
$PAR
If a greebo is 20 zigs then you divide 20 by \(\frac {1}{5}\) to get
the number of queeps in a greebo (answer T or F). \{ans_rule(1)\}
END_TEXT
##############################################################
#
# Answers
Context("TF");

ANS($ans1->cmp);
ANS($ans2->cmp);
ANS($ans3->cmp);
ANS($ans4->cmp);
ANS($ans5->cmp);
ANS($ans6->cmp);
} #end of part 4
##############################################
#
# Part 5
#
if ($part == 5) {
$ans1=6;
$ans2=15;
Context()->texStrings;
BEGIN_TEXT
Part 5:
$PAR
In all of the examples in parts 1-4 we have used units in which $BR
one is an integer multiple of another (for example, a gallon is four quarts, a dollar is ten dimes).$BR
Let us look at questions that are a little different.
$PAR
John has a pocketful of quarters but needs 15 dimes. He will have to pay
Mary \{ans_rule(2)\} quarters for the 15 dimes.
$PAR
Road signs in the United states use the approximation that 5 miles is equal
to 8 kilometers.$BR
Using this approximation, 24 kilometers would be approximately \{ans_rule(2)\}miles

END_TEXT
##############################################################
#
# Answers
Context("LeadingZero");
ANS(Real ($ans1)-> cmp);
ANS(Real ($ans2)-> cmp);
} #end of part 5

##############################################
#
# Part 6
#
if ($part == 6) {

Context()->texStrings;
$ans1=6;
$ans2="9/4";
BEGIN_TEXT
Part 6:
$PAR
Now what did you think to yourself when you solved the last two problems?$BR
(You must have solved them or you would not have gotten to this part.)$BR
If you were following the pattern of the previous parts you might have said
$BR
One mile is approximately \(\frac {8}{5}\) kilometers so 24 kilometers is
approximately \(\frac{24}{\frac{8}{5}}\) miles.$BR
or you might have said $BR
One kilometer is approximately \(\frac {5}{8}\) miles so 24 kilometers is
approximately \(\frac{5}{8}\times 24\) miles.
$PAR
But that must mean that multiplying 24 by \(\frac{5}{8}\) gives the same result
as dividing 24 by \(\frac{8}{5}\).$BR
To \(invert\) a fraction means to turn it upside down, like going from \(\frac{8}{5}\) to \(\frac {5}{8}\). $BR
Thus dividing by a fraction is the same as inverting the fraction and multiplying
by the result. $BR
Use this idea to do the problems below.
$PAR \(\frac{2}{\frac{1}{3}}=\) \{ans_rule(1)\}
$PAR \(\frac{3}{\frac{4}{3}}=\) \{ans_rule(3)\}


END_TEXT
##############################################################
#
# Answers

Context("LeadingZero");
ANS( Real($ans1)->cmp);
Context(Numeric);
ANS(str_cmp($ans2));

} #end of part 6
ENDDOCUMENT()
##############################################

Now for the questions.
1. I did not want the answer .4444444 for the last question in part 6. I wanted the answer as a reduced fraction. Clearly I used
an unpleasant kluge. Was there a better way to force fractions?

2. If you look at parts 2 and 4 I have noted what seems to me a lack of parallelism. It appears that the two situations are the same and yet it would
not accept the same context in 4 as I used in 2. Why?
In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
I did not want the answer .4444444 for the last question in part 6. I wanted the answer as a reduced fraction.

I'm not sure which answer you mean, the student's answer or the correct answer as shown when the "show correct answers" button is checked.

If you mean the latter, then you can accomplish that using Compute($ans1) rather than Real($ans1), which will use the exact string that you provided rather than the result of the formula. In this case it would give 9/4, since that is what $ans1 contains. If you want it to be reduced, you would have to do that yourself.

MathObjects doesn't currently have a fraction object, and one certainly is needed.

If you want the student's answer to show as 9/4 (or whatever), then you need to set the Context's formatStudentAnswer flag to parsed:

    Context()->flags->set(formatStudentAnswer=>'parsed');
This will show the student answer as it is parsed rather than its final value (it will correspond to the answer preview).

Again, a fraction object is the real solution to this problem.


If you look at parts 2 and 4 I have noted what seems to me a lack of parallelism. It appears that the two situations are the same and yet it would not accept the same context in 4 as I used in 2. Why?

Neither part works for me. (I suspect you debugged part 2 and then made changes to the loadMacros() call for part 4 and didn't go back to check part 2 again.) The last file you loaded is contextString.pl, and so the context will be the String context at the beginning of each part. Therefore, part 2 will fail at the String("F") since there is no string "F" defined in the String context. You need to set the "TF" context explicitly for part 2. (This is why I said you should always set the context explicitly and not rely on the .pl that defines the context setting the context.)

The same is true for part 4, which is why you needed to set the "TF" context explicitly. You need the same for part 2.

Davide

In reply to Davide Cervone

Re: contextTF

by Davide Cervone -
OOPS, there were two typos in my code sample above: I had formatStudentAnswers rather than formatStudentAnswer (should be singular, not plural), and I had - rather than -> before set. I have corrected both in the original post.

An alternative to setting the format globally would be to set it for the specific answer you are interested in, e.g.:

    ANS(Compute("3/2")->with(formatStudentAnswer=>"parsed")->cmp);

Davide

In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
There are a number of other problems with the file as it stands. these include the following:

  1. You aren't using parserAutoStrings.pl or unionLists.pl, so there is no need to load either one.

Your definition of the compoundProblem() is incorrect, since it lists too many parts, and not enough totalAnswers. (There are not 10 parts, and they are many more than 4 total answers.) You also don't need to set parserValues to 1, since you haven't used named answers and so no values are being set from previous parts.

You do not need the Context()->texStrings or Context()->normalStrings, since you are not substituting any MathObjects into the text strings anywhere.

In part 1 you set the context to LeadingZeros and set its reduceConstants flag, but then set the context to LeadingZeros again before creating any MathObjects. That means you lose the reduceConstants that you set.

In part 2, the Context("TF") in the answer section needs to be moved to the beginning of the problem. Where it is now it does nothing, since no MathObjects are created after that, and the earlier String() calls will fail because there is no "T" or "F" in the context that is current at the beginning of the part.

In part 4, the Context("TF") in the answer section is superfluous.

In part 6, the Context(Numeric) is missing the quotation marks around Numeric, and is superfluous since the str_cmp doesn't care about the current context.. As a matter of form, I would prefer to see you use Real() and Formula() in the same way you have used String(): use them when you define the answer, not in the ANS() call. So rather than
    $ans1 = 2;
    ...
    ANS(Real($ans1)->cmp);
I would write
    $ans2 = Real(2);
    ...
    ANS($ans1->cmp);
just as is the case with your true/false answers.

Davide

In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
I would like to know the difference between -> and =>

The -> arrow is used to dereference a perl object pointer (for example a HASH or ARRAY reference, or a MathObject). When an object reference has been stored in a scalar variable, -> can be used to access the values and methods stored in the object.

For instance, when you say $a = Real(10), then $a is a reference (i.e., a pointer) to the Real object that stores the value 10. But the object contains lots of information in addition to the 10, as well as methods (i.e., subroutines) that act on the Real value. So when you use $a->TeX, for instance, you are accessing the TeXmethod of the Real object stored in $a. When you use $a->{format} = "%5.2f", you are setting the format property so that it will print as a 5-character string having exactly 2 decimal points.

On the other hand, => forms a key/value pair (for use with perl HASH objects). In WeBWorK, these are used frequently to pass named arguments to function calls. In MathObjects use them extensively for that. For example, when you use num_cmp(10,relTol=>.1), the => associates the value .1 with the name relTol so that num_cmp() can look it up later. (In actuality, => is almost identical to a comma, except that in most cases the left-hand argument is treated as a string literal that doesn't need quotation marks.

As a final example, when you use

    Context()->variables->are(r=>'Real',s=>'Real');
the first Context() call returns a reference to a Context object, and the ->variables calls its variables method. That returns another object (the Context's variables object), and the ->are calls its are method, passing it the HASH that has the key r associated with the string Real and s with Real.


what was the reason that you used r=>'Real' rather than r=>"Real"

Either would work. The single-quote differs from the double-quote in that it does not do variable substitution, so something like '$a and $b' would produce the string $a and $b, whereas "$a and $b" would substitute the values of $a and $b into the string.

I tend to use single-quotes for string constants when no substitution is necessary, as it is slightly more efficient, but that is not really necessary, as the difference probably is negligible.

Davide

In reply to Kenneth Appel

Re: contextTF

by Davide Cervone -
I could not get the suggestion using parserAutoStrings in your previous message to work.
I can't really tell from this what your problem might be because you do not report the error, nor do you give the code you actually used so I could run it and get the error myself. Since AutoStrings work for me, I am at a loss as to what you might have done wrong.

Davide
In reply to Davide Cervone

Re: contextTF

by Paul Pearson -
To address your original problem about entering "G" for a True/False question: The best way to ensure that students don't enter "G" is to use a popup list whose only options are "True" or "False". See, for example,

http://webwork.maa.org/wiki/PopUpListsLong

for a way to write a list of True/False questions that get shuffled for the students (to remove the shuffling, set $qns = $qn; in the code) and use popup lists for entering answers.