PREP 2014 Question Authoring - Archived

Customizing error messages

Customizing error messages

by Michele Titcombe -
Number of replies: 4
I teach in Quebec Canada where many students use the comma instead of the dot for the decimal point.

If the correct answer is 1.2 and the student enters 1,2 instead, I would like to customize the error message to include something like "Remember to use a dot and not a comma for a decimal point." I think the students would otherwise see an error message that says something like the answer looks like a list.

Another notation that is commonly taught in Quebec is one for intervals, where the endpoints are excluded: the interval -1<x<3 would be written as ]-1,3[
instead of (-1,3). Again, I'd like to customize an error message on a question requiring an interval as an answer if the student uses that reverse-square-bracket notation.



In reply to Michele Titcombe

Re: Customizing error messages

by Paul Pearson -
Hi Michele,

I understand your desire to find "high tech" solutions to problems such as these, but sometimes "low tech" solutions work just as well and cause fewer headaches.  For instance, putting instructions into the problem text telling students to use a particular style of notation, such as "(5,6]" instead of "]5,6]" and then telling them in person to use this notation style is a good way to go.  

In fact, giving students explicit instructions in the problem text regarding answer format and syntax is almost always a good idea.  Students get really frustrated when they don't understand why webwork won't take their "correct" answer, and problem authors can alleviate some of this frustration by giving clear instructions that tell them what their answer should look like.  (Gavin does a very good job of including instructions like these -- look at the Michigan problems in the library for examples.)  We will talk about providing answer format help links in next week's workshop.

Best regards,

Paul Pearson 
In reply to Michele Titcombe

Re: Customizing error messages

by Davide Cervone -
I'm going to answer the second question, about reversed square bracket notation. I spent yesterday working out a means of doing what you request. It turns out to have been subtler than I originally thought it would be, mostly because the parsing algorithm didn't have quite enough flexibility in terms of using the same delimiters for both open and close delimiters, so I had to extend it a little to make that happen. Fortunately, it is possible to override just about anything in the parser, so I was able to come up with a macro file that you can use to allow or prevent reverse-square-bracket notation without your having to update PG. I've attached the file

The macro file contains comments at the top that tell you how to use it, but I'm reproducing that below. Note that you can set up your course to replace the Interval context with one that allows the alternate format, or one that gives a warning if the alternate format is used. See the last section below for details.


NAME

Context("AlternateIntervals") - Provides a context that allows the entry of intervals using reversed bracket notation for open endpoints (e.g., ]a,b[ rather than (a,b) for an open interval).

DESCRIPTION

This macro file defines contexts in which open intervals can be specified using reversed brackets rather than parentheses. Both forms are always recognized, but you can determine whether one or the other form produces an error message when used. You can also force the display of intervals to use one or the other form.

USAGE

To use this file, first load it into your problem, then select the context that you wish to use. There are three pre-defined contexts, AlternateIntervals, AlternateIntervals-Only, and AlternateIntervals-Warning. The first allows both the standard and alternate forms to be used, the second allows only the alternate form, and the third allows only the standard form, but recognizes the alternate form and gives an error message when it is used.

        loadMacros("contextAlternateIntervals.pl");
        
        Context("AlternateIntervals");
        
        $I1 = Compute("]2,5[");
        $I2 = Compute("(2,5)");    # equivalent to $I1;
        
        Context("AlternateIntervals-Only");
        
        $I1 = Compute("]2,5[");
        $I2 = Compute("(2,5)");    # causes an error message
        
        Context("AlternateIntervals-Warning");
        
        $I1 = Compute("]2,5[");    # causes an error message
        $I2 = Compute("(2,5)");

There are two context flags that control the input and output of intervals.

enterIntervals => "either" (or "alternate" or "standard")

This specifies what formats the student is allowed to use to enter an interval. A value of "either" allows either of the formats to be accepted, while the other two options produce error messages if the wrong form is used.

displayIntervals => "either" (or "alternate" or "standard")

This controls how intervals are displayed. When set to "either">, the interval is displayed in whatever format was used to create it. When set to "standard" or "alternate", the display is forced to be in the given format regardless of how it was entered.

The AlternateIntervals context has both flags set to "either", so the intervals remain in the format the student entered them, and either form can be used. The AlternateIntervals-Only context has both set to "alternate", so only the alternate format can be used, and any Interval will be displayed in alternate format. The AlternateIntervals-Warning context has both set to "standard", so only standard format can be used, and all intervals will be displayed in standard format.

It is possible to set enterIntervals and displayIntervals to different values. For example.

        Context()->flags->set(
          enterIntervals => "either",
          displayIntervals => "standard",
        );
would allow students to enter intervals in either format, but all intervals would be displayed in standard form.

SETTING ALTERNATE FORM AS THE DEFAULT

If you want to force existing problems that use the Interval context to use one of the alternate contexts instead, then create a file named parserCustomization.pl in your course's templates/macros directory, and enter the following in it:
        loadMacros("contextAlternateIntervals.pl");
        $context{Interval} = $context{"AlternateIntervals"};
This will replace the Interval context with the AlternateIntervals context so that any problem that sets Context("Interval") will get the AlternateInervals context instead, so students can enter intervals in either format.

You could also do

        loadMacros("contextAlternateIntervals.pl");
        $context{Interval} = $context{"AlternateIntervals-Warning"};
to cause a warning message to appear when students enter the alternate format.

If you want to force students to enter the alternate format, you can't use AlternateIntervals-Only because the original problem code probably involves the creation of intervals using the standard notation. Instead, use

        loadMacros("contextAlternateIntervals.pl");
        $context{Interval} = $context{"AlternateIntervals"};
        $context{Interval}->flags->set(displayIntervals => "alternate");
        $context{Interval}->{cmpDefaults}{Interval}{enterIntervals} = "alternate";

This will force the diplay of all intervals into the alternate form (so even the ones created in the problem using standard form will show using reverse brackets), and will force students to enter their results using the alternate format. So this makes the problem work as though it were written using AlternateIntervals->Only.

In reply to Davide Cervone

Re: Customizing error messages

by Michele Titcombe -
Thank you, Davide, for putting the time in yesterday to write a macro for alternative interval notation.

I tried out the AlternateIntervals context, in the following basic WeBWorK problem, the code for which I have included in case anyone else is interested:
#---------------------------------------------------------------------
DOCUMENT();

loadMacros(
"PGstandard.pl", # Standard macros for PG language
"MathObjects.pl",
"contextAlternateIntervals.pl",
);

TEXT(beginproblem());
$showPartialCorrectAnswers = 1;

Context("AlternateIntervals");

$I1 = Compute("]2,5[");
$I2 = Compute("(2,5)"); # equivalent to $I1;

Context()->texStrings;
BEGIN_TEXT

Enter the interval corresponding to \( 2<x<5 \) using interval notation: \{ ans_rule \}
$BR

END_TEXT
BEGIN_SOLUTION
The answer is: \( $I2 \) $BR
Note: the reverse-square-bracket notation is also accepted, as in: \( $I1 \)
END_SOLUTION
Context()->normalStrings;

ANS($I2->cmp);

ENDDOCUMENT();
#---------------------------------------------------------------------

This will also be of great interest to my colleagues, some of whom don't mind, as much as I do, the reverse-square-bracket notation (I don't really know if there is an official name for it - I've only seen it here, in Quebec).

Thanks again for the great effort that you put in to responding to my request.
In reply to Michele Titcombe

Re: Customizing error messages

by Davide Cervone -
OK, I've done a similar arrangement for the decimal notation. Getting it to be used by default is a little more complicated, and I'm not sure this will work for every problem in the OPL, but it should cover quite a few.

The documentation from the file is included below. It will look familiar.

One thing to note is the section on lists. I added a semi-colon as an alliterative to commas, since there is ambiguity using commas for decimals and lists. I'm not sure how you usually handle something like that using comma notation.

Also, note that I'm forcing comma-users to write 0,3 and 3,0 rather than ,3 or 3, in order to facilitate the distinction between numbers and lists. Let me know if that doesn't work for you.


NAME

Context("AlternateDecimal") - Provides a context that allows the entry of decimal numbers using a comma for the decimal indicator rather than a dot (e.g., 3,14159 rather than 3.14159).

DESCRIPTION

This macro file defines contexts in which decimal numbers can be entered using a comma rather than a period as the decimal separator. Both forms are always recognized, but you can determine whether one or the other form produces an error message when used. You can also force the display of numbers to use one or the other form.

USAGE

To use this file, first load it into your problem, then select the context that you wish to use. There are three pre-defined contexts, AlternateDecimal, AlternateDecimal-Only, and AlternateDecimal-Warning. The first allows both the standard and alternate forms to be used, the second allows only the alternate form, and the third allows only the standard form, but recognizes the alternate form and gives an error message when it is used.
	loadMacros("contextAlternateDecimal.pl");
	
	Context("AlternateDecimal");
	
	$r1 = Compute("3.14159");
        $r2 = Compute("3,14159");    # equivalent to $r1;
	
	Context("AlternateDecimal-Only");
	
	$r1 = Compute("3.14159");
        $r2 = Compute("3,14159");    # causes an error message
	
	Context("AlternateDecimal-Warning");
	
	$I1 = Compute("3.14159");    # causes an error message
        $I2 = Compute("3,14159");
There are two context flags that control the input and output of decimals.

enterDecimals => "either" (or "," or ".")

This specifies what formats the student is allowed to use to enter a Decimal. A value of "either" allows either of the formats to be accepted, while the other two options produce error messages if the wrong form is used.

displayDecimals = "either" (or "," or ".")

This controls how decimals are displayed. When set to "either", the decimal is displayed in whatever format was used to create it. When set to "." or ",", the display is forced to be in the given format regardless of how it was entered.

The AlternateDecimal context has both flags set to "either", so the decimals remain in the format the student entered them, and either form can be used. The AlternateDecimal-Only context has both set to ",", so only the alternate format can be used, and any number will be displayed in the alternate format. The AlternateDecimal-Warning context has both set to ".", so only standard format can be used, and all numbers will be displayed in standard format.

It is possible to set enterDecimals and displayDecimals to different values. For example.

	Context()->flags->set(
	  enterDecimals => "either",
	  displayDecimals => ".",
	);
would allow students to enter decimals in either format, but all numebrs would be displayed in standard form.

LISTS IN ALTERNATE FORMAT

Because the alternate format allows numbers to be entered using commas rather than periods, this makes the formation of lists harder. For example, 3,5 is the number 3-and-5-tenths, not the list consisting of 3 followed by 5. Because of this ambiguity, the AlternateDecimal contexts also include the semi-colon as a replacement for the comma as a separator. So 3;5 is the list consisting of 3 followed by 5, and 3,1;5.2 is the list consisting of 3.1 and 5.2.

Note that the comma is still available for use as a separator, but this makes things like 3,2,1 tricky, because it is not clear if this is 3.2 followed by 1, or 3.2 times .1, or the list of 3, 2, and 1. To help make this unambiguous, numbers that use a comma as decimal inidcator must have a digit on both sides of the comma. So one tenth would have to be entered as 0,1 not just ,1 (but you can still enter .1. Similarly, You must enter 3,0 or just 3 rather than 3,, even though 3. is acceptable.

With this notation 3,2,1 means the list consisting of 3.2 followed by 1. If you want the list consisting of 3 followed by 2.1, you could use 3, 2,1 since the comma in 3, is not part of the number, so must be a list separator.

SETTING THE ALTERNATE FORM AS THE DEFAULT

If you want to force existing problems to allow (or force, or warn about) the alternate format instead, then create a file named parserCustomization.pl in your course's templates/macros directory, and enter the following in it:
	loadMacros("contextAlternateDecimal.pl");
        context::AlternateDecimal->Default("either","either");
        Context("Numeric");
This will alter all the standard contexts to allow students to enter numbers in either format, and will display them using the form that was used to enter them.

You could also do

	loadMacros("contextAlternateDecimal.pl");
        context::AlternateDecimal->Default(".",".");
        Context("Numeric");
to cause a warning message to appear when students enter the alternate format.

If you want to force students to enter the alternate format, use

	loadMacros("contextAlternateDecimal.pl");
        context::AlternateDecimal->Default(",",".");
        Context("Numeric");
This will force the display of all numbers into the alternate form (so even the ones created in the problem using standard form will show using commas), and will force students to enter their results using commas.