--- loncom/interface/statistics/lonproblemanalysis.pm	2004/02/16 19:59:49	1.67
+++ loncom/interface/statistics/lonproblemanalysis.pm	2004/02/18 19:16:55	1.70
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonproblemanalysis.pm,v 1.67 2004/02/16 19:59:49 matthew Exp $
+# $Id: lonproblemanalysis.pm,v 1.70 2004/02/18 19:16:55 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -159,8 +159,13 @@ sub BuildProblemAnalysisPage {
                                        $ProblemData,
                                        \@Students);
             } elsif ($current_problem->{'resptype'} eq 'numerical') {
-                &NumericalResponseAnalysis($r,$current_problem,
-                                           $ProblemData,\@Students);
+#                if (exists($ENV{'form.ExcelOutput'})) {
+                    &prepare_excel_output($r,$current_problem,
+                                          $ProblemData,\@Students);
+#                } else {
+#                    &NumericalResponseAnalysis($r,$current_problem,
+#                                               $ProblemData,\@Students);
+#                }
             } else {
                 $r->print('<h2>This analysis is not supported</h2>');
             }
@@ -176,6 +181,137 @@ sub BuildProblemAnalysisPage {
     }
 }
 
+
+#########################################################
+#########################################################
+##
+##      Excel output of student answers and correct answers
+##
+#########################################################
+#########################################################
+sub prepare_excel_output {
+    my ($r,$problem,$ProblemData,$Students) = @_;
+    my ($resource,$respid,$partid) = ($problem->{'resource'},
+                                      $problem->{'respid'},
+                                      $problem->{'part'});
+    $r->print('<h2>'.
+              &mt('Preparing Excel spreadsheet of student responses').
+              '</h2>');
+    #
+    &GetStudentAnswers($r,$problem,$Students);
+    #
+    my @Columns = ( 'username','domain','attempt','time',
+                    'submission','correct', 'grading','awarded','weight',
+                    'score');
+    my $awarded_col = 7;
+    my $weight_col  = 8;
+    #
+    # Create excel worksheet
+    my $filename = '/prtspool/'.
+        $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+        time.'_'.rand(1000000000).'.xls';
+    my $workbook  = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
+    if (! defined($workbook)) {
+        $r->log_error("Error creating excel spreadsheet $filename: $!");
+        $r->print('<p>'.&mt("Unable to create new Excel file.  ".
+                            "This error has been logged.  ".
+                            "Please alert your LON-CAPA administrator").
+                  '</p>');
+        return undef;
+    }
+    #
+    $workbook->set_tempdir('/home/httpd/perl/tmp');
+    #
+    my $format = &Apache::loncommon::define_excel_formats($workbook);
+    my $worksheet  = $workbook->addworksheet('Student Submission Data');
+    #
+    # Make sure we get new weight data instead of data on a 10 minute delay
+    &Apache::lonnet::clear_EXT_cache_status();
+    #
+    # Put on the standard headers and whatnot
+    my $rows_output=0;
+    $worksheet->write($rows_output++,0,$resource->{'title'},$format->{'h1'});
+    $worksheet->write($rows_output++,0,$resource->{'src'},$format->{'h3'});
+    $rows_output++;
+    $worksheet->write_row($rows_output++,0,\@Columns,$format->{'bold'});
+    #
+    # Populate the worksheet with the student data
+    foreach my $student (@$Students) {
+        my $results = &Apache::loncoursedata::get_response_data_by_student
+            ($student,$resource->{'symb'},$respid);
+        my %row;
+        $row{'username'} = $student->{'username'};
+        $row{'domain'}   = $student->{'domain'};
+        $row{'correct'} = $student->{'answer'};
+        $row{'weight'} = &Apache::lonnet::EXT
+            ('resource.'.$partid.'.weight',$resource->{'symb'},
+             undef,undef,undef);
+        if (! defined($results) || ref($results) ne 'ARRAY') {
+            $row{'score'} = '='.
+                &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+                    ($rows_output,$awarded_col)
+                .'*'.
+                &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+                    ($rows_output,$weight_col);
+            my $cols_output = 0;
+            foreach my $col (@Columns) {
+                if (! exists($row{$col})) {
+                    $cols_output++;
+                    next;
+                }
+                $worksheet->write($rows_output,$cols_output++,$row{$col});
+            }
+            $rows_output++;
+        } else {
+            foreach my $response (@$results) {
+                delete($row{'time'});
+                delete($row{'attempt'});
+                delete($row{'submission'});
+                delete($row{'awarded'});
+                delete($row{'grading'});
+                delete($row{'score'});
+                my %row_format;
+                #
+                # Time is handled differently
+                $row{'time'} = &calc_serial(
+                     $response->[&Apache::loncoursedata::RDs_timestamp()]);
+                $row_format{'time'}=$format->{'date'};
+                #
+                $row{'attempt'}  = $response->[
+                     &Apache::loncoursedata::RDs_tries()];
+                $row{'submission'} = $response->[
+                     &Apache::loncoursedata::RDs_submission()];
+                $row{'grading'} = $response->[
+                     &Apache::loncoursedata::RDs_awarddetail()];
+                $row{'awarded'} = $response->[
+                     &Apache::loncoursedata::RDs_awarded()];
+                $row{'score'} = '='.
+                    &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+                        ($rows_output,$awarded_col)
+                    .'*'.
+                    &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+                        ($rows_output,$weight_col);
+                my $cols_output = 0;
+                foreach my $col (@Columns) {
+                    $worksheet->write($rows_output,$cols_output++,$row{$col},
+                                      $row_format{$col});
+                }
+                $rows_output++;
+            }
+        } # End of else clause on if (! defined($results) ....
+    }
+    #
+    # Close the excel file
+    $workbook->close();
+    #
+    # Write a link to allow them to download it
+    $r->print('<p><a href="'.$filename.'">'.
+              &mt('Your Excel spreadsheet.').
+              '</a></p>'."\n");
+
+}
+
+
 #########################################################
 #########################################################
 ##
@@ -185,6 +321,7 @@ sub BuildProblemAnalysisPage {
 #########################################################
 sub NumericalResponseAnalysis {
     my ($r,$problem,$ProblemData,$Students) = @_;
+    $r->print('<h2>This analysis is not yet supported</h2>');
     my ($resource,$respid) = ($problem->{'resource'},
                               $problem->{'respid'});
     my $analysis_html;
@@ -199,9 +336,38 @@ sub NumericalResponseAnalysis {
         $r->print($analysis_html);
         return;
     }
-    my $Answers = &GetStudentAnswers($r,$problem,$Students);
-    
-    $r->print('<h2>This analysis is not yet supported</h2>');
+    my ($max,$min) = &GetStudentAnswers($r,$problem,$Students);
+    $r->print('Maximum = '.$max.' Minimum = '.$min);
+    my $max_students = 0;
+    my %Data;
+    foreach my $student (@$Students) {
+        my $answer = $student->{'answer'};
+        $Data{$answer}++;
+        if ($max_students < $Data{$answer}) {
+            $max_students = $Data{$answer};
+        }
+    }
+    foreach (5,10,20,25,50,75,100,150,200,250,500,1000,1500,2000,2500,5000) {
+        if ($max_students < $_) {
+            $max_students = $_;
+            last;
+        }
+    }
+    my @Labels = sort {$a <=> $b } keys(%Data);
+    $r->print('number of labels = '.scalar(@Labels));
+    my @PlotData = @Data{@Labels};
+    $r->print('number of PlotData = '.scalar(@PlotData));
+    my $graph = 
+        &Apache::loncommon::DrawXYGraph('Correct Answer Distribution',
+                                        'Correct Answer',
+                                        'Number of students',
+                                        $max_students,
+                                        undef,
+                                        \@Labels,
+                                        [\@PlotData],
+                                        (xskip=>10));
+    $r->print($graph);
+    return;
 }
 
 sub GetStudentAnswers {
@@ -219,23 +385,45 @@ sub GetStudentAnswers {
     foreach my $student (@$Students) {
         my $sname = $student->{'username'};
         my $sdom = $student->{'domain'};
-        my $answer = analyze_problem_as_student($resource,
-                                                $sname,$sdom,
-                                                $partid,$respid);
-        $r->print('<tr>'.
-                  '<td>'.$sname.'</td>'.
-                  '<td>'.$sdom.'</td>'.
-                  '<td>'.$answer.'</td>'.
-                  '</tr>'."\n");
+        my $answer = &analyze_problem_as_student($resource,
+                                                 $sname,$sdom,
+                                                 $partid,$respid);
         &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
                                                  &mt('last student'));
-        $Answers{$sname.':'.$sdom}=$answer;
+        $student->{'answer'} = $answer;
     }
     $r->print("</table>\n");
     $r->rflush();
-    &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
     # close progress window
-    return \%Answers;
+    &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
+    return;
+}
+
+sub build_student_data_worksheet {
+    my ($workbook,$format) = @_;
+    my $rows_output = 3;
+    my $cols_output = 0;
+    my $worksheet  = $workbook->addworksheet('Student Data');
+    $worksheet->write($rows_output++,0,'Student Data',$format->{'h3'});
+    my @Headers = ('full name','username','domain','section',
+                   "student\nnumber",'identifier');
+    $worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'});
+    my @Students = @Apache::lonstatistics::Students;
+    my $studentrows = &Apache::loncoursedata::get_student_data(\@Students);
+    my %ids;
+    foreach my $row (@$studentrows) {
+        my ($mysqlid,$student) = @$row;
+        $ids{$student}=$mysqlid;
+    }
+    foreach my $student (@Students) {
+        my $name_domain = $student->{'username'}.':'.$student->{'domain'};
+        $worksheet->write_row($rows_output++,0,
+                          [$student->{'fullname'},
+                           $student->{'username'},$student->{'domain'},
+                           $student->{'section'},$student->{'id'},
+                           $ids{$name_domain}]);
+    }
+    return $worksheet;
 }
 
 #########################################################
@@ -935,22 +1123,11 @@ sub OR_excel_sheet {
     }
     #
     $workbook->set_tempdir('/home/httpd/perl/tmp');
-    #
-    # Define some potentially useful formats
-    my $format;
-    $format->{'header'} = $workbook->add_format(bold      => 1, 
-                                                bottom    => 1,
-                                                align     => 'center');
-    $format->{'bold'} = $workbook->add_format(bold=>1);
-    $format->{'h1'}   = $workbook->add_format(bold=>1, size=>18);
-    $format->{'h2'}   = $workbook->add_format(bold=>1, size=>16);
-    $format->{'h3'}   = $workbook->add_format(bold=>1, size=>14);
-    $format->{'date'} = $workbook->add_format(num_format=>
-                                              'mmm d yyyy hh:mm AM/PM');
+    my $format = &Apache::loncommon::define_excel_formats($workbook);
     #
     # Create and populate main worksheets
     my $problem_data_sheet  = $workbook->addworksheet('Problem Data');
-    my $student_data_sheet  = $workbook->addworksheet('Student Data');
+    my $student_data_sheet = &build_student_data_worksheet($workbook,$format);
     my $response_data_sheet = $workbook->addworksheet('Response Data');
     foreach my $sheet ($problem_data_sheet,$student_data_sheet,
                        $response_data_sheet) {
@@ -964,10 +1141,6 @@ sub OR_excel_sheet {
     if ($result ne 'okay') {
         # Do something useful
     }
-    $result = &OR_build_student_data_worksheet($student_data_sheet,$format);
-    if ($result ne 'okay') {
-        # Do something useful
-    }
     $result = &OR_build_response_data_worksheet($response_data_sheet,$format,
                                              $PerformanceData,$Foils,
                                              $ORdata);
@@ -1056,32 +1229,6 @@ sub OR_build_problem_data_worksheet {
     return 'okay';
 }
 
-sub OR_build_student_data_worksheet {
-    my ($worksheet,$format) = @_;
-    my $rows_output = 3;
-    my $cols_output = 0;
-    $worksheet->write($rows_output++,0,'Student Data',$format->{'h3'});
-    my @Headers = ('full name','username','domain','section',
-                   "student\nnumber",'identifier');
-    $worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'});
-    my @Students = @Apache::lonstatistics::Students;
-    my $studentrows = &Apache::loncoursedata::get_student_data(\@Students);
-    my %ids;
-    foreach my $row (@$studentrows) {
-        my ($mysqlid,$student) = @$row;
-        $ids{$student}=$mysqlid;
-    }
-    foreach my $student (@Students) {
-        my $name_domain = $student->{'username'}.':'.$student->{'domain'};
-        $worksheet->write_row($rows_output++,0,
-                          [$student->{'fullname'},
-                           $student->{'username'},$student->{'domain'},
-                           $student->{'section'},$student->{'id'},
-                           $ids{$name_domain}]);
-    }
-    return;
-}
-
 sub OR_build_response_data_worksheet {
     my ($worksheet,$format,$PerformanceData,$Foils,$ORdata)=@_;
     my $rows_output = 3;