| … | |
… | |
| 825 | |
825 | |
| 826 | |
826 | |
| 827 | sub check_units { |
827 | sub check_units { |
| 828 | my ($rh_ans, %options) = @_; |
828 | my ($rh_ans, %options) = @_; |
| 829 | |
829 | |
|
|
830 | |
| 830 | my %correct_units = %{$rh_ans-> {rh_correct_units}}; |
831 | my %correct_units = %{$rh_ans-> {rh_correct_units}}; |
| 831 | |
832 | |
| 832 | my $ans = $rh_ans->{student_ans}; |
833 | my $ans = $rh_ans->{student_ans}; |
| 833 | # $ans = '' unless defined ($ans); |
834 | # $ans = '' unless defined ($ans); |
| 834 | $ans = str_filters ($ans, 'trim_whitespace'); |
835 | $ans = str_filters ($ans, 'trim_whitespace'); |
| … | |
… | |
| 861 | my %units = Units::evaluate_units($units); |
862 | my %units = Units::evaluate_units($units); |
| 862 | if ( defined( $units{'ERROR'} ) ) { |
863 | if ( defined( $units{'ERROR'} ) ) { |
| 863 | # handle error condition |
864 | # handle error condition |
| 864 | $units{'ERROR'} = clean_up_error_msg($units{'ERROR'}); |
865 | $units{'ERROR'} = clean_up_error_msg($units{'ERROR'}); |
| 865 | $rh_ans -> setKeys( 'ans_message' => "$units{'ERROR'}" ); |
866 | $rh_ans -> setKeys( 'ans_message' => "$units{'ERROR'}" ); |
|
|
867 | $rh_ans -> throw_error('UNITS', "$units{'ERROR'}"); |
| 866 | return $rh_ans; |
868 | return $rh_ans; |
| 867 | } |
869 | } |
| 868 | |
870 | |
| 869 | my $units_match = 1; |
871 | my $units_match = 1; |
| 870 | my $fund_unit; |
872 | my $fund_unit; |
| … | |
… | |
| 876 | if ( $units_match ) { |
878 | if ( $units_match ) { |
| 877 | # units are ok. Evaluate the numerical part of the answer |
879 | # units are ok. Evaluate the numerical part of the answer |
| 878 | $rh_ans->{'tolerance'} = $rh_ans->{'tolerance'}* $correct_units{'factor'}/$units{'factor'} if |
880 | $rh_ans->{'tolerance'} = $rh_ans->{'tolerance'}* $correct_units{'factor'}/$units{'factor'} if |
| 879 | $rh_ans->{'tolType'} eq 'absolute'; # the tolerance is in the units specified by the instructor. |
881 | $rh_ans->{'tolType'} eq 'absolute'; # the tolerance is in the units specified by the instructor. |
| 880 | $rh_ans->{correct_ans} = prfmt($rh_ans->{correct_ans}*$correct_units{'factor'}/$units{'factor'}); |
882 | $rh_ans->{correct_ans} = prfmt($rh_ans->{correct_ans}*$correct_units{'factor'}/$units{'factor'}); |
|
|
883 | $rh_ans->{student_units} = $units; |
| 881 | $rh_ans->{student_ans} = $num_answer; |
884 | $rh_ans->{student_ans} = $num_answer; |
| 882 | |
885 | |
| 883 | } else { |
886 | } else { |
| 884 | $rh_ans -> setKeys( ans_message => 'There is an error in the units for this answer.' ); |
887 | $rh_ans -> setKeys( ans_message => 'There is an error in the units for this answer.' ); |
| 885 | $rh_ans -> throw_error ( 'UNITS', 'There is an error in the units for this answer.' ); |
888 | $rh_ans -> throw_error ( 'UNITS', 'There is an error in the units for this answer.' ); |
| … | |
… | |
| 899 | |
902 | |
| 900 | # it surprises me that the match below works since the first .* is greedy. |
903 | # it surprises me that the match below works since the first .* is greedy. |
| 901 | my ($correct_num_answer, $correct_units) = $correct_answer =~ /^(.*)\s+([^\s]*)$/; |
904 | my ($correct_num_answer, $correct_units) = $correct_answer =~ /^(.*)\s+([^\s]*)$/; |
| 902 | |
905 | |
| 903 | $options{units} = $correct_units; |
906 | $options{units} = $correct_units; |
| 904 | |
|
|
| 905 | |
907 | |
| 906 | num_cmp($correct_num_answer, %options); |
908 | num_cmp($correct_num_answer, %options); |
| 907 | } |
909 | } |
| 908 | |
910 | |
| 909 | |
911 | |
| … | |
… | |
| 1114 | 'zeroLevel' => $numZeroLevelDefault, |
1116 | 'zeroLevel' => $numZeroLevelDefault, |
| 1115 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
1117 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
| 1116 | 'tolType' => 'relative', |
1118 | 'tolType' => 'relative', |
| 1117 | 'tolerance' => 1, |
1119 | 'tolerance' => 1, |
| 1118 | 'reltol' => undef, #alternate spelling |
1120 | 'reltol' => undef, #alternate spelling |
| 1119 | 'unit' => undef); #alternate spelling |
1121 | 'unit' => undef, #alternate spelling |
|
|
1122 | 'debug' => 0 |
|
|
1123 | |
|
|
1124 | ); |
| 1120 | |
1125 | |
| 1121 | my @output_list; |
1126 | my @output_list; |
| 1122 | my( $relPercentTol, $format, $zeroLevel, $zeroLevelTol) = @opt; |
1127 | my( $relPercentTol, $format, $zeroLevel, $zeroLevelTol) = @opt; |
| 1123 | |
1128 | |
| 1124 | unless( ref($correctAnswer) eq 'ARRAY' || scalar( @opt ) == 0 || |
1129 | unless( ref($correctAnswer) eq 'ARRAY' || scalar( @opt ) == 0 || |
| … | |
… | |
| 1435 | } |
1440 | } |
| 1436 | if (defined($num_params{strings}) && $num_params{strings}) { |
1441 | if (defined($num_params{strings}) && $num_params{strings}) { |
| 1437 | $answer_evaluator->install_pre_filter(\&check_strings, %num_params); |
1442 | $answer_evaluator->install_pre_filter(\&check_strings, %num_params); |
| 1438 | } |
1443 | } |
| 1439 | |
1444 | |
| 1440 | |
|
|
| 1441 | $answer_evaluator->install_pre_filter(\&check_syntax); |
1445 | $answer_evaluator->install_pre_filter(\&check_syntax); |
| 1442 | |
1446 | |
| 1443 | $answer_evaluator->install_pre_filter(\&math_constants); |
1447 | $answer_evaluator->install_pre_filter(\&math_constants); |
| 1444 | |
1448 | |
| 1445 | |
1449 | |
| 1446 | |
1450 | |
|
|
1451 | |
| 1447 | if ($mode eq 'std') { |
1452 | if ($mode eq 'std') { |
| 1448 | # do nothing |
1453 | # do nothing |
| 1449 | } elsif ($mode eq 'strict') { |
1454 | } elsif ($mode eq 'strict') { |
| 1450 | $answer_evaluator->install_pre_filter(\&is_a_number); |
1455 | $answer_evaluator->install_pre_filter(\&is_a_number); |
| 1451 | } elsif ($mode eq 'arith') { |
1456 | } elsif ($mode eq 'arith') { |
| … | |
… | |
| 1455 | |
1460 | |
| 1456 | } else { |
1461 | } else { |
| 1457 | $PGanswerMessage = 'Tell your professor that there is an error in his or her answer mechanism. No mode was specified.'; |
1462 | $PGanswerMessage = 'Tell your professor that there is an error in his or her answer mechanism. No mode was specified.'; |
| 1458 | $formattedSubmittedAnswer = $in; |
1463 | $formattedSubmittedAnswer = $in; |
| 1459 | } |
1464 | } |
| 1460 | |
1465 | |
| 1461 | if ($corrAnswerIsString == 0 ){ # avoiding running compare_numbers when correct answer is a string. |
1466 | if ($corrAnswerIsString == 0 ){ # avoiding running compare_numbers when correct answer is a string. |
| 1462 | $answer_evaluator->install_evaluator(\&compare_numbers, %num_params); |
1467 | $answer_evaluator->install_evaluator(\&compare_numbers, %num_params); |
| 1463 | } |
1468 | } |
|
|
1469 | ############################################################################### |
|
|
1470 | # We'll leave these next lines out for now, so that the evaluated versions of the student's and professor's |
|
|
1471 | # can be displayed in the answer message. This may still cause a few anomolies when strings are used |
|
|
1472 | # |
|
|
1473 | ############################################################################### |
| 1464 | |
1474 | |
| 1465 | $answer_evaluator->install_post_filter(sub {my $rh_ans = shift; |
1475 | $answer_evaluator->install_post_filter(\&fix_answers_for_display); |
| 1466 | |
|
|
| 1467 | $rh_ans->{student_ans} = $rh_ans->{original_student_ans}; |
|
|
| 1468 | $rh_ans->{correct_ans} = $rh_ans->{original_correct_ans}; |
|
|
| 1469 | $rh_ans;} |
|
|
| 1470 | ); |
|
|
| 1471 | |
1476 | |
| 1472 | $answer_evaluator->install_post_filter(sub {my $rh_ans = shift; |
1477 | $answer_evaluator->install_post_filter(sub {my $rh_ans = shift; |
| 1473 | return $rh_ans unless $rh_ans->catch_error('EVAL'); |
1478 | return $rh_ans unless $rh_ans->catch_error('EVAL'); |
| 1474 | $rh_ans->{student_ans} = $rh_ans->{original_student_ans}. ' '. $rh_ans->{error_message}; |
1479 | $rh_ans->{student_ans} = $rh_ans->{original_student_ans}. ' '. $rh_ans->{error_message}; |
| 1475 | $rh_ans->clear_error('EVAL'); } ); |
1480 | $rh_ans->clear_error('EVAL'); } ); |
| … | |
… | |
| 1480 | |
1485 | |
| 1481 | |
1486 | |
| 1482 | $answer_evaluator; |
1487 | $answer_evaluator; |
| 1483 | } |
1488 | } |
| 1484 | |
1489 | |
| 1485 | |
1490 | sub fix_answers_for_display { |
|
|
1491 | my ($rh_ans, %options) = @_; |
|
|
1492 | if (defined ($rh_ans->{student_units})) { |
|
|
1493 | $rh_ans->{student_ans} = $rh_ans->{student_ans}. ' '. $rh_ans->{student_units}; |
|
|
1494 | } |
|
|
1495 | $rh_ans->{correct_ans} = $rh_ans->{original_correct_ans}; |
|
|
1496 | $rh_ans; |
|
|
1497 | } |
| 1486 | |
1498 | |
| 1487 | |
1499 | |
| 1488 | |
1500 | |
| 1489 | ########################################################################## |
1501 | ########################################################################## |
| 1490 | ########################################################################## |
1502 | ########################################################################## |