');
- }
+ my @array=split($$scantron_config{'Qon'},$currentquest,-1);
if (length($array[0]) eq $$scantron_config{'Qlength'}) {
$record{"scantron.$questnum.answer"}='';
+ if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
+ push(@{$record{"scantron.missingerror"}},$questnum);
+ }
} else {
$record{"scantron.$questnum.answer"}=$alphabet[length($array[0])];
}
+ if (scalar(@array) gt 2) {
+ push(@{$record{'scantron.doubleerror'}},$questnum);
+ my @ans=@array;
+ my $i=length($ans[0]);shift(@ans);
+ while ($#ans) {
+ $i+=length($ans[0])+1;
+ $record{"scantron.$questnum.answer"}.=$alphabet[$i];
+ shift(@ans);
+ }
+ }
}
$record{'scantron.maxquest'}=$questnum;
return \%record;
@@ -3297,7 +3378,6 @@ sub scantron_parse_scanline {
sub scantron_add_delay {
my ($delayqueue,$scanline,$errormessage,$errorcode)=@_;
- Apache->request->print('add_delay_error '.$_[2] );
push(@$delayqueue,
{'line' => $scanline, 'emsg' => $errormessage,
'ecode' => $errorcode }
@@ -3305,12 +3385,13 @@ sub scantron_add_delay {
}
sub scantron_find_student {
- my ($scantron_record,$idmap)=@_;
+ my ($scantron_record,$scan_data,$idmap,$line)=@_;
my $scanID=$$scantron_record{'scantron.ID'};
+ if ($scanID =~ /^\s*$/) {
+ return &scan_data($scan_data,"$line.user");
+ }
foreach my $id (keys(%$idmap)) {
- #Apache->request->print('
checking studnet -'.$id.'- againt -'.$scanID.'-
');
if (lc($id) eq lc($scanID)) {
- #Apache->request->print('success');
return $$idmap{$id};
}
}
@@ -3325,16 +3406,397 @@ sub scantron_filter {
return 0;
}
-#FIXME I think I am doing this in the wrong order, I think it would be
-#better to make a several passes analyzing all of the lines in the
-#file for common errors wrong/invalid PID/username duplicated
-#PID/username, missing bubbles, double bubbles, missing/invalid CODE
-#and then get the instructor to fix all of these errors, then grade
-#the corrected one, I'll still need to catch error conditions, but
-#maybe most will taken care even before we start
+sub scantron_process_corrections {
+ my ($r) = @_;
+ my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'});
+ my ($scanlines,$scan_data)=&scantron_getfile();
+ my $classlist=&Apache::loncoursedata::get_classlist();
+ my $which=$ENV{'form.scantron_line'};
+ my $line=&scantron_get_line($scanlines,$which);
+ my ($skip,$err,$errmsg);
+ if ($ENV{'form.scantron_skip_record'}) {
+ $skip=1;
+ } elsif ($ENV{'form.scantron_corrections'} =~ /^(duplicate|incorrect)ID$/) {
+ my $newstudent=$ENV{'form.scantron_username'}.':'.
+ $ENV{'form.scantron_domain'};
+ my $newid=$classlist->{$newstudent}->[&Apache::loncoursedata::CL_ID];
+ ($line,$err,$errmsg)=
+ &scantron_fixup_scanline(\%scantron_config,$scan_data,$line,$which,
+ 'ID',{'newid'=>$newid,
+ 'username'=>$ENV{'form.scantron_username'},
+ 'domain'=>$ENV{'form.scantron_domain'}});
+ } elsif ($ENV{'form.scantron_corrections'} =~ /^(missing|double)bubble$/) {
+ foreach my $question (split(',',$ENV{'form.scantron_questions'})) {
+ ($line,$err,$errmsg)=
+ &scantron_fixup_scanline(\%scantron_config,$scan_data,$line,
+ $which,'answer',
+ { 'question'=>$question,
+ 'response'=>$ENV{"form.scantron_correct_Q_$question"}});
+ if ($err) { last; }
+ }
+ }
+ if ($err) {
+ $r->print("Unable to accept last correction, an error occurred :$errmsg:");
+ } else {
+ &scantron_put_line($scanlines,$which,$line,$skip);
+ &scantron_putfile($scanlines,$scan_data);
+ }
+}
+
sub scantron_validate_file {
my ($r) = @_;
+ my ($symb,$url)=&get_symb_and_url($r);
+ if (!$symb) {return '';}
+ my $default_form_data=&defaultFormData($symb,$url);
+
+ if ($ENV{'form.scantron_corrections'}) {
+ &scantron_process_corrections($r);
+ }
+ #get the student pick code ready
+ $r->print(&Apache::loncommon::studentbrowser_javascript());
+ my $result= <
+
+
+
+
+ $default_form_data
+SCANTRONFORM
+ $r->print($result);
+
+ my @validate_phases=( 'ID',
+ 'CODE',
+ 'doublebubble',
+ 'missingbubbles');
+ if (!$ENV{'form.validatepass'}) {
+ $ENV{'form.valiadatepass'} = 0;
+ }
+ my $currentphase=$ENV{'form.valiadatepass'};
+
+ if ($ENV{'form.scantron_selectfile'}=~m-^/-) {
+ #first pass copy file to classdir
+
+ }
+ my $stop=0;
+ while (!$stop && $currentphase < scalar(@validate_phases)) {
+ $r->print("
Validating ".$validate_phases[$currentphase]."
");
+ $r->rflush();
+ my $which="scantron_validate_".$validate_phases[$currentphase];
+ {
+ no strict 'refs';
+ ($stop,$currentphase)=&$which($r,$currentphase);
+ }
+ }
+ if (!$stop) {
+ $r->print("Validation process complete. ");
+ $r->print('');
+ $r->print('');
+ } else {
+ $r->print('');
+ $r->print("");
+ }
+ if ($stop) {
+ $r->print('');
+ $r->print(' using corrected info ');
+ $r->print("");
+ $r->print(" this scanline saving it for later.");
+ }
+ $r->print(" ".&show_grading_menu_form($symb,$url).
+ "