WeBWorK Main Forum

Course-wide context modification

Course-wide context modification

by Alex Jordan -
Number of replies: 3
Is it possible to modify the behavior of a context for a course using PGcourse.pl? Supposing that all problems used by a course load PGcourse.pl, then is there something I could add to that file that could change the defaults for a context? For my purposes, I can also assume that all problems use Math Objects.

For a specific example, suppose I want the Numeric context's `tolerance` flag, whose usual server default value is 0.001, to have default value 0.01. But I only want to affect one course, not all courses on the server.

In reply to Alex Jordan

Re: Course-wide context modification

by Davide Cervone -

There is another file called parserCustomization.pl that might be better for this. It is loaded automatically when MathObjects.pl is loaded, so you don't have to worry about whether PGcourse.pl is used or not. So make a file called parserCustomization.pl in your templates/macros folder in order to make course-wide customizations.

I can think of two ways to do what you want, though neither is ideal. The first is to add

foreach my $name (keys %Parser::Context::Default::context) {
  $context{$name} = Parser::Context->getCopy($name);
  $context{$name}->flags->set(tolerance => .01);
to your parserCustomization.pl file. This will create a local copy of all the predefined contexts with the new tolerance, and these will be used in preference to the default ones whenever one is loaded via Context() or accessed in any other way. This means that any other contexts that are loaded later (such as those defined in files like contextInequalities.pl) will inherit the changes you made, since all these macro files copy an existing context and modify it (as I recall). This also means that the traditional checkers (like num_cmp()), which use MathObjects behind the scenes, will also use the new tolerance, provided the problem they are in loads MathObejcts.pl.

The main drawback here is that, since this is done for each problem individually every time it is run, and for every context that is predefined (there are 21), that can be a lot of overhead copying contexts that aren't used. There is also the issue that not all problems that use the traditional checkers like num_cmp will load MathObejcts.pl, but you could add

to your PGcourse.pl file an perhaps pick up some are of those, if that is ends up being a problem.

The other way would be to add

sub Context {
  my $context = Parser::Context->current(\%context,@_);
  $context->flags->set(tolerance => .01) if scalar(@_);
  return $context;
to your parserCustomization.pl file. This overrides the Context() function so that only the contexts that you actually use would be modified (so less overhead). The PG_restricted_eval() is there to prevent error messages about redefining an existing macro (I think this will prevent them from appearing in the server log as well, but I'm not sure of that).

The issue here is that This only works when Context() is called explicitly, and so if a context is acquired by other means (e.g., by copying an existing one), that means it won't get modified. Most of the macro files that create contexts do so by copying without setting them directly, but since you eventually do use Context() to enable them, that should not be a problem. But the traditional num_cmp() and friends never call Context() (they use a lower-level call), the contexts they use would not be modified.

So those are the two ways I can see to accomplish what you want. Try them out and see if one works for you.


In reply to Alex Jordan

Re: Course-wide context modification

by Danny Glin -
There is a setting under Course Configuration -> PG - Problem Display/Answer Checking:
Allowed error, as a percentage, for numerical comparisons

This sets the variable $pg{ansEvalDefaults}{numRelPercentTolDefault}

I would think that this should do what you want, but I don't know if this variable is respected by the answer checkers. If not, that should either be fixed, or this item should be removed from the config page.
In reply to Danny Glin

Re: Course-wide context modification

by Davide Cervone -
Yes, the Context does pick up this value (and a number of other values that control the traditional answer checkers). I didn't realize you could set that in the course configuration page, so thanks for the helpful info!