function updateRadio(formname,id,weight) {
@@ -1695,7 +1656,7 @@ sub gradeBox {
$wgt.')" />'."\n";
$line.='/'.$wgt.' '.$wgtmsg.
($$record{'resource.'.$partid.'.solved'} eq 'correct_by_student' ? ' '.$checkIcon : '').
- ' '.&mt('Grade Status').': '."\n";
+ ' '."\n";
$line.=''."\n";
if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
@@ -1709,7 +1670,8 @@ sub gradeBox {
$result .=
- ''.&mt('Part').': '.$display_part.' '.&mt('Points').': '.$radio.' '.&mt('or').' '.$line.' ';
+ &mt('Part: [_1] Points: [_2] or [_3] ',$display_part,$radio,$line);
+
$result.=''."\n";
$result.=' '."\n".
@@ -2132,7 +2094,7 @@ KEYWORDS
' ) ';
my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
if (@$files) {
- $lastsubonly.=''.&mt('Like all files provided by users, this file may contain viruses').' ';
+ $lastsubonly.=''.&mt('Like all files provided by users, this file may contain virusses').' ';
my $file_counter = 0;
foreach my $file (@$files) {
$file_counter++;
@@ -2143,7 +2105,7 @@ KEYWORDS
}
$lastsubonly.=''.&mt('Submitted Answer:').' '.
&cleanRecord($subval,$responsetype,$symb,$partid,
- $respid,\%record,$order,undef,$uname,$udom);
+ $respid,\%record,$order);
if ($similar) {$lastsubonly.=" $similar\n";}
$lastsubonly.='';
}
@@ -2272,7 +2234,7 @@ KEYWORDS
'7 10 '."\n";
my $nsel = ($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : '1');
$ntstu =~ s/$nsel $nsel;
- $endform.=&mt('[quant,_1,student]',$ntstu);
+ $endform.=&mt('[_1]student(s)',$ntstu);
$endform.=' '."\n".
' Nothing submitted - no attempts.';
+ ''.&mt('Nothing submitted - no attempts.').' ';
}
return (\@string,\$timestamp);
}
@@ -3211,19 +3173,19 @@ sub viewgrades {
' '."\n".
' '."\n";
- my ($common_header,$specific_header);
+ my $sectionClass;
+ my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
if ($env{'form.section'} eq 'all') {
- $common_header = &mt('Assign Common Grade to Class');
- $specific_header = &mt('Assign Grade to Specific Students in Class');
+ $sectionClass=&mt('Class');
} elsif ($env{'form.section'} eq 'none') {
- $common_header = &mt('Assign Common Grade to Students in no Section');
- $specific_header = &mt('Assign Grade to Specific Students in no Section');
+ $sectionClass=&mt('Students in no Section');
} else {
- my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
- $common_header = &mt('Assign Common Grade to Students in Section(s) [_1]',$section_display);
- $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display);
+ $sectionClass=&mt('Students in Section(s) [_1]');
}
- $result.= ''.$common_header.' '.&Apache::loncommon::start_data_table();
+ $result.=
+ ''.
+ &mt("Assign Common Grade to [_1]",$sectionClass,$section_display).' ';
+ $result.= &Apache::loncommon::start_data_table();
#radio buttons/text box for assigning points for a section or class.
#handles different parts of a problem
my ($partlist,$handgrade,$responseType) = &response_type($symb);
@@ -3268,9 +3230,10 @@ sub viewgrades {
$line.=' '."\n";
+ #&mt('Part: [_1] Points: [_2] or [_3] ',$display_part,$radio,$line).
$result.=
&Apache::loncommon::start_data_table_row()."\n".
- ''.&mt('Part').': '.$display_part.' '.&mt('Points').': '.$radio.' '.&mt('or').' '.$line.' '.
+ ''.&mt('Part').': '.$display_part.' '.&mt('Points').': '.$radio.' '.&mt('or').' '.$line.' '.
&Apache::loncommon::end_data_table_row()."\n";
$ctsparts++;
}
@@ -3281,32 +3244,33 @@ sub viewgrades {
#table listing all the students in a section/class
#header of table
- $result.= ''.$specific_header.' '.
- &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row().
- ''.&mt('No.').' '.
- ''.&nameUserString('header')." \n";
+ $result.= ''.&mt('Assign Grade to Specific Students in ').$sectionClass,
+ $section_display.' ';
+ $result.= &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('No.').' '.
+ ''.&nameUserString('header')." \n";
my (@parts) = sort(&getpartlist($symb));
my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
my @partids = ();
foreach my $part (@parts) {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
- my $narrowtext = &mt('Tries').' ';
- $display =~ s{^Number of Attempts}{$narrowtext}; # makes the column narrower
+ my $narrowtext = &mt('Tries');
+ $display =~ s|^Number of Attempts|$narrowtext |; # makes the column narrower
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
my ($partid) = &split_part_type($part);
push(@partids,$partid);
my $display_part=&get_display_part($partid,$symb);
if ($display =~ /^Partial Credit Factor/) {
$result.=''.
- &mt('Score Part: [_1] (weight = [_2])',
- $display_part.' ',$weight{$partid}).' '."\n";
+ &mt('Score Part: [_1] (weight = [_2])',
+ $display_part,$weight{$partid}).''."\n";
next;
} else {
if ($display =~ /Problem Status/) {
- my $grade_status_mt = &mt('Grade Status').' ';
- $display =~ s{Problem Status}{$grade_status_mt};
+ my $grade_status_mt = &mt('Grade Status');
+ $display =~ s{Problem Status}{$grade_status_mt };
}
my $part_mt = &mt('Part:');
$display =~s{\[Part: \Q$partid\E\]}{$part_mt $display_part};
@@ -3463,9 +3427,9 @@ sub editgrades {
if ($part !~ m/^\Q$partid\E/) { next;}
if ($type eq 'awarded' || $type eq 'solved') { next; }
my $display=&Apache::lonnet::metadata($url,$stores.'.display');
- $display =~ s/\[Part: \Q$part\E\]//;
+ $display =~ s/\[Part: (\w)+\]//;
my $narrowtext = &mt('Tries');
- $display =~ s{Number of Attempts}{$narrowtext};
+ $display =~ s/Number of Attempts/$narrowtext/;
$header .= ''.&mt('Old').' '.$display.' '.
''.&mt('New').' '.$display.' ';
$columns{$partid}+=2;
@@ -3835,7 +3799,7 @@ sub upcsvScores_form {
$result.=''."\n";
$result.=''."\n";
$result.=' '.&mt('Specify a file containing the class scores for current resource.').
- '. '."\n";
+ ''."\n";
$result.=''."\n";
my $upload=&mt("Upload Scores");
my $upfile_select=&Apache::loncommon::upfile_select_html();
@@ -4129,7 +4093,7 @@ LISTJAVASCRIPT
$ctr++;
}
$select.= '';
- $result.=' '.&mt('Problems from').": $select \n";
+ $result.=' '.&mt('Problems from').': '.$select." \n";
$ctr=0;
foreach (@$titles) {
@@ -4144,13 +4108,13 @@ LISTJAVASCRIPT
my $options =
' '.&mt('no').' '."\n".
' '.&mt('yes').' '." \n";
- $result.=' '.&mt('View Problem Text').": $options";
+ $result.=' '.&mt('View Problem Text').': '.$options;
$options =
' '.&mt('none').' '."\n".
' '.&mt('by dates and submissions').' '."\n".
' '.&mt('all details').' '."\n";
- $result.=' >b>'.&mt('Submissions').": $options";
+ $result.=' '.&mt('Submissions').': '.$options;
$result.=&build_section_inputs();
my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
@@ -4159,7 +4123,7 @@ LISTJAVASCRIPT
' '."\n".
' '." \n";
- $result.=' '.&mt('Use CODE').': '."\n";
+ $result.=' '.&mt('Use CODE').': '."\n";
$result.=' '."\n";
@@ -4201,7 +4165,7 @@ LISTJAVASCRIPT
}
$studentTable.=&Apache::loncommon::end_data_table()."\n";
$studentTable.=' '."\n";
+ 'onClick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' →" />'."\n";
$studentTable.=&show_grading_menu_form($symb);
$request->print($studentTable);
@@ -5524,8 +5488,7 @@ sub scantron_parse_scanline {
my ($line,$whichline,$scantron_config,$scan_data,$just_header)=@_;
my %record;
- my $lastpos = $env{'form.scantron_maxbubble'}*$$scantron_config{'Qlength'};
- my $questions=substr($line,$$scantron_config{'Qstart'}-1,$lastpos); # Answers
+ my $questions=substr($line,$$scantron_config{'Qstart'}-1); # Answers
my $data=substr($line,0,$$scantron_config{'Qstart'}-1); # earlier stuff
if (!($$scantron_config{'CODElocation'} eq 0 ||
$$scantron_config{'CODElocation'} eq 'none')) {
@@ -6214,25 +6177,20 @@ sub scantron_validate_file {
}
}
if (!$stop) {
- my $warning=&scantron_warning_screen('Start Grading');
- $r->print(&mt('Validation process complete.').' '.
- $warning.
- &mt('Perform verification for each student after storage of submissions?').
- ' '.
- ' '.&mt('Yes').' '.
- (' 'x3).''.
- ' '.&mt('No').
- ' '.
- &mt('Grading will take longer if you use verification.').' '. &mt("Alternatively, the 'Review scantron data' utility (see grading menu) can be used for all students after grading is complete.").' '.
- ' '.
- ' '."\n");
+ my $warning=&scantron_warning_screen('Start Grading');
+ $r->print(&mt('Validation process complete.').'
+'.$warning.'
+
+
+');
+
} else {
- $r->print(' ');
- $r->print(" ");
+ $r->print(' ');
+ $r->print(" ");
}
if ($stop) {
if ($validate_phases[$currentphase] eq 'sequence') {
- $r->print(' ');
+ $r->print(' ');
$r->print(' '.&mt('this error').' ');
$r->print(" ".&mt("Or click the 'Grading Menu' button to start over.")."
");
@@ -6618,14 +6576,7 @@ sub scantron_validate_sequence {
return (0,$currentphase+1);
}
-=pod
-
-=item scantron_validate_ID
- Validates all scanlines in the selected file to not have any
- invalid or underspecified student IDs
-
-=cut
sub scantron_validate_ID {
my ($r,$currentphase) = @_;
@@ -6691,35 +6642,6 @@ sub scantron_validate_ID {
return (0,$currentphase+1);
}
-=pod
-
-=item scantron_get_correction
-
- Builds the interface screen to interact with the operator to fix a
- specific error condition in a specific scanline
-
- Arguments:
- $r - Apache request object
- $i - number of the current scanline
- $scan_record - hash ref as returned from &scantron_parse_scanline()
- $scan_config - hash ref as returned from &get_scantron_config()
- $line - full contents of the current scanline
- $error - error condition, valid values are
- 'incorrectCODE', 'duplicateCODE',
- 'doublebubble', 'missingbubble',
- 'duplicateID', 'incorrectID'
- $arg - extra information needed
- For errors:
- - duplicateID - paper number that this studentID was seen before on
- - duplicateCODE - array ref of the paper numbers this CODE was
- seen on before
- - incorrectCODE - current incorrect CODE
- - doublebubble - array ref of the bubble lines that have double
- bubble errors
- - missingbubble - array ref of the bubble lines that have missing
- bubble errors
-
-=cut
sub scantron_get_correction {
my ($r,$i,$scan_record,$scan_config,$line,$error,$arg)=@_;
@@ -6833,7 +6755,7 @@ ENDSCRIPT
".&mt("[_1]Select[_2] a CODE from the list of all CODEs and use it.",
""," ")."
- ".&mt('Selected CODE is [_1]',' '));
+ ".&mt("Selected CODE is [_1]"," "));
$r->print("\n ");
}
$r->print("
@@ -7290,25 +7212,6 @@ sub scantron_validate_doublebubble {
return (0,$currentphase+1);
}
-=pod
-
-=item scantron_get_maxbubble
-
- Returns the maximum number of bubble lines that are expected to
- occur. Does this by walking the selected sequence rendering the
- resource and then checking &Apache::lonxml::get_problem_counter()
- for what the current value of the problem counter is.
-
- Caches the results to $env{'form.scantron_maxbubble'},
- $env{'form.scantron.bubble_lines.n'},
- $env{'form.scantron.first_bubble_line.n'} and
- $env{"form.scantron.sub_bubblelines.n"}
- which are the total number of bubble, lines, the number of bubble
- lines for response n and number of the first bubble line for response n,
- and a comma separated list of numbers of bubble lines for sub-questions
- (for optionresponse, matchresponse, and rankresponse items), for response n.
-
-=cut
sub scantron_get_maxbubble {
if (defined($env{'form.scantron_maxbubble'}) &&
@@ -7338,84 +7241,35 @@ sub scantron_get_maxbubble {
my $response_number = 0;
my $bubble_line = 0;
foreach my $resource (@resources) {
- my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom);
- if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
- foreach my $part_id (@{$parts}) {
-
- my $lines;
-
- # TODO - make this a persistent hash not an array.
-
- # optionresponse, matchresponse and rankresponse type items
- # render as separate sub-questions in exam mode.
- if (($analysis->{$part_id.'.type'} eq 'optionresponse') ||
- ($analysis->{$part_id.'.type'} eq 'matchresponse') ||
- ($analysis->{$part_id.'.type'} eq 'rankresponse')) {
- my ($numbub,$numshown);
- if ($analysis->{$part_id.'.type'} eq 'optionresponse') {
- if (ref($analysis->{$part_id.'.options'}) eq 'ARRAY') {
- $numbub = scalar(@{$analysis->{$part_id.'.options'}});
- }
- } elsif ($analysis->{$part_id.'.type'} eq 'matchresponse') {
- if (ref($analysis->{$part_id.'.items'}) eq 'ARRAY') {
- $numbub = scalar(@{$analysis->{$part_id.'.items'}});
- }
- } elsif ($analysis->{$part_id.'.type'} eq 'rankresponse') {
- if (ref($analysis->{$part_id.'.foils'}) eq 'ARRAY') {
- $numbub = scalar(@{$analysis->{$part_id.'.foils'}});
- }
- }
- if (ref($analysis->{$part_id.'.shown'}) eq 'ARRAY') {
- $numshown = scalar(@{$analysis->{$part_id.'.shown'}});
- }
- my $bubbles_per_line = 10;
- my $inner_bubble_lines = int($numbub/$bubbles_per_line);
- if (($numbub % $bubbles_per_line) != 0) {
- $inner_bubble_lines++;
- }
- for (my $i=0; $i<$numshown; $i++) {
- $subdivided_bubble_lines{$response_number} .=
- $inner_bubble_lines.',';
- }
- $subdivided_bubble_lines{$response_number} =~ s/,$//;
- $lines = $numshown * $inner_bubble_lines;
- } else {
- $lines = $analysis->{"$part_id.bubble_lines"};
- }
+ my $symb = $resource->symb();
- $first_bubble_line{$response_number} = $bubble_line;
- $bubble_lines_per_response{$response_number} = $lines;
- $responsetype_per_response{$response_number} =
- $analysis->{$part_id.'.type'};
- $response_number++;
+ my (@parts,@allparts,@possible_parts);
- $bubble_line += $lines;
- $total_lines += $lines;
- }
+ # Need to retrieve part IDs and response IDs because essayresponse,
+ # reactionresponse and organicresponse items are not included in
+ # $analysis{'parts'} from lonnet::ssi.
+ if (ref($resource->parts()) eq 'ARRAY') {
+ foreach my $part (@{$resource->parts()}) {
+ if (!&Apache::loncommon::check_if_partid_hidden($part,$symb,$udom,$uname)) {
+ my @resp_ids = $resource->responseIds($part);
+ foreach my $id (@resp_ids) {
+ my $part_id = $part.'.'.$id;
+ push(@possible_parts,$part_id);
+ }
+ }
+ }
}
- }
- &Apache::lonnet::delenv('scantron.');
-
- &save_bubble_lines();
- $env{'form.scantron_maxbubble'} =
- $total_lines;
- return $env{'form.scantron_maxbubble'};
-}
-sub scantron_partids_tograde {
- my ($resource,$cid,$uname,$udom) = @_;
- my (%analysis,@parts);
-
- if (ref($resource)) {
- my $symb = $resource->symb();
my $result=&ssi_with_retries($resource->src(), $ssi_retries,
('symb' => $symb,
'grade_target' => 'analyze',
'grade_courseid' => $cid,
'grade_domain' => $udom,
'grade_username' => $uname));
- my (undef, $an) = split(/_HASH_REF__/,$result, 2);
- %analysis = &Apache::lonnet::str2hash($an);
+ my (undef, $an) =
+ split(/_HASH_REF__/,$result, 2);
+
+ my %analysis = &Apache::lonnet::str2hash($an);
if (ref($analysis{'parts'}) eq 'ARRAY') {
foreach my $part (@{$analysis{'parts'}}) {
@@ -7425,19 +7279,81 @@ sub scantron_partids_tograde {
}
}
}
- }
- return (\%analysis,\@parts);
-}
+ # Add part_ids for any essayresponse, reactionresponse or
+ # organicresponse items.
+ foreach my $part_id (@possible_parts) {
+ if (grep(/^\Q$part_id\E$/,@parts)) {
+ push(@allparts,$part_id);
+ } else {
+ if (($analysis{$part_id.'.type'} eq 'essayresponse') ||
+ ($analysis{$part_id.'.type'} eq 'reactionresponse') ||
+ ($analysis{$part_id.'.type'} eq 'organicresponse')) {
+ push(@allparts,$part_id);
+ }
+ }
+ }
-=pod
+ foreach my $part_id (@allparts) {
+ my $lines;
-=item scantron_validate_missingbubbles
+ # TODO - make this a persistent hash not an array.
- Validates all scanlines in the selected file to not have any
- answers that don't have bubbles that have not been verified
- to be bubble free.
+ # optionresponse, matchresponse and rankresponse type items
+ # render as separate sub-questions in exam mode.
+ if (($analysis{$part_id.'.type'} eq 'optionresponse') ||
+ ($analysis{$part_id.'.type'} eq 'matchresponse') ||
+ ($analysis{$part_id.'.type'} eq 'rankresponse')) {
+ my ($numbub,$numshown);
+ if ($analysis{$part_id.'.type'} eq 'optionresponse') {
+ if (ref($analysis{$part_id.'.options'}) eq 'ARRAY') {
+ $numbub = scalar(@{$analysis{$part_id.'.options'}});
+ }
+ } elsif ($analysis{$part_id.'.type'} eq 'matchresponse') {
+ if (ref($analysis{$part_id.'.items'}) eq 'ARRAY') {
+ $numbub = scalar(@{$analysis{$part_id.'.items'}});
+ }
+ } elsif ($analysis{$part_id.'.type'} eq 'rankresponse') {
+ if (ref($analysis{$part_id.'.foils'}) eq 'ARRAY') {
+ $numbub = scalar(@{$analysis{$part_id.'.foils'}});
+ }
+ }
+ if (ref($analysis{$part_id.'.shown'}) eq 'ARRAY') {
+ $numshown = scalar(@{$analysis{$part_id.'.shown'}});
+ }
+ my $bubbles_per_line = 10;
+ my $inner_bubble_lines = int($numbub/$bubbles_per_line);
+ if (($numbub % $bubbles_per_line) != 0) {
+ $inner_bubble_lines++;
+ }
+ for (my $i=0; $i<$numshown; $i++) {
+ $subdivided_bubble_lines{$response_number} .=
+ $inner_bubble_lines.',';
+ }
+ $subdivided_bubble_lines{$response_number} =~ s/,$//;
+ $lines = $numshown * $inner_bubble_lines;
+ } else {
+ $lines = $analysis{"$part_id.bubble_lines"};
+ }
+
+ $first_bubble_line{$response_number} = $bubble_line;
+ $bubble_lines_per_response{$response_number} = $lines;
+ $responsetype_per_response{$response_number} =
+ $analysis{$part_id.'.type'};
+ $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'};
+}
-=cut
sub scantron_validate_missingbubbles {
my ($r,$currentphase) = @_;
@@ -7492,29 +7408,6 @@ sub scantron_validate_missingbubbles {
return (0,$currentphase+1);
}
-=pod
-
-=item scantron_process_students
-
- Routine that does the actual grading of the bubble sheet information.
-
- The parsed scanline hash is added to %env
-
- Then foreach unskipped scanline it does an &Apache::lonnet::ssi()
- foreach resource , with the form data of
-
- 'submitted' =>'scantron'
- 'grade_target' =>'grade',
- 'grade_username'=> username of student
- 'grade_domain' => domain of student
- 'grade_courseid'=> of course
- 'grade_symb' => symb of resource to grade
-
- This triggers a grading pass. The problem grading code takes care
- of converting the bubbled letter information (now in %env) into a
- valid submission.
-
-=cut
sub scantron_process_students {
my ($r) = @_;
@@ -7533,14 +7426,6 @@ sub scantron_process_students {
my $navmap=Apache::lonnavmaps::navmap->new();
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
-
- my ($uname,$udom,%partids_by_symb);
- foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
- my ($analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom);
- $partids_by_symb{$ressymb} = $parts;
- }
# $r->print("geto ".scalar(@resources)." ");
my $result= <
@@ -7550,7 +7435,7 @@ SCANTRONFORM
$r->print($result);
my @delayqueue;
- my (%completedstudents,,%scandata);
+ my %completedstudents;
my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam'));
my $count=&get_todo_count($scanlines,$scan_data);
@@ -7559,10 +7444,9 @@ SCANTRONFORM
'inline',undef,'scantronupload');
&Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
'Processing first student');
- $r->print(' ');
my $start=&Time::HiRes::time();
my $i=-1;
- my $started;
+ my ($uname,$udom,$started);
&scantron_get_maxbubble(); # Need the bubble lines array to parse.
@@ -7578,9 +7462,6 @@ SCANTRONFORM
return ''; # Dunno why the other returns return '' rather than just returning.
}
- my %lettdig = &letter_to_digits();
- my $numletts = scalar(keys(%lettdig));
-
while ($i<$scanlines->{'count'}) {
($uname,$udom)=('','');
$i++;
@@ -7612,95 +7493,40 @@ SCANTRONFORM
if (&scantron_clear_skip($scanlines,$scan_data,$i)) {
&scantron_putfile($scanlines,$scan_data);
}
+
+ my $i=0;
+ foreach my $resource (@resources) {
+ $i++;
+ my %form=('submitted' =>'scantron',
+ 'grade_target' =>'grade',
+ 'grade_username'=>$uname,
+ 'grade_domain' =>$udom,
+ 'grade_courseid'=>$env{'request.course.id'},
+ 'grade_symb' =>$resource->symb());
+ if (exists($scan_record->{'scantron.CODE'})
+ &&
+ &Apache::lonnet::validCODE($scan_record->{'scantron.CODE'})) {
+ $form{'CODE'}=$scan_record->{'scantron.CODE'};
+ } else {
+ $form{'CODE'}='';
+ }
+ my $result=&ssi_with_retries($resource->src(), $ssi_retries, %form);
+ if ($ssi_error) {
+ $ssi_error = 0; # So end of handler error message does not trigger.
+ $r->print("");
+ &ssi_print_error($r);
+ $r->print(&show_grading_menu_form($symb));
+ &Apache::lonnet::remove_lock($lock);
+ return ''; # Why return ''? Beats me.
+ }
- my $scancode;
- if ((exists($scan_record->{'scantron.CODE'})) &&
- (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) {
- $scancode = $scan_record->{'scantron.CODE'};
- } else {
- $scancode = '';
- }
-
- if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- @resources) eq 'ssi_error') {
- $ssi_error = 0; # So end of handler error message does not trigger.
- $r->print("");
- &ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
- &Apache::lonnet::remove_lock($lock);
- return ''; # Why return ''? Beats me.
- }
-
+ if (&Apache::loncommon::connection_aborted($r)) { last; }
+ }
$completedstudents{$uname}={'line'=>$line};
- if ($env{'form.verifyrecord'}) {
- my $lastpos = $env{'form.scantron_maxbubble'}*$scantron_config{'Qlength'};
- my $studentdata = substr($line,$scantron_config{'Qstart'}-1,$lastpos);
- chomp($studentdata);
- $studentdata =~ s/\r$//;
- my $studentrecord = '';
- my $counter = -1;
- foreach my $resource (@resources) {
- ($counter,my $recording) =
- &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
- $counter,$studentdata,\%partids_by_symb,
- \%scantron_config,\%lettdig,$numletts);
- $studentrecord .= $recording;
- }
- if ($studentrecord ne $studentdata) {
- &Apache::lonxml::clear_problem_counter();
- if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources) eq 'ssi_error') {
- $ssi_error = 0; # So end of handler error message does not trigger.
- $r->print("");
- &ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
- &Apache::lonnet::remove_lock($lock);
- delete($completedstudents{$uname});
- return '';
- }
- $counter = -1;
- $studentrecord = '';
- foreach my $resource (@resources) {
- ($counter,my $recording) =
- &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
- $counter,$studentdata,\%partids_by_symb,
- \%scantron_config,\%lettdig,$numletts);
- $studentrecord .= $recording;
- }
- if ($studentrecord ne $studentdata) {
- $r->print('');
- if ($scancode eq '') {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2].',
- $uname.':'.$udom,$scan_record->{'scantron.ID'}));
- } else {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2] and CODE: [_3].',
- $uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));
- }
- $r->print(' '.&Apache::loncommon::start_data_table()."\n".
- &Apache::loncommon::start_data_table_header_row()."\n".
- '
'.&mt('Source').' '.&mt('Bubbled responses').' '.
- &Apache::loncommon::end_data_table_header_row()."\n".
- &Apache::loncommon::start_data_table_row().
- ''.&mt('Bubble Sheet').' '.
- ''.$studentdata.' '.
- &Apache::loncommon::end_data_table_row().
- &Apache::loncommon::start_data_table_row().
- 'Stored submissions '.
- ''.$studentrecord.' '."\n".
- &Apache::loncommon::end_data_table_row().
- &Apache::loncommon::end_data_table().'');
- } else {
- $r->print(''.
- &mt('A second grading pass was needed for user: [_1] with ID: [_2], because a mismatch was seen on the first pass.',$uname.':'.$udom,$scan_record->{'scantron.ID'}).' '.
- &mt("As a consequence, this user's submission history records two tries.").
- ' ');
- }
- }
- }
if (&Apache::loncommon::connection_aborted($r)) { last; }
} continue {
&Apache::lonxml::clear_problem_counter();
- &Apache::lonnet::delenv('scantron.');
+ &Apache::lonnet::delenv('scantron\.');
}
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
&Apache::lonnet::remove_lock($lock);
@@ -7712,31 +7538,6 @@ SCANTRONFORM
return '';
}
-sub grade_student_bubbles {
- my ($r,$uname,$udom,$scan_record,$scancode,@resources) = @_;
- foreach my $resource (@resources) {
- my %form = ('submitted' => 'scantron',
- 'grade_target' => 'grade',
- 'grade_username'=> $uname,
- 'grade_domain' => $udom,
- 'grade_courseid'=> $env{'request.course.id'},
- 'grade_symb' => $resource->symb(),
- 'CODE' => $scancode);
- my $result=&ssi_with_retries($resource->src(),$ssi_retries,%form);
- return 'ssi_error' if ($ssi_error);
- last if (&Apache::loncommon::connection_aborted($r));
- }
- return;
-}
-
-=pod
-
-=item scantron_upload_scantron_data
-
- Creates the screen for adding a new bubble sheet data file to a course.
-
-=cut
-
sub scantron_upload_scantron_data {
my ($r)=@_;
$r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'}));
@@ -7777,14 +7578,6 @@ sub scantron_upload_scantron_data {
return '';
}
-=pod
-
-=item scantron_upload_scantron_data_save
-
- Adds a provided bubble information data file to the course if user
- has the correct privileges to do so.
-
-=cut
sub scantron_upload_scantron_data_save {
my($r)=@_;
@@ -7846,14 +7639,6 @@ sub scantron_upload_scantron_data_save {
return '';
}
-=pod
-
-=item valid_file
-
- Validates that the requested bubble data file exists in the course.
-
-=cut
-
sub valid_file {
my ($requested_file)=@_;
foreach my $filename (sort(&scantron_filenames())) {
@@ -7862,16 +7647,6 @@ sub valid_file {
return 0;
}
-=pod
-
-=item scantron_download_scantron_data
-
- Shows a list of the three internal files (original, corrected,
- skipped) for a specific bubble sheet data file that exists in the
- course.
-
-=cut
-
sub scantron_download_scantron_data {
my ($r)=@_;
my $default_form_data=&defaultFormData(&get_symb($r,1));
@@ -7917,7 +7692,18 @@ sub checkscantron_results {
if (!$symb) {return '';}
my $grading_menu_button=&show_grading_menu_form($symb);
my $cid = $env{'request.course.id'};
- my %lettdig = &letter_to_digits();
+ my %lettdig = (
+ A => 1,
+ B => 2,
+ C => 3,
+ D => 4,
+ E => 5,
+ F => 6,
+ G => 7,
+ H => 8,
+ I => 9,
+ J => 0,
+ );
my $numletts = scalar(keys(%lettdig));
my $cnum = $env{'course.'.$cid.'.num'};
my $cdom = $env{'course.'.$cid.'.domain'};
@@ -7931,13 +7717,6 @@ sub checkscantron_results {
my $navmap=Apache::lonnavmaps::navmap->new();
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,undef,1,0);
- my ($uname,$udom,%partids_by_symb);
- foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
- my ($analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom);
- $partids_by_symb{$ressymb} = $parts;
- }
my (%scandata,%lastname,%bylast);
$r->print('
\n";
my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");
$request->print(<'.$section.''."\n";
+ }
+ }
+
$result.='