[LON-CAPA-cvs] cvs: loncom /homework grades.pm
ng
lon-capa-cvs@mail.lon-capa.org
Tue, 11 Mar 2003 19:32:02 -0000
This is a MIME encoded message
--ng1047411122
Content-Type: text/plain
ng Tue Mar 11 14:32:02 2003 EDT
Modified files:
/loncom/homework grades.pm
Log:
will handle manual grading by page/sequence
--ng1047411122
Content-Type: text/plain
Content-Disposition: attachment; filename="ng-20030311143202.txt"
Index: loncom/homework/grades.pm
diff -u loncom/homework/grades.pm:1.70 loncom/homework/grades.pm:1.71
--- loncom/homework/grades.pm:1.70 Fri Feb 28 16:06:28 2003
+++ loncom/homework/grades.pm Tue Mar 11 14:32:02 2003
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.70 2003/02/28 21:06:28 ng Exp $
+# $Id: grades.pm,v 1.71 2003/03/11 19:32:02 ng Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -32,7 +32,7 @@
# Year 2002
# June-August H.K. Ng
# Year 2003
-# February H.K. Ng
+# February, March H.K. Ng
#
package Apache::grades;
@@ -237,7 +237,8 @@
my $title.='<h3><font color="#339933">Verifying Submission Receipt '.
$receipt.'</h3></font>'."\n".
- '<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font><br><br>'."\n";
+ '<font size=+1><b>Problem: </b>'.
+ &Apache::lonnet::metadata($ENV{'form.url'},'title').'</font><br><br>'."\n";
my ($string,$contents,$matches) = ('','',0);
my (undef,undef,$fullname) = &getclasslist('all','0');
@@ -306,7 +307,7 @@
$viewgrade.
' Submissions for a Student or a Group of Students</font></h3>'.
'<table border="0"><tr><td colspan=3><font size=+1>'.
- '<b>Resource: </b>'.$url.'</font></td></tr>'.$result;
+ '<b>Problem: </b>'.&Apache::lonnet::metadata($url,'title').'</font></td></tr>'.$result;
$request->print(<<LISTJAVASCRIPT);
<script type="text/javascript" language="javascript">
@@ -455,91 +456,175 @@
my $request = shift;
$request->print(<<SUBJAVASCRIPT);
<script type="text/javascript" language="javascript">
- function updateRadio(radioButton,formtextbox,formsel,scores,weight) {
- var pts = formtextbox.value;
- var resetbox =false;
- if (isNaN(pts) || pts < 0) {
- alert("A number equal or greater than 0 is expected. Entered value = "+pts);
- for (var i=0; i<radioButton.length; i++) {
- if (radioButton[i].checked) {
- formtextbox.value = i;
- resetbox = true;
- }
+ function updateRadio(formname,id,weight) {
+ var gradeBox = eval("formname.GD_BOX"+id);
+ var radioButton = eval("formname.RADVAL"+id);
+ var pts = checkSolved(formname,id) == 'update' ? gradeBox.value : weight;
+ gradeBox.value = pts;
+ var resetbox = false;
+ if (isNaN(pts) || pts < 0) {
+ alert("A number equal or greater than 0 is expected. Entered value = "+pts);
+ for (var i=0; i<radioButton.length; i++) {
+ if (radioButton[i].checked) {
+ gradeBox.value = i;
+ resetbox = true;
+ }
+ }
+ if (!resetbox) {
+ formtextbox.value = "";
+ }
+ return;
}
- if (!resetbox) {
- formtextbox.value = "";
+
+ if (pts > weight) {
+ var resp = confirm("You entered a value ("+pts+
+ ") greater than the weight for the part. Accept?");
+ if (resp == false) {
+ gradeBox.value = "";
+ return;
+ }
}
- return;
- }
- if (pts > weight) {
- var resp = confirm("You entered a value ("+pts+
- ") greater than the weight for the part. Accept?");
- if (resp == false) {
- formtextbox.value = "";
- return;
- }
+ for (var i=0; i<radioButton.length; i++) {
+ radioButton[i].checked=false;
+ if (pts == i && pts != "") {
+ radioButton[i].checked=true;
+ }
+ }
+ updateSelect(formname,id);
+ var stores = eval("formname.stores"+id);
+ stores.value = "0";
}
- for (var i=0; i<radioButton.length; i++) {
- radioButton[i].checked=false;
- if (pts == i) {
- radioButton[i].checked=true;
+ function writeBox(formname,id,pts,weight) {
+ var gradeBox = eval("formname.GD_BOX"+id);
+ if (checkSolved(formname,id) == 'update') {
+ gradeBox.value = pts;
+ } else {
+ gradeBox.value = weight;
+ var radioButton = eval("formname.RADVAL"+id);
+ for (var i=0; i<radioButton.length; i++) {
+ radioButton[i].checked=false;
+ if (i == weight) {
+ radioButton[i].checked=true;
+ }
+ }
}
+ var stores = eval("formname.stores"+id);
+ stores.value = "0";
+ updateSelect(formname,id);
+ return;
}
- updateSelect(formsel);
- scores.value = "0";
- }
- function writeBox(formrad,formsel,pts,scores) {
- formrad.value = pts;
- scores.value = "0";
- updateSelect(formsel,pts);
- return;
- }
+ function clearRadBox(formname,id) {
+ if (checkSolved(formname,id) == 'noupdate') {
+ updateSelect(formname,id);
+ return;
+ }
+ gradeSelect = eval("formname.GD_SEL"+id);
+ for (var i=0; i<gradeSelect.length; i++) {
+ if (gradeSelect[i].selected) {
+ var selectx=i;
+ }
+ }
+ var stores = eval("formname.stores"+id);
+ if (selectx == stores.value) { return };
+ var gradeBox = eval("formname.GD_BOX"+id);
+ gradeBox.value = "";
+ var radioButton = eval("formname.RADVAL"+id);
+ for (var i=0; i<radioButton.length; i++) {
+ radioButton[i].checked=false;
+ }
+ stores.value = selectx;
+ }
- function clearRadBox(radioButton,formbox,formsel,scores) {
- for (var i=0; i<formsel.length; i++) {
- if (formsel[i].selected) {
- var selectx=i;
+ function checkSolved(formname,id) {
+ if (eval("formname.solved"+id+".value") == "correct_by_student") {
+ alert("This problem has been graded correct by the computer. The score cannot be changed.");
+ return "noupdate";
}
+ return "update";
}
- if (selectx == scores.value) { return };
- formbox.value = "";
- for (var i=0; i<radioButton.length; i++) {
- radioButton[i].checked=false;
+
+ function updateSelect(formname,id) {
+ var gradeSelect = eval("formname.GD_SEL"+id);
+ gradeSelect[0].selected = true;
+ return;
}
- scores.value = selectx;
- }
- function updateSelect(formsel) {
- formsel[0].selected = true;
- return;
- }
+//=========== Check that a point is assigned for all the parts (essay grading only) ============
+ function checksubmit(formname,val,total,parttot) {
+ document.SCORE.gradeOpt.value = val;
+ if (val == "Save & Next") {
+ for (i=0;i<=total;i++) {
+ for (j=0;j<parttot;j++) {
+ var partid = eval("formname.partid"+i+"_"+j+".value");
+ var selopt = eval("formname.GD_SEL"+i+"_"+partid);
+ if (selopt[0].selected) {
+ var points = eval("formname.GD_BOX"+i+"_"+partid+".value");
+ if (points == "") {
+ var name = eval("formname.name"+i+".value");
+ var resp = confirm("You did not assign a score for "+name+", part "+partid+". Continue?");
+ if (resp == false) {
+ eval("formname.GD_BOX"+i+"_"+partid+".focus()");
+ return false;
+ }
+ }
+ }
+
+ }
+ }
+
+ }
+ formname.submit();
+ }
-//=================== Check that a point is assigned for all the parts ==============
- function checksubmit(val,total,parttot) {
- document.SCORE.gradeOpt.value = val;
- if (val == "Save & Next") {
- for (i=0;i<=total;i++) {
- for (j=0;j<parttot;j++) {
- var partid = eval("document.SCORE.partid"+i+"_"+j+".value");
- var selopt = eval("document.SCORE.GD_SEL"+i+"_"+partid);
- if (selopt[0].selected) {
- var points = eval("document.SCORE.GD_BOX"+i+"_"+partid+".value");
- if (points == "") {
- var name = eval("document.SCORE.name"+i+".value");
- alert("Please assign a score for "+name+", part "+partid+".");
- return false;
- }
- }
+//======= Check that a score is assigned for all the problems (page/sequence grading only) =========
+ function checkSubmitPage(formname,total) {
+ noscore = new Array(100);
+ var ptr = 0;
+ for (i=1;i<total;i++) {
+ var partid = eval("formname.q_"+i+".value");
+ var selopt = eval("formname.GD_SEL"+i+"_"+partid);
+ if (selopt[0].selected) {
+ var points = eval("formname.GD_BOX"+i+"_"+partid+".value");
+ var status = eval("formname.solved"+i+"_"+partid+".value");
+ if (points == "" && status != "correct_by_student") {
+ noscore[ptr] = i;
+ ptr++;
+ }
+ }
+ }
+ if (ptr != 0) {
+ var sense = ptr == 1 ? ": " : "s: ";
+ var prolist = "";
+ if (ptr == 1) {
+ prolist = noscore[0];
+ } else {
+ var i = 0;
+ while (i < ptr-1) {
+ prolist += noscore[i]+", ";
+ i++;
+ }
+ prolist += "and "+noscore[i];
+ }
+ var resp = confirm("You did not assign any score for the following problem"+sense+prolist+". Continue?");
+ if (resp == false) {
+ return false;
+ }
+ }
- }
- }
+ formname.submit();
+ }
+</script>
+SUBJAVASCRIPT
+}
- }
- document.SCORE.submit();
- }
+#--- javascript for essay type problem --
+sub sub_page_kw_js {
+ my $request = shift;
+ $request->print(<<SUBJAVASCRIPT);
+<script type="text/javascript" language="javascript">
//===================== Show list of keywords ====================
function keywords(keyform) {
@@ -797,9 +882,65 @@
SUBJAVASCRIPT
}
+#--- displays the grading box, used in essay type problem and grading by page/sequence
+sub gradeBox {
+ my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_;
+
+ my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').
+ '/check.gif" height="16" border="0" />';
+
+ my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
+ my $wgtmsg = ($wgt > 0 ? '(problem weight)' :
+ '<font color="red">problem weight assigned by computer</font>');
+ $wgt = ($wgt > 0 ? $wgt : '1');
+ my $score = ($$record{'resource.'.$partid.'.awarded'} eq '' ?
+ '' : $$record{'resource.'.$partid.'.awarded'}*$wgt);
+ my $result='<input type="hidden" name="WGT'.$counter.'_'.$partid.'" value="'.$wgt.'" />'."\n";
+
+ $result.='<table border="0"><tr><td>'.
+ '<b>Part </b>'.$partid.' <b>Points: </b></td><td>'."\n";
+
+ my $ctr = 0;
+ $result.='<table border="0"><tr>'."\n"; # display radio buttons in a nice table 10 across
+ while ($ctr<=$wgt) {
+ $result.= '<td><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
+ 'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.
+ $ctr.','.$wgt.')" value="'.$ctr.'" '.
+ ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";
+ $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
+ $ctr++;
+ }
+ $result.='</tr></table>';
+
+ $result.='</td><td> <b>or</b> </td>'."\n";
+ $result.='<td><input type="text" name="GD_BOX'.$counter.'_'.$partid.'"'.
+ ($score ne ''? ' value = "'.$score.'"':'').' size="4" '.
+ 'onChange="javascript:updateRadio(this.form,\''.$counter.'_'.$partid.'\','.
+ $wgt.')" /></td>'."\n";
+ $result.='<td>/'.$wgt.' '.$wgtmsg.
+ ($$record{'resource.'.$partid.'.solved'} eq 'correct_by_student' ? ' '.$checkIcon : '').
+ ' </td><td>'."\n";
+
+ $result.='<select name="GD_SEL'.$counter.'_'.$partid.'" '.
+ 'onChange="javascript:clearRadBox(this.form,\''.$counter.'_'.$partid.'\')" >'."\n";
+ if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
+ $result.='<option> </option>'.
+ '<option selected="on">excused</option></select>'."\n";
+ } else {
+ $result.='<option selected="on"> </option>'.
+ '<option>excused</option></select>'."\n";
+ }
+ $result.="  \n";
+ $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".
+ '<input type="hidden" name="oldpts'.$counter.'_'.$partid.'" value="'.$score.'" />'."\n".
+ '<input type="hidden" name="solved'.$counter.'_'.$partid.'" value="'.
+ $$record{'resource.'.$partid.'.solved'}.'" />'."\n";
+ $result.='</td></tr></table>'."\n";
+ return $result;
+}
sub show_problem {
- my ($request,$symb,$uname,$udom,$removeform) = @_;
+ my ($request,$symb,$uname,$udom,$removeform,$viewon) = @_;
my $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,
$ENV{'request.course.id'});
if ($removeform) {
@@ -815,13 +956,15 @@
$rendered=~s|name="submit"|name="would_have_been_submit"|g;
}
my $result.='<table border="0" width="100%"><tr><td bgcolor="#777777">';
- $result.='<table border="0" width="100%"><tr><td bgcolor="#e6ffff">';
- $result.='<b> View of the problem - '.$ENV{'form.fullname'}.
- '</b></td></tr><tr><td bgcolor="#ffffff">'.$rendered.'<br />';
+ $result.='<table border="0" width="100%">';
+ $result.='<tr><td bgcolor="#e6ffff"><b> View of the problem - '.$ENV{'form.fullname'}.
+ '</b></td></tr>' if ($viewon);
+ $result.='<tr><td bgcolor="#ffffff">'.$rendered.'<br />';
$result.='<b>Correct answer:</b><br />'.$companswer;
$result.='</td></tr></table>';
$result.='</td></tr></table><br />';
- $request->print($result);
+ return $result;
+# $request->print($result);
}
# --------------------------- show submissions of a student, option to grade
@@ -843,13 +986,15 @@
# header info
if ($counter == 0) {
&sub_page_js($request);
+ &sub_page_kw_js($request);
$request->print('<h3> <font color="#339933">Submission Record</font></h3>'."\n".
- '<font size=+1> <b>Resource: </b>'.$url.'</font>'."\n");
+ '<font size=+1> <b>Problem: </b>'.
+ &Apache::lonnet::metadata($url,'title').'</font>'."\n");
# option to display problem, only once else it cause problems
# with the form later since the problem has a form.
if ($ENV{'form.vProb'} eq 'yes' or !$ENV{'form.vProb'}) {
- &show_problem($request,$symb,$uname,$udom,0);
+ $request->print(&show_problem($request,$symb,$uname,$udom,0,1));
}
# kwclr is the only variable that is guaranteed to be non blank
@@ -913,8 +1058,8 @@
}
if ($ENV{'form.vProb'} eq 'all') {
- $request->print('<br /><br /><br />');
- &show_problem($request,$symb,$uname,$udom,1);
+ $request->print('<br /><br /><br />') if ($counter > 0);
+ $request->print(&show_problem($request,$symb,$uname,$udom,1,1));
}
my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
@@ -1010,7 +1155,7 @@
} else {
my ($string,$timestamp)=
&get_last_submission (%record);
- my $lastsubonly.=''.
+ my $lastsubonly=''.
($$timestamp eq '' ? '' : '<b>Date Submitted:</b> '.
$$timestamp).'';
if ($$timestamp eq '') {
@@ -1081,9 +1226,9 @@
next if ($$handgrade{$_} =~ /:no$/);
push @partlist,$partid;
- $result=&gradeBox($symb,$uname,$udom,$counter,$partid,\%record);
+ $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
- $request->print($result);
+# $request->print($result);
}
$result='<input type="hidden" name="partlist'.$counter.
'" value="'.(join ":",@partlist).'" />'."\n";
@@ -1101,7 +1246,7 @@
'<input type="hidden" name="gradeOpt" value="" />'."\n";
if ($ENV{'form.handgrade'} eq 'yes') {
$endform.='<input type="button" value="Save & Next" '.
- 'onClick="javascript:checksubmit(\'Save & Next\','.
+ 'onClick="javascript:checksubmit(this.form,\'Save & Next\','.
$total.','.scalar(@partlist).');" TARGET=_self> '."\n";
my $ntstu ='<select name="NTSTU">'.
'<option>1</option><option>2</option>'.
@@ -1114,9 +1259,9 @@
$endform.='<input type="hidden" name="NTSTU" value="1" />'."\n";
}
$endform.='<input type="button" value="Next" '.
- 'onClick="javascript:checksubmit(\'Next\');" TARGET=_self> '."\n".
+ 'onClick="javascript:checksubmit(this.form,\'Next\');" TARGET=_self> '."\n".
'<input type="button" value="Previous" '.
- 'onClick="javascript:checksubmit(\'Previous\');" TARGET=_self> ';
+ 'onClick="javascript:checksubmit(this.form,\'Previous\');" TARGET=_self> ';
$endform.='(Next and Previous do not save the scores.)'."\n"
if ($ENV{'form.handgrade'} eq 'yes');
$endform.='</td><tr></table></form>';
@@ -1186,6 +1331,10 @@
while ($ctr < $ngrade) {
my ($uname,$udom) = split(/:/,$ENV{'form.unamedom'.$ctr});
my ($errorflag) = &saveHandGrade($request,$url,$symb,$uname,$udom,$ctr);
+ if ($errorflag eq 'no_score') {
+ $ctr++;
+ next;
+ }
my $includemsg = $ENV{'form.includemsg'.$ctr};
my ($subject,$message,$msgstatus) = ('','','');
@@ -1349,6 +1498,7 @@
my $pts = ($ENV{'form.GD_BOX'.$newflg.'_'.$_} ne '' ?
$ENV{'form.GD_BOX'.$newflg.'_'.$_} :
$ENV{'form.RADVAL'.$newflg.'_'.$_});
+ return 'no_score' if ($pts eq '' && $ENV{'form.GD_SEL'.$newflg.'_'.$_} eq '');
my $wgt = $ENV{'form.WGT'.$newflg.'_'.$_} eq '' ? 1 :
$ENV{'form.WGT'.$newflg.'_'.$_};
my $partial= $pts/$wgt;
@@ -1557,7 +1707,8 @@
my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'});
my $result='<h3><font color="#339933">Manual Grading</font></h3>';
- $result.='<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font>'."\n";
+ $result.='<font size=+1><b>Problem: </b>'.&Apache::lonnet::metadata($ENV{'form.url'},'title')
+ .'</font>'."\n";
#view individual student submission form - called using Javascript viewOneStudent
$result.=&jscriptNform($url,$symb);
@@ -1733,7 +1884,8 @@
my $symb=$ENV{'form.symb'};
my $url =$ENV{'form.url'};
my $title='<h3><font color="#339933">Current Grade Status</font></h3>';
- $title.='<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font><br />'."\n";
+ $title.='<font size=+1><b>Problem: </b>'.
+ &Apache::lonnet::metadata($ENV{'form.url'},'title').'</font><br />'."\n";
$title.='<font size=+1><b>Section: </b>'.$ENV{'form.section'}.'</font>'."\n";
$title.= &show_grading_menu_form ($symb,$url);
my $result= '<table border="0"><tr><td bgcolor="#777777">'."\n";
@@ -1957,7 +2109,8 @@
}
my $result='<table border="0">';
- $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$url.'</font></td></tr>';
+ $result.='<tr><td colspan=3><font size=+1><b>Problem: </b>'.&Apache::lonnet::metadata($url,'title')
+ .'</font></td></tr>';
my ($partlist,$handgrade) = &response_type($url);
my ($resptype,$hdgrade)=('','no');
for (sort keys(%$handgrade)) {
@@ -2141,7 +2294,8 @@
if (!$symb) {return '';}
my $result='<h3> <font color="#339933">Select a Grading Method</font></h3>';
$result.='<table border="0">';
- $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$url.'</font></td></tr>';
+ $result.='<tr><td colspan=3><font size=+1><b>Problem: </b>'.
+ &Apache::lonnet::metadata($ENV{'form.url'},'title').'</font></td></tr>';
my ($partlist,$handgrade) = &response_type($url);
my ($resptype,$hdgrade)=('','no');
for (sort keys(%$handgrade)) {
@@ -2294,7 +2448,6 @@
return $result;
}
-
sub pickStudentPage {
my ($request) = shift;
@@ -2308,8 +2461,8 @@
return;
}
var ptr = pullDownSelection(formname.selectpage);
- formname.page.value = formname.eval("page"+ptr).value;
- formname.title.value = formname.eval("title"+ptr).value;
+ formname.page.value = eval("formname.page"+ptr+".value");
+ formname.title.value = eval("formname.title"+ptr+".value");
formname.submit();
}
@@ -2344,18 +2497,16 @@
my $result='<h3><font color="#339933"> '.
'Manual Grading by Page or Sequence</font></h3>';
- my ($pagepath,$pagename,$type,$mapId) = ($symb =~ /(.*\/)(.*?\.(page|sequence))___(\d+)___/);
- my $curtitle = &Apache::lonnet::metadata($pagepath.$pagename,'title');
-
$result.='<form action="/adm/grades" method="post" name="displayPage">'."<br>\n";
$result.=' <b>Problems from:</b> <select name="selectpage">'."\n";
my ($titles,$symbx) = &getSymbMap();
-# shift @$titles; # skip the top level sequence
+ my ($curpage,$type,$mapId) = ($symb =~ /(.*?\.(page|sequence))___(\d+)___/);
my $ctr=0;
foreach (@$titles) {
my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
$result.='<option value="'.$ctr.'" '.
- ($showtitle eq $curtitle ? 'selected="on"' : '').'>'.$showtitle.'</option>'."\n";
+ ($$symbx{$_} =~ /$curpage$/ ? 'selected="on"' : '').
+ '>'.$showtitle.'</option>'."\n";
$ctr++;
}
$result.= '</select>'."<br>\n";
@@ -2369,11 +2520,12 @@
$result.='<input type="hidden" name="page" />'."\n";
$result.='<input type="hidden" name="title" />'."\n";
-# $result.=' <b>View Problems: </b><input type="radio" name="vProb" value="no" checked /> no '."\n".
-# '<input type="radio" name="vProb" value="yes" /> yes '."<br>\n";
-# $result.=' <b>Submission Details: </b>'.
-# '<input type="radio" name="lastSub" value="last" checked /> last sub only'."\n".
-# '<input type="radio" name="lastSub" value="all" /> all details'."\n";
+ $result.=' <b>View Problems: </b><input type="radio" name="vProb" value="no" checked /> no '."\n".
+ '<input type="radio" name="vProb" value="yes" /> yes '."<br>\n";
+ $result.=' <b>Submission Details: </b>'.
+ '<input type="radio" name="lastSub" value="none" /> none'."\n".
+ '<input type="radio" name="lastSub" value="datesub" checked /> dates and submissions'."\n".
+ '<input type="radio" name="lastSub" value="all" /> all details'."\n";
$result.='<input type="hidden" name="section" value="'.$getsec.'" />'."\n".
'<input type="hidden" name="command" value="displayPage" />'."\n".
'<input type="hidden" name="url" value="'.$url.'" />'."\n".
@@ -2434,10 +2586,32 @@
if ($curRes == $iterator->END_MAP()) { $depth--; }
if (ref($curRes) && $curRes->is_map()) {
- my $title = $curRes->compTitle();
- push @titles,$minder.'.'.$title; # minder, just in case two titles are identical
- $symbx{$minder.'.'.$title} = $curRes->symb();
- $minder++;
+ my ($mapUrl, $id, $resUrl) = split(/___/, $curRes->symb()); # check map contains at least one problem
+ my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
+
+ my $mapiterator = $navmap->getIterator($map->map_start(),
+ $map->map_finish());
+
+ my $mapdepth = 1;
+ my $countProblems = 0;
+ $mapiterator->next(); # skip the first BEGIN_MAP
+ my $mapcurRes = $mapiterator->next(); # for "current resource"
+ my $ctr=0;
+ while ($mapdepth > 0 && $ctr < 100) {
+ if($mapcurRes == $mapiterator->BEGIN_MAP) { $mapdepth++; }
+ if($mapcurRes == $mapiterator->END_MAP) { $mapdepth++; }
+
+ if (ref($mapcurRes) && $mapcurRes->is_problem() && !$mapcurRes->randomout) {
+ $countProblems++;
+ }
+ $ctr++;
+ }
+ if ($countProblems > 0) {
+ my $title = $curRes->compTitle();
+ push @titles,$minder.'.'.$title; # minder, just in case two titles are identical
+ $symbx{$minder.'.'.$title} = $curRes->symb();
+ $minder++;
+ }
}
$curRes = $iterator->next();
}
@@ -2449,18 +2623,21 @@
sub displayPage {
my ($request) = shift;
+ my ($symb,$url) = &get_symb_and_url();
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,'0');
my ($uname,$udom) = split(/:/,$ENV{'form.student'});
- my ($idx,$showtitle) = ($pageTitle =~ /(\d+)\.(.*)/);
my $result='<h3><font color="#339933"> '.$ENV{'form.title'}.'</font></h3>';
$result.='<h3> Student: '.$$fullname{$ENV{'form.student'}}.
'<font color="#999999"> ('.$uname.($udom eq $cdom ? '':':'.$udom).')</font></h3>'."\n";
+ &sub_page_js($request);
+ $request->print($result);
+
my $navmap = Apache::lonnavmaps::navmap-> new(
$ENV{'request.course.fn'}.'.db',
$ENV{'request.course.fn'}.'_parms.db',1, 1);
@@ -2470,128 +2647,231 @@
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
- my $depth = 1;
+ my $studentTable='<form action="/adm/grades" method="post" name="gradePage">'."\n".
+ '<input type="hidden" name="command" value="gradeByPage" />'."\n".
+ '<input type="hidden" name="student" value="'.$ENV{'form.student'}.'" />'."\n".
+ '<input type="hidden" name="page" value="'.$pageTitle.'" />'."\n".
+ '<input type="hidden" name="title" value="'.$ENV{'form.title'}.'" />'."\n".
+ '<input type="hidden" name="url" value="'.$url.'" />'."\n".
+ '<input type="hidden" name="symb" value="'.$symb.'" />'."\n";
+
+ my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').
+ '/check.gif" height="16" border="0" />';
+
+ $studentTable.=' <b>Note:</b> A problem graded correct ('.$checkIcon.
+ ') by the computer cannot be changed.'."\n".
+ '<table border="0"><tr><td bgcolor="#777777">'.
+ '<table border="0"><tr bgcolor="#e6ffff">'.
+ '<td align="center"><b> No </b></td>'.
+ '<td><b> '.($ENV{'form.vProb'} eq 'no' ? 'Title' : 'Problem View').'/Grade</b></td></tr>';
+
+ my ($depth,$ctr,$question) = (1,0,1);
$iterator->next(); # skip the first BEGIN_MAP
my $curRes = $iterator->next(); # for "current resource"
- my %symbx = ();
- my @titles = ();
- my %parts = ();
- my $ctr=0;
- my $minder=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();
+ if (scalar(@{$parts}) > 1) { shift @{$parts}; }
my $title = $curRes->compTitle();
- push @titles,$minder.'.'.$title; # minder, just in case two titles are identical
- if (scalar(@{$parts}) > 1) { shift @{$parts}; }
- $parts{$minder.'.'.$title} = join '::',@{$parts};
- $symbx{$minder.'.'.$title} = $curRes->symb();
- $minder++;
+ my $symbx = $curRes->symb();
+ $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$question.
+ (scalar(@{$parts}) == 1 ? '' : '<br>('.scalar(@{$parts}).' parts)').'</td>';
+ $studentTable.='<td valign="top">';
+ 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|<form(.*?)>||g;
+ $companswer=~s|</form>||g;
+
+# while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a>
+# $request->print('match='.$1.'<br>');
+# $companswer =~ s/$1/ /s;
+# }
+# $companswer =~ s/<table border=\"1\">/<table border=\"0\">/g;
+ $studentTable.=' <b>'.$title.'</b> <br> <b>Correct answer:</b><br>'.$companswer;
+ }
+
+ my %record = &Apache::lonnet::restore($symbx,$ENV{'request.course.id'},$udom,$uname);
+
+ if ($ENV{'form.lastSub'} eq 'datesub') {
+ if ($record{'version'} eq '') {
+ $studentTable.='<br /> <font color="red">No recorded submission for this problem</font><br />';
+ } else {
+ $studentTable.='<table border="0" width="100%"><tr><td bgcolor="#777777">'.
+ '<table border="0" width="100%"><tr bgcolor="#e6ffff">'.
+ '<td><b>Date/Time</b></td>'.
+ '<td><b>Submission</b></td>'.
+ '<td><b>Status </b></td></tr>';
+ my ($version);
+ for ($version=1;$version<=$record{'version'};$version++) {
+ my $timestamp = scalar(localtime($record{$version.':timestamp'}));
+ $studentTable.='<tr bgcolor="#ffffff" valign="top"><td>'.$timestamp.'</td>';
+ my @versionKeys = split(/\:/,$record{$version.':keys'});
+ my @displaySub = ();
+ foreach my $partid (@{$parts}) {
+ my @matchKey = grep /^resource\.$partid\..*?\.submission$/,@versionKeys;
+ $displaySub[0].=(exists $record{$version.':'.$matchKey[0]}) ?
+ '<b>Part:</b> '.$partid.' <b>Submission:</b> '
+ .$record{$version.':'.$matchKey[0]}.'<br />' : '';
+ $displaySub[1].=(exists $record{"$version:resource.$partid.award"}) ?
+ '<b>Part:</b> '.$partid.' '.
+ $record{"$version:resource.$partid.award"}.'/'.
+ $record{"$version:resource.$partid.solved"}.'<br />' : '';
+ }
+ $displaySub[1].=(exists $record{"$version:resource.regrader"}) ?
+ 'Manually graded by '.$record{"$version:resource.regrader"} : '';
+ $studentTable.='<td>'.$displaySub[0].' </td><td>'.$displaySub[1].' </td></tr>';
+ }
+ $studentTable.='</table></td></tr></table>';
+ }
+ } 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.='<input type="hidden" name="q_'.$question.'" value="'.$partid.'" />'."\n";
+ $question++;
+ }
+ $studentTable.='</td></tr>';
}
$curRes = $iterator->next();
$ctr++;
}
+ $navmap->init();
+ $studentTable.='</td></tr></table></td></tr></table>'."\n".
+ ' <input type="button" value="Save" '.
+ 'onClick="javascript:checkSubmitPage(this.form,'.$question.');" TARGET=_self />'.
+ '</form>'."\n";
+ $studentTable.=&show_grading_menu_form($symb,$url);
+ $request->print($studentTable);
+
+ return '';
+}
+
+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,'0');
+ my ($uname,$udom) = split(/:/,$ENV{'form.student'});
+
+ my $result='<h3><font color="#339933"> '.$ENV{'form.title'}.'</font></h3>';
+ $result.='<h3> Student: '.$$fullname{$ENV{'form.student'}}.
+ '<font color="#999999"> ('.$uname.($udom eq $cdom ? '':':'.$udom).')</font></h3>'."\n";
- $navmap->init();
$request->print($result);
- &sub_page_js($request);
- my $studentTable='<form action="/adm/grades" method="post" name="gradePage">'."\n".
- '<input type="hidden" name="command" value="gradePage" />'."\n".
- '<input type="hidden" name="student" value="'.$ENV{'form.student'}.'" />'."\n".
- '<input type="hidden" name="page" value="'.$pageTitle.'" />'."\n".
- '<input type="hidden" name="title" value="'.$ENV{'form.title'}.'" />'."\n";
+ 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
- $studentTable.=
- '<table border="0"><tr><td bgcolor="#777777">'.
+ my $iterator = $navmap->getIterator($map->map_start(),
+ $map->map_finish());
+
+ my $studentTable='<table border="0"><tr><td bgcolor="#777777">'.
'<table border="0"><tr bgcolor="#e6ffff">'.
'<td align="center"><b> No </b></td>'.
- '<td><b> Title</b></td>'.
- '<td><b> Answer</b></td>'.
- '<td><b> Grade</b></td></tr>';
- my $question=1;
- foreach (@titles) {
- my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
- my @parts = split(/::/,$parts{$_});
- $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$question.
- (scalar(@parts) == 1 ? '' : '<br>('.scalar(@parts).' parts)').'</td>';
- $studentTable.='<td valign="top"> '.$showtitle.' </td>';
- $studentTable.='<td> '.
- &Apache::loncommon::get_student_answers($symbx{$_},$uname,$udom,$ENV{'request.course.id'}).'</td>';
+ '<td><b> Title </b></td>'.
+ '<td><b> Previous Score </b></td>'.
+ '<td><b> New Score </b></td></tr>';
- my %record = &Apache::lonnet::restore($symbx{$_},$ENV{'request.course.id'},$udom,$uname);
- $studentTable.='<td> ';
- foreach my $partid (@parts) {
- $studentTable.=&gradeBox($symbx{$_},$uname,$udom,$question,$partid,\%record);
- $question++;
- }
- $studentTable.='</td></tr>';
+ $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();
+ if (scalar(@{$parts}) > 1) { shift @{$parts}; }
+ my $title = $curRes->compTitle();
+ my $symbx = $curRes->symb();
+ $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$question.
+ (scalar(@{$parts}) == 1 ? '' : '<br>('.scalar(@{$parts}).' parts)').'</td>';
+ $studentTable.='<td valign="top"> <b>'.$title.'</b> </td>';
+
+ 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].=' <b>Part</b> '.$partid.' = '.
+ (($oldstatus eq 'excused') ? 'excused' : $oldpts).
+ ' <br>';
+ $displayPts[1].=' <b>Part</b> '.$partid.' = '.
+ ($oldstatus eq 'correct_by_student' ? $oldpts :
+ (($score eq 'excused') ? 'excused' : $newpts)).
+ ' <br>';
+
+ $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;
- $studentTable.='</table></td></tr></table>';
- $studentTable.='</form>';
+ $changeflag++;
+ }
+ if (scalar(keys(%newrecord)) > 0) {
+ $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+ &Apache::lonnet::cstore(\%newrecord,$symbx,$ENV{'request.course.id'},
+ $udom,$uname);
+ }
+ $studentTable.='<td valign="top">'.$displayPts[0].'</td>'.
+ '<td valign="top">'.$displayPts[1].'</td>'.
+ '</tr>';
+ }
+ $curRes = $iterator->next();
+ $ctr++;
+ }
+ $navmap->init();
+
+ $studentTable.='</td></tr></table></td></tr></table>';
+ $studentTable.=($changeflag == 0 ? 'No score was changed or updated.' :
+ 'The scores were changed for '.
+ $changeflag.' problem'.($changeflag == 1 ? '.' : 's.'));
+ $studentTable.=&show_grading_menu_form($ENV{'form.symb'},$ENV{'form.url'});
$request->print($studentTable);
return '';
}
-sub gradeBox {
- my ($symb,$uname,$udom,$counter,$partid,$record) = @_;
- my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
- my $wgtmsg = ($wgt > 0 ? '(problem weight)' :
- '<font color="red">problem weight assigned by computer</font>');
- $wgt = ($wgt > 0 ? $wgt : '1');
- my $score = ($$record{'resource.'.$partid.'.awarded'} eq '' ?
- '' : $$record{'resource.'.$partid.'.awarded'}*$wgt);
- my $result='<input type="hidden" name="WGT'.$counter.'_'.$partid.'" value="'.$wgt.'" />';
- $result.='<table border="0"><tr><td><b>Part </b>'.$partid.' <b>Points: </b></td><td>';
-
- my $ctr = 0;
- $result.='<table border="0"><tr>'; # display radio buttons in a nice table 10 across
- while ($ctr<=$wgt) {
- $result.= '<td><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
- 'onclick="javascript:writeBox(this.form.GD_BOX'.$counter.'_'.$partid.
- ',this.form.GD_SEL'.$counter.'_'.$partid.','.$ctr.
- ',this.form.stores'.$counter.'_'.$partid.')" '.
- ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";
- $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
- $ctr++;
- }
- $result.='</tr></table>';
- $result.='</td><td> <b>or</b> </td>';
- $result.='<td><input type="text" name="GD_BOX'.$counter.'_'.$partid.'"'.
- ($score ne ''? ' value = "'.$score.'"':'').' size="4" '.
- 'onChange="javascript:updateRadio(this.form.RADVAL'.$counter.'_'.$partid.
- ',this.form.GD_BOX'.$counter.'_'.$partid.
- ',this.form.GD_SEL'.$counter.'_'.$partid.
- ',this.form.stores'.$counter.'_'.$partid.
- ','.$wgt.')" /></td>'."\n";
- $result.='<td>/'.$wgt.' '.$wgtmsg.' </td><td>';
-
- $result.='<select name="GD_SEL'.$counter.'_'.$partid.'" '.
- 'onChange="javascript:clearRadBox(this.form.RADVAL'.$counter.'_'.$partid.
- ',this.form.GD_BOX'.$counter.'_'.$partid.
- ',this.form.GD_SEL'.$counter.'_'.$partid.
- ',this.form.stores'.$counter.'_'.$partid.')" >'."\n";
- if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
- $result.='<option> </option>'.
- '<option selected="on">excused</option></select>';
- } else {
- $result.='<option selected="on"> </option>'.
- '<option>excused</option></select>';
- }
- $result.="  \n";
- $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="0" />';
- $result.='</td></tr></table>'."\n";
- return $result;
-}
#--- Form to input a receipt number ---
sub verifyReceipt_form {
@@ -2688,6 +2968,8 @@
&pickStudentPage($request);
} elsif ($command eq 'displayPage') {
&displayPage($request);
+ } elsif ($command eq 'gradeByPage') {
+ &updateGradeByPage($request);
} elsif ($command eq 'processGroup') {
&processGroup($request);
} elsif ($command eq 'gradingmenu') {
--ng1047411122--