[LON-CAPA-cvs] cvs: loncom /homework grades.pm

ng lon-capa-cvs@mail.lon-capa.org
Fri, 26 Jul 2002 20:28:42 -0000


This is a MIME encoded message

--ng1027715322
Content-Type: text/plain

ng		Fri Jul 26 16:28:42 2002 EDT

  Modified files:              
    /loncom/homework	grades.pm 
  Log:
  Added all the necessary javascript codes to do grading by section or class.
  Still to be implemented - saving the scores.
  
  
  
--ng1027715322
Content-Type: text/plain
Content-Disposition: attachment; filename="ng-20020726162842.txt"

Index: loncom/homework/grades.pm
diff -u loncom/homework/grades.pm:1.41 loncom/homework/grades.pm:1.42
--- loncom/homework/grades.pm:1.41	Thu Jul 25 17:25:38 2002
+++ loncom/homework/grades.pm	Fri Jul 26 16:28:42 2002
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.41 2002/07/25 21:25:38 ng Exp $
+# $Id: grades.pm,v 1.42 2002/07/26 20:28:42 ng Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -321,55 +321,6 @@
     return @parts;
 }
 
-#FIXME need to look at the metadata <stores> spec on what type of data to accept and provide an
-#interface based on that, also do that to above function.
-sub setstudentgrade {
-    my ($url,$symb,$courseid,$student,@parts) = @_;
-    my $result ='';
-    my ($stuname,$domain) = split(/:/,$student);
-    my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$stuname);
-    my %newrecord;
-
-    foreach my $part (@parts) {
-	my ($temp,$part,$type)=split(/_/,$part);
-	my $oldscore=$record{"resource.$part.$type"};
-	my $newscore=$ENV{"form.GRADE.$student.$part.$type"};
-	if ($type eq 'solved') {
-	    my $update=0;
-	    if ($newscore eq 'nothing' ) {
-		if ($oldscore ne '') {
-		    $update=1;
-		    $newscore = '';
-		}
-	    } elsif ($oldscore !~ m/^$newscore/) {
-		$update=1;
-		$result.="Updating $stuname to $newscore<br />\n";
-		if ($newscore eq 'correct')   { $newscore = 'correct_by_override'; }
-		if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; }
-		if ($newscore eq 'excused')   { $newscore = 'excused'; }
-		if ($newscore eq 'ungraded')  { $newscore = 'ungraded_attempted'; }
-	    } else {
-		#$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
-	    }
-	    if ($update) { $newrecord{"resource.$part.$type"}=$newscore; }
-	} else {
-	    if ($oldscore ne $newscore) {
-		$newrecord{"resource.$part.$type"}=$newscore;
-		$result.="Updating $student"."'s status for $part.$type to $newscore<br />\n";
-	    } else {
-		#$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
-	    }
-	}
-    }
-    if ( scalar(keys(%newrecord)) > 0 ) {
-	$newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
-#       &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname);
-
-	$result.="Stored away ".scalar(keys(%newrecord))." elements.<br />\n";
-    }
-    return $result;
-}
-
 sub print_hash {
     my ($request, $hash) = @_;
     $request->print('<table border=1><tr><td>Key</td><td>Value</td></tr>');
@@ -1067,8 +1018,9 @@
     return $result;
 }
 
-sub viewgrades {
-    my ($request) = @_;
+sub viewgrades_js {
+    my ($request) = shift;
+
     $request->print(<<VIEWJAVASCRIPT);
 <script type="text/javascript" language="javascript">
     function viewOneStudent(user) {
@@ -1076,38 +1028,140 @@
 	document.onestudent.submit();
     }
 
-
     function writePoint(partid,weight,point) {
+	var radioButton = eval("document.classgrade.RADVAL_"+partid);
+	var textbox = eval("document.classgrade.TEXTVAL_"+partid);
+	if (point == "textval") {
+	    var point = eval("document.classgrade.TEXTVAL_"+partid+".value");
+	    if (isNaN(point) || point < 0) {
+		alert("A number equal or greater than 0 is expected. Entered value = "+point);
+		var resetbox = false;
+		for (var i=0; i<radioButton.length; i++) {
+		    if (radioButton[i].checked) {
+			textbox.value = i;
+			resetbox = true;
+		    }
+		}
+		if (!resetbox) {
+		    textbox.value = "";
+		}
+		return;
+	    }
+	    for (var i=0; i<radioButton.length; i++) {
+		radioButton[i].checked=false;
+		if (point == i) {
+		    radioButton[i].checked=true;
+		}
+	    }
+
+	} else {
+	    textbox.value = point;
+	}
 	for (i=0;i<document.classgrade.total.value;i++) {
 	    var user = eval("document.classgrade.counter"+i+".value");
-	    var scorename = eval("document.classgrade.GRADE_"+user+"_"+partid+"_awarded");
-	    scorename.value = point;
+	    var scorename = eval("document.classgrade.GRADE_"+user+
+				 "_"+partid+"_awarded");
+	    var saveval   = eval("document.classgrade.GRADE_"+user+
+				 "_"+partid+"_solved_save.value");
+	    var selname   = eval("document.classgrade.GRADE_"+user+"_"+partid+"_solved");
+	    if (saveval != "correct") {
+		scorename.value = point;
+		selname[0].selected = true;
+	    }
 	}
-}
+	var selval   = eval("document.classgrade.SELVAL_"+partid);
+	selval[0].selected = true;
+    }
+
+    function writeRadText(partid,weight) {
+	var selval   = eval("document.classgrade.SELVAL_"+partid);
+	if (selval[1].selected) {
+	    var radioButton = eval("document.classgrade.RADVAL_"+partid);
+	    for (var i=0; i<radioButton.length; i++) {
+		radioButton[i].checked=false;
+
+	    }
+	    var textbox = eval("document.classgrade.TEXTVAL_"+partid);
+	    textbox.value = "";
+
+	    for (i=0;i<document.classgrade.total.value;i++) {
+		var user = eval("document.classgrade.counter"+i+".value");
+		var scorename = eval("document.classgrade.GRADE_"+user+
+				     "_"+partid+"_awarded");
+		var saveval   = eval("document.classgrade.GRADE_"+user+
+				     "_"+partid+"_solved_save.value");
+		var selname   = eval("document.classgrade.GRADE_"+user+
+				     "_"+partid+"_solved");
+		if (saveval != "correct") {
+		    scorename.value = "";
+		    selname[1].selected = true;
+		}
+	    }
+	}
+    }
+
+    function changeSelect(partid,user) {
+	var selval = eval("document.classgrade.GRADE_"+user+'_'+partid+"_solved");
+	selval[0].selected = true;
+    }
+
+    function changeOneScore(partid,user) {
+	var selval = eval("document.classgrade.GRADE_"+user+'_'+partid+"_solved");
+	if (selval[1].selected) {
+	    var boxval = eval("document.classgrade.GRADE_"+user+'_'+partid+"_awarded");
+	    boxval.value = "";
+	}
+    }
+
+    function resetEntry(numpart) {
+	for (ctpart=0;ctpart<numpart;ctpart++) {
+	    var partid = eval("document.classgrade.partid_"+ctpart+".value");
+	    var radioButton = eval("document.classgrade.RADVAL_"+partid);
+	    var textbox = eval("document.classgrade.TEXTVAL_"+partid);
+	    var selval  = eval("document.classgrade.SELVAL_"+partid);
+	    for (var i=0; i<radioButton.length; i++) {
+		radioButton[i].checked=false;
+
+	    }
+	    textbox.value = "";
+	    selval[0].selected = true;
+
+	    for (i=0;i<document.classgrade.total.value;i++) {
+		var user = eval("document.classgrade.counter"+i+".value");
+		var resetscore = eval("document.classgrade.GRADE_"+user+
+				      "_"+partid+"_awarded");
+		resetscore.value = eval("document.classgrade.GRADE_"+user+
+					"_"+partid+"_awarded_save.value");
+
+		var saveselval   = eval("document.classgrade.GRADE_"+user+
+				     "_"+partid+"_solved_save.value");
+
+		var selname   = eval("document.classgrade.GRADE_"+user+"_"+partid+"_solved");
+		if (saveselval == "excused") {
+		    selname[1].selected = true;
+		} else {
+		    selname[0].selected = true;
+		}
+	    }
+	}
+    }
+
+
 </script>
 VIEWJAVASCRIPT
+}
+
+sub viewgrades {
+    my ($request) = shift;
+    &viewgrades_js($request);
 
     my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); 
     $request->print ('<h2><font color="#339933">Manual Grading</font></h2>');
 
-    my $result='<table border="0">';
-    $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$ENV{'form.url'}.
-	'</font></td></tr>'."\n";
-    my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
-    my %weight = ();
-    for (sort keys(%$handgrade)) {
-	my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
-	my ($partid,$respid) = split (/_/);
-	my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
-	$weight{$partid} = $wgt eq '' ? '1' : $wgt;
-	$result.='<tr><td><b>Part id: </b>'.$partid.'</td>'.
-	    '<td><b>Type: </b>'.$responsetype.'</td>'.
-	    '<td><b>Handgrade: </b>'.$handgrade.'</font></td></tr>'."\n";
-    }
-    $request->print($result.'</table>'."\n");
+    my $result='<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font>'."\n";
 
     #view individual student submission form - called using Javascript viewOneStudent
-    $result = '<form action="/adm/grades" method="post" name="onestudent">'."\n".
+    $result.= '<form action="/adm/grades" method="post" name="onestudent">'."\n".
 	'<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
 	'<input type="hidden" name="url"     value="'.$url.'" />'."\n".
 	'<input type="hidden" name="command" value="submission" />'."\n".
@@ -1120,26 +1174,50 @@
 	'<input type="hidden" name="url"     value="'.$url.'" />'."\n".
 	'<input type="hidden" name="command" value="editgrades" />'."\n".
 	'<input type="hidden" name="section" value="'.$ENV{'form.section'}.'" />'."\n";
-    $result.='To assign the same score for all the students use the radio buttons or box below. '.
-	'To assign individual score fill in the score for each student in the table below.<br />';
+
+    $result.='To assign the same score for all the students use the radio buttons or '.
+	'text box below. To assign scores individually fill in the score boxes for '.
+	'each student in the table below. <font color="red">A score that has already '.
+	'been graded does not get changed using the radio buttons or text box. '.
+	'If needed, it has to be changed individually.</font>';
+
+    my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
+    my %weight = ();
+    my $ctsparts = 0;
     $result.='<table border="0">';
-    for (sort keys (%weight)) {
+    for (sort keys(%$handgrade)) {
+	my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
+	my ($partid,$respid) = split (/_/);
+	my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
+	$weight{$partid} = $wgt eq '' ? '1' : $wgt;
+
+	$result.='<input type="hidden" name="partid_'.$ctsparts.'" value="'.$partid.'" />'."\n";
+	$result.='<tr><td><b>Part ID:</b> '.$partid.'&nbsp; &nbsp;</td><td>';
+	$result.='<table border="0"><tr>';  
 	my $ctr = 0;
-	$result.='<tr><td><b>Part</b> '.$_.'</td><td>';
-	$result.='<table border="0"><tr>';  # display radio buttons in a nice table 10 across
-	while ($ctr<=$weight{$_}) {
-	    $result.= '<td><input type="radio" name="RADVAL_'.$_.'" '.
-		'onclick="javascript:writePoint('.$_.','.$weight{$_}.
+	while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
+	    $result.= '<td><input type="radio" name="RADVAL_'.$partid.'" '.
+		'onclick="javascript:writePoint('.$partid.','.$weight{$partid}.
 		','.$ctr.')" />'.$ctr."</td>\n";
 	    $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
 	    $ctr++;
 	}
 	$result.='</tr></table>';
+	$result.= '</td><td><b> or </b><input type="text" name="TEXTVAL_'.$partid.'" size="4" '.
+	    'onChange="javascript:writePoint('.$partid.','.$weight{$partid}.',\'textval\')" /> /'.
+	    $weight{$partid}.' (problem weight)</td>'."\n";
+	$result.= '</td><td><select name="SELVAL_'.$partid.'"'.
+	    'onChange="javascript:writeRadText('.$partid.','.$weight{$partid}.')" /> '.
+	    '<option selected="on"> </option>'.
+	    '<option>excused</option></select></td></tr>'."\n";
+	$ctsparts++;
     }
-    $result.='</tr></table>';
+    $result.='</table><input type="hidden" name="totalparts" value="'.$ctsparts.'" />';
+    $result.='<input type="button" value="Reset" '.
+	'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self> &nbsp &nbsp;';
+    $result.= '<input type="submit" name="submit"  value="Submit Changes" />'."\n";
 
-    $result.= '<input type="submit" name="submit"  value="Submit Changes" />'."\n".
-	'<table border=0><tr><td bgcolor="#777777">'."\n".
+    $result.= '<table border=0><tr><td bgcolor="#777777">'."\n".
 	'<table border=0><tr bgcolor="#deffff">'.
 	'<td><b>Username</b></td><td><b>Fullname</b></td><td><b>Domain</b></td>'."\n";
     #get list of parts for this problem
@@ -1151,10 +1229,11 @@
 	if ($display =~ /^Partial Credit Factor/) {
 	    $_ = $display;
 	    my ($partid) = /.*?(\d+).*/;
-	    $result.='<td><b>Score Part '.$partid.'<br>(weight = '.$weight{$partid}.')</b></td>'."\n";
+	    $result.='<td><b>Score Part '.$partid.'<br>(weight = '.
+		$weight{$partid}.')</b></td>'."\n";
 	    next;
 	}
-	$display =~ s/Problem Status/Grade Status/;
+	$display =~ s/Problem Status/Grade Status<br>/;
 	$result.='<td><b>'.$display.'</b></td>'."\n";
     }
     $result.='</tr>';
@@ -1187,20 +1266,24 @@
 	my $score=$record{"resource.$part.$type"};
 	next if $type eq 'tries';
 	if ($type eq 'awarded') {
-	    my $pts = $score*$$weight{$part};
-	    $result.='<td align="middle"><input type="text" name="GRADE_'.$username.'_'.$part.'_'.$type.
-		'" value="'.$pts.'" size="4" /></td>'."\n";
-#	    $result.='<td align="middle"><input type="text" name="GRADE.'.$student.'.'.$part.'.'.$type.
-#		'" value="'.$pts.'" size="4" /></td>'."\n";
-#	} elsif ($type eq 'tries') {
-#	    $result.='<td align="middle">'.$score.'&nbsp;</td>'."\n";
+	    my $pts = $score eq '' ? '' : $score*$$weight{$part};
+	    $result.='<input type="hidden" name="'.
+		'GRADE_'.$username.'_'.$part.'_awarded_save" value="'.$pts.'" />'."\n";
+	    $result.='<td align="middle"><input type="text" name="'.
+		'GRADE_'.$username.'_'.$part.'_awarded"'.
+		'onChange="javascript:changeSelect('.$part.',\''.$username.'\')" value="'.
+		$pts.'" size="4" /></td>'."\n";
 	} elsif ($type eq 'solved') {
 	    my ($status,$foo)=split(/_/,$score,2);
-	    $result.="<td align=\"middle\"><select name=\"GRADE.$student.$part.$type\">\n";
-	    my $optsel = '<option>correct</option><option>incorrect</option><option>excused</option>'.
-		'<option>ungraded</option><option>nothing</option>'."\n";
 	    $status = 'nothing' if ($status eq '');
-	    $optsel =~ s/<option>$status/<option selected="on">$status/;
+	    $result.='<input type="hidden" name="'.
+		'GRADE_'.$username.'_'.$part.'_solved_save" value="'.$status.'" />'."\n";
+	    $result.='<td align="middle"><select name="'.
+		'GRADE_'.$username.'_'.$part.'_solved" '.
+		'onChange="javascript:changeOneScore('.$part.',\''.$username.'\')" >'."\n";
+	    my $optsel = '<option selected="on"> </option><option>excused</option>'."\n";
+	    $optsel = '<option> </option><option selected="on">excused</option>'."\n"
+		if ($status eq 'excused');
 	    $result.=$optsel;
 	    $result.="</select></td>\n";
 	}
@@ -1232,6 +1315,57 @@
     $result.='<input type="submit" name="submit" value="See Grades" /></table></form>';
     return $result;
 }
+
+
+#FIXME need to look at the metadata <stores> spec on what type of data to accept and provide an
+#interface based on that, also do that to above function.
+sub setstudentgrade {
+    my ($url,$symb,$courseid,$student,@parts) = @_;
+    my $result ='';
+    my ($stuname,$domain) = split(/:/,$student);
+    my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$stuname);
+    my %newrecord;
+
+    foreach my $part (@parts) {
+	my ($temp,$part,$type)=split(/_/,$part);
+	my $oldscore=$record{"resource.$part.$type"};
+	my $newscore=$ENV{"form.GRADE.$student.$part.$type"};
+	if ($type eq 'solved') {
+	    my $update=0;
+	    if ($newscore eq 'nothing' ) {
+		if ($oldscore ne '') {
+		    $update=1;
+		    $newscore = '';
+		}
+	    } elsif ($oldscore !~ m/^$newscore/) {
+		$update=1;
+		$result.="Updating $stuname to $newscore<br />\n";
+		if ($newscore eq 'correct')   { $newscore = 'correct_by_override'; }
+		if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; }
+		if ($newscore eq 'excused')   { $newscore = 'excused'; }
+		if ($newscore eq 'ungraded')  { $newscore = 'ungraded_attempted'; }
+	    } else {
+		#$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
+	    }
+	    if ($update) { $newrecord{"resource.$part.$type"}=$newscore; }
+	} else {
+	    if ($oldscore ne $newscore) {
+		$newrecord{"resource.$part.$type"}=$newscore;
+		$result.="Updating $student"."'s status for $part.$type to $newscore<br />\n";
+	    } else {
+		#$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
+	    }
+	}
+    }
+    if ( scalar(keys(%newrecord)) > 0 ) {
+	$newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+#       &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname);
+
+	$result.="Stored away ".scalar(keys(%newrecord))." elements.<br />\n";
+    }
+    return $result;
+}
+
 
 sub sub_page_js {
     my $request = shift;

--ng1027715322--