');
- pDoc.write("$lt{'type'}<\\/b><\\/td> | $lt{'incl'}<\\/b><\\/td> | $lt{'mesa'}<\\/td><\\/tr>");
+ pDoc.write('
- '.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
+ '.&mt("If this information is correct, please click on '[_1]'.",&mt($button_text)).'
'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','','').'
@@ -6999,7 +7003,13 @@ sub scantron_validate_sequence {
my @resources=
$navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0);
if (@resources) {
- $r->print("".&mt('Some resources in the sequence currently are not set to exam mode. Grading these resources currently may not work correctly.')." ");
+ $r->print(
+ ''
+ .&mt('Some resources in the sequence currently are not set to'
+ .' bubblesheet exam mode. Grading these resources currently may not'
+ .' work correctly.')
+ .' '
+ );
return (1,$currentphase);
}
}
@@ -7130,7 +7140,7 @@ sub scantron_get_correction {
$r->print(&Apache::loncommon::selectstudent_link('scantronupload',
'scantron_username','scantron_domain'));
$r->print(": ");
- $r->print("\n@".
+ $r->print("\n:\n".
&Apache::loncommon::select_dom_form($env{'request.role.domain'},'scantron_domain'));
$r->print('');
@@ -7390,7 +7400,16 @@ sub prompt_for_corrections {
($responsetype_per_response{$question-1} eq 'imageresponse') ||
($responsetype_per_response{$question-1} eq 'reactionresponse') ||
($responsetype_per_response{$question-1} eq 'organicresponse')) {
- $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines).'
'.&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.').' '.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').' '.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").'
');
+ $r->print(
+ &mt("Although this particular question type requires handgrading, the instructions for this question in the bubblesheet exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines)
+ .'
'
+ .&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.')
+ .' '
+ .&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.')
+ .' '
+ .&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.")
+ .'
'
+ );
} else {
$r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")." ");
}
@@ -7713,7 +7732,8 @@ 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,undef,$bubbles_per_row);
+ my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,
+ $udom,undef,$bubbles_per_row);
if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
foreach my $part_id (@{$parts}) {
my $lines;
@@ -7903,22 +7923,29 @@ sub scantron_process_students {
return '';
}
my $map=$navmap->getResourceByUrl($sequence);
+ my $randomorder;
+ if (ref($map)) {
+ $randomorder = $map->randomorder();
+ }
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
- my (%grader_partids_by_symb,%grader_randomlists_by_symb);
+ my (%grader_partids_by_symb,%grader_randomlists_by_symb,%ordered);
&graders_resources_pass(\@resources,\%grader_partids_by_symb,
\%grader_randomlists_by_symb,$bubbles_per_row);
- my $resource_error;
+ my ($resource_error,%symb_to_resource,@master_seq);
foreach my $resource (@resources) {
my $ressymb;
if (ref($resource)) {
$ressymb = $resource->symb();
+ push(@master_seq,$ressymb);
+ $symb_to_resource{$ressymb} = $resource;
} else {
$resource_error = 1;
last;
}
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
+ $env{'user.name'},$env{'user.domain'},
+ 1,$bubbles_per_row);
$grader_partids_by_symb{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -7994,10 +8021,26 @@ SCANTRONFORM
'Student '.$uname.' has multiple sheets',2);
next;
}
+ my $usec = $classlist->{$uname}->[&Apache::loncoursedata::CL_SECTION];
+ my $user = $uname.':'.$usec;
($uname,$udom)=split(/:/,$uname);
+ my $scancode;
+ if ((exists($scan_record->{'scantron.CODE'})) &&
+ (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) {
+ $scancode = $scan_record->{'scantron.CODE'};
+ } else {
+ $scancode = '';
+ }
+
+ my @mapresources = @resources;
+ if ($randomorder) {
+ @mapresources =
+ &users_order($user,$scancode,$sequence,\@master_seq,\%ordered,
+ \%symb_to_resource);
+ }
my (%partids_by_symb,$res_error);
- foreach my $resource (@resources) {
+ foreach my $resource (@mapresources) {
my $ressymb;
if (ref($resource)) {
$ressymb = $resource->symb();
@@ -8008,7 +8051,8 @@ SCANTRONFORM
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
my ($analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom,undef,$bubbles_per_row);
+ &scantron_partids_tograde($resource,$env{'request.course.id'},
+ $uname,$udom,undef,$bubbles_per_row);
$partids_by_symb{$ressymb} = $parts;
} else {
$partids_by_symb{$ressymb} = $grader_partids_by_symb{$ressymb};
@@ -8028,16 +8072,8 @@ SCANTRONFORM
&scantron_putfile($scanlines,$scan_data);
}
- 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,\%partids_by_symb,
+ \@mapresources,\%partids_by_symb,
$bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
@@ -8054,7 +8090,7 @@ SCANTRONFORM
$studentdata =~ s/\r$//;
my $studentrecord = '';
my $counter = -1;
- foreach my $resource (@resources) {
+ foreach my $resource (@mapresources) {
my $ressymb = $resource->symb();
($counter,my $recording) =
&verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
@@ -8065,7 +8101,7 @@ SCANTRONFORM
if ($studentrecord ne $studentdata) {
&Apache::lonxml::clear_problem_counter();
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%partids_by_symb,
+ \@mapresources,\%partids_by_symb,
$bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
@@ -8076,7 +8112,7 @@ SCANTRONFORM
}
$counter = -1;
$studentrecord = '';
- foreach my $resource (@resources) {
+ foreach my $resource (@mapresources) {
my $ressymb = $resource->symb();
($counter,my $recording) =
&verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
@@ -8137,7 +8173,8 @@ sub graders_resources_pass {
my $ressymb = $resource->symb();
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
+ $env{'user.name'},$env{'user.domain'},
+ 1,$bubbles_per_row);
$grader_partids_by_symb->{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -8150,9 +8187,55 @@ sub graders_resources_pass {
return;
}
+=pod
+
+=item users_order
+
+ Returns array of resources in current map, ordered based on either CODE,
+ if this is a CODEd exam, or based on student's identity if this is a
+ "NAMEd" exam.
+
+ Should be used when randomorder applied when the corresponding exam was
+ printed, prior to students completing bubblesheets for the version of the
+ exam the student received.
+
+=cut
+
+sub users_order {
+ my ($user,$scancode,$mapurl,$master_seq,$ordered,$symb_to_resource) = @_;
+ my @mapresources;
+ unless ((ref($ordered) eq 'HASH') && (ref($symb_to_resource) eq 'HASH')) {
+ return @mapresources;
+ }
+ if (($scancode) && (ref($ordered->{$scancode}) eq 'ARRAY')) {
+ @mapresources = @{$ordered->{$scancode}};
+ } elsif ($scancode) {
+ $env{'form.CODE'} = $scancode;
+ my $actual_seq =
+ &Apache::lonprintout::master_seq_to_person_seq($mapurl,
+ $master_seq,
+ $user,$scancode);
+ if (ref($actual_seq) eq 'ARRAY') {
+ @{$ordered->{$scancode}} =
+ map { $symb_to_resource->{$_}; } @{$actual_seq};
+ @mapresources = @{$ordered->{$scancode}};
+ }
+ delete($env{'form.CODE'});
+ } else {
+ my $actual_seq =
+ &Apache::lonprintout::master_seq_to_person_seq($mapurl,
+ $master_seq,
+ $user);
+ if (ref($actual_seq) eq 'ARRAY') {
+ @mapresources =
+ map { $symb_to_resource->{$_}; } @{$actual_seq};
+ }
+ }
+ return @mapresources;
+}
+
sub grade_student_bubbles {
- my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts,$bubbles_per_row) = @_;
-# Walk folder as student here to get resources in order student sees.
+ my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts,$bubbles_per_row) = @_;
if (ref($resources) eq 'ARRAY') {
my $count = 0;
foreach my $resource (@{$resources}) {
@@ -8406,7 +8489,7 @@ sub scantron_download_scantron_data {
if (! &valid_file($file)) {
$r->print('
- '.&mt('The requested file name was invalid.').'
+ '.&mt('The requested filename was invalid.').'
');
return;
@@ -8456,10 +8539,21 @@ sub checkscantron_results {
return '';
}
my $map=$navmap->getResourceByUrl($sequence);
+ my ($randomorder,@master_seq,%symb_to_resource);
+ if (ref($map)) {
+ $randomorder=$map->randomorder();
+ }
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ foreach my $resource (@resources) {
+ if (ref($resource)) {
+ my $ressymb = $resource->symb();
+ push(@master_seq,$ressymb);
+ $symb_to_resource{$ressymb} = $resource;
+ }
+ }
my (%grader_partids_by_symb,%grader_randomlists_by_symb);
- &graders_resources_pass(\@resources,\%grader_partids_by_symb, \%grader_randomlists_by_symb);
-
+ &graders_resources_pass(\@resources,\%grader_partids_by_symb,
+ \%grader_randomlists_by_symb,$bubbles_per_row);
my ($uname,$udom);
my (%scandata,%lastname,%bylast);
$r->print('
@@ -8470,7 +8564,7 @@ sub checkscantron_results {
my $count=&Apache::grades::get_todo_count($scanlines,$scan_data);
my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count);
- my ($username,$domain,$started);
+ my ($username,$domain,$started,%ordered);
my $nav_error;
&scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
if ($nav_error) {
@@ -8512,15 +8606,34 @@ sub checkscantron_results {
$scandata{$pid} = substr($line,$scantron_config{'Qstart'}-1,$lastpos);
chomp($scandata{$pid});
$scandata{$pid} =~ s/\r$//;
+ my $usec = $classlist->{$uname}->[&Apache::loncoursedata::CL_SECTION];
+ my $user = $uname.':'.$usec;
($username,$domain)=split(/:/,$uname);
+
+ my $scancode;
+ if ((exists($scan_record->{'scantron.CODE'})) &&
+ (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) {
+ $scancode = $scan_record->{'scantron.CODE'};
+ } else {
+ $scancode = '';
+ }
+
+ my @mapresources = @resources;
+ if ($randomorder) {
+ @mapresources =
+ &users_order($user,$scancode,$sequence,\@master_seq,\%ordered,
+ \%symb_to_resource);
+ }
my $counter = -1;
- foreach my $resource (@resources) {
+ foreach my $resource (@mapresources) {
my $parts;
my $ressymb = $resource->symb();
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
(my $analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$username,$domain,undef,$bubbles_per_row);
+ &scantron_partids_tograde($resource,$env{'request.course.id'},
+ $username,$domain,undef,
+ $bubbles_per_row);
} else {
$parts = $grader_partids_by_symb{$ressymb};
}
@@ -8574,7 +8687,12 @@ sub checkscantron_results {
$env{'form.scantron_maxbubble'})
.''
);
- $r->print(''.&mt('Exact matches for [quant,_1,student].',$passed).' '.&mt('Discrepancies detected for [quant,_1,student].',$failed).' ');
+ $r->print(''
+ .&mt('Exact matches for [_1][quant,_2,student][_3].','',$passed,'')
+ .' '
+ .&mt('Discrepancies detected for [_1][quant,_2,student][_3].','',$failed,'')
+ .' '
+ );
if ($passed) {
$r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'
');
$r->print(&Apache::loncommon::start_data_table()."\n".
@@ -9003,6 +9121,21 @@ sub init_perm {
}
}
+sub init_old_essays {
+ my ($symb,$apath,$adom,$aname) = @_;
+ if ($symb ne '') {
+ my %essays = &Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
+ if (keys(%essays) > 0) {
+ $old_essays{$symb} = \%essays;
+ }
+ }
+ return;
+}
+
+sub reset_old_essays {
+ undef(%old_essays);
+}
+
sub gather_clicker_ids {
my %clicker_ids;
|