Diff for /loncom/interface/statistics/lonstudentassessment.pm between versions 1.31 and 1.33

version 1.31, 2003/03/03 19:28:29 version 1.33, 2003/03/04 14:21:36
Line 83  my $Statistics; Line 83  my $Statistics;
   
 =item $output_mode 'html', 'excel', or 'csv' for output mode  =item $output_mode 'html', 'excel', or 'csv' for output mode
   
 =item $show 'all' or 'totals' determines how much data is output  =item $show 'all', 'totals', or 'scores' determines how much data is output
   
 =cut  =cut
   
Line 143  the button marked "Update Disp Line 143  the button marked "Update Disp
 </font>  </font>
 </p>  </p>
 ENDMSG  ENDMSG
   #        $r->print(&OutputDescriptions());
         return;          return;
     }      }
     #      #
Line 270  sub CreateInterface { Line 271  sub CreateInterface {
   
 #######################################################  #######################################################
 #######################################################  #######################################################
   my @OutputOptions = 
       ({ name  => 'HTML, with links',
          value => 'html, with links',
          description => 'Output HTML with each symbol linked to the problem '.
      'which generated it.'},
        { name  => 'HTML, without links',
          value => 'html, without links',
          description => 'Output HTML.  By not including links, the size of the'.
      ' web page is greatly reduced.  If your browser crashes on the '.
      'full display, try this.'},
        { name  => 'HTML, scores only',
          value => 'html, scores only',
          description => 'Output HTML, only showing the total number of correct'.
      ' problems (or problem parts) and not the maximum possible for '.
      'each student'},
        { name  => 'HTML, totals',
          value => 'html, totals',
          description => 'Output HTML, but only the summary statistics for each'.
      ' sequence selected.'},
        { name  => 'Excel, scores only',
          value => 'excel, scores only',
          description => 'Output an Excel file (compatable with Excel 95), '.
      'with a single column for each sequence showing the students '.
      'score.'},
   #     { name  => 'Excel, everything',
   #       value => 'excel, everything',
   #       description => 'Output an Excel file (compatable with Excel 95), '.
   #   'with a seperate worksheet for each sequence you have selected '.
   #           'the data for each problem part '.
   #           '(number of tries, status, points awarded) '.
   #           'will be listed.'},
        { name  => 'Excel, totals',
          value => 'excel, totals',
          description => 'Output an Excel file (compatable with Excel 95), '.
      'with two columns for each sequence, the students score on the '.
      'sequence and the students maximum possible on the sequence'},
        { name  => 'CSV, everything',
          value => 'csv, everything',
          description => ''},
        { name  => 'CSV, scores only',
          value => 'csv, scores only',
          description => ''},
        { name  => 'CSV, totals',
          value => 'csv, totals',
          description => ''},
        );
   
   sub OutputDescriptions {
       my $Str = '';
       $Str .= "<h2>Output Modes</h2>\n";
       $Str .= "<dl>\n";
       foreach my $outputmode (@OutputOptions) {
    $Str .="    <dt>".$outputmode->{'name'}."</dt>\n";
    $Str .="        <dd>".$outputmode->{'description'}."</dd>\n";
       }
       $Str .= "</dl>\n";
       return $Str;
   }
   
 sub CreateAndParseOutputSelector {  sub CreateAndParseOutputSelector {
     my $Str = '';      my $Str = '';
     my $elementname = 'outputmode';      my $elementname = 'outputmode';
     #      #
     # Format for output options is 'mode, restrictions';      # Format for output options is 'mode, restrictions';
     my @Options = ('html, with links','html, without links',  
                    'html, totals only','excel, totals only',  
                    'csv, totals only','csv, everything');  
     my $selected = 'html, with links';      my $selected = 'html, with links';
     if (exists($ENV{'form.'.$elementname})) {      if (exists($ENV{'form.'.$elementname})) {
         if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {          if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
Line 303  sub CreateAndParseOutputSelector { Line 360  sub CreateAndParseOutputSelector {
     } else {      } else {
         $show_links = 'no';          $show_links = 'no';
     }      }
     if ($restriction eq 'totals only') {      if ($restriction eq 'totals') {
         $show = 'totals';          $show = 'totals';
       } elsif ($restriction eq 'scores only') {
           $show = 'scores';
     } else {      } else {
         $show = 'everything';          $show = 'everything';
     }      }
     #      #
     # Build the form element      # Build the form element
     $Str = qq/<select size="5" name="$elementname">/;      $Str = qq/<select size="5" name="$elementname">/;
     foreach my $option (@Options) {      foreach my $option (@OutputOptions) {
         $Str .= qq/\n    <option value="$option"/;          $Str .= "\n".'    <option value="'.$option->{'value'}.'"';
         $Str .= " selected " if ($option eq $selected);          $Str .= " selected " if ($option->{'value'} eq $selected);
         $Str .= ">$option<\/option>";          $Str .= ">".$option->{'name'}."<\/option>";
     }      }
     $Str .= "\n</select>";      $Str .= "\n</select>";
     return $Str;      return $Str;
Line 412  sub html_outputstudent { Line 471  sub html_outputstudent {
         if ($show eq 'totals') {          if ($show eq 'totals') {
             $performance = ' 'x(length($seq_max)-length($score)).$ratio;              $performance = ' 'x(length($seq_max)-length($score)).$ratio;
             $performance .= ' 'x($seq->{'width'}-length($performance));              $performance .= ' 'x($seq->{'width'}-length($performance));
           } elsif ($show eq 'scores') {
               $performance = $score;
               $performance .= ' 'x($seq->{'width'}-length($performance));
         } else {          } else {
             # Pad with extra spaces              # Pad with extra spaces
             $performance .= ' 'x($seq->{'width'}-$seq_max-              $performance .= ' 'x($seq->{'width'}-$seq_max-
Line 475  sub html_finish { Line 537  sub html_finish {
 {  {
   
 my $excel_sheet;  my $excel_sheet;
   my $excel_workbook;
   
   my $filename;
   my $rows_output;
   my $cols_output;
   
   my $num_students;
   my $start_time;
   
 sub excel_initialize {  sub excel_initialize {
     my ($r) = @_;      my ($r) = @_;
     #      #
     $r->print("<h1>Not implemented yet</h1>");      $filename = '/prtspool/'.
     return;  
     my $filename = '/prtspool/'.  
         $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.          $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
             time.'_'.rand(1000000000).'.xls';              time.'_'.rand(1000000000).'.xls';
     $excel_sheet = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);      #
     if (! defined($excel_sheet)) {      $excel_workbook = undef;
       $excel_sheet = undef;
       #
       $rows_output = 0;
       $cols_output = 0;
       #
       $num_students = 0;
       $start_time   = time;
       #
       # Create sheet
       $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
       #
       # Check for errors
       if (! defined($excel_workbook)) {
         $r->log_error("Error creating excel spreadsheet $filename: $!");          $r->log_error("Error creating excel spreadsheet $filename: $!");
         $r->print("Problems creating new Excel file.  ".          $r->print("Problems creating new Excel file.  ".
                   "This error has been logged.  ".                    "This error has been logged.  ".
                   "Please alert your LON-CAPA administrator");                    "Please alert your LON-CAPA administrator");
         return 0;          return ;
     }      }
     #      #
     # The excel spreadsheet stores temporary data in files, then put them      # The excel spreadsheet stores temporary data in files, then put them
     # together.  If needed we should be able to disable this (memory only).      # together.  If needed we should be able to disable this (memory only).
     # The temporary directory must be specified before calling 'addworksheet'.      # The temporary directory must be specified before calling 'addworksheet'.
     # File::Temp is used to determine the temporary directory.      # File::Temp is used to determine the temporary directory.
     $excel_sheet->set_tempdir($Apache::lonnet::tmpdir);      $excel_workbook->set_tempdir($Apache::lonnet::tmpdir);
       #
       # Add a worksheet
       my $sheetname = $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
       if (length($sheetname) > 31) {
           $sheetname = substr($sheetname,0,31);
       }
       $excel_sheet = $excel_workbook->addworksheet($sheetname);
       #
       # Add the student headers
       foreach my $field (&get_student_fields_to_show()) {
           $excel_sheet->write(1,$cols_output++,$field);
       }
       #
       # Add the Sequence Headers
       foreach my $seq (&get_sequences_to_show) {
           $excel_sheet->write(0,$cols_output,$seq->{'title'});
           if ($show eq 'totals') {
               $excel_sheet->write(1,$cols_output,'score');
               $excel_sheet->write(1,$cols_output+1,'maximum');
               $cols_output += 2;
           } else {
               $cols_output++;
           }
       }
       #
       # Bookkeeping
       if ($show eq 'totals') {
           $rows_output = 2;
       } else {
           $rows_output = 1;
       }
       #
       # Let the user know what we are doing
       my $studentcount = scalar(@Apache::lonstatistics::Students); 
       $r->print("<h1>Compiling Excel spreadsheet for ".
                 $studentcount.' student');
       $r->print('s') if ($studentcount > 1);
       $r->print("</h1>\n");
       $r->rflush();
     #      #
     # Determine the name to give the worksheet  
 #    $excel_sheet->addworksheet();  
   
     return;      return;
 }  }
   
 sub excel_outputstudent {  sub excel_outputstudent {
     my ($r,$student) = @_;      my ($r,$student) = @_;
       return if (! defined($excel_sheet));
       $cols_output=0;
       #
       # Write out student data
       my @to_show = &get_student_fields_to_show();
       foreach my $field (@to_show) {
           $excel_sheet->write($rows_output,$cols_output++,$student->{$field});
       }
       #
       # Get student assessment data
       my %StudentsData;
       my @tmp = &Apache::loncoursedata::get_current_state($student->{'username'},
                                                           $student->{'domain'},
                                                           undef,
                                                      $ENV{'request.course.id'});
       if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
           %StudentsData = @tmp;
       }
       #
       # Write out sequence scores and totals data
       foreach my $seq (&get_sequences_to_show) {
           my ($performance,$score,$seq_max) =
               &StudentPerformanceOnSequence($student,\%StudentsData,
                                             $seq,'no');
           if ($show eq 'totals' || $show eq 'scores') {
               $excel_sheet->write($rows_output,$cols_output++,$score);
           }
           if ($show eq 'totals') {
               $excel_sheet->write($rows_output,$cols_output++,$seq_max);
           }
       }
       #
       # Bookkeeping
       $rows_output++; 
       $cols_output=0;
       #
       # Time estimate
       $num_students++;
       if ($num_students % 10 == 0) {
           my $time_est = (time - $start_time)/$num_students * 
               (scalar(@Apache::lonstatistics::Students)-$num_students);
           $time_est = int($time_est);
           if (int ($time_est/60) > 0) {
               my $min = int($time_est/60);
               my $sec = $time_est % 60;
               $time_est = $min.' minutes';
               if ($sec > 1) {
                   $time_est.= ', '.$sec.' seconds';
               } elsif ($sec > 0) {
                   $time_est.= ', '.$sec.' second';
               }
           } else {
               $time_est .= ' seconds';
           }
           $r->print($num_students.' out of '.
                     (scalar(@Apache::lonstatistics::Students)).
                     " students processed.  ".
                     $time_est." remain.  <br />\n");
           $r->rflush();
       }
       return;
 }  }
   
 sub excel_finish {  sub excel_finish {
     my ($r) = @_;      my ($r) = @_;
       return if (! defined($excel_sheet));
       #
       # Write the excel file
       $excel_workbook->close();
       my $c = $r->connection();
       #
       return if($c->aborted());
       #
       # Tell the user where to get their excel file
       $r->print('<br /><br />'.
                 '<a href="'.$filename.'">Your Excel spreadsheet.</a>'."\n");
       my $total_time = time - $start_time;
       if (int ($total_time / 60) > 0) {
           $total_time = int($total_time/60).' minutes, '.($total_time % 60);
       }
       $r->print('<br />'.$total_time.' seconds total');
       $r->rflush();
       return;
 }  }
   
 }  }
Line 575  Inputs: Line 771  Inputs:
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub StudentPerformanceOnSequence {  sub StudentPerformanceOnSequence {
     my ($student,$studentdata,$seq,$links,$totalonly) = @_;      my ($student,$studentdata,$seq,$links) = @_;
     $totalonly = 0 if (! defined($totalonly));  
     $links = 'no' if (! defined($links));      $links = 'no' if (! defined($links));
     my $Str = '';      my $Str = '';
     my ($sum,$max) = (0,0);      my ($sum,$max) = (0,0);

Removed from v.1.31  
changed lines
  Added in v.1.33


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