Diff for /loncom/homework/grades.pm between versions 1.446 and 1.447

version 1.446, 2007/10/08 22:29:59 version 1.447, 2007/10/09 09:16:04
Line 47  use POSIX qw(floor); Line 47  use POSIX qw(floor);
   
   
 my %perm=();  my %perm=();
 my %bubble_lines_per_response;     # no. bubble lines for each response.  my %bubble_lines_per_response = ();     # no. bubble lines for each response.
                                    # index is "symb.part_id"                                     # index is "symb.part_id"
   
   my %first_bubble_line = (); # First bubble line no. for each bubble.
   
   # Save and restore the bubble lines array to the form env.
   
   
   sub save_bubble_lines {
   
       foreach my $line (keys(%bubble_lines_per_response)) {
    $env{"form.scantron.bubblelines.$line"}  = $bubble_lines_per_response{$line};
    $env{"form.scantron.first_bubble_line.$line"} =
       $first_bubble_line{$line};
       }
   }
   
   
   sub restore_bubble_lines {
       my $line = 0;
       %bubble_lines_per_response = ();
       while ($env{"form.scantron.bubblelines.$line"}) {
    my $value = $env{"form.scantron.bubblelines.$line"};
    $bubble_lines_per_response{$line} = $value;
    $first_bubble_line{$line}  =
       $env{"form.scantron.first_bubble_line.$line"};
    $line++;
       }
   
   }
   
   #  Given the parsed scanline, get the response for 
   #  'answer' number n:
   
   sub get_response_bubbles {
       my ($parsed_line, $response)  = @_;
   
       my $bubble_line = $first_bubble_line{$response};
       my $bubble_lines= $bubble_linse_per_response{$response};
       my $selected = "";
   
       for (my $bline = 0; $bline < $bubble_lines; $bline++) {
    $selected .= $$parsed_line{"scantron.$bubble_line.answer"};
    $bubble_line++;
       }
       return $selected;
   }
   
   
 # ----- These first few routines are general use routines.----  # ----- These first few routines are general use routines.----
   
   # Return the number of occurences of a pattern in a string.
   
   sub occurence_count {
       my ($string, $pattern) = @_;
   
       my @matches = ($string =~ /$pattern/g);
   
       return scalar(@matches);
   }
   
   
   # Take a string known to have digits and convert all the
   # digits into letters in the range J,A..I.
   
   sub digits_to_letters {
       my ($input) = @_;
   
       my @alphabet = ('J', 'A'..'I');
   
       my @input    = split(//, $input);
       my $output ='';
       for (my $i = 0; $i < scalar(@input); $i++) {
    if ($input[$i] =~ /\d/) {
       $output .= $alphabet[$input[$i]];
    } else {
       $output .= $input[$i];
    }
       }
       return $output;
   }
   
 #  #
 # --- Retrieve the parts from the metadata file.---  # --- Retrieve the parts from the metadata file.---
 sub getpartlist {  sub getpartlist {
Line 531  sub jscriptNform { Line 608  sub jscriptNform {
     return $jscript;      return $jscript;
 }  }
   
   
   
 # Given the score (as a number [0-1] and the weight) what is the final  # Given the score (as a number [0-1] and the weight) what is the final
 # point value? This function will round to the nearest tenth, third,  # point value? This function will round to the nearest tenth, third,
 # or quarter if one of those is within the tolerance of .00001.  # or quarter if one of those is within the tolerance of .00001.
Line 2789  sub version_selected_portfile { Line 2868  sub version_selected_portfile {
     my $new_answer;      my $new_answer;
     $env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stu_name/portfolio$directory$file_name");      $env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stu_name/portfolio$directory$file_name");
     if($env{'form.copy'} eq '-1') {      if($env{'form.copy'} eq '-1') {
         &Apache::lonnet::logthis('problem getting file '.$file_name);  
         $new_answer = 'problem getting file';          $new_answer = 'problem getting file';
     } else {      } else {
         $new_answer = $answer_name.'.'.$version.'.'.$answer_ext;          $new_answer = $answer_name.'.'.$version.'.'.$answer_ext;
Line 3823  sub csvuploadassign { Line 3901  sub csvuploadassign {
  }   }
  if (! %grades) { push(@skipped,"$username:$domain no data to save"); }   if (! %grades) { push(@skipped,"$username:$domain no data to save"); }
  $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";   $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";
 # &Apache::lonnet::logthis(" storing ".(join('-',%grades)));  
  my $result=&Apache::lonnet::cstore(\%grades,$symb,   my $result=&Apache::lonnet::cstore(\%grades,$symb,
    $env{'request.course.id'},     $env{'request.course.id'},
    $domain,$username);     $domain,$username);
Line 4176  sub displaySubByDates { Line 4253  sub displaySubByDates {
   
  my $where = ($isTask ? "$version:resource.$interaction"   my $where = ($isTask ? "$version:resource.$interaction"
              : "$version:resource");               : "$version:resource");
  #&Apache::lonnet::logthis(" got $where");  
  $studentTable.='<tr bgcolor="#ffffff" valign="top"><td>'.$timestamp.'</td>';   $studentTable.='<tr bgcolor="#ffffff" valign="top"><td>'.$timestamp.'</td>';
  if ($isCODE) {   if ($isCODE) {
     $studentTable.='<td>'.$record->{$version.':resource.CODE'}.'</td>';      $studentTable.='<td>'.$record->{$version.':resource.CODE'}.'</td>';
Line 4196  sub displaySubByDates { Line 4272  sub displaySubByDates {
   
     my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/)      my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/)
                : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));                 : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));
     #&Apache::lonnet::logthis("match $matchKey $responseId (".$$record{$version.':'.$matchKey});  
     $displaySub[0].='<b>Part:</b>&nbsp;'.$display_part.'&nbsp;';      $displaySub[0].='<b>Part:</b>&nbsp;'.$display_part.'&nbsp;';
     $displaySub[0].='<span class="LC_internal_info">(ID&nbsp;'.      $displaySub[0].='<span class="LC_internal_info">(ID&nbsp;'.
  $responseId.')</span>&nbsp;<b>';   $responseId.')</span>&nbsp;<b>';
Line 4465  the homework problem. Line 4540  the homework problem.
   
 =over 4  =over 4
   
 =cut  
   
   
 =pod   
   
 =item defaultFormData  =item defaultFormData
   
Line 4481  the homework problem. Line 4553  the homework problem.
   
 sub defaultFormData {  sub defaultFormData {
     my ($symb)=@_;      my ($symb)=@_;
     return '      return '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".
       <input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".  
      '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".       '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".
      '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n";       '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n";
 }  }
   
   
 =pod   =pod 
   
 =item getSequenceDropDown  =item getSequenceDropDown
Line 5076  sub scan_data { Line 5148  sub scan_data {
   
      if just_header was not true these key may also exist       if just_header was not true these key may also exist
   
        missingerror - a list of bubbled line numbers that had a blank bubble         missingerror - a list of bubble ranges that are considered to be answers
                       that is considered an error (if the operator had already                        to a single question that don't have any bubbles filled in.
                       okayed a blank bubble line as really being blank then                        Of the form questionnumber:firstbubblenumber:count.
                       that bubble line number won't appear here.         doubleerror  - a list of bubble ranges that are considered to be answers
        doubleerror  - a list of bubbled line numbers that had more than one                        to a single question that have more than one bubble filled in.
                       bubble filled in and has not been corrected by the                        Of the form questionnumber::firstbubblenumber:count
                       operator     
                   In the above, count is the number of bubble responses in the
                   input line needed to represent the possible answers to the question.
                   e.g. a radioresponse with 15 choices in an answer sheet with 10 choices
                   per line would have count = 2.
   
        maxquest     - the number of the last bubble line that was parsed         maxquest     - the number of the last bubble line that was parsed
   
        (<number> starts at 1)         (<number> starts at 1)
Line 5133  sub scantron_parse_scanline { Line 5210  sub scantron_parse_scanline {
   
     my @alphabet=('A'..'Z');      my @alphabet=('A'..'Z');
     my $questnum=0;      my $questnum=0;
       my $ansnum  =1; # Multiple 'answer lines'/question.
   
     while ($questions) {      while ($questions) {
    my $answers_needed = $bubble_lines_per_response{$questnum};
    my $answer_length  = $$scantron_config{'Qlength'} * $answers_needed;
   
   
   
  $questnum++;   $questnum++;
  my $currentquest=substr($questions,0,$$scantron_config{'Qlength'});   my $currentquest = substr($questions,0,$answer_length);
  substr($questions,0,$$scantron_config{'Qlength'})='';   $questions       = substr($questions,0,$answer_length)='';
  if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }   if (length($currentquest) < $answer_length) { next; }
   
    # Qon letter implies for each slot in currentquest we have:
    #    ? or * for doubles a letter in A-Z for a bubble and
           #    about anything else (esp. a value of Qoff for missing
    #    bubbles.
   
   
  if ($$scantron_config{'Qon'} eq 'letter') {   if ($$scantron_config{'Qon'} eq 'letter') {
     if ($currentquest eq '?'  
  || $currentquest eq '*') {      if ($currentquest =~ /\?/
    || $currentquest =~ /\*/
    || (&occurence_count($currentquest, "[A-Z]") > 1)) {
  push(@{$record{'scantron.doubleerror'}},$questnum);   push(@{$record{'scantron.doubleerror'}},$questnum);
  $record{"scantron.$questnum.answer"}='';   for (my $ans = 0; $ans < $answers_needed; $ans++) { 
       $record{"scantron.$ansnum.answer"}='';
       $ansnum++;
    }
   
     } elsif (!defined($currentquest)      } elsif (!defined($currentquest)
      || $currentquest eq $$scantron_config{'Qoff'}       || (&occurence_count($currentquest, $$scantron_config{'Qoff'}) == length($currentquest))
      || $currentquest !~ /^[A-Z]$/) {       || (&occurence_count($currentquest, "[A-Z]") == 0)) {
  $record{"scantron.$questnum.answer"}='';   for (my $ans = 0; $ans < $answers_needed; $ans++ ) {
       $record{"scantron.$ansnum.answer"}='';
       $ansnum++;
   
    }
  if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {   if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
     push(@{$record{"scantron.missingerror"}},$questnum);      push(@{$record{"scantron.missingerror"}},$questnum);
       $ansnum += $answers_needed;
  }   }
   
     } else {      } else {
  $record{"scantron.$questnum.answer"}=$currentquest;   for (my $ans = 0; $ans < $answers_needed; $ans++) {
       $record{"scantron.$ansnum.answer"} = substr($currentquest, $ans, 1);
       $ansnum++;
    }
     }      }
   
    # Qon 'number' implies each slot gives a digit that indexes the
    #    the bubbles filled or Qoff or a non number for unbubbled lines.
           #    and *? for double bubbles on a line.
    #    these answers are also stored as letters.
   
  } elsif ($$scantron_config{'Qon'} eq 'number') {   } elsif ($$scantron_config{'Qon'} eq 'number') {
     if ($currentquest eq '?'      if ($currentquest =~ /\?/
  || $currentquest eq '*') {   || $currentquest =~ /\*/
    || (&occurence_count($currentquest, '\d') > 1)) {
  push(@{$record{'scantron.doubleerror'}},$questnum);   push(@{$record{'scantron.doubleerror'}},$questnum);
  $record{"scantron.$questnum.answer"}='';   for (my $ans = 0; $ans < $answers_needed; $ans++) {
       $record{"scantron.$ansnum.answer"}='';
       $ansnum++;
    }
   
     } elsif (!defined($currentquest)      } elsif (!defined($currentquest)
      || $currentquest eq $$scantron_config{'Qoff'}        || (&occurence_count($currentquest,$$scantron_config{'Qoff'}) == length($currentquest)) 
      || $currentquest !~ /^\d$/) {       || (&occurence_count($currentquest, '\d') == 0)) {
  $record{"scantron.$questnum.answer"}='';   for (my $ans = 0; $ans < $answers_needed; $ans++ ) {
       $record{"scantron.$ansnum.answer"}='';
       $ansnum++;
   
    }
  if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {   if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
     push(@{$record{"scantron.missingerror"}},$questnum);      push(@{$record{"scantron.missingerror"}},$questnum);
       $ansnum += $answers_needed;
  }   }
   
     } else {      } else {
  # wrap zero back to J   $currentquest = &digits_to_letters($currentquest);
  if ($currentquest eq '0') {   for (my $ans =0; $ans < $answers_needed; $ans++) {
     $record{"scantron.$questnum.answer"}=      $record{"scantron.$ansnum.answer"} = substr($currentquest, $ans, 1);
  $alphabet[9];      $ansnum++;
  } else {  
     $record{"scantron.$questnum.answer"}=  
  $alphabet[$currentquest-1];  
  }   }
     }      }
  } else {   } else {
   
       # Otherwise there's a positional notation;
       # each bubble line requires Qlength items, and there are filled in
       # bubbles for each case where there 'Qon' characters.
       #
   
     my @array=split($$scantron_config{'Qon'},$currentquest,-1);      my @array=split($$scantron_config{'Qon'},$currentquest,-1);
     if (length($array[0]) eq $$scantron_config{'Qlength'}) {  
  $record{"scantron.$questnum.answer"}='';      # If the split only  giveas us one element.. the full length of the
       # answser string, no bubbles are filled in:
   
       if (length($array[0]) eq $$scantron_config{'Qlength'}*$answers_needed) {
    for (my $ans = 0; $ans < $answers_needed; $ans++ ) {
       $record{"scantron.$ansnum.answer"}='';
       $ansnum++;
   
    }
  if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {   if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
     push(@{$record{"scantron.missingerror"}},$questnum);      push(@{$record{"scantron.missingerror"}},$questnum);
  }   }
     } else {      } elsif (scalar(@array) lt 2) {
  $record{"scantron.$questnum.answer"}=  
     $alphabet[length($array[0])];   my $location      = [length($array[0])];
    my $line_num      = $location / $$scantron_config{'Qlength'};
    my $bubble        = $alphabet[$location % $$scantron_config{'Qlength'}];
   
    for (my $ans = 0; $ans < $answers_needed; $ans++) {
       if ($ans eq $line_num) {
    $record{"scantron.$ansnum.answer"} = $bubble;
       } else {
    $record{"scantron.$ansnum.answer"} = ' ';
       }
       $ansnum++;
    }
     }      }
     if (scalar(@array) gt 2) {      #  If there's more than one instance of a bubble character
       #  That's a double bubble; with positional notation we can
       #  record all the bubbles filled in as well as the 
       #  fact this response consists of multiple bubbles.
       #
       else {
  push(@{$record{'scantron.doubleerror'}},$questnum);   push(@{$record{'scantron.doubleerror'}},$questnum);
   
    my $first_answer = $ansnum;
    for (my $ans =0; $ans < $answers_needed; $ans++) {
       $record{"scantron.$ansnum.answer"} = '';
       $ans++;
    }
   
  my @ans=@array;   my @ans=@array;
  my $i=length($ans[0]);shift(@ans);   my $i=length($ans[0]);shift(@ans);
  while ($#ans) {   while ($#ans) {
     $i+=length($ans[0])+1;      $i+=length($ans[0])+1;
     $record{"scantron.$questnum.answer"}.=$alphabet[$i];      my $line   = $i/$$scantron_config{'Qlength'} + $first_answer;
       my $bubble = $i%$$scantron_config{'Qlength'};
   
       $record{"scantron.$line.answer"}.=$alphabet[$bubble];
     shift(@ans);      shift(@ans);
  }   }
     }      }
Line 5551  sub scantron_form_start { Line 5711  sub scantron_form_start {
   <input type="hidden" name="scantron_options_ignore" value="$env{'form.scantron_options_ignore'}" />    <input type="hidden" name="scantron_options_ignore" value="$env{'form.scantron_options_ignore'}" />
   <input type="hidden" name="scantron_options_hidden" value="$env{'form.scantron_options_hidden'}" />    <input type="hidden" name="scantron_options_hidden" value="$env{'form.scantron_options_hidden'}" />
 SCANTRONFORM  SCANTRONFORM
   
     my $line = 0;
       while (defined($env{"form.scantron.bubblelines.$line"})) {
          my $chunk =
      '<input type="hidden" name="scantron.bubblelines.'.$line.'" value="'.$env{"form.scantron.bubblelines.$line"}.'" />'."\n";
          $chunk +=
      '<input type="hidden" name="scantron.first_bubble_line.'.$line'." value="'.$env{"form.scantron.first_bubble_line.$line"}.'" />'."\n";
          $result .= $chunk;
          $line++;
      }
     return $result;      return $result;
 }  }
   
Line 6032  sub scantron_validate_ID { Line 6202  sub scantron_validate_ID {
     #get scantron line setup      #get scantron line setup
     my %scantron_config=&get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
     my ($scanlines,$scan_data)=&scantron_getfile();      my ($scanlines,$scan_data)=&scantron_getfile();
       
       &scantron_get_maxbubble(); # parse needs the bubble_lines.. array.
   
     my %found=('ids'=>{},'usernames'=>{});      my %found=('ids'=>{},'usernames'=>{});
     for (my $i=0;$i<=$scanlines->{'count'};$i++) {      for (my $i=0;$i<=$scanlines->{'count'};$i++) {
Line 6216  ENDSCRIPT Line 6388  ENDSCRIPT
  $r->print($message);   $r->print($message);
  $r->print("<p>Please indicate which bubble should be used for grading</p>");   $r->print("<p>Please indicate which bubble should be used for grading</p>");
  foreach my $question (@{$arg}) {   foreach my $question (@{$arg}) {
     my $selected=$$scan_record{"scantron.$question.answer"};  
       my $selected  = &get_response_bubbles($scan_record, $question);
     &scantron_bubble_selector($r,$scan_config,$question,      &scantron_bubble_selector($r,$scan_config,$question,
       split('',$selected));        split('',$selected));
  }   }
Line 6228  ENDSCRIPT Line 6401  ENDSCRIPT
  $r->print('<input type="hidden" name="scantron_questions" value="'.   $r->print('<input type="hidden" name="scantron_questions" value="'.
   join(',',@{$arg}).'" />');    join(',',@{$arg}).'" />');
  foreach my $question (@{$arg}) {   foreach my $question (@{$arg}) {
     my $selected=$$scan_record{"scantron.$question.answer"};      my $selected = &get_response_bubbles($scan_record, $quesion);
     &scantron_bubble_selector($r,$scan_config,$question);      &scantron_bubble_selector($r,$scan_config,$question);
  }   }
     } else {      } else {
Line 6250  ENDSCRIPT Line 6423  ENDSCRIPT
     $scan_config - hash from &get_scantron_config()      $scan_config - hash from &get_scantron_config()
     $quest       - number of the bubble line to make a corrector for      $quest       - number of the bubble line to make a corrector for
     $selected    - array of letters of previously selected bubbles      $selected    - array of letters of previously selected bubbles
     $lines       - if present, number of bubble lines to show  
   
 =cut  =cut
   
 sub scantron_bubble_selector {  sub scantron_bubble_selector {
     my ($r,$scan_config,$quest,@selected, $lines)=@_;      my ($r,$scan_config,$quest,@selected)=@_;
     my $max=$$scan_config{'Qlength'};      my $max=$$scan_config{'Qlength'};
   
     my $scmode=$$scan_config{'Qon'};      my $scmode=$$scan_config{'Qon'};
   
   
     if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }           if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }     
   
   
     if (!defined($lines)) {      my $lines = $bubble_lines_per_response{$quest};
  $lines = 1;  
     }  
     my $total_lines = $lines*2;      my $total_lines = $lines*2;
     my @alphabet=('A'..'Z');      my @alphabet=('A'..'Z');
     $r->print("<table border='1'><tr><td rowspan='".$total_lines."'>$quest</td>");      $r->print("<table border='1'><tr><td rowspan='".$total_lines."'>$quest</td>");
Line 6438  sub scantron_validate_CODE { Line 6611  sub scantron_validate_CODE {
   
     my %allcodes=&get_codes();      my %allcodes=&get_codes();
   
       &scantron_get_maxbubble(); # parse needs the lines per response array.
   
     my ($scanlines,$scan_data)=&scantron_getfile();      my ($scanlines,$scan_data)=&scantron_getfile();
     for (my $i=0;$i<=$scanlines->{'count'};$i++) {      for (my $i=0;$i<=$scanlines->{'count'};$i++) {
  my $line=&scantron_get_line($scanlines,$scan_data,$i);   my $line=&scantron_get_line($scanlines,$scan_data,$i);
Line 6490  sub scantron_validate_doublebubble { Line 6665  sub scantron_validate_doublebubble {
     #get scantron line setup      #get scantron line setup
     my %scantron_config=&get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
     my ($scanlines,$scan_data)=&scantron_getfile();      my ($scanlines,$scan_data)=&scantron_getfile();
   
       &scantron_get_maxbubble(); # parse needs the bubble line array.
   
     for (my $i=0;$i<=$scanlines->{'count'};$i++) {      for (my $i=0;$i<=$scanlines->{'count'};$i++) {
  my $line=&scantron_get_line($scanlines,$scan_data,$i);   my $line=&scantron_get_line($scanlines,$scan_data,$i);
  if ($line=~/^[\s\cz]*$/) { next; }   if ($line=~/^[\s\cz]*$/) { next; }
Line 6513  sub scantron_validate_doublebubble { Line 6691  sub scantron_validate_doublebubble {
    resource and then checking &Apache::lonxml::get_problem_counter()     resource and then checking &Apache::lonxml::get_problem_counter()
    for what the current value of the problem counter is.     for what the current value of the problem counter is.
   
    Caches the result to $env{'form.scantron_maxbubble'}     Caches the results to $env{'form.scantron_maxbubble'},
      $env{'form.scantron.bubble_lines.n'} and 
      $env{'form.scantron.first_bubble_line.n'}
      which are the total number of bubble, lines, the number of bubble
      lines for reponse n and number of the first bubble line for response n.
   
 =cut  =cut
   
Line 6521  sub scantron_get_maxbubble { Line 6703  sub scantron_get_maxbubble {
   
     if (defined($env{'form.scantron_maxbubble'}) &&      if (defined($env{'form.scantron_maxbubble'}) &&
  $env{'form.scantron_maxbubble'}) {   $env{'form.scantron_maxbubble'}) {
    &restore_bubble_lines();
  return $env{'form.scantron_maxbubble'};   return $env{'form.scantron_maxbubble'};
     }      }
   
     my $navmap=Apache::lonnavmaps::navmap->new();      my (undef, undef, $sequence) =
     my (undef,undef,$sequence)=  
  &Apache::lonnet::decode_symb($env{'form.selectpage'});   &Apache::lonnet::decode_symb($env{'form.selectpage'});
   
       my $navmap=Apache::lonnavmaps::navmap->new();
     my $map=$navmap->getResourceByUrl($sequence);      my $map=$navmap->getResourceByUrl($sequence);
     my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);      my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
   
Line 6538  sub scantron_get_maxbubble { Line 6721  sub scantron_get_maxbubble {
     my $cid         = $env{'request.course.id'};      my $cid         = $env{'request.course.id'};
     my $total_lines = 0;      my $total_lines = 0;
     %bubble_lines_per_response = ();      %bubble_lines_per_response = ();
       %first_bubble_line         = ();
   
     
       my $response_number = 0;
       my $bubble_line     = 0;
     foreach my $resource (@resources) {      foreach my $resource (@resources) {
  my $symb = $resource->symb();   my $symb = $resource->symb();
    &Apache::lonxml::clear_bubble_lines_for_part();
  my $result=&Apache::lonnet::ssi($resource->src(),   my $result=&Apache::lonnet::ssi($resource->src(),
  ('symb' => $resource->symb()),   ('symb' => $resource->symb()),
  ('grade_target' => 'analyze'),   ('grade_target' => 'analyze'),
Line 6555  sub scantron_get_maxbubble { Line 6743  sub scantron_get_maxbubble {
   
   
  foreach my $part_id (@{$analysis{'parts'}}) {   foreach my $part_id (@{$analysis{'parts'}}) {
     my $bubble_lines = $analysis{"$part_id.bubble_lines"}[0];      my ($trash, $part) = split(/\./, $part_id);
     if (!$bubble_lines) {  
  $bubble_lines = 1;      my $lines = $analysis{"$part_id.bubble_lines"}[0];
     }  
     $bubble_lines_per_response{"$symb.$part_id"} = $bubble_lines;      # TODO - make this a persistent hash not an array.
     $total_lines = $total_lines + $bubble_lines;  
   
       $first_bubble_line{$response_number}           = $bubble_line;
       $bubble_lines_per_response{$response_number}   = $lines;
       $response_number++;
   
       $bubble_line +=  $lines;
       $total_lines +=  $lines;
  }   }
   
     }      }
     &Apache::lonnet::delenv('scantron\.');      &Apache::lonnet::delenv('scantron\.');
   
       &save_bubble_lines();
     $env{'form.scantron_maxbubble'} =      $env{'form.scantron_maxbubble'} =
  $total_lines;   $total_lines;
     return $env{'form.scantron_maxbubble'};      return $env{'form.scantron_maxbubble'};
Line 6575  sub scantron_get_maxbubble { Line 6772  sub scantron_get_maxbubble {
 =item scantron_validate_missingbubbles  =item scantron_validate_missingbubbles
   
    Validates all scanlines in the selected file to not have any     Validates all scanlines in the selected file to not have any
    bubble lines with missing bubbles that haven't been verified as missing.      answers that don't have bubbles that have not been verified
       to be bubble free.
   
 =cut  =cut
   
Line 6669  SCANTRONFORM Line 6867  SCANTRONFORM
     my $start=&Time::HiRes::time();      my $start=&Time::HiRes::time();
     my $i=-1;      my $i=-1;
     my ($uname,$udom,$started);      my ($uname,$udom,$started);
   
       &scantron_get_maxbubble(); # Need the bubble lines array to parse.
   
     while ($i<$scanlines->{'count'}) {      while ($i<$scanlines->{'count'}) {
   ($uname,$udom)=('','');    ($uname,$udom)=('','');
   $i++;    $i++;
Line 6719  SCANTRONFORM Line 6920  SCANTRONFORM
     }      }
     my $result=&Apache::lonnet::ssi($resource->src(),%form);      my $result=&Apache::lonnet::ssi($resource->src(),%form);
     if ($result ne '') {      if ($result ne '') {
  &Apache::lonnet::logthis("scantron grading error -> $result");  
  &Apache::lonnet::logthis("scantron grading error info name $uname domain $udom course $env{'request.course.id'} url ".$resource->src());  
     }      }
     if (&Apache::loncommon::connection_aborted($r)) { last; }      if (&Apache::loncommon::connection_aborted($r)) { last; }
  }   }
Line 7798  ENDHEADER Line 7997  ENDHEADER
   
 sub handler {  sub handler {
     my $request=$_[0];      my $request=$_[0];
   
     &reset_caches();      &reset_caches();
     if ($env{'browser.mathml'}) {      if ($env{'browser.mathml'}) {
  &Apache::loncommon::content_type($request,'text/xml');   &Apache::loncommon::content_type($request,'text/xml');
Line 7810  sub handler { Line 8010  sub handler {
     my $symb=&get_symb($request,1);      my $symb=&get_symb($request,1);
     my @commands=&Apache::loncommon::get_env_multiple('form.command');      my @commands=&Apache::loncommon::get_env_multiple('form.command');
     my $command=$commands[0];      my $command=$commands[0];
   
     if ($#commands > 0) {      if ($#commands > 0) {
  &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));   &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
     }      }
   
   
     $request->print(&Apache::loncommon::start_page('Grading'));      $request->print(&Apache::loncommon::start_page('Grading'));
     if ($symb eq '' && $command eq '') {      if ($symb eq '' && $command eq '') {
  if ($env{'user.adv'}) {   if ($env{'user.adv'}) {
Line 7890  sub handler { Line 8093  sub handler {
  } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {   } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {
     $request->print(&csvuploadassign($request));      $request->print(&csvuploadassign($request));
  } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {   } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {
       &Apache::lonnet::logthis("Selecting pyhase");
     $request->print(&scantron_selectphase($request));      $request->print(&scantron_selectphase($request));
   } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {    } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {
      $request->print(&scantron_do_warning($request));       $request->print(&scantron_do_warning($request));

Removed from v.1.446  
changed lines
  Added in v.1.447


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