PGanswermacros.pl - Macros for building answer evaluators.

From WeBWorK

Jump to: navigation


NAME

PGanswermacros.pl - Macros for building answer evaluators.

SYNPOSIS

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()

DESCRIPTION

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}.

MACROS

Answer evaluator macros

The answer macros have been split up into several separate files, one for each type:

the PGnumericevaluators.pl manpage - contains answer evaluators for evaluating numeric values, including num_cmp() and related.

the PGfunctionevaluators.pl manpage - contains answer evaluators for evaluating functions, including fun_cmp() and related.

the PGstringevaluators.pl manpage - contains answer evaluators for evaluating strings, including str_cmp() and related.

the PGtextevaluators.pl manpage - contains answer evaluators that handle free response questions and questionnaires.

the PGmiscevaluators.pl manpage - contains answer evaluators that don't seem to fit into other categories.

Filters

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.
        }

compare_numbers

std_num_filter

        std_num_filter($rh_ans, %options)
        returns $rh_ans

Replaces some constants using math_constants, then evaluates a perl expression.

std_num_array_filter

        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).

function_from_string2

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_numeric_expression

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. =cut

# ^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; }

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);

Utility subroutines

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