'.
+ ''.
+ ' No '.
+ ' '.($ENV{'form.vProb'} eq 'no' ? 'Title' : 'Problem View').'/Grade ';
+
+ my ($depth,$ctr,$question) = (1,0,1);
+ $iterator->next(); # skip the first BEGIN_MAP
+ my $curRes = $iterator->next(); # for "current resource"
+ while ($depth > 0 && $ctr < 100) { # ctr, just in case it never gets out of loop
+ if($curRes == $iterator->BEGIN_MAP) { $depth++; }
+ if($curRes == $iterator->END_MAP) { $depth++; }
+
+ if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout) {
+ my $parts = $curRes->parts();
+ $parts = &temp_parts_fix($parts); # remove line when lonnavmap is fixed
+ my $title = $curRes->compTitle();
+ my $symbx = $curRes->symb();
+ $studentTable.=''.$question.
+ (scalar(@{$parts}) == 1 ? '' : ' ('.scalar(@{$parts}).' parts)').' ';
+ $studentTable.='';
+ if ($ENV{'form.vProb'} eq 'yes') {
+ $studentTable.=&show_problem($request,$symbx,$uname,$udom,1);
+ } else {
+ my $companswer = &Apache::loncommon::get_student_answers(
+ $symbx,$uname,$udom,$ENV{'request.course.id'});
+ $companswer =~ s|||g;
+
+# while ($companswer =~ /()/s) { # / /g;
+ $studentTable.=' '.$title.' Correct answer: '.$companswer;
+ }
+
+ my %record = &Apache::lonnet::restore($symbx,$ENV{'request.course.id'},$udom,$uname);
+
+ if ($ENV{'form.lastSub'} eq 'datesub') {
+ if ($record{'version'} eq '') {
+ $studentTable.=' No recorded submission for this problem ';
+ } else {
+ $studentTable.=''.
+ ''.
+ 'Date/Time '.
+ 'Submission '.
+ 'Status ';
+ my ($version);
+ for ($version=1;$version<=$record{'version'};$version++) {
+ my $timestamp = scalar(localtime($record{$version.':timestamp'}));
+ $studentTable.=''.$timestamp.' ';
+ my @versionKeys = split(/\:/,$record{$version.':keys'});
+ my @displaySub = ();
+ foreach my $partid (@{$parts}) {
+ my @matchKey = grep /^resource\.$partid\..*?\.submission$/,@versionKeys;
+ next if ($record{"$version:resource.$partid.solved"} eq '');
+# next if ($record{"$version:resource.$partid.award"} eq 'APPROX_ANS' &&
+# $record{"$version:resource.$partid.solved"} eq '');
+ $displaySub[0].=(exists $record{$version.':'.$matchKey[0]}) ?
+ 'Part '.$partid.' '.
+ ($record{"$version:resource.$partid.tries"} eq '' ? 'Trial not counted' :
+ 'Trial '.$record{"$version:resource.$partid.tries"}).' '.
+ $record{$version.':'.$matchKey[0]}.' ' : '';
+ $displaySub[1].=(exists $record{"$version:resource.$partid.award"}) ?
+ 'Part '.$partid.' '.
+ $record{"$version:resource.$partid.award"}.'/'.
+ $record{"$version:resource.$partid.solved"}.' ' : '';
+ $displaySub[2].=(exists $record{"$version:resource.$partid.regrader"}) ?
+ $record{"$version:resource.$partid.regrader"}.' (Part: '.$partid.')' : '';
+ }
+ $displaySub[2].=(exists $record{"$version:resource.regrader"}) ?
+ $record{"$version:resource.regrader"} : '';
+ $studentTable.=''.$displaySub[0].' '.$displaySub[1].
+ ($displaySub[2] eq '' ? '' : 'Manually graded by '.$displaySub[2]).' ';
+ }
+ $studentTable.='
';
+ }
+ } elsif ($ENV{'form.lastSub'} eq 'all') {
+ my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
+ $studentTable.=&Apache::loncommon::get_previous_attempt($symbx,$uname,$udom,
+ $ENV{'request.course.id'},
+ '','.submission');
+
+ }
+
+ foreach my $partid (@{$parts}) {
+ $studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$partid,\%record);
+ $studentTable.=' '."\n";
+ $question++;
+ }
+ $studentTable.='';
+
+ }
+ $curRes = $iterator->next();
+ $ctr++;
+ }
+
+ $studentTable.='
'."\n".
+ ' '.
+ ''."\n";
+ $studentTable.=&show_grading_menu_form($symb,$url);
+ $request->print($studentTable);
+
+ return '';
+}
+
+sub temp_parts_fix { #remove sub once lonnavmap is fixed
+ my $parts = shift;
+ my %seen = ();
+ my @correctParts = ();
+ foreach (@{$parts}) {
+ next if ($seen{$_} > 0);
+ $seen{$_}++;
+ push @correctParts,$_;
+ }
+ return \@correctParts;
+}
+
+sub updateGradeByPage {
+ my ($request) = shift;
+
+ 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 $pageTitle = $ENV{'form.page'};
+ my (undef,undef,$fullname) = &getclasslist($getsec,'1');
+ my ($uname,$udom) = split(/:/,$ENV{'form.student'});
+
+ my $result=' '.$ENV{'form.title'}.' ';
+ $result.=' Student: '.$$fullname{$ENV{'form.student'}}.
+ ' ('.$uname.($udom eq $cdom ? '':':'.$udom).') '."\n";
+
+ $request->print($result);
+
+ my $navmap = Apache::lonnavmaps::navmap-> new($ENV{'request.course.fn'}.'.db',
+ $ENV{'request.course.fn'}.'_parms.db',1, 1);
+ my ($mapUrl, $id, $resUrl) = split(/___/, $ENV{'form.page'});
+ my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
+
+ my $iterator = $navmap->getIterator($map->map_start(),
+ $map->map_finish());
+
+ my $studentTable=''.
+ ''.
+ ' No '.
+ ' Title '.
+ ' Previous Score '.
+ ' New Score ';
+
+ $iterator->next(); # skip the first BEGIN_MAP
+ my $curRes = $iterator->next(); # for "current resource"
+ my ($depth,$ctr,$question,$changeflag)= (1,0,1,0);
+ while ($depth > 0 && $ctr < 100) { # ctr, just in case it never gets out of loop
+ if($curRes == $iterator->BEGIN_MAP) { $depth++; }
+ if($curRes == $iterator->END_MAP) { $depth++; }
+
+ if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout) {
+ my $parts = $curRes->parts();
+ $parts = &temp_parts_fix($parts); # remove line when lonnavmap is fixed
+ my $title = $curRes->compTitle();
+ my $symbx = $curRes->symb();
+ $studentTable.=''.$question.
+ (scalar(@{$parts}) == 1 ? '' : ' ('.scalar(@{$parts}).' parts)').' ';
+ $studentTable.=' '.$title.' ';
+
+ my %newrecord=();
+ my @displayPts=();
+ foreach my $partid (@{$parts}) {
+ my $newpts = $ENV{'form.GD_BOX'.$question.'_'.$partid};
+ my $oldpts = $ENV{'form.oldpts'.$question.'_'.$partid};
+
+ my $wgt = $ENV{'form.WGT'.$question.'_'.$partid} != 0 ?
+ $ENV{'form.WGT'.$question.'_'.$partid} : 1;
+ my $partial = $newpts/$wgt;
+ my $score;
+ if ($partial > 0) {
+ $score = 'correct_by_override';
+ } elsif ($partial == 0) {
+ $score = 'incorrect_by_override';
+ }
+ if ($ENV{'form.GD_SEL'.$question.'_'.$partid} eq 'excused') {
+ $partial = '';
+ $score = 'excused';
+ }
+ my $oldstatus = $ENV{'form.solved'.$question.'_'.$partid};
+ $displayPts[0].=' Part '.$partid.' = '.
+ (($oldstatus eq 'excused') ? 'excused' : $oldpts).
+ ' ';
+ $displayPts[1].=' Part '.$partid.' = '.
+ ($oldstatus eq 'correct_by_student' ? $oldpts :
+ (($score eq 'excused') ? 'excused' : $newpts)).
+ ' ';
+
+ $question++;
+ if (($oldstatus eq 'correct_by_student') ||
+ ($newpts eq $oldpts && $score eq $oldstatus))
+ {
+ next;
+ }
+ $newrecord{'resource.'.$partid.'.awarded'} = $partial if $partial ne '';
+ $newrecord{'resource.'.$partid.'.solved'} = $score;
+ $newrecord{'resource.'.$partid.'.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+
+ $changeflag++;
+ }
+ if (scalar(keys(%newrecord)) > 0) {
+ &Apache::lonnet::cstore(\%newrecord,$symbx,$ENV{'request.course.id'},
+ $udom,$uname);
+ }
+ $studentTable.=''.$displayPts[0].' '.
+ ''.$displayPts[1].' '.
+ ' ';
+
+ }
+ $curRes = $iterator->next();
+ $ctr++;
+ }
+
+ $studentTable.='
';
+ $studentTable.=&show_grading_menu_form($ENV{'form.symb'},$ENV{'form.url'});
+ my $grademsg=($changeflag == 0 ? 'No score was changed or updated.' :
+ 'The scores were changed for '.
+ $changeflag.' problem'.($changeflag == 1 ? '.' : 's.'));
+ $request->print($grademsg.$studentTable);
+
+ return '';
+}
+
+#-------- end of section for handling grading by page/sequence ---------
+#
+#-------------------------------------------------------------------
+
+#--------------------Scantron Grading-----------------------------------
+#
+#------ start of section for handling grading by page/sequence ---------
+
+sub defaultFormData {
+ my ($symb,$url)=@_;
+ return '
+ '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n";
+}
+
+sub getSequenceDropDown {
+ my ($request,$symb)=@_;
+ my $result=''."\n";
+ my ($titles,$symbx) = &getSymbMap($request);
+ my ($curpage,$type,$mapId) = ($symb =~ /(.*?\.(page|sequence))___(\d+)___/);
+ my $ctr=0;
+ foreach (@$titles) {
+ my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
+ $result.=''.$showtitle.' '."\n";
+ $ctr++;
+ }
+ $result.= ' ';
+ return $result;
+}
+
+sub scantron_uploads {
+ if (!-e $Apache::lonnet::perlvar{'lonScansDir'}) { return ''};
+ my $result= '';
+ opendir(DIR,$Apache::lonnet::perlvar{'lonScansDir'});
+ my @files=sort(readdir(DIR));
+ foreach my $filename (@files) {
+ if ($filename eq '.' or $filename eq '..') { next; }
+ $result.="$filename \n";
+ }
+ closedir(DIR);
+ $result.=" ";
+ return $result;
+}
+
+sub scantron_scantab {
+ my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
+ my $result=''."\n";
+ foreach my $line (<$fh>) {
+ my ($name,$descrip)=split(/:/,$line);
+ if ($name =~ /^\#/) { next; }
+ $result.=''.$descrip.' '."\n";
+ }
+ $result.=' '."\n";
+
+ return $result;
+}
+
+sub scantron_selectphase {
+ my ($r) = @_;
+ my ($symb,$url)=&get_symb_and_url($r);
+ if (!$symb) {return '';}
+ my $sequence_selector=&getSequenceDropDown($r,$symb);
+ my $default_form_data=&defaultFormData($symb,$url);
+ my $grading_menu_button=&show_grading_menu_form($symb,$url);
+ my $file_selector=&scantron_uploads();
+ my $format_selector=&scantron_scantab();
+ my $result;
+ $result.= <
+
+ $default_form_data
+
+
+
+
+
+
+ Specify file location and which Folder/Sequence to grade
+
+
+
+
+ Sequence to grade: $sequence_selector
+
+
+
+
+ Filename of scoring office file: $file_selector
+
+
+
+
+ Format of data file: $format_selector
+
+
+
+
+
+
+
+
+$grading_menu_button
+SCANTRONFORM
+
+ return $result;
+}
+
+sub get_scantron_config {
+ my ($which) = @_;
+ my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
+ my %config;
+ foreach my $line (<$fh>) {
+ my ($name,$descrip)=split(/:/,$line);
+ if ($name ne $which ) { next; }
+ chomp($line);
+ my @config=split(/:/,$line);
+ $config{'name'}=$config[0];
+ $config{'description'}=$config[1];
+ $config{'CODElocation'}=$config[2];
+ $config{'CODEstart'}=$config[3];
+ $config{'CODElength'}=$config[4];
+ $config{'IDstart'}=$config[5];
+ $config{'IDlength'}=$config[6];
+ $config{'Qstart'}=$config[7];
+ $config{'Qlength'}=$config[8];
+ $config{'Qoff'}=$config[9];
+ $config{'Qon'}=$config[10];
+ last;
+ }
+ return %config;
+}
+
+sub username_to_idmap {
+ my ($classlist)= @_;
+ my %idmap;
+ foreach my $student (keys(%$classlist)) {
+ $idmap{$classlist->{$student}->[&Apache::loncoursedata::CL_ID]}=
+ $student;
+ }
+ return %idmap;
+}
+
+sub scantron_parse_scanline {
+ my ($line,$scantron_config)=@_;
+ my %record;
+ my $questions=substr($line,$$scantron_config{'Qstart'}-1);
+ my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
+ if ($$scantron_config{'CODElocation'} ne 0) {
+ if ($$scantron_config{'CODElocation'} < 0) {
+ $record{'scantron.CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
+ $$scantron_config{'CODElength'});
+ } else {
+ #FIXME interpret first N questions
+ }
+ }
+ $record{'scantron.ID'}=substr($data,$$scantron_config{'IDstart'}-1,
+ $$scantron_config{'IDlength'});
+ my @alphabet=('A'..'Z');
+ my $questnum=0;
+ while ($questions) {
+ $questnum++;
+ my $currentquest=substr($questions,0,$$scantron_config{'Qlength'});
+ substr($questions,0,$$scantron_config{'Qlength'})='';
+ if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
+ my (@array)=split(/$$scantron_config{'Qon'}/,$currentquest);
+ if (scalar(@array) gt 2) {
+ #FIXME do something intelligent with double bubbles
+ Apache->request->print("Wha!!! ".scalar(@array).
+ '-'.$currentquest.'-'.$questnum.' ');
+ }
+ if (length($array[0]) eq $$scantron_config{'Qlength'}) {
+ $record{"scantron.$questnum.answer"}='';
+ } else {
+ $record{"scantron.$questnum.answer"}=$alphabet[length($array[0])];
+ }
+ }
+ $record{'scantron.maxquest'}=$questnum;
+ return \%record;
+}
+
+sub scantron_add_delay {
+}
+
+sub scantron_find_student {
+ my ($scantron_record,$idmap)=@_;
+ my $scanID=$$scantron_record{'scantron.ID'};
+ 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}; }
+ }
+ return undef;
+}
+
+sub scantron_filter {
+ my ($curres)=@_;
+ if (ref($curres) && $curres->is_problem() && !$curres->randomout) {
+ return 1;
+ }
+ return 0;
+}
+
+sub scantron_process_students {
+ my ($r) = @_;
+ my (undef,undef,$sequence)=split(/___/,$ENV{'form.selectpage'});
+ my ($symb,$url)=&get_symb_and_url($r);
+ if (!$symb) {return '';}
+ my $default_form_data=&defaultFormData($symb,$url);
+
+ my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'});
+ my $scanlines=Apache::File->new($Apache::lonnet::perlvar{'lonScansDir'}."/$ENV{'form.scantron_selectfile'}");
+ my @scanlines=<$scanlines>;
+ my $classlist=&Apache::loncoursedata::get_classlist();
+ my %idmap=&username_to_idmap($classlist);
+ my $navmap=Apache::lonnavmaps::navmap->new($ENV{'request.course.fn'}.'.db',$ENV{'request.course.fn'}.'_parms.db',1, 1);
+ my $map=$navmap->getResourceByUrl($sequence);
+ my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ $r->print("geto ".scalar(@resources)." ");
+ my $result= <
+
+ $default_form_data
+SCANTRONFORM
+ $r->print($result);
+
+ my @delayqueue;
+ my $totalcorrect;
+ my $totalincorrect;
+
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,
+ 'Scantron Status','Scantron Progress',scalar(@scanlines));
+ foreach my $line (@scanlines) {
+ my $studentcorrect;
+ my $studentincorrect;
+
+ chomp($line);
+ my $scan_record=&scantron_parse_scanline($line,\%scantron_config);
+ my ($uname,$udom);
+ if ($uname=&scantron_find_student($scan_record,\%idmap)) {
+ &scantron_add_delay(\@delayqueue,$line,
+ 'Unable to find a student that matches');
+ }
+ $r->print('doing studnet'.$uname.' ');
+ ($uname,$udom)=split(/:/,$uname);
+ &Apache::lonnet::delenv('form.counter');
+ &Apache::lonnet::appenv(%$scan_record);
+# &Apache::lonhomework::showhash(%ENV);
+ $Apache::lonxml::debug=1;
+ &Apache::lonxml::debug("line is $line");
+
+ my $i=0;
+ foreach my $resource (@resources) {
+ $i++;
+ my $result=&Apache::lonnet::ssi($resource->src(),
+ ('submitted' =>'scantron',
+ 'grade_target' =>'grade',
+ 'grade_username'=>$uname,
+ 'grade_domain' =>$udom,
+ 'grade_courseid'=>$ENV{'request.course.id'},
+ 'grade_symb' =>$resource->symb()));
+ my %score=&Apache::lonnet::restore($resource->symb(),
+ $ENV{'request.course.id'},
+ $udom,$uname);
+ foreach my $part ($resource->{PARTS}) {
+ if ($score{'resource.'.$part.'.solved'} =~ /^correct/) {
+ $studentcorrect++;
+ $totalcorrect++;
+ } else {
+ $studentincorrect++;
+ $totalincorrect++;
+ }
+ }
+ $r->print(''.
+ $resource->symb().'-'.
+ $resource->src().'-'.' result is'.$result);
+ &Apache::lonhomework::showhash(%score);
+ # if ($i eq 3) {last;}
+ }
+ &Apache::lonnet::delenv('form.counter');
+ &Apache::lonnet::delenv('scantron\.');
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
+ 'last student Who got a '.$studentcorrect.' correct and '.
+ $studentincorrect.' incorrect. The class has gotten '.
+ $totalcorrect.' correct and '.$totalincorrect.' incorrect');
+ last;
+ #FIXME
+ #get iterator for $sequence
+ #foreach question 'submit' the students answer to the server
+ # through grade target {
+ # generate data to pass back that includes grade recevied
+ #}
+ }
+ $Apache::lonxml::debug=0;
+ foreach my $delay (@delayqueue) {
+ #FIXME
+ #print out each delayed student with interface to select how
+ # to repair student provided info
+ #Expected errors include
+ # 1 bad/no stuid/username
+ # 2 invalid bubblings
+
+ }
+ #FIXME
+ # if delay queue exists 2 submits one to process delayed students one
+ # to ignore delayed students, possibly saving the delay queue for later
+
+ $navmap->untieHashes();
+}
+#-------- end of section for handling grading scantron forms -------
+#
+#-------------------------------------------------------------------
+
#-------------------------- Menu interface -------------------------
#
@@ -2144,20 +3177,93 @@ sub show_grading_menu_form {
my $result.=''."\n";
return $result;
}
+# -- Retrieve choices for grading form
+sub savedState {
+ my %savedState = ();
+ if ($ENV{'form.saveState'}) {
+ foreach (split(/:/,$ENV{'form.saveState'})) {
+ my ($key,$value) = split(/=/,$_,2);
+ $savedState{$key} = $value;
+ }
+ }
+ return \%savedState;
+}
+
#--- Displays the main menu page -------
sub gradingmenu {
my ($request) = @_;
my ($symb,$url)=&get_symb_and_url($request);
if (!$symb) {return '';}
- my $result=' Select a Grading Method ';
- $result.='';
- $result.='Resource: '.$url.' ';
+ my $probTitle = &Apache::lonnet::gettitle($symb);
+
+ $request->print(<
+ function checkChoice(formname) {
+ var cmd = formname.command;
+ formname.saveState.value = "saveCmd="+radioSelection(cmd)+":saveSec="+pullDownSelection(formname.section)+
+ ":saveSub="+radioSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.status);
+ if (cmd[0].checked || cmd[1].checked || cmd[2].checked || cmd[3].checked || cmd[4].checked) formname.submit();
+ if (cmd[5].checked) {
+ if (!checkReceiptNo(formname,'notOK')) { return false;}
+ formname.submit();
+ }
+ }
+
+ function checkReceiptNo(formname,nospace) {
+ var receiptNo = formname.receipt.value;
+ var checkOpt = false;
+ if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}
+ if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}
+ if (checkOpt) {
+ alert("Please enter a receipt number given by a student in the receipt box.");
+ formname.receipt.value = "";
+ formname.receipt.focus();
+ return false;
+ }
+ formname.command[5].checked = true;
+ return true;
+ }
+
+ function radioSelection(radioButton) {
+ var selection=null;
+ if (radioButton.length > 1) {
+ for (var i=0; i 1) {
+ for (var i=0; i
+GRADINGMENUJS
+
+ my $result=' Manual Grading/View Submission '.
+ ''.
+ 'Problem: '.$probTitle.' '."\n";
my ($partlist,$handgrade) = &response_type($url);
my ($resptype,$hdgrade)=('','no');
for (sort keys(%$handgrade)) {
@@ -2168,156 +3274,97 @@ sub gradingmenu {
'Type: '.$responsetype.' '.
'Handgrade: '.$handgrade.' ';
}
- $result.='
';
- $result.=&view_edit_entire_class_form($symb,$url).' ';
- $result.=&upcsvScores_form($symb,$url).' ';
- $result.=&viewGradeaStu_form($symb,$url,$resptype,$hdgrade).' ';
- $result.=&verifyReceipt_form($symb,$url)
- if ((&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) && ($symb));
-
- return $result;
-}
+ $result.='
'."\n";
-#--- Menu for grading a section or the whole class ---
-sub view_edit_entire_class_form {
- my ($symb,$url)=@_;
- my ($classlist,$sections) = &getclasslist('all','0');
- my $result.=''."\n";
- $result.=''."\n";
- $result.=' Grade Entire Section or Class '."\n";
- $result.=''."\n";
- $result.='
'."\n".
+ '
'."\n";
return $result;
}
@@ -2371,8 +3418,13 @@ sub handler {
} else {
$Apache::grades::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
if ($command eq 'submission') {
- &listStudents($request) if ($ENV{'form.student'} eq '');
- &submission($request,0,0) if ($ENV{'form.student'} ne '');
+ ($ENV{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));
+ } elsif ($command eq 'pickStudentPage') {
+ &pickStudentPage($request);
+ } elsif ($command eq 'displayPage') {
+ &displayPage($request);
+ } elsif ($command eq 'gradeByPage') {
+ &updateGradeByPage($request);
} elsif ($command eq 'processGroup') {
&processGroup($request);
} elsif ($command eq 'gradingmenu') {
@@ -2385,6 +3437,8 @@ sub handler {
$request->print(&editgrades($request));
} elsif ($command eq 'verify') {
$request->print(&verifyreceipt($request));
+ } elsif ($command eq 'csvform') {
+ $request->print(&upcsvScores_form($request));
} elsif ($command eq 'csvupload') {
$request->print(&csvupload($request));
} elsif ($command eq 'viewclasslist') {
@@ -2402,6 +3456,10 @@ sub handler {
}
$request->print(&csvuploadmap($request));
}
+ } elsif ($command eq 'scantron_selectphase') {
+ $request->print(&scantron_selectphase($request));
+ } elsif ($command eq 'scantron_process') {
+ $request->print(&scantron_process_students($request));
} else {
$request->print("Unknown action: $command:");
}