--- loncom/homework/default_homework.lcpm 2003/03/25 23:05:03 1.60 +++ loncom/homework/default_homework.lcpm 2004/03/12 21:06:19 1.71 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # used by lonxml::xmlparse() as input variable $safeinit to Apache::run::run() # -# $Id: default_homework.lcpm,v 1.60 2003/03/25 23:05:03 albertel Exp $ +# $Id: default_homework.lcpm,v 1.71 2004/03/12 21:06:19 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -42,14 +42,14 @@ $"=' '; sub caparesponse_check { #not properly used yet: calc #not to be used: $ans_fmt - my ($answer,$type,$tol,$sig,$ans_fmt,$unit,$calc,$samples) = - eval $_[1]. - ';return ($answer,$type,$tol,$sig,$ans_fmt,$unit,$calc,$samples);'; + my ($type,$tol,$sig,$ans_fmt,$unit,$calc,$samples) = + eval $_[2]. + ';return ($__LC__type,$__LC__tol,$__LC__sig,$__LC__ans_fmt,$__LC__unit,$__LC__calc,$__LC__samples);'; my $tol_type=''; # gets it's value from whether tol has a % or not done my $sig_lbound=''; #done my $sig_ubound=''; #done - my ($response,$expr)=@_; + my ($answer,$response,$expr)=@_; #type's definitons come from capaParser.h @@ -62,6 +62,8 @@ sub caparesponse_check { $message .="no ws in :$response:\n"; } + if (length($response) > 500) { return "TOO_LONG: Answer too long"; } + if ($type eq '' ) { $message .= "Didn't find a type :$type:$expr: defaulting\n"; if ( $answer eq ($answer *1.0)) { $type = 2; @@ -82,7 +84,7 @@ sub caparesponse_check { #formula type setup the sample points if ($type eq '8') { ($id_list,$points)=split(/@/,$samples); - $message.="Found :$points: points\n"; + $message.="Found :$id_list:$points: points in $samples\n"; } if ($tol eq '') { $tol=0.0; @@ -107,11 +109,13 @@ sub caparesponse_check { } if (!defined($sig_ubound)) { $sig_ubound=$sig_lbound; } } + my $reterror=""; my $result = &caparesponse_capa_check_answer($response,$answer,$type, $tol_type,$tol, $sig_lbound,$sig_ubound, $ans_fmt,$unit,$calc,$id_list, - $points,$external::randomseed); + $points,$external::randomseed, + \$reterror); if ($result == '1') { $result='EXACT_ANS'; } elsif ($result == '2') { $result='APPROX_ANS'; } @@ -127,15 +131,15 @@ sub caparesponse_check { elsif ($result =='12') { $result='WANTED_NUMERIC'; } else {$result = "ERROR: Unknown Result:$result:$@:";} - return "$result:\nError $error:\nAnswer $answer:\nResponse $response:\n type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|\n$message$expr"; + return ("$result:\nRetError $reterror:\nError $error:\nAnswer $answer:\nResponse $response:\n type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|\n$message$expr",$reterror); } sub get_array_args { my ($expr,$arg)=@_; # do these first, because who knows what varname the instructor might have used # but it probably isn't $CAPARESPONSE_CHECK_LIST_answer - my $CAPARESPONSE_CHECK_LIST_answer = eval $expr.';return $'.$arg; #' - my $GET_ARRAY_ARGS_result; + my $CAPARESPONSE_CHECK_LIST_answer = eval $expr.';return $'.$arg; #' stupid emacs + my $GET_ARRAY_ARGS_result="expr is $expr\narg is $arg\nfirst answer guess is $CAPARESPONSE_CHECK_LIST_answer\n"; my @GET_ARRAY_ARGS_list; if ($CAPARESPONSE_CHECK_LIST_answer =~ /^\s*[\$\@]/) { (@GET_ARRAY_ARGS_list) = eval $CAPARESPONSE_CHECK_LIST_answer; @@ -151,15 +155,20 @@ sub get_array_args { sub caparesponse_check_list { my ($response,$expr)=@_; - $expr =~ s/\\/\\\\/g; - $expr =~ s/\'/\\\'/g; - my ($result,@list) = &get_array_args($expr,'answer'); +# $expr =~ s/\\/\\\\/g; +# $expr =~ s/\'/\\\'/g; +# my ($result,@list) = &get_array_args($expr,'answer'); +# $expr =~ s/\\\'/\'/g; +# $expr =~ s/\\\\/\\/g; + my ($result,@list); + @list=@CAPARESPONSE_CHECK_LIST_answer; my $aresult=''; my $current_answer; my $answers=join(':',@list); $result.="Got response :$answers:\n"; my @responselist; - my $type =eval $expr.';return $answer;'; + my $type =eval $expr.';return $__LC__type;'; + $result.="Got type :$type:\n"; if ($type ne '' && $#list > 0) { (@responselist)=split /,/,$response; } else { @@ -167,7 +176,7 @@ sub caparesponse_check_list { } my $unit=''; $result.="Initial final response :$responselist['-1']:\n"; - if ($type eq '') { + if ($type eq '' || $type eq 'float') { #for numerical problems split off the unit if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) { $responselist['-1']=$1; @@ -179,24 +188,29 @@ sub caparesponse_check_list { $unit=~s/\s//; my $i=0; my $awards=''; + my @msgs; for ($i=0; $i<@list;$i++) { + my $msg; $result.="trying answer :$list[$i]:\n"; my $thisanswer=$list[$i]; - $thisanswer=~ s/\\/\\\\/g; - $thisanswer =~ s/\'/\\\'/g; +# $thisanswer=~ s/\\/\\\\/g; +# $thisanswer =~ s/\'/\\\'/g; + $result.="trying answer :$thisanswer:\n"; if ($unit eq '') { - $aresult=&caparesponse_check($responselist[$i], - $expr.';my $answer=\''.$thisanswer.'\';'); + ($aresult,$msg)=&caparesponse_check($thisanswer,$responselist[$i], + $expr); } else { - $aresult=&caparesponse_check($responselist[$i]." $unit", - $expr.';my $answer=\''.$thisanswer.'\';'); + ($aresult,$msg)=&caparesponse_check($thisanswer, + $responselist[$i]." $unit", + $expr); } my ($temp)=split /:/, $aresult; $awards.="$temp,"; $result.=$aresult; + push(@msgs,$msg); } chop $awards; - return "$awards:\n$result"; + return ("$awards:\n$result",@msgs); } sub tex { @@ -238,17 +252,22 @@ sub hinton { } sub random { - my ($start,$end,$step)=@_; - if ( ! $hidden::RANDOMINIT ) { - if ($external::randomseed == 0) { $external::randomseed=1; } - &random_set_seed(1,int(abs($external::randomseed))); - &math_random_uniform(); - $hidden::RANDOMINIT=1; - } - if (!defined($step)) { $step=1; } - my $num=1+int(($end-$start)/$step); - my $result=$start + int(&math_random_uniform() * $num)*$step; - return $result; + my ($start,$end,$step)=@_; + if ( ! $hidden::RANDOMINIT ) { + if ($external::randomseed == 0) { $external::randomseed=1; } + if ($external::randomseed =~/,/) { + my ($num1,$num2)=split(/,/,$seed); + &random_set_seed(abs($num1),abs($num2)); + } else { + &random_set_seed(1,int(abs($external::randomseed))); + } + &math_random_uniform(); + $hidden::RANDOMINIT=1; + } + if (!defined($step)) { $step=1; } + my $num=1+int(($end-$start)/$step); + my $result=$start + int(&math_random_uniform() * $num)*$step; + return $result; } sub random_normal { @@ -478,6 +497,7 @@ sub format { my ($value,$fmt)=@_; my $dollarmode; if ($fmt =~ /^\$(.*)/) { $fmt=$1; $dollarmode=1; } + $fmt=~s/e/E/g; my $result=sprintf('%.'.$fmt,$value); $result=~s/(E[+-]*)0/$1/; if ($dollarmode) {$result=&dollarmode($result);} @@ -485,21 +505,24 @@ sub format { } sub prettyprint { - my ($value,$fmt)=@_; + my ($value,$fmt,$target)=@_; my $result; my $dollarmode; + if (!$target) { $target = $external::target; } if ($fmt =~ /^\$(.*)/) { $fmt=$1; $dollarmode=1; } if ($fmt) { $value=sprintf('%.'.$fmt,$value); } - if ($value =~ /([0-9\.\-\+]+)E([0-9\-\+]+)/ ) { + if ($value =~ /([0-9\.\-\+]+)E([0-9\-\+]+)/i ) { my $frac=$1; if ($dollarmode) { $frac=&dollarformat($frac); } my $exponent=$2; $exponent=~s/^\+0*//; $exponent=~s/^-0*/-/; + $exponent=~s/^-0*/-/; + if ($exponent eq '-') { undef($exponent); } if ($exponent) { - if ($external::target eq 'web') { + if ($target eq 'web') { $result=$frac.'×10'.$exponent.''; - } elsif ($external::target eq 'tex') { + } elsif ($target eq 'tex') { $result='\ensuremath{'.$frac.'\times 10^{'.$exponent.'}}'; } else { $result=$value; @@ -509,13 +532,14 @@ sub prettyprint { } } else { $result=$value; - if ($dollarmode) { $result=&dollarformat($result); } + if ($dollarmode) { $result=&dollarformat($result,$target); } } return $result; } sub dollarformat { - my ($number) = @_; + my ($number,$target) = @_; + if (!$target) { $target = $external::target; } if ($number =~ /\./) { while ($number =~ /([^\.,]+)([^\.,][^\.,][^\.,])([,0-9]*\.[0-9]*$)/) { $number = $1.','.$2.$3; @@ -525,7 +549,7 @@ sub dollarformat { $number = $1.','.$2.$3; } } - if ($external::target eq 'tex') { + if ($target eq 'tex') { $number='\$'.$number; #' stupid emacs } else { $number='$'.$number; #' stupid emacs