Diff for /loncom/homework/grades.pm between versions 1.41 and 1.42

version 1.41, 2002/07/25 21:25:38 version 1.42, 2002/07/26 20:28:42
Line 321  sub getpartlist { Line 321  sub getpartlist {
     return @parts;      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 {  sub print_hash {
     my ($request, $hash) = @_;      my ($request, $hash) = @_;
     $request->print('<table border=1><tr><td>Key</td><td>Value</td></tr>');      $request->print('<table border=1><tr><td>Key</td><td>Value</td></tr>');
Line 1067  sub verifyReceipt_form { Line 1018  sub verifyReceipt_form {
     return $result;      return $result;
 }  }
   
 sub viewgrades {  sub viewgrades_js {
     my ($request) = @_;      my ($request) = shift;
   
     $request->print(<<VIEWJAVASCRIPT);      $request->print(<<VIEWJAVASCRIPT);
 <script type="text/javascript" language="javascript">  <script type="text/javascript" language="javascript">
     function viewOneStudent(user) {      function viewOneStudent(user) {
Line 1076  sub viewgrades { Line 1028  sub viewgrades {
  document.onestudent.submit();   document.onestudent.submit();
     }      }
   
   
     function writePoint(partid,weight,point) {      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++) {   for (i=0;i<document.classgrade.total.value;i++) {
     var user = eval("document.classgrade.counter"+i+".value");      var user = eval("document.classgrade.counter"+i+".value");
     var scorename = eval("document.classgrade.GRADE_"+user+"_"+partid+"_awarded");      var scorename = eval("document.classgrade.GRADE_"+user+
     scorename.value = point;   "_"+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>  </script>
 VIEWJAVASCRIPT  VIEWJAVASCRIPT
   }
   
   sub viewgrades {
       my ($request) = shift;
       &viewgrades_js($request);
   
     my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'});       my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); 
     $request->print ('<h2><font color="#339933">Manual Grading</font></h2>');      $request->print ('<h2><font color="#339933">Manual Grading</font></h2>');
   
     my $result='<table border="0">';      my $result='<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font>'."\n";
     $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");  
   
     #view individual student submission form - called using Javascript viewOneStudent      #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="symb"    value="'.$symb.'" />'."\n".
  '<input type="hidden" name="url"     value="'.$url.'" />'."\n".   '<input type="hidden" name="url"     value="'.$url.'" />'."\n".
  '<input type="hidden" name="command" value="submission" />'."\n".   '<input type="hidden" name="command" value="submission" />'."\n".
Line 1120  VIEWJAVASCRIPT Line 1174  VIEWJAVASCRIPT
  '<input type="hidden" name="url"     value="'.$url.'" />'."\n".   '<input type="hidden" name="url"     value="'.$url.'" />'."\n".
  '<input type="hidden" name="command" value="editgrades" />'."\n".   '<input type="hidden" name="command" value="editgrades" />'."\n".
  '<input type="hidden" name="section" value="'.$ENV{'form.section'}.'" />'."\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">';      $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;   my $ctr = 0;
  $result.='<tr><td><b>Part</b> '.$_.'</td><td>';   while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
  $result.='<table border="0"><tr>';  # display radio buttons in a nice table 10 across      $result.= '<td><input type="radio" name="RADVAL_'.$partid.'" '.
  while ($ctr<=$weight{$_}) {   'onclick="javascript:writePoint('.$partid.','.$weight{$partid}.
     $result.= '<td><input type="radio" name="RADVAL_'.$_.'" '.  
  'onclick="javascript:writePoint('.$_.','.$weight{$_}.  
  ','.$ctr.')" />'.$ctr."</td>\n";   ','.$ctr.')" />'.$ctr."</td>\n";
     $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');      $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
     $ctr++;      $ctr++;
  }   }
  $result.='</tr></table>';   $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".      $result.= '<table border=0><tr><td bgcolor="#777777">'."\n".
  '<table border=0><tr><td bgcolor="#777777">'."\n".  
  '<table border=0><tr bgcolor="#deffff">'.   '<table border=0><tr bgcolor="#deffff">'.
  '<td><b>Username</b></td><td><b>Fullname</b></td><td><b>Domain</b></td>'."\n";   '<td><b>Username</b></td><td><b>Fullname</b></td><td><b>Domain</b></td>'."\n";
     #get list of parts for this problem      #get list of parts for this problem
Line 1151  VIEWJAVASCRIPT Line 1229  VIEWJAVASCRIPT
  if ($display =~ /^Partial Credit Factor/) {   if ($display =~ /^Partial Credit Factor/) {
     $_ = $display;      $_ = $display;
     my ($partid) = /.*?(\d+).*/;      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;      next;
  }   }
  $display =~ s/Problem Status/Grade Status/;   $display =~ s/Problem Status/Grade Status<br>/;
  $result.='<td><b>'.$display.'</b></td>'."\n";   $result.='<td><b>'.$display.'</b></td>'."\n";
     }      }
     $result.='</tr>';      $result.='</tr>';
Line 1187  sub viewstudentgrade { Line 1266  sub viewstudentgrade {
  my $score=$record{"resource.$part.$type"};   my $score=$record{"resource.$part.$type"};
  next if $type eq 'tries';   next if $type eq 'tries';
  if ($type eq 'awarded') {   if ($type eq 'awarded') {
     my $pts = $score*$$weight{$part};      my $pts = $score eq '' ? '' : $score*$$weight{$part};
     $result.='<td align="middle"><input type="text" name="GRADE_'.$username.'_'.$part.'_'.$type.      $result.='<input type="hidden" name="'.
  '" value="'.$pts.'" size="4" /></td>'."\n";   'GRADE_'.$username.'_'.$part.'_awarded_save" value="'.$pts.'" />'."\n";
 #    $result.='<td align="middle"><input type="text" name="GRADE.'.$student.'.'.$part.'.'.$type.      $result.='<td align="middle"><input type="text" name="'.
 # '" value="'.$pts.'" size="4" /></td>'."\n";   'GRADE_'.$username.'_'.$part.'_awarded"'.
 # } elsif ($type eq 'tries') {   'onChange="javascript:changeSelect('.$part.',\''.$username.'\')" value="'.
 #    $result.='<td align="middle">'.$score.'&nbsp;</td>'."\n";   $pts.'" size="4" /></td>'."\n";
  } elsif ($type eq 'solved') {   } elsif ($type eq 'solved') {
     my ($status,$foo)=split(/_/,$score,2);      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 '');      $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.=$optsel;
     $result.="</select></td>\n";      $result.="</select></td>\n";
  }   }
Line 1233  sub editgrades { Line 1316  sub editgrades {
     return $result;      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 {  sub sub_page_js {
     my $request = shift;      my $request = shift;
     $request->print(<<SUBJAVASCRIPT);      $request->print(<<SUBJAVASCRIPT);

Removed from v.1.41  
changed lines
  Added in v.1.42


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>