[system] / trunk / webwork-modperl / lib / WeBWorK / PG.pm Repository:
ViewVC logotype

View of /trunk/webwork-modperl/lib/WeBWorK/PG.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1239 - (download) (as text) (annotate)
Fri Jun 20 23:06:17 2003 UTC (9 years, 11 months ago) by sh002i
File size: 20136 byte(s)
changed occurences of $courseEnv to $ce. uses
$ce->{pg}->{directories}->{macros} instead of the (now removed)
$ce->{webworkDirs}->{macros}.

    1 ################################################################################
    2 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
    3 # $Id$
    4 ################################################################################
    5 
    6 package WeBWorK::PG;
    7 
    8 =head1 NAME
    9 
   10 WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API.
   11 
   12 =cut
   13 
   14 use strict;
   15 use warnings;
   16 use File::Path qw(rmtree);
   17 use WeBWorK::PG::ImageGenerator;
   18 use WeBWorK::PG::Translator;
   19 use WeBWorK::Utils qw(readFile formatDateTime writeTimingLogEntry makeTempDirectory);
   20 
   21 sub new {
   22   my $invocant = shift;
   23   my $class = ref($invocant) || $invocant;
   24   my (
   25     $ce,
   26     $user,
   27     $key,
   28     $set,
   29     $problem,
   30     $psvn,
   31     $formFields, # in CGI::Vars format
   32     $translationOptions, # hashref containing options for the
   33                          # translator, such as whether to show
   34              # hints and the display mode to use
   35   ) = @_;
   36 
   37   # write timing log entry
   38   writeTimingLogEntry($ce, "WeBWorK::PG::new",
   39     "user=".$user->user_id.",problem=".$ce->{courseName}."/".$set->set_id."/".$problem->problem_id.",mode=".$translationOptions->{displayMode},
   40     "begin");
   41 
   42   # install a local warn handler to collect warnings
   43   my $warnings = "";
   44   local $SIG{__WARN__} = sub { $warnings .= shift }
   45     if $ce->{pg}->{options}->{catchWarnings};
   46 
   47   # create a Translator
   48   #warn "PG: creating a Translator\n";
   49   my $translator = WeBWorK::PG::Translator->new;
   50 
   51   # set the directory hash
   52   #warn "PG: setting the directory hash\n";
   53   $translator->rh_directories({
   54     courseScriptsDirectory => $ce->{pg}->{directories}->{macros},
   55     macroDirectory         => $ce->{courseDirs}->{macros},
   56     templateDirectory      => $ce->{courseDirs}->{templates},
   57     tempDirectory          => $ce->{courseDirs}->{html_temp},
   58   });
   59 
   60   # evaluate modules and "extra packages"
   61   #warn "PG: evaluating modules and \"extra packages\"\n";
   62   my @modules = @{ $ce->{pg}->{modules} };
   63   foreach my $module_packages_ref (@modules) {
   64     my ($module, @extra_packages) = @$module_packages_ref;
   65     # the first item is the main package
   66     $translator->evaluate_modules($module);
   67     # the remaining items are "extra" packages
   68     $translator->load_extra_packages(@extra_packages);
   69   }
   70 
   71   # set the environment (from defineProblemEnvir)
   72   #warn "PG: setting the environment (from defineProblemEnvir)\n";
   73   my $envir = defineProblemEnvir(
   74     $ce,
   75     $user,
   76     $key,
   77     $set,
   78     $problem,
   79     $psvn,
   80     $formFields,
   81     $translationOptions,
   82   );
   83   $translator->environment($envir);
   84 
   85   # initialize the Translator
   86   #warn "PG: initializing the Translator\n";
   87   $translator->initialize();
   88 
   89   # load IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load
   90   # i'd like to change this at some point to have the same sort of interface to global.conf
   91   # that the module loading does -- have a list of macros to load unrestrictedly.
   92   #warn "PG: loading IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load\n";
   93   foreach (qw(IO.pl PG.pl dangerousMacros.pl)) {
   94     my $macroPath = $ce->{pg}->{directories}->{macros} . "/$_";
   95     my $err = $translator->unrestricted_load($macroPath);
   96     warn "Error while loading $macroPath: $err" if $err;
   97   }
   98 
   99   # set the opcode mask (using default values)
  100   #warn "PG: setting the opcode mask (using default values)\n";
  101   $translator->set_mask();
  102 
  103   # store the problem source
  104   #warn "PG: storing the problem source\n";
  105   my $sourceFile = $problem->source_file;
  106   $sourceFile = $ce->{courseDirs}->{templates}."/".$sourceFile
  107     unless ($sourceFile =~ /^\//);
  108   eval { $translator->source_string(readFile($sourceFile)) };
  109   if ($@) {
  110     # well, we couldn't get the problem source, for some reason.
  111     return bless {
  112       translator => $translator,
  113       head_text  => "",
  114       body_text  => <<EOF,
  115 WeBWorK::Utils::readFile($sourceFile) says:
  116 $@
  117 EOF
  118       answers    => {},
  119       result     => {},
  120       state      => {},
  121       errors     => "Failed to read the problem source file.",
  122       warnings   => $warnings,
  123       flags      => {error_flag => 1},
  124     }, $class;
  125   }
  126 
  127   # install a safety filter (&safetyFilter)
  128   #warn "PG: installing a safety filter\n";
  129   $translator->rf_safety_filter(\&safetyFilter);
  130 
  131   # write timing log entry -- the translator is now all set up
  132   writeTimingLogEntry($ce, "WeBWorK::PG::new",
  133     "initialized",
  134     "intermediate");
  135 
  136   # translate the PG source into text
  137   #warn "PG: translating the PG source into text\n";
  138   $translator->translate();
  139 
  140   # after we're done translating, we may have to clean up after the
  141   # translator:
  142 
  143   # for example, HTML_img mode uses a tempdir for dvipng's temp files.\
  144   # We have to remove it.
  145   if ($envir->{dvipngTempDir}) {
  146     rmtree($envir->{dvipngTempDir}, 0, 0);
  147   }
  148 
  149   # HTML_dpng, on the other hand, uses an ImageGenerator. We have to
  150   # render the queued equations.
  151   if ($envir->{imagegen}) {
  152     my $sourceFile = $ce->{courseDirs}->{templates} . "/" . $problem->source_file;
  153     my %mtimeOption = -e $sourceFile
  154       ? (mtime => (stat $sourceFile)[9])
  155       : ();
  156 
  157     $envir->{imagegen}->render(
  158       refresh => $translationOptions->{refreshMath2img},
  159       %mtimeOption,
  160     );
  161   }
  162 
  163   my ($result, $state); # we'll need these on the other side of the if block!
  164   if ($translationOptions->{processAnswers}) {
  165 
  166     # process student answers
  167     #warn "PG: processing student answers\n";
  168     $translator->process_answers($formFields);
  169 
  170     # retrieve the problem state and give it to the translator
  171     #warn "PG: retrieving the problem state and giving it to the translator\n";
  172     $translator->rh_problem_state({
  173       recorded_score =>       $problem->status,
  174       num_of_correct_ans =>   $problem->num_correct,
  175       num_of_incorrect_ans => $problem->num_incorrect,
  176     });
  177 
  178     # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by
  179     # the PG macro package (PG.pl)
  180     #warn "PG: determining an entry order\n";
  181     my @answerOrder =
  182       $translator->rh_flags->{ANSWER_ENTRY_ORDER}
  183         ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} }
  184         : keys %{ $translator->rh_evaluated_answers };
  185 
  186     # install a grader -- use the one specified in the problem,
  187     # or fall back on the default from the course environment.
  188     # (two magic strings are accepted, to avoid having to
  189     # reference code when it would be difficult.)
  190     #warn "PG: installing a grader\n";
  191     my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE}
  192       || $ce->{pg}->{options}->{grader};
  193     $grader = $translator->rf_std_problem_grader
  194       if $grader eq "std_problem_grader";
  195     $grader = $translator->rf_avg_problem_grader
  196       if $grader eq "avg_problem_grader";
  197     die "Problem grader $grader is not a CODE reference."
  198       unless ref $grader eq "CODE";
  199     $translator->rf_problem_grader($grader);
  200 
  201     # grade the problem
  202     #warn "PG: grading the problem\n";
  203     ($result, $state) = $translator->grade_problem(
  204       answers_submitted  => $translationOptions->{processAnswers},
  205       ANSWER_ENTRY_ORDER => \@answerOrder,
  206     );
  207 
  208   }
  209 
  210   # write timing log entry
  211   writeTimingLogEntry($ce, "WeBWorK::PG::new", "", "end");
  212 
  213   # return an object which contains the translator and the results of
  214   # the translation process. this is DIFFERENT from the "format expected
  215   # by Webwork.pm (and I believe processProblem8, but check.)"
  216   return bless {
  217     translator => $translator,
  218     head_text  => ${ $translator->r_header },
  219     body_text  => ${ $translator->r_text   },
  220     answers    => $translator->rh_evaluated_answers,
  221     result     => $result,
  222     state      => $state,
  223     errors     => $translator->errors,
  224     warnings   => $warnings,
  225     flags      => $translator->rh_flags,
  226   }, $class;
  227 }
  228 
  229 # -----
  230 
  231 sub defineProblemEnvir {
  232   my (
  233     $ce,
  234     $user,
  235     $key,
  236     $set,
  237     $problem,
  238     $psvn,
  239     $formFields,
  240     $options,
  241   ) = @_;
  242 
  243   my %envir;
  244 
  245   # ----------------------------------------------------------------------
  246 
  247   # PG environment variables
  248   # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002
  249   # any changes are noted by "ADDED:" or "REMOVED:"
  250 
  251   # Vital state information
  252   # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img,
  253   #        texDisposition
  254 
  255   $envir{psvn}              = $set->psvn;
  256   $envir{psvnNumber}        = $envir{psvn};
  257   $envir{probNum}           = $problem->problem_id;
  258   $envir{questionNumber}    = $envir{probNum};
  259   $envir{fileName}          = $problem->source_file;
  260   $envir{probFileName}      = $envir{fileName};
  261   $envir{problemSeed}       = $problem->problem_seed;
  262   $envir{displayMode}       = translateDisplayModeNames($options->{displayMode});
  263   $envir{languageMode}      = $envir{displayMode};
  264   $envir{outputMode}        = $envir{displayMode};
  265   $envir{displayHintsQ}     = $options->{showHints};
  266   $envir{displaySolutionsQ} = $options->{showSolutions};
  267   # FIXME: this is HTML_img specific
  268   #$envir{refreshMath2img}   = $options->{refreshMath2img};
  269   $envir{texDisposition}    = "pdf"; # in webwork-modperl, we use pdflatex
  270 
  271   # Problem Information
  272   # ADDED: courseName, formatedDueDate
  273 
  274   $envir{openDate}            = $set->open_date;
  275   $envir{formattedOpenDate}   = formatDateTime($envir{openDate});
  276   $envir{dueDate}             = $set->due_date;
  277   $envir{formattedDueDate}    = formatDateTime($envir{dueDate});
  278   $envir{formatedDueDate}     = $envir{formattedDueDate}; # typo in many header files
  279   $envir{answerDate}          = $set->answer_date;
  280   $envir{formattedAnswerDate} = formatDateTime($envir{answerDate});
  281   $envir{numOfAttempts}       = ($problem->num_correct || 0) + ($problem->num_incorrect || 0);
  282   $envir{problemValue}        = $problem->value;
  283   $envir{sessionKey}          = $key;
  284   $envir{courseName}          = $ce->{courseName};
  285 
  286   # Student Information
  287   # ADDED: studentID
  288 
  289   $envir{sectionName}      = $user->section;
  290   $envir{sectionNumber}    = $envir{sectionName};
  291   $envir{recitationName}   = $user->recitation;
  292   $envir{recitationNumber} = $envir{recitationName};
  293   $envir{setNumber}        = $set->set_id;
  294   $envir{studentLogin}     = $user->user_id;
  295   $envir{studentName}      = $user->first_name . " " . $user->last_name;
  296   $envir{studentID}        = $user->student_id;
  297 
  298   # Answer Information
  299   # REMOVED: refSubmittedAnswers
  300 
  301   $envir{inputs_ref} = $formFields;
  302 
  303   # External Programs
  304   # ADDED: externalLaTeXPath, externalDvipngPath,
  305   #        externalGif2EpsPath, externalPng2EpsPath
  306 
  307   $envir{externalTTHPath}      = $ce->{externalPrograms}->{tth};
  308   $envir{externalLaTeXPath}    = $ce->{externalPrograms}->{latex};
  309   $envir{externalDvipngPath}   = $ce->{externalPrograms}->{dvipng};
  310   $envir{externalGif2EpsPath}  = $ce->{externalPrograms}->{gif2eps};
  311   $envir{externalPng2EpsPath}  = $ce->{externalPrograms}->{png2eps};
  312   $envir{externalGif2PngPath}  = $ce->{externalPrograms}->{gif2png};
  313 
  314   # Directories and URLs
  315   # REMOVED: courseName
  316   # ADDED: dvipngTempDir
  317 
  318   $envir{cgiDirectory}           = undef;
  319   $envir{cgiURL}                 = undef;
  320   $envir{classDirectory}         = undef;
  321   $envir{courseScriptsDirectory} = $ce->{pg}->{directories}->{macros}."/";
  322   $envir{htmlDirectory}          = $ce->{courseDirs}->{html}."/";
  323   $envir{htmlURL}                = $ce->{courseURLs}->{html}."/";
  324   $envir{macroDirectory}         = $ce->{courseDirs}->{macros}."/";
  325   $envir{templateDirectory}      = $ce->{courseDirs}->{templates}."/";
  326   $envir{tempDirectory}          = $ce->{courseDirs}->{html_temp}."/";
  327   $envir{tempURL}                = $ce->{courseURLs}->{html_temp}."/";
  328   $envir{scriptDirectory}        = undef;
  329   $envir{webworkDocsURL}         = $ce->{webworkURLs}->{docs}."/";
  330   # FIXME: this is HTML_img mode-specific
  331   #$envir{dvipngTempDir}          = $options->{displayMode} eq 'images'
  332   # ? makeTempDirectory($envir{tempDirectory}, "webwork-dvipng")
  333   # : undef;
  334 
  335   # Information for sending mail
  336 
  337   $envir{mailSmtpServer} = $ce->{mail}->{smtpServer};
  338   $envir{mailSmtpSender} = $ce->{mail}->{smtpSender};
  339   $envir{ALLOW_MAIL_TO}  = $ce->{mail}->{allowedRecipients};
  340 
  341   # Default values for evaluating answers
  342 
  343   my $ansEvalDefaults = $ce->{pg}->{ansEvalDefaults};
  344   $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults);
  345 
  346   # ----------------------------------------------------------------------
  347 
  348   my $basename = "equation-$envir{psvn}.$envir{probNum}";
  349   $basename .= ".$envir{problemSeed}" if $envir{problemSeed};
  350 
  351   # Object for generating equation images
  352   $envir{imagegen} = WeBWorK::PG::ImageGenerator->new(
  353     tempDir  => $ce->{webworkDirs}->{tmp}, # global temp dir
  354     dir  => $envir{tempDirectory},
  355     url  => $envir{tempURL},
  356     basename => $basename,
  357     latex  => $envir{externalLaTeXPath},
  358     dvipng   => $envir{externalDvipngPath},
  359   );
  360 
  361   # Other things...
  362   $envir{QUIZ_PREFIX}              = $options->{QUIZ_PREFIX}; # used by quizzes
  363   $envir{PROBLEM_GRADER_TO_USE}    = $ce->{pg}->{options}->{grader};
  364   $envir{PRINT_FILE_NAMES_FOR}     = $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR};
  365 
  366   # variables for interpreting capa problems.
  367   $envir{CAPA_Tools}               = $ce->{pg}->{specialPGEnvironmentVars}->{CAPA_Tools};
  368   $envir{CAPA_MCTools}             = $ce->{pg}->{specialPGEnvironmentVars}->{CAPA_MCTools};
  369   $envir{CAPA_Graphics_URL}        = $ce->{pg}->{specialPGEnvironmentVars}->{CAPA_Graphics_URL};
  370   $envir{CAPA_GraphicsDirectory}   = $ce->{pg}->{specialPGEnvironmentVars}->{CAPA_GraphicsDirectory};
  371 
  372   return \%envir;
  373 }
  374 
  375 sub translateDisplayModeNames($) {
  376   my $name = shift;
  377   return {
  378     tex           => "TeX",
  379     plainText     => "HTML",
  380     formattedText => "HTML_tth",
  381     images        => "HTML_dpng", # "HTML_img",
  382   }->{$name};
  383 }
  384 
  385 sub safetyFilter {
  386   my $answer = shift; # accepts one answer and checks it
  387   my $submittedAnswer = $answer;
  388   $answer = '' unless defined $answer;
  389   my ($errorno);
  390   $answer =~ tr/\000-\037/ /;
  391   # Return if answer field is empty
  392   unless ($answer =~ /\S/) {
  393     #$errorno = "<BR>No answer was submitted.";
  394     $errorno = 0;  ## don't report blank answer as error
  395     return ($answer,$errorno);
  396   }
  397   # replace ^ with **    (for exponentiation)
  398   # $answer =~ s/\^/**/g;
  399   # Return if forbidden characters are found
  400   unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\[\]\(\)\,\|]+$/ )  {
  401     $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c;
  402     $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>";
  403     return ($answer,$errorno);
  404   }
  405   $errorno = 0;
  406   return($answer, $errorno);
  407 }
  408 
  409 1;
  410 
  411 __END__
  412 
  413 =head1 SYNOPSIS
  414 
  415  $pg = WeBWorK::PG->new(
  416    $ce,         # a WeBWorK::CourseEnvironment object
  417    $user,       # a WeBWorK::DB::Record::User object
  418    $sessionKey,
  419    $set,        # a WeBWorK::DB::Record::UserSet object
  420    $problem,    # a WeBWorK::DB::Record::UserProblem object
  421    $psvn,
  422    $formFields  # in &WeBWorK::Form::Vars format
  423    { # translation options
  424      displayMode     => "images", # (plainText|formattedText|images)
  425      showHints       => 1,        # (0|1)
  426      showSolutions   => 0,        # (0|1)
  427      refreshMath2img => 0,        # (0|1)
  428      processAnswers  => 1,        # (0|1)
  429    },
  430  );
  431 
  432  $translator = $pg->{translator}; # WeBWorK::PG::Translator
  433  $body       = $pg->{body_text};  # text string
  434  $header     = $pg->{head_text};  # text string
  435  $answerHash = $pg->{answers};    # WeBWorK::PG::AnswerHash
  436  $result     = $pg->{result};     # hash reference
  437  $state      = $pg->{state};      # hash reference
  438  $errors     = $pg->{errors};     # text string
  439  $warnings   = $pg->{warnings};   # text string
  440  $flags      = $pg->{flags};      # hash reference
  441 
  442 =head1 DESCRIPTION
  443 
  444 WeBWorK::PG encapsulates the PG translation process, making multiple calls to
  445 WeBWorK::PG::Translator. Much of the flexibility of the Translator is hidden,
  446 instead making choices that are appropriate for the webwork-modperl system.
  447 
  448 =head1 CONSTRUCTION
  449 
  450 =over
  451 
  452 =item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS)
  453 
  454 The C<new> method creates a translator, initializes it using the parameters
  455 specified, translates a PG file, and processes answers. It returns a reference
  456 to a blessed hash containing the results of the translation process.
  457 
  458 =back
  459 
  460 =head2 Parameters
  461 
  462 =over
  463 
  464 =item ENVIRONMENT
  465 
  466 a WeBWorK::CourseEnvironment object
  467 
  468 =item USER
  469 
  470 a WeBWorK::User object
  471 
  472 =item KEY
  473 
  474 the session key of the current session
  475 
  476 =item SET
  477 
  478 a WeBWorK::Set object
  479 
  480 =item PROBLEM
  481 
  482 a WeBWorK::DB::Record::UserProblem object. The contents of the source_file
  483 field can specify a PG file either by absolute path or path relative to the
  484 "templates" directory. I<The caller should remove taint from this value before
  485 passing!>
  486 
  487 =item PSVN
  488 
  489 the problem set version number
  490 
  491 =item FIELDS
  492 
  493 a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form
  494 fields submitted by a problem processor. The translator will look for fields
  495 like "AnSwEr[0-9]" containing submitted student answers.
  496 
  497 =item OPTIONS
  498 
  499 a reference to a hash containing the following data:
  500 
  501 =over
  502 
  503 =item displayMode
  504 
  505 one of "plainText", "formattedText", or "images"
  506 
  507 =item showHints
  508 
  509 boolean, render hints
  510 
  511 =item showSolutions
  512 
  513 boolean, render solutions
  514 
  515 =item refreshMath2img
  516 
  517 boolean, force images created by math2img (in "images" mode) to be recreated,
  518 even if the PG source has not been updated. FIXME: change the name of this
  519 option to "refreshEquations" and update the docs accordingly.
  520 
  521 =item processAnswers
  522 
  523 boolean, call answer evaluators and graders
  524 
  525 =back
  526 
  527 =back
  528 
  529 =head2 RETURN VALUE
  530 
  531 The C<new> method returns a blessed hash reference containing the following
  532 fields. More information can be found in the documentation for
  533 WeBWorK::PG::Translator.
  534 
  535 =over
  536 
  537 =item translator
  538 
  539 The WeBWorK::PG::Translator object used to render the problem.
  540 
  541 =item head_text
  542 
  543 HTML code for the E<lt>headE<gt> block of an resulting web page. Used for
  544 JavaScript features.
  545 
  546 =item body_text
  547 
  548 HTML code for the E<lt>bodyE<gt> block of an resulting web page.
  549 
  550 =item answers
  551 
  552 An C<AnswerHash> object containing submitted answers, and results of answer
  553 evaluation.
  554 
  555 =item result
  556 
  557 A hash containing the results of grading the problem.
  558 
  559 =item state
  560 
  561 A hash containing the new problem state.
  562 
  563 =item errors
  564 
  565 A string containing any errors encountered while rendering the problem.
  566 
  567 =item warnings
  568 
  569 A string containing any warnings encountered while rendering the problem.
  570 
  571 =item flags
  572 
  573 A hash containing PG_flags (see the Translator docs).
  574 
  575 =back
  576 
  577 =head1 OPERATION
  578 
  579 WeBWorK::PG goes through the following operations when constructed:
  580 
  581 =over
  582 
  583 =item Get database information
  584 
  585 Retrieve information about the current user, set, and problem from the
  586 database.
  587 
  588 =item Create a translator
  589 
  590 Instantiate a WeBWorK::PG::Translator object.
  591 
  592 =item Set the directory hash
  593 
  594 Set the translator's directory hash (courseScripts, macros, templates, and temp
  595 directories) from the course environment.
  596 
  597 =item Evaluate PG modules
  598 
  599 Using the module list from the course environment (pg->modules), perform a
  600 "use"-like operation to evaluate modules at runtime.
  601 
  602 =item Set the problem environment
  603 
  604 Use data from the user, set, and problem, as well as the course environemnt and
  605 translation options, to set the problem environment.
  606 
  607 =item Initialize the translator
  608 
  609 Call &WeBWorK::PG::Translator::initialize. What more do you want?
  610 
  611 =item Load PG.pl and dangerousMacros.pl
  612 
  613 These macros must be loaded without opcode masking, so they are loaded here.
  614 
  615 =item Set the opcode mask
  616 
  617 Set the opcode mask to the default specified by WeBWorK::PG::Translator.
  618 
  619 =item Load the problem source
  620 
  621 Give the problem source to the translator.
  622 
  623 =item Install a safety filter
  624 
  625 The safety filter is used to preprocess student input before evaluation. The
  626 default safety filter, &WeBWorK::PG::safetyFilter, is used.
  627 
  628 =item Translate the problem source
  629 
  630 Call &WeBWorK::PG::Translator::translate to render the problem source into the
  631 format given by the display mode.
  632 
  633 =item Process student answers
  634 
  635 Use form field inputs to evaluate student answers.
  636 
  637 =item Load the problem state
  638 
  639 Use values from the database to initialize the problem state, so that the
  640 grader will have a point of reference.
  641 
  642 =item Determine an entry order
  643 
  644 Use the ANSWER_ENTRY_ORDER flag to determine the order of answers in the
  645 problem. This is important for problems with dependancies among parts.
  646 
  647 =item Install a grader
  648 
  649 Use the PROBLEM_GRADER_TO_USE flag, or a default from the course environment,
  650 to install a grader.
  651 
  652 =item Grade the problem
  653 
  654 Use the selected grader to grade the problem.
  655 
  656 =back
  657 
  658 =head1 AUTHOR
  659 
  660 Written by Sam Hathaway, sh002i (at) math.rochester.edu.
  661 
  662 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9