--- loncom/homework/grades.pm 2007/10/04 02:00:29 1.443
+++ loncom/homework/grades.pm 2007/10/09 23:42:49 1.451
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.443 2007/10/04 02:00:29 banghart Exp $
+# $Id: grades.pm,v 1.451 2007/10/09 23:42:49 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -47,11 +47,90 @@ use POSIX qw(floor);
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"
+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 {
+ &Apache::lonnet::logthis("Saving bubble_lines...");
+ foreach my $line (keys(%bubble_lines_per_response)) {
+ &Apache::lonnet::logthis("Saving form.scantron.bubblelines.$line value: $bubble_lines_per_response{$line}");
+ $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"};
+ &Apache::lonnet::logthis("Restoring form.scantron.bubblelines.$line value: $value");
+ $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_lines_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.----
+
+# 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.---
sub getpartlist {
@@ -396,8 +475,9 @@ COMMONJSFUNCTIONS
#--- Dumps the class list with usernames,list of sections,
#--- section, ids and fullnames for each user.
sub getclasslist {
- my ($getsec,$filterlist) = @_;
+ my ($getsec,$filterlist,$getgroup) = @_;
my @getsec;
+ my @getgroup;
my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
if (!ref($getsec)) {
if ($getsec ne '' && $getsec ne 'all') {
@@ -407,10 +487,19 @@ sub getclasslist {
@getsec=@{$getsec};
}
if (grep(/^all$/,@getsec)) { undef(@getsec); }
+ if (!ref($getgroup)) {
+ if ($getgroup ne '' && $getgroup ne 'all') {
+ @getgroup=($getgroup);
+ }
+ } else {
+ @getgroup=@{$getgroup};
+ }
+ if (grep(/^all$/,@getgroup)) { undef(@getgroup); }
- my $classlist=&Apache::loncoursedata::get_classlist();
+ my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
# Bail out if we were unable to get the classlist
return if (! defined($classlist));
+ &Apache::loncoursedata::get_group_memberships($classlist,$keylist);
#
my %sections;
my %fullnames;
@@ -427,18 +516,34 @@ sub getclasslist {
$classlist->{$student}->[&Apache::loncoursedata::CL_FULLNAME()];
my $status =
$classlist->{$student}->[&Apache::loncoursedata::CL_STATUS()];
+ my $group =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];
# filter students according to status selected
if ($filterlist && (!($stu_status =~ /Any/))) {
if (!($stu_status =~ $status)) {
- delete ($classlist->{$student});
+ delete($classlist->{$student});
next;
}
}
+ # filter students according to groups selected
+ if (@getgroup) {
+ my $exclude = 1;
+ foreach my $grp(@getgroup) {
+ if ($group eq $grp) {
+ $exclude = 0;
+ }
+ }
+ if ($exclude) {
+ delete($classlist->{$student});
+ }
+ }
$section = ($section ne '' ? $section : 'none');
if (&canview($section)) {
if (!@getsec || grep(/^\Q$section\E$/,@getsec)) {
$sections{$section}++;
- $fullnames{$student}=$fullname;
+ if ($classlist->{$student}) {
+ $fullnames{$student}=$fullname;
+ }
} else {
delete($classlist->{$student});
}
@@ -531,6 +636,8 @@ sub jscriptNform {
return $jscript;
}
+
+
# 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,
# or quarter if one of those is within the tolerance of .00001.
@@ -687,8 +794,8 @@ sub listStudents {
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
+ my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};
-
my $viewgrade = $env{'form.showgrading'} eq 'yes' ? 'View/Grade/Regrade' : 'View';
$env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?
&Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};
@@ -788,7 +895,7 @@ LISTJAVASCRIPT
'value="Next->" /> '."\n";
$gradeTable.=&check_buttons();
$gradeTable.='';
- my ($classlist, undef, $fullname) = &getclasslist($getsec,'1');
+ my ($classlist, undef, $fullname) = &getclasslist($getsec,'1',$getgroup);
$gradeTable.='
'.
'
';
my $loop = 0;
@@ -1703,7 +1810,6 @@ sub build_section_inputs {
# --------------------------- show submissions of a student, option to grade
sub submission {
my ($request,$counter,$total) = @_;
-
my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'});
$udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student?
my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});
@@ -2789,7 +2895,6 @@ sub version_selected_portfile {
my $new_answer;
$env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stu_name/portfolio$directory$file_name");
if($env{'form.copy'} eq '-1') {
- &Apache::lonnet::logthis('problem getting file '.$file_name);
$new_answer = 'problem getting file';
} else {
$new_answer = $answer_name.'.'.$version.'.'.$answer_ext;
@@ -3823,7 +3928,6 @@ sub csvuploadassign {
}
if (! %grades) { push(@skipped,"$username:$domain no data to save"); }
$grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";
-# &Apache::lonnet::logthis(" storing ".(join('-',%grades)));
my $result=&Apache::lonnet::cstore(\%grades,$symb,
$env{'request.course.id'},
$domain,$username);
@@ -4176,7 +4280,6 @@ sub displaySubByDates {
my $where = ($isTask ? "$version:resource.$interaction"
: "$version:resource");
- #&Apache::lonnet::logthis(" got $where");
$studentTable.='
'.$timestamp.'
';
if ($isCODE) {
$studentTable.='
'.$record->{$version.':resource.CODE'}.'
';
@@ -4196,7 +4299,6 @@ sub displaySubByDates {
my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/)
: ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));
- #&Apache::lonnet::logthis("match $matchKey $responseId (".$$record{$version.':'.$matchKey});
$displaySub[0].='Part: '.$display_part.' ';
$displaySub[0].='(ID '.
$responseId.')';
@@ -4465,11 +4567,8 @@ the homework problem.
=over 4
-=cut
-=pod
-
=item defaultFormData
Returns html hidden inputs used to hold context/default values.
@@ -4481,12 +4580,12 @@ the homework problem.
sub defaultFormData {
my ($symb)=@_;
- return '
- '."\n".
+ return ''."\n".
''."\n".
''."\n";
}
+
=pod
=item getSequenceDropDown
@@ -5076,13 +5175,18 @@ sub scan_data {
if just_header was not true these key may also exist
- missingerror - a list of bubbled line numbers that had a blank bubble
- that is considered an error (if the operator had already
- okayed a blank bubble line as really being blank then
- that bubble line number won't appear here.
- doubleerror - a list of bubbled line numbers that had more than one
- bubble filled in and has not been corrected by the
- operator
+ missingerror - a list of bubble ranges that are considered to be answers
+ to a single question that don't have any bubbles filled in.
+ Of the form questionnumber:firstbubblenumber:count.
+ doubleerror - a list of bubble ranges that are considered to be answers
+ to a single question that have more than one bubble filled in.
+ Of the form questionnumber::firstbubblenumber:count
+
+ 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
( starts at 1)
@@ -5133,66 +5237,149 @@ sub scantron_parse_scanline {
my @alphabet=('A'..'Z');
my $questnum=0;
+ my $ansnum =1; # Multiple 'answer lines'/question.
+
while ($questions) {
+ my $answers_needed = $bubble_lines_per_response{$questnum};
+ my $answer_length = $$scantron_config{'Qlength'} * $answers_needed;
+
+
+
$questnum++;
- my $currentquest=substr($questions,0,$$scantron_config{'Qlength'});
- substr($questions,0,$$scantron_config{'Qlength'})='';
- if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
+ my $currentquest = substr($questions,0,$answer_length);
+ $questions = substr($questions,0,$answer_length)='';
+ 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 ($currentquest eq '?'
- || $currentquest eq '*') {
+
+ if ($currentquest =~ /\?/
+ || $currentquest =~ /\*/
+ || (&occurence_count($currentquest, "[A-Z]") > 1)) {
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)
- || $currentquest eq $$scantron_config{'Qoff'}
- || $currentquest !~ /^[A-Z]$/) {
- $record{"scantron.$questnum.answer"}='';
+ || (&occurence_count($currentquest, $$scantron_config{'Qoff'}) == length($currentquest))
+ || (&occurence_count($currentquest, "[A-Z]") == 0)) {
+ for (my $ans = 0; $ans < $answers_needed; $ans++ ) {
+ $record{"scantron.$ansnum.answer"}='';
+ $ansnum++;
+
+ }
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
+ $ansnum += $answers_needed;
}
+
} 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') {
- if ($currentquest eq '?'
- || $currentquest eq '*') {
+ if ($currentquest =~ /\?/
+ || $currentquest =~ /\*/
+ || (&occurence_count($currentquest, '\d') > 1)) {
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)
- || $currentquest eq $$scantron_config{'Qoff'}
- || $currentquest !~ /^\d$/) {
- $record{"scantron.$questnum.answer"}='';
+ || (&occurence_count($currentquest,$$scantron_config{'Qoff'}) == length($currentquest))
+ || (&occurence_count($currentquest, '\d') == 0)) {
+ for (my $ans = 0; $ans < $answers_needed; $ans++ ) {
+ $record{"scantron.$ansnum.answer"}='';
+ $ansnum++;
+
+ }
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
+ $ansnum += $answers_needed;
}
+
} else {
- # wrap zero back to J
- if ($currentquest eq '0') {
- $record{"scantron.$questnum.answer"}=
- $alphabet[9];
- } else {
- $record{"scantron.$questnum.answer"}=
- $alphabet[$currentquest-1];
+ $currentquest = &digits_to_letters($currentquest);
+ for (my $ans =0; $ans < $answers_needed; $ans++) {
+ $record{"scantron.$ansnum.answer"} = substr($currentquest, $ans, 1);
+ $ansnum++;
}
}
} 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);
- 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")) {
push(@{$record{"scantron.missingerror"}},$questnum);
}
- } else {
- $record{"scantron.$questnum.answer"}=
- $alphabet[length($array[0])];
+ } elsif (scalar(@array) lt 2) {
+
+ 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);
+
+ my $first_answer = $ansnum;
+ for (my $ans =0; $ans < $answers_needed; $ans++) {
+ $record{"scantron.$ansnum.answer"} = '';
+ $ans++;
+ }
+
my @ans=@array;
my $i=length($ans[0]);shift(@ans);
while ($#ans) {
$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);
}
}
@@ -5551,6 +5738,17 @@ sub scantron_form_start {
SCANTRONFORM
+
+ my $line = 0;
+ while (defined($env{"form.scantron.bubblelines.$line"})) {
+ &Apache::lonnet::logthis("Saving chunk for $line");
+ my $chunk =
+ ''."\n";
+ $chunk .=
+ ''."\n";
+ $result .= $chunk;
+ $line++;
+ }
return $result;
}
@@ -5609,6 +5807,8 @@ sub scantron_validate_file {
}
my $currentphase=$env{'form.validatepass'};
+ &Apache::lonnet::logthis("Phase: $currentphase");
+
my $stop=0;
while (!$stop && $currentphase < scalar(@validate_phases)) {
$r->print("
Validating ".$validate_phases[$currentphase]."
");
@@ -6032,6 +6232,8 @@ sub scantron_validate_ID {
#get scantron line setup
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
+
+ &scantron_get_maxbubble(); # parse needs the bubble_lines.. array.
my %found=('ids'=>{},'usernames'=>{});
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
@@ -6216,7 +6418,8 @@ ENDSCRIPT
$r->print($message);
$r->print("
Please indicate which bubble should be used for grading
");
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,
split('',$selected));
}
@@ -6228,7 +6431,7 @@ ENDSCRIPT
$r->print('');
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);
}
} else {
@@ -6250,21 +6453,22 @@ ENDSCRIPT
$scan_config - hash from &get_scantron_config()
$quest - number of the bubble line to make a corrector for
$selected - array of letters of previously selected bubbles
- $lines - if present, number of bubble lines to show
=cut
sub scantron_bubble_selector {
- my ($r,$scan_config,$quest,@selected, $lines)=@_;
+ my ($r,$scan_config,$quest,@selected)=@_;
my $max=$$scan_config{'Qlength'};
my $scmode=$$scan_config{'Qon'};
+
+
if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+ my $response = $quest-1;
+ my $lines = $bubble_lines_per_response{$response};
+ &Apache::lonnet::logthis("Question $quest, lines: $lines");
- if (!defined($lines)) {
- $lines = 1;
- }
my $total_lines = $lines*2;
my @alphabet=('A'..'Z');
$r->print("
$quest
");
@@ -6438,6 +6642,8 @@ sub scantron_validate_CODE {
my %allcodes=&get_codes();
+ &scantron_get_maxbubble(); # parse needs the lines per response array.
+
my ($scanlines,$scan_data)=&scantron_getfile();
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
my $line=&scantron_get_line($scanlines,$scan_data,$i);
@@ -6490,6 +6696,9 @@ sub scantron_validate_doublebubble {
#get scantron line setup
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
+
+ &scantron_get_maxbubble(); # parse needs the bubble line array.
+
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
my $line=&scantron_get_line($scanlines,$scan_data,$i);
if ($line=~/^[\s\cz]*$/) { next; }
@@ -6513,21 +6722,28 @@ sub scantron_validate_doublebubble {
resource and then checking &Apache::lonxml::get_problem_counter()
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
sub scantron_get_maxbubble {
-
+ &Apache::lonnet::logthis("get_max_bubble");
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
+ &Apache::lonnet::logthis("cached");
+ &restore_bubble_lines();
return $env{'form.scantron_maxbubble'};
}
+ &Apache::lonnet::logthis("computing");
- my $navmap=Apache::lonnavmaps::navmap->new();
- my (undef,undef,$sequence)=
+ my (undef, undef, $sequence) =
&Apache::lonnet::decode_symb($env{'form.selectpage'});
+ my $navmap=Apache::lonnavmaps::navmap->new();
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
@@ -6538,9 +6754,14 @@ sub scantron_get_maxbubble {
my $cid = $env{'request.course.id'};
my $total_lines = 0;
%bubble_lines_per_response = ();
+ %first_bubble_line = ();
+
+ my $response_number = 0;
+ my $bubble_line = 0;
foreach my $resource (@resources) {
my $symb = $resource->symb();
+ &Apache::lonxml::clear_bubble_lines_for_part();
my $result=&Apache::lonnet::ssi($resource->src(),
('symb' => $resource->symb()),
('grade_target' => 'analyze'),
@@ -6555,16 +6776,25 @@ sub scantron_get_maxbubble {
foreach my $part_id (@{$analysis{'parts'}}) {
- my $bubble_lines = $analysis{"$part_id.bubble_lines"}[0];
- if (!$bubble_lines) {
- $bubble_lines = 1;
- }
- $bubble_lines_per_response{"$symb.$part_id"} = $bubble_lines;
- $total_lines = $total_lines + $bubble_lines;
+ my ($trash, $part) = split(/\./, $part_id);
+
+ my $lines = $analysis{"$part_id.bubble_lines"}[0];
+
+ # TODO - make this a persistent hash not an array.
+
+
+ $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\.');
+
+ &save_bubble_lines();
$env{'form.scantron_maxbubble'} =
$total_lines;
return $env{'form.scantron_maxbubble'};
@@ -6575,7 +6805,8 @@ sub scantron_get_maxbubble {
=item scantron_validate_missingbubbles
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
@@ -6669,6 +6900,9 @@ SCANTRONFORM
my $start=&Time::HiRes::time();
my $i=-1;
my ($uname,$udom,$started);
+
+ &scantron_get_maxbubble(); # Need the bubble lines array to parse.
+
while ($i<$scanlines->{'count'}) {
($uname,$udom)=('','');
$i++;
@@ -6719,8 +6953,6 @@ SCANTRONFORM
}
my $result=&Apache::lonnet::ssi($resource->src(),%form);
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; }
}
@@ -6954,7 +7186,9 @@ sub grading_menu {
#
# Define menu data
-
+ $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb);
+ my ($table) = &showResourceInfo($symb,$env{'form.probTitle'});
+ $request->print($table);
my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb),
'handgrade'=>$hdgrade,
'probTitle'=>$probTitle,
@@ -6988,7 +7222,8 @@ sub grading_menu {
&mt('')});
$fields{'command'} = 'verify';
$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
- push (@menu, { url => $url,
+ push (@menu, { url => "",
+ jscript => ' onClick="javascript:checkChoice2(document.forms.gradingMenu,\'5\',\'verify\')" ',
name => &mt('Verify Receipt'),
short_description =>
&mt('')});
@@ -7008,16 +7243,37 @@ sub grading_menu {
#
# Create the menu
my $Str;
- $Str .= '
'.&mt('Please select a grading task').'
';
+ # $Str .= '
'.&mt('Please select a grading task').'
';
+ $Str .= '\n";
$request->print(<
function checkChoice(formname,val,cmdx) {
@@ -7038,6 +7294,22 @@ sub grading_menu {
}
if (val < 7) formname.submit();
}
+ function checkChoice2(formname,val,cmdx) {
+ if (val <= 2) {
+ var cmd = radioSelection(formname.radioChoice);
+ var cmdsave = cmd;
+ } else {
+ cmd = cmdx;
+ cmdsave = 'submission';
+ }
+ formname.command.value = cmd;
+ if (val < 5) formname.submit();
+ if (val == 5) {
+ if (!checkReceiptNo(formname,'notOK')) { return false;}
+ formname.submit();
+ }
+ if (val < 7) formname.submit();
+ }
function checkReceiptNo(formname,nospace) {
var receiptNo = formname.receipt.value;
@@ -7159,15 +7431,15 @@ GRADINGMENUJS
''."\n".
''."\n";
- $result.='