WeBWorK Main Forum

Answer checker for 'appropriate' precision

Re: Answer checker for 'appropriate' precision

by Steven Fiedler -
Number of replies: 0
To head off student frustration, I modified my earlier code to convert student answers written in scientific notation from the double asterisk and caret format to the "E" format. This was accomplished by adding an answer prefilter, which calls a subroutine containing a couple simple regex expressions. Such an approach now also permits these sig fig type problems to use a Limited Numeric context, which is useful to disallow trivial solutions from cutting and pasting the original problem, as well as filtering extraneous non-numeric input. Below is the code and screenshot.

Steven

DOCUMENT();
loadMacros("PGstandard.pl","PGML.pl");

Context("LimitedNumeric");

sub addSF{
my ($n1,$n2)=@_;
return Math::SigFigs::addSF($n1,$n2);
}

sub subSF{
my ($n1,$n2)=@_;
return Math::SigFigs::subSF($n1,$n2);
}

sub multSF{
my ($n1,$n2)=@_;
return Math::SigFigs::multSF($n1,$n2);
}

sub divSF{
my ($n1,$n2)=@_;
return Math::SigFigs::divSF($n1,$n2);
}

sub CountSigFigs{
my $num=shift;
return Math::SigFigs::CountSigFigs($num);
}

sub sci_notation{
my $number = shift;
$number =~ s/(~~*10~~*~~*)/E/;
$number =~ s/(~~*10~~^)/E/;

return $number;
}

$num1="1.2000";
$num2="2345.00";
$add_ans=addSF($num1,$num2);
$sub_ans=subSF($num1,$num2);
$mult_ans=multSF($num1,$num2);
$div_ans=divSF($num1,$num2);

BEGIN_PGML
[$num1] + [$num2] = [___] [``\hspace{1em}``] The answer is [$add_ans]

[$num1] - [$num2] = [___] [``\hspace{1em}``] The answer is [$sub_ans]

[$num1] * [$num2] = [___] [``\hspace{1em}``] The answer is [$mult_ans]

[$num1] / [$num2] = [___] [``\hspace{1em}``] The answer is [$div_ans]
END_PGML

chk_ans($add_ans);
chk_ans($sub_ans);
chk_ans($mult_ans);
chk_ans($div_ans);


sub chk_ans{
#Subroutine used to capture nontruncated correct values
my $ans=shift;
$ans->{correct_ans_latex_string}=$ans;

ANS(Real($ans)->cmp(checker=> sub {
my ($correct,$student,$ansHash) = @_;
my $orig_sval = $ansHash->{original_student_ans};
$orig_sval=sci_notation($orig_sval); #Converts numbers to "E" format

$student=Real($orig_sval);
my $orig_cval=$ans->{correct_ans_latex_string};
$ansHash->{student_ans} = $orig_sval; #The "Entered" column
$ansHash->{preview_latex_string}=$orig_sval; #The "Preview" column
$ansHash->{preview_text_string} = $orig_sval; #"Answer Preview" popup
if($student == $correct){
$nsf_sval=CountSigFigs($orig_sval); #num sig figs in $sval
$nsf_corr = CountSigFigs($orig_cval);#Num sigfigs in corr_string
if($nsf_sval==$nsf_corr) { $ansHash->{score} = 1; }
else{
$ansHash->{ans_message}="Incorrect number of sig figs.";
$ansHash->{score} = 0.5;
}#end else
}#endif $student==$correct

return $ansHash->{score};

}#end ANS sub{}
) #end cmp()
->withPreFilter(
#Prefilter used to capture student answer and convert numbers
# written in scientific notation to "E" format. This permits the use
# of the Limited Numeric context
sub{
my $ans=shift;
$tmp=$ans->{student_ans};
$ans->{student_ans} = sci_notation($tmp);
return $ans;
}

)
); #end ANS()

}#end sub chk_ans

ENDDOCUMENT();


Attachment Screenshot_2024-01-10_17-04-28am.png