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).
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( $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.
)
# ^function phase_pi
sub phase_pi {
my ($num,%options) = @_;
my $process_ans_hash = ( ref( $num ) eq 'AnswerHash' ) ? 1 : 0 ;
my ($rh_ans);
if ($process_ans_hash) {
$rh_ans = $num;
$num = $rh_ans->{correct_ans};
}
while( ($rh_ans->{correct_ans}) > 3.14159265358979/2 ){
$rh_ans->{correct_ans} -= 3.14159265358979;
}
while( ($rh_ans->{correct_ans}) <= -3.14159265358979/2 ){
$rh_ans->{correct_ans} += 3.14159265358979;
}
$rh_ans;
}
replaces pi, e, and ^ with their Perl equivalents
if useBaseTenLog is non-zero, convert log to logten
is_array($rh_ans)
returns: $rh_ans. Throws error "NOTARRAY" if this is not an array
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 ($rh_ans, %options)
returns $rh_ans
check_strings ($rh_ans, %options)
returns $rh_ans
These two subroutines can be used in filters to set default options. They
help make filters perform in uniform, predictable ways, and also make it
easy to recognize from the code which options a given filter expects.
Use this to assign aliases for the standard options. It must come before set_default_options
within the subroutine.
assign_option_aliases(\%options,
'alias1' => 'option5'
'alias2' => 'option7'
);
If the subroutine is called with an option " alias1 => 23 " it will behave as if
it had been
called with the option " option5 => 23 "
set_default_options(\%options,
'_filter_name' => 'filter',
'option5' => .0001,
'option7' => 'ascii',
'allow_unknown_options => 0,
}
Note that the first entry is a reference to the options with which the filter was
called.
The option5 is set to .0001 unless the option is explicitly set when the subroutine
is called.
The '_filter_name' option should always be set, although there is no error if it
is missing.
It is used mainly for debugging answer evaluators and allows
you to keep track of which filter is currently processing the answer.
If 'allow_unknown_options' is set to 0 then if the filter is called with options
which do NOT appear in the
set_default_options list an error will be signaled and a warning message will be
printed out. This provides
error checking against misspelling an option and is generally what is desired for
most filters.
Occasionally one wants to write a filter which accepts a long list of options, not
all of which are known in advance,
but only uses a subset of the options
provided. In this case, setting 'allow_unkown_options' to 1 prevents the error
from being signaled.
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);
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.
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);
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
File path = /ww/webwork/pg/macros/PGanswermacros.pl