Diff for /loncom/homework/response.pm between versions 1.208 and 1.241

version 1.208, 2008/11/25 13:16:17 version 1.241, 2015/02/23 19:46:19
Line 30 Line 30
   
 =head1 NAME  =head1 NAME
   
 Apache::resonse.pm  Apache::response.pm
   
 =head1 SYNOPSIS  =head1 SYNOPSIS
   
Line 53  package Apache::response; Line 53  package Apache::response;
 use strict;  use strict;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::inputtags();
 use Apache::lonmaxima();  use Apache::lonmaxima();
   use Apache::lonr();
   use Apache::lontexconvert();
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse','customresponse','mathresponse'));      &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse','customresponse','mathresponse'));
Line 135  sub poprandomnumber { Line 138  sub poprandomnumber {
 }  }
   
 sub setrandomnumber {  sub setrandomnumber {
     my ($ignore_id2) = @_;      my ($ignore_id2,$target,$rndseed) = @_;
     my $rndseed;      if (!defined($rndseed)) {
     $rndseed=&Apache::structuretags::setup_rndseed();          $rndseed=&Apache::structuretags::setup_rndseed(undef,$target);
       } 
     if (!defined($rndseed)) { $rndseed=&Apache::lonnet::rndseed(); }      if (!defined($rndseed)) { $rndseed=&Apache::lonnet::rndseed(); }
     &Apache::lonxml::debug("randseed $rndseed");      &Apache::lonxml::debug("randseed $rndseed");
     #  $rndseed=unpack("%32i",$rndseed);      #  $rndseed=unpack("%32i",$rndseed);
Line 177  sub setrandomnumber { Line 181  sub setrandomnumber {
     } else {      } else {
  ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2");   ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2");
     }      }
   
     if ($rndseed =~/([,:])/) {      if ($rndseed =~/([,:])/) {
  my $char=$1;   my $char=$1;
  use integer;   use integer;
Line 239  sub meta_stores_write { Line 242  sub meta_stores_write {
       "></stores>\n";        "></stores>\n";
 }  }
   
 sub mandatory_part_meta {  
 =pod  =pod
   
 =item meta_part_order  =item mandatory_part_meta()
   
 Autogenerate metadata for mandatory  Autogenerate metadata for mandatory
 input (from RAT or lonparmset) and   input (from RAT or lonparmset) and
 output (to lonspreadsheet)  output (to lonspreadsheet)
 of each part  of each part
 #  
     return  
    &meta_parameter_write('opendate','date_start','',  
                          'Opening Date').  
    &meta_parameter_write('duedate','date_end','',  
                          'Due Date').  
    &meta_parameter_write('answerdate','date_start','',  
                          'Show Answer Date').  
    &meta_parameter_write('weight','int_zeropos','',  
                          'Available Points').  
    &meta_parameter_write('maxtries','int_pos','',  
                          'Maximum Number of Tries').  
  &meta_package_write('part').  
         &meta_stores_write('solved','string',  
    'Problem Status').  
         &meta_stores_write('tries','int_zeropos',  
    'Number of Attempts').  
         &meta_stores_write('awarded','float',  
    'Partial Credit Factor');  
   
 Note: responseid-specific data 'submission' and 'awarddetail'  Note: responseid-specific data 'submission' and 'awarddetail'
 not available to spreadsheet -> skip here  not available to spreadsheet -> skip here
   
 =cut  =cut
   
   
   sub mandatory_part_meta {
       return &meta_package_write('part').
              &meta_stores_write('solved','string','Problem Status').
              &meta_stores_write('tries','int_zeropos','Number of Attempts').
              &meta_stores_write('awarded','float','Partial Credit Factor');
 }  }
   
 sub meta_part_order {  sub meta_part_order {
Line 293  sub meta_response_order { Line 282  sub meta_response_order {
 }  }
   
 sub check_for_previous {  sub check_for_previous {
     my ($curresponse,$partid,$id,$last) = @_;      my ($curresponse,$partid,$id,$last,$type) = @_;
     my %previous;      my %previous;
     $previous{'used'} = 0;      $previous{'used'} = 0;
       my $questiontype = $Apache::lonhomework::type;
       my $curr_rndseed = $env{'form.'.$partid.'.rndseed'};
     foreach my $key (sort(keys(%Apache::lonhomework::history))) {      foreach my $key (sort(keys(%Apache::lonhomework::history))) {
  if ($key =~ /resource\.$partid\.$id\.submission$/) {   if ($key =~ /resource\.\Q$partid\E\.\Q$id\E\.submission$/) {
     if ( $last && $key =~ /^(\d+):/ ) {      if ( $last && $key =~ /^(\d+):/ ) {
  next if ($1 >= $last);   next if ($1 >= $last);
     }      }
     &Apache::lonxml::debug("Trying $key");      &Apache::lonxml::debug("Trying $key");
     my $pastresponse=$Apache::lonhomework::history{$key};      my $pastresponse=$Apache::lonhomework::history{$key};
     if ($pastresponse eq $curresponse) {      if ($pastresponse eq $curresponse) {
  $previous{'used'} = 1;  
  my $history;   my $history;
  if ( $key =~ /^(\d+):/ ) {   if ( $key =~ /^(\d+):/ ) {
     $history=$1;                      $history=$1;
                       next if ((($questiontype eq 'randomizetry') ||
                                ($Apache::lonhomework::history{"$history:resource.$partid.type"} eq 'randomizetry')) &&
                                ($curr_rndseed ne $Apache::lonhomework::history{"$history:resource.$partid.rndseed"}));
     $previous{'award'} = $Apache::lonhomework::history{"$history:resource.$partid.$id.awarddetail"};      $previous{'award'} = $Apache::lonhomework::history{"$history:resource.$partid.$id.awarddetail"};
     $previous{'last'}='0';      $previous{'last'}='0';
     push(@{ $previous{'version'} },$history);      push(@{ $previous{'version'} },$history);
  } else {   } else {
                       next if ((($questiontype eq 'randomizetry') ||
                                ($Apache::lonhomework::history{"resource.$partid.type"} eq 'randomizetry')) &&
                                ($curr_rndseed ne $Apache::lonhomework::history{"resource.$partid.rndseed"}));
     $previous{'award'} = $Apache::lonhomework::history{"resource.$partid.$id.awarddetail"};      $previous{'award'} = $Apache::lonhomework::history{"resource.$partid.$id.awarddetail"};
     $previous{'last'}='1';      $previous{'last'}='1';
  }   }
                   $previous{'used'} = 1;
  if (! $previous{'award'} ) { $previous{'award'} = 'UNKNOWN'; }   if (! $previous{'award'} ) { $previous{'award'} = 'UNKNOWN'; }
                   if ($previous{'award'} eq 'INTERNAL_ERROR') { $previous{'used'}=0; }
  &Apache::lonxml::debug("got a match :$previous{'award'}:$previous{'used'}:");   &Apache::lonxml::debug("got a match :$previous{'award'}:$previous{'used'}:");
     }              } elsif ($type eq 'ci') {
                   if (lc($pastresponse) eq lc($curresponse)) {
                       if ($key =~ /^(\d+):/) {
                           my $history = $1;
                           next if (($questiontype eq 'randomizetry') &&
                                ($curr_rndseed ne $Apache::lonhomework::history{"$history:resource.$partid.rndseed"}));
                           push (@{$previous{'versionci'}},$history);
                           $previous{'awardci'} = $Apache::lonhomework::history{"$history:resource.$partid.$id.awarddetail"};
                           $previous{'usedci'} = 1;
                       }
                   }
               }
  }   }
     }      }
     &Apache::lonhomework::showhash(%previous);      &Apache::lonhomework::showhash(%previous);
Line 330  sub handle_previous { Line 339  sub handle_previous {
  if ($$previous{'last'}) {   if ($$previous{'last'}) {
     push(@Apache::inputtags::previous,'PREVIOUSLY_LAST');      push(@Apache::inputtags::previous,'PREVIOUSLY_LAST');
     push(@Apache::inputtags::previous_version,$$previous{'version'});      push(@Apache::inputtags::previous_version,$$previous{'version'});
  } elsif ($Apache::lonhomework::type ne 'survey') {   } elsif (($Apache::lonhomework::type ne 'survey') &&
                    ($Apache::lonhomework::type ne 'surveycred') &&
                    ($Apache::lonhomework::type ne 'anonsurvey') &&
                    ($Apache::lonhomework::type ne 'anonsurveycred')) {
     push(@Apache::inputtags::previous,'PREVIOUSLY_USED');      push(@Apache::inputtags::previous,'PREVIOUSLY_USED');
     push(@Apache::inputtags::previous_version,$$previous{'version'});      push(@Apache::inputtags::previous_version,$$previous{'version'});
  }   }
Line 386  sub end_dataresponse { Line 398  sub end_dataresponse {
     $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}='SUBMITTED';      $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}='SUBMITTED';
  }   }
     } else {      } else {
  $result='Not Permitted to change values.'                  $result=&mt('Not Permitted to change values');
     }      }
  }   }
     }      }
Line 411  sub start_customresponse { Line 423  sub start_customresponse {
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result.=&Apache::edit::tag_start($target,$token);   $result.=&Apache::edit::tag_start($target,$token);
  $result.=&Apache::edit::text_arg('String to display for answer:',   $result.=&Apache::edit::text_arg('String to display for answer:',
  'answerdisplay',$token);   'answerdisplay',$token,'50');
  $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();   $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
     } elsif ($target eq 'modified') {      } elsif ($target eq 'modified') {
  my $constructtag;   my $constructtag;
Line 451  sub end_customresponse { Line 463  sub end_customresponse {
     ${$safeeval->varglob('LONCAPA::customresponse_submission')}=      ${$safeeval->varglob('LONCAPA::customresponse_submission')}=
  $response;   $response;
           
     my $award = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer[-1].'}',$safeeval);      my ($award,$score) = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer[-1].'}',$safeeval);
     if (!&Apache::inputtags::valid_award($award)) {      if (!&Apache::inputtags::valid_award($award)) {
  $error = $award;   $error = $award;
  $award = 'ERROR';   $award = 'ERROR';
     }      }
               if (($award eq 'INCORRECT' || $award eq 'APPROX_ANS' ||
                    $award eq 'EXACT_ANS')) {
                   if ($Apache::lonhomework::type eq 'survey') {
                       $award='SUBMITTED';
                   } elsif ($Apache::lonhomework::type eq 'surveycred') {
                       $award='SUBMITTED_CREDIT';
                   } elsif ($Apache::lonhomework::type eq 'anonsurvey') {
                       $award='ANONYMOUS';
                   } elsif ($Apache::lonhomework::type eq 'anonsurveycred') {
                       $award='ANONYMOUS_CREDIT';
                   }
               }
     &Apache::response::handle_previous(\%previous,$award);      &Apache::response::handle_previous(\%previous,$award);
     $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=      $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
  $award;   $award;
               if ($award eq 'ASSIGNED_SCORE') {
                   $Apache::lonhomework::results{"resource.$part.$id.awarded"}=1.0*$score;
               }
     if ($error) {      if ($error) {
  $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=   $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=
     $error;      $error;
Line 475  sub end_customresponse { Line 502  sub end_customresponse {
  $result .= &Apache::response::answer_footer('customresponse');   $result .= &Apache::response::answer_footer('customresponse');
     }      }
     if ($target eq 'web') {      if ($target eq 'web') {
  &setup_prior_tries_hash(\&format_prior_response_math);   &setup_prior_tries_hash(\&format_prior_response_custom);
     }      }
     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(&Apache::response::repetition(),          my $repetition = &repetition();
    "$part.$id");   &Apache::lonxml::increment_counter($repetition,"$part.$id");
  if ($target eq 'analyze') {   if ($target eq 'analyze') {
             $Apache::lonhomework::analyze{"$part.$id.type"} = 'customresponse';              $Apache::lonhomework::analyze{"$part.$id.type"} = 'customresponse';
     &Apache::lonhomework::set_bubble_lines();      &Apache::lonhomework::set_bubble_lines();
Line 496  sub end_customresponse { Line 523  sub end_customresponse {
   
 sub format_prior_response_custom {  sub format_prior_response_custom {
     my ($mode,$answer) =@_;      my ($mode,$answer) =@_;
       if (ref($answer) eq 'ARRAY') {
           $answer = '('.join(', ', @{ $answer }).')';
       }
     return '<span class="LC_prior_custom">'.      return '<span class="LC_prior_custom">'.
     &HTML::Entities::encode($answer,'"<>&').'</span>';      &HTML::Entities::encode($answer,'"<>&').'</span>';
 }  }
Line 518  sub start_mathresponse { Line 548  sub start_mathresponse {
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result.=&Apache::edit::tag_start($target,$token);   $result.=&Apache::edit::tag_start($target,$token);
  $result.=&Apache::edit::text_arg('String to display for answer:',   $result.=&Apache::edit::text_arg('String to display for answer:',
  'answerdisplay',$token);   'answerdisplay',$token,'50');
  $result.=&Apache::edit::select_arg('Algebra System:',   $result.=&Apache::edit::select_arg('Algebra System:',
    'cas',     'cas',
    ['maxima'],     ['maxima','R'],
    $token);     $token);
  $result.=&Apache::edit::text_arg('Argument Array:',   $result.=&Apache::edit::text_arg('Argument Array:',
  'args',$token).   'args',$token).
Line 546  sub start_mathresponse { Line 576  sub start_mathresponse {
 }  }
   
 sub edit_mathresponse_button {  sub edit_mathresponse_button {
     my ($id,$field)=@_;      my ($partid,$id)=@_;
     my $button=&mt('Edit Answer');      my $field = 'HWVAL_'.$partid.'_'.$id;
 #    my $helplink=&Apache::loncommon::help_open_topic('Formula_Editor');      my $eqneditor = 'lcmath';
     my $iconpath=$Apache::lonnet::perlvar{'lonIconsURL'};      if ($env{'browser.type'} eq 'safari') {
     return(<<ENDFORMULABUTTON);          if ($env{'browser.os'} eq 'mac') {
 <script language="JavaScript">              my ($prefix,$version) = ($env{'browser.version'} =~ /^(\d*)(\d{3})\./);
 function edit_${id}_${field} (textarea) {              if ($env{'browser.mobile'}) {
     thenumber = textarea;                  if (($version < 531) || (($prefix eq '') && ($version < 533))) {
     thedata = document.forms['lonhomework'].elements[textarea].value;                      $eqneditor = '';
     newwin = window.open("/adm/dragmath/applet/MaximaPopup.html","","width=565,height=400,resizable");                  }
               } elsif ($version < 522) {
                   $eqneditor = 'dragmath';
               }
           }
       } elsif ($env{'browser.type'} eq 'explorer') {
           if ($env{'browser.version'} < 9) {
               $eqneditor = 'dragmath';
           }
       } elsif ($env{'browser.type'} eq 'mozilla') {
           if ($env{'browser.version'} < 3) {
               $eqneditor = 'dragmath';
           } else {
               if ($env{'browser.info'} =~ /^firefox\-([\d\.]+)/) {
                   my $firefox = $1;
                   if ($firefox < 3) {
                       $eqneditor = 'dragmath';
                   }
               }
           }
       }
       if ($eqneditor eq 'dragmath') {
           # DragMath applet
           my $button=&mt('Edit Answer');
   #       my $helplink=&Apache::loncommon::help_open_topic('Formula_Editor');
           my $iconpath=$Apache::lonnet::perlvar{'lonIconsURL'};
           return(<<ENDFORMULABUTTON);
   <script type="text/javascript" language="JavaScript">
   function LC_mathedit_${field} (LCtextline) {
       thenumber = LCtextline;
       var thedata = '';
       if (document.getElementById(LCtextline)) {
           thedata = document.getElementById(LCtextline).value;
       }
       newwin = window.open("/adm/dragmath/MaximaPopup.html","","width=565,height=400,resizable");
 }  }
 </script>  </script>
 <a href="javascript:edit_${id}_${field}('${field}');void(0);"><img class="stift" src='$iconpath/stift.gif' alt='$button' title='$button'/></a>  <a href="javascript:LC_mathedit_${field}('${field}');void(0);"><img class="stift" src="$iconpath/stift.gif" alt="$button" title="$button" /></a>
 ENDFORMULABUTTON  ENDFORMULABUTTON
       } elsif ($eqneditor eq 'lcmath') {
           # LON-CAPA math equation editor
           my $mathjaxjs;
           unless (lc(&Apache::lontexconvert::tex_engine()) eq 'mathjax') {
               $mathjaxjs = <<"MATHJAX_SCRIPT";
   var mathjaxscript = document.createElement("script");
       mathjaxscript.type = "text/javascript";
       mathjaxscript.src = "/adm/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
       document.body.appendChild(mathjaxscript);
   MATHJAX_SCRIPT
           }
           return(<<EQ_EDITOR_SCRIPT);
   <script type="text/javascript">
     var LCmathField = document.getElementById('${field}');
     LCmathField.className += ' math'; // note the space
     LCmathField.setAttribute('data-implicit_operators', 'true');
     var LCMATH_started;
     if (typeof LCMATH_started === 'undefined') {
       $mathjaxjs
       LCMATH_started = true;
       var script = document.createElement("script");
       script.type = "text/javascript";
       script.src = "/adm/LC_math_editor/LC_math_editor.min.js";
       document.body.appendChild(script);
       window.addEventListener('load', function(e) {
           LCMATH.initEditors();
       }, false);
     }
   </script>
   EQ_EDITOR_SCRIPT
       }
 }  }
   
 sub end_mathresponse {  sub end_mathresponse {
Line 585  sub end_mathresponse { Line 680  sub end_mathresponse {
                 $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args,                  $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args,
                                                       &Apache::lonxml::get_param('libraries',$parstack,$safeeval));                                                        &Apache::lonxml::get_param('libraries',$parstack,$safeeval));
             }              }
               if ($cas eq 'R') {
                   my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)];
                   $award=&Apache::lonr::r_run($Apache::response::custom_answer[-1],$response,$args,
                                               &Apache::lonxml::get_param('libraries',$parstack,$safeeval));
               }
   
     if (!&Apache::inputtags::valid_award($award)) {      if (!&Apache::inputtags::valid_award($award)) {
  $error = $award;   $error = $award;
  $award = 'ERROR';   $award = 'ERROR';
     }      }
               if (($award eq 'INCORRECT' || $award eq 'APPROX_ANS' ||
                    $award eq 'EXACT_ANS')) {
                   if ($Apache::lonhomework::type eq 'survey') {
                       $award='SUBMITTED';
                   } elsif ($Apache::lonhomework::type eq 'surveycred') {
                       $award='SUBMITTED_CREDIT';
                   } elsif ($Apache::lonhomework::type eq 'anonsurvey') {
                       $award='ANONYMOUS';
                   } elsif ($Apache::lonhomework::type eq 'anonsurveycred') {
                       $award='ANONYMOUS_CREDIT';
                   }
               }
     &Apache::response::handle_previous(\%previous,$award);      &Apache::response::handle_previous(\%previous,$award);
     $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=      $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
  $award;   $award;
Line 604  sub end_mathresponse { Line 717  sub end_mathresponse {
         my $id = $Apache::inputtags::response[-1];          my $id = $Apache::inputtags::response[-1];
         if (($Apache::inputtags::status['-1'] eq 'CAN_ANSWER')          if (($Apache::inputtags::status['-1'] eq 'CAN_ANSWER')
            && (&Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.turnoffeditor') ne 'yes')) {             && (&Apache::lonnet::EXT('resource.'.$partid.'_'.$id.'.turnoffeditor') ne 'yes')) {
             $result.=&edit_mathresponse_button($id,"HWVAL_$id");              $result.=&edit_mathresponse_button($partid,$id);
         }          }
     }      }
   
Line 814  sub answer_header { Line 927  sub answer_header {
  if ($Apache::lonhomework::type eq 'exam') {   if ($Apache::lonhomework::type eq 'exam') {
     $bit = ($Apache::lonxml::counter+$increment).') ';      $bit = ($Apache::lonxml::counter+$increment).') ';
  } else {   } else {
     $bit .= ' Answer for Part: \verb|'.              $bit .= ' '.&mt('Answer for Part: [_1]',
  $Apache::inputtags::part.'| ';                                  '\verb|'.$Apache::inputtags::part.'|').' ';
  }   }
  push(@answer_bits,$bit);   push(@answer_bits,$bit);
     } else {      } else {
Line 910  sub showallfoils { Line 1023  sub showallfoils {
  }   }
     }      }
     if ($Apache::lonhomework::type eq 'survey') { return 1; }      if ($Apache::lonhomework::type eq 'survey') { return 1; }
       if ($Apache::lonhomework::type eq 'surveycred') { return 1; }
       if ($Apache::lonhomework::type eq 'anonsurvey') { return 1; }
       if ($Apache::lonhomework::type eq 'anonsurveycred') { return 1; }
   
     return 0;      return 0;
 }  }
   
 =pod  =pod
   
 =item &getresponse($offset,$resulttype);  =item &getresponse();
   
 Retreives the current submitted response, helps out in the case of  Retreives the current submitted response, helps out in the case of
 scantron mode.  scantron mode.
Line 961  sub getresponse { Line 1078  sub getresponse {
  my $id    = $Apache::inputtags::response[-1];   my $id    = $Apache::inputtags::response[-1];
   
  my $line;   my $line;
    my $startline = $env{'form.scantron_questnum_start.'.$part.'.'.$id};
           if (!$startline) {
               $startline = $Apache::lonxml::counter;
           }
  for ($line = 0; $line < $lines; $line++) {   for ($line = 0; $line < $lines; $line++) {
     my $theline = $Apache::lonxml::counter+$offset-1+$line;              my $theline = $startline+$offset-1+$line;
     $response = $env{"scantron.$theline.answer"};      $response = $env{"scantron.$theline.answer"};
     if ((defined($response)) && ($response ne "") && ($response ne " ")) {      if ((defined($response)) && ($response ne "") && ($response ne " ")) {
  last;   last;
     }      }
        
  }   }
   
  # save bubbled letter for later   # save bubbled letter for later
  $Apache::lonhomework::results{"resource.$part.$id.scantron"}.=   $Apache::lonhomework::results{"resource.$part.$id.scantron"}.=
     $response;      $response;
  if ($resulttype ne 'letter') {   if ($resulttype ne 'letter') {
     if ($resulttype eq 'A is 1') {              $response = $let_to_num{$response};
  $response = $let_to_num{$response}+1;              if ($resulttype eq 'A is 1') {
     } else {                  if ($response ne "") {
  $response = $let_to_num{$response};                      $response = $response+1;
                   }
     }      }
     if ($response ne "") {      if ($response ne "") {
  $response += $line * $bubbles_per_line;   $response += $line * $bubbles_per_line;
     }      }
  } else {   } else {
     if ($response ne "") {      if ($response ne "") {
                   my $raw = $response;
  $response = chr(ord($response) + $line * $bubbles_per_line);   $response = chr(ord($response) + $line * $bubbles_per_line);
     }      }
  }   }
Line 1003  sub getresponse { Line 1126  sub getresponse {
   
 =item &repetition();  =item &repetition();
   
 Returns the number of lines that are required to encode the weight.  In scalar context:
 (Currently expects that there are 10 bubbles per line)  
   returns: the number of lines that are required to encode the weight.
   (Default is for 10 bubbles per bubblesheet item; other (integer) 
   values can be specified by using a custom Bubblesheet format file 
   with an eighteenth entry (BubblesPerRow) set to the integer 
   appropriate for the bubblesheets which will be used to assign weights.
   
   In array context:
    
   returns: number of lines required to encode weight, and bubbles/line.
   
 =cut  =cut
   
Line 1012  sub repetition { Line 1144  sub repetition {
     my $id = $Apache::inputtags::part;      my $id = $Apache::inputtags::part;
     my $weight = &Apache::lonnet::EXT("resource.$id.weight");      my $weight = &Apache::lonnet::EXT("resource.$id.weight");
     if (!defined($weight) || ($weight eq '')) { $weight=1; }      if (!defined($weight) || ($weight eq '')) { $weight=1; }
     my $repetition = int($weight/10);      my $bubbles_per_row;
     if ($weight % 10 != 0) { $repetition++; }       if (($env{'form.bubbles_per_row'} =~ /^\d+$/) && 
           ($env{'form.bubbles_per_row'} > 0)) {
           $bubbles_per_row = $env{'form.bubbles_per_row'};
       } else {
           $bubbles_per_row = 10;
       }
       my $denominator = $bubbles_per_row;
       if (($env{'form.scantron_lastbubblepoints'} == 0) && 
           ($bubbles_per_row > 1)) {
           $denominator = $bubbles_per_row - 1;
       } 
       my $repetition = int($weight/$denominator);
       if ($weight % $denominator != 0) { $repetition++; } 
       if (wantarray) {
           return ($repetition,$bubbles_per_row);
       }
     return $repetition;      return $repetition;
   
 }  }
   
 =pod  =pod
   
 =item &scored_response($part_id,$response_id);  =item &scored_response();
   
 Sets the results hash elements  Sets the results hash elements
   
Line 1044  Arguments Line 1192  Arguments
 sub scored_response {  sub scored_response {
     my ($part,$id)=@_;      my ($part,$id)=@_;
     my $repetition=&repetition();      my $repetition=&repetition();
       my $bubbles_per_row;
       if (($env{'form.bubbles_per_row'} =~ /^\d+$/) &&
           ($env{'form.bubbles_per_row'} > 0)) {
           $bubbles_per_row = $env{'form.bubbles_per_row'};
       } else {
           $bubbles_per_row = 10;
       }
     my $score=0;      my $score=0;
     for (my $i=0;$i<$repetition;$i++) {      for (my $i=0;$i<$repetition;$i++) {
  # A is 1, B is 2, etc. (get response return 0-9 and then we add 1)   # A is 1, B is 2, etc.
  my $increase=&Apache::response::getresponse($i+1);   my $increase=&Apache::response::getresponse($i+1);
  if ($increase ne '') { $score+=$increase+1; }          unless (($increase == $bubbles_per_row-1) &&
                   ($env{'form.scantron_lastbubblepoints'} == 0)) {
               # (get response return 0-9 and then we add 1)
               if ($increase ne '') {
                   $score+=$increase+1;
               }
           }
     }      }
     my $weight = &Apache::lonnet::EXT("resource.$part.weight");      my $weight = &Apache::lonnet::EXT("resource.$part.weight");
     if (!defined($weight) || $weight eq '' || $weight eq 0) { $weight = 1; }      if (!defined($weight) || $weight eq '' || $weight eq 0) { $weight = 1; }
Line 1060  sub scored_response { Line 1221  sub scored_response {
 }  }
   
 sub whichorder {  sub whichorder {
     my ($max,$randomize,$showall,$hash)=@_;      my ($max,$randomize,$showall,$hash,$rndseed)=@_;
     #&Apache::lonxml::debug("man $max randomize $randomize");      #&Apache::lonxml::debug("man $max randomize $randomize");
     if (!defined(@{ $$hash{'names'} })) { return; }      my @names;
     my @names = @{ $$hash{'names'} };      if (ref($hash->{'names'}) eq 'ARRAY') {
           @names = @{$hash->{'names'}};
       }
       return if (!@names);
     my @whichopt =();      my @whichopt =();
     my (%top,@toplist,%bottom,@bottomlist);      my (%top,@toplist,%bottom,@bottomlist);
     if (!($showall || ($randomize eq 'no'))) {      if (!($showall || ($randomize eq 'no'))) {
Line 1114  sub show_answer { Line 1278  sub show_answer {
     my $part   = $Apache::inputtags::part;      my $part   = $Apache::inputtags::part;
     my $award  = $Apache::lonhomework::history{"resource.$part.solved"};      my $award  = $Apache::lonhomework::history{"resource.$part.solved"};
     my $status = $Apache::inputtags::status[-1];      my $status = $Apache::inputtags::status[-1];
     return  ( ($award =~ /^correct/      my $canshow = 0;
        && &Apache::lonhomework::show_problem_status())      if ($award =~ /^correct/) {
       || $status eq "SHOW_ANSWER");          if (($Apache::lonhomework::history{"resource.$part.awarded"} >= 1) ||
               (&Apache::lonnet::EXT("resource.$part.retrypartial") !~/^1|on|yes$/)) {
               $canshow = 1;
           }   
       }
       return  (($canshow && &Apache::lonhomework::show_problem_status()) 
        || $status eq "SHOW_ANSWER");
 }  }
   
 sub analyze_store_foilgroup {  sub analyze_store_foilgroup {
Line 1144  sub check_if_computed { Line 1314  sub check_if_computed {
   
 sub pick_foil_for_concept {  sub pick_foil_for_concept {
     my ($target,$attrs,$hinthash,$parstack,$safeeval)=@_;      my ($target,$attrs,$hinthash,$parstack,$safeeval)=@_;
     if (not defined(@{ $Apache::response::conceptgroup{'names'} })) { return; }      my @names;
     my @names = @{ $Apache::response::conceptgroup{'names'} };      if (ref($Apache::response::conceptgroup{'names'}) eq 'ARRAY') {
           @names = @{ $Apache::response::conceptgroup{'names'} };
       }
       return if (!@names);
     my $pick=int(&Math::Random::random_uniform() * ($#names+1));      my $pick=int(&Math::Random::random_uniform() * ($#names+1));
     my $name=$names[$pick];      my $name=$names[$pick];
     push @{ $Apache::response::foilgroup{'names'} }, $name;      push @{ $Apache::response::foilgroup{'names'} }, $name;
Line 1270  sub check_status { Line 1443  sub check_status {
     if (!defined($id)) { $id=$Apache::inputtags::part; }      if (!defined($id)) { $id=$Apache::inputtags::part; }
     my $curtime=&Apache::lonnet::EXT('system.time');      my $curtime=&Apache::lonnet::EXT('system.time');
     my $opendate=&Apache::lonnet::EXT("resource.$id.opendate");      my $opendate=&Apache::lonnet::EXT("resource.$id.opendate");
     my $duedate=&Apache::lonnet::EXT("resource.$id.duedate");      my $duedate=&Apache::lonhomework::due_date($id);
     my $answerdate=&Apache::lonnet::EXT("resource.$id.answerdate");      my $answerdate=&Apache::lonnet::EXT("resource.$id.answerdate");
     if ( $opendate && $curtime > $opendate &&      if ( $opendate && $curtime > $opendate &&
          $duedate && $curtime > $duedate &&           $duedate && $curtime > $duedate &&
Line 1289  sub check_status { Line 1462  sub check_status {
   
 =pod  =pod
   
 =item setup_prior_tries_hash($func,$data)  =item setup_prior_tries_hash()
   
   Foreach each past .submission $func is called with 3 arguments    Foreach each past .submission $func is called with 3 arguments
      - the mode to set things up for (currently always 'grade')       - the mode to set things up for (currently always 'grade')
Line 1300  sub check_status { Line 1473  sub check_status {
     - scalars that are other elements of the history hash to pass to $func      - scalars that are other elements of the history hash to pass to $func
     - ref to data to be passed untouched to $func      - ref to data to be passed untouched to $func
   
     $questiontype is the questiontype (currently only passed in if
         randomizebytry.
   
 =cut  =cut
   
 sub setup_prior_tries_hash {  sub setup_prior_tries_hash {
     my ($func,$data) = @_;      my ($func,$data,$questiontype) = @_;
     my $part = $Apache::inputtags::part;      my $part = $Apache::inputtags::part;
     my $id   = $Apache::inputtags::response[-1];      my $id   = $Apache::inputtags::response[-1];
     foreach my $i (1..$Apache::lonhomework::history{'version'}) {      foreach my $i (1..$Apache::lonhomework::history{'version'}) {
  my $sub_key   = "$i:resource.$part.$id.submission";          my $partprefix = "$i:resource.$part";
    my $sub_key   = "$partprefix.$id.submission";
  next if (!exists($Apache::lonhomework::history{$sub_key}));   next if (!exists($Apache::lonhomework::history{$sub_key}));
           my $type_key = "$partprefix.type";
           my $type = $Apache::lonhomework::history{$type_key};
  my @other_data;   my @other_data;
  foreach my $datum (@{ $data }) {          if (ref($data) eq 'ARRAY') {
     if (ref($datum)) {      foreach my $datum (@{ $data }) {
  push(@other_data,$datum);          if (ref($datum)) {
     } else {      push(@other_data,$datum);
  my $info_key = "$i:resource.$part.$id.$datum";          } else {
  push(@other_data,$Apache::lonhomework::history{$info_key});      my $info_key = "$i:resource.$part.$id.$datum";
       push(@other_data,$Apache::lonhomework::history{$info_key});
           }
     }      }
  }          }
           if ($questiontype eq 'randomizetry') { 
               my $order_key = "$partprefix.$id.foilorder";
               my @whichopts = &Apache::lonnet::str2array($Apache::lonhomework::history{$order_key});
               if (@whichopts > 0) {
                   shift(@other_data);
                   unshift(@other_data,\@whichopts);
               }
           }
  my $output =   my $output =
     &$func('grade',      &$func('grade',
    $Apache::lonhomework::history{$sub_key},     $Apache::lonhomework::history{$sub_key},
Line 1334  __END__ Line 1522  __END__
     
 =pod  =pod
   
 =back  
   
 =cut  
   
   =cut

Removed from v.1.208  
changed lines
  Added in v.1.241


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>