version 1.117, 2006/09/29 23:10:22
|
version 1.134, 2008/05/30 01:16:04
|
Line 152 sub caparesponse_check {
|
Line 152 sub caparesponse_check {
|
} |
} |
if ($response=~ /^\s|\s$/) { |
if ($response=~ /^\s|\s$/) { |
$response=~ s:^\s+|\s+$::g; |
$response=~ s:^\s+|\s+$::g; |
#&LONCAPA_INTERNAL_DEBUG("Removed ws now :$response:"); |
&LONCAPA_INTERNAL_DEBUG("Removed ws now :$response:"); |
} |
} |
|
|
#&LONCAPA_INTERNAL_DEBUG(" type is $type "); |
#&LONCAPA_INTERNAL_DEBUG(" type is $type "); |
if ($type eq 'cs' || $type eq 'ci') { |
if ($type eq 'cs' || $type eq 'ci') { |
#for string answers make surec all places spaces occur, there is |
#for string answers make sure all places spaces occur, there is |
#really only 1 space, in both the answer and the response |
#really only 1 space, in both the answer and the response |
$answer=~s/ +/ /g; |
$answer=~s/ +/ /g; |
$response=~s/ +/ /g; |
$response=~s/ +/ /g; |
Line 166 sub caparesponse_check {
|
Line 166 sub caparesponse_check {
|
$response=~s/[\s,]//g; |
$response=~s/[\s,]//g; |
} |
} |
if ($type eq 'float' && $unit=~/\$/) { |
if ($type eq 'float' && $unit=~/\$/) { |
if ($response!~/^\$/) { return ('NO_UNIT', undef); } |
if ($response!~/^\$|\$$/) { return ('NO_UNIT', undef); } |
$response=~s/\$//g; |
$response=~s/\$//g; |
} |
} |
if ($type eq 'float' && $unit=~/\,/ && (&check_commas($response)<0)) { |
if ($type eq 'float' && $unit=~/\,/ && (&check_commas($response)<0)) { |
Line 179 sub caparesponse_check {
|
Line 179 sub caparesponse_check {
|
if (length($response) > 500) { return ('TOO_LONG',undef); } |
if (length($response) > 500) { return ('TOO_LONG',undef); } |
|
|
if ($type eq '' ) { |
if ($type eq '' ) { |
#&LONCAPA_INTERNAL_DEBUG("Didn't find a type :$type: defaulting"); |
&LONCAPA_INTERNAL_DEBUG("Didn't find a type :$type: defaulting"); |
if ( $answer eq ($answer *1.0)) { $type = 2; |
if ( $answer eq ($answer *1.0)) { $type = 2; |
} else { $type = 3; } |
} else { $type = 3; } |
} else { |
} else { |
Line 199 sub caparesponse_check {
|
Line 199 sub caparesponse_check {
|
#formula type setup the sample points |
#formula type setup the sample points |
if ($type eq '8') { |
if ($type eq '8') { |
($id_list,$points)=split(/@/,$samples); |
($id_list,$points)=split(/@/,$samples); |
#&LONCAPA_INTERNAL_DEBUG("Found :$id_list:$points: points in $samples"); |
&LONCAPA_INTERNAL_DEBUG("Found :$id_list:$points: points in $samples"); |
} |
} |
if ($tol eq '') { |
if ($tol eq '') { |
$tol=0.0; |
$tol=0.0; |
Line 217 sub caparesponse_check {
|
Line 217 sub caparesponse_check {
|
|
|
my $reterror=""; |
my $reterror=""; |
my $result; |
my $result; |
|
if ((($type eq '9') || ($type eq '8')) && ($response=~/\=/)) { return ('BAD_FORMULA','Please submit just an expression, not an equation.'); } |
if ($type eq '9') { |
if ($type eq '9') { |
$result = &maxima_check(&maxima_cas_formula_fix($response),&maxima_cas_formula_fix($answer),\$reterror); |
$result = &maxima_check(&maxima_cas_formula_fix($response),&maxima_cas_formula_fix($answer),\$reterror); |
} else { |
} else { |
Line 251 sub caparesponse_check {
|
Line 252 sub caparesponse_check {
|
elsif ($result =='15') { $result='UNIT_IRRECONCIBLE'; } |
elsif ($result =='15') { $result='UNIT_IRRECONCIBLE'; } |
else {$result = "ERROR: Unknown Result:$result:$@:";} |
else {$result = "ERROR: Unknown Result:$result:$@:";} |
|
|
#&LONCAPA_INTERNAL_DEBUG("RetError $reterror: Answer $answer: Response $response: type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|"); |
&LONCAPA_INTERNAL_DEBUG("RetError $reterror: Answer $answer: Response $response: type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|"); |
#&LONCAPA_INTERNAL_DEBUG(" $answer $response $result "); |
&LONCAPA_INTERNAL_DEBUG(" $answer $response $result "); |
return ($result,$reterror) |
return ($result,$reterror) |
} |
} |
|
|
sub maxima_cas_formula_fix { |
|
my ($expression)=@_; |
|
return &implicit_multiplication($expression); |
|
} |
|
|
|
sub capa_formula_fix { |
|
my ($expression)=@_; |
|
return &implicit_multiplication($expression); |
|
} |
|
|
|
sub implicit_multiplication { |
|
my ($expression)=@_; |
|
# Escape scientific notation, so 3e8 does not become 3*e*8 |
|
# 3e8 -> 3&8; 3e-8 -> 3&-8; 3E+8 -> e&+8 |
|
$expression=~s/(\d+)e([\+\-]*\d+)/$1\&\($2\)/gsi; |
|
# 3x10^8 -> 3&8; 3*10^-8 -> 3&-8 |
|
$expression=~s/(\d+)(?:x|\*)10(?:\^|\*\*)([\+\-]*\d+)/$1\&\($2\)/gsi; |
|
# Fill in multiplication signs |
|
# a b -> a*b;3 b -> 3*b;3 4 -> 3*4 |
|
$expression=~s/(\w)\s+(\w)/$1\*$2/gs; |
|
# )( -> )*(; ) ( -> )*( |
|
$expression=~s/\)\s*\(/\)\*\(/gs; |
|
# 3a -> 3*a; 3( -> 3*(; 3 ( -> 3*(; 3A -> 3*A |
|
$expression=~s/(\d)\s*([a-zA-Z\(])/$1\*$2/gs; |
|
# a ( -> a*( |
|
$expression=~s/(\w)\s+\(/$1\*\(/gs; |
|
# a3 -> a*3; |
|
$expression=~s/([a-zA-Z])(\d)/$1\*$2/gs; |
|
# )a -> )*a; )3 -> )*3; ) 3 -> )*3 |
|
$expression=~s/\)\s*(\w)/\)\*$1/gs; |
|
# 3&8 -> 3e8; 3&-4 -> 3e-4 |
|
$expression=~s/(\d+)\&\(([\+\-]*\d+)\)/$1e$2/gs; |
|
return $expression; |
|
} |
|
|
|
sub caparesponse_check_list { |
sub caparesponse_check_list { |
my $response=$LONCAPA::CAPAresponse_args{'response'}; |
my $responses=$LONCAPA::CAPAresponse_args{'response'}; |
my $result="Got response :".join(':',@LONCAPA::CAPAresponse_answer).":\n"; |
|
&LONCAPA_INTERNAL_DEBUG("args ".join(':',%LONCAPA::CAPAresponse_args)); |
&LONCAPA_INTERNAL_DEBUG("args ".join(':',%LONCAPA::CAPAresponse_args)); |
my @responselist; |
|
my $type = $LONCAPA::CAPAresponse_args{'type'}; |
my $type = $LONCAPA::CAPAresponse_args{'type'}; |
&LONCAPA_INTERNAL_DEBUG("Got type :$type:\n"); |
my $answerunit=$LONCAPA::CAPAresponse_args{'unit'}; |
my $num_answers = scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}}); |
&LONCAPA_INTERNAL_DEBUG("Got type :$type: answer unit :$answerunit:\n"); |
if ($type ne '' |
|
&& $num_answers > 1) { |
my $num_input_lines = |
(@responselist)=split(/,/,$response); |
scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}}); |
if (@responselist < $num_answers) { |
|
|
if ($type ne '' ) { |
|
if (scalar(@$responses) < $num_input_lines) { |
return 'MISSING_ANSWER'; |
return 'MISSING_ANSWER'; |
} |
} |
if (@responselist > $num_answers) { |
if (scalar(@$responses) > $num_input_lines) { |
|
return 'EXTRA_ANSWER'; |
|
} |
|
|
|
} |
|
|
|
foreach my $which (0..($num_input_lines-1)) { |
|
my $answer_size = |
|
scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}[$which]}); |
|
if ($type ne '' |
|
&& $answer_size > 1) { |
|
$responses->[$which]=[split(/,/,$responses->[$which])]; |
|
} else { |
|
$responses->[$which]=[$responses->[$which]]; |
|
} |
|
} |
|
foreach my $which (0..($num_input_lines-1)) { |
|
my $answer_size = |
|
scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}[$which]}); |
|
my $response_size = |
|
scalar(@{$responses->[$which]}); |
|
if ($answer_size > $response_size) { |
|
return 'MISSING_ANSWER'; |
|
} |
|
if ($answer_size < $response_size) { |
return 'EXTRA_ANSWER'; |
return 'EXTRA_ANSWER'; |
} |
} |
} else { |
|
(@responselist)=($response); |
|
} |
} |
&LONCAPA_INTERNAL_DEBUG("Initial final response :$responselist['-1']:"); |
|
|
&LONCAPA_INTERNAL_DEBUG("Initial final response :$responses->[0][-1]:"); |
my $unit; |
my $unit; |
if ($type eq '' || $type eq 'float') { |
if ($type eq '' || $type eq 'float') { |
#for numerical problems split off the unit |
#for numerical problems split off the unit |
if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) { |
# if ( $responses->[0][-1]=~ /(.*[^\s])\s+([^\s]+)/ ) { |
$responselist['-1']=$1; |
if ( $responses->[0][-1]=~ /^([\d\.\,\s\$]*(?:(?:[xX\*]10[\^\*]*|[eE]*)[\+\-]*\d*)*(?:^|\S)\d+)([\$\s\w\^\*\/\(\)\+\-]*[^\d\.\s\,][\$\s\w\^\*\/\(\)\+\-]*)$/ ) { |
$unit=$2; |
$responses->[0][-1]=$1; |
|
$unit=&capa_formula_fix($2); |
|
&LONCAPA_INTERNAL_DEBUG("Found unit :$unit:"); |
} |
} |
} |
} |
&LONCAPA_INTERNAL_DEBUG("Final final response :$responselist['-1']:$unit:"); |
&LONCAPA_INTERNAL_DEBUG("Final final response :$responses->[0][-1]:$unit:"); |
$unit=~s/\s//; |
$unit=~s/\s//; |
|
foreach my $response (@$responses) { |
|
foreach my $element (@$response) { |
|
$element =~ s/\s//g; |
|
my $appendunit=$unit; |
|
if ($unit=~/\%/) { |
|
$element=$element/100; |
|
$appendunit=~s/\%//; |
|
} |
|
if (($element==0) && ($unit!~/\w/) && ($answerunit=~/\w/)) { |
|
$appendunit=$answerunit; |
|
} |
|
$element .= " $appendunit"; |
|
&LONCAPA_INTERNAL_DEBUG("Made response element :$element:"); |
|
} |
|
} |
|
|
foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
if (!defined($thisanswer)) { |
if (!defined($thisanswer)) { |
return ('ERROR','answer was undefined'); |
return ('ERROR','answer was undefined'); |
} |
} |
} |
} |
|
|
if ($unit ne '') { |
|
foreach my $response (@responselist) { |
|
$response .= " $unit"; |
|
} |
|
} |
|
|
|
|
# &LONCAPA_INTERNAL_DEBUG(&LONCAPA_INTERNAL_Dumper($responses)); |
my %memoized; |
my %memoized; |
if ($LONCAPA::CAPAresponse_answer->{'type'} eq 'ordered') { |
if ($LONCAPA::CAPAresponse_answer->{'type'} eq 'ordered') { |
for (my $i=0; $i<scalar(@responselist);$i++) { |
for (my $i=0; $i<scalar(@$responses);$i++) { |
my $answer = $LONCAPA::CAPAresponse_answer->{'answers'}[$i]; |
my $answer = $LONCAPA::CAPAresponse_answer->{'answers'}[$i]; |
my $response = $responselist[$i]; |
my $response = $responses->[$i]; |
my $key = "$answer\0$response"; |
my $key = "$answer\0$response"; |
$memoized{$key} = [&caparesponse_check($answer, $response)]; |
my (@awards,@msgs); |
|
for (my $j=0; $j<scalar(@$response); $j++) { |
|
my ($award,$msg) = &caparesponse_check($answer->[$j], |
|
$response->[$j]); |
|
push(@awards,$award); |
|
push(@msgs, $msg); |
|
} |
|
my ($award,$msg) = |
|
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs); |
|
$memoized{$key} = [$award,$msg]; |
} |
} |
} else { |
} else { |
foreach my $response (@responselist) { |
#FIXME broken with unorder responses where one is a <value> |
|
# and the other is a <vector> (need to delay parse til |
|
# inside the loop?) |
|
foreach my $response (@$responses) { |
|
my $response_size = scalar(@{$response}); |
foreach my $answer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
foreach my $answer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
my $key = "$answer\0$response"; |
my $key = "$answer\0$response"; |
$memoized{$key} = [&caparesponse_check($answer, $response)]; |
my $answer_size = scalar(@{$answer}); |
|
my ($award,$msg); |
|
if ($answer_size > $response_size) { |
|
$award = 'MISSING_ANSWER'; |
|
} elsif ($answer_size < $response_size) { |
|
$award = 'EXTRA_ANSWER'; |
|
} else { |
|
my (@awards,@msgs); |
|
for (my $j=0; $j<scalar(@$response); $j++) { |
|
my ($award,$msg) = &caparesponse_check($answer->[$j], |
|
$response->[$j]); |
|
push(@awards,$award); |
|
push(@msgs, $msg); |
|
} |
|
($award,$msg) = |
|
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs); |
|
} |
|
$memoized{$key} = [$award,$msg]; |
} |
} |
} |
} |
} |
} |
|
|
my ($final_award,$final_msg); |
my ($final_award,$final_msg); |
&init_permutation(scalar(@responselist), |
&init_permutation(scalar(@$responses), |
$LONCAPA::CAPAresponse_answer->{'type'}); |
$LONCAPA::CAPAresponse_answer->{'type'}); |
|
|
|
# possible FIXMEs |
|
# - significant time is spent calling non-safe space routine |
|
# from safe space |
|
# - early outs could be possible with classifying awards is to stratas |
|
# and stopping as so as hitting the top strata |
|
# - some early outs also might be possible with check ing the |
|
# memoized hash of results (is correct even possible? etc.) |
|
|
my (@final_awards,@final_msg); |
my (@final_awards,@final_msg); |
while( &get_permutations_left() ) { |
while( &get_permutations_left() ) { |
my $order = &get_next_permutation(); |
my $order = &get_next_permutation(); |
my (@awards, @msgs, $i); |
my (@awards, @msgs, $i); |
foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) { |
my $key = "$thisanswer\0".$responselist[$order->[$i]]; |
my $key = "$thisanswer\0".$responses->[$order->[$i]]; |
push(@awards,$memoized{$key}[0]); |
push(@awards,$memoized{$key}[0]); |
push(@msgs,$memoized{$key}[1]); |
push(@msgs,$memoized{$key}[1]); |
$i++; |
$i++; |
|
|
} |
} |
|
&LONCAPA_INTERNAL_DEBUG(" all awards ".join(':',@awards)); |
|
|
my ($possible_award,$possible_msg) = |
my ($possible_award,$possible_msg) = |
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs); |
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs); |
|
&LONCAPA_INTERNAL_DEBUG(" pos awards ".$possible_award); |
push(@final_awards,$possible_award); |
push(@final_awards,$possible_award); |
push(@final_msg,$possible_msg); |
push(@final_msg,$possible_msg); |
} |
} |
|
|
|
&LONCAPA_INTERNAL_DEBUG(" all final_awards ".join(':',@final_awards)); |
my ($final_award,$final_msg) = |
my ($final_award,$final_msg) = |
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@final_awards,\@final_msg,undef,1); |
&LONCAPA_INTERNAL_FINALIZEAWARDS(\@final_awards,\@final_msg,undef,1); |
return ($final_award,$final_msg); |
return ($final_award,$final_msg); |
} |
} |
|
|
|
sub cas { |
|
my ($system,$input)=@_; |
|
my $output; |
|
if ($system eq 'maxima') { |
|
$output=&maxima_eval($input); |
|
} |
|
return $output; |
|
} |
|
|
sub tex { |
sub tex { |
if ( $external::target eq "tex" ) { |
if ( $external::target eq "tex" ) { |
return $_[0]; |
return $_[0]; |
Line 970 sub sec {
|
Line 1025 sub sec {
|
} |
} |
|
|
sub open_date { |
sub open_date { |
my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate'))); |
my ($partid)=@_; |
|
unless ($partid) { $partid=0; } |
|
my @dc = split(/\s+/,localtime(&EXT('resource.'.$partid.'.opendate'))); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
my @hm = split(/:/,$dc[3]); |
my @hm = split(/:/,$dc[3]); |
my $ampm = " am"; |
my $ampm = " am"; |
Line 981 sub open_date {
|
Line 1038 sub open_date {
|
return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm; |
return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm; |
} |
} |
|
|
sub due_date { |
sub due_date { |
my @dc = split(/\s+/,localtime(&EXT('resource.0.duedate'))); |
my ($partid)=@_; |
|
unless ($partid) { $partid=0; } |
|
my @dc = split(/\s+/,localtime(&EXT('resource.'.$partid.'.duedate'))); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
my @hm = split(/:/,$dc[3]); |
my @hm = split(/:/,$dc[3]); |
my $ampm = " am"; |
my $ampm = " am"; |
Line 994 sub due_date {
|
Line 1053 sub due_date {
|
} |
} |
|
|
sub answer_date { |
sub answer_date { |
my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate'))); |
my ($partid)=@_; |
|
unless ($partid) { $partid=0; } |
|
my @dc = split(/\s+/,localtime(&EXT('resource.'.$partid.'.answerdate'))); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); |
my @hm = split(/:/,$dc[3]); |
my @hm = split(/:/,$dc[3]); |
my $ampm = " am"; |
my $ampm = " am"; |