From: Mike G. v. a. <we...@ma...> - 2005-07-16 22:29:44
|
Log Message: ----------- Added documentation for macros used in constructing sequential problems. Modified Files: -------------- pg/macros: PG.pl PGsequentialmacros.pl Revision Data ------------- Index: PG.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PG.pl,v retrieving revision 1.20 retrieving revision 1.21 diff -Lmacros/PG.pl -Lmacros/PG.pl -u -r1.20 -r1.21 --- macros/PG.pl +++ macros/PG.pl @@ -255,10 +255,30 @@ my @in = @_; $STRINGforOUTPUT .= join(" ",@in); } + +=head2 STOP_RENDERING() + + STOP_RENDERING() unless all_answers_are_correct; + +No text is printed and no answer blanks or answer evaluators are stored or processed until +RESUME_RENDERING() is executed. + +=cut + sub STOP_RENDERING { $PG_STOP_FLAG=1; ""; } + +=head2 RESUME_RENDERING() + + RESUME_RENDERING(); + +Resumes processing of text, answer blanks, and +answer evaluators. + +=cut + sub RESUME_RENDERING { $PG_STOP_FLAG=0; ""; Index: PGsequentialmacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGsequentialmacros.pl,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmacros/PGsequentialmacros.pl -Lmacros/PGsequentialmacros.pl -u -r1.1 -r1.2 --- macros/PGsequentialmacros.pl +++ macros/PGsequentialmacros.pl @@ -1,3 +1,66 @@ + +=head1 NAME + + PGsequentialmacros.pl + +Provides support for writing sequential problems, where certain parts +of the problem are hidden until earlier questions are answered correctly. + + +=head1 SYNPOSIS + + The basic sequential problem structure: + + DOCUMENT(); + loadMacros(.....); + ## first segment ## + BEGIN_TEXT + The first question: Enter \(sin(0) = \) \{ans_rule\}. + END_TEXT + ANS(num_cmp(0)); + if (@incorrect_answers = get_incorrect_answers( ) ) { + TEXT( "These answers are not correct ", join(" ",@incorrect_answers),$BR); + foreach my $label (@incorrect_answers) { + checkAnswer($label,debug=>1); + } + } + if (all_answers_are_correct() ) { + TEXT("$PAR Right! Now for the next part of the problem"); + } else { + STOP_RENDERING(); + } + ## second segment ## + .... + if (@incorrect_answers = get_incorrect_answers( ) ) { + TEXT( "These answers are not correct ", join(" ",@incorrect_answers),$BR); + foreach my $label (@incorrect_answers) { + checkAnswer($label,debug=>1); + } + } + if (all_answers_are_correct() ) { + TEXT("$PAR Right! Now for the next part of the problem"); + } else { + STOP_RENDERING(); + } + ## third segment ## + ENDDOCUMENT() # must be the last statement in the problem + + + +=head1 DESCRIPTION + + +=cut + + +=head2 listFormVariables + + listFormVariables(); + +Lists all variables submitted in the problem form. This is used for debugging. + +=cut + sub listFormVariables { # Lists all of the variables filled out on the input form # Useful for debugging @@ -7,6 +70,19 @@ TEXT(pretty_print(\%envir)); TEXT($HR); } + +=head2 checkAnswer + + + checkAnswer($label); + +Checks the answer to the question labeled C<$label>. The result is 1 if the answer is completely correct. +0 if the answer is wrong or partially wrong and undefined if that question has not yet +been answered. (Specifically if no answer hash is produced when the answer is evaluated +by the corresponding answer evaluator.) + +=cut + sub checkAnswer { # checks an answer on a given answer evaluator. my $answerName = shift; # get the name of the answer @@ -26,11 +102,34 @@ } return $response; # response is (undef => no answer, 1=> correct answer, 0 => not completely correct } + +=head2 listQueuedAnswers + + listQueuedAnswers(); + +Lists the labels of the answer blanks which have been printed so far. +The return value is a string which can be printed. This is mainly +used for debugging. + +=cut + + sub listQueuedAnswers { # lists the names of the answer blanks so far; my %pg_answers_hash = get_PG_ANSWERS_HASH(); join(" ", keys %pg_answers_hash); } + +=head2 checkQueuedAnswers + + checkQueuedAnswers(); + +Returns a hash whose key/value pairs are the labels of the questions +have been printed so far and the scores obtained by evaluating the +answers to these questions. + +=cut + sub checkQueuedAnswers { # gather all of the answers submitted up to this time my %options = @_; @@ -42,6 +141,16 @@ } %scores; } + +=head2 all_answers_are_correct + + all_answers_are_correct(); + +Returns 1 if there is at least one answer and all of the questions +printed so far have been answered correctly. + +=cut + sub all_answers_are_correct{ # return 1 if all scores are 1, else it returns 0; # returns 0 if no answers have been checked yet @@ -51,6 +160,18 @@ foreach my $label (keys %scores) { if (not defined($scores{$label}) or $scores{$label} <1) {$result=0; last;} }; $result; } + +=head2 get_incorrect_answers + + get_incorrect_answers(); + +Returns a list of labels of questions which have been printed and have +been answered incorrectly. This list does NOT include blank or undefined +answers. It's possible for the returned list to be empty AND for all_answers_are_correct() +to return false. + +=cut + sub get_incorrect_answers { # returns only incorrect answers, not blank or undefined answers. my %scores = checkQueuedAnswers(); |