Diff for /loncom/homework/grades.pm between versions 1.406 and 1.417

version 1.406, 2007/06/15 22:00:42 version 1.417, 2007/06/22 22:50:30
Line 41  use Apache::Constants qw(:common); Line 41  use Apache::Constants qw(:common);
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonenc;  use Apache::lonenc;
 use String::Similarity;  use String::Similarity;
 use lib '/home/httpd/lib/perl';  
 use LONCAPA;  use LONCAPA;
   
 use POSIX qw(floor);  use POSIX qw(floor);
Line 618  sub verifyreceipt { Line 617  sub verifyreceipt {
     if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) {      if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) {
  $contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".   $contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".
     '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.      '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
     '\')"; TARGET=_self>'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".      '\');" target="_self">'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".
     '<td>&nbsp;'.$uname.'&nbsp;</td>'.      '<td>&nbsp;'.$uname.'&nbsp;</td>'.
     '<td>&nbsp;'.$udom.'&nbsp;</td>';      '<td>&nbsp;'.$udom.'&nbsp;</td>';
  if ($receiptparts) {   if ($receiptparts) {
Line 1793  sub submission { Line 1792  sub submission {
 #  #
     $request->print(<<KEYWORDS);      $request->print(<<KEYWORDS);
 &nbsp;<b>Keyword Options:</b>&nbsp;  &nbsp;<b>Keyword Options:</b>&nbsp;
 <a href="javascript:keywords(document.SCORE)"; TARGET=_self>List</a>&nbsp; &nbsp;  <a href="javascript:keywords(document.SCORE);" target="_self">List</a>&nbsp; &nbsp;
 <a href="#" onMouseDown="javascript:getSel(); return false"  <a href="#" onMouseDown="javascript:getSel(); return false"
  CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;   CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;
 <a href="javascript:kwhighlight()"; TARGET=_self>Highlight Attribute</a><br /><br />  <a href="javascript:kwhighlight();" target="_self">Highlight Attribute</a><br /><br />
 KEYWORDS  KEYWORDS
 #  #
 # Load the other essays for similarity check  # Load the other essays for similarity check
Line 1922  KEYWORDS Line 1921  KEYWORDS
  ' <b>Collaborative submission by:</b> '.   ' <b>Collaborative submission by:</b> '.
  '<a href="javascript:viewSubmitter(\''.   '<a href="javascript:viewSubmitter(\''.
  $env{"form.$uname:$udom:$partid:submitted_by"}.   $env{"form.$uname:$udom:$partid:submitted_by"}.
  '\')"; TARGET=_self>'.   '\');" target="_self">'.
  $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a><br />';   $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a><br />';
     $request->print($submitby);      $request->print($submitby);
     next;      next;
Line 2000  KEYWORDS Line 1999  KEYWORDS
     if ($env{'form.showgrading'} eq '' || (!&canmodify($usec))) {      if ($env{'form.showgrading'} eq '' || (!&canmodify($usec))) {
  my $toGrade.='<input type="button" value="Grade Student" '.   my $toGrade.='<input type="button" value="Grade Student" '.
     'onClick="javascript:checksubmit(this.form,\'Grade Student\',\''      'onClick="javascript:checksubmit(this.form,\'Grade Student\',\''
     .$counter.'\');" TARGET=_self> &nbsp;'."\n" if (&canmodify($usec));      .$counter.'\');" target="_self" /> &nbsp;'."\n" if (&canmodify($usec));
  $toGrade.='</td></tr></table></td></tr></table>'."\n";   $toGrade.='</td></tr></table></td></tr></table>'."\n";
  if (($env{'form.command'} eq 'submission') ||    if (($env{'form.command'} eq 'submission') || 
     ($env{'form.command'} eq 'processGroup' && $counter == $total)) {      ($env{'form.command'} eq 'processGroup' && $counter == $total)) {
Line 2024  KEYWORDS Line 2023  KEYWORDS
  $result='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".   $result='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
     '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";      '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";
  $result.='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.   $result.='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.
     ',\''.$msgfor.'\')"; TARGET=_self>'.      ',\''.$msgfor.'\');" target="_self">'.
     &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a><label> ('.      &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a><label> ('.
     &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'.      &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'.
     '<img src="'.$request->dir_config('lonIconsURL').      '<img src="'.$request->dir_config('lonIconsURL').
Line 2076  KEYWORDS Line 2075  KEYWORDS
  my $endform='<table border="0"><tr><td>'."\n";   my $endform='<table border="0"><tr><td>'."\n";
  $endform.='<input type="button" value="Save & Next" '.   $endform.='<input type="button" value="Save & Next" '.
     'onClick="javascript:checksubmit(this.form,\'Save & Next\','.      'onClick="javascript:checksubmit(this.form,\'Save & Next\','.
     $total.','.scalar(@partlist).');" TARGET=_self> &nbsp;'."\n";      $total.','.scalar(@partlist).');" target="_self" /> &nbsp;'."\n";
  my $ntstu ='<select name="NTSTU">'.   my $ntstu ='<select name="NTSTU">'.
     '<option>1</option><option>2</option>'.      '<option>1</option><option>2</option>'.
     '<option>3</option><option>5</option>'.      '<option>3</option><option>5</option>'.
Line 2085  KEYWORDS Line 2084  KEYWORDS
  $ntstu =~ s/<option>$nsel</<option selected="selected">$nsel</;   $ntstu =~ s/<option>$nsel</<option selected="selected">$nsel</;
  $endform.=$ntstu.'student(s) &nbsp;&nbsp;';   $endform.=$ntstu.'student(s) &nbsp;&nbsp;';
  $endform.='<input type="button" value="Previous" '.   $endform.='<input type="button" value="Previous" '.
     'onClick="javascript:checksubmit(this.form,\'Previous\');" TARGET=_self> &nbsp;'."\n".      'onClick="javascript:checksubmit(this.form,\'Previous\');" target="_self" /> &nbsp;'."\n".
     '<input type="button" value="Next" '.      '<input type="button" value="Next" '.
     'onClick="javascript:checksubmit(this.form,\'Next\');" TARGET=_self> &nbsp;';      'onClick="javascript:checksubmit(this.form,\'Next\');" target="_self" /> &nbsp;';
  $endform.='(Next and Previous (student) do not save the scores.)'."\n" ;   $endform.='(Next and Previous (student) do not save the scores.)'."\n" ;
         $endform.="<input type='hidden' value='".&get_increment().          $endform.="<input type='hidden' value='".&get_increment().
             "' name='increment' />";              "' name='increment' />";
Line 3037  sub viewgrades { Line 3036  sub viewgrades {
     $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n".      $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n".
  '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />';   '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />';
     $result.='<input type="button" value="Revert to Default" '.      $result.='<input type="button" value="Revert to Default" '.
  'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self>';   'onClick="javascript:resetEntry('.$ctsparts.');" target="_self" />';
   
     #table listing all the students in a section/class      #table listing all the students in a section/class
     #header of table      #header of table
Line 3088  sub viewgrades { Line 3087  sub viewgrades {
     $result.='</table></td></tr></table>';      $result.='</table></td></tr></table>';
     $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n";      $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n";
     $result.='<input type="button" value="Save" '.      $result.='<input type="button" value="Save" '.
  'onClick="javascript:submit();" TARGET=_self /></form>'."\n";   'onClick="javascript:submit();" target="_self" /></form>'."\n";
     if (scalar(%$fullname) eq 0) {      if (scalar(%$fullname) eq 0) {
  my $colspan=3+scalar(@parts);   my $colspan=3+scalar(@parts);
  $result='<span class="LC_warning">There are no students in section "'.$env{'form.section'}.   $result='<span class="LC_warning">There are no students in section "'.$env{'form.section'}.
Line 3108  sub viewstudentgrade { Line 3107  sub viewstudentgrade {
  '<input type="hidden" name="ctr'.($ctr-1).'" value="'.$student.'" />'.   '<input type="hidden" name="ctr'.($ctr-1).'" value="'.$student.'" />'.
  "\n".$ctr.'&nbsp;</td><td>&nbsp;'.   "\n".$ctr.'&nbsp;</td><td>&nbsp;'.
  '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.   '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
  '\')"; TARGET=_self>'.$fullname.'</a> '.   '\');" target="_self">'.$fullname.'</a> '.
  '<span class="LC_internal_info">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</span></td>'."\n";   '<span class="LC_internal_info">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</span></td>'."\n";
     $student=~s/:/_/; # colon doen't work in javascript for names      $student=~s/:/_/; # colon doen't work in javascript for names
     foreach my $apart (@$parts) {      foreach my $apart (@$parts) {
Line 6130  sub init_perm { Line 6129  sub init_perm {
 }  }
   
 sub gather_clicker_ids {  sub gather_clicker_ids {
     my %clickerids=();      my %clicker_ids;
   
     my $classlist = &Apache::loncoursedata::get_classlist();      my $classlist = &Apache::loncoursedata::get_classlist();
   
     # Set up a couple variables.      # Set up a couple variables.
     my $usernameidx = &Apache::loncoursedata::CL_SNAME();      my $username_idx = &Apache::loncoursedata::CL_SNAME();
     my $domainidx   = &Apache::loncoursedata::CL_SDOM();      my $domain_idx   = &Apache::loncoursedata::CL_SDOM();
   
     foreach my $student (keys %$classlist) {      foreach my $student (keys(%$classlist)) {
   
         my $username = $classlist->{$student}->[$usernameidx];          my $username = $classlist->{$student}->[$username_idx];
         my $domain   = $classlist->{$student}->[$domainidx];          my $domain   = $classlist->{$student}->[$domain_idx];
         my $clickers =          my $clickers =
    (&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1];      (&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1];
         foreach my $id (split(/\,/,$clickers)) {          foreach my $id (split(/\,/,$clickers)) {
             $id=~s/^0+//;              $id=~s/^[\#0]+//;
             if (exists($clickerids{$id})) {              if (exists($clicker_ids{$id})) {
                $clickerids{$id}.=','.$username.':'.$domain;   $clicker_ids{$id}.=','.$username.':'.$domain;
             } else {              } else {
                $clickerids{$id}=$username.':'.$domain;   $clicker_ids{$id}=$username.':'.$domain;
             }              }
         }          }
     }      }
     return %clickerids;      return %clicker_ids;
 }  }
   
 sub gather_adv_clicker_ids {  sub gather_adv_clicker_ids {
     my %clickerids=();      my %clicker_ids;
     my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);      my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
     foreach my $element (sort keys %coursepersonnel) {      foreach my $element (sort(keys(%coursepersonnel))) {
         foreach my $person (split(/\,/,$coursepersonnel{$element})) {          foreach my $person (split(/\,/,$coursepersonnel{$element})) {
             my ($puname,$pudom)=split(/\:/,$person);              my ($puname,$pudom)=split(/\:/,$person);
             my $clickers =              my $clickers =
                (&Apache::lonnet::userenvironment($pudom,$puname,'clickers'))[1];   (&Apache::lonnet::userenvironment($pudom,$puname,'clickers'))[1];
             foreach my $id (split(/\,/,$clickers)) {              foreach my $id (split(/\,/,$clickers)) {
                $id=~s/^0+//;   $id=~s/^[\#0]+//;
                if (exists($clickerids{$id})) {   if (exists($clicker_ids{$id})) {
                   $clickerids{$id}.=','.$puname.':'.$pudom;      $clicker_ids{$id}.=','.$puname.':'.$pudom;
                } else {   } else {
                   $clickerids{$id}=$puname.':'.$pudom;      $clicker_ids{$id}=$puname.':'.$pudom;
                }   }
             }              }
         }          }
     }      }
     return %clickerids;      return %clicker_ids;
   }
   
   sub clicker_grading_parameters {
       return ('gradingmechanism' => 'scalar',
               'upfiletype' => 'scalar',
               'specificid' => 'scalar',
               'pcorrect' => 'scalar',
               'pincorrect' => 'scalar');
 }  }
   
 sub process_clicker {  sub process_clicker {
Line 6192  sub process_clicker { Line 6199  sub process_clicker {
     $result.='&nbsp;<b>'.&mt('Specify a file containing the clicker information for this resource').      $result.='&nbsp;<b>'.&mt('Specify a file containing the clicker information for this resource').
         '.</b></td></tr>'."\n";          '.</b></td></tr>'."\n";
     $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
   # Attempt to restore parameters from last session, set defaults if not present
       my %Saveable_Parameters=&clicker_grading_parameters();
       &Apache::loncommon::restore_course_settings('grades_clicker',
                                                    \%Saveable_Parameters);
       if (!$env{'form.pcorrect'}) { $env{'form.pcorrect'}=100; }
       if (!$env{'form.pincorrect'}) { $env{'form.pincorrect'}=100; }
       if (!$env{'form.gradingmechanism'}) { $env{'form.gradingmechanism'}='attendance'; }
       if (!$env{'form.upfiletype'}) { $env{'form.upfiletype'}='iclicker'; }
   
       my %checked;
       foreach my $gradingmechanism ('attendance','personnel','specific') {
          if ($env{'form.gradingmechanism'} eq $gradingmechanism) {
             $checked{$gradingmechanism}="checked='checked'";
          }
       }
   
     my $upload=&mt("Upload File");      my $upload=&mt("Upload File");
     my $type=&mt("Type");      my $type=&mt("Type");
     my $attendance=&mt("Award points just for participation");      my $attendance=&mt("Award points just for participation");
     my $personnel=&mt("Correctness determined from response by course personnel");      my $personnel=&mt("Correctness determined from response by course personnel");
     my $specific=&mt("Correctness determined from response with clicker ID");       my $specific=&mt("Correctness determined from response with clicker ID(s)"); 
     my $pcorrect=&mt("Percentage points for correct solution");      my $pcorrect=&mt("Percentage points for correct solution");
     my $pincorrect=&mt("Percentage points for incorrect solution");      my $pincorrect=&mt("Percentage points for incorrect solution");
     my $selectform=&Apache::loncommon::select_form('iclicker','upfiletype',      my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
                                   ('iclicker' => 'i>clicker'));     ('iclicker' => 'i>clicker'));
   
     $result.=<<ENDUPFORM;      $result.=<<ENDUPFORM;
 <script type="text/javascript">  <script type="text/javascript">
Line 6249  function sanitycheck() { Line 6272  function sanitycheck() {
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />
 <input type="file" name="upfile" size="50" />  <input type="file" name="upfile" size="50" />
 <br /><label>$type: $selectform</label>  <br /><label>$type: $selectform</label>
 <br /><label>$attendance: <input type="radio" name="gradingmechanism" value="attendance" checked="checked" onClick="sanitycheck()" /></label>  <br /><label>$attendance: <input type="radio" name="gradingmechanism" value="attendance" $checked{'attendance'} onClick="sanitycheck()" /></label>
 <br /><label>$personnel: <input type="radio" name="gradingmechanism" value="personnel" onClick="sanitycheck()" /></label>  <br /><label>$personnel: <input type="radio" name="gradingmechanism" value="personnel" $checked{'personnel'} onClick="sanitycheck()" /></label>
 <br /><label>$specific: <input type="radio" name="gradingmechanism" value="specific" onClick="sanitycheck()" /></label>  <br /><label>$specific: <input type="radio" name="gradingmechanism" value="specific" $checked{'specific'} onClick="sanitycheck()" /></label>
 <input type="text" name="specificid" size="15" />  <input type="text" name="specificid" value="$env{'form.specificid'}" size="20" />
 <input type="hidden" name="waschecked" value="attendance" />  <input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" />
 <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="100" onChange="sanitycheck()" /></label>  <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onChange="sanitycheck()" /></label>
 <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="100" onChange="sanitycheck()" /></label>  <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onChange="sanitycheck()" /></label>
 <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" />  <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" />
 </form>  </form>
 ENDUPFORM  ENDUPFORM
Line 6269  sub process_clicker_file { Line 6292  sub process_clicker_file {
     my ($r)=@_;      my ($r)=@_;
     my ($symb)=&get_symb($r);      my ($symb)=&get_symb($r);
     if (!$symb) {return '';}      if (!$symb) {return '';}
   
       my %Saveable_Parameters=&clicker_grading_parameters();
       &Apache::loncommon::store_course_settings('grades_clicker',
                                                 \%Saveable_Parameters);
   
     my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});      my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
     if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {      if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {
        $result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>';   $result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>';
        return $result.&show_grading_menu_form($symb);   return $result.&show_grading_menu_form($symb);
     }      }
     my %clickerids=&gather_clicker_ids();      my %clicker_ids=&gather_clicker_ids();
     my %correctids=();      my %correct_ids;
     if ($env{'form.gradingmechanism'} eq 'personnel') {      if ($env{'form.gradingmechanism'} eq 'personnel') {
        %correctids=&gather_adv_clicker_ids();   %correct_ids=&gather_adv_clicker_ids();
     }      }
     if ($env{'form.gradingmechanism'} eq 'specific') {      if ($env{'form.gradingmechanism'} eq 'specific') {
        my $correctid=$env{'form.specificid'};   foreach my $correct_id (split(/[\s\,]/,$env{'form.specificid'})) {;
        $correctid=~tr/a-z/A-Z/;     $correct_id=~tr/a-z/A-Z/;
        $correctid=~s/\s//gs;     $correct_id=~s/\s//gs;
        $correctid=~s/^0+//;     $correct_id=~s/^[\#0]+//;
        $correctids{$correctid}='specified';             if ($correct_id) {
         $correct_ids{$correct_id}='specified';
              }
           }
     }      }
     if ($env{'form.gradingmechanism'} eq 'attendance') {      if ($env{'form.gradingmechanism'} eq 'attendance') {
        $result.=&mt('Score based on attendance only');   $result.=&mt('Score based on attendance only');
     } else {      } else {
        my $number=0;   my $number=0;
        $result.='<h3>'.&mt('Correctness determined by the following IDs').'</h3>';   $result.='<p><b>'.&mt('Correctness determined by the following IDs').'</b>';
        foreach my $id (sort(keys(%correctids))) {   foreach my $id (sort(keys(%correct_ids))) {
           $result.='<tt>'.$id.'</tt> - ';      $result.='<br /><tt>'.$id.'</tt> - ';
           if ($correctids{$id} eq 'specified') {      if ($correct_ids{$id} eq 'specified') {
              $result.=&mt('specified');   $result.=&mt('specified');
           } else {      } else {
              my ($uname,$udom)=split(/\:/,$correctids{$id});   my ($uname,$udom)=split(/\:/,$correct_ids{$id});
              $result.=&Apache::loncommon::plainname($uname,$udom);   $result.=&Apache::loncommon::plainname($uname,$udom);
           }      }
           $result.='<br />';      $number++;
           $number++;   }
        }          $result.="</p>\n";
        if ($number==0) {   if ($number==0) {
           $result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>';      $result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>';
           return $result.&show_grading_menu_form($symb);      return $result.&show_grading_menu_form($symb);
        }   }
     }      }
     if (length($env{'form.upfile'}) < 2) {      if (length($env{'form.upfile'}) < 2) {
         $result.="<span class=\"LC_error\">Error:</span> The file you attempted to upload, <tt>".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."</tt>, contained no information. Please check that you entered the correct filename.";          $result.=&mt('[_1] Error: [_2] The file you attempted to upload, [_3] contained no information. Please check that you entered the correct filename.',
        '<span class="LC_error">',
        '</span>',
        '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>');
         return $result.&show_grading_menu_form($symb);          return $result.&show_grading_menu_form($symb);
     }      }
     my %responses=();  
     my @questiontitles=();  # Were able to get all the info needed, now analyze the file
   
       $result.=&Apache::loncommon::studentbrowser_javascript();
       my $heading=&mt('Scanning clicker file');
       $result.=(<<ENDHEADER);
   <br /><table width="100%" border="0"><tr><td bgcolor="#777777">
   <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>
   <b>$heading</b></td></tr><tr bgcolor=#ffffe6><td>
   <form method="post" action="/adm/grades" name="clickeranalysis">
   <input type="hidden" name="symb" value="$symb" />
   <input type="hidden" name="command" value="assignclickergrades" />
   <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />
   <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />
   <input type="hidden" name="gradingmechanism" value="$env{'form.gradingmechanism'}" />
   <input type="hidden" name="pcorrect" value="$env{'form.pcorrect'}" />
   <input type="hidden" name="pincorrect" value="$env{'form.pincorrect'}" />
   ENDHEADER
       my %responses;
       my @questiontitles;
     my $errormsg='';      my $errormsg='';
     my $number=0;      my $number=0;
     if ($env{'form.upfiletype'} eq 'iclicker') {      if ($env{'form.upfiletype'} eq 'iclicker') {
        ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);   ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);
     }      }
     $result.='<br />'.&mt('Found [_1] questions',$number).'<br />';      $result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />'.
     foreach my $id (keys %responses) {               '<input type="hidden" name="number" value="'.$number.'" />'.
        $result.='<br />'.$id.' - '.$responses{$id};               &mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses',
                    $env{'form.pcorrect'},$env{'form.pincorrect'}).
                '<br />';
   # Remember Question Titles
   # FIXME: Possibly need delimiter other than ":"
       for (my $i=0;$i<$number;$i++) {
           $result.='<input type="hidden" name="question:'.$i.'" value="'.
                    &HTML::Entities::encode($questiontitles[$i],'"&<>').'" />';
       }
       my $correct_count=0;
       my $student_count=0;
       my $unknown_count=0;
   # Match answers with usernames
   # FIXME: Possibly need delimiter other than ":"
       foreach my $id (keys(%responses)) {
          if ($correct_ids{$id}) {
             $result.="\n".'<input type="hidden" name="correct:'.$correct_count.':'.$correct_ids{$id}.'" value="'.$responses{$id}.'" />';
             $correct_count++;
          } elsif ($clicker_ids{$id}) {
             $result.="\n".'<input type="hidden" name="student:'.$clicker_ids{$id}.'" value="'.$responses{$id}.'" />';
             $student_count++;
          } else {
             $result.="\n<hr />".&mt('Unregistered Clicker')." <tt>".$id."</tt><br />";
             $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'.
                      "\n".&mt("Username").": <input type='text' name='uname".$id."' />&nbsp;".
                      "\n".&mt("Domain").": ".
                      &Apache::loncommon::select_dom_form($env{'course.'.$env{'request.course.id'}.'.domain'},'udom'.$id).'&nbsp;'.
                      &Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id);
             $unknown_count++;
          }
     }      }
       $result.='<hr />'.
                &mt('Found [_1] registered and [_2] unregistered clickers.',$student_count,$unknown_count);
       if ($env{'form.gradingmechanism'} ne 'attendance') {
          if ($correct_count==0) {
             $errormsg.="Found no correct answers answers for grading!";
          } elsif ($correct_count>1) {
             $result.='<br /><span class="LC_warning">'.&mt("Found [_1] entries for grading!",$correct_count).'</span>';
          }
       }
       if ($errormsg) {
          $result.='<br /><span class="LC_error">'.&mt($errormsg).'</span>';
       } else {
          $result.='<br /><input type="submit" name="finalize" value="'.&mt('Finalize Grading').'" />';
       }
       $result.='</form></td></tr></table>'."\n".
                '</td></tr></table><br /><br />'."\n";
     return $result.&show_grading_menu_form($symb);      return $result.&show_grading_menu_form($symb);
 }  }
   
Line 6330  sub iclicker_eval { Line 6427  sub iclicker_eval {
     my $number=0;      my $number=0;
     my $errormsg='';      my $errormsg='';
     foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) {      foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) {
        chomp($line);          my %components=&Apache::loncommon::record_sep($line);
        foreach my $quoted ($line=~/\,\s*\"([^\"]*)\"\s*\,/g) {          my @entries=map {$components{$_}} (sort(keys(%components)));
           my $replace=$quoted;   if ($entries[0] eq 'Question') {
           $replace=~s/\,//g;      for (my $i=3;$i<$#entries;$i+=6) {
           &Apache::lonnet::logthis($quoted.' - '.$replace.'<br />');   $$questiontitles[$number]=$entries[$i];
           $line=~s/\,\s*\"\Q$quoted\E\"\s*\,/,$replace,/gs;   $number++;
       }
    }
    if ($entries[0]=~/^\#/) {
       my $id=$entries[0];
       my @idresponses;
       $id=~s/^[\#0]+//;
       for (my $i=0;$i<$number;$i++) {
    my $idx=3+$i*6;
    push(@idresponses,$entries[$idx]);
       }
       $$responses{$id}=join(',',@idresponses);
    }
       }
       return ($errormsg,$number);
   }
   
   sub assign_clicker_grades {
       my ($r)=@_;
       my ($symb)=&get_symb($r);
       if (!$symb) {return '';}
   # See which part we are saving to
       my ($partlist,$handgrade,$responseType) = &response_type($symb);
   # FIXME: This should probably look for the first handgradeable part
       my $part=$$partlist[0];
   # Start screen output
       my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
   
       my $heading=&mt('Assigning grades based on clicker file');
       $result.=(<<ENDHEADER);
   <br /><table width="100%" border="0"><tr><td bgcolor="#777777">
   <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>
   <b>$heading</b></td></tr><tr bgcolor=#ffffe6><td>
   ENDHEADER
   # Get correct result
   # FIXME: Possibly need delimiter other than ":"
       my @correct=();
       my $gradingmechanism=$env{'form.gradingmechanism'};
       my $number=$env{'form.number'};
       if ($gradingmechanism ne 'attendance') {
          foreach my $key (keys(%env)) {
             if ($key=~/^form\.correct\:/) {
                my @input=split(/\,/,$env{$key});
                for (my $i=0;$i<=$#input;$i++) {
                    if (($correct[$i]) && ($input[$i]) &&
                        ($correct[$i] ne $input[$i])) {
                       $result.='<br /><span class="LC_warning">'.
                                &mt('More than one correct result given for question "[_1]": [_2] versus [_3].',
                                    $env{'form.question:'.$i},$correct[$i],$input[$i]).'</span>';
                    } elsif ($input[$i]) {
                       $correct[$i]=$input[$i];
                    }
                }
             }
        }         }
        my @entries=split(/\,/,$line);         for (my $i=0;$i<$number;$i++) {
        if ($entries[0] eq 'Question') {            if (!$correct[$i]) {
           for (my $i=3;$i<$#entries;$i+=6) {               $result.='<br /><span class="LC_error">'.
               $$questiontitles[$number]=$entries[$i];                        &mt('No correct result given for question "[_1]"!',
               $number++;                            $env{'form.question:'.$i}).'</span>';
           }            }
        }         }
        if ($entries[0]=~/^\#/) {         $result.='<br />'.&mt("Correct answer: [_1]",join(', ',map { ($_?$_:'-') } @correct));
           my $id=$entries[0];      }
           my @idresponses=();  # Start grading
           $id=~s/^[\#0]+//;      my $pcorrect=$env{'form.pcorrect'};
       my $pincorrect=$env{'form.pincorrect'};
       my $storecount=0;
       foreach my $key (keys(%env)) {
          if ($key=~/^form\.student\:(.*)$/) {
             my $user=$1;
             my @answer=split(/\,/,$env{$key});
             my $sum=0;
           for (my $i=0;$i<$number;$i++) {            for (my $i=0;$i<$number;$i++) {
              my $idx=3+$i*6;               if ($answer[$i]) {
              push(@idresponses,$entries[$idx]);                  if ($gradingmechanism eq 'attendance') {
                      $sum+=$pcorrect;
                   } else {
                      if ($answer[$i] eq $correct[$i]) {
                         $sum+=$pcorrect;
                      } else {
                         $sum+=$pincorrect;
                      }
                   }
                }
             }
             my $ave=$sum/(100*$number);
   # Store
             my ($username,$domain)=split(/\:/,$user);
             my %grades=();
             $grades{"resource.$part.solved"}='correct_by_override';
             $grades{"resource.$part.awarded"}=$ave;
             $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";
             my $returncode=&Apache::lonnet::cstore(\%grades,$symb,
                                                    $env{'request.course.id'},
                                                    $domain,$username);
             if ($returncode ne 'ok') {
                $result.="<br /><span class=\"LC_error\">Failed to save student $username:$domain. Message when trying to save was ($returncode)</span>";
             } else {
                $storecount++;
           }            }
           $$responses{$id}=join(',',@idresponses);  
        }         }
     }      }
     return ($errormsg,$number);  # We are done
       $result.='<br />'.&mt('Successfully stored grades for [_1] student(s).',$storecount).
                '</td></tr></table>'."\n".
                '</td></tr></table><br /><br />'."\n";
       return $result.&show_grading_menu_form($symb);
 }  }
   
 sub handler {  sub handler {
Line 6429  sub handler { Line 6613  sub handler {
             $request->print(&process_clicker($request));              $request->print(&process_clicker($request));
         } elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {          } elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {
             $request->print(&process_clicker_file($request));              $request->print(&process_clicker_file($request));
           } elsif ($command eq 'assignclickergrades' && $perm{'mgr'}) {
               $request->print(&assign_clicker_grades($request));
  } elsif ($command eq 'csvform' && $perm{'mgr'}) {   } elsif ($command eq 'csvform' && $perm{'mgr'}) {
     $request->print(&upcsvScores_form($request));      $request->print(&upcsvScores_form($request));
  } elsif ($command eq 'csvupload' && $perm{'mgr'}) {   } elsif ($command eq 'csvupload' && $perm{'mgr'}) {

Removed from v.1.406  
changed lines
  Added in v.1.417


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