Difference between revisions of "Answer Checkers (MathObjects)"

From WeBWorK_wiki
Jump to navigation Jump to search
(Better examples)
m (don't break the example list)
Line 56: Line 56:
 
 
 
ANS(Compute("(-inf,2),(4,5)")->cmp);
 
ANS(Compute("(-inf,2),(4,5)")->cmp);
 
  +
 
ANS(Formula("x, x+1, x^2-1")->cmp);
 
ANS(Formula("x, x+1, x^2-1")->cmp);
 
ANS(Compute("<x,2x>,<x,-2x>,<0,x>")->cmp);
 
ANS(Compute("<x,2x>,<x,-2x>,<0,x>")->cmp);

Revision as of 06:13, 6 August 2012

Basic Answer Checkers

Checkers are available for each of the types of values that the parser can produce (numbers, complex numbers, infinities, points, vectors, intervals, sets, unions, formulas, lists of numbers, lists of points, lists of intervals, lists of formulas returning numbers, lists of formulas returning points, and so on).

To use one of these checkers, simply call the cmp() method of the object that represents the correct answer. For example,

   $n = Real(sqrt(2));
   ANS($n->cmp);

will produce an answer checker that matches the square root of two. Similarly,

   ANS(Vector(1,2,3)->cmp);

matches the vector <1,2,3> (or any computation that produces it, e.g., <i+2j+3k>, or <4,4,4>-<3,2,1>), while

   ANS(Interval("(-inf,3]")->cmp);

matches the given interval. Other examples include

   ANS(Infinity->cmp);
   ANS(String('NONE')->cmp);
   ANS(Union("(-inf,$a) U ($a,inf)")->cmp);

and so on.

Formulas are handled in the same way:

   ANS(Formula("x+1")->cmp);
   
   $a = random(-5,5,1); $b = random(-5,5,1); $x = random(-5,5,1);
   $f = Formula("x^2 + $a x + $b")->reduce;
   ANS($f->cmp);
   ANS($f->eval(x=>$x)->cmp);
   
   $x = Formula('x');
   ANS((1+$a*$x)->cmp);
   
   Context("Vector")->variables->are(t=>'Real');
   $v = Formula("<t,t^2,t^3>"); $t = random(-5,5,1);
   ANS($v->cmp);
   ANS($v->eval(t=>$t)->cmp);

Answer Checkers for Lists

Lists of items can be checked easily:

   ANS(List(1,-1,0)->cmp);
   ANS(Compute("1,-1,0")->cmp);
   
   ANS(List(Point($a,$b),Point($a,-$b))->cmp);
   ANS(Compute("($a,$b),($a,-$b)")->cmp);
   
   ANS(List(Vector(1,0,0),Vector(0,1,1))->cmp);
   ANS(Compute("<1,0,0>,<0,1,1>")->cmp);
   
   ANS(Compute("(-inf,2),(4,5)")->cmp);
   
   ANS(Formula("x, x+1, x^2-1")->cmp);
   ANS(Compute("<x,2x>,<x,-2x>,<0,x>")->cmp);
   
   ANS(List('NONE')->cmp);

and so on. The last example may seem strange, as you could have used ANS(String('NONE')->cmp), but there is a reason for using this type of construction. You might be asking for one or more numbers (or points, or whatever) or the word NONE if there are no numbers (or points). If you used String('NONE')->cmp, the student would get an error message about a type mismatch if he entered a list of numbers, but with List('NONE')->cmp, he will get appropriate error messages for the wrong entries in the list.

In the case of a list of points where the answer is NONE, you should tell MathObject what the expected type of answer is, so that appropriate messages can be given. E.g.,

   ANS(List('NONE')->cmp(typeMatch => 'Value::Point');

would give appropriate messages for points rather than numbers (the default type).

It is often appropriate to use the list checker in this way even when the correct answer is a single value, if the student might type a list of answers.

On the other hand, using the list checker has its disadvantages. For example, if you use

   ANS(Interval("(-inf,3]")->cmp);

and the student enters (-inf,3), she will get a message indicating that the type of interval is incorrect, while that would not be the case if

   ANS(List(Interval("(-inf,3]"))->cmp);

were used. (This is because the student doesn't know how many intervals there are, so saying that the type of interval is wrong would inform her that there is only one.)

The rule of thumb is: the individual checkers can give more detailed information about what is wrong with the student's answer; the list checker allows a wider range of answers to be given without giving away how many answers there are. If the student knows there's only one, use the individual checker; if there may or may not be more than one, use the list checker.

Note that you can form lists of formulas as well. The following all produce the same answer checker:

   ANS(List(Formula("x+1"),Formula("x-1"))->cmp);
   
   ANS(Formula("x+1,x-1")->cmp); # easier
   
   $f = Formula("x+1"); $g = Formula("x-1");
   ANS(List($f,$g)->cmp);
   
   $x = Formula('x');
   ANS(List($x+1,$x-1)->cmp);

See the files in pg/doc/MathObjects/problems for more examples of using the parser's answer checkers.

Controlling the Details of the Answer Checkers

The various features of the answer checkers can be controlled by passing options to the cmp() method of a MathObject.

  ANS($mathObject->cmp(options));

For example:

   ANS(Real(pi)->cmp(showTypeWarnings => 0));

will prevent the answer checker from reporting errors due to the student entering the wrong type of answer (say a vector rather than a number).

See the Answer Checker Options documentation for details about the available options, and the individual MathObject class documentation for the options specific to each class. See the Answer Checkers and the Context page for information about how the Context can control the answers that students can enter.

Custom Answer Checkers

While the built-in answer checkers do a good job of testing a student response for agreement with a given correct answer, sometimes an answer may require a more sophisticated or customized check. For example, you might ask a student to provide a solution to a given implicit equation for which there are infinitely many solutions and would like to count any of them as correct. You can do this by providing your own answer checker as a parameter to a MathObject answer checker. This lets you get the advantage of the MathObject parsing, syntax checking, type checking, and error messages, while still giving you the control of deciding when the student's answer is correct.

See the Custom Answer Checkers and Custom Answer Checkers for Lists documentation for details about how to create your own custom checkers using MathObjects.