PGanswermacros.pl - Macros for building answer evaluators.
Number Answer Evaluators:
num_cmp() -- uses an input hash to determine parameters
std_num_cmp(), std_num_cmp_list(), std_num_cmp_abs, std_num_cmp_abs_list()
frac_num_cmp(), frac_num_cmp_list(), frac_num_cmp_abs, frac_num_cmp_abs_list()
arith_num_cmp(), arith_num_cmp_list(), arith_num_cmp_abs, arith_num_cmp_abs_list()
strict_num_cmp(), strict_num_cmp_list(), strict_num_cmp_abs, strict_num_cmp_abs_list()
numerical_compare_with_units() -- requires units as part of the answer
std_num_str_cmp() -- also accepts a set of strings as possible answers
Function Answer Evaluators:
fun_cmp() -- uses an input hash to determine parameters
function_cmp(), function_cmp_abs()
function_cmp_up_to_constant(), function_cmp_up_to_constant_abs()
multivar_function_cmp()
String Answer Evaluators:
str_cmp() -- uses an input hash to determine parameters
std_str_cmp(), std_str_cmp_list(), std_cs_str_cmp(), std_cs_str_cmp_list()
strict_str_cmp(), strict_str_cmp_list()
ordered_str_cmp(), ordered_str_cmp_list(), ordered_cs_str_cmp(), ordered_cs_str_cmp_list()
unordered_str_cmp(), unordered_str_cmp_list(), unordered_cs_str_cmp(), unordered_cs_str_cmp_list()
Miscellaneous Answer Evaluators:
checkbox_cmp()
radio_cmp()
The macros in this file are factories which construct and return answer evaluators for checking student answers. The macros take various arguments, including the correct answer, and return an "answer evaluator", which is a subroutine reference suitable for passing to the ANS* family of macro.
When called with the student's answer, the answer evaluator will compare this answer to the correct answer that it keeps internally and returns an AnswerHash representing the results of the comparison. Part of the answer hash is a score, which is a number between 0 and 1 representing the correctness of the student's answer. The fields of an AnswerHash are as follows:
score => $correctQ,
correct_ans => $originalCorrEqn,
student_ans => $modified_student_ans,
original_student_ans => $original_student_answer,
ans_message => $PGanswerMessage,
type => 'typeString',
preview_text_string => $preview_text_string,
preview_latex_string => $preview_latex_string, # optional
$ans_hash{score}
a number between 0 and 1 indicating whether the answer is correct. Fractions allow the implementation of partial credit for incorrect answers.
$ans_hash{correct_ans}
The correct answer, as supplied by the instructor and then formatted. This can be viewed by the student after the answer date.
$ans_hash{student_ans}
This is the student answer, after reformatting; for example the answer might be forced to capital letters for comparison with the instructors answer. For a numerical answer, it gives the evaluated answer. This is displayed in the section reporting the results of checking the student answers.
$ans_hash{original_student_ans}
This is the original student answer. This is displayed on the preview page and may be used for sticky answers.
$ans_hash{ans_message}
Any error message, or hint provided by the answer evaluator. This is also displayed in the section reporting the results of checking the student answers.
$ans_hash{type}
A string indicating the type of answer evaluator. This helps in preprocessing the student answer for errors. Some examples: 'number_with_units'
, 'function'
, 'frac_number'
, 'arith_number'
.
$ans_hash{preview_text_string}
This typically shows how the student answer was parsed. It is displayed on the preview page. For a student answer of 2sin(3x) this would be 2*sin(3*x). For string answers it is typically the same as $ans_hash{student_ans}.
$ans_hash{preview_latex_string}
(Optional.) This is latex version of the student answer which is used to show a typeset view on the answer on the preview page. For a student answer of 2/3, this would be \frac{2}{3}.
The answer macros have been split up into several separate files, one for each type:
PGnumericevaluators.pl - contains answer evaluators for evaluating numeric values, including num_cmp() and related.
PGfunctionevaluators.pl - contains answer evaluators for evaluating functions, including fun_cmp() and related.
PGstringevaluators.pl - contains answer evaluators for evaluating strings, including str_cmp() and related.
PGtextevaluators.pl - contains answer evaluators that handle free response questions and questionnaires.
PGmiscevaluators.pl - contains answer evaluators that don't seem to fit into other categories.
A filter is a short subroutine with the following structure. It accepts an AnswerHash, followed by a hash of options. It returns an AnswerHash
$ans_hash = filter($ans_hash, %options);
See the AnswerHash.pm file for a list of entries which can be expected to be found in an AnswerHash, such as 'student_ans', 'score' and so forth. Other entries may be present for specialized answer evaluators.
The hope is that a well designed set of filters can easily be combined to form a new answer_evaluator and that this method will produce answer evaluators which are are more robust than the method of copying existing answer evaluators and modifying them.
Here is an outline of how a filter is constructed:
sub filter{
my $rh_ans = shift;
my %options = @_;
assign_option_aliases(\%options,
'alias1' => 'option5'
'alias2' => 'option7'
);
set_default_options(\%options,
'_filter_name' => 'filter',
'option5' => .0001,
'option7' => 'ascii',
'allow_unknown_options => 0,
}
.... body code of filter .......
if ($error) {
$rh_ans->throw_error("FILTER_ERROR", "Something went wrong");
# see AnswerHash.pm for details on using the throw_error method.
$rh_ans; #reference to an AnswerHash object is returned.
}
std_num_filter($rh_ans, %options)
returns $rh_ans
Replaces some constants using math_constants, then evaluates a perl expression.
std_num_array_filter($rh_ans, %options)
returns $rh_ans
Assumes the {student_ans} field is a numerical array, and applies BOTH check_syntax and std_num_filter to each element of the array. Does it's best to generate sensible error messages for syntax errors. A typical error message displayed in {studnet_ans} might be ( 56, error message, -4).
is_zero_array
best_approx_parameters
best_approx_parameters($rh_ans,%options); # requires the following fields in $rh_ans
{rf_student_ans} # reference to the test answer
{rf_correct_ans} # reference to the comparison answer
{evaluation_points}, # an array of row vectors indicating the points
# to evaluate when comparing the functions
%options # debug => 1 gives more error answers
# param_vars => [''] additional parameters used to adapt to function
)
The parameters for the comparison function which best approximates the test_function are stored in the field {ra_parameters}.
The last $dim_of_parms_space variables are assumed to be parameters, and it is also assumed that the function \&comparison_fun depends linearly on these variables. This function finds the values for these parameters which minimizes the Euclidean distance (L2 distance) between the test function and the comparison function and the test points specified by the array reference \@rows_of_test_points. This is assumed to be an array of arrays, with the inner arrays determining a test point.
The comparison function should have $dim_of_params_space more input variables than the test function.
calculate_difference_vector
calculate_difference_vector( $ans_hash, %options);
{rf_student_ans}, # a reference to the test function
rf_correct_ans}, # a reference to the correct answer function
evaluation_points}, # an array of row vectors indicating the points
# to evaluate when comparing the functions
ra_parameters} # these are the (optional) additional inputs to
# the comparison function which adapt it properly
# to the problem at hand.
%options # mode => 'rel' specifies that each element in the
# difference matrix is divided by the correct answer.
# unless the correct answer is nearly 0.
fix_answer_for_display
evaluatesToNumber
is_a_number
is_a_fraction
phase_pi
I often discovered that the answers I was getting, when using the arctan function would be off by phases of pi, which for the tangent function, were equivalent values. This method allows for this.
is_an_arithemetic_expression
math_constants
replaces pi, e, and ^ with their Perl equivalents if useBaseTenLog is non-zero, convert log to logten
is_array
is_array($rh_ans)
returns:
$rh_ans
. Throws error "NOTARRAY" if this is not an array
check_syntax
check_syntax( $rh_ans, %options)
returns an answer hash.
latex2html preview code are installed in the answer hash. The input has been transformed, changing 7pi to 7*pi or 7x to 7*x. Syntax error messages may be generated and stored in student_ans Additional syntax error messages are stored in {ans_message} and duplicated in {error_message}
check_strings
check_strings ($rh_ans, %options)
returns $rh_ans
check_units
check_strings ($rh_ans, %options)
returns $rh_ans
std_problem_grader
This is an all-or-nothing grader. A student must get all parts of the problem write before receiving credit. You should make sure to use this grader on multiple choice and true-false questions, otherwise students will be able to deduce how many answers are correct by the grade reported by webwork.
install_problem_grader(~~&std_problem_grader);
std_problem_grader2
This is an all-or-nothing grader. A student must get all parts of the problem write before receiving credit. You should make sure to use this grader on multiple choice and true-false questions, otherwise students will be able to deduce how many answers are correct by the grade reported by webwork.
install_problem_grader(~~&std_problem_grader2);
The only difference between the two versions is at the end of the subroutine, where std_problem_grader2 records the attempt only if there have been no syntax errors, whereas std_problem_grader records it regardless.
avg_problem_grader
This grader gives a grade depending on how many questions from the problem are correct. (The highest grade is the one that is kept. One can never lower the recorded grade on a problem by repeating it.) Many professors (and almost all students :-) ) prefer this grader.
install_problem_grader(~~&avg_problem_grader);
pretty_print
Usage: warn pretty_print( $rh_hash_input)
TEXT(pretty_print($ans_hash));
TEXT(~~%envir);
This can be very useful for printing out messages about objects while debugging