WeBWorK Main Forum

Answer checker for 'appropriate' precision

Re: Answer checker for 'appropriate' precision

by Steven Fiedler -
Number of replies: 1
Sorry about the delay, I've been ill.

The behavior you are observing is likely due to the input accepted by the Math::SigFigs module itself. This can be checked by directly running a small perl script on directly on your computer or VM. Below is one example, followed by the output. Both the carrot and double asterisk notation return absent values.

As a work-around, I suppose you could use regex to parse the original_student_ans value to search and replace the carrot and double asterisk symbols.

Program: prog.pl
--------------------------------------
use Math::SigFigs qw(:all);

$n1="2.34E3";
$n2="1.1";
$n3="4.56*10^2";
$n4="4.56*10**2";
$nsf1=CountSigFigs($n1);
print "$n1 has $nsf1 sig figs\n";
$sum12=addSF($n1,$n2);
print "$n1 + $n2 is $sum12\n\n";


$nsf3=CountSigFigs($n3);
print "$n3 has $nsf3 sig figs\n";
$sum23=addSF($n2,$n3);
print "$n2 + $n3 is $sum23\n\n";

$nsf4=CountSigFigs($n4);
print "$n4 has $nsf4 sig figs\n";
$sum24=addSF($n2,$n4);
print "$n2 + $n4 is $sum24\n\n";

Output
----------
$ perl ./prog.pl
2.34E3 has 3 sig figs
2.34E3 + 1.1 is 2340

4.56*10^2 has sig figs
1.1 + 4.56*10^2 is

4.56*10**2 has sig figs
1.1 + 4.56*10**2 is
In reply to Steven Fiedler

Re: Answer checker for 'appropriate' precision

by Steven Fiedler -
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