Diff for /loncom/homework/default_homework.lcpm between versions 1.32 and 1.118

version 1.32, 2001/07/23 22:40:59 version 1.118, 2006/10/02 18:23:38
Line 1 Line 1
 # file name (temp): default_homework  # The LearningOnline Network with CAPA 
 # used by lonxml::xmlparse() as input variable $safeinit to Apache::run::run()  # used by lonxml::xmlparse() as input variable $safeinit to Apache::run::run()
 #  #
 # Guy Albertelli  # $Id$
 #  #
 # 05/25/2001 H. K. Ng  # Copyright Michigan State University Board of Trustees
 # 05/31/2001 H. K. Ng  
 #  #
   # 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
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
   #
   
 #init some globals  #init some globals
 $RANDOMINIT=0;  $hidden::RANDOMINIT=0;
 $pi=atan2(1,1)*4;  $pi=atan2(1,1)*4;
 $rad2deg=180.0/$pi;  $rad2deg=180.0/$pi;
 $deg2rad=$pi/180.0;  $deg2rad=$pi/180.0;
   $"=' ';
   use strict;
   {
       my $n = 0;
       my $total = 0;
       my $num_left = 0;
       my @order;
       my $type;
   
       sub init_permutation {
    my ($size,$requested_type) = @_;
    @order = (0..$size-1);
    $n = $size;
    $type = $requested_type;
    if ($type eq 'ordered') {
       $total = $num_left = 1;
    } elsif ($type eq 'unordered') {
       $total = $num_left = &factorial($size);
    } else {
       die("Unkown type: $type");
    }
       }
   
       sub get_next_permutation {
    if ($num_left == $total) {
       $num_left--;
       return \@order;
    }
   
    # Find largest index j with a[j] < a[j+1]
   
    my $j = scalar(@order) - 2;
    while ($order[$j] > $order[$j+1]) {
       $j--;
    }
   
    # Find index k such that a[k] is smallest integer
    # greater than a[j] to the right of a[j]
   
    my $k = scalar(@order) - 1;
    while ($order[$j] > $order[$k]) {
       $k--;
    }
   
    # Interchange a[j] and a[k]
   
    @order[($k,$j)] = @order[($j,$k)];
   
    # Put tail end of permutation after jth position in increasing order
   
    my $r = scalar(@order) - 1;
    my $s = $j + 1;
   
    while ($r > $s) {
       @order[($s,$r)]=@order[($r,$s)];
       $r--;
       $s++;
    }
   
    $num_left--;
    return(\@order);
       }
       
       sub get_permutations_left {
    return $num_left;
       }
   }
   
   sub check_commas {
       my ($response)=@_;
       #print("$response ");
       my @numbers=split(',',$response);
       #print(" numbers ".join('-',@numbers)." ");
       if (scalar(@numbers) > 1) {
           #print(" numbers[0] ".$numbers[0]." "); 
    if (length($numbers[0]) > 3 || length($numbers[0]) == 0) { return -1; }
    shift(@numbers);
    #print(" numbers ".scalar(@numbers)." ");
    while (scalar(@numbers) > 1) {
       #print(" numbers ".join('-',@numbers)." ");
       if (length($numbers[0]) != 3) { return -2; }
       shift(@numbers);
    }
    my ($number)=split('\.',$numbers[0]);
    #print(" number ".$number." ");
    #print(" numbers[0] ".$numbers[0]." ");
    if (length($number) != 3) { return -3; }
       } else {
    my ($number)=split('\.',$numbers[0]);
    if (length($number) > 3) { return -4; }
       }
       return 1;
   }
   
   
 sub caparesponse_check {  sub caparesponse_check {
   my $answer='';  #done      my ($answer,$response)=@_;
   my $type='';    #done      #not properly used yet: calc
   my $tol_type=''; # gets it's value from whether tol has a % or not done      #not to be used: $ans_fmt
   my $tol='';     #done      my $type=$LONCAPA::CAPAresponse_args{'type'};
   my $sig='';     #done lowerbnd,upperbnd      my $tol=$LONCAPA::CAPAresponse_args{'tol'};
   my $sig_lbound=''; #done      my $sig=$LONCAPA::CAPAresponse_args{'sig'};
   my $sig_ubound=''; #done      my $ans_fmt=$LONCAPA::CAPAresponse_args{'format'};
   my $ans_fmt='';      my $unit=$LONCAPA::CAPAresponse_args{'unit'};
   my $unit='';     #done      my $calc=$LONCAPA::CAPAresponse_args{'calc'};
   my $calc='';      my $samples=$LONCAPA::CAPAresponse_args{'samples'};
   my ($response,$expr)=@_;      
       my $tol_type=''; # gets it's value from whether tol has a % or not done
       my $sig_lbound=''; #done
   ($answer,$type,$tol,$sig,$ans_fmt,      my $sig_ubound=''; #done
    $unit,$calc) = eval $expr.';return ($answer,$type,$tol,$sig,$ans_fmt,$unit,$calc);';  
   #type's definitons come from capaParser.h  
   my $message='';      #type's definitons come from capaParser.h
   #remove leading and trailing whitespace  
   if ($response=~ /^\s|\s$/) {      #remove leading and trailing whitespace
     $response=~ s:^\s+|\s+$::g;      if (!defined($response)) {
     $message .="Removed ws now :$response:<br />";   $response='';
   } else {      }
     $message .="no ws in :$response:<br />";      if ($response=~ /^\s|\s$/) {
   }   $response=~ s:^\s+|\s+$::g;
    #&LONCAPA_INTERNAL_DEBUG("Removed ws now :$response:");
   if ($type eq '' ) {      }
     $message .= "Didn't find a type :$type:$expr: defaulting<br />";  
     if ( $answer eq ($answer *1.0)) { $type = 2;      #&LONCAPA_INTERNAL_DEBUG(" type is $type ");
     } else { $type = 3; }      if ($type eq 'cs' || $type eq 'ci') {
   } else {   #for string answers make surec all places spaces occur, there is 
          if ($type eq 'cs')    { $type = 4;          #really only 1 space, in both the answer and the response
     } elsif ($type eq 'ci')    { $type = 3;   $answer=~s/ +/ /g;
     } elsif ($type eq 'mc')    { $type = 5;   $response=~s/ +/ /g;
     } elsif ($type eq 'fml')   { $type = 8;      } elsif ($type eq 'mc') {
     } elsif ($type eq 'subj')  { $type = 7;   $answer=~s/[\s,]//g;
     } else { return "ERROR: Unknown type of answer: $type" }   $response=~s/[\s,]//g;
   }      }
       if ($type eq 'float' && $unit=~/\$/) {
   if ($tol eq '') {   if ($response!~/^\$/)  { return ('NO_UNIT', undef); }
     $tol=0.0;   $response=~s/\$//g;
     $tol_type=1; #TOL_ABSOLUTE      }
   } else {      if ($type eq 'float' && $unit=~/\,/ && (&check_commas($response)<0)) {
     if ($tol =~ /%$/) {   return "COMMA_FAIL:";
       chop $tol;      }
       $tol_type=2; #TOL_PERCENTAGE      $ans_fmt=~s/\W//g;
     } else {      $unit=~s/[\$,]//g;
       $tol_type=1; #TOL_ABSOLUTE      if ($type eq 'float') { $response=~s/,//g; }
     }  
   }      if (length($response) > 500) { return ('TOO_LONG',undef); }
   
   if ($sig eq '') {      if ($type eq '' ) {
     $sig_lbound = 0; #SIG_LB_DEFAULT   #&LONCAPA_INTERNAL_DEBUG("Didn't find a type :$type: defaulting");
     $sig_ubound =15; #SIG_UB_DEFAULT   if ( $answer eq ($answer *1.0)) { $type = 2;
   } else {        } else { $type = 3; }
     ($sig_lbound,$sig_ubound) = split /,/,$sig;      } else {
   }   if    ($type eq 'cs')    { $type = 4; }
   my $result = &caparesponse_capa_check_answer($response,$answer,$type,   elsif ($type eq 'ci')    { $type = 3 }
        $tol_type,$tol,   elsif ($type eq 'mc')    { $type = 5; }
        $sig_lbound,$sig_ubound,   elsif ($type eq 'fml')   { $type = 8; }
        $ans_fmt,$unit,$calc);          elsif ($type eq 'math')  { $type = 9; }
    elsif ($type eq 'subj')  { $type = 7; }
   if    ($result == '1') { $result='EXACT_ANS'; }    elsif ($type eq 'float') { $type = 2; }
   elsif ($result == '2') { $result='APPROX_ANS'; }   elsif ($type eq 'int')   { $type = 1; }
   elsif ($result == '3') { $result='SIG_FAIL'; }   else { return ('ERROR', "Unknown type of answer: $type") }
   elsif ($result == '4') { $result='UNIT_FAIL'; }      }
   elsif ($result == '5') { $result='NO_UNIT'; }  
   elsif ($result == '6') { $result='UNIT_OK'; }      my $points;
   elsif ($result == '7') { $result='INCORRECT'; }      my $id_list;
   elsif ($result == '8') { $result='UNIT_NOTNEEDED'; }      #formula type setup the sample points
   elsif ($result == '9') { $result='ANS_CNT_NOT_MATCH'; }      if ($type eq '8') {
   elsif ($result =='10') { $result='SUB_RECORDED'; }   ($id_list,$points)=split(/@/,$samples);
   elsif ($result =='11') { $result='BAD_FORMULA'; }   #&LONCAPA_INTERNAL_DEBUG("Found :$id_list:$points: points in $samples");
   elsif ($result =='12') { $result='WANTED_NUMERIC'; }      }
   else  {$result = "ERROR: Unknown Result:$result:$@:";}      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
    }
       }
   
   return "$result:<br />Error $error:<br />Answer $answer:<br />Response $response:<br /> type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$units<br />$message$expr";      ($sig_ubound,$sig_lbound)=&LONCAPA_INTERNAL_get_sigrange($sig);
   
       my $reterror="";
       my $result;
       if ($type eq '9') {
         $result = &maxima_check(&maxima_cas_formula_fix($response),&maxima_cas_formula_fix($answer),\$reterror);
       } else {
    if ($type eq '8') { # fml type
       $response = &capa_formula_fix($response);
       $answer   = &capa_formula_fix($answer);
    }
          $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' && !$response) { $result='MISSING_ANSWER'; }
       elsif ($result =='12') { $result='WANTED_NUMERIC'; }
       elsif ($result =='13') { $result='UNIT_INVALID_INSTRUCTOR'; }
       elsif ($result =='141') { $result='UNIT_INVALID_STUDENT'; }
       elsif ($result =='142') { $result='UNIT_INVALID_STUDENT'; }
       elsif ($result =='143') { $result='UNIT_INVALID_STUDENT'; }
       elsif ($result =='15') { $result='UNIT_IRRECONCIBLE'; }
       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(" $answer $response $result ");
       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,$expr)=@_;      my $response=$LONCAPA::CAPAresponse_args{'response'};
   # do these first, because who knows what varname the instructor might have used      my $result="Got response :".join(':',@LONCAPA::CAPAresponse_answer).":\n";
   # but it probably isn't $CAPARESPONSE_CHECK_LIST_answer      &LONCAPA_INTERNAL_DEBUG("args ".join(':',%LONCAPA::CAPAresponse_args));
   my $CAPARESPONSE_CHECK_LIST_answer = eval $expr.';return $answer';      my @responselist;
   my (@list) = eval $CAPARESPONSE_CHECK_LIST_answer;      my $type = $LONCAPA::CAPAresponse_args{'type'};
   my $result='';      &LONCAPA_INTERNAL_DEBUG("Got type :$type:\n");
   $result.="error:$@:<br />";      my $num_answers = scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}});
   # if the eval fails just use what is in the answer exactly      if ($type ne '' 
   if (!defined(@list) || !defined($list[0])) {   && $num_answers > 1) {
     $result.="list zero is undefined<br />";   (@responselist)=split(/,/,$response);
     $list[0]=$CAPARESPONSE_CHECK_LIST_answer;   if (@responselist < $num_answers) {
   }      return 'MISSING_ANSWER';
   my $aresult='';   }
   my $current_answer;   if (@responselist > $num_answers) {
   $result.="Got response :$CAPARESPONSE_CHECK_LIST_answer:$list[0]:<br />";      return 'EXTRA_ANSWER';
   my @responselist;   }
   my $type =eval $expr.';return $answer;';      } else {
   if ($type ne '' && $#list > 0) {   (@responselist)=($response);
     (@responselist)=split /,/,$response;      }
   } else {      &LONCAPA_INTERNAL_DEBUG("Initial final response :$responselist['-1']:");
     (@responselist)=($response);      my $unit;
   }      if ($type eq '' || $type eq 'float') {
   my $unit='';   #for numerical problems split off the unit
   $result.="Initial final response :$responselist['-1']:<br />";   if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) {
   if ($type eq '') {      $responselist['-1']=$1;
     #for numerical problems split off the unit      $unit=$2;
     if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) {   }
       $responselist['-1']=$1;      }
       $unit=$2;      &LONCAPA_INTERNAL_DEBUG("Final final response :$responselist['-1']:$unit:");
     }      $unit=~s/\s//;
   }  
   $result.="Final final response :$responselist['-1']:<br />";      foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) {
   $result.=":$#list: answers<br />";   if (!defined($thisanswer)) {
   $unit=~s/\s//;      return ('ERROR','answer was undefined');
   my $i=0;   }
   my $awards='';      }
   for ($i=0; $i<@list;$i++) {  
     $result.="trying answer :$list[$i]:<br />";      if ($unit ne '') {
     if ($unit eq '') {   foreach my $response (@responselist) {
       $aresult=&caparesponse_check($responselist[$i],      $response .= " $unit";
      $expr.';my $answer=\''.$list[$i].'\';');   }
     } else {      }
       $aresult=&caparesponse_check($responselist[$i]." $unit",  
    $expr.';my $answer=\''.$list[$i].'\';');      my %memoized;
     }      if ($LONCAPA::CAPAresponse_answer->{'type'}  eq 'ordered') {
     my ($temp)=split /:/, $aresult;   for (my $i=0; $i<scalar(@responselist);$i++) {
     $awards.="$temp,";      my $answer   = $LONCAPA::CAPAresponse_answer->{'answers'}[$i];
     $result.=$aresult;      my $response = $responselist[$i];
   }      my $key = "$answer\0$response";
   chop $awards;      $memoized{$key} = [&caparesponse_check($answer, $response)];
   return "$awards:<br />$result";   }
       } else {
    foreach my $response (@responselist) {
       foreach my $answer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) {
    my $key = "$answer\0$response";
    $memoized{$key} = [&caparesponse_check($answer, $response)];
       }
    }
       }
   
       my ($final_award,$final_msg);
       &init_permutation(scalar(@responselist),
         $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);
       while( &get_permutations_left() ) {
    my $order = &get_next_permutation();
    my (@awards, @msgs, $i);
    foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) {
       my $key = "$thisanswer\0".$responselist[$order->[$i]];
       push(@awards,$memoized{$key}[0]);
       push(@msgs,$memoized{$key}[1]);
       $i++;
    }
    my ($possible_award,$possible_msg) = 
       &LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs);
    push(@final_awards,$possible_award);
    push(@final_msg,$possible_msg);
       }
   
       my ($final_award,$final_msg) = 
    &LONCAPA_INTERNAL_FINALIZEAWARDS(\@final_awards,\@final_msg,undef,1);
       return ($final_award,$final_msg);
 }  }
   
 sub tex {  sub tex {
   if ( $external::target eq "tex" ) {      if ( $external::target eq "tex" ) {
     return @_[0];   return $_[0];
   } else {      } else {
     return @_[1];   return $_[1];
   }      }
 }  }
   
 sub var_in_tex {  sub var_in_tex {
   if ( $external::target eq "tex" ) {      if ( $external::target eq "tex" ) {
     return @_[0];   return $_[0];
   } else {      } else {
     return "";   return "";
   }      }
 }  }
   
 sub web {  sub web {
   if ( $external::target eq "tex" ) {      if ( $external::target eq "tex" ) {
     return @_[1];   return $_[1];
   } else {  
     if ( $external::target eq "web") {  
       return @_[2];  
     } else {      } else {
       return @_[0];   if ( $external::target eq "web" || $external::target eq "answer") {
       return $_[2];
    } else {
       return $_[0];
    }
     }      }
   }  
 }  }
   
 sub html {  sub html {
   if ( $external::target eq "web" ) {      if ( $external::target eq "web" ) {
     return shift;   return shift;
   }      }
 }  
   
 sub problem {  
   return '1';  
 }  }
   
 sub hinton {  sub hinton {
   return 0;      return 0;
 }  }
   
 sub random {  sub random {
   my ($start,$end,$step)=@_;      my ($start,$end,$step)=@_;
   if ( ! $RANDOMINIT ) { srand($external::randomseed); $RANDOMINIT=1; }      if ( ! $hidden::RANDOMINIT ) {
   my $num=1+int(($end-$start)/$step);   if ($external::randomseed == 0) { $external::randomseed=1; }
   my $result=$start + int(rand() * $num)*$step;   if ($external::randomseed =~/,/) {
   return $result;      my ($num1,$num2)=split(/,/,$external::randomseed);
       &random_set_seed(1,abs($num1));
    } elsif ($external::randomseed =~/:/) {
       my ($num1,$num2)=split(/:/,$external::randomseed);
       &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 {  sub random_normal {
   my ($item_cnt,$seed,$av,$std_dev) = @_;      my ($item_cnt,$seed,$av,$std_dev) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_normal($item_cnt,$av,$std_dev);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_normal($item_cnt,$av,$std_dev);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_beta {  sub random_beta {
   my ($item_cnt,$seed,$aa,$bb) = @_;      my ($item_cnt,$seed,$aa,$bb) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_beta($item_cnt,$aa,$bb);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_beta($item_cnt,$aa,$bb);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_gamma {  sub random_gamma {
   my ($item_cnt,$seed,$a,$r) = @_;      my ($item_cnt,$seed,$a,$r) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_gamma($item_cnt,$a,$r);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_gamma($item_cnt,$a,$r);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_exponential {  sub random_exponential {
   my ($item_cnt,$seed,$av) = @_;      my ($item_cnt,$seed,$av) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_exponential($item_cnt,$av);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_exponential($item_cnt,$av);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_poisson {  sub random_poisson {
   my ($item_cnt,$seed,$mu) = @_;      my ($item_cnt,$seed,$mu) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_poisson($item_cnt,$mu);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_poisson($item_cnt,$mu);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_chi {  sub random_chi {
   my ($item_cnt,$seed,$df) = @_;      my ($item_cnt,$seed,$df) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_chi_square($item_cnt,$df);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_chi_square($item_cnt,$df);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_noncentral_chi {  sub random_noncentral_chi {
   my ($item_cnt,$seed,$df,$nonc) = @_;      my ($item_cnt,$seed,$df,$nonc) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_noncentral_chi_square($item_cnt,$df,$nonc);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_noncentral_chi_square($item_cnt,$df,$nonc);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_f {  sub random_f {
   my ($item_cnt,$seed,$dfn,$dfd) = @_;      my ($item_cnt,$seed,$dfn,$dfd) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_f($item_cnt,$dfn,$dfd);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_f($item_cnt,$dfn,$dfd);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_noncentral_f {  sub random_noncentral_f {
   my ($item_cnt,$seed,$dfn,$dfd,$nonc) = @_;      my ($item_cnt,$seed,$dfn,$dfd,$nonc) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_noncentral_f($item_cnt,$dfn,$dfd,$nonc);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_noncentral_f($item_cnt,$dfn,$dfd,$nonc);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_multivariate_normal {  sub random_multivariate_normal {
   my ($item_cnt,$seed,@mean) = @_;      my ($item_cnt,$seed,$mean,$covar) = @_;
   return "Number of deviates must be greater than 0" if $item_cnt <= 0;      my @oldseed=&random_get_seed();
   my (@covar,@retArray);      &random_set_seed_from_phrase($seed);
   my $ind = 0;      my @retArray=&math_random_multivariate_normal($item_cnt,@$mean,@$covar);
   while ($ind<$item_cnt) {      &random_set_seed(@oldseed);
      push @covar, pop (@mean);      return @retArray;
      $ind++;  
   }  
   &random_set_seed_from_phrase($seed);  
   @retArray=&math_random_multivariate_normal($item_cnt,@mean,@covar);  
   return @retArray;  
 }  }
   
 sub random_multinomial {  sub random_multinomial {
   my ($item_cnt,$seed,@p) = @_;      my ($item_cnt,$seed,@p) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_multinomial($item_cnt,@p);      &random_set_seed_from_phrase($seed);
   return @retArray;      my @retArray=&math_random_multinomial($item_cnt,@p);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_permutation {  sub random_permutation {
   my ($seed,@inArray) = @_;      my ($seed,@inArray) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_permutation(@inArray);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_permutation(@inArray);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_uniform {  sub random_uniform {
   my ($item_cnt,$seed,$low,$high) = @_;      my ($item_cnt,$seed,$low,$high) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_uniform($item_cnt,$low,$high);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_uniform($item_cnt,$low,$high);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_uniform_integer {  sub random_uniform_integer {
   my ($item_cnt,$seed,$low,$high) = @_;      my ($item_cnt,$seed,$low,$high) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_uniform_integer($item_cnt,$low,$high);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_uniform_integer($item_cnt,$low,$high);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_binomial {  sub random_binomial {
   my ($item_cnt,$seed,$nt,$p) = @_;      my ($item_cnt,$seed,$nt,$p) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_binomial($item_cnt,$nt,$p);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_binomial($item_cnt,$nt,$p);
       &random_set_seed(@oldseed);
       return @retArray;
 }  }
   
 sub random_negative_binomial {  sub random_negative_binomial {
   my ($item_cnt,$seed,$ne,$p) = @_;      my ($item_cnt,$seed,$ne,$p) = @_;
   my @retArray;      my @oldseed=&random_get_seed();
   &random_set_seed_from_phrase($seed);      my @retArray;
   @retArray=&math_random_negative_binomial($item_cnt,$ne,$p);      &random_set_seed_from_phrase($seed);
   return @retArray;      @retArray=&math_random_negative_binomial($item_cnt,$ne,$p);
 }      &random_set_seed(@oldseed);
       return @retArray;
 sub abs { abs(shift) }  }
 sub sin { sin(shift) }  
 sub cos { cos(shift) }  sub abs { CORE::abs(shift) }
 sub exp { exp(shift) }  sub sin { CORE::sin(shift) }
 sub int { int(shift) }  sub cos { CORE::cos(shift) }
 sub log { log(shift) }  sub exp { CORE::exp(shift) }
 sub atan2 { atan2($_[0],$_[1]) }  sub int { CORE::int(shift) }
 sub sqrt { sqrt(shift) }  sub log { CORE::log(shift) }
   sub atan2 { CORE::atan2($_[0],$_[1]) }
   sub sqrt { CORE::sqrt(shift) }
   
 sub tan  { sin($_[0]) / cos($_[0]) }  sub tan  { CORE::sin($_[0]) / CORE::cos($_[0]) }
 #sub atan { atan2($_[0], 1); }  #sub atan { atan2($_[0], 1); }
 #sub acos { atan2(sqrt(1 - $_[0] * $_[0]), $_[0] ); }  #sub acos { atan2(sqrt(1 - $_[0] * $_[0]), $_[0] ); }
 #sub asin { atan2($_[0], sqrt(1- $_[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 {  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 - 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 "Error - factorial result is greater than system limit ($input)" if $input > 170;
     return 1 if $input == 0;      return 1 if $input == 0;
Line 389  sub sub_string { Line 664  sub sub_string {
 }  }
   
 sub pow   {return $_[0] ** $_[1]; }  sub pow   {return $_[0] ** $_[1]; }
 sub ceil  {return (($_[0]-int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? (int($_[0])+ 1) : 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]-int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? int($_[0]) : (int($_[0])-1)); }  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 floor {return int($_[0]); }
   
 sub format {  sub format {
   my ($value,$fmt)=@_;      my ($value,$fmt)=@_;
   return sprintf('%.'.$fmt,$value);      my ($dollarmode,$commamode,$alwaysperiod,$options);
       if ($fmt =~ /^([^\d]*)(.*)/) { $options=$1; $fmt=$2; } 
       #if ($options =~ /\$/) { $dollamode=1; }
       #if ($options =~ /,/)  { $commamode=1; }
       if ($options =~ /\./) { $alwaysperiod=1; }
       my $result;
       if ($fmt=~/s$/i) {
    $result=&format_significant_figures($value,$fmt);
       } else {
    $fmt=~s/e/E/g;
    $result=sprintf('%.'.$fmt,$value);
    if ($alwaysperiod && $fmt eq '0f') { $result .='.'; }
    $result=~s/(E[+-]*)0/$1/;
       }
       #if ($dollarmode) {$result=&dollarformat($result);}
       #if ($commamode) {$result=&commaformat($result);}
       return $result;
   }
   
   sub chemparse {
       my ($reaction) = @_;
       my @tokens = split(/(\s\+|\->|<=>|<\-|\.)/,$reaction);
       my $formula = '';
       foreach my $token (@tokens) {
    if ($token eq '->' ) {
       $formula .= '<m>\ensuremath{\rightarrow}</m> ';
       next;
    }
    if ($token eq '<-' ) {
       $formula .= '<m>\ensuremath{\leftarrow}</m> ';
       next;
    }  
    if ($token eq '<=>') {
       if ($external::target eq 'web' &&
    &EXT('request.browser.unicode')) {
    $formula .= '&#8652; ';
       } else {
    $formula .= &web('<=> ','<m>\ensuremath{\rightleftharpoons}</m> ',
    '&lt;=&gt; ');
       }
       next;
    }
    if ($token eq '.') {
     $formula =~ s/(\&nbsp\;| )$//;
     $formula .= '&middot;';
     next;
    }
    $token =~ /^\s*([\d|\/]*(?:&frac\d\d)?)(.*)/;
           $formula .= $1 if ($1 ne '1');  # stoichiometric coefficient
   
    my $molecule = $2;
    # subscripts
    $molecule =~ s|(?<=[a-zA-Z\)\]\s])(\d+)|<sub>$1</sub>|g;
    # superscripts
    $molecule =~ s|\^(\d*[+\-]*)|<sup>$1</sup>|g;
    # strip whitespace
    $molecule =~ s/\s*//g;
    # forced space
    $molecule =~ s/_/ /g;
    $molecule =~ s/-/&minus;/g;
    $formula .= $molecule.'&nbsp;';
       }
       # get rid of trailing space
       $formula =~ s/(\&nbsp\;| )$//;
       return &xmlparse($formula);
   }
   
   sub prettyprint {
       my ($value,$fmt,$target)=@_;
       my $result;
       if (!$target) { $target = $external::target; }
       if ($fmt =~ /chem/i) { return(&chemparse($value)); }
       my ($dollarmode,$commamode,$alwaysperiod,$options);
       if ($fmt =~ /^([^\d]*)(.*)/) { $options=$1; $fmt=$2; } 
       if ($options =~ /\$/) { $dollarmode=1; }
       if ($options =~ /,/)  { $commamode=1; }
       if ($options =~ /\./) { $alwaysperiod=1; }
       if ($fmt=~/s$/i) {
    $value=&format_significant_figures($value,$fmt);
       } elsif ($fmt) {
    $value=sprintf('%.'.$fmt,$value);
       }
       if ($alwaysperiod && $fmt eq '0f') {
    if ($target eq 'tex') {
       $value .='\\ensuremath{.}';
    } else {
       $value .='.';
    }
       }
       if ($value =~ /([0-9\.\-\+]+)E([0-9\-\+]+)/i ) {
    my $frac=$1;
    if ($dollarmode) { $frac=&dollarformat($frac); }
    if ($commamode) { $frac=&commaformat($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.'&#215;10<sup>'.$exponent.'</sup>';
       } 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); }
    elsif ($commamode)  { $result=&commaformat($result,$target); }
       }
       return $result;
   }
   
   sub commaformat {
       my ($number,$target) = @_;
       if ($number =~ /\./) {
    while ($number =~ /([^0-9]*)([0-9]+)([^\.,][^\.,][^\.,])([,0-9]*\.[0-9]*)$/) {
       $number = $1.$2.','.$3.$4;
    }
       } else {
    while ($number =~ /^([^0-9]*)([0-9]+)([^,][^,][^,])([,0-9]*)$/) {
       $number = $1.$2.','.$3.$4;
    }
       }
       return $number;
   }
   
   sub dollarformat {
       my ($number,$target) = @_;
       if (!$target) { $target = $external::target; }
       $number=&commaformat($number,$target);
       if ($target eq 'tex') {
    $number='\$'.$number; #' stupid emacs
       } else {
    $number='$'.$number; #' stupid emacs
       }
       return $number; 
   }
   
   # format of form ns or nS where n is an integer
   sub format_significant_figures {
       my ($number,$format) = @_; 
       return '0' if ($number == 0);
       # extract number of significant figures needed
       my ($sig) = ($format =~ /(\d+)s/i);
       # arbitrary choice - suggestions ?? or throw error message?
       $sig = 3 if ($sig eq '');
       # save the minus sign
       my $sign = ($number < 0) ? '-' : '';
       $number = abs($number);
       # needed to correct for a number greater than 1 (or
       my $power = ($number < 1) ? 0 : 1;
       # could round up. Take the integer part of log10.
       my $x10 = int(log($number)/log(10));
       # find number with values left of decimal pt = # of sign figs.
       my $xsig = $number*10**($sig-$x10-$power);
       # get just digits left of decimal pt - also rounds off correctly
       my $xint  = sprintf('%.0f',$xsig);
       # save any trailing zero's
       my ($zeros) = ($xint =~ /(0+)$/);
       # return number to original magnitude
       my $numSig = $xint*10**($x10-$sig+$power);
       # insert trailing zero's if have decimal point
       $numSig =~ s/^(\d+)\.(\d+)(\e?(.*)?)$/$1\.$2$zeros$3/;
       # put a decimal pt for number ending with 0 and length = # of sig fig
       $numSig.='.' if (length($numSig) == $sig && $numSig =~ /0$/);
       if (length($numSig) < $sig) {
    $numSig.='.'.substr($zeros,0,($sig-length($numSig)));
       }
       # return number with sign
       return $sign.$numSig;
   
 }  }
   
 sub map {  sub map {
     my ($phrase,$dest,$source)=@_;      my ($phrase,$dest,$source)=@_;
       my @oldseed=&random_get_seed();
     my @seed = &random_seed_from_phrase($phrase);      my @seed = &random_seed_from_phrase($phrase);
     &random_set_seed(@seed);      &random_set_seed(@seed);
     my $destct = scalar(@$dest);      my $destct = scalar(@$dest);
Line 411  sub map { Line 862  sub map {
     $output[$ctr] = $$dest[$idx[$ctr]];      $output[$ctr] = $$dest[$idx[$ctr]];
     $ctr++;      $ctr++;
  }   }
           &random_set_seed(@oldseed);
  return @output;   return @output;
     } else {      } else {
  my $num = scalar(@$source);   my $num = scalar(@$source);
Line 430  sub map { Line 882  sub map {
     }      }
  }   }
     }      }
       &random_set_seed(@oldseed);
       return '';
 }  }
   
 sub rmap {  sub rmap {
     my ($phrase,$dest,$source)=@_;      my ($phrase,$dest,$source)=@_;
       my @oldseed=&random_get_seed();
     my @seed = &random_seed_from_phrase($phrase);      my @seed = &random_seed_from_phrase($phrase);
     &random_set_seed(@seed);      &random_set_seed(@seed);
     my $destct = scalar(@$dest);      my $destct = scalar(@$dest);
Line 451  sub rmap { Line 906  sub rmap {
     $output[$ctr] = $$dest[$r_idx[$ctr]];      $output[$ctr] = $$dest[$r_idx[$ctr]];
     $ctr++;      $ctr++;
  }   }
           &random_set_seed(@oldseed);
  return @output;   return @output;
     } else {      } else {
  my $num = scalar(@$source);   my $num = scalar(@$source);
Line 476  sub rmap { Line 932  sub rmap {
     }      }
  }   }
     }      }
       &random_set_seed(@oldseed);
       return '';
 }  }
   
 sub capa_id { return }  sub capa_id { return }
Line 483  sub capa_id { return } Line 941  sub capa_id { return }
 sub problem { return }  sub problem { return }
   
 sub name{  sub name{
   my $fullname = &EXT('environment.lastname').', '.&EXT('environment.firstname').' '.&EXT('environment.middlename');      my $fullname = &EXT('environment.lastname').', '.&EXT('environment.firstname').' '.&EXT('environment.middlename');
   $fullname = "" if $fullname eq ",  ";      $fullname = "" if $fullname eq ",  ";
   $fullname =~ s/\%2d/-/g;      $fullname =~ s/\%2d/-/g;
   return $fullname;      return $fullname;
 }  }
   
 sub student_number {   sub student_number { 
   my $id = &EXT('environment.id');      my $id = &EXT('environment.id');
   $id = '' if $id eq "";      $id = '' if $id eq "";
   return $id;      return $id;
 }  }
   
 sub class {  sub class {
   my $course = &EXT('course.description');      my $course = &EXT('course.description');
   $course = '' if $course eq "";      $course = '' if $course eq "";
   return $course;      return $course;
   }
   
   sub firstname {
       my $firstname = &EXT('environment.firstname');
       $firstname = '' if $firstname eq "";
       return $firstname;
   }
                                                                                   
   sub lastname {
       my $lastname = &EXT('environment.lastname');
       $lastname = '' if $lastname eq "";
       return $lastname;
 }  }
   
 sub sec {   sub sec { 
   my $sec = &EXT('request.course.sec');      my $sec = &EXT('request.course.sec');
   $sec = '' if $sec eq "";      $sec = '' if $sec eq "";
   return $sec;      return $sec;
 }  }
   
 sub open_date {   sub open_date { 
   my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate')));      my @dc = split(/\s+/,localtime(&EXT('resource.0.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";
   if ($hm[0] > 12) {      if ($hm[0] > 12) {
     $hm[0]-=12;   $hm[0]-=12;
     $ampm = " pm";   $ampm = " pm";
   }      }
   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 @dc = split(/\s+/,localtime(&EXT('resource.0.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";
   if ($hm[0] > 12) {      if ($hm[0] > 12) {
     $hm[0]-=12;   $hm[0]-=12;
     $ampm = " pm";   $ampm = " pm";
   }      }
   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;
 #  return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3];  
 }  }
   
 sub answer_date {   sub answer_date { 
   my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate')));      my @dc = split(/\s+/,localtime(&EXT('resource.0.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";
   if ($hm[0] > 12) {      if ($hm[0] > 12) {
     $hm[0]-=12;   $hm[0]-=12;
     $ampm = " pm";   $ampm = " pm";
   }      }
   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;
 #  return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3];  
 }  }
   
 sub array_moments {  sub array_moments {
   my @input=@_;      my @input=@_;
   my (@output,$N);      my (@output,$N);
   $N=scalar (@input);      $N=scalar (@input);
   $output[0]=$N;      $output[0]=$N;
   if ($N <= 1) {      if ($N <= 1) {
     $output[1]=$input[0];   $output[1]=$input[0];
     $output[1]="Input array not defined" if ($N == 0);   $output[1]="Input array not defined" if ($N == 0);
     $output[2]="variance undefined for N<=1";   $output[2]="variance undefined for N<=1";
     $output[3]="skewness undefined for N<=1";   $output[3]="skewness undefined for N<=1";
     $output[4]="kurtosis 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;      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=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 {  sub choose {
   my $num = $_[0];      my $num = $_[0];
   return $_[$num];      return $_[$num];
 }  }
   
   #&sum1(1,$x,sub { &sum1($_[0],2*$_[0], sub { fact($_[0])**2 })});
   #sub sum1 {
   #    my ($start,$end,$sub)=@_;
   #    my $sum=0;
   #    for (my $i=$start;$i<=$end;$i++) {
   #        $sum+=&$sub($i);
   #    }
   #    return $sum
   #}
   
   #&sum2('a',1,$x,'&sum2(\'b\',$a,2*$a, \'&factorial($b)**2\')');
   #sub sum2 {
   #    my ($varname,$start,$end,$line)=@_;
   #    my $sum=0;
   #    for (my $i=$start;$i<=$end;$i++) {
   # my $func=sub {
   #    eval("\$".$varname."=$i");
   #    eval($line);
   # };
   #        $sum+=&$func($i);
   #    }
   #    return $sum
   #}
   
   # expiremental idea
   sub proper_path {
       my ($path)=@_;
       if ( $external::target eq "tex" ) {
    return '/home/httpd/html'.$path;
       } else {
    return $path;
       }
   }
   

Removed from v.1.32  
changed lines
  Added in v.1.118


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.