'.
+ ''.
+ ' 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]}) ?
+ 'Trial '.$version.' Part '.$partid.' '
+ .$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 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_selectphase {
+ my ($r) = @_;
+ my ($symb,$url)=&get_symb_and_url($r);
+ if (!$symb) {return '';}
+ my $sequence_selector=&getSequenceDropDown($r,$symb);
+ my $result;
+ $result.= <
+
+
+
+
+
+
+
+
+
+ Specify file location and which Folder/Sequence to grade
+
+
+
+
+ Sequence to grade: $sequence_selector
+
+
+
+
+
+ Filename of scoring office file:
+
+ filename1
+ filename2
+
+
+
+
+
+
+
+
+
+SCANTRONFORM
+
+ return $result;
+}
+
+sub scantron_configphase {
+ my ($r) = @_;
+ my $sequence=$ENV{'form.selectpage'};
+ my $result;
+ $result.="got page $sequence";
+ $Apache::lonxml::debug=1;
+ &Apache::lonhomework::showhash(%ENV);
+ $Apache::lonxml::debug=0;
+ #FIXME Needs to present some lines from the file and allow the instructor to specify which columns represent what data, possibly have some nice defaults setup, probably should do a pass through all problems for a student to get an idea of how many questions there are, and homw many lines we'll have,
+ return $result;
+}
+
+sub scantron_process_students {
+ #FIXME
+ # loop through students, {
+ # Check if studnet info valid, if not add line to delay queue
+ # foreach question 'submit' the students answer to the server
+ # through grade target {
+ # generate data to pass back that includes grade recevied
+ # }
+ # }
+ # loop through delay queue {
+ # 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
+ # }
+ # if delay queue exists 2 submits one to process delayed students one
+ # to ignore delayed students, possibly saving the delay queue for later
+
+}
+#-------- end of section for handling grading scantron forms -------
+#
+#-------------------------------------------------------------------
+
#-------------------------- Menu interface -------------------------
#
@@ -2165,20 +2858,147 @@ 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[4].checked) formname.submit();
+
+ if (cmd[3].checked) browseAndUpload();
+
+ 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");
+ lDoc.write("Browse And Upload ");
+
+ lDoc.write("
+GRADINGMENUJS
+
+ my $result=' Manual Grading/View Submission '.
+ ''.
+ 'Problem: '.$probTitle.' '."\n";
my ($partlist,$handgrade) = &response_type($url);
my ($resptype,$hdgrade)=('','no');
for (sort keys(%$handgrade)) {
@@ -2189,156 +3009,96 @@ 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,undef) = &getclasslist('all','0');
- my $result.=''."\n";
- $result.=''."\n";
- $result.=' Grade Entire Section or Class '."\n";
- $result.=''."\n";
- $result.='
'."\n".
+ '
'."\n";
return $result;
}
@@ -2392,8 +3152,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') {
@@ -2406,6 +3171,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') {
@@ -2423,6 +3190,10 @@ sub handler {
}
$request->print(&csvuploadmap($request));
}
+ } elsif ($command eq 'scantron_selectphase') {
+ $request->print(&scantron_selectphase($request));
+ } elsif ($command eq 'scantron_configphase') {
+ $request->print(&scantron_configphase($request));
} else {
$request->print("Unknown action: $command:");
}