--- loncom/homework/default_homework.lcpm 2001/05/30 21:49:13 1.23 +++ loncom/homework/default_homework.lcpm 2004/03/22 21:05:15 1.76 @@ -1,154 +1,413 @@ -# file name (temp): default_homework +# The LearningOnline Network with CAPA # used by lonxml::xmlparse() as input variable $safeinit to Apache::run::run() -# # -#init some globals +# $Id: default_homework.lcpm,v 1.76 2004/03/22 21:05:15 albertel Exp $ +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Guy Albertelli +# /home/httpd/html/adm/gpl.txt # -# 05/25/2001 H. K. Ng +# http://www.lon-capa.org/ # -$RANDOMINIT=0; +# + +#init some globals +$hidden::RANDOMINIT=0; $pi=atan2(1,1)*4; $rad2deg=180.0/$pi; $deg2rad=$pi/180.0; +$"=' '; sub caparesponse_check { - my $answer=''; #done - my $type=''; #done - my $tol_type=''; # gets it's value from whether tol has a % or not done - my $tol=''; #done - my $sig=''; #done lowerbnd,upperbnd - my $sig_lbound=''; #done - my $sig_ubound=''; #done - my $ans_fmt=''; - my $units=''; #done - my $calc=''; - my ($response,$expr)=@_; - - ($answer,$type,$tol,$sig,$ans_fmt, - $units,$calc) = eval $expr.';return $answer,$type,$tol,$sig,$ans_fmt,$units,$calc'; - #type's definitons come from capaParser.h - if ($type eq '' ) { - if ( $answer eq ($answer *1.0)) { $type = 2; - } else { $type = 3; } - } else { - if ($type eq 'cs') { $type = 4; - } elsif ($type eq 'ci') { $type = 3; - } elsif ($type eq 'mc') { $type = 5; - } elsif ($type eq 'fml') { $type = 8; - } elsif ($type eq 'subj') { $type = 7; - } else { return "ERROR: Unknown type of answer: $type" } - } - - if ($tol eq '') { - $tol=0.0; - $tol_type=1; #TOL_ABSOLUTE - } else { - if ($tol =~ /%$/) { - chop $tol; - $tol_type=2; #TOL_PERCENTAGE - } else { - $tol_type=1; #TOL_ABSOLUTE - } - } - - if ($sig eq '') { - $sig_lbound = 0; #SIG_LB_DEFAULT - $sig_ubound =15; #SIG_UB_DEFAULT - } else { - ($sig_lbound,$sig_ubound) = split /,/,$sig; - } - my $result = &caparesponse_capa_check_answer($response,$answer,$type, - $tol_type,$tol, - $sig_lbound,$sig_ubound, - $ans_fmt,$units,$calc); - - if ($result == '1') { $result='EXACT_ANS'; } - elsif ($result == '2') { $result='APPROX_ANS'; } - elsif ($result == '3') { $result='SIG_FAIL'; } - elsif ($result == '4') { $result='UNIT_FAIL'; } - elsif ($result == '5') { $result='NO_UNIT'; } - elsif ($result == '6') { $result='UNIT_OK'; } - elsif ($result == '7') { $result='INCORRECT'; } - elsif ($result == '8') { $result='UNIT_NOTNEEDED'; } - elsif ($result == '9') { $result='ANS_CNT_NOT_MATCH'; } - elsif ($result =='10') { $result='SUB_RECORDED'; } - elsif ($result =='11') { $result='BAD_FORMULA'; } - elsif ($result =='12') { $result='WANTED_NUMERIC'; } - else {$result = "ERROR: Unknown Result:$result:$@:";} + my ($answer,$response)=@_; + #not properly used yet: calc + #not to be used: $ans_fmt + my $type=$LONCAPA::CAPAresponse_args{'type'}; + my $tol=$LONCAPA::CAPAresponse_args{'tol'}; + my $sig=$LONCAPA::CAPAresponse_args{'sig'}; + my $ans_fmt=$LONCAPA::CAPAresponse_args{'ans_fmt'}; + my $unit=$LONCAPA::CAPAresponse_args{'unit'}; + my $calc=$LONCAPA::CAPAresponse_args{'calc'}; + my $samples=$LONCAPA::CAPAresponse_args{'samples'}; + + my $tol_type=''; # gets it's value from whether tol has a % or not done + my $sig_lbound=''; #done + my $sig_ubound=''; #done + + + #type's definitons come from capaParser.h + my $message=''; + #remove leading and trailing whitespace + if (!defined($response)) { + $response=''; + } + if ($response=~ /^\s|\s$/) { + $response=~ s:^\s+|\s+$::g; + $message .="Removed ws now :$response:\n"; + } else { + $message .="no ws in :$response:\n"; + } + if ($type eq 'cs' || $type eq 'ci' || $type eq 'mc') { + #for string answers make surec all places spaces occur, there is + #really only 1 space, in both the answer and the response + $answer=~s/ +/ /g; + $response=~s/ +/ /g; + } + if (length($response) > 500) { return "TOO_LONG: Answer too long"; } + + if ($type eq '' ) { + $message .= "Didn't find a type :$type: defaulting\n"; + if ( $answer eq ($answer *1.0)) { $type = 2; + } else { $type = 3; } + } else { + if ($type eq 'cs') { $type = 4; } + elsif ($type eq 'ci') { $type = 3 } + elsif ($type eq 'mc') { $type = 5; } + elsif ($type eq 'fml') { $type = 8; } + elsif ($type eq 'subj') { $type = 7; } + elsif ($type eq 'float') { $type = 2; } + elsif ($type eq 'int') { $type = 1; } + else { return "ERROR: Unknown type of answer: $type" } + } - return "$result:
Error $error:
Answer $answer:
Response $response:
$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$units
"; + my $points; + my $id_list; + #formula type setup the sample points + if ($type eq '8') { + ($id_list,$points)=split(/@/,$samples); + $message.="Found :$id_list:$points: points in $samples\n"; + } + if ($tol eq '') { + $tol=0.0; + $tol_type=1; #TOL_ABSOLUTE + } else { + if ($tol =~ /%$/) { + chop $tol; + $tol_type=2; #TOL_PERCENTAGE + } else { + $tol_type=1; #TOL_ABSOLUTE + } + } + + if ($sig eq '') { + $sig_lbound = 0; #SIG_LB_DEFAULT + $sig_ubound =15; #SIG_UB_DEFAULT + } else { + ($sig_lbound,$sig_ubound) = split /,/,$sig; + if (!defined($sig_lbound)) { + $sig_lbound = 0; #SIG_LB_DEFAULT + $sig_ubound =15; #SIG_UB_DEFAULT + } + 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, + \$reterror); + + if ($result == '1') { $result='EXACT_ANS'; } + elsif ($result == '2') { $result='APPROX_ANS'; } + elsif ($result == '3') { $result='SIG_FAIL'; } + elsif ($result == '4') { $result='UNIT_FAIL'; } + elsif ($result == '5') { $result='NO_UNIT'; } + elsif ($result == '6') { $result='UNIT_OK'; } + elsif ($result == '7') { $result='INCORRECT'; } + elsif ($result == '8') { $result='UNIT_NOTNEEDED'; } + elsif ($result == '9') { $result='ANS_CNT_NOT_MATCH'; } + elsif ($result =='10') { $result='SUB_RECORDED'; } + elsif ($result =='11') { $result='BAD_FORMULA'; } + elsif ($result =='12') { $result='WANTED_NUMERIC'; } + else {$result = "ERROR: Unknown Result:$result:$@:";} + + return ("$result:\nRetError $reterror:\nError $error:\nAnswer $answer:\nResponse $response:\n type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|\n$message",$reterror); } + sub caparesponse_check_list { - my ($response,$expr)=@_; - my $result=''; - my $aresult=''; - my $current_answer; - my $answer = eval $expr.';return $answer'; - my (@list) = eval $answer; - my (@responselist)=split /,/,$response; - my $unit=''; - $result.="Final response :$responselist['-1']:
"; - if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) { - $responselist['-1']=$1; - $unit=$2; - } - $result.="Final response :$responselist['-1']:
"; - $unit=~s/\s//; - my $i=0; - my $awards=''; - for ($i=0; $i<@list;$i++) { - if ($unit eq '') { - $aresult=&caparesponse_check($responselist[$i], - $expr.';my $answer='.$list[$i].';'); - } else { - $aresult=&caparesponse_check($responselist[$i]." $unit", - $expr.';my $answer='.$list[$i].';'); - } - my ($temp)=split /:/, $aresult; - $awards.="$temp,"; - $result.=$aresult; - } - chop $awards; - return "$awards:
$result"; + my $response=$LONCAPA::CAPAresponse_args{'response'}; + my ($result,@list); + @list=@LONCAPA::CAPAresponse_answer; + my $aresult=''; + my $current_answer; + my $answers=join(':',@list); + $result.="Got response :$answers:\n"; + &LONCAPA_INTERNAL_DEBUG("Yo! got ".join(':',%LONCAPA::CAPAresponse_args)); + my @responselist; + my $type = $LONCAPA::CAPAresponse_args{'type'}; + $result.="Got type :$type:\n"; + if ($type ne '' && $#list > 0) { + (@responselist)=split /,/,$response; + } else { + (@responselist)=($response); + } + my $unit=''; + $result.="Initial final response :$responselist['-1']:\n"; + if ($type eq '' || $type eq 'float') { + #for numerical problems split off the unit + if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) { + $responselist['-1']=$1; + $unit=$2; + } + } + $result.="Final final response :$responselist['-1']:\n"; + $result.=":$#list: answers\n"; + $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]; + $result.="trying answer :$thisanswer:\n"; + if ($unit eq '') { + ($aresult,$msg)=&caparesponse_check($thisanswer,$responselist[$i]); + } else { + ($aresult,$msg)=&caparesponse_check($thisanswer, + $responselist[$i]." $unit"); + } + my ($temp)=split /:/, $aresult; + $awards.="$temp,"; + $result.=$aresult; + push(@msgs,$msg); + } + chop $awards; + return ("$awards:\n$result",@msgs); } sub tex { - if ( $external::target eq "tex" ) { - return @_[0]; - } else { - return @_[1]; - } + if ( $external::target eq "tex" ) { + return $_[0]; + } else { + return $_[1]; + } +} + +sub var_in_tex { + if ( $external::target eq "tex" ) { + return $_[0]; + } else { + return ""; + } } sub web { - if ( $external::target eq "tex" ) { - return @_[1]; - } else { - if ( $external::target eq "web") { - return @_[0]; + if ( $external::target eq "tex" ) { + return $_[1]; } else { - return @_[2]; + if ( $external::target eq "web" || $external::target eq "answer") { + return $_[2]; + } else { + return $_[0]; + } } - } } -sub problem { - return '1'; +sub html { + if ( $external::target eq "web" ) { + return shift; + } } sub hinton { - return 0; + return 0; } sub random { - my ($start,$end,$step)=@_; - if ( ! $RANDOMINIT ) { srand($external::randomseed); $RANDOMINIT=1; } - my $num=1+int(($end-$start)/$step); - my $result=$start + int(rand() * $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 { + my ($item_cnt,$seed,$av,$std_dev) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_normal($item_cnt,$av,$std_dev); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_beta { + my ($item_cnt,$seed,$aa,$bb) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_beta($item_cnt,$aa,$bb); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_gamma { + my ($item_cnt,$seed,$a,$r) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_gamma($item_cnt,$a,$r); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_exponential { + my ($item_cnt,$seed,$av) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_exponential($item_cnt,$av); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_poisson { + my ($item_cnt,$seed,$mu) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_poisson($item_cnt,$mu); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_chi { + my ($item_cnt,$seed,$df) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_chi_square($item_cnt,$df); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_noncentral_chi { + my ($item_cnt,$seed,$df,$nonc) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_noncentral_chi_square($item_cnt,$df,$nonc); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_f { + my ($item_cnt,$seed,$dfn,$dfd) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_f($item_cnt,$dfn,$dfd); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_noncentral_f { + my ($item_cnt,$seed,$dfn,$dfd,$nonc) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_noncentral_f($item_cnt,$dfn,$dfd,$nonc); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_multivariate_normal { + my ($item_cnt,$seed,$mean,$covar) = @_; + my @oldseed=&random_get_seed(); + &random_set_seed_from_phrase($seed); + @retArray=&math_random_multivariate_normal($item_cnt,@$mean,@$covar); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_multinomial { + my ($item_cnt,$seed,@p) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_multinomial($item_cnt,@p); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_permutation { + my ($seed,@inArray) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_permutation(@inArray); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_uniform { + my ($item_cnt,$seed,$low,$high) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_uniform($item_cnt,$low,$high); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_uniform_integer { + my ($item_cnt,$seed,$low,$high) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_uniform_integer($item_cnt,$low,$high); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_binomial { + my ($item_cnt,$seed,$nt,$p) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_binomial($item_cnt,$nt,$p); + &random_set_seed(@oldseed); + return @retArray; +} + +sub random_negative_binomial { + my ($item_cnt,$seed,$ne,$p) = @_; + my @oldseed=&random_get_seed(); + my @retArray; + &random_set_seed_from_phrase($seed); + @retArray=&math_random_negative_binomial($item_cnt,$ne,$p); + &random_set_seed(@oldseed); + return @retArray; } sub abs { abs(shift) } @@ -160,15 +419,15 @@ sub log { log(shift) } sub atan2 { atan2($_[0],$_[1]) } sub sqrt { sqrt(shift) } -sub tan { sin($_[0]) / cos($_[0]) } +sub tan { CORE::sin($_[0]) / CORE::cos($_[0]) } #sub atan { atan2($_[0], 1); } #sub acos { atan2(sqrt(1 - $_[0] * $_[0]), $_[0] ); } #sub asin { atan2($_[0], sqrt(1- $_[0] * $_[0]) ); } -sub log10 { log($_[0])/log(10); } +sub log10 { CORE::log($_[0])/CORE::log(10); } sub factorial { - my $input = int(shift); + my $input = CORE::int(shift); return "Error - unable to take factorial of an negative number ($input)" if $input < 0; return "Error - factorial result is greater than system limit ($input)" if $input > 170; return 1 if $input == 0; @@ -193,12 +452,6 @@ sub max { return pop @sorted; } -sub html { - if ( $external::target eq "web" ) { - return @_[0]; - } -} - sub roundto { my ($input,$n) = @_; return sprintf('%.'.$n.'f',$input); @@ -206,8 +459,9 @@ sub roundto { sub to_string { my ($input,$n) = @_; - return sprintf('%'.$n,$input) if $n ne ""; return sprintf($input) if $n eq ""; + $n = '.'.$n if $n !~ /^\./; + return sprintf('%'.$n,$input) if $n ne ""; } sub sub_string { @@ -216,30 +470,200 @@ sub sub_string { } sub pow {return $_[0] ** $_[1]; } -sub ceil {return (($_[0]-int($_[0]))== 0.0) ? $_[0] : (int($_[0])+ 1); } -sub floor {return int($_[0]); } +sub ceil {return (($_[0]-CORE::int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? (CORE::int($_[0])+ 1) : CORE::int($_[0])); } +sub floor {return (($_[0]-CORE::int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? CORE::int($_[0]) : (CORE::int($_[0])-1)); } +#sub floor {return int($_[0]); } sub format { - my ($value,$fmt)=@_; - return sprintf('%.'.$fmt,$value); + 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);} + return $result; +} + +sub chemparse { + my ($reaction) = @_; + my @tokens = split(/(\s\+|\->|<=>)/,$reaction); + my $formula = ''; + foreach my $token (@tokens) { + if ($token eq '->' ) { + $formula .= '\ensuremath{\rightarrow} '; + next; + } + if ($token eq '<=>') { + if ($external::target eq 'web' && + &EXT('request.browser.unicode')) { + $formula .= '⇌ '; + } else { + $formula .= &web('<=> ','\ensuremath{\rightleftharpoons} ', + '<=$gt; '); + } + next; + } + $token =~ /^\s*(\d*)(.*)/; + $formula .= $1 if ($1 > 1); # stoichiometric coefficient + + my $molecule = $2; + # subscripts + $molecule =~ s|(?<=[a-zA-Z\[\s])(\d+)|$1|g; + # superscripts + $molecule =~ s|\^(\d*[+\-]*)|$1|g; + # strip whitespace + $molecule =~ s/\s*//g; + # forced space + $molecule =~ s/_/ /g; + $formula .= $molecule.' '; + } + # get rid of trailing space + $formula =~ s/(\Q${nbsp}\E| )$//; + + return &xmlparse($formula); +} + +sub prettyprint { + my ($value,$fmt,$target)=@_; + my $result; + my $dollarmode; + if (!$target) { $target = $external::target; } + if ($fmt =~ /chem/i) { return(&chemparse($value)); } + if ($fmt =~ /^\$(.*)/) { $fmt=$1; $dollarmode=1; } + if ($fmt) { $value=sprintf('%.'.$fmt,$value); } + 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 ($target eq 'web') { + $result=$frac.'×10'.$exponent.''; + } elsif ($target eq 'tex') { + $result='\ensuremath{'.$frac.'\times 10^{'.$exponent.'}}'; + } else { + $result=$value; + } + } else { + $result=$frac; + } + } else { + $result=$value; + if ($dollarmode) { $result=&dollarformat($result,$target); } + } + return $result; +} + +sub dollarformat { + my ($number,$target) = @_; + if (!$target) { $target = $external::target; } + if ($number =~ /\./) { + while ($number =~ /([^\.,]+)([^\.,][^\.,][^\.,])([,0-9]*\.[0-9]*)$/) { + $number = $1.','.$2.$3; + } + } else { + while ($number =~ /([^,]+)([^,][^,][^,])([,0-9]*)$/) { + $number = $1.','.$2.$3; + } + } + if ($target eq 'tex') { + $number='\$'.$number; #' stupid emacs + } else { + $number='$'.$number; #' stupid emacs + } + return $number; } sub map { - my $num = $#_/2; - my $i; - my @used; - my @permutation; - for ($i=0; $i < $num;) { - $rand = &random(1,$num,1); - if ( $used[$rand] == '0' ) { - $i++; - $used[$rand]='1'; - $permutation[$i]=$rand; - } - } - for ( $i=1 ; $i<$num+1 ; $i++ ) { - ${$_[$permutation[$i]]}=$_[$i+$num] - } + my ($phrase,$dest,$source)=@_; + my @oldseed=&random_get_seed(); + my @seed = &random_seed_from_phrase($phrase); + &random_set_seed(@seed); + my $destct = scalar(@$dest); + if (!$source) { + my @output; + my @idx = &math_random_permuted_index($destct); + my $ctr = 0; + while ($ctr < $destct) { + $output[$ctr] = $$dest[$idx[$ctr]]; + $ctr++; + } + &random_set_seed(@oldseed); + return @output; + } else { + my $num = scalar(@$source); + my @idx = &math_random_permuted_index($num); + my $ctr = 0; + my $tot = $num; + $tot = $destct if $destct < $num; + if (ref($$dest[0])) { + while ($ctr < $tot) { + ${$$dest[$ctr]} = $$source[$idx[$ctr]]; + $ctr++; + } + } else { + while ($ctr < $tot) { + $$dest[$ctr] = $$source[$idx[$ctr]]; + $ctr++; + } + } + } + &random_set_seed(@oldseed); + return ''; +} + +sub rmap { + my ($phrase,$dest,$source)=@_; + my @oldseed=&random_get_seed(); + my @seed = &random_seed_from_phrase($phrase); + &random_set_seed(@seed); + my $destct = scalar(@$dest); + if (!$source) { + my @idx = &math_random_permuted_index($destct); + my $ctr = 0; + my @r_idx; + while ($ctr < $destct) { + $r_idx[$idx[$ctr]] = $ctr; + $ctr++; + } + my @output; + $ctr = 0; + while ($ctr < $destct) { + $output[$ctr] = $$dest[$r_idx[$ctr]]; + $ctr++; + } + &random_set_seed(@oldseed); + return @output; + } else { + my $num = scalar(@$source); + my @idx = &math_random_permuted_index($num); + my $ctr = 0; + my $tot = $num; + $tot = $destct if $destct < $num; + my @r_idx; + while ($ctr < $tot) { + $r_idx[$idx[$ctr]] = $ctr; + $ctr++; + } + $ctr = 0; + if (ref($$dest[0])) { + while ($ctr < $tot) { + ${$$dest[$ctr]} = $$source[$r_idx[$ctr]]; + $ctr++; + } + } else { + while ($ctr < $tot) { + $$dest[$ctr] = $$source[$r_idx[$ctr]]; + $ctr++; + } + } + } + &random_set_seed(@oldseed); + return ''; } sub capa_id { return } @@ -247,59 +671,115 @@ sub capa_id { return } sub problem { return } sub name{ - my $fullname = &EXT('environment.lastname').', '.&EXT('environment.firstname').' '.&EXT('environment.middlename'); - $fullname = "" if $fullname eq ", "; - $fullname =~ s/\%2d/-/; - return $fullname; + my $fullname = &EXT('environment.lastname').', '.&EXT('environment.firstname').' '.&EXT('environment.middlename'); + $fullname = "" if $fullname eq ", "; + $fullname =~ s/\%2d/-/g; + return $fullname; } sub student_number { - my $id = &EXT('environment.id'); - $id = '' if $id eq ""; - return $id; + my $id = &EXT('environment.id'); + $id = '' if $id eq ""; + return $id; } sub class { - my $course = &EXT('course.description'); - $course = '' if $course eq ""; - return $course; + my $course = &EXT('course.description'); + $course = '' if $course eq ""; + return $course; } sub sec { - my $sec = &EXT('request.course.sec'); - $sec = '' if $sec eq ""; - return $sec; + my $sec = &EXT('request.course.sec'); + $sec = '' if $sec eq ""; + return $sec; } sub open_date { - my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate'))); - return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3]; + my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate'))); + return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); + my @hm = split(/:/,$dc[3]); + my $ampm = " am"; + if ($hm[0] > 12) { + $hm[0]-=12; + $ampm = " pm"; + } + return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm; } sub due_date { - my @dc = split(/\s+/,localtime(&EXT('resource.0.duedate'))); - return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3]; + my @dc = split(/\s+/,localtime(&EXT('resource.0.duedate'))); + return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); + my @hm = split(/:/,$dc[3]); + my $ampm = " am"; + if ($hm[0] > 12) { + $hm[0]-=12; + $ampm = " pm"; + } + return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm; } sub answer_date { - my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate'))); - return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3]; - } - -sub choose { - my $num = $_[0]; - return $_[$num]; + my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate'))); + return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969); + my @hm = split(/:/,$dc[3]); + my $ampm = " am"; + if ($hm[0] > 12) { + $hm[0]-=12; + $ampm = " pm"; + } + return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm; } -#$external::randomseed=time; -#$a=2; -#$b=2; -#$c=2; -#&map(1,\$a,\$b,\$c,3,4,5); -#print $a."\n".$b."\n"; - - - +sub array_moments { + my @input=@_; + my (@output,$N); + $N=scalar (@input); + $output[0]=$N; + if ($N <= 1) { + $output[1]=$input[0]; + $output[1]="Input array not defined" if ($N == 0); + $output[2]="variance undefined for N<=1"; + $output[3]="skewness undefined for N<=1"; + $output[4]="kurtosis undefined for N<=1"; + return @output; + } + my $sum=0; + foreach my $line (@input) { + $sum+=$line; + } + $output[1] = $sum/$N; + my ($x,$sdev,$var,$skew,$kurt) = 0; + foreach my $line (@input) { + $x=$line-$output[1]; + $var+=$x**2; + $skew+=$x**3; + $kurt+=$x**4; + } + $output[2]=$var/($N-1); + $sdev=CORE::sqrt($output[2]); + if ($sdev == 0) { + $output[3]="inf-variance=0"; + $output[4]="inf-variance=0"; + return @output; + } + $output[3]=$skew/($sdev**3*$N); + $output[4]=$kurt/($sdev**4*$N)-3; + return @output; +} +sub choose { + my $num = $_[0]; + return $_[$num]; +} +# expiremental idea +sub proper_path { + my ($path)=@_; + if ( $external::target eq "tex" ) { + return '/home/httpd/html'.$path; + } else { + return $path; + } +} 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.