Diff for /loncom/interface/lonquickgrades.pm between versions 1.90 and 1.114

version 1.90, 2011/05/24 18:06:10 version 1.114, 2018/11/13 03:59:00
Line 29 Line 29
 package Apache::lonquickgrades;  package Apache::lonquickgrades;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http REDIRECT);
 use POSIX;  use POSIX;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::grades;  use Apache::grades;
   use Apache::loncoursedata;
   use Apache::lonstudentassessment;
   use Apache::lonuserstate;
   
   use Time::HiRes;
   use Spreadsheet::WriteExcel;
   use Spreadsheet::WriteExcel::Utility();
   #
   # Excel data
   #
   my $excel_sheet;
   my $excel_workbook;
   my $filename;
   my $format;
   my $request_aborted;
   my $header_row;
   my $cols_output;
   my %prog_state;
   
   
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
Line 57  sub real_handler { Line 76  sub real_handler {
         return OK;          return OK;
     }      }
   
     # Send header, don't cache this page      my $cangrade=&Apache::lonnet::allowed('mgr');
     &Apache::loncommon::no_cache($r);  
     $r->send_http_header;  
   
     my $showPoints =      my $showPoints =
         (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'standard')          (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'standard')
       || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'categories'));        || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'categories'));
     my $notshowSPRSlink =  
         (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'external')  
       || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals'));  
     my $notshowTotals=  
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals';  
     my $showCategories=  
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'categories';  
   
       my $reinitresult;
   
     my $title = "Grading and Statistics";#$showPoints ? "Points Display" : "Completed Problems Display";      unless ($cangrade) {
     my $brcrum = [{href=>"/adm/quickgrades",text => "Points Display"}];          # Check for critical messages and redirect if present.
     $r->print(&Apache::loncommon::start_page($title,undef,          my ($redirect,$url) = &Apache::loncommon::critical_redirect(300,'grades');
                                             {'bread_crumbs' => $brcrum})          if ($redirect) {
              );              &Apache::loncommon::content_type($r,'text/html');
               $r->header_out(Location => $url);
               return REDIRECT;
           }
   
           # Check if course needs to be re-initialized
           my $loncaparev = $r->dir_config('lonVersion');
           ($reinitresult,my @reinit) = &Apache::loncommon::needs_coursereinit($loncaparev);
   
           if ($reinitresult eq 'switch') {
               &Apache::loncommon::content_type($r,'text/html');
               $r->send_http_header;
               $r->print(&Apache::loncommon::check_release_result(@reinit));
               return OK;
           } elsif ($reinitresult eq 'update') {
               my $cid = $env{'request.course.id'};
               my $cnum = $env{'course.'.$cid.'.num'};
               my $cdom = $env{'course.'.$cid.'.domain'};
               &Apache::loncommon::content_type($r,'text/html');
               $r->send_http_header;
               &startpage($r,$showPoints);
               my $preamble = '<div id="LC_update_'.$cid.'" class="LC_info">'.
                              '<br />'.
                              &mt('Your course session is being updated because of recent changes by course personnel.').
                              ' '.&mt('Please be patient.').'<br /></div>'.
                              '<div style="padding:0;clear:both;margin:0;border:0"></div>';
               %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,undef,$preamble);
               &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Updating course'));
               $r->rflush();
               my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
               &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Finished')); 
               &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
               my $closure = <<ENDCLOSE;
   <script type="text/javascript">
   // <![CDATA[
   \$("#LC_update_$cid").hide('slow');
   // ]]>
   </script>
   ENDCLOSE
               if ($ferr) {
                   $r->print($closure.&Apache::loncommon::end_page());
                   my $requrl = $r->uri;
                   $env{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
                   $env{'user.reinit'} = 1;
                   return HTTP_NOT_ACCEPTABLE;
               } else {
                  $r->print($closure);
               }
           } elsif ((&Apache::loncommon::course_type() eq 'Placement') &&
                    (!$env{'request.role.adv'})) {
               my $furl = &Apache::lonpageflip::first_accessible_resource();
               &Apache::loncommon::content_type($r,'text/html');
               $r->header_out(Location => $furl);
               return REDIRECT;
           }
       }
   
       unless ($reinitresult eq 'update') {
           # Send header, don't cache this page
           &Apache::loncommon::no_cache($r);
           $r->send_http_header;
           &startpage($r,$showPoints);
       }
       $r->rflush();
   
     &startGradeScreen($r,'quick');      &startGradeScreen($r,'quick');
   
     my $cangrade=&Apache::lonnet::allowed('mgr');  
 #  #
 # Pick student  # Pick student
 #  #
Line 89  sub real_handler { Line 161  sub real_handler {
     my $udom;      my $udom;
     my $stdid;      my $stdid;
     if ($cangrade) {      if ($cangrade) {
           $r->print("<h2>".&mt("Download Multiple")."</h2>".
                     '<table cellspacing="5">'."\n".
                     '<tr>'.
                     '<td align="center"><b>'.&mt('Sections').'</b>'.
                     &Apache::loncommon::help_open_topic("Chart_Sections").
                     '</td>'.
                     '<td align="center"><b>'.&mt('Groups').'</b>'.
                     '</td>'.
                     '<td align="center"><b>'.&mt('Student Data').'</b>'.
                     &Apache::loncommon::help_open_topic("Chart_Student_Data").
                     '</td>'.
                     '<td align="center"><b>'.&mt('Access Status').'</b>'.
                     &Apache::loncommon::help_open_topic("Chart_Enrollment_Status").
                     '</td>'.
                     '<td align="center"><b>'.&mt('Output Format').'</b>'.
                     &Apache::loncommon::help_open_topic("Chart_Output_Formats").
                     '</td><td>&nbsp;</td></tr>'."\n".
                     '<tr><td align="center">'."\n".
                     &Apache::lonstatistics::SectionSelect('Section','multiple',5).
                     '</td><td align="center">'.
                     &Apache::lonstatistics::GroupSelect('Group','multiple',5).
                     '</td><td align="center">'.
                     &Apache::lonstatistics::StudentDataSelect('StudentData','multiple',5,undef).
                     '</td><td>'."\n".
                     &Apache::lonhtmlcommon::StatusOptions(undef,undef,5).
                     '</td><td>'."\n".
                     &Apache::lonstudentassessment::CreateAndParseOutputSelector().
                     '</td><td>'.
                     '<input type="submit" name="download" value="'.&mt('Display/Download Multiple Students').'" />'.
                     '</td></tr>'."\n".
                     '</table>'."\n"
                    );
           $r->print("<hr /><h2>".&mt("Display Individual")."</h2>");
         if ($env{'form.uname'}) { $uname=$env{'form.uname'}; }          if ($env{'form.uname'}) { $uname=$env{'form.uname'}; }
         if ($env{'form.udom'}) { $udom=$env{'form.udom'}; }          if ($env{'form.udom'}) { $udom=$env{'form.udom'}; }
         if ($env{'form.id'}) { $stdid=$env{'form.id'}; }          if ($env{'form.id'}) { $stdid=$env{'form.id'}; }
         if (($stdid) && ($udom)) {          if (($stdid) && ($udom)) {
             $uname=(&Apache::lonnet::idget($udom,$stdid))[1];              $uname=(&Apache::lonnet::idget($udom,[$stdid],'ids'))[1];
         }          }
         if (($stdid) && (!$uname)) {          if (($stdid) && (!$uname)) {
             $r->print('<p><span class="LC_warning">'.&mt("Unknown Student/Employee ID: [_1]",$stdid).'</span></p>');              $r->print('<p><span class="LC_warning">'.&mt("Unknown Student/Employee ID: [_1]",$stdid).'</span></p>');
Line 106  sub real_handler { Line 211  sub real_handler {
         $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'          $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
                  ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'                   ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
                  ,'<input type="text" value="'.$stdid.'" size="12" name="id" /> '                   ,'<input type="text" value="'.$stdid.'" size="12" name="id" /> '
                  ,$chooseopt).'<br />'.                   ,$chooseopt).
                  '<input type="submit" name="display" value="'.&mt('Update Display').'" /></p>');                   '&nbsp;&nbsp;<input type="submit" name="display" value="'.&mt('Display Individual Student').'" /></p>');
         if (($uname) && ($udom)) {          if (($uname) && ($udom)) {
             $r->print('<p>'.&mt('Full Name: [_1]',&Apache::loncommon::plainname($uname,$udom)).'</p>');              $r->print('<p>'.&mt('Full Name: [_1]',&Apache::loncommon::plainname($uname,$udom)).'</p>');
         }          }
     }      }
     $r->rflush();      $r->rflush();
   
       my $notshowSPRSlink =
           (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'external')
         || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals'));
       my $notshowTotals=
           $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals';
       my $showCategories=
           $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'categories';
   
     my ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=      my ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=
        &getData($showPoints,$uname,$udom);         &getData($showPoints,$uname,$udom);
   
Line 130  sub real_handler { Line 243  sub real_handler {
   
 }  }
   
   sub getStudentCatGrade {
       my ($uname,$udom,%categories)=@_;
       my ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=
          &getData(1,$uname,$udom);
       return &output_category_table(undef,0,$navmap,0,%categories);
   }
   
   sub getAllStudentData {
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   
       my %categories=&Apache::lonnet::dump('grading_categories',$cdom,$cnum);
   
       my $classlist = &Apache::loncoursedata::get_classlist();
   
       my $statusidx   = &Apache::loncoursedata::CL_STATUS();
       my $usernameidx = &Apache::loncoursedata::CL_SNAME();
       my $domainidx   = &Apache::loncoursedata::CL_SDOM();
       my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME();
   
       foreach my $key (keys(%{$classlist})) {
           my $student = $classlist->{$key};
           my $perc=&getStudentCatGrade($classlist->{$student}->[$usernameidx],
                                        $classlist->{$student}->[$domainidx],
                                        %categories);
       }
   }
   
   sub startpage {
       my ($r,$showPoints) = @_;
       my $title = "Grading and Statistics";#$showPoints ? "Points Display" : "Completed Problems Display";
       my $brcrum = [{href=>"/adm/quickgrades",text => "Points Display"}];
       $r->print(&Apache::loncommon::start_page($title,undef,
                                               {'bread_crumbs' => $brcrum})
                );
   }
   
 sub startGradeScreen {  sub startGradeScreen {
     my ($r,$mode)=@_;      my ($r,$mode)=@_;
   
Line 172  sub startGradeScreen { Line 322  sub startGradeScreen {
                                                                  &mt('Statistics and Reports').'</b></a></li>');                                                                   &mt('Statistics and Reports').'</b></a></li>');
   
        $r->print("\n".'<li'.($mode eq 'chart'?' class="active"':'').'><a href="/adm/statistics?reportSelected=student_assessment"><b>'.         $r->print("\n".'<li'.($mode eq 'chart'?' class="active"':'').'><a href="/adm/statistics?reportSelected=student_assessment"><b>'.
                                                                  &mt('Assessment Overview Chart').'</b></a></li>');                                                                   &mt('Assessment Chart').'</b></a></li>');
   
     }      }
     if ($allowed_to_edit) {      if ($allowed_to_edit) {
Line 181  sub startGradeScreen { Line 331  sub startGradeScreen {
        if ($env{'form.symb'}) {         if ($env{'form.symb'}) {
           $r->print("\n".'<li'.($mode eq 'probgrading'?' class="active"':'').'><a href="/adm/grades?symb='.            $r->print("\n".'<li'.($mode eq 'probgrading'?' class="active"':'').'><a href="/adm/grades?symb='.
                                               &Apache::lonhtmlcommon::entity_encode($env{'form.symb'}).                                                &Apache::lonhtmlcommon::entity_encode($env{'form.symb'}).
                                               '&command=gradingmenu"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.                                                '&amp;command=gradingmenu"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.
                                               &mt('Problem Grading').'&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>');                                                &mt('Problem Grading').'&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>');
   
        }         }
Line 195  sub endGradeScreen { Line 345  sub endGradeScreen {
    $r->print('</div></div></div>'.&Apache::loncommon::end_page());     $r->print('</div></div></div>'.&Apache::loncommon::end_page());
 }  }
   
   # -----------
   
   
   sub excel_cleanup {
       undef ($excel_sheet);
       undef ($excel_workbook);
       undef ($filename);
       undef ($format);
   }
   
   
   sub excel_initialize {
       my ($r) = @_;
   
       &excel_cleanup();
   
       # Create sheet
       ($excel_workbook,$filename,$format)=
           &Apache::loncommon::create_workbook($r);
       return if (! defined($excel_workbook));
      #
      # Add a worksheet
       my $sheetname = $env{'course.'.$env{'request.course.id'}.'.description'};
       $sheetname = &Apache::loncommon::clean_excel_name($sheetname);
       $excel_sheet = $excel_workbook->addworksheet($sheetname);
      #
      # Put the course description in the header
       $excel_sheet->write($header_row,$cols_output++,
                      $env{'course.'.$env{'request.course.id'}.'.description'},
                           $format->{'h1'});
   } 
   
   sub excel_finish {
       my ($r) = @_;
       if ($request_aborted || ! defined($excel_sheet)) {
           &excel_cleanup();
           return;
       }
       #
       # Write the excel file
       $excel_workbook->close();
       #
       # Close the progress window
       &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
       #
       # Tell the user where to get their excel file
       $r->print('<br />'.
                 '<a href="'.$filename.'">'.&mt('Your Excel spreadsheet').'</a>'."\n");
       $r->rflush();
       &excel_cleanup();
       return;
   }
   
   
   #
   # CSV data
   #
   # -----------
   
   #
   # Go through the complete course and collect data
   #
   
 sub getData {  sub getData {
   
Line 232  sub getData { Line 444  sub getData {
         if ($curRes == $iterator->BEGIN_MAP()) {$depth++;}          if ($curRes == $iterator->BEGIN_MAP()) {$depth++;}
         if ($curRes == $iterator->END_MAP()) { $depth--; }          if ($curRes == $iterator->END_MAP()) { $depth--; }
   
         if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout)          if (ref($curRes) && $curRes->is_gradable() && !$curRes->randomout && 
               ($curRes->deeplink ne 'absent'))
         {          {
             # Get number of correct, incorrect parts              # Get number of correct, incorrect parts
             my $parts = $curRes->parts();              my $parts = $curRes->parts();
Line 242  sub getData { Line 455  sub getData {
             my $stack = $iterator->getStack();              my $stack = $iterator->getStack();
                           
             for my $part (@{$parts}) {              for my $part (@{$parts}) {
  my $completionStatus = $curRes->getCompletionStatus($part);  
  my $dateStatus = $curRes->getDateStatus($part);   my $dateStatus = $curRes->getDateStatus($part);
                   my $weight = $curRes->weight($part);
                 if ($completionStatus == $curRes->EXCUSED()) {                  my $problemstatus = $curRes->problemstatus($part);
   
                   if ($curRes->solved($part) eq 'excused') {
                     next;                      next;
                 }                  }
  if ($showPoints) {   if ($showPoints) {
     my $score = 0;      my $score = 0;
     # If we're not telling status and the answer date isn't passed yet,       # If we're not telling status and the answer date isn't passed yet, 
     # it's an "attempted" point      # it's an "attempted" point
     if ((($curRes->problemstatus($part) eq 'no') ||      if ((($problemstatus eq 'no') ||
                         ($curRes->problemstatus($part) eq 'no_feedback_ever')) &&                           ($problemstatus eq 'no_feedback_ever')) &&
  ($dateStatus != $curRes->ANSWER_OPEN)) {   ($dateStatus != $curRes->ANSWER_OPEN)) {
  my $status = $curRes->simpleStatus($part);   my $status = $curRes->simpleStatus($part);
  if ($status == $curRes->ATTEMPTED) {   if ($status == $curRes->ATTEMPTED) {
     $partsAttempted += $curRes->weight($part);      $partsAttempted += $weight;
     $totalAttempted += $partsAttempted;      $totalAttempted += $partsAttempted;
  }   }
     } else {      } else {
  $score = &Apache::grades::compute_points($curRes->weight($part), $curRes->awarded($part));   $score = &Apache::grades::compute_points($weight, $curRes->awarded($part));
     }      }
     $partsRight += $score;      $partsRight += $score;
     $totalRight += $score;      $totalRight += $score;
     $partsCount += $curRes->weight($part);      $partsCount += $weight;
   
                     $curRes->{DATA}->{PROB_SCORE}  += $score;                      $curRes->{DATA}->{PROB_SCORE}  += $score;
                     $curRes->{DATA}->{PROB_WEIGHT} += $curRes->weight($part);                      $curRes->{DATA}->{PROB_WEIGHT} += $weight;
   
     if ($curRes->opendate($part) < $now) {      if ($curRes->opendate($part) < $now) {
  $totalPossible += $curRes->weight($part);   $totalPossible += $weight;
                         $curRes->{DATA}->{PROB_POSSIBLE} += $curRes->weight($part);                          $curRes->{DATA}->{PROB_POSSIBLE} += $weight;
     }      }
     $totalParts += $curRes->weight($part);      $totalParts += $weight;
  } else {   } else {
     my $status = $curRes->simpleStatus($part);      my $status = $curRes->simpleStatus($part);
     my $thisright = 0;      my $thisright = 0;
Line 291  sub getData { Line 505  sub getData {
  $totalAttempted++;   $totalAttempted++;
     }      }
           
     my $dateStatus = $curRes->getDateStatus($part);  
     $totalParts++;      $totalParts++;
     if ($curRes->opendate($part) < $now) {      if ($curRes->opendate($part) < $now) {
  $totalPossible++;   $totalPossible++;
Line 461  sub outputCategories { Line 674  sub outputCategories {
         &Apache::lonnet::put('grading_categories',\%categories,$cdom,$cnum);          &Apache::lonnet::put('grading_categories',\%categories,$cdom,$cnum);
     }      }
 # new categories loaded now  # new categories loaded now
     &output_category_table($r,$cangrade,$navmap,%categories);      &output_category_table($r,$cangrade,$navmap,1,%categories);
 #  #
     if ($cangrade) {      if ($cangrade) {
         $r->print(&Apache::loncommon::resourcebrowser_javascript().          $r->print(&Apache::loncommon::resourcebrowser_javascript().
Line 471  sub outputCategories { Line 684  sub outputCategories {
                   '<input type="submit" name="storechanges" value="'.&mt("Save changes to grading categories").'" />'.                    '<input type="submit" name="storechanges" value="'.&mt("Save changes to grading categories").'" />'.
                   '<script>function storecmd (cmd) { document.quickform.cmd.value=cmd; document.quickform.submit(); }</script>');                    '<script>function storecmd (cmd) { document.quickform.cmd.value=cmd; document.quickform.submit(); }</script>');
     }      }
 #  
 # Debug  
 #  
 #    my %data=&dumpdata($navmap);  
 #    foreach (keys(%data)) {  
 #        $r->print("\n<br />".$_.'='.$data{$_});  
 #    }  
 }  }
   
 #  #
Line 560  sub process_category_edits { Line 766  sub process_category_edits {
 #  #
   
 sub output_category_table {  sub output_category_table {
     my ($r,$cangrade,$navmaps,%categories)=@_;      my ($r,$cangrade,$navmaps,$output,%categories)=@_;
     my $sum=0;      
     my $total=0;      my $totalweight=0;
     $r->print(&Apache::loncommon::start_data_table());      my $totalpoints=0;
   
       if ($output) { 
          $r->print(&Apache::loncommon::start_data_table());
 #  #
     &output_category_table_header($r,$cangrade);         &output_category_table_header($r,$cangrade);
       }
 #  #
     my @order=split(/\,/,$categories{'order'});      my @order=split(/\,/,$categories{'order'});
 #  #
     my %performance=&dumpdata($navmaps);      my %performance=&dumpdata($navmaps);
     my $maxpos=$#order;      my $maxpos=$#order;
     for (my $i=0;$i<=$maxpos;$i++) {      for (my $i=0;$i<=$maxpos;$i++) {
         my ($value,$weight)=&output_and_calc_category($r,$cangrade,$navmaps,$order[$i],$i,$maxpos,\%performance,1,%categories);          my ($correct,$possible,$type,$weight)=&output_and_calc_category($r,$cangrade,$navmaps,$order[$i],$i,$maxpos,\%performance,$output,%categories);
         $sum+=$value*$weight;          unless ($possible) { next; }
         $total+=$weight;          $totalpoints+=$weight*$correct/$possible;
           $totalweight+=$weight;
     }      }
 #  #
     &bottom_line_category($r,$cangrade,$sum,$total);      my $perc=0;
 #      if ($totalweight) { $perc=100.*$totalpoints/$totalweight; }
     $r->print(&Apache::loncommon::end_data_table());  
     return $sum;      if ($output) { 
           &bottom_line_category($r,$cangrade,$perc); 
           $r->print(&Apache::loncommon::end_data_table());
       }
       return $perc;
 }  }
   
 sub output_category_table_header {  sub output_category_table_header {
Line 605  sub output_category_table_header { Line 820  sub output_category_table_header {
   
 sub output_and_calc_category {  sub output_and_calc_category {
     my ($r,$cangrade,$navmaps,$id,$currentpos,$maxpos,$performance,$output,%categories)=@_;      my ($r,$cangrade,$navmaps,$id,$currentpos,$maxpos,$performance,$output,%categories)=@_;
     my $value=0;      
     my $weight=0;  
     my $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");  
     my %lt=&Apache::lonlocal::texthash(  
            'up' => 'Move Up',  
            'dw' => 'Move Down');  
     if ($output) { $r->print("\n".&Apache::loncommon::start_data_table_row()); }      if ($output) { $r->print("\n".&Apache::loncommon::start_data_table_row()); }
   
     if ($output && $cangrade) {      if ($output && $cangrade) {
           my $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
           my %lt=&Apache::lonlocal::texthash(
              'up' => 'Move Up',
              'dw' => 'Move Down');
   
         $r->print(<<ENDMOVE);          $r->print(<<ENDMOVE);
 <td>  <td>
 <div class="LC_docs_entry_move">  <div class="LC_docs_entry_move">
Line 646  ENDMOVE Line 861  ENDMOVE
 # Content display and summing up of points  # Content display and summing up of points
     my $totalpossible=0;      my $totalpossible=0;
     my $totalcorrect=0;      my $totalcorrect=0;
       my @individual=();
     if ($output) { $r->print('<td><ul>'); }      if ($output) { $r->print('<td><ul>'); }
     foreach my $contentid (split(/\,/,$categories{$id.'_content'})) {      foreach my $contentid (split(/\,/,$categories{$id.'_content'})) {
         my ($type,$possible,$attempted,$correct)=split(/\:/,$$performance{$contentid});          my ($type,$possible,$attempted,$correct)=split(/\:/,$$performance{$contentid});
         $totalpossible+=$possible;          $totalpossible+=$possible;
         $totalcorrect+=$correct;          $totalcorrect+=$correct;
           if ($possible>0) { push(@individual,"$possible:$correct"); }
         if ($output) {          if ($output) {
            $r->print('<li>');             $r->print('<li>');
            $r->print(&Apache::lonnet::gettitle($contentid).' ('.$correct.'/'.$possible.')');             $r->print(&Apache::lonnet::gettitle($contentid).' ('.&numberout($correct).'/'.&numberout($possible).')');
            if ($cangrade) {             if ($cangrade) {
               $r->print(' <a href="javascript:storecmd(\'delcont_'.$id.'______'.$contentid.'\');">'.&mt('Delete').'</a>');                $r->print(' <a href="javascript:storecmd(\'delcont_'.$id.'______'.$contentid.'\');">'.&mt('Delete').'</a>');
            }             }
Line 662  ENDMOVE Line 879  ENDMOVE
     }      }
     if ($output) {      if ($output) {
        $r->print('</ul>');         $r->print('</ul>');
        $r->print('<p>'.&mt('Total raw points: [_1]/[_2]',$totalcorrect,$totalpossible).'</p>');   
        if ($cangrade) {         if ($cangrade) {
            $r->print('<br />'.&Apache::loncommon::selectresource_link('quickform','addcont_'.$id,&mt('Add Problem or Folder')).'<br />');             $r->print('<br />'.&Apache::loncommon::selectresource_link('quickform','addcont_'.$id,&mt('Add Problem or Folder')).'<br />');
        }         }
          $r->print('<p><b>'.&mt('Total raw points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'</b></p>');
        $r->print('</td>');          $r->print('</td>'); 
     }      }
 # Total  # Total
Line 690  ENDMOVE Line 907  ENDMOVE
        $totalpossible=1.*$categories{$id.'_total'};         $totalpossible=1.*$categories{$id.'_total'};
     }      }
     if ($output) {      if ($output) {
        $r->print('<p>'.&mt('Adjusted raw points: [_1]/[_2]',$totalcorrect,$totalpossible).'</p>');         $r->print('<p><b>'.&mt('Adjusted raw points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'</b></p>');
     }      }
   
   
Line 703  ENDMOVE Line 920  ENDMOVE
         if ($cangrade) {          if ($cangrade) {
            if ($output) { $r->print(' <a href="javascript:storecmd(\'delrule_'.$id.'______'.$code.'\');">'.&mt('Delete').'</a>'); }             if ($output) { $r->print(' <a href="javascript:storecmd(\'delrule_'.$id.'______'.$code.'\');">'.&mt('Delete').'</a>'); }
         }          }
           if ($code eq 'capabove') {
               if ($totalpossible>0) {
                   if ($totalcorrect/$totalpossible>$value/100.) {
                       $totalcorrect=$totalpossible*$value/100.;
                   }
               }
           } elsif ($code eq 'capbelow') {
               if ($totalpossible>0) {
                   if ($totalcorrect/$totalpossible<$value/100.) {
                       $totalcorrect=$totalpossible*$value/100.;
                   }
               }
           } elsif ($code eq 'droplow') {
               ($totalpossible,$totalcorrect,@individual)=&drop(0,0,$value,@individual);
           } elsif ($code eq 'drophigh') {
               ($totalpossible,$totalcorrect,@individual)=&drop(1,0,$value,@individual);
           } elsif ($code eq 'droplowperc') {
               ($totalpossible,$totalcorrect,@individual)=&drop(0,1,$value,@individual);
           } elsif ($code eq 'drophighperc') {
               ($totalpossible,$totalcorrect,@individual)=&drop(1,1,$value,@individual);
           }
         if ($output) { $r->print('</li>'); }          if ($output) { $r->print('</li>'); }
     }      }
     if ($output) { $r->print('</ul>'); }  # Re-adjust total points if force total
     if ($cangrade) {      if ($categories{$id.'_totaltype'} eq 'typein') {
         if ($output) { $r->print('<br />'.&new_calc_rule_form($id)); }         $totalpossible=1.*$categories{$id.'_total'};
     }      }
     if ($output) { $r->print('</td>'); }  
   
       if ($output) { 
           $r->print('</ul>'); 
           if ($cangrade) { $r->print('<br />'.&new_calc_rule_form($id)); }
           $r->print('<p><b>'.&mt('Calculated points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'</b></p>');
           $r->print('</td>'); 
       }
   #
   # Prepare for export
   #
 # Weight  # Weight
       my $weight=$categories{$id.'_weight'};
       unless (1.*$weight>0) { $weight=0; }
     if ($cangrade) {      if ($cangrade) {
        if ($output) {          if ($output) { 
           $r->print('<td>'.            $r->print('<td>'.
                   '<input type="text" size="4" name="weight_'.$id.                    '<input type="text" size="4" name="weight_'.$id.
                   '" value="'.&Apache::lonhtmlcommon::entity_encode($categories{$id.'_weight'}).'" /></td>');                    '" value="'.&Apache::lonhtmlcommon::entity_encode($weight).'" /></td>');
        }         }
     } else {      } else {
        if ($output) {         if ($output) {
           $r->print('<td>'.$categories{$id.'_weight'}.'</td>');            $r->print('<td>'.$weight.'</td>');
        }         }
     }      }
 # Achieved  # Achieved
       my $type=$categories{$id.'_displayachieved'};
       unless (($type eq 'percent') || ($type eq 'points')) { $type='points'; }
     if ($output) { $r->print('<td>'); }      if ($output) { $r->print('<td>'); }
     if ($cangrade) {      if ($cangrade) {
         if ($output) {          if ($output) {
            $r->print('<select name="displayachieved_'.$id.'">'.             $r->print('<select name="displayachieved_'.$id.'">'.
                   '<option value="percent"'.($categories{$id.'_displayachieved'} eq 'percent'?' selected="selected"':'').'>'.&mt('percent').'</option>'.                    '<option value="percent"'.($type eq 'percent'?' selected="selected"':'').'>'.&mt('percent').'</option>'.
                   '<option value="points"'.($categories{$id.'_displayachieved'} eq 'points'?' selected="selected"':'').'>'.&mt('points').'</option>'.                    '<option value="points"'.($type eq 'points'?' selected="selected"':'').'>'.&mt('points').'</option>'.
                   '</select>');                    '</select>');
         }          }
     } else {      }
         if ($output) {      if ($output) {
             if ($categories{$id.'_displayachieved'} eq 'percent') {          $r->print('<p><b>');
                 $r->print(&mt('percent'));          if ($type eq 'percent') {
             } else {              my $perc='---';
                 $r->print(&mt('points'));              if ($totalpossible) {
                   $perc=100.*$totalcorrect/$totalpossible;
             }              }
               $r->print(&mt('[_1] percent',&numberout($perc)));
           } else {
               $r->print(&mt('[_1]/[_2] points',&numberout($totalcorrect),&numberout($totalpossible)));
         }          }
           $r->print('</b></p>');
     }      }
     if ($output) { $r->print('</td>'); }      if ($output) { $r->print('</td>'); }
   
     return ($value,$weight);      return ($totalcorrect,$totalpossible,$type,$weight);
 }  }
   
 #  #
   # Drop folders and problems
   #
   
   sub drop {
       my ($high,$percent,$n,@individual)=@_;
   # Sort assignments by points or percent
       my @newindividual=sort {
           my ($pa,$ca)=split(/\:/,$a);
           my ($pb,$cb)=split(/\:/,$b);
           if ($percent) {
               my $perca=0;
               if ($pa>0) { $perca=$ca/$pa; }
               my $percb=0;
               if ($pb>0) { $percb=$cb/$pb; }
               $perca<=>$percb;
           } else {
               $ca<=>$cb;
           }
       } @individual;
   # Drop the ones we don't want
       if ($#newindividual>=$n) {
           if ($high) {
              splice(@newindividual,$#newindividual+1-$n,$n);
           } else {
              splice(@newindividual,0,$n);
           }
       } else {
           @newindividual=();
       }
   # Re-calculate how many points possible and achieved
       my $newpossible=0;
       my $newcorrect=0;
       for my $score (@newindividual) {
           my ($thispossible,$thiscorrect)=(split(/\:/,$score));
           $newpossible+=$thispossible;
           $newcorrect+=$thiscorrect;
       }
       return ($newpossible,$newcorrect,@newindividual);
   } 
   #
 # Bottom line with grades  # Bottom line with grades
 #  #
   
 sub bottom_line_category {  sub bottom_line_category {
     my ($r,$cangrade,$sum,$total)=@_;      my ($r,$cangrade,$perc)=@_;
     $r->print(&Apache::loncommon::start_data_table_row());      $r->print(&Apache::loncommon::start_data_table_row());
     if ($cangrade) {      if ($cangrade) {
         $r->print('<td colspan="3"><a href="javascript:storecmd(\'createnewcat\');">'.&mt('Create New Category').'</a></td>');          $r->print('<td colspan="3"><a href="javascript:storecmd(\'createnewcat\');">'.&mt('Create New Category').'</a></td>');
     }      }
     $r->print('<td colspan="6">'.&mt('Current:').$sum.'<br />'.&mt('Total:').$total.'<br /></td>');      $r->print('<td colspan="6"><b>'.&mt('Total: [_1] percent',&numberout($perc)).'</b></td>');
 }  }
   
   sub numberout {
       my ($number)=@_;
       my $printout=sprintf("%.3f", $number);
       $printout=~s/0+$//;
       $printout=~s/\.$//;
       return $printout;
   }
 #  #
 # Make one new category  # Make one new category
 #  #
Line 789  sub make_new_category { Line 1091  sub make_new_category {
   
 sub category_rule_codes {  sub category_rule_codes {
     return &Apache::lonlocal::texthash(      return &Apache::lonlocal::texthash(
                 'droplow'  => 'Drop N lowest grade assignments',                  'droplowperc'  => 'Drop N lowest grade percentage problems/folders',
                 'drophigh' => 'Drop N highest grade assignments',                  'drophighperc' => 'Drop N highest grade percentage problems/folderss',
                   'droplow'  => 'Drop N lowest point problems/folders',
                   'drophigh' => 'Drop N highest point problems/folders',
                 'capabove' => 'Cap percentage above N percent',                  'capabove' => 'Cap percentage above N percent',
                 'capbelow' => 'Cap percentage below N percent');                  'capbelow' => 'Cap percentage below N percent');
 }  }

Removed from v.1.90  
changed lines
  Added in v.1.114


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