[system] / trunk / pg / macros / answerCustom.pl Repository:
ViewVC logotype

View of /trunk/pg/macros/answerCustom.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3208 - (download) (as text) (annotate)
Tue Mar 29 19:16:36 2005 UTC (14 years, 10 months ago) by dpvc
File size: 5848 byte(s)
Provide an easy means of generating a custom answer checker based on
an user-supplied subroutine.  Most of the work is done by the Parser's
answer checker framework, and the user's routine is called at the
point that the student's answer is compared to the correct answer.

    1 loadMacros('Parser.pl');
    2 
    3 sub _answerCustom_init {}; # don't reload this file
    4 
    5 ######################################################################
    6 #
    7 #  This answer checker provides an easy method for creating an answer
    8 #  checker with a custom subroutine that performs the check for
    9 #  correctness.
   10 #
   11 #  Pass the correct answer (either as a string or as a Parser object)
   12 #  as the first argument, and a reference to the checker subroutine
   13 #  as the second argument.  Additional parameters can follow.  These
   14 #  include any of the parameters for the usual answer checker of the
   15 #  of the type of the correct answer (e.g., showCoordinateHints), plus
   16 #  the following:
   17 #
   18 #     sameClass => 0 or 1      If 1 (the default), only call the
   19 #                              custom checker if the student answer
   20 #                              is the same object class as the correct
   21 #                              answer (e.g., both are points).
   22 #                              If 0, the checker will be called
   23 #                              whenever the student answer passes
   24 #                              the typeMatch check for the correct
   25 #                              answer.  For example, if the correct
   26 #                              answer is a vector, and promotePoints
   27 #                              has been set to 1, then the checker
   28 #                              will be called when the student answer
   29 #                              is a vector OR a point.
   30 #
   31 #    sameLength => 0 or 1      If 1 (the default), only call the
   32 #                              custom checker if the student answer
   33 #                              has the same number of coordinates as
   34 #                              the correct answer.
   35 #
   36 #  If the correct answer is a list, the custom checker will be called
   37 #  on the individual entries of the list, not on the list as a whole.
   38 #  If the list is an unordered list, the routine may be called
   39 #  multiple times with various combinations of student and professor's
   40 #  answers in order to find a correct match.
   41 #
   42 #  The checker routine will be passed the correct answer, the
   43 #  student's answer, and the answer evaluator object, in that order.
   44 #
   45 #  For example, the following checks if a student entered
   46 #  a unit vector (any unit vector in R^3 will do):
   47 #
   48 #     custom_cmp("<1,2,3>",sub {
   49 #       my ($correct,$student,$ans) = @_;
   50 #       return norm($student) == 1;
   51 #     });
   52 #
   53 #  The checker subroutine can call Value::Error(message) to generate
   54 #  an error message that will be reported in the table at the top of
   55 #  the page.  If the checker generates a fatal runtime error (e.g.,
   56 #  calls the "die" function), then the message is reported with the
   57 #  "pink screen of death", and includes a request for the student to
   58 #  inform the instructor.
   59 #
   60 
   61 sub custom_cmp {
   62   my $correct = shift; my $checker = shift;
   63   die "custom_cmp requires a correct answer" unless defined($correct);
   64   die "custom_cmp requires a checker subroutine" unless defined($checker);
   65   $correct = Value::makeValue($correct);
   66   $correct = main::Formula($correct) unless Value::isValue($correct);
   67   $correct->cmp(
   68     checker => sub {
   69       my ($correct,$student,$ans) = @_;
   70       return 0 if $ans->{sameClass} && $correct->class ne $student->class;
   71       return 0 if $ans->{sameLength} && $correct->length != $student->length;
   72       return &{$ans->{custom_checker}}($correct,$student,$ans);
   73     },
   74     custom_checker => $checker,
   75     sameClass => 1,
   76     sameLength => 1,
   77     showEqualErrors => 1,  # make sure we see errors in list checker
   78     @custom_cmp_defaults,
   79     @_,
   80   );
   81 }
   82 
   83 #
   84 #  Set this to include any default parameters you want
   85 #  to include in the custom answer checkers
   86 #
   87 @custom_cmp_defaults = ();
   88 
   89 
   90 #
   91 #  This one installs a custom list-based answer checker (for the
   92 #  List and Union classes).  Basically it is just a shell that makes
   93 #  it a little easier to do, and provides an interface similar to
   94 #  custom_cmp.
   95 #
   96 #  You pass the correct answer (as a string or as a List or Union
   97 #  object) as the first argument, and the custom list checker as
   98 #  the second argument.  You can pass any additional parameters
   99 #  that should be included in the answer checker following those
  100 #  two required ones.
  101 #
  102 #  The checker will be passe a reference to the array of correct
  103 #  answers, a reference ro the array of student answers, and
  104 #  the answer evaluator object.  Note that the correct and student
  105 #  anwers are array references, not List structures (this is because
  106 #  a list of formulas becomes a formula returning a list, so in order
  107 #  to keep the formulas separate, they are passed in an array).
  108 #
  109 #  For example, the following checks for any list of the same length
  110 #  as the instructor's list.  (A stupid checker, but just an example.)
  111 #
  112 #      custom_list_cmp("1,2,3",sub {
  113 #        my ($correct,$student,$ans) = @_;
  114 #        scalar(@{$correct}) == scalar(@{$student});
  115 #      });
  116 #
  117 #  The checker subroutine can call Value::Error(message) to generate
  118 #  an error message that will be reported in the table at the top of
  119 #  the page.  If the checker generates a fatal runtime error (e.g.,
  120 #  calls the "die" function), then the message is reported with the
  121 #  "pink screen of death", and includes a request for the student to
  122 #  inform the instructor.
  123 #
  124 
  125 sub custom_list_cmp {
  126   my $correct = shift; my $checker = shift;
  127   die "custom_list_cmp requires a correct answer" unless defined($correct);
  128   die "custom_list_cmp requires a checker subroutine" unless defined($checker);
  129   $correct = Value::makeValue($correct);
  130   $correct = main::Formula($correct) unless Value::isValue($correct);
  131   $correct->cmp(
  132     custom_list_checker => $checker,
  133     @custom_list_cmp_defaults,
  134     @_,
  135   );
  136 }
  137 
  138 #
  139 #  Set this to include any default parameters you want
  140 #  to include in the custom answer checkers
  141 #
  142 @custom_list_cmp_defaults = ();

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9