I'm trying to get an answer with units to have a relative tolerance for the numerical part (this is for a physics question giving a force in Newtons where the number and range of the decimals needs to be flexible. So far, i'm using
ANS(NumberWithUnits(8.23E-8,"N")->cmp);
which works fine on its own but I'm not sure of how to include relTol=>0.3 in this as it can be with std_num_cmp();
Thanks.
ANS(NumberWithUnits(8.23E-8,"N")->with(tolType=>'relative', tolerance=>'.01')->cmp )
I believe this will give you 1 per cent tolerance, but you might double check that.
-- Mike
Warning messages
No answer provided by instructor for answer AnSwEr2 at line 471 of (eval 214)
There is no answer evaluator for the question labeled AnSwEr2 at /home/pg/lib/WeBWorK/PG/Translator.pm line 1129
Error in Translator.pm::process_answers: Answer AnSwEr2:
Unrecognized evaluator type || at /home/pg/lib/WeBWorK/PG/Translator.pm line 1153
Error in Translator.pm::process_answers: Answer AnSwEr2:
Answer evaluators must return a hash or an AnswerHash type, not type || at /home/pg/lib/WeBWorK/PG/Translator.pm line 1158
Check for typos in your input. I actually checked my suggestion this time on our local system :-) Here is the snippet I used:
DOCUMENT(); loadMacros( "PGstandard.pl", # Standard macros for PG language "MathObjects.pl", "parserNumberWithUnits.pl", ); BEGIN_TEXT Enter the answer of 1 Newton \{ans_rule()\} END_TEXT ANS( NumberWithUnits(1, 'N')->with(tolType=>'relative', tolerance=>'.01')->cmp ); ENDDOCUMENT();This accepts .9901 N but not .99 N
In your example the answer is small enough that the answer evaluator might default to absolute error checking in any case.
Hope this helps.
Would that make a difference?
Davide
if tolerance=>.01 is 1% tolerance then surely 0.99 N should be accepted. 0.9901 is 0.01% of 1 not 1% of 1.
In any case, the tolerance uses a strict inequality, not less-than-or-equal, so even with exact arithmetic, .99 would not match a .1 tolerance.
Finally, the error for .9901 (compared to a correct answer of 1) is .0099, or just under 1% (not the .01% you claim), so this answer is correctly marked, and, together with the answer of .99, does show that the tolerance is correctly set at .01 (or 1%).
Davide
If the NumberWithUnits already IS the second answer checker, then something is going wrong. If that is the case, please post a complete code sample, since it is difficult to debug this without actually seeing the code you are using.
Davide
ANS(Real(8.23E-8)->with(tolType=>'relative',tolerance=>'.01')->cmp);
which works fine for the relative tolerance but has no units, so I tried
ANS(Real(8.23E-8)->with(tolType=>'relative',tolerance=>'.1',units=>'N')->cmp);
but that made absolutely no difference to the answers required by the first line when N wasn't included in the answer and when it was included Webwork said it was an undefined variable.
Does this help?
The MathObject library needs a better units feature; NumberWithUnits and FormulaWithUnits are intermediate measures until the a more complete Units class is added to MathObjects.
Davide
ANS(NumberWithUnits(8.23E-8,"N")->with(tolerance=>0.03)->cmp);
(i.e. 3% tolerance) then tried different values for the answer but was only allowed to input
8.222E-8 to 8.238E-8 which is a tolerance of 0.097% and not the 3% I want. Then I tried
ANS(NumberWithUnits(8.23E-8,"N")->with(tolerance=>3)->cmp);
(i.e. 300% tolerance) and got the exact same behaviour.
This is usually the desirable behavior, if the answer results in zero for some particular value of the seed, then it is quite possible that round off error will make the instructor's answer a very small number. A student, using a mathematically equivalent but operationally different method of calculating the answer, will have a slightly different round off error and their answer will be marked incorrect -- not what is desired or expected. The errors are small in absolute terms but large relative to the correct answer.
For your problem you want to work with answers that are very small, so the defaults at which the comparison automatically switches from relative to absolute (zeroLevel) needs to be lowered and the absolute comparison with zero (zeroLevelTol) needs to be lowered as well. You can experiment with various settings in the snippet below:
######################################################################## DOCUMENT(); loadMacros( "PGstandard.pl", # Standard macros for PG language "MathObjects.pl", "parserNumberWithUnits.pl", ); Context()->flags->set(zeroLevel => 1E-50); Context()->flags->set(zeroLevelTol => 1E-55); BEGIN_TEXT zeroLevel \{ Context()->flags->get('zeroLevel')\} $PAR zeroLevelTol \{ Context()->flags->get('zeroLevelTol')\} $PAR Enter the answer of 1E-23 Newton \{ans_rule()\} END_TEXT ANS( NumberWithUnits(1E-23, 'N')->with(tolType=>'relative', tolerance=>.01)->cmp ); ENDDOCUMENT();
If desired the default limits can be reset in global.conf (for the site) or course.conf (for the course), but you should be cautious about setting extreme values for these.
(Edited by Davide Cervone - original submission Tuesday, 18 December 2007, 12:40 PM)
While your code is a nice example, it might also be valuable to print out the ORIGINAL values of zeroLevel and zeroLevelTol. I think the default zeroLevel is 1E-14, and so Clinton's value of 8.23E-8 is above that. The difficulty he is having is, I think, due to having a older version of PG, not to zeroLevel issues. One of the reasons for many of the changes this summer was to improve the reliability of the the flags when they are attached to individual objects (they were not always passed down to sub-objects properly). This has been improved, though there is still some work that could be done on it.
In any case, I think an update of the PG tree will take care of the issue he is having.
Davide
One other thing -- for future reference. I originally tried to change the values of $main::zeroLevelDefault and $main::zeroLevelTolDefault in the problem but was unable to affect the way the answer checker behaved because the answer checker had already read those values and replaced them in its interior database.
You have to change the values in the current Context in order for them to affect the answer checkers.
One other thing -- for future reference. I originally tried to change the values of $main::zeroLevelDefault and $main::zeroLevelTolDefault in the problem but was unable to affect the way the answer checker behaved because the answer checker had already read those values and replaced them in its interior database.
The values are loaded into the context at the time it is created or copied, so if you set these values before the
Context("Numeric");(or whatever context you use), then that should do it.
Davide
Context()->flags->set( zeroLevel => 1E-50, zeroLevelTol => 1E-55, );so there is no need for two separate Context() calls.
Davide
ANS(NumberWithUnits(8.23E-8,"N")->with(tolerance=>0.03)->cmp);accepts answers up to 8.476E-8, which is the requires 3%. I suspect that the reason is that your copy of PG needs to be updated. There were a number of important changes this past summer, and one was to fix some problems with passing tolerance values (and other flags) from one object to another. In this case, the NumberWithUnits uses a Real object internally and wasn't passing the flags downward properly. This is working in the current version, so you may want to upgrade.
You can update the PG directory without updating the whole WeBWorK installation, and I would recommend that you do that (after first backing up the PG directory tree in case you decide you need to go back). The current version of PG can be used with WW2.3.2 for sure, and perhaps even earlier.
If you can't update to this version, then you can try using
ANS(NumberWithUnits(8.23E-8,"N")->cmp(tolerance=>0.03));instead, and if that doesn't work either, try setting the tolerance in the context itself:
Context()->flags->set(tolerance=>.03); ANS(NumberWithUnits(8.23E-8,"N")->cmp);though that will affect all numeric comparisons, not just this one.
Davide
ANS(NumberWithUnits(8.23E-8,"N")->cmp(tolerance=>0.03));doesn't work, BUT, using
Context()->flags->set(tolerance=>.03); ANS(NumberWithUnits(8.23E-8,"N")->cmp);works perfectly.
Thanks for all your help, I appreciate it.
Where can I get a list of all the possible flags [Context()->flags->...] and the options that can go with ->cmp?
The context flags depend on which context you are using, but you can get the ones for the current context by using
warn join('<BR>',lex_sort(Context()->flags->names));in your problem file after you select the context. There are also some tools in pg/macros/PGinfo.pl for listing the flags and their values, or the entire Context() structure.
As for the cmp() flags, that is harder, since each MathObject class has its own set, and there is no one place where they are all listed, even in the code itself. Many of the most common ones are in the documentation at
http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/doc/MathObjects/MathObjectsAnswerCheckers.htmlso that is the first place to start. As you have found out, the documentation on MathObjects is something that needs improvement.
Davide