Diff for /loncom/homework/grades.pm between versions 1.51 and 1.57

version 1.51, 2002/09/20 23:46:41 version 1.57, 2002/10/17 14:35:34
Line 40  use Apache::lonxml; Line 40  use Apache::lonxml;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::lonhomework;  use Apache::lonhomework;
   use Apache::loncoursedata;
 use Apache::lonmsg qw(:user_normal_msg);  use Apache::lonmsg qw(:user_normal_msg);
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
   
Line 51  sub getpartlist { Line 52  sub getpartlist {
     my @parts =();      my @parts =();
     my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys'));      my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys'));
     foreach my $key (@metakeys) {      foreach my $key (@metakeys) {
  if ( $key =~ m/stores_([0-9]+)_.*/) {   if ( $key =~ m/stores_(\w+)_.*/) {
     push(@parts,$key);      push(@parts,$key);
  }   }
     }      }
Line 72  sub get_symb_and_url { Line 73  sub get_symb_and_url {
 sub get_fullname {  sub get_fullname {
     my ($uname,$udom) = @_;      my ($uname,$udom) = @_;
     my %name=&Apache::lonnet::get('environment', ['lastname','generation',      my %name=&Apache::lonnet::get('environment', ['lastname','generation',
   'firstname','middlename'],$udom,$uname);    'firstname','middlename'],
                                     $udom,$uname);
     my $fullname;      my $fullname;
     my ($tmp) = keys(%name);      my ($tmp) = keys(%name);
     if ($tmp !~ /^(con_lost|error|no_such_host)/i) {      if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
  $fullname=$name{'lastname'}.$name{'generation'};          $fullname = &Apache::loncoursedata::ProcessFullName
  if ($fullname =~ /[^\s]+/) { $fullname.=', '; }              (@name{qw/lastname generation firstname middlename/});
  $fullname.=$name{'firstname'}.' '.$name{'middlename'};      } else {
           &Apache::lonnet::logthis('grades.pm: no name data for '.$uname.
                                    '@'.$udom.':'.$tmp);
     }      }
     return $fullname;      return $fullname;
 }  }
Line 91  sub response_type { Line 95  sub response_type {
     my %seen = ();      my %seen = ();
     my (@partlist,%handgrade);      my (@partlist,%handgrade);
     foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) {      foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) {
  if (/^\w+response_\d+.*/) {   if (/^\w+response_\w+.*/) {
     my ($responsetype,$part) = split(/_/,$_,2);      my ($responsetype,$part) = split(/_/,$_,2);
     my ($partid,$respid) = split(/_/,$part);      my ($partid,$respid) = split(/_/,$part);
     $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no');      $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no');
Line 107  sub response_type { Line 111  sub response_type {
 #--- section, ids and fullnames for each user.  #--- section, ids and fullnames for each user.
 sub getclasslist {  sub getclasslist {
     my ($getsec,$hideexpired) = @_;      my ($getsec,$hideexpired) = @_;
     my $now = time;      my $classlist=&Apache::loncoursedata::get_classlist();
     my %classlist=&Apache::lonnet::dump('classlist',  
  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},  
  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});  
     my ($tmp) = keys(%classlist);  
     # Bail out if we were unable to get the classlist      # Bail out if we were unable to get the classlist
     return if ($tmp =~ /^(con_lost|error|no_such_host)/i);      return if (! defined($classlist));
       #
     # codes to check for fields in the classlist      my %sections;
     # should contain end:start:id:section:fullname      my %fullnames;
     for (keys %classlist) {      foreach (keys(%$classlist)) {
  my (@fields) = split(/:/,$classlist{$_});          # the following undefs are for 'domain', and 'username' respectively.
  %classlist   = &reformat_classlist(\%classlist) if (scalar(@fields) <= 2);   my (undef,undef,$end,$start,$id,$section,$fullname,$status)=
  last;              @{$classlist->{$_}};
     }  
   
     my (@holdsec,@sections,%allids,%stusec,%fullname);  
     foreach (keys(%classlist)) {  
  my ($end,$start,$id,$section,$fullname)=split(/:/,$classlist{$_});  
  # still a student?   # still a student?
  if (($hideexpired) && ($end) && ($end < $now)) {   if (($hideexpired) && ($status ne 'Active')) {
     next;              delete ($classlist->{$_});
  }              next;
           }
  $section = ($section ne '' ? $section : 'no');   $section = ($section ne '' ? $section : 'no');
  push @holdsec,$section;  
  if ($getsec eq 'all' || $getsec eq $section) {   if ($getsec eq 'all' || $getsec eq $section) {
     push (@{ $classlist{$getsec} }, $_);              $sections{$section}++;
     $allids{$_}  =$id;              $fullnames{$_}=$fullname;
     $stusec{$_}  =$section;          } else {
     $fullname{$_}=$fullname;              delete($classlist->{$_});
  }          }
     }      }
     my %seen = ();      my %seen = ();
     foreach my $item (@holdsec) {      my @sections = sort(keys(%sections));
  push (@sections, $item) unless $seen{$item}++;      return ($classlist,\@sections,\%fullnames);
     }  
     return (\%classlist,\@sections,\%allids,\%stusec,\%fullname);  
 }  
   
 # add id, section and fullname to the classlist.db  
 # done to maintain backward compatibility with older versions  
 sub reformat_classlist {  
     my ($classlist) = shift;  
     foreach (sort keys(%$classlist)) {  
  my ($unam,$udom) = split(/:/);  
  my $section      = &Apache::lonnet::usection($udom,$unam,$ENV{'request.course.id'});  
  my $fullname     = &get_fullname ($unam,$udom);  
  my %userid       = &Apache::lonnet::idrget($udom,($unam));  
  $$classlist{$_}  = $$classlist{$_}.':'.$userid{$unam}.':'.$section.':'.$fullname;  
     }  
     my $putresult = &Apache::lonnet::put  
  ('classlist',\%$classlist,  
  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},  
  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});  
   
     return %$classlist;  
 }  }
   
 #find user domain  #find user domain
Line 263  sub verifyreceipt { Line 237  sub verifyreceipt {
  '<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font><br><br>'."\n";   '<font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font><br><br>'."\n";
   
     my ($string,$contents,$matches) = ('','',0);      my ($string,$contents,$matches) = ('','',0);
     my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist('all','0');      my (undef,undef,$fullname) = &getclasslist('all','0');
       
     foreach (sort {$$fullname{$a} cmp $$fullname{$b} } keys %$fullname) {      foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
  my ($uname,$udom)=split(/\:/);   my ($uname,$udom)=split(/\:/);
  if ($receipt eq    if ($receipt eq 
     &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {      &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {
Line 365  LISTJAVASCRIPT Line 339  LISTJAVASCRIPT
     my $checklastsub = $ENV{'form.handgrade'} eq 'yes' ? '' : 'checked';      my $checklastsub = $ENV{'form.handgrade'} eq 'yes' ? '' : 'checked';
   
     my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'."\n".      my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'."\n".
  '&nbsp;<b>View Problem: </b><input type="radio" name="vProb" value="no" checked> no '."\n".   '&nbsp;<b>View Problem: </b><input type="radio" name="vProb" value="no" > no '."\n".
  '<input type="radio" name="vProb" value="yes"> yes <br />'."\n".   '<input type="radio" name="vProb" value="yes" checked > yes <br />'."\n".
  '&nbsp;<b>Submissions: </b>'."\n";   '&nbsp;<b>Submissions: </b>'."\n";
     if ($ENV{'form.handgrade'} eq 'yes') {      if ($ENV{'form.handgrade'} eq 'yes') {
  $gradeTable.='<input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> handgrade only'."\n";   $gradeTable.='<input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> handgrade only'."\n";
Line 389  LISTJAVASCRIPT Line 363  LISTJAVASCRIPT
  'onClick="javascript:checkSelect(this.form.stuinfo);" '."\n".   'onClick="javascript:checkSelect(this.form.stuinfo);" '."\n".
  'value="'.$viewgrade.'" />'."\n";   'value="'.$viewgrade.'" />'."\n";
     
     my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($getsec,'0');      my (undef,undef,$fullname) = &getclasslist($getsec,'0');
           
     $gradeTable.='<table border="0"><tr><td bgcolor="#777777">'.      $gradeTable.='<table border="0"><tr><td bgcolor="#777777">'.
  '<table border="0"><tr bgcolor="#e6ffff">'.   '<table border="0"><tr bgcolor="#e6ffff">'.
Line 401  LISTJAVASCRIPT Line 375  LISTJAVASCRIPT
     $gradeTable.='</tr>'."\n";      $gradeTable.='</tr>'."\n";
   
     my $ctr = 0;      my $ctr = 0;
     foreach my $student (sort {$$fullname{$a} cmp $$fullname{$b} } keys %$fullname) {      foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
  my ($uname,$udom) = split(/:/,$student);   my ($uname,$udom) = split(/:/,$student);
  my (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist);   my (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist);
  my $statusflg = '';   my $statusflg = '';
Line 836  sub submission { Line 810  sub submission {
     if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
     my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');      my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
     $ENV{'form.vProb'} = $ENV{'form.vProb'} ne '' ? $ENV{'form.vProb'} : 'yes';      $ENV{'form.vProb'} = $ENV{'form.vProb'} ne '' ? $ENV{'form.vProb'} : 'yes';
     my ($classlist,$seclist,$ids,$stusec,$fullname);  
   
     # header info      # header info
     if ($counter == 0) {      if ($counter == 0) {
Line 937  KEYWORDS Line 910  KEYWORDS
   
     # If this is handgraded, then check for collaborators      # If this is handgraded, then check for collaborators
     my @col_fullnames;      my @col_fullnames;
       my ($classlist,$fullname);
     if ($ENV{'form.handgrade'} eq 'yes') {      if ($ENV{'form.handgrade'} eq 'yes') {
  my @col_list;   my @col_list;
  ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist('all','0');   ($classlist,undef,$fullname) = &getclasslist('all','0');
  for (keys (%$handgrade)) {   for (keys (%$handgrade)) {
     my $ncol = &Apache::lonnet::EXT('resource.'.$_.      my $ncol = &Apache::lonnet::EXT('resource.'.$_.
     '.maxcollaborators',$symb,$udom,$uname);      '.maxcollaborators',
     if ($ncol > 0) {                                              $symb,$udom,$uname);
  s/\_/\./g;      next if ($ncol <= 0);
  if ($record{'resource.'.$_.'.collaborators'} ne '') {              s/\_/\./g;
     my (@collaborators) = split(/,?\s+/,              next if ($record{'resource.'.$_.'.collaborators'} eq '');
  $record{'resource.'.$_.'.collaborators'});              my (@collaborators) = split(/,?\s+/,
     my (@badcollaborators);                                     $record{'resource.'.$_.'.collaborators'});
     if (scalar(@collaborators) != 0) {              my (@badcollaborators);
  $result.='<b>Collaborators: </b>';              if (scalar(@collaborators) != 0) {
  foreach my $collaborator (@collaborators) {                  $result.='<b>Collaborators: </b>';
     $collaborator = $collaborator =~ /\@|:/ ?                   foreach my $collaborator (@collaborators) {
  (split(/@|:/,$collaborator))[0] : $collaborator;                      my ($co_name,$co_dom) = split /\@|:/,$collaborator;
     next if ($collaborator eq $uname);                      $co_dom = $udom if (! defined($co_dom));
     if (!grep /^$collaborator:/i,keys %$classlist) {                      next if ($co_name eq $uname && $co_dom eq $udom);
  push @badcollaborators,$collaborator;                      # Doing this grep allows 'fuzzy' specification
  next;                      my @Matches = grep /^$co_name:$co_dom/i,
     }                      keys %$classlist;
     push @col_list, $collaborator;                      if (! scalar(@Matches)) {
     my ($lastname,$givenn) = split(/,/,$$fullname{$collaborator.':'.$udom});                          push @badcollaborators,$collaborator;
     push @col_fullnames, $givenn.' '.$lastname;                          next;
     $result.=$$fullname{$collaborator.':'.$udom}.'&nbsp; &nbsp; &nbsp;';                      }
  }                      push @col_list, @Matches;
  $result.='<br />'."\n";                      foreach (@Matches) {
  $result.='<table border="0"><tr bgcolor="#ffbbbb"><td>'.                          my ($lastname,$givenn) = split(/,/,$$fullname{$_});
     'This student has submitted '.                          push @col_fullnames, $givenn.' '.$lastname;
     (scalar (@badcollaborators) > 1 ? '' : 'an').                          $result.=$$fullname{$_}.'&nbsp; &nbsp; &nbsp;';
     ' invalid collaborator'.(scalar (@badcollaborators) > 1 ? 's. ' : '. ').                      }
     (join ', ',@badcollaborators).'</td></tr></table>'                   }
     if (scalar(@badcollaborators) > 0);                  $result.='<br />'."\n";
                   if (scalar(@badcollaborators) > 0) {
  $result.='<table border="0"><tr bgcolor="#ffbbbb"><td>'.                      $result.='<table border="0"><tr bgcolor="#ffbbbb"><td>';
     'This student has submitted too many collaborators. Maximum is '.                      $result.='This student has submitted ';
     $ncol.'.</td></tr></table>' if (scalar(@collaborators) > $ncol);                      if (scalar(@badcollaborators) == 1) {
  $result.='<input type="hidden" name="collaborator'.$counter.                          $result .= 'an invalid collaborator';
     '" value="'.(join ':',@col_list).'" />'."\n";                      } else {
     }                          $result .= 'invalid collaborators';
  }                      }
     }                      $result .= ': '.join(', ',@badcollaborators);
                       
                   }
                   if (scalar(@collaborators > $ncol)) {
                       $result .= '<table border="0"><tr bgcolor="#ffbbbb"><td>';
                       $result .= 'This student has sumbitted too many '.
                           'collaborators.  Maximum is '.$ncol;
                       $result .= '</td></tr></table>';
                   }
                   $result.='<input type="hidden" name="collaborator'.$counter.
                       '" value="'.(join ':',@col_list).'" />'."\n";
               }
  }   }
     }      }
     $request->print($result."\n");      $request->print($result."\n");
Line 1189  sub keywords_highlight { Line 1174  sub keywords_highlight {
     foreach (@keylist) {      foreach (@keylist) {
  $string =~ s/\b$_(\b|\.)/\<font color\=$ENV{'form.kwclr'} $size\>$styleon$_$styleoff\<\/font\>/gi;   $string =~ s/\b$_(\b|\.)/\<font color\=$ENV{'form.kwclr'} $size\>$styleon$_$styleoff\<\/font\>/gi;
     }      }
       # This is not really the right place to do this, but I cannot find a
       # better one at this time.  So here we go - the m in the s:::mg causes
       # ^ to match the beginning of a new line.  So we replace(???) the beginning
       # of the line with <br /> to make things formatted a little better.
       $string =~ s:^:<br />:mg;
     return $string;      return $string;
 }  }
   
Line 1297  sub processHandGrade { Line 1287  sub processHandGrade {
  $laststu = $firststu if ($ctr > $ngrade);   $laststu = $firststu if ($ctr > $ngrade);
     }      }
   
     my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0');      my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
     my (@parsedlist,@nextlist);      my (@parsedlist,@nextlist);
     my ($nextflg) = 0;      my ($nextflg) = 0;
     foreach (sort {$$fullname{$a} cmp $$fullname{$b} } keys %$fullname) {      foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
  if ($nextflg == 1 && $button =~ /Next$/) {   if ($nextflg == 1 && $button =~ /Next$/) {
     push @parsedlist,$_;      push @parsedlist,$_;
  }   }
Line 1441  sub viewgrades_js { Line 1431  sub viewgrades_js {
  for (i=0;i<document.classgrade.total.value;i++) {   for (i=0;i<document.classgrade.total.value;i++) {
     var user = eval("document.classgrade.ctr"+i+".value");      var user = eval("document.classgrade.ctr"+i+".value");
     var scorename = eval("document.classgrade.GD_"+user+      var scorename = eval("document.classgrade.GD_"+user+
  "_"+partid+"_aw");   "_"+partid+"_awarded");
     var saveval   = eval("document.classgrade.GD_"+user+      var saveval   = eval("document.classgrade.GD_"+user+
  "_"+partid+"_sv_s.value");   "_"+partid+"_solved_s.value");
     var selname   = eval("document.classgrade.GD_"+user+"_"+partid+"_sv");      var selname   = eval("document.classgrade.GD_"+user+"_"+partid+"_solved");
     if (saveval != "correct") {      if (saveval != "correct") {
  scorename.value = point;   scorename.value = point;
  if (selname[0].selected != true) {   if (selname[0].selected != true) {
Line 1470  sub viewgrades_js { Line 1460  sub viewgrades_js {
     for (i=0;i<document.classgrade.total.value;i++) {      for (i=0;i<document.classgrade.total.value;i++) {
  var user = eval("document.classgrade.ctr"+i+".value");   var user = eval("document.classgrade.ctr"+i+".value");
  var scorename = eval("document.classgrade.GD_"+user+   var scorename = eval("document.classgrade.GD_"+user+
      "_"+partid+"_aw");       "_"+partid+"_awarded");
  var saveval   = eval("document.classgrade.GD_"+user+   var saveval   = eval("document.classgrade.GD_"+user+
      "_"+partid+"_sv_s.value");       "_"+partid+"_solved_s.value");
  var selname   = eval("document.classgrade.GD_"+user+   var selname   = eval("document.classgrade.GD_"+user+
      "_"+partid+"_sv");       "_"+partid+"_solved");
  if (saveval != "correct") {   if (saveval != "correct") {
     scorename.value = "";      scorename.value = "";
     selname[1].selected = true;      selname[1].selected = true;
Line 1484  sub viewgrades_js { Line 1474  sub viewgrades_js {
     for (i=0;i<document.classgrade.total.value;i++) {      for (i=0;i<document.classgrade.total.value;i++) {
  var user = eval("document.classgrade.ctr"+i+".value");   var user = eval("document.classgrade.ctr"+i+".value");
  var scorename = eval("document.classgrade.GD_"+user+   var scorename = eval("document.classgrade.GD_"+user+
      "_"+partid+"_aw");       "_"+partid+"_awarded");
  var saveval   = eval("document.classgrade.GD_"+user+   var saveval   = eval("document.classgrade.GD_"+user+
      "_"+partid+"_sv_s.value");       "_"+partid+"_solved_s.value");
  var selname   = eval("document.classgrade.GD_"+user+   var selname   = eval("document.classgrade.GD_"+user+
      "_"+partid+"_sv");       "_"+partid+"_solved");
  if (saveval != "correct") {   if (saveval != "correct") {
     scorename.value = eval("document.classgrade.GD_"+user+      scorename.value = eval("document.classgrade.GD_"+user+
      "_"+partid+"_aw_s.value");;       "_"+partid+"_awarded_s.value");;
     selname[0].selected = true;      selname[0].selected = true;
  }   }
     }      }
Line 1499  sub viewgrades_js { Line 1489  sub viewgrades_js {
     }      }
   
     function changeSelect(partid,user) {      function changeSelect(partid,user) {
  var selval = eval("document.classgrade.GD_"+user+'_'+partid+"_sv");   var selval = eval("document.classgrade.GD_"+user+'_'+partid+"_solved");
  var textbox = eval("document.classgrade.GD_"+user+'_'+partid+"_aw");   var textbox = eval("document.classgrade.GD_"+user+'_'+partid+"_awarded");
  var point  = textbox.value;   var point  = textbox.value;
  var weight = eval("document.classgrade.weight_"+partid+".value");   var weight = eval("document.classgrade.weight_"+partid+".value");
   
Line 1521  sub viewgrades_js { Line 1511  sub viewgrades_js {
     }      }
   
     function changeOneScore(partid,user) {      function changeOneScore(partid,user) {
  var selval = eval("document.classgrade.GD_"+user+'_'+partid+"_sv");   var selval = eval("document.classgrade.GD_"+user+'_'+partid+"_solved");
  if (selval[1].selected) {   if (selval[1].selected) {
     var boxval = eval("document.classgrade.GD_"+user+'_'+partid+"_aw");      var boxval = eval("document.classgrade.GD_"+user+'_'+partid+"_awarded");
     boxval.value = "";      boxval.value = "";
  }   }
     }      }
Line 1544  sub viewgrades_js { Line 1534  sub viewgrades_js {
     for (i=0;i<document.classgrade.total.value;i++) {      for (i=0;i<document.classgrade.total.value;i++) {
  var user = eval("document.classgrade.ctr"+i+".value");   var user = eval("document.classgrade.ctr"+i+".value");
  var resetscore = eval("document.classgrade.GD_"+user+   var resetscore = eval("document.classgrade.GD_"+user+
       "_"+partid+"_aw");        "_"+partid+"_awarded");
  resetscore.value = eval("document.classgrade.GD_"+user+   resetscore.value = eval("document.classgrade.GD_"+user+
  "_"+partid+"_aw_s.value");   "_"+partid+"_awarded_s.value");
   
  var saveselval   = eval("document.classgrade.GD_"+user+   var saveselval   = eval("document.classgrade.GD_"+user+
      "_"+partid+"_sv_s.value");       "_"+partid+"_solved_s.value");
   
  var selname   = eval("document.classgrade.GD_"+user+"_"+partid+"_sv");   var selname   = eval("document.classgrade.GD_"+user+"_"+partid+"_solved");
  if (saveselval == "excused") {   if (saveselval == "excused") {
     if (selname[1].selected == false) { selname[1].selected = true;}      if (selname[1].selected == false) { selname[1].selected = true;}
  } else {   } else {
Line 1584  sub viewgrades { Line 1574  sub viewgrades {
  '<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 '.      $result.='<h3>Assign Common Grade To ';
  'text box below. To assign scores individually fill in the score boxes for '.      if ($ENV{'form.section'} eq 'all') {
  'each student in the table below. <font color="red">A part that has already '.   $result.='Class </h3>';
  'been graded does not get changed using the radio buttons or text box. '.      } elsif ($ENV{'form.section'} eq 'no') {
  'If needed, it has to be changed individually.</font>';   $result.='Students in no Section </h3>';
       } else {
    $result.='Students in Section '.$ENV{'form.section'}.'</h3>';
       }
       $result.= '<table border=0><tr><td bgcolor="#777777">'."\n".
    '<table border=0><tr bgcolor="#ffffdd"><td>';
   #    $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 part 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>';
   #    $result.='</td></tr><tr><td>';
     #radio buttons/text box for assigning points for a section or class.      #radio buttons/text box for assigning points for a section or class.
     #handles different parts of a problem      #handles different parts of a problem
     my ($partlist,$handgrade) = &response_type($ENV{'form.url'});      my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
Line 1598  sub viewgrades { Line 1598  sub viewgrades {
     $result.='<table border="0">';      $result.='<table border="0">';
     my %seen = ();      my %seen = ();
     for (sort keys(%$handgrade)) {      for (sort keys(%$handgrade)) {
  my ($partid,$respid) = split (/_/);   my ($partid,$respid) = split (/_/,$_,2);
  next if $seen{$partid};   next if $seen{$partid};
  $seen{$partid}++;   $seen{$partid}++;
  my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});   my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
Line 1614  sub viewgrades { Line 1614  sub viewgrades {
  my $ctr = 0;   my $ctr = 0;
  while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across   while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
     $result.= '<td><input type="radio" name="RADVAL_'.$partid.'" '.      $result.= '<td><input type="radio" name="RADVAL_'.$partid.'" '.
  'onclick="javascript:writePoint('.$partid.','.$weight{$partid}.   'onclick="javascript:writePoint(\''.$partid.'\','.$weight{$partid}.
  ','.$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_'.   $result.= '</td><td><b> or </b><input type="text" name="TEXTVAL_'.
     $partid.'" size="4" '.      $partid.'" size="4" '.'onChange="javascript:writePoint(\''.
     'onChange="javascript:writePoint('.$partid.','.$weight{$partid}.   $partid.'\','.$weight{$partid}.',\'textval\')" /> /'.
     ',\'textval\')" /> /'.  
     $weight{$partid}.' (problem weight)</td>'."\n";      $weight{$partid}.' (problem weight)</td>'."\n";
  $result.= '</td><td><select name="SELVAL_'.$partid.'"'.   $result.= '</td><td><select name="SELVAL_'.$partid.'"'.
     'onChange="javascript:writeRadText('.$partid.','.$weight{$partid}.')" /> '.      'onChange="javascript:writeRadText(\''.$partid.'\','.
    $weight{$partid}.')" /> '.
     '<option selected="on"> </option>'.      '<option selected="on"> </option>'.
     '<option>excused</option></select></td></tr>'."\n";      '<option>excused</option></select></td></tr>'."\n";
  $ctsparts++;   $ctsparts++;
     }      }
     $result.='</table><input type="hidden" name="totalparts" value="'.$ctsparts.'" />';      $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n".
    '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />';
     $result.='<input type="button" value="Reset" '.      $result.='<input type="button" value="Reset" '.
  'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self> &nbsp; &nbsp;';   'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self> &nbsp; &nbsp;';
     $result.='<input type="button" value="Submit Changes" '.      $result.='<input type="button" value="Submit Changes" '.
Line 1639  sub viewgrades { Line 1640  sub viewgrades {
   
     #table listing all the students in a section/class      #table listing all the students in a section/class
     #header of table      #header of table
       $result.= '<h3>Assign Grade to Specific Students in ';
       if ($ENV{'form.section'} eq 'all') {
    $result.='the Class </h3>';
       } elsif ($ENV{'form.section'} eq 'no') {
    $result.='no Section </h3>';
       } else {
    $result.='Section '.$ENV{'form.section'}.'</h3>';
       }
     $result.= '<table border=0><tr><td bgcolor="#777777">'."\n".      $result.= '<table border=0><tr><td bgcolor="#777777">'."\n".
  '<table border=0><tr bgcolor="#deffff">'.   '<table border=0><tr bgcolor="#deffff">'.
  '<td><b>Fullname</b></td><td><b>Username</b></td><td><b>Domain</b></td>'."\n";   '<td><b>Fullname</b></td><td><b>Username</b></td><td><b>Domain</b></td>'."\n";
     my (@parts) = sort(&getpartlist($url));      my (@parts) = sort(&getpartlist($url));
     foreach my $part (@parts) {      foreach my $part (@parts) {
  my $display=&Apache::lonnet::metadata($url,$part.'.display');   my $display=&Apache::lonnet::metadata($url,$part.'.display');
  next if ($display =~ /^Number of Attempts/);  
  if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }   if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
  if ($display =~ /^Partial Credit Factor/) {   if ($display =~ /^Partial Credit Factor/) {
     $_ = $display;      my ($partid) = &split_part_type($part);
     my ($partid) = /.*?(\d+).*/;      $result.='<td><b>Score Part '.$partid.'<br />(weight = '.
     $result.='<td><b>Score Part '.$partid.'<br>(weight = '.  
  $weight{$partid}.')</b></td>'."\n";   $weight{$partid}.')</b></td>'."\n";
     next;      next;
  }   }
  $display =~ s/Problem Status/Grade Status<br>/;   $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>';
   
     #get info for each student      #get info for each student
     #list all the students - with points and grade status      #list all the students - with points and grade status
     my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0');      my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
     my $ctr = 0;      my $ctr = 0;
     foreach (sort {$$fullname{$a} cmp $$fullname{$b} } keys %$fullname) {      foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
  my ($uname,$udom) = split(/:/);   my ($uname,$udom) = split(/:/);
  $result.='<input type="hidden" name="ctr'.$ctr.'" value="'.$uname.'" />'."\n";   $result.='<input type="hidden" name="ctr'.$ctr.'" value="'.$uname.'" />'."\n";
  $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},   $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},
Line 1688  sub viewstudentgrade { Line 1695  sub viewstudentgrade {
  '\')"; TARGET=_self>'.$fullname.'</a>'.   '\')"; TARGET=_self>'.$fullname.'</a>'.
  '</td><td>'.$uname.'</td><td align="middle">'.$udom.'</td>'."\n";   '</td><td>'.$uname.'</td><td align="middle">'.$udom.'</td>'."\n";
     foreach my $part (@$parts) {      foreach my $part (@$parts) {
  my ($temp,$part,$type)=split(/_/,$part);   my ($part,$type) = &split_part_type($part);
  my $score=$record{"resource.$part.$type"};   my $score=$record{"resource.$part.$type"};
  next if $type eq 'tries';  
  if ($type eq 'awarded') {   if ($type eq 'awarded') {
     my $pts = $score eq '' ? '' : $score*$$weight{$part};      my $pts = $score eq '' ? '' : $score*$$weight{$part};
     $result.='<input type="hidden" name="'.      $result.='<input type="hidden" name="'.
  'GD_'.$uname.'_'.$part.'_aw_s" value="'.$pts.'" />'."\n";   'GD_'.$uname.'_'.$part.'_awarded_s" value="'.$pts.'" />'."\n";
     $result.='<td align="middle"><input type="text" name="'.      $result.='<td align="middle"><input type="text" name="'.
  'GD_'.$uname.'_'.$part.'_aw" '.   'GD_'.$uname.'_'.$part.'_awarded" '.
  'onChange="javascript:changeSelect('.$part.',\''.$uname.   'onChange="javascript:changeSelect(\''.$part.'\',\''.$uname.
  '\')" value="'.$pts.'" size="4" /></td>'."\n";   '\')" value="'.$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);
     $status = 'nothing' if ($status eq '');      $status = 'nothing' if ($status eq '');
     $result.='<input type="hidden" name="'.      $result.='<input type="hidden" name="'.'GD_'.$uname.'_'.
  'GD_'.$uname.'_'.$part.'_sv_s" value="'.$status.'" />'."\n";   $part.'_solved_s" value="'.$status.'" />'."\n";
     $result.='<td align="middle"><select name="'.      $result.='<td align="middle"><select name="'.
  'GD_'.$uname.'_'.$part.'_sv" '.   'GD_'.$uname.'_'.$part.'_solved" '.
  'onChange="javascript:changeOneScore('.$part.',\''.$uname.'\')" >'."\n";   'onChange="javascript:changeOneScore(\''.$part.'\',\''.$uname.'\')" >'."\n";
     my $optsel = '<option selected="on"> </option><option>excused</option>'."\n";      my $optsel = '<option selected="on"> </option><option>excused</option>'."\n";
     $optsel = '<option> </option><option selected="on">excused</option>'."\n"      $optsel = '<option> </option><option selected="on">excused</option>'."\n"
  if ($status eq 'excused');   if ($status eq 'excused');
     $result.=$optsel;      $result.=$optsel;
     $result.="</select></td>\n";      $result.="</select></td>\n";
    } else {
       $result.='<input type="hidden" name="'.
    'GD_'.$uname.'_'.$part.'_'.$type.'_s" value="'.$score.'" />'.
       "\n";
       $result.='<td align="middle"><input type="text" name="'.
    'GD_'.$uname.'_'.$part.'_'.$type.'" '.
    'value="'.$score.'" size="4" /></td>'."\n";
  }   }
     }      }
     $result.='</tr>';      $result.='</tr>';
Line 1740  sub editgrades { Line 1753  sub editgrades {
     'ungraded' =>'ungraded_attempted',      'ungraded' =>'ungraded_attempted',
     'nothing'  => '',      'nothing'  => '',
     );      );
     my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0');      my ($classlist,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
   
     my (@partid);      my (@partid);
     my %weight = ();      my %weight = ();
       my %columns = ();
     my ($i,$ctr,$count,$rec_update) = (0,0,0,0);      my ($i,$ctr,$count,$rec_update) = (0,0,0,0);
   
       my (@parts) = sort(&getpartlist($url));
       my $header;
     while ($ctr < $ENV{'form.totalparts'}) {      while ($ctr < $ENV{'form.totalparts'}) {
  my $partid = $ENV{'form.partid_'.$ctr};   my $partid = $ENV{'form.partid_'.$ctr};
  push @partid,$partid;   push @partid,$partid;
  $weight{$partid} = $ENV{'form.weight_'.$partid};   $weight{$partid} = $ENV{'form.weight_'.$partid};
  $ctr++;   $ctr++;
  $result .= '<td colspan = 2 align="center"><b>Part '.$partid.  
     '</b> (Weight = '.$weight{$partid}.')</td>';  
     }      }
     $result .= '</tr><tr bgcolor="#deffff">';      foreach my $partid (@partid) {
     foreach (@partid) {   $header .= '<td align="center">&nbsp;<b>Old Score</b>&nbsp;</td>'.
  $result .= '<td align="center">&nbsp;<b>Old Score</b>&nbsp;</td>'.  
     '<td align="center">&nbsp;<b>New Score</b>&nbsp;</td>';      '<td align="center">&nbsp;<b>New Score</b>&nbsp;</td>';
    $columns{$partid}=2;
    foreach my $stores (@parts) {
       my ($part,$type) = &split_part_type($stores);
       if ($part !~ m/^\Q$partid\E/) { next;}
       if ($type eq 'awarded' || $type eq 'solved') { next; }
       my $display=&Apache::lonnet::metadata($url,$stores.'.display');
       $display =~ s/\[Part: (\w)+\]//;
       $header .= '<td align="center">&nbsp;<b>Old</b> '.$display.'&nbsp;</td>'.
    '<td align="center">&nbsp;<b>New</b> '.$display.'&nbsp;</td>';
       $columns{$partid}+=2;
    }
     }      }
       foreach my $partid (@partid) {
    $result .= '<td colspan="'.$columns{$partid}.
       '" align="center"><b>Part '.$partid.
       '</b> (Weight = '.$weight{$partid}.')</td>';
   
       }
       $result .= '</tr><tr bgcolor="#deffff">';
       $result .= $header;
     $result .= '</tr>'."\n";      $result .= '</tr>'."\n";
   
     for ($i=0; $i<$ENV{'form.total'}; $i++) {      for ($i=0; $i<$ENV{'form.total'}; $i++) {
Line 1765  sub editgrades { Line 1798  sub editgrades {
  my %newrecord;   my %newrecord;
  my $updateflag = 0;   my $updateflag = 0;
  my @userdom = grep /^$user:/,keys %$classlist;   my @userdom = grep /^$user:/,keys %$classlist;
  my ($foo,$udom) = split(/:/,$userdom[0]);   my (undef,$udom) = split(/:/,$userdom[0]);
   
  $result .= '<tr bgcolor="#ffffde"><td>'.$user.'&nbsp;</td><td>'.   $result .= '<tr bgcolor="#ffffde"><td>'.$user.'&nbsp;</td><td>'.
     $$fullname{$userdom[0]}.'&nbsp;</td>';      $$fullname{$userdom[0]}.'&nbsp;</td>';
   
  foreach (@partid) {   foreach (@partid) {
     my $old_aw    = $ENV{'form.GD_'.$user.'_'.$_.'_aw_s'};      my $old_aw    = $ENV{'form.GD_'.$user.'_'.$_.'_awarded_s'};
     my $old_part  = $old_aw eq '' ? '' : $old_aw/$weight{$_};      my $old_part_pcr = $old_aw/($weight{$_} ne '0' ? $weight{$_}:1);
     my $old_score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_sv_s'}};      my $old_part  = $old_aw eq '' ? '' : $old_part_pcr;
       my $old_score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_solved_s'}};
     my $awarded   = $ENV{'form.GD_'.$user.'_'.$_.'_aw'};  
     my $partial   = $awarded eq '' ? '' : $awarded/$weight{$_};      my $awarded   = $ENV{'form.GD_'.$user.'_'.$_.'_awarded'};
       my $pcr       = $awarded/($weight{$_} ne '0' ? $weight{$_} : 1);
       my $partial   = $awarded eq '' ? '' : $pcr;
     my $score;      my $score;
     if ($partial eq '') {      if ($partial eq '') {
  $score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_sv_s'}};   $score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_solved_s'}};
     } elsif ($partial > 0) {      } elsif ($partial > 0) {
  $score = 'correct_by_override';   $score = 'correct_by_override';
     } elsif ($partial == 0) {      } elsif ($partial == 0) {
  $score = 'incorrect_by_override';   $score = 'incorrect_by_override';
     }      }
     $score = 'excused' if (($ENV{'form.GD_'.$user.'_'.$_.'_sv'} eq 'excused') &&      $score = 'excused' if (($ENV{'form.GD_'.$user.'_'.$_.'_solved'} eq 'excused') &&
    ($score ne 'excused'));     ($score ne 'excused'));
     $result .= '<td align="center">'.$old_aw.'&nbsp;</td>'.      $result .= '<td align="center">'.$old_aw.'&nbsp;</td>'.
  '<td align="center">'.$awarded.   '<td align="center">'.$awarded.
  ($score eq 'excused' ? $score : '').'&nbsp;</td>';   ($score eq 'excused' ? $score : '').'&nbsp;</td>';
   
     next if ($old_part eq $partial && $old_score eq $score);      if (!($old_part eq $partial && $old_score eq $score)) {
    $updateflag = 1;
     $updateflag = 1;   $newrecord{'resource.'.$_.'.awarded'}  = $partial if $partial ne '';
     $newrecord{'resource.'.$_.'.awarded'}  = $partial if $partial ne '';   $newrecord{'resource.'.$_.'.solved'}   = $score;
     $newrecord{'resource.'.$_.'.solved'}   = $score;   $rec_update++;
     $rec_update++;      }
   
       my $partid=$_;
       foreach my $stores (@parts) {
    my ($part,$type) = &split_part_type($stores);
    if ($part !~ m/^\Q$partid\E/) { next;}
    if ($type eq 'awarded' || $type eq 'solved') { next; }
    my $old_aw    = $ENV{'form.GD_'.$user.'_'.$part.'_'.$type.'_s'};
    my $awarded   = $ENV{'form.GD_'.$user.'_'.$part.'_'.$type};
    if ($awarded ne '' && $awarded ne $old_aw) {
       $newrecord{'resource.'.$part.'.'.$type}= $awarded;
       $updateflag=1;
    }
    $result .= '<td align="center">'.$old_aw.'&nbsp;</td>'.
       '<td align="center">'.$awarded.'&nbsp;</td>';
       }
  }   }
  $result .= '</tr>'."\n";   $result .= '</tr>'."\n";
  if ($updateflag) {   if ($updateflag) {
Line 1812  sub editgrades { Line 1861  sub editgrades {
  '<b>Total number of students = '.$ENV{'form.total'}.'</b><br />';   '<b>Total number of students = '.$ENV{'form.total'}.'</b><br />';
     return $title.$msg.$result;      return $title.$msg.$result;
 }  }
   
   sub split_part_type {
       my ($partstr) = @_;
       my ($temp,@allparts)=split(/_/,$partstr);
       my $type=pop(@allparts);
       my $part=join('.',@allparts);
       return ($part,$type);
   }
   
 #------------- end of section for handling grading by section/class ---------  #------------- end of section for handling grading by section/class ---------
 #  #
 #----------------------------------------------------------------------------  #----------------------------------------------------------------------------
Line 2113  sub gradingmenu { Line 2171  sub gradingmenu {
 #--- Menu for grading a section or the whole class ---  #--- Menu for grading a section or the whole class ---
 sub view_edit_entire_class_form {  sub view_edit_entire_class_form {
     my ($symb,$url)=@_;      my ($symb,$url)=@_;
     my ($classlist,$sections) = &getclasslist('all','0');      my ($classlist,$sections,undef) = &getclasslist('all','0');
     my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";      my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
     $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
     $result.='&nbsp;<b>Grade Entire Class</b></td></tr>'."\n";      $result.='&nbsp;<b>Grade Entire Section or Class</b></td></tr>'."\n";
     $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
     $result.='<form action="/adm/grades" method="post">'."\n".      $result.='<form action="/adm/grades" method="post">'."\n".
  '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".   '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".

Removed from v.1.51  
changed lines
  Added in v.1.57


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