Diff for /loncom/homework/caparesponse/caparesponse.pm between versions 1.108 and 1.183

version 1.108, 2003/08/21 17:33:22 version 1.183, 2005/12/01 22:30:55
Line 29 Line 29
 package Apache::caparesponse;  package Apache::caparesponse;
 use strict;  use strict;
 use capa;  use capa;
   use Apache::lonlocal;
   use Apache::lonnet;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::caparesponse',('caparesponse','numericalresponse','stringresponse','formularesponse'));      &Apache::lonxml::register('Apache::caparesponse',('caparesponse','numericalresponse','stringresponse','formularesponse'));
 }  }
   
   my %answer;
   my $cur_name;
   sub start_answer {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       $cur_name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
       if ($cur_name =~ /^\s*$/) { $cur_name = $Apache::lonxml::curdepth; }
       my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
       if (!defined($type) && $tagstack->[-2] eq 'answergroup') {
    $type = &Apache::lonxml::get_param('type',$parstack,$safeeval,-2);
       }
       if (!defined($type)) { $type = 'ordered' };
       $answer{$cur_name}= { 'type' => $type,
     'answers' => [] };
       return $result;
   }
   
   sub end_answer {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       undef($cur_name);
       return $result;
   }
   
   sub start_answergroup {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       my $id = $Apache::inputtags::response[-1];
       my $dis = &Apache::lonxml::get_param('answerdisplay',$parstack,$safeeval);
       if (defined($dis)) { $Apache::inputtags::answertxt{$id}=$dis; }
       return $result;
   }
   
   sub end_answergroup {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       return $result;
   }
   
   sub start_value {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
       my $result;
       if ( $target eq 'web' || $target eq 'tex' ||
    $target eq 'grade' || $target eq 'webgrade' ||
    $target eq 'answer' || $target eq 'analyze' ) {
    my $bodytext = &Apache::lonxml::get_all_text("/value",$parser,$style);
    $bodytext = &Apache::run::evaluate($bodytext,$safeeval,
      $$parstack[-1]);
    push(@{ $answer{$cur_name}{'answers'} },$bodytext);
       }
       return $result;
   }
   
   sub end_value {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       return $result;
   }
   
   sub start_array {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
       my $result;
       if ( $target eq 'web' || $target eq 'tex' ||
    $target eq 'grade' || $target eq 'webgrade' ||
    $target eq 'answer' || $target eq 'analyze' ) {
    my $bodytext = &Apache::lonxml::get_all_text("/array",$parser,$style);
    my @values = &Apache::run::evaluate($bodytext,$safeeval,
       $$parstack[-1]);
    push(@{ $answer{$cur_name}{'answers'} },@values);
       }
       return $result;
   }
   
   sub end_array {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       return $result;
   }
   
   sub start_unit {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       return $result;
   }
   
   sub end_unit {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       return $result;
   }
   
 sub start_numericalresponse {  sub start_numericalresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       &Apache::lonxml::register('Apache::caparesponse',('answer','answergroup','value','array','unit'));
     my $id = &Apache::response::start_response($parstack,$safeeval);      my $id = &Apache::response::start_response($parstack,$safeeval);
     my $result;      my $result;
       undef(%answer);
       undef(%{$safeeval->varglob('LONCAPA::CAPAresponse_args')});
     if ($target eq 'edit') {      if ($target eq 'edit') {
  $result.=&Apache::edit::tag_start($target,$token);   $result.=&Apache::edit::tag_start($target,$token);
  $result.=&Apache::edit::text_arg('Answer:','answer',$token);   $result.=&Apache::edit::text_arg('Answer:','answer',$token);
  if ($token->[1] eq 'numericalresponse') {   if ($token->[1] eq 'numericalresponse') {
       $result.=&Apache::edit::text_arg('Incorrect Answers:','incorrect',
        $token).
    &Apache::loncommon::help_open_topic('numerical_wrong_answers');
     $result.=&Apache::edit::text_arg('Unit:','unit',$token,5).      $result.=&Apache::edit::text_arg('Unit:','unit',$token,5).
  &Apache::loncommon::help_open_topic('Physical_Units');   &Apache::loncommon::help_open_topic('Physical_Units');
     $result.=&Apache::edit::text_arg('Format:','format',$token,4).      $result.=&Apache::edit::text_arg('Format:','format',$token,4).
  &Apache::loncommon::help_open_topic('Numerical_Response_Format');   &Apache::loncommon::help_open_topic('Numerical_Response_Format');
  } elsif ($token->[1] eq 'stringresponse') {  
     $result.=&Apache::edit::select_arg('Type:','type',  
  [['cs','Case Sensitive'],['ci','Case Insensitive'],  
   ['mc','Case Insensitive, Any Order']],$token);  
  } elsif ($token->[1] eq 'formularesponse') {   } elsif ($token->[1] eq 'formularesponse') {
     $result.=&Apache::edit::text_arg('Sample Points:','samples',      $result.=&Apache::edit::text_arg('Sample Points:','samples',
      $token,40).       $token,40).
Line 61  sub start_numericalresponse { Line 156  sub start_numericalresponse {
  if ($token->[1] eq 'numericalresponse') {   if ($token->[1] eq 'numericalresponse') {
     $constructtag=&Apache::edit::get_new_args($token,$parstack,      $constructtag=&Apache::edit::get_new_args($token,$parstack,
       $safeeval,'answer',        $safeeval,'answer',
       'unit','format');         'incorrect','unit',
  } elsif ($token->[1] eq 'stringresponse') {        'format');
     $constructtag=&Apache::edit::get_new_args($token,$parstack,  
       $safeeval,'answer',  
       'type');  
  } elsif ($token->[1] eq 'formularesponse') {   } elsif ($token->[1] eq 'formularesponse') {
     $constructtag=&Apache::edit::get_new_args($token,$parstack,      $constructtag=&Apache::edit::get_new_args($token,$parstack,
       $safeeval,'answer',        $safeeval,'answer',
Line 89  sub start_numericalresponse { Line 181  sub start_numericalresponse {
     $safeeval);      $safeeval);
     if ($unit =~ /\S/) { $result.=" (in $unit) "; }      if ($unit =~ /\S/) { $result.=" (in $unit) "; }
  }   }
    if (  &Apache::response::show_answer() ) {
       my $answertxt;
       my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,
    $safeeval);
       my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,
    $safeeval);
       my $unit=&Apache::lonxml::get_param_var('unit',$parstack,
       $safeeval);
       for (my $i=0; $i <= $#answers; $i++) {
    my $answer=$answers[$i];
    my $format;
    if ($#formats > 0) {
       $format=$formats[$i];
    } else {
       $format=$formats[0];
    }
    if ($unit=~/\$/) { $format="\$".$format; $unit=~s/\$//g; }
    if ($unit=~/\,/) { $format="\,".$format; $unit=~s/\,//g; }
    my $formatted=&format_number($answer,$format,$target,
        $safeeval);
    $answertxt.=$formatted.',';
       }
       chop $answertxt;
       if ($target eq 'web') {
    $answertxt.=" $unit ";
       }
       $Apache::inputtags::answertxt{$id}=$answertxt;
    }
     }      }
     return $result;      return $result;
 }  }
   
   sub check_submission {
       my ($response,$partid,$id,$tag,$parstack,$safeeval,$ignore_sig)=@_;
       my $args_ref= \%{$safeeval->varglob('LONCAPA::CAPAresponse_args')};
       $$args_ref{'response'}=$response;
       my $hideunit=&Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.turnoffunit');
       
       foreach my $arg ('type','tol','sig','format','unit','calc',
        'samples') {
    $$args_ref{$arg}=
       &Apache::lonxml::get_param($arg,$parstack,$safeeval);
       }
       foreach my $key (keys(%Apache::inputtags::params)) {
    $$args_ref{$key}=$Apache::inputtags::params{$key};
       }
       
       #no way to enter units, with radio buttons
       if ($Apache::lonhomework::type eq 'exam' ||
    lc($hideunit) eq "yes") {
    delete($$args_ref{'unit'});
       }
       #sig fig don't make much sense either
       if (($Apache::lonhomework::type eq 'exam' ||
    &Apache::response::submitted('scantron') ||
    $ignore_sig) &&
    $tag eq 'numericalresponse') {
    delete($$args_ref{'sig'});
       }
       
       if ($tag eq 'formularesponse') {
    $$args_ref{'type'}='fml';
       } elsif ($tag eq 'numericalresponse') {
    $$args_ref{'type'}='float';
       }
       my @answer=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
       &Apache::lonxml::debug('answer is'.join(':',@answer));
       if (@answer && defined($answer[0])) {
    $answer{'INTERNAL'}= {'type' => 'ordered',
         'answers' => \@answer };
       }
       #FIXME would be nice if we could save name so we know who graded him
       #correct
       my (%results,@final_awards,@final_msgs,@names);
       foreach my $name (keys(%answer)) {
    &Apache::lonxml::debug(" doing $name with ".join(':',@{ $answer{$name}{'answers'} }));
    @{$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=@{ $answer{$name}{'answers'} };
    my ($result,@msgs) = 
       &Apache::run::run("&caparesponse_check_list()",$safeeval);
    &Apache::lonxml::debug('msgs are '.join(':',@msgs));
    my ($awards)=split(/:/,$result);
    my @awards= split(/,/,$awards);
    my ($ad, $msg) = &Apache::inputtags::finalizeawards(\@awards,\@msgs);
    $results{$name}= [$ad,$msg];
    push(@final_awards,$ad);
    push(@final_msgs,$msg);
    push(@names,$name);
       }
       my ($ad, $msg, $name) = &Apache::inputtags::finalizeawards(\@final_awards,
          \@final_msgs,
          \@names,1);
       return($ad,$msg);
   }
   
 sub end_numericalresponse {  sub end_numericalresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $increment=1;      my $increment=1;
Line 100  sub end_numericalresponse { Line 282  sub end_numericalresponse {
     if (!$Apache::lonxml::default_homework_loaded) {      if (!$Apache::lonxml::default_homework_loaded) {
  &Apache::lonxml::default_homework_load($safeeval);   &Apache::lonxml::default_homework_load($safeeval);
     }      }
     if ( $target eq 'grade' && defined($ENV{'form.submitted'})) {      my $partid = $Apache::inputtags::part;
  &Apache::response::setup_params($$tagstack[-1]);      my $id = $Apache::inputtags::response[-1];
  $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);      my $tag;
  my $partid = $Apache::inputtags::part;      $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
  my $id = $Apache::inputtags::response['-1'];      if (scalar(@$tagstack)) { $tag=$$tagstack[-1]; }
       if ( $target eq 'grade' && &Apache::response::submitted() ) {
    &Apache::response::setup_params($tag,$safeeval);
  if ($Apache::lonhomework::type eq 'exam' &&    if ($Apache::lonhomework::type eq 'exam' && 
     ($$tagstack[-1] eq 'formularesponse' ||      $tag eq 'formularesponse') {
      $$tagstack[-1] eq 'stringresponse')) {  
     $increment=&Apache::response::scored_response($partid,$id);      $increment=&Apache::response::scored_response($partid,$id);
  } else {   } else {
     my $response = &Apache::response::getresponse();      my $response = &Apache::response::getresponse();
     if ( $response =~ /[^\s]/) {      if ( $response =~ /[^\s]/) {
  my $ad;  
  my %previous = &Apache::response::check_for_previous($response,$partid,$id);   my %previous = &Apache::response::check_for_previous($response,$partid,$id);
  $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;  
  &Apache::lonxml::debug("submitted a $response<br>\n");   &Apache::lonxml::debug("submitted a $response<br>\n");
  &Apache::lonxml::debug($$parstack[-1] . "\n<br>");   &Apache::lonxml::debug($$parstack[-1] . "\n<br>");
   
  if ($ENV{'form.submitted'} eq 'scantron') {   if ( &Apache::response::submitted('scantron')) {
     my $number_of_bubbles = 8;#default values for number of bubbles      my $number_of_bubbles = &Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.numbubbles');
     my (@formats)=&Apache::lonxml::get_param_var('format',      if (!$number_of_bubbles) { $number_of_bubbles=8; }
  $parstack,$safeeval);      my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,$safeeval);
     my (@answers)=&Apache::lonxml::get_param_var('answer',      my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
  $parstack,$safeeval);      my (@incorrect)=&Apache::lonxml::get_param_var('incorrect',$parstack,$safeeval);
     my @values=&make_numerical_bubbles($number_of_bubbles,$target,      if ($#incorrect eq 0) { @incorrect=(split(/,/,$incorrect[0])); }
        $answers[0],$formats[0]);      my ($values,$display)=&make_numerical_bubbles($number_of_bubbles,$target,$answers[0],$formats[0],\@incorrect,$safeeval);
     $response=$values[$response];      $response=$values->[$response];
  } else {   }
     $response =~ s/\\/\\\\/g;   $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
     $response =~ s/\'/\\\'/g;   my ($ad,$msg)=&check_submission($response,$partid,$id,
    $tag,$parstack,$safeeval);
   
    &Apache::lonxml::debug('ad is'.$ad);
    if ($ad eq 'SIG_FAIL') {
       my ($sig_u,$sig_l)=
    &get_sigrange($Apache::inputtags::params{'sig'});
       $msg=join(':',$msg,$sig_l,$sig_u);
       &Apache::lonxml::debug("sigs bad $sig_u $sig_l ".
      $Apache::inputtags::params{'sig'});
  }   }
  &Apache::lonxml::debug("current $response");  
  my $expression="&caparesponse_check_list('".$response."','".  
     $$parstack[-1];  
  my $hideunit=&Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.turnoffunit');  
  #no way to enter units, with radio buttons  
  if ($Apache::lonhomework::type eq 'exam' ||  
     lc($hideunit) eq "yes") {  
     $expression.=';my $unit=undef;';  
  }  
  foreach my $key (keys(%Apache::inputtags::params)) {  
     $expression.= ';my $'. #'  
  $key.'="'.$Apache::inputtags::params{$key}.'"';  
  }  
  if ($$tagstack[-1] eq 'formularesponse') {  
     $expression.=';my $type="fml";';  
  } elsif ($$tagstack[-1] eq 'numericalresponse') {  
     $expression.=';my $type="float";';  
  }  
  $expression.="');";  
  my @answer=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);  
  &Apache::lonxml::debug('answer is'.join(':',@answer));  
  @{$safeeval->varglob('CAPARESPONSE_CHECK_LIST_answer')}=@answer;  
   
  $result = &Apache::run::run($expression,$safeeval);  
  my ($awards) = split /:/ , $result;  
  ($ad) = &Apache::inputtags::finalizeawards(split /,/ , $awards);  
  &Apache::lonxml::debug("$expression");  
  &Apache::lonxml::debug("\n<br>result:$result:$Apache::lonxml::curdepth<br>\n");   &Apache::lonxml::debug("\n<br>result:$result:$Apache::lonxml::curdepth<br>\n");
    if ($Apache::lonhomework::type eq 'survey' &&
       ($ad eq 'INCORRECT' || $ad eq 'APPROX_ANS' ||
        $ad eq 'EXACT_ANS')) {
       $ad='SUBMITTED';
    }
  &Apache::response::handle_previous(\%previous,$ad);   &Apache::response::handle_previous(\%previous,$ad);
  $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;   $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;
    $Apache::lonhomework::results{"resource.$partid.$id.awardmsg"}=$msg;
  $result='';   $result='';
     }      }
  }   }
Line 169  sub end_numericalresponse { Line 338  sub end_numericalresponse {
      $safeeval);       $safeeval);
  my $award = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"};   my $award = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"};
  my $status = $Apache::inputtags::status['-1'];   my $status = $Apache::inputtags::status['-1'];
  if (   ($award =~ /^correct/  
                 && lc($Apache::lonhomework::problemstatus) ne 'no')  
              || $status eq "SHOW_ANSWER"  
              || $ENV{'form.texaward'} eq 'SHOW_ANSWER') {  
     my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,  
  $safeeval);  
     my $unit=&Apache::lonxml::get_param_var('unit',$parstack,  
     $safeeval);  
     if ($target eq 'web') {  
  $result="<br />The correct answer is ";  
     } elsif ($target eq 'tex') {  
  if ($ENV{'form.texaward'} eq 'SHOW_ANSWER') {  
     $result='\vskip 0 mm The correct answer is \\texttt{ ';  
  }  
     }  
     for (my $i=0; $i <= $#answers; $i++) {  
  my $answer=$answers[$i];  
  my $format;  
  if ($#formats > 0) {  
     $format=$formats[$i];  
  } else {  
     $format=$formats[0];  
  }  
  my $formatted;  
  if ((defined($format)) && ($format ne '')) {  
     &Apache::lonxml::debug("formatting with :$format: answer :$answer:");  
     $formatted=sprintf('%.'.$format,$answer).',';  
  } else {  
     &Apache::lonxml::debug("no format answer :$answer:");  
     $formatted="$answer,";  
  }  
  if ($ENV{'form.texaward'} eq 'SHOW_ANSWER') {  
     $result.=$formatted;  
  }  
  if ($target eq 'tex') {  
     $formatted='';  
     #$formatted=&Apache::lonxml::latex_special_symbols($formatted);  
  }  
  $result.=$formatted;  
     }  
     chop $result;  
     if ($target eq 'web') {  
  $result.=" $unit.<br />";  
     } elsif ($target eq 'tex') {  
  if ($ENV{'form.texaward'} eq 'SHOW_ANSWER') {  
     $result.=&Apache::lonxml::latex_special_symbols($unit);  
     $result.="}. \\vskip 0 mm ";  
  }  
     }  
  }  
  if ($Apache::lonhomework::type eq 'exam') {   if ($Apache::lonhomework::type eq 'exam') {
     my $number_of_bubbles = 8; #default values for number of bubbles      my $number_of_bubbles = &Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.numbubbles');
       if ($Apache::inputtags::params{'numbubbles'}) {
    $number_of_bubbles = $Apache::inputtags::params{'numbubbles'};
       }
       if (!$number_of_bubbles) { $number_of_bubbles=8; }
       
     my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,      my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,
  $safeeval);   $safeeval);
     my $unit=&Apache::lonxml::get_param_var('unit',$parstack,      my $unit=&Apache::lonxml::get_param_var('unit',$parstack,
     $safeeval);      $safeeval);
     my @bubble_values=&make_numerical_bubbles($number_of_bubbles,      my (@incorrect)=&Apache::lonxml::get_param_var('incorrect',$parstack,$safeeval);
       $target,$answers[0],      if ($#incorrect eq 0) { @incorrect=(split(/,/,$incorrect[0])); }
       $formats[0]);      my ($bubble_values,$bubble_display)=
    &make_numerical_bubbles($number_of_bubbles,
    $target,$answers[0],
    $formats[0],\@incorrect,$safeeval);
     my @alphabet=('A'..'Z');      my @alphabet=('A'..'Z');
     my $id=$Apache::inputtags::response[-1];  
     if ($target eq 'web') {      if ($target eq 'web') {
  if ($$tagstack[-1] eq 'numericalresponse') {   if ($tag eq 'numericalresponse') {
     if ($unit=~/\S/) {$result.=' (in '.$unit.')<br /><br />';}      if ($unit=~/\S/) {$result.=' (in '.$unit.')<br /><br />';}
     $result.= '<table border="1"><tr>';      $result.= '<table border="1"><tr>';
       my $previous=$Apache::lonhomework::history{"resource.$Apache::inputtags::part.$id.submission"};
     for (my $ind=0;$ind<$number_of_bubbles;$ind++) {      for (my $ind=0;$ind<$number_of_bubbles;$ind++) {
    my $checked='';
    if ($previous eq $bubble_values->[$ind]) {
       $checked=" checked='on' ";
    }
  $result.='<td><input type="radio" name="HWVAL_'.$id.   $result.='<td><input type="radio" name="HWVAL_'.$id.
     '" value="'.$bubble_values[$ind].'"><b>'.      '" value="'.$bubble_values->[$ind].'" '.$checked
  $alphabet[$ind].'</b>: '.      .' /><b>'.$alphabet[$ind].'</b>: '.
     $bubble_values[$ind].'</td>';      $bubble_display->[$ind].'</td>';
     }      }
     $result.='</tr></table>';      $result.='</tr></table>';
  } elsif ($$tagstack[-1] eq 'formularesponse') {   } elsif ($tag eq 'formularesponse') {
     $result.= '<br /><br /><font color="red">      $result.= '<br /><br /><font color="red">
                            <textarea name="HWVAL_'.$id.'" rows="4" cols="50">                             <textarea name="HWVAL_'.$id.'" rows="4" cols="50">
                            </textarea></font> <br /><br />';                             </textarea></font> <br /><br />';
Line 250  sub end_numericalresponse { Line 381  sub end_numericalresponse {
  if ((defined $unit) and ($unit=~/\S/) and ($Apache::lonhomework::type eq 'exam')) {   if ((defined $unit) and ($unit=~/\S/) and ($Apache::lonhomework::type eq 'exam')) {
     $result.=' \textit{(in} \verb|'.$unit.'|\textit{)} ';      $result.=' \textit{(in} \verb|'.$unit.'|\textit{)} ';
  }   }
  if ($$tagstack[-1] eq 'numericalresponse') {   if ($tag eq 'numericalresponse') {
     my ($celllength,$number_of_tables,@table_range)=      my ($celllength,$number_of_tables,@table_range)=
  &get_table_sizes($formats[0],$number_of_bubbles);   &get_table_sizes($number_of_bubbles,$bubble_display);
     my $j=0;      my $j=0;
     my $cou=0;      my $cou=0;
     $result.='\vskip -1 mm \noindent \begin{enumerate}\item[\textbf{'.$Apache::lonxml::counter.'}.]';      $result.='\vskip -1 mm \noindent \begin{enumerate}\item[\textbf{'.$Apache::lonxml::counter.'}.]';
     for (my $i=0;$i<$number_of_tables;$i++) {      for (my $i=0;$i<$number_of_tables;$i++) {
  $result.='\vskip -1 mm \noindent \begin{tabular}{';   $result.='\vskip -1 mm \noindent \setlength{\tabcolsep}{2 mm}\begin{tabular}{';
  for (my $ind=0;$ind<$table_range[$j];$ind++) {   for (my $ind=0;$ind<$table_range[$j];$ind++) {
     $result.='lp{'.$celllength.' mm}';      $result.='p{3 mm}p{'.$celllength.' mm}';
  }   }
  $result.='}';   $result.='}';
  for (my $ind=$cou;$ind<$cou+$table_range[$j];$ind++) {   for (my $ind=$cou;$ind<$cou+$table_range[$j];$ind++) {
     $result.='\hskip -3 mm {\small \textbf{'.$alphabet[$ind].'}}$\bigcirc$\hskip -2 mm & {\small '.$bubble_values[$ind].'} ';      $result.='\hskip -4 mm {\small \textbf{'.$alphabet[$ind].'}}$\bigcirc$ & \hskip -3 mm {\small '.$bubble_display->[$ind].'} ';
     if ($ind != $cou+$table_range[$j]-1) {$result.=' & ';}      if ($ind != $cou+$table_range[$j]-1) {$result.=' & ';}
  }   }
  $cou += $table_range[$j];   $cou += $table_range[$j];
Line 286  sub end_numericalresponse { Line 417  sub end_numericalresponse {
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result.='</td></tr>'.&Apache::edit::end_table;   $result.='</td></tr>'.&Apache::edit::end_table;
     } elsif ($target eq 'answer' || $target eq 'analyze') {      } elsif ($target eq 'answer' || $target eq 'analyze') {
    my $part_id="$partid.$id";
  my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]";  
  if ($target eq 'analyze') {   if ($target eq 'analyze') {
     push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);      push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
     $Apache::lonhomework::analyze{"$part_id.type"} = $$tagstack[-1];      $Apache::lonhomework::analyze{"$part_id.type"} = $tag;
       my (@incorrect)=&Apache::lonxml::get_param_var('incorrect',$parstack,$safeeval);
       if ($#incorrect eq 0) { @incorrect=(split(/,/,$incorrect[0])); }
       push (@{ $Apache::lonhomework::analyze{"$part_id.incorrect"} }, @incorrect);
       &Apache::response::check_if_computed($token,$parstack,
    $safeeval,'answer');
    }
    if (scalar(@$tagstack)) {
       &Apache::response::setup_params($tag,$safeeval);
  }   }
  &Apache::response::setup_params($$tagstack[-1]);  
  my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);   my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
  my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,$safeeval);   my (@formats)=&Apache::lonxml::get_param_var('format',$parstack,$safeeval);
  my $unit=&Apache::lonxml::get_param_var('unit',$parstack,$safeeval);   my $unit=&Apache::lonxml::get_param_var('unit',$parstack,$safeeval);
  my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval);
   
  if ($target eq 'answer') {   if ($target eq 'answer') {
     $result.=&Apache::response::answer_header($$tagstack[-1]);      $result.=&Apache::response::answer_header($tag);
  }   }
    my ($sigline,$tolline);
  for(my $i=0;$i<=$#answers;$i++) {   for(my $i=0;$i<=$#answers;$i++) {
     my $ans=$answers[$i];      my $ans=$answers[$i];
     my $fmt=$formats[0];      my $fmt=$formats[0];
Line 313  sub end_numericalresponse { Line 451  sub end_numericalresponse {
     if ($Apache::inputtags::params{'sig'}) {      if ($Apache::inputtags::params{'sig'}) {
  ($sighigh,$siglow)=&get_sigrange($Apache::inputtags::params{'sig'});   ($sighigh,$siglow)=&get_sigrange($Apache::inputtags::params{'sig'});
     }      }
     if ($fmt && $$tagstack[-1] eq 'numericalresponse') {      if ($fmt && $tag eq 'numericalresponse') {
  $ans = sprintf('%.'.$fmt,$ans);   $fmt=~s/e/E/g;
  if ($high) {   if ($unit=~/\$/) { $fmt="\$".$fmt; $unit=~s/\$//g; }
     $high=sprintf('%.'.$fmt,$high);   if ($unit=~/\,/) { $fmt="\,".$fmt; $unit=~s/\,//g; }
     $low =sprintf('%.'.$fmt,$low);   $ans = &format_number($ans,$fmt,$target,$safeeval);
  }   #if ($high) {
    #    $high=&format_number($high,$fmt,$target,$safeeval);
    #    $low =&format_number($low,$fmt,$target,$safeeval);
    #}
     }      }
     if ($target eq 'answer') {      if ($target eq 'answer') {
  if ($high && $$tagstack[-1] eq 'numericalresponse') { $ans.=' ['.$low.','.$high.']'; }   if ($high && $tag eq 'numericalresponse') {
  if ($sighigh && $$tagstack[-1] eq 'numericalresponse') {      $ans.=' ['.$low.','.$high.']';
     if ($ENV{'form.answer_output_mode'} eq 'tex') {      $tolline .= "[$low, $high]";
    }
    if (defined($sighigh) && $tag eq 'numericalresponse') {
       if ($env{'form.answer_output_mode'} eq 'tex') {
  $ans.= " Sig $siglow - $sighigh";   $ans.= " Sig $siglow - $sighigh";
     } else {      } else {
  $ans.= " Sig <i>$siglow - $sighigh</i>";   $ans.= " Sig <i>$siglow - $sighigh</i>";
    $sigline .= "[$siglow, $sighigh]";
     }      }
  }   }
  $result.=&Apache::response::answer_part($$tagstack[-1],$ans);   $result.=&Apache::response::answer_part($tag,$ans);
     } elsif ($target eq 'analyze') {      } elsif ($target eq 'analyze') {
  push (@{ $Apache::lonhomework::analyze{"$part_id.answer"} }, $ans);   push (@{ $Apache::lonhomework::analyze{"$part_id.answer"} }, $ans);
  if ($high) {   if ($high) {
     push (@{ $Apache::lonhomework::analyze{"$part_id.ans_high"} }, $high);      push (@{ $Apache::lonhomework::analyze{"$part_id.ans_high"} }, $high);
     push (@{ $Apache::lonhomework::analyze{"$part_id.ans_low"} }, $low);      push (@{ $Apache::lonhomework::analyze{"$part_id.ans_low"} }, $low);
  }   }
    if ($fmt) {
       push (@{ $Apache::lonhomework::analyze{"$part_id.format"} }, $fmt);
    }
     }      }
  }   }
  if (defined($unit) and ($unit ne '') and  
     $$tagstack[-1] eq 'numericalresponse') {   my @fmt_ans;
     if ($target eq 'answer') {   for(my $i=0;$i<=$#answers;$i++) {
  if ($ENV{'form.answer_output_mode'} eq 'tex') {      my $ans=$answers[$i];
     $result.=&Apache::response::answer_part($$tagstack[-1],      my $fmt=$formats[0];
     " Unit: $unit ");      if (@formats && $#formats) {$fmt=$formats[$i];}
       if ($fmt && $tag eq 'numericalresponse') {
    $fmt=~s/e/E/g;
    if ($unit=~/\$/) { $fmt="\$".$fmt; $unit=~s/\$//g; }
    if ($unit=~/\,/) { $fmt="\,".$fmt; $unit=~s/\,//g; }
    $ans = &format_number($ans,$fmt,$target,$safeeval);
    if ($fmt=~/\$/ && $unit!~/\$/) { $ans=~s/\$//; }
       }
       push(@fmt_ans,$ans);
    }
    my $response=join(', ',@fmt_ans);
    my $hideunit=&Apache::lonnet::EXT('resource.'.$partid.'_'.
     $id.'.turnoffunit');
    if ($unit ne ''  && 
       ! ($Apache::lonhomework::type eq 'exam' ||
          lc($hideunit) eq "yes") )  {
       my $cleanunit=$unit;
       $cleanunit=~s/\$\,//g;
       $response.=" $cleanunit";
    }
   
    my ($ad,$msg)=&check_submission($response,$partid,$id,$tag,
    $parstack,$safeeval);
    if ($ad ne 'EXACT_ANS' && $ad ne 'APPROX_ANS') {
       my $error;
       if ($tag eq 'formularesponse') {
    $error=&mt('Computer\'s answer is incorrect ("[_1]").',$response);
       } else {
    # answer failed check if it is sig figs that is failing
    my ($ad,$msg)=&check_submission($response,$partid,$id,
    $tag,$parstack,
    $safeeval,1);
    if ($sigline ne '') {
       $error=&mt('Computer\'s answer is incorrect ("[_1]"). It is likely that the tolerance range [_2] or significant figures [_3] need to be adjusted.',$response,$tolline,$sigline);
  } else {   } else {
     $result.=&Apache::response::answer_part($$tagstack[-1],      $error=&mt('Computer\'s answer is incorrect ("[_1]"). It is likely that the tolerance range [_2] needs to be adjusted.',$response,$tolline);
     "Unit: <b>$unit</b>");  
  }   }
     } elsif ($target eq 'analyze') {  
  push (@{ $Apache::lonhomework::analyze{"$part_id.unit"} }, $unit);  
     }      }
  }      if ($ad ne 'EXACT_ANS' && $ad ne 'APPROX_ANS') {
  if ($type || $$tagstack[-1] eq 'stringresponse') {   &Apache::lonxml::error($error);
     my $string='Case Insensitive';      } else {
     if ($type eq 'mc') {   &Apache::lonxml::warning($error);
  $string='Multiple Choice';  
     } elsif ($type eq 'cs') {  
  $string='Case Sensitive';  
     } elsif ($type eq 'ci') {  
  $string='Case Insensitive';  
     } elsif ($type eq 'fml') {  
  $string='Formula';  
     }      }
    }
   
    if (defined($unit) and ($unit ne '') and
       $tag eq 'numericalresponse') {
     if ($target eq 'answer') {      if ($target eq 'answer') {
  if ($ENV{'form.answer_output_mode'} eq 'tex') {   if ($env{'form.answer_output_mode'} eq 'tex') {
     $result.=&Apache::response::answer_part($$tagstack[-1],      $result.=&Apache::response::answer_part($tag,
   "$string");      " Unit: $unit ");
  } else {   } else {
     $result.=&Apache::response::answer_part($$tagstack[-1],      $result.=&Apache::response::answer_part($tag,
     "<b>$string</b>");      "Unit: <b>$unit</b>");
  }   }
     } elsif ($target eq 'analyze') {      } elsif ($target eq 'analyze') {
  push (@{ $Apache::lonhomework::analyze{"$part_id.str_type"} },   push (@{ $Apache::lonhomework::analyze{"$part_id.unit"} }, $unit);
       $type);  
     }      }
  }   }
  if ($$tagstack[-1] eq 'formularesponse' && $target eq 'answer') {   if ($tag eq 'formularesponse' && $target eq 'answer') {
     my $samples=&Apache::lonxml::get_param('samples',$parstack,$safeeval);      my $samples=&Apache::lonxml::get_param('samples',$parstack,$safeeval);
     $result.=&Apache::response::answer_part($$tagstack[-1],$samples);      $result.=&Apache::response::answer_part($tag,$samples);
  }   }
  if ($target eq 'answer') {   if ($target eq 'answer') {
     $result.=&Apache::response::answer_footer($$tagstack[-1]);      $result.=&Apache::response::answer_footer($tag);
  }   }
     }      }
     if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||      if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || 
  $target eq 'tex' || $target eq 'analyze') {   $target eq 'tex' || $target eq 'analyze') {
  &Apache::lonxml::increment_counter($increment);   &Apache::lonxml::increment_counter($increment);
     }      }
Line 393  sub end_numericalresponse { Line 567  sub end_numericalresponse {
 }  }
   
 sub get_table_sizes {  sub get_table_sizes {
     my ($format,$number_of_bubbles)=@_;      my ($number_of_bubbles,$rbubble_values)=@_;
     my $max_val = 0;      my $scale=2; #mm for one digit
     if ($format=~m/^(\d+)E([^\d]*)(\d*)$/) {      my $cell_width=0;
  $max_val=$1+$2+4;      foreach my $member (@$rbubble_values) {
    my $cell_width_real=0;
    if ($member=~/(\+|-)?(\d*)\.?(\d*)\s*\$?\\times\s*10\^{(\+|-)?(\d+)}\$?/) {
       $cell_width_real=(length($2)+length($3)+length($5)+7)*$scale;
    } elsif ($member=~/(\d*)\.?(\d*)(E|e)(\+|-)?(\d*)/) {
       $cell_width_real=(length($1)+length($2)+length($5)+9)*$scale;
           } elsif ($member=~/(\d*)\.(\d*)/) {
       $cell_width_real=(length($1)+length($2)+3)*$scale;
    } else {
       $cell_width_real=(length($member)+1)*$scale*0.9;
    }
    if ($cell_width_real>$cell_width) {$cell_width=$cell_width_real;}
       }
       $cell_width+=8; 
       my $textwidth;
       if ($env{'form.textwidth'} ne '') {
    $env{'form.textwidth'}=~/(\d*)\.?(\d*)/;
    $textwidth=$1.'.'.$2;
     } else {      } else {
  $max_val=4;   $env{'form.textwidth'}=~/(\d+)\.?(\d*)/;
    $textwidth=$1.'.'.$2;
     }      }
     $max_val = int(0.9*$ENV{'form.textwidth'}/(($max_val+6)*2));      my $bubbles_per_line=int($textwidth/$cell_width);
     my $celllength = 0.9*$ENV{'form.textwidth'}/$max_val-10;      if ($bubbles_per_line > $number_of_bubbles) {
    $bubbles_per_line=$number_of_bubbles;
       }elsif (($bubbles_per_line > $number_of_bubbles/2) && ($number_of_bubbles % 2==0)) {$bubbles_per_line=$number_of_bubbles/2;}
       my $number_of_tables = int($number_of_bubbles/$bubbles_per_line);
     my @table_range = ();      my @table_range = ();
     my $number_of_tables = int($number_of_bubbles/$max_val);      for (my $i=0;$i<$number_of_tables;$i++) {push @table_range,$bubbles_per_line;}
     for (my $i=0;$i<$number_of_tables;$i++) {push @table_range,$max_val;}      if ($number_of_bubbles % $bubbles_per_line) {
     if ($number_of_bubbles % $max_val != 0) {  
  $number_of_tables++;   $number_of_tables++;
  push @table_range,($number_of_bubbles % $max_val);   push @table_range,($number_of_bubbles % $bubbles_per_line);
     }      }
     return ($celllength,$number_of_tables,@table_range);      $cell_width-=8;
       $cell_width=$cell_width*3/4;
       return ($cell_width,$number_of_tables,@table_range);
 }  }
   
 sub format_number {  sub format_number {
     my ($number,$format,$target)=@_;      my ($number,$format,$target,$safeeval)=@_;
     my $ans;      my $ans;
     if ($format ne '') {      if ($format eq '') {
  $ans = sprintf('%.'.$format,$number);  
     } else {  
  my $format = '';  
  #What is the number? (integer,decimal,floating point)   #What is the number? (integer,decimal,floating point)
  if ($number=~/^(\d*\.?\d*)(E|e)(\d*)$/) {   if ($number=~/^(\d*\.?\d*)(E|e)(\d*)$/) {
     $format = 'e'.$2;      $format = '3e';
  } elsif ($number=~/^(\d*)\.(\d*)$/) {   } elsif ($number=~/^(\d*)\.(\d*)$/) {
     $format = '4f';      $format = '4f';
  } elsif ($number=~/^(\d*)$/) {   } elsif ($number=~/^(\d*)$/) {
     $format = 'd';      $format = 'd';
  }   }
  $ans = sprintf('%.'.$format,$number);  
     }      }
     if ($target eq 'tex') {      if (!$Apache::lonxml::default_homework_loaded) {
  if ($ans =~ m/([0-9\.\-\+]+)E([0-9\-\+]+)/ ) {   &Apache::lonxml::default_homework_load($safeeval);
     my $number = $1;  
     my $power = $2;  
     $power=~s/^\+//;  
     $power=~s/^(-?)0+(\d+)//;  
     $ans=$number.'$\times 10^{'.$1.$2.'}$'; #'stupidemacs  
  }  
     }      }
       $ans=&Apache::run::run("&prettyprint(q\0$number\0,q\0$format\0,q\0$target\0)",$safeeval);
     return $ans;      return $ans;
 }  }
   
 sub make_numerical_bubbles {  sub make_numerical_bubbles {
     my ($number_of_bubbles,$target,$answer,$format) =@_;      my ($number_of_bubbles,$target,$answer,$format,$incorrect,$safeeval) =@_;
     my @bubble_values = ();      my @bubble_values=();
       &Apache::lonxml::debug("answer is $answer incorrect is $incorrect");
       my @oldseed=&Math::Random::random_get_seed();
       if (defined($incorrect) && ref($incorrect)) {
    &Apache::lonxml::debug("inside ".(scalar(@$incorrect)+1 gt $number_of_bubbles));
    if (defined($$incorrect[0]) &&
       scalar(@$incorrect)+1 >= $number_of_bubbles) {
       &Apache::lonxml::debug("inside ".(scalar(@$incorrect)+1).":$number_of_bubbles");
       &Apache::response::setrandomnumber();
       my @rand_inc=&Math::Random::random_permutation(@$incorrect);
       @bubble_values=@rand_inc[0..($number_of_bubbles-2)];
       @bubble_values=sort {$a <=> $b} (@bubble_values,$answer);
       &Apache::lonxml::debug("Answer was :$answer: returning :".$#bubble_values.": whih are :".join(':',@bubble_values));
       &Math::Random::random_set_seed(@oldseed);
       if (defined($format) && $format ne '') {
    my @bubble_display;
    foreach my $value (@bubble_values) {
       push(@bubble_display,
    &format_number($value,$format,$target,$safeeval));
    }
    return (\@bubble_values,\@bubble_display);
       } else {
    return (\@bubble_values,\@bubble_values);
       }
    }
    if (defined($$incorrect[0]) &&
       scalar(@$incorrect)+1 < $number_of_bubbles) {
       &Apache::lonxml::warning("Not enough incorrect answers were specified in the incorrect array, ignoring the specified incorrect answers and instead generating them (".join(',',@$incorrect).").");
    }
       }
     my @factors = (1.13,1.17,1.25,1.33,1.45); #default values of factors      my @factors = (1.13,1.17,1.25,1.33,1.45); #default values of factors
     my @powers = (1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0); #default values for powers      my @powers = (1..$number_of_bubbles);
     &Apache::response::setrandomnumber();      &Apache::response::setrandomnumber();
     my $ind=&Math::Random::random_uniform_integer(1,0,$#powers);      my $ind=&Math::Random::random_uniform_integer(1,0,$#powers);
     my $power = $powers[$ind];      my $power = $powers[$ind];
     $ind=&Math::Random::random_uniform_integer(1,0,$#factors);      $ind=&Math::Random::random_uniform_integer(1,0,$#factors);
     my $factor = $factors[$ind];      my $factor = $factors[$ind];
       my @bubble_display;
     for ($ind=0;$ind<$number_of_bubbles;$ind++) {      for ($ind=0;$ind<$number_of_bubbles;$ind++) {
  $bubble_values[$ind] = $answer*($factor**($power-$powers[$#powers-$ind]));   $bubble_values[$ind] = $answer*($factor**($power-$powers[$#powers-$ind]));
  $bubble_values[$ind] = &format_number($bubble_values[$ind],   $bubble_display[$ind] = &format_number($bubble_values[$ind],
        $format,$target);         $format,$target,$safeeval);
   
     }      }
     return @bubble_values;      &Math::Random::random_set_seed(@oldseed);
       return (\@bubble_values,\@bubble_display);
 }  }
   
 sub get_tolrange {  sub get_tolrange {
Line 478  sub get_tolrange { Line 696  sub get_tolrange {
 sub get_sigrange {  sub get_sigrange {
     my ($sig)=@_;      my ($sig)=@_;
     &Apache::lonxml::debug("Got a sig of :$sig:");      &Apache::lonxml::debug("Got a sig of :$sig:");
       my $courseid=$env{'request.course.id'};
       if (lc($env{"course.$courseid.disablesigfigs"}) eq 'yes') {
    return (15,0);
       }
     my $sig_lbound;      my $sig_lbound;
     my $sig_ubound;      my $sig_ubound;
     if ($sig eq '') {      if ($sig eq '') {
Line 485  sub get_sigrange { Line 707  sub get_sigrange {
  $sig_ubound =15; #SIG_UB_DEFAULT   $sig_ubound =15; #SIG_UB_DEFAULT
     } else {      } else {
  ($sig_lbound,$sig_ubound) = split(/,/,$sig);   ($sig_lbound,$sig_ubound) = split(/,/,$sig);
  if (!$sig_lbound) {   if (!defined($sig_lbound)) {
     $sig_lbound = 0; #SIG_LB_DEFAULT      $sig_lbound = 0; #SIG_LB_DEFAULT
     $sig_ubound =15; #SIG_UB_DEFAULT      $sig_ubound =15; #SIG_UB_DEFAULT
  }   }
  if (!$sig_ubound) { $sig_ubound=$sig_lbound; }   if (!defined($sig_ubound)) { $sig_ubound=$sig_lbound; }
       }
       if (($sig_ubound<$sig_lbound) ||
    ($sig_lbound > 15) ||
    ($sig =~/(\+|-)/ ) ) {
    my $errormsg=&mt("Invalid Significant figures detected")." ($sig)";
    if ($env{'request.state'} eq 'construct') {
       $errormsg.=
    &Apache::loncommon::help_open_topic('Significant_Figures');
    }
    &Apache::lonxml::error($errormsg);
     }      }
     return ($sig_ubound,$sig_lbound);      return ($sig_ubound,$sig_lbound);
 }  }
Line 497  sub get_sigrange { Line 729  sub get_sigrange {
 sub start_stringresponse {  sub start_stringresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result;      my $result;
       my $id = &Apache::response::start_response($parstack,$safeeval);
     if ($target eq 'meta') {      if ($target eq 'meta') {
  &Apache::response::start_response($parstack,$safeeval);  
  $result=&Apache::response::meta_package_write('stringresponse');   $result=&Apache::response::meta_package_write('stringresponse');
  &Apache::response::end_response();      } elsif ($target eq 'edit') {
     } else {   $result.=&Apache::edit::tag_start($target,$token);
  $result.=&start_numericalresponse(@_);   $result.=&Apache::edit::text_arg('Answer:','answer',$token);
    $result.=&Apache::edit::select_arg('Type:','type',
    [['cs','Case Sensitive'],['ci','Case Insensitive'],
     ['mc','Case Insensitive, Any Order'],
     ['re','Regular Expression']],$token);
    $result.=&Apache::edit::text_arg('String to display for answer:',
    'answerdisplay',$token);
    $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
       } elsif ($target eq 'modified') {
    my $constructtag;
    $constructtag=&Apache::edit::get_new_args($token,$parstack,
     $safeeval,'answer',
     'type','answerdisplay');
    if ($constructtag) {
       $result = &Apache::edit::rebuild_tag($token);
       $result.=&Apache::edit::handle_insert();
    }
       } elsif ($target eq 'web') {
    if (  &Apache::response::show_answer() ) {
       my $answer=
          &Apache::lonxml::get_param('answerdisplay',$parstack,$safeeval);
       if (!defined $answer || $answer eq '') {
    $answer=
       &Apache::lonxml::get_param('answer',$parstack,$safeeval);
       }
       $Apache::inputtags::answertxt{$id}=$answer;
    } 
       } elsif ($target eq 'answer' || $target eq 'grade') {
    &Apache::response::reset_params();
     }      }
     return $result;      return $result;
 }  }
   
 sub end_stringresponse {  sub end_stringresponse {
     return end_numericalresponse(@_);      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
       my $increment=1;
       my $result = '';
       my $part=$Apache::inputtags::part;
       my $id=$Apache::inputtags::response[-1];
       my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
       my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval);
       my $answerdisplay=&Apache::lonxml::get_param('answerdisplay',$parstack,$safeeval);
       &Apache::lonxml::debug("current $answer ".$token->[2]);
       if (!$Apache::lonxml::default_homework_loaded) {
    &Apache::lonxml::default_homework_load($safeeval);
       }
       if ( $target eq 'grade' && &Apache::response::submitted() ) {
    &Apache::response::setup_params('stringresponse',$safeeval);
    $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
    if ($Apache::lonhomework::type eq 'exam' ||
       &Apache::response::submitted('scantron')) {
       $increment=&Apache::response::scored_response($part,$id);
    } else {
       my $response = &Apache::response::getresponse();
       if ( $response =~ /[^\s]/) {
    my %previous = &Apache::response::check_for_previous($response,
       $part,$id);
    &Apache::lonxml::debug("submitted a $response<br>\n");
    &Apache::lonxml::debug($$parstack[-1] . "\n<br>");
    $Apache::lonhomework::results{"resource.$part.$id.submission"}=
       $response;
    my ($ad,$msg);
    if ($type eq 're' ) { 
       # if the RE wasn't in a var it likely got munged,
                       # thus grab it from the var directly
   #    my $testans=$token->[2]->{'answer'};
   #    if ($testans !~ m/^\s*\$/) {
   # $answer=$token->[2]->{'answer'};
   #    }
       ${$safeeval->varglob('LONCAPA::response')}=$response;
       $result = &Apache::run::run('if ($LONCAPA::response=~m'.$answer.') { return 1; } else { return 0; }',$safeeval);
       &Apache::lonxml::debug("current $response");
       &Apache::lonxml::debug("current $answer");
       $ad = ($result) ? 'APPROX_ANS' : 'INCORRECT';
    } else {
       my $args_ref= 
    \%{$safeeval->varglob('LONCAPA::CAPAresponse_args')};
   
       $$args_ref{'response'}=$response;
       &Apache::lonxml::debug("current $response");
       $$args_ref{'type'}=
    &Apache::lonxml::get_param('type',$parstack,$safeeval);
       foreach my $key (keys(%Apache::inputtags::params)) {
    $$args_ref{$key}=$Apache::inputtags::params{$key};
       }
       &Apache::lonxml::debug('answer is'.join(':',$answer));
       @{$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=($answer);
       ($result, my @msgs)=&Apache::run::run("&caparesponse_check_list()",$safeeval);
       &Apache::lonxml::debug('msgs are'.join(':',@msgs));
       my ($awards)=split(/:/,$result);
       my (@awards) = split(/,/,$awards);
       ($ad,$msg) = &Apache::inputtags::finalizeawards(\@awards,\@msgs);
       &Apache::lonxml::debug("\n<br>result:$result:$Apache::lonxml::curdepth<br>\n");
    }
    if ($Apache::lonhomework::type eq 'survey' &&
       ($ad eq 'INCORRECT' || $ad eq 'APPROX_ANS' ||
        $ad eq 'EXACT_ANS')) {
       $ad='SUBMITTED';
    }
    &Apache::response::handle_previous(\%previous,$ad);
    $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=$ad;
    $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=$msg;
       }
    }
       } elsif ($target eq 'web' || $target eq 'tex') {
    my $award = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"};
    my $status = $Apache::inputtags::status['-1'];
    if ($Apache::lonhomework::type eq 'exam' && $target eq 'tex') {
       $result.='\fbox{\fbox{\parbox{\textwidth-5mm}{\strut\\\\\strut\\\\\strut\\\\\strut\\\\}}}';
       $increment = &Apache::response::repetition();
       $result.='\begin{enumerate}';
       for (my $i=0;$i<$increment;$i++) {
    $result.='\item[\textbf{'.($Apache::lonxml::counter+$i).
       '}.]\textit{Leave blank on scoring form}\vskip 0 mm';
       }
       $result.= '\end{enumerate}';
    }
       } elsif ($target eq 'answer' || $target eq 'analyze') {
    if ($target eq 'analyze') {
       push (@{ $Apache::lonhomework::analyze{"parts"} },"$part.$id");
       $Apache::lonhomework::analyze{"$part.$id.type"} = 'stringresponse';
       &Apache::response::check_if_computed($token,$parstack,$safeeval,
    'answer');
    }
    &Apache::response::setup_params('stringresponse',$safeeval);
    if ($target eq 'answer') {
       $result.=&Apache::response::answer_header('stringresponse');
    }
   # foreach my $ans (@answers) {
       if ($target eq 'answer') {
    $result.=&Apache::response::answer_part('stringresponse',$answer);
    if ($type eq 're') {
       $result.=&Apache::response::answer_part('stringresponse',
       $answerdisplay);
    }
       } elsif ($target eq 'analyze') {
    push (@{ $Apache::lonhomework::analyze{"$part.$id.answer"} },
         $answer);
       }
   # }
    my $string='Case Insensitive';
    if ($type eq 'mc') {
       $string='Multiple Choice';
    } elsif ($type eq 'cs') {
       $string='Case Sensitive';
    } elsif ($type eq 'ci') {
       $string='Case Insensitive';
    } elsif ($type eq 're') {
       $string='Regular Expression';
    }
    if ($target eq 'answer') {
       if ($env{'form.answer_output_mode'} eq 'tex') {
    $result.=&Apache::response::answer_part('stringresponse',
    "$string");
       } else {
    $result.=&Apache::response::answer_part('stringresponse',
    "<b>$string</b>");
       }
    } elsif ($target eq 'analyze') {
       push (@{$Apache::lonhomework::analyze{"$part.$id.str_type"}},
     $type);
    }
    if ($target eq 'answer') {
       $result.=&Apache::response::answer_footer('stringresponse');
    }
       } elsif ($target eq 'edit') {
    $result.='</td></tr>'.&Apache::edit::end_table;
       }
       if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || 
    $target eq 'tex' || $target eq 'analyze') {
    &Apache::lonxml::increment_counter($increment);
       }
       &Apache::response::end_response;
       return $result;
 }  }
   
 sub start_formularesponse {  sub start_formularesponse {

Removed from v.1.108  
changed lines
  Added in v.1.183


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.