--- loncom/interface/statistics/lonstudentassessment.pm	2003/03/12 20:53:53	1.42
+++ loncom/interface/statistics/lonstudentassessment.pm	2003/06/05 19:21:22	1.52
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonstudentassessment.pm,v 1.42 2003/03/12 20:53:53 matthew Exp $
+# $Id: lonstudentassessment.pm,v 1.52 2003/06/05 19:21:22 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -85,6 +85,9 @@ my $Statistics;
 
 =item $show 'all', 'totals', or 'scores' determines how much data is output
 
+=item $single_student_mode evaluates to true if we are showing only one
+student.
+
 =cut
 
 #######################################################
@@ -92,6 +95,7 @@ my $Statistics;
 my $show_links;
 my $output_mode;
 my $show;
+my $single_student_mode;
 
 #######################################################
 #######################################################
@@ -127,17 +131,20 @@ Inputs:
 sub BuildStudentAssessmentPage {
     my ($r,$c)=@_;
     undef($Statistics);
+    $single_student_mode = 1 if ($ENV{'form.SelectedStudent'});
     #
     # Print out the HTML headers for the interface
     #    This also parses the output mode selector
     #    This step must always be done.
     $r->print(&CreateInterface());
     $r->print('<input type="hidden" name="notfirstrun" value="true" />');
+    $r->print('<input type="hidden" name="sort" value="'.
+              $ENV{'form.sort'}.'" />');
     $r->rflush();
-    if (! exists($ENV{'form.notfirstrun'})) {
+    if (! exists($ENV{'form.notfirstrun'}) && ! $single_student_mode) {
         $r->print(<<ENDMSG);
 <p>
-<font size="+1">
+<font size="+2">
 Please make your selections in the boxes above and hit 
 the button marked &quot;Update&nbsp;Display&quot;.
 </font>
@@ -156,10 +163,10 @@ ENDMSG
         $initialize     = \&excel_initialize;
         $output_student = \&excel_outputstudent;
         $finish         = \&excel_finish;
-    } elsif ($output_mode eq 'multi-sheet excel') {
-        $initialize     = \&multi_sheet_excel_initialize;
-        $output_student = \&multi_sheet_excel_outputstudent;
-        $finish         = \&multi_sheet_excel_finish;
+#    } elsif ($output_mode eq 'multi-sheet excel') {
+#        $initialize     = \&multi_sheet_excel_initialize;
+#        $output_student = \&multi_sheet_excel_outputstudent;
+#        $finish         = \&multi_sheet_excel_finish;
     } elsif ($output_mode eq 'csv') {
         $initialize     = \&csv_initialize;
         $output_student = \&csv_outputstudent;
@@ -168,9 +175,19 @@ ENDMSG
     #
     if($c->aborted()) {  return ; }
     #
+    # Determine which students we want to look at
+    my @Students;
+    if ($single_student_mode) {
+        @Students = (&Apache::lonstatistics::current_student());
+        $r->print(&next_and_previous_buttons());
+        $r->rflush();
+    } else {
+        @Students = @Apache::lonstatistics::Students;
+    }
+    #
     # Call the initialize routine selected above
     $initialize->($r);
-    foreach my $student (@Apache::lonstatistics::Students) {
+    foreach my $student (@Students) {
         if($c->aborted()) { 
             $finish->($r);
             return ; 
@@ -186,6 +203,54 @@ ENDMSG
 
 #######################################################
 #######################################################
+sub next_and_previous_buttons {
+    my $Str = '';
+    $Str .= '<input type="hidden" name="SelectedStudent" value="'.
+        $ENV{'form.SelectedStudent'}.'" />';
+    #
+    # Build the previous student link
+    my $previous = &Apache::lonstatistics::previous_student();
+    my $previousbutton = '';
+    if (defined($previous)) {
+        my $sname = $previous->{'username'}.':'.$previous->{'domain'};
+        $previousbutton .= '<input type="button" value="'.
+            'Previous Student ('.
+            $previous->{'username'}.'@'.$previous->{'domain'}.')'.
+            '" onclick="document.Statistics.SelectedStudent.value='.
+            "'".$sname."'".';'.
+            'document.Statistics.submit();" />';
+    } else {
+        $previousbutton .= '<input type="button" value="'.
+            'Previous student (none)'.'" />';
+    }
+    #
+    # Build the next student link
+    my $next = &Apache::lonstatistics::next_student();
+    my $nextbutton = '';
+    if (defined($next)) {
+        my $sname = $next->{'username'}.':'.$next->{'domain'};
+        $nextbutton .= '<input type="button" value="'.
+            'Next Student ('.
+            $next->{'username'}.'@'.$next->{'domain'}.')'.
+            '" onclick="document.Statistics.SelectedStudent.value='.
+            "'".$sname."'".';'.
+            'document.Statistics.submit();" />';
+    } else {
+        $nextbutton .= '<input type="button" value="'.
+            'Next student (none)'.'" />';
+    }
+    #
+    # Build the 'all students' button
+    my $all = '';
+    $all .= '<input type="button" value="All Students" '.
+            '" onclick="document.Statistics.SelectedStudent.value='.
+            "''".';'.'document.Statistics.submit();" />';
+    $Str .= $previousbutton.('&nbsp;'x5).$all.('&nbsp;'x5).$nextbutton;
+    return $Str;
+}
+
+#######################################################
+#######################################################
 
 sub get_student_fields_to_show {
     my @to_show = @Apache::lonstatistics::SelectedStudentData;
@@ -224,6 +289,7 @@ sub CreateInterface {
     $Str .= '<tr>';
     $Str .= '<td align="center"><b>Sections</b></td>';
     $Str .= '<td align="center"><b>Student Data</b></td>';
+    $Str .= '<td align="center"><b>Enrollment Status</b></td>';
     $Str .= '<td align="center"><b>Sequences and Folders</b></td>';
     $Str .= '<td align="center"><b>Output Format</b></td>';
     $Str .= '</tr>'."\n";
@@ -242,6 +308,8 @@ sub CreateInterface {
     $Str .= &Apache::lonstatistics::StudentDataSelect('StudentData','multiple',
                                                       5,undef);
     $Str .= '</td><td>'."\n";
+    $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
+    $Str .= '</td><td>'."\n";
     $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
                                               $only_seq_with_assessments);
     $Str .= '</td><td>'."\n";
@@ -271,6 +339,15 @@ my @OutputOptions =
        show => 'all',
        show_links => 'yes',
        },
+     { name  => 'HTML, with all links',
+       value => 'html, with all links',
+       description => 'Output HTML with each symbol linked to the problem '.
+	   'which generated it.  '.
+           'This includes links for unattempted problems.',
+       mode => 'html',
+       show => 'all',
+       show_links => 'all',
+       },
      { name  => 'HTML, without links',
        value => 'html, without links',
        description => 'Output HTML.  By not including links, the size of the'.
@@ -323,27 +400,27 @@ my @OutputOptions =
        show => 'totals',
        show_links => 'no',
            },
-     { name  => 'multi-sheet Excel',
-       value => 'multi-sheet excel',
-       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.',
-       mode => 'multi-sheet excel',
-       show => 'totals',
-       show_links => 'no',
-           },
-     { name  => 'multi-sheet Excel, by section',
-       value => 'multi-sheet excel, by section',
-       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.  '.
-           'There will be one Excel workbook for each section selected.',
-       mode => 'multi-sheet excel',
-       show => 'by section',
-       show_links => 'no',
-           },
+#     { name  => 'multi-sheet Excel',
+#       value => 'multi-sheet excel',
+#       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.',
+#       mode => 'multi-sheet excel',
+#       show => 'totals',
+#       show_links => 'no',
+#           },
+#     { name  => 'multi-sheet Excel, by section',
+#       value => 'multi-sheet excel, by section',
+#       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.  '.
+#           'There will be one Excel workbook for each section selected.',
+#       mode => 'multi-sheet excel',
+#       show => 'by section',
+#       show_links => 'no',
+#           },
      { name  => 'CSV, everything',
        value => 'csv, everything',
        description => '',
@@ -381,10 +458,10 @@ sub OutputDescriptions {
 
 sub CreateAndParseOutputSelector {
     my $Str = '';
-    my $elementname = 'outputmode';
+    my $elementname = 'chartoutputmode';
     #
     # Format for output options is 'mode, restrictions';
-    my $selected = 'html, with links';
+    my $selected = 'html, without links';
     if (exists($ENV{'form.'.$elementname})) {
         if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
             $selected = $ENV{'form.'.$elementname}->[0];
@@ -526,7 +603,7 @@ sub html_outputstudent {
     my $studentstats;
     my $PerformanceStr = '';
     foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
-        my ($performance,$score,$seq_max) =
+        my ($performance,$performance_length,$score,$seq_max) =
             &StudentPerformanceOnSequence($student,\%StudentsData,
                                           $seq,$show_links);
         my $ratio = $score.'/'.$seq_max;
@@ -539,7 +616,7 @@ sub html_outputstudent {
             $performance .= ' 'x($seq->{'width'}-length($performance));
         } else {
             # Pad with extra spaces
-            $performance .= ' 'x($seq->{'width'}-$seq_max-
+            $performance .= ' 'x($seq->{'width'}-$performance_length-
                                  length($ratio)
                                  ).$ratio;
         }
@@ -583,7 +660,11 @@ sub html_finish {
     } else {
         $r->print("</pre>\n"); 
     }
-    $r->print(&StudentAverageTotal());
+    if ($single_student_mode) {
+        $r->print(&SingleStudentTotal());
+    } else {
+        $r->print(&StudentAverageTotal());
+    }
     $r->rflush();
     return;
 }
@@ -626,6 +707,31 @@ sub StudentAverageTotal {
     return $Str;
 }
 
+sub SingleStudentTotal {
+    my $student = &Apache::lonstatistics::current_student();
+    my $Str = "<h3>Summary table for ".$student->{'fullname'}." ".
+        $student->{'username'}.'@'.$student->{'domain'}."</h3>\n";
+    $Str .= '<table border=2 cellspacing="1">'."\n";
+    $Str .= 
+        "<tr><th>Sequence or Folder</th><th>Score</th><th>Maximum</th></tr>\n";
+    my $total = 0;
+    my $total_max = 0;
+    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+        my $value = $Statistics->{$seq->{'symb'}}->{'score'};
+        my $max = $Statistics->{$seq->{'symb'}}->{'max'};
+        $Str .= '<tr><td>'.$seq->{'title'}.'</td>'.
+            '<td align="right">'.$value.'</td>'.
+                '<td align="right">'.$max.'</td></tr>'."\n";
+        $total += $value;
+        $total_max +=$max;
+    }
+    $Str .= '<tr><td><b>Total</b></td>'.
+        '<td align="right">'.$total.'</td>'.
+        '<td align="right">'.$total_max."</td></tr>\n";
+    $Str .= "</table>\n";
+    return $Str;
+}
+
 }
 
 #######################################################
@@ -822,6 +928,26 @@ sub excel_initialize {
         $rows_output += 1;
     }
     #
+    # Output a row for MAX
+    if ($show ne 'totals') {
+        $cols_output = 0;
+        foreach my $field (&get_student_fields_to_show()) {
+            if ($field eq 'username' || $field eq 'fullname' || 
+                $field eq 'id') {
+                $excel_sheet->write($rows_output,$cols_output++,'Maximum');
+            } else {
+                $excel_sheet->write($rows_output,$cols_output++,'');
+            }
+        }
+        #
+        # Add the Sequence Headers
+        foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+            $excel_sheet->write($rows_output,$cols_output++,
+                                $seq->{'num_assess_parts'});
+        }
+        $rows_output++;
+    }
+    #
     # Let the user know what we are doing
     my $studentcount = scalar(@Apache::lonstatistics::Students); 
     $r->print("<h1>Compiling Excel spreadsheet for ".
@@ -861,7 +987,7 @@ sub excel_outputstudent {
     #
     # Write out sequence scores and totals data
     foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
-        my ($performance,$score,$seq_max) =
+        my ($performance,$performance_length,$score,$seq_max) =
             &StudentPerformanceOnSequence($student,\%StudentsData,
                                           $seq,'no');
         if ($show eq 'totals' || $show eq 'scores') {
@@ -1021,7 +1147,7 @@ sub csv_outputstudent {
     #
     # Output performance data
     foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
-        my ($performance,$score,$seq_max) =
+        my ($performance,$performance_length,$score,$seq_max) =
             &StudentPerformanceOnSequence($student,\%StudentsData,
                                           $seq,'no');
         if ($show eq 'scores') {
@@ -1093,12 +1219,14 @@ sub StudentPerformanceOnSequence {
     $links = 'no' if (! defined($links));
     my $Str = '';
     my ($sum,$max) = (0,0);
+    my $performance_length = 0;
     foreach my $resource (@{$seq->{'contents'}}) {
         next if ($resource->{'type'} ne 'assessment');
         my $resource_data = $studentdata->{$resource->{'symb'}};
         my $value = '';
         foreach my $partnum (@{$resource->{'parts'}}) {
             $max++;
+            $performance_length++;
             my $symbol = ' '; # default to space
             #
             if (exists($resource_data->{'resource.'.$partnum.'.solved'})) {
@@ -1126,6 +1254,9 @@ sub StudentPerformanceOnSequence {
                         $symbol = ' ';
                     }
                     $sum++;
+                } elsif (exists($resource_data->{'resource.'.
+                                                     $partnum.'.tries'})){
+                    $symbol = '.';
                 } else {
                     $symbol = ' ';
                 }
@@ -1137,8 +1268,15 @@ sub StudentPerformanceOnSequence {
                     $symbol = ' ';
                 }
             }
+#            if ($symbol ne ' ') {
+#                $attempted_sum++;
+#            }
             #
-            if ($links eq 'yes' && $symbol ne ' ') {
+            if ( ($links eq 'yes' && $symbol ne ' ') ||
+                 ($links eq 'all')) {
+                if (length($symbol) > 1) {
+                    &Apache::lonnet::logthis('length of symbol "'.$symbol.'" > 1');
+                }
                 $symbol = '<a href="/adm/grades'.
                     '?symb='.&Apache::lonnet::escape($resource->{'symb'}).
                         '&student='.$student->{'username'}.
@@ -1149,7 +1287,10 @@ sub StudentPerformanceOnSequence {
         }
         $Str .= $value;
     }
-    return ($Str,$sum,$max);
+    if ($seq->{'randompick'}) {
+        $max = $seq->{'randompick'};
+    }
+    return ($Str,$performance_length,$sum,$max);
 }
 
 #######################################################