Diff for /loncom/homework/default_homework.lcpm between versions 1.105 and 1.170

version 1.105, 2005/11/16 23:17:39 version 1.170, 2014/12/14 02:43:59
Line 33  $pi=atan2(1,1)*4; Line 33  $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 {  sub check_commas {
     my ($response)=@_;      my ($response)=@_;
Line 60  sub check_commas { Line 126  sub check_commas {
     return 1;      return 1;
 }  }
   
   
 sub caparesponse_check {  sub caparesponse_check {
     my ($answer,$response)=@_;      my ($answer,$response)=@_;
     #not properly used yet: calc      #not properly used yet: calc
Line 76  sub caparesponse_check { Line 143  sub caparesponse_check {
     my $sig_lbound=''; #done      my $sig_lbound=''; #done
     my $sig_ubound=''; #done      my $sig_ubound=''; #done
   
   
     #type's definitons come from capaParser.h      #type's definitons come from capaParser.h
     my $message='';  
     #remove leading and trailing whitespace      #remove leading and trailing whitespace
     if (!defined($response)) {      if (!defined($response)) {
  $response='';   $response='';
     }      }
     if ($response=~ /^\s|\s$/) {      if ($response=~ /^\s|\s$/) {
  $response=~ s:^\s+|\s+$::g;   $response=~ s:^\s+|\s+$::g;
  $message .="Removed ws now :$response:\n";  
     } else {  
  $message .="no ws in :$response:\n";  
     }      }
     &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 100  sub caparesponse_check { Line 163  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: Missing \$ "; }   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 110  sub caparesponse_check { Line 173  sub caparesponse_check {
     $unit=~s/[\$,]//g;      $unit=~s/[\$,]//g;
     if ($type eq 'float') { $response=~s/,//g; }      if ($type eq 'float') { $response=~s/,//g; }
   
     if (length($response) > 500) { return "TOO_LONG: Answer too long"; }      if (length($response) > 500) { return ('TOO_LONG',undef); }
   
     if ($type eq '' ) {      if ($type eq '' ) {
  $message .= "Didn't find a type :$type: defaulting\n";  
  if ( $answer eq ($answer *1.0)) { $type = 2;   if ( $answer eq ($answer *1.0)) { $type = 2;
       } else { $type = 3; }        } else { $type = 3; }
     } else {      } else {
  if ($type eq 'cs')    { $type = 4; }   if    ($type eq 'cs')    { $type = 4; }
  elsif ($type eq 'ci')    { $type = 3 }   elsif ($type eq 'ci')    { $type = 3 }
  elsif ($type eq 'mc')    { $type = 5; }   elsif ($type eq 'mc')    { $type = 5; }
  elsif ($type eq 'fml')   { $type = 8; }   elsif ($type eq 'fml')   { $type = 8; }
           elsif ($type eq 'math')  { $type = 9; }
  elsif ($type eq 'subj')  { $type = 7; }   elsif ($type eq 'subj')  { $type = 7; }
  elsif ($type eq 'float') { $type = 2; }   elsif ($type eq 'float') { $type = 2; }
  elsif ($type eq 'int')   { $type = 1; }   elsif ($type eq 'int')   { $type = 1; }
  else { return "ERROR: Unknown type of answer: $type" }   else { return ('ERROR', "Unknown type of answer: $type") }
     }      }
   
     my $points;      my $points;
Line 132  sub caparesponse_check { Line 195  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);
  $message.="Found :$id_list:$points: points in $samples\n";  
     }      }
     if ($tol eq '') {      if ($tol eq '') {
  $tol=0.0;   $tol=0.0;
Line 149  sub caparesponse_check { Line 211  sub caparesponse_check {
     ($sig_ubound,$sig_lbound)=&LONCAPA_INTERNAL_get_sigrange($sig);      ($sig_ubound,$sig_lbound)=&LONCAPA_INTERNAL_get_sigrange($sig);
   
     my $reterror="";      my $reterror="";
     my $result = &caparesponse_capa_check_answer($response,$answer,$type,      my $result;
       if (($type eq '9') || ($type eq '8')) {
           if ($response=~/\=/) {
               return ('BAD_FORMULA','Please submit just an expression, not an equation.');
           } elsif ($response =~ /\,/ and $response !~ /^\s*\{.*\}\s*$/) {
               return ('BAD_FORMULA');
           }
       }
       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,   $tol_type,$tol,
  $sig_lbound,$sig_ubound,   $sig_lbound,$sig_ubound,
  $ans_fmt,$unit,$calc,$id_list,   $ans_fmt,$unit,$calc,$id_list,
  $points,$external::randomseed,   $points,$external::randomseed,
  \$reterror);   \$reterror);
       }
     if    ($result == '1') { $result='EXACT_ANS'; }       if    ($result == '1') { $result='EXACT_ANS'; } 
     elsif ($result == '2') { $result='APPROX_ANS'; }      elsif ($result == '2') { $result='APPROX_ANS'; }
     elsif ($result == '3') { $result='SIG_FAIL'; }      elsif ($result == '3') { $result='SIG_FAIL'; }
Line 176  sub caparesponse_check { Line 253  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:$@:";}
   
     return ("$result:\nRetError $reterror:\nAnswer $answer:\nResponse $response:\n type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|\n$message",$reterror);      return ($result,$reterror);
 }  }
   
   
 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'};
     $result.="Got type :$type:\n";      my $answerunit=$LONCAPA::CAPAresponse_args{'unit'};
     if ($type ne '' && $#LONCAPA::CAPAresponse_answer > 0) {      &LONCAPA_INTERNAL_DEBUG("Got type :$type: answer unit :$answerunit:\n");
  (@responselist)=split(/,/,$response);     
  if (@responselist < @LONCAPA::CAPAresponse_answer) {      my $preprocess=$LONCAPA::CAPAresponse_args{'preprocess'};
       $preprocess=~s/^\&//;
   
       my $num_input_lines =
    scalar(@{$LONCAPA::CAPAresponse_answer->{'answers'}});
       
       if ($type ne '' ) {
    if (scalar(@$responses) < $num_input_lines) {
     return 'MISSING_ANSWER';      return 'MISSING_ANSWER';
  }   }
  if (@responselist > @LONCAPA::CAPAresponse_answer) {   if (scalar(@$responses) > $num_input_lines) {
     return 'EXTRA_ANSWER';      return 'EXTRA_ANSWER';
  }   }
     } else {  
  (@responselist)=($response);  
     }      }
     $result.="Initial final response :$responselist['-1']:\n";  
       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';
    }
       }
   
     my $unit;      my $unit;
     if ($type eq '' || $type eq 'float') {      my ($allowalgebra)=($LONCAPA::CAPAresponse_args{'allowalgebra'}=~/^(yes|1|on)$/i);
       if ($type eq 'float' || $type eq '') {
  #for numerical problems split off the unit   #for numerical problems split off the unit
  if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) {          my $part1;
     $responselist['-1']=$1;          my $part2;
     $unit=$2;          if ($allowalgebra) {
              ($part1,$part2)=($responses->[0][-1]=~ /^(.*[^\s])\s+([^\s]+)$/); 
           } else {
              ($part1,$part2)=($responses->[0][-1]=~ /^([\d\.\,\s\$]*(?:(?:[xX\*]10[\^\*]*|[eE]*)[\+\-]*\d*)*(?:^|\S)\d+)([\$\s\w\^\*\/\(\)\+\-]*[^\d\.\s\,][\$\s\w\^\*\/\(\)\+\-]*)$/);
           }
           if (defined($part1) && defined($part2)) {
       $responses->[0][-1]=$part1;
       $unit=&capa_formula_fix($part2);
               my $customunits=$LONCAPA::CAPAresponse_args{'customunits'};
               if ($customunits =~ /\S/) {
                   foreach my $replacement (split(/\s*\,\s*/,$customunits)) {
                       my ($which,$what)=split(/\s*\=\s*/,$replacement);
                       if ((defined($which)) && (defined($what))) {
                           $what=&capa_formula_fix($what);
                           $unit=~s/$which/\($what\)/g;
                       }
                   }
               }
  }   }
     }      }
     $result.="Final final response :$responselist['-1']:$unit:\n";  
     $unit=~s/\s//;      $unit=~s/\s//;
       my $error;
       foreach my $response (@$responses) {
          foreach my $element (@$response) {
             # See if we have preprocessor
             if ($preprocess=~/\S/) {
                if (defined(&$preprocess)) {
                   no strict 'refs';
                   $element=&$preprocess($element,$unit);
                   use strict 'refs';
                }
             }
             if (($type eq 'float') || (($type eq '') && ($unit ne ''))) {
                 $element =~ s/\s//g;
             }
             my $appendunit=$unit;
   # Deal with percentages
   # unit is unit entered by student, answerunit is unit by author
   # Deprecated: divide answer by 100 if student entered percent,
   # but author did not. Too much confusion
   #          if (($unit=~/\%/) && ($answerunit ne '%'))  {
   #             $element=$element/100;
   #             $appendunit=~s/\%//;
   #          }    
   # Author entered percent, student did not
             if (($unit!~/\%/) && ($answerunit=~/\%/)) {
                $element=$element*100;
                $appendunit='%'.$appendunit;
             }
   # Zero does not need a dimension
             if (($element =~ /^[0\.]+$/) && ($unit!~/\w/) && ($answerunit=~/\w/)) {
                $appendunit=$answerunit;
             }
   # Do the math for the student if allowed
             if ($allowalgebra) {
                $element=&cas('maxima',$element);
             }
             if ($appendunit ne '') {
                 $element .= " $appendunit";
             }  
             &LONCAPA_INTERNAL_DEBUG("Made response element :$element:");
          }
       }
       
       foreach my $thisanswer (@{ $LONCAPA::CAPAresponse_answer->{'answers'} }) {
    if (!defined($thisanswer)) {
       return ('ERROR','answer was undefined');
    }
       }
   
     my ($awards, @msgs);      my $allow_control_char = 0;
     foreach my $thisanswer (@LONCAPA::CAPAresponse_answer) {      my $control_chars_removed = 0;
  my ($msg,$aresult);      my $ansstring;
  $result.="trying answer :$thisanswer:\n";      if ($type eq 'cs' || $type eq 'ci') {
  if (defined($thisanswer)) {          if (ref($LONCAPA::CAPAresponse_answer->{'answers'}) eq 'ARRAY') {
     if ($unit eq '') {              foreach my $strans (@{$LONCAPA::CAPAresponse_answer->{'answers'}}) {
  ($aresult,$msg)=&caparesponse_check($thisanswer,                  if (ref($strans) eq 'ARRAY') {
     $responselist[$i]);                      $ansstring = join("\0",@{$strans});
     } else {                      foreach my $item (@{$strans}) {  
  ($aresult,$msg)=&caparesponse_check($thisanswer,                          if ($item =~ /[\000-\037]/) {
     $responselist[$i]." $unit");                              $allow_control_char = 1;
                           }
                       }
                   }
               }
           }
       }
   
   #    &LONCAPA_INTERNAL_DEBUG(&LONCAPA_INTERNAL_Dumper($responses));
       my %memoized;
       if ($LONCAPA::CAPAresponse_answer->{'type'}  eq 'ordered') {
    for (my $i=0; $i<scalar(@$responses);$i++) {
       my $answer   = $LONCAPA::CAPAresponse_answer->{'answers'}[$i];
       my $response = $responses->[$i];
       my $key = "$answer\0$response";
       my (@awards,@msgs);
       for (my $j=0; $j<scalar(@$response); $j++) {
                   if ($type eq 'cs' || $type eq 'ci') {
                       unless ($allow_control_char) {
                           if ($response->[$j] =~ /[\000-\037]/) { 
                               $response->[$j] =~ s/[\000-\037]//g;
                               $control_chars_removed = 1;
                           }  
                       }
                   }
                   # See if we have preprocessor for string responses
                   if (($preprocess=~/\S/) && ($type eq 'cs' || $type eq 'ci'))  {
                       if (defined(&$preprocess)) {
                           no strict 'refs';
                           $response->[$j]=&$preprocess($response->[$j]);
                           use strict 'refs';
                       }
                   }
   
    my ($award,$msg) = &caparesponse_check($answer->[$j],
          $response->[$j]);
                   if ($type eq 'cs' || $type eq 'ci') {
                       $error = &verify_stringresponse($type,$award,$response->[$j],
                                                       $answer->[$j]);
                   }
    push(@awards,$award);
    push(@msgs,  $msg);
       }
       my ($award,$msg) = 
    &LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs);
       $memoized{$key} = [$award,$msg];
    }
       } else {
    #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'} }) {
    my $key = "$answer\0$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++) {
                           if ($type eq 'cs' || $type eq 'ci') {
                               unless ($allow_control_char) {
                                   if ($response->[$j] =~ /[\000-\037]/) {
                                       $response->[$j] =~ s/[\000-\037]//g;
                                       $control_chars_removed = 1;
                                   }
                               }
                           }
                           # See if we have preprocessor
                           if (($preprocess=~/\S/) && ($type eq 'cs' || $type eq 'ci')) {
                               if (defined(&$preprocess)) {
                                   no strict 'refs';
                                   $response->[$j]=&$preprocess($response->[$j]);
                                   use strict 'refs';
                               }
                           }
   
    my ($award,$msg) = &caparesponse_check($answer->[$j],
          $response->[$j]);
                           if ($type eq 'cs' || $type eq 'ci') {
                               $error = &verify_stringresponse($type,$award,$response->[$j],
                                                               $answer->[$j]);
                           }
    push(@awards,$award);
    push(@msgs,  $msg);
       }
       ($award,$msg) = 
    &LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs);
    }
    $memoized{$key} = [$award,$msg];
     }      }
  } else {  
     $aresult='ERROR';  
     $msg='answer was undefined';  
  }   }
  &LONCAPA_INTERNAL_DEBUG("after if $aresult -- $msg");  
  my ($temp)=split(/:/, $aresult);  
  $awards.="$temp,";  
  $result.=$aresult;  
  push(@msgs,$msg);  
     }      }
     chop($awards);  
     return ("$awards:\n$result",@msgs);      my ($final_award,$final_msg);
       &init_permutation(scalar(@$responses),
         $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".$responses->[$order->[$i]];
       push(@awards,$memoized{$key}[0]);
       push(@msgs,$memoized{$key}[1]);
       $i++;
   
    }
    &LONCAPA_INTERNAL_DEBUG(" all awards ".join(':',@awards));
   
    my ($possible_award,$possible_msg) = 
       &LONCAPA_INTERNAL_FINALIZEAWARDS(\@awards,\@msgs);
    &LONCAPA_INTERNAL_DEBUG(" pos awards ".$possible_award);
    push(@final_awards,$possible_award);
    push(@final_msg,$possible_msg);
       }
   
       &LONCAPA_INTERNAL_DEBUG(" all final_awards ".join(':',@final_awards));
       my ($final_award,$final_msg) = 
    &LONCAPA_INTERNAL_FINALIZEAWARDS(\@final_awards,\@final_msg,undef,1);
       return ($final_award,$final_msg,$error,$control_chars_removed,$ansstring);
   }
   
   sub verify_stringresponse {
       my ($type,$award,$resp,$ans) = @_;
       return if ($award eq 'EXACT_ANS');
       my $error;
       if ($resp =~ /^\s|\s$/) {
           $resp =~ s{^\s+|\s+$}{}g;
       }
       if ($ans =~ /^\s|\s$/) {
           $ans =~ s{^\s+|\s+$}{}g;
       }
       if ($type eq 'ci') {
           $resp = lc($resp);
           $ans = lc($ans);
       }
       if ($resp eq $ans) {
           if ($award eq 'INCORRECT') {
               $error = 'MISGRADED';
           }
       }
       return $error;
   }
   
   sub cas {
       my ($system,$input,$library)=@_;
       my $output;
       my $dump;
       if ($system eq 'maxima') {
          $output=&maxima_eval($input,$library);
       } elsif ($system eq 'R') {
          ($output,$dump)=&r_eval($input,$library,0);
       } else {
          $output='Error: unrecognized CAS';
       }
       return $output;
   }
   
   sub cas_hashref {
       my ($system,$input,$library)=@_;
       if ($system eq 'maxima') {
          return 'Error: unsupported CAS';
       } elsif ($system eq 'R') {
          return &r_eval($input,$library,1);
       } else {
          return 'Error: unrecognized CAS';
       }
   }
   
   #
   # cas_hashref_entry takes a list of indices and gets the entry in a hash generated by Rreturn.
   # Call: cas_hashref_entry(Rvalue, index1, index2, ...) where Rvalue is a hash returned by Rreturn.
   # Rentry will return the first scalar value it encounters (ignoring excess indices).
   # If an invalid key is given, it returns undef.
   #
   sub cas_hashref_entry {
       return &Rentry(@_);
   }
   
   #
   # cas_hashref_array takes a list of indices and gets a column array from a hash generated by Rreturn.
   # Call: cas_hashref_array(Rvalue, index1, index2, ...) where Rvalue is a hash returned by Rreturn.
   # If an invalid key is given, it returns undef.
   #
   sub cas_hashref_array {
       return &Rarray(@_);
 }  }
   
 sub tex {  sub tex {
Line 461  sub cos { CORE::cos(shift) } Line 816  sub cos { CORE::cos(shift) }
 sub exp { CORE::exp(shift) }  sub exp { CORE::exp(shift) }
 sub int { CORE::int(shift) }  sub int { CORE::int(shift) }
 sub log { CORE::log(shift) }  sub log { CORE::log(shift) }
   sub ln { CORE::log(shift) }
 sub atan2 { CORE::atan2($_[0],$_[1]) }  sub atan2 { CORE::atan2($_[0],$_[1]) }
 sub sqrt { CORE::sqrt(shift) }  sub sqrt { CORE::sqrt(shift) }
   
Line 687  sub format_significant_figures { Line 1043  sub format_significant_figures {
     my ($zeros) = ($xint =~ /(0+)$/);      my ($zeros) = ($xint =~ /(0+)$/);
     # return number to original magnitude      # return number to original magnitude
     my $numSig = $xint*10**($x10-$sig+$power);      my $numSig = $xint*10**($x10-$sig+$power);
     # insert trailing zero's if have decimal point      if ($numSig =~ /^(\d+)\.(\d+)/) {
     $numSig =~ s/^(\d+)\.(\d+)(\e?(.*)?)$/$1\.$2$zeros$3/;          # insert trailing zero's if have decimal point
     # put a decimal pt for number ending with 0 and length = # of sig fig          my @digarray = split('',$1.$2);
     $numSig.='.' if (length($numSig) == $sig && $numSig =~ /0$/);          my $sigcount;
     if (length($numSig) < $sig) {          while (@digarray > 0) {
  $numSig.='.'.substr($zeros,0,($sig-length($numSig)));              my $item = shift(@digarray);
               if ($item) {
                   $sigcount = 1 + @digarray;
                   last;
               }
           }
           if (($sigcount) && ($sig >= $sigcount)) {
               $zeros = substr($zeros,0,($sig - $sigcount));
           }
           $numSig =~ s/^(\d+)\.(\d+)(\e?(.*)?)$/$1\.$2$zeros$3/;
       } else {
           if ($numSig =~ /^(\d+)e([\+\-]\d+)$/i) {
               my $pre_exp = $1;
               my $exponent = $2;
               $numSig = $pre_exp.'.'.$zeros.'E'.$exponent;
           } elsif ($numSig =~ /0$/) {
               # add decimal pt for number ending with 0 and length == # of sig figs
               if (length($numSig) == $sig) {
                   $numSig.='.';
               } elsif (length($numSig) > $sig) {
                   # exponential form for number ending with 0 and length > # of sig figs
                   my $fmtsig = $sig-1;
                   if ($fmtsig) {
                       $numSig = sprintf('%.'.$fmtsig.'E',$numSig);
                   }
               } elsif (length($numSig) < $sig) {
                   $numSig.='.'.substr($zeros,0,($sig-length($numSig)));
               }
           } else {
               if (length($numSig) < $sig) {
                   $numSig.='.'.substr($zeros,0,($sig-length($numSig)));
               }
           }
     }      }
     # return number with sign      # return number with sign
     return $sign.$numSig;      return $sign.$numSig;
   
 }  }
   
 sub map {  sub map {
Line 810  sub class { Line 1197  sub class {
     return $course;      return $course;
 }  }
   
   sub classid {
       my $courseid = &EXT('request.course.id');
       $courseid = '' if $courseid eq "";
       return $courseid;
   }
   
   sub firstname {
       my $firstname = &EXT('environment.firstname');
       $firstname = '' if $firstname eq "";
       return $firstname;
   }
   
   sub middlename {
       my $middlename = &EXT('environment.middlename');
       $middlename = '' if $middlename eq "";
       return $middlename;
   }
   
   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 submission {
     my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate')));     my ($partid,$responseid,$subnumber,$encode,$cleanupnum,$mapalias)=@_;
     return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);     my $sub='';
     my @hm = split(/:/,$dc[3]);     if ($subnumber) { $sub=$subnumber.':'; }
     my $ampm = " am";     my $output =
     if ($hm[0] > 12) {         &EXT('user.resource.'.$sub.'resource.'.$partid.'.'.$responseid.'.submission',$mapalias);
  $hm[0]-=12;     if (ref($output) eq 'ARRAY') {
  $ampm = " pm";         my @items = @{$output};
     }         if ($encode) {
     return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;             @items = map { &encode_response($_); } @items;
 }         }
          if (ref($cleanupnum) eq 'HASH') {
 sub due_date {              @items = map { &cleanup_numerical_response($cleanupnum,$_); } @items;
     my @dc = split(/\s+/,localtime(&EXT('resource.0.duedate')));         }
     return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);         return \@items;
     my @hm = split(/:/,$dc[3]);     } else {
     my $ampm = " am";         if ($encode) {
     if ($hm[0] > 12) {             $output = &encode_response($output);
  $hm[0]-=12;         }
  $ampm = " pm";         if (ref($cleanupnum) eq 'HASH') {
              $output = &cleanup_numerical_response($cleanupnum,$output);
          }
          return $output;
      }
   }
   
   sub encode_response {
       my ($value) = @_;
       $value =~ s/&/&amp;/g;
       $value =~ s/</&lt;/g;
       $value =~ s/>/&gt;/g;
       $value =~ s/"/&quot;/g;
       return $value;
   }
   
   sub cleanup_numerical_response {
       my ($cleanupnum,$value) = @_;
       if (ref($cleanupnum) eq 'HASH') {
           if ($cleanupnum->{exponent}) {
               if ($value =~ m{^(.*)[\*xX]\s*10\s*\^\s*(\+|\-)?\s*(\d+)(.*)$}) {
                   my $pre_exp = $1;
                   my $sign = $2;
                   my $exponent = $3;
                   my $post_exp = $4;
                   if ($pre_exp !~ /\./) {
                       $pre_exp .= '.';
                   }
                   if ($sign eq '') {
                       $sign = '+';
                   }
                   $value = $pre_exp.'E'.$sign.$exponent.$post_exp;
               }
           }
           if ($cleanupnum->{comma}) {
               $value =~ s{(\d+),(\d+)}{$1$2};
           }
           if ($cleanupnum->{letterforzero}) {
               $value =~ s/^\s*o(\.\d+)/0$1/i;
           }
           if ($cleanupnum->{spaces}) {
               $value =~ s{^\s+|\s+$}{}g;
               if ($value =~ m{^(.*)\.\s+(\d+)(.*)$}) {
                   my $pre_pt = $1;
                   my $decimal = $2;
                   my $post_dec = $3;
                   $value = $pre_pt.'.'.$decimal.$post_dec;
               }
           }
           if ($cleanupnum->{format} =~ /^\d+s$/i) {
               $value = &format_significant_figures($value,$cleanupnum->{format});
           }
     }      }
     return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;      return $value;
   }
   
   sub currentpart {
      return $external::part;
   }
   
   sub eval_time {
      my ($timestamp)=@_;
      unless ($timestamp) { return ''; }
      return &locallocaltime($timestamp);
   }
   
   sub open_date { 
       my ($partid)=@_;
       unless ($partid) { $partid=0; }
       return &eval_time(&EXT('resource.'.$partid.'.opendate'));
   }
   
   sub due_date {
       my ($partid)=@_;
       unless ($partid) { $partid=0; } 
       return &eval_time(&EXT('resource.'.$partid.'.duedate'));
 }  }
   
 sub answer_date {   sub answer_date { 
     my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate')));      my ($partid)=@_;
     return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);      unless ($partid) { $partid=0; }
     my @hm = split(/:/,$dc[3]);      return &eval_time(&EXT('resource.'.$partid.'.answerdate'));
     my $ampm = " am";  }
     if ($hm[0] > 12) {  
  $hm[0]-=12;  sub open_date_epoch {
  $ampm = " pm";      my ($partid)=@_;
       unless ($partid) { $partid=0; }
       return &EXT('resource.'.$partid.'.opendate');
   }
   
   sub due_date_epoch {
       my ($partid)=@_;
       unless ($partid) { $partid=0; }
       return &EXT('resource.'.$partid.'.duedate');
   }
   
   sub answer_date_epoch {
       my ($partid)=@_;
       unless ($partid) { $partid=0; }
       return &EXT('resource.'.$partid.'.answerdate');
   }
   
   sub parameter_setting {
       my ($which,$partid)=@_;
       unless ($partid) { $partid=0; }
       return &EXT('resource.'.$partid.'.'.$which);
   }
   
   sub stored_data {
       my ($which,$partid)=@_;
       unless ($partid) { $partid=0; }
       return &EXT('user.resource.resource.'.$partid.'.'.$which);
   }
   
   sub wrong_bubbles {
       my ($correct,$lower,$upper,$step,@given)=@_;
       my @array=();
       my %hash=();
       foreach my $new (@given) {
           $hash{$new}=1;
       }
       my $num=int(&parameter_setting('numbubbles',&currentpart()));
       unless ($num) { $num=8; }
       if ($num>1) {
           for (my $i=0;$i<=500;$i++) {
               my $new=&random($lower,$upper,$step);
               if ($hash{$new}) { next; }
               if (abs($new-$correct)<$step) { next; }
               $hash{$new}=1;
               @array=keys(%hash);
               if ($#array+2>=$num) { last; }
           }
     }      }
     return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;      return @array;
 }  }
   
 sub array_moments {  sub array_moments {

Removed from v.1.105  
changed lines
  Added in v.1.170


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.