[LON-CAPA-cvs] cvs: loncom /interface/statistics lonstudentassessment.pm

matthew lon-capa-cvs@mail.lon-capa.org
Fri, 25 Feb 2005 23:32:24 -0000


This is a MIME encoded message

--matthew1109374344
Content-Type: text/plain

matthew		Fri Feb 25 18:32:24 2005 EDT

  Modified files:              
    /loncom/interface/statistics	lonstudentassessment.pm 
  Log:
  More work on getting chart to use navmaps.  Excel output works now.  CSV is
  broken.
  
  
--matthew1109374344
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20050225183224.txt"

Index: loncom/interface/statistics/lonstudentassessment.pm
diff -u loncom/interface/statistics/lonstudentassessment.pm:1.114 loncom/interface/statistics/lonstudentassessment.pm:1.115
--- loncom/interface/statistics/lonstudentassessment.pm:1.114	Fri Feb 25 14:48:01 2005
+++ loncom/interface/statistics/lonstudentassessment.pm	Fri Feb 25 18:32:23 2005
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonstudentassessment.pm,v 1.114 2005/02/25 19:48:01 matthew Exp $
+# $Id: lonstudentassessment.pm,v 1.115 2005/02/25 23:32:23 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -581,6 +581,26 @@
 
 #######################################################
 #######################################################
+sub count_parts {
+    my ($navmap,$sequence) = @_;
+    my @resources = &get_resources($navmap,$sequence);
+    my $count = 0;
+    foreach my $res (@resources) {
+        $count += scalar(@{$res->parts});
+    }
+    return $count;
+}
+
+sub get_resources {
+    my ($navmap,$sequence) = @_;
+    my @resources = $navmap->retrieveResources($sequence,
+                                               sub { shift->is_problem(); },
+                                               0,0,0);
+    return @resources;
+}
+
+#######################################################
+#######################################################
 
 =pod
 
@@ -620,9 +640,17 @@
     $nodata_count = 0;
     undef(%prog_state);
     undef(%width);
+    #
     undef($navmap);
     undef(@sequences);
-    &Apache::lonnet::logthis('called html_initialize');
+    ($navmap,@sequences) = 
+        &Apache::lonstatistics::selected_sequences_with_assessments();
+    if (! ref($navmap)) {
+        # Unable to get data, so bail out
+        $r->print("<h3>".
+                  &mt('Unable to retrieve course information.').
+                  '</h3>');
+    }
     #
     $r->print("<h3>".$ENV{'course.'.$ENV{'request.course.id'}.'.description'}.
               "&nbsp;&nbsp;".localtime(time)."</h3>");
@@ -642,14 +670,6 @@
     #
     # Compute the column widths and output the sequence titles
     my $total_count;
-    ($navmap,@sequences) = 
-        &Apache::lonstatistics::selected_sequences_with_assessments();
-    if (! ref($navmap)) {
-        # Unable to get data, so bail out
-        $r->print("<h3>".
-                  &mt('Unable to retrieve course information.').
-                  '</h3>');
-    }
     #
     # Compute sequence widths
     my $starttime = Time::HiRes::time;
@@ -679,18 +699,8 @@
 	#
         if ($chosen_output->{'every_problem'}) {
             # one problem per digit
-            $width{$symb}->{'width_parts'}=0;
-            $starttime = Time::HiRes::time;
-            my @resources = 
-                $navmap->retrieveResources($seq,sub { shift->is_problem(); },
-                                           0,0,0);
-            $starttime = Time::HiRes::time;
-            foreach my $res (@resources) {
-                my @parts = @{$res->parts};
-                $width{$symb}->{'width_parts'} += scalar(@parts);
-            } 
-            &Apache::lonnet::logthis('2elapsed:'.(Time::HiRes::time-$starttime));            $width{$symb}->{'width_problem'} += 
-                $width{$symb}->{'width_parts'};
+            $width{$symb}->{'width_parts'}= &count_parts($navmap,$seq);
+            $width{$symb}->{'width_problem'} += $width{$symb}->{'width_parts'};
         } else {
             $width{$symb}->{'width_problem'} = 0;
         }
@@ -769,7 +779,8 @@
             $ratio .= ' ';
         }
         if ($chosen_output->{'sequence_sum'} && $score ne ' ') {
-            $ratio .= sprintf("%3.0f",$score);
+            my $score .= sprintf("%3.0f",$score);
+            $ratio .= (' 'x(3-length($score))).$score;
         } elsif($chosen_output->{'sequence_sum'}) {
             $ratio .= ' 'x3;
         }
@@ -812,6 +823,7 @@
         $score = ' ' x $total_sum_width;
     } else {
         $score = sprintf("%.0f",$score);
+        $score = (' 'x(3-length($score))).$score;
     }
     $Str .= ' '.' 'x($total_sum_width-length($score)).$score.' / '.$max;
     $Str .= " \n";
@@ -870,6 +882,7 @@
 }
 
 sub SingleStudentTotal {
+    return if (! defined($navmap));
     my $student = &Apache::lonstatistics::current_student();
     my $Str = '<h3>'.&mt('Summary table for [_1] ([_2]@[_3])',
                          $student->{'fullname'},
@@ -887,7 +900,7 @@
     $Str .= '<th>'.&mt('Maximum').'</th>'."</tr>\n";
     my $total = 0;
     my $total_max = 0;
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+    foreach my $seq (@sequences) {
         my $value = $Statistics->{$seq->symb}->{'score'};
         my $max = $Statistics->{$seq->symb}->{'max'};
         $Str .= '<tr><td>'.&HTML::Entities::encode($seq->compTitle).'</td>'.
@@ -936,6 +949,10 @@
 
 my $total_formula;
 my $maximum_formula;
+my %formula_data;
+
+my $navmap;
+my @sequences;
 
 sub excel_initialize {
     my ($r) = @_;
@@ -950,12 +967,25 @@
     undef ($total_formula);
     undef ($maximum_formula);
     #
+    undef(%formula_data);
+    #
+    undef($navmap);
+    undef(@sequences);
+    ($navmap,@sequences) = 
+        &Apache::lonstatistics::selected_sequences_with_assessments();
+    if (! ref($navmap)) {
+        # Unable to get data, so bail out
+        $r->print("<h3>".
+                  &mt('Unable to retrieve course information.').
+                  '</h3>');
+    }
+    #
     my $total_columns = scalar(&get_student_fields_to_show());
     my $num_students = scalar(@Apache::lonstatistics::Students);
     #
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+    foreach my $seq (@sequences) {
         if ($chosen_output->{'every_problem'}) {
-            $total_columns += $seq->{'num_assess_parts'};
+            $total_columns+=&count_parts($navmap,$seq);
         }
         # Add 2 because we need a 'sequence_sum' and 'total' column for each
         $total_columns += 2;
@@ -993,7 +1023,7 @@
     my $summary_header_row;
     if ($chosen_output->{'summary_table'}) {
         $summary_header_row = $rows_output++;
-        $rows_output+= scalar(&Apache::lonstatistics::Sequences_with_Assess());
+        $rows_output+= scalar(@sequences);
         $rows_output++;
     }
     my $sequence_name_row = $rows_output++;
@@ -1084,63 +1114,58 @@
     # Add the remaining column headers
     my $total_formula_string = '=0';
     my $maximum_formula_string = '=0';
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+    foreach my $seq (@sequences) {
+        my $symb = $seq->symb;
         $excel_sheet->write($sequence_name_row,,
-                            $cols_output,$seq->{'title'},$format->{'bold'});
+                            $cols_output,$seq->compTitle,$format->{'bold'});
         # Determine starting cell
-        $seq->{'Excel:startcell'}=
+        $formula_data{$symb}->{'Excel:startcell'}=
             &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
             ($first_data_row,$cols_output);
-        $seq->{'Excel:startcol'}=$cols_output;
+        $formula_data{$symb}->{'Excel:startcol'}=$cols_output;
         my $count = 0;
         if ($chosen_output->{'every_problem'}) {
             # Put the names of the problems and parts into the sheet
-            foreach my $res (@{$seq->{'contents'}}) {
-                if ($res->{'type'} ne 'assessment'  || 
-                    ! exists($res->{'parts'})       ||
-                    ref($res->{'parts'}) ne 'ARRAY' ||
-                    scalar(@{$res->{'parts'}}) < 1) {
-                    next;
-                }
-                if (scalar(@{$res->{'parts'}}) > 1) {
-                    foreach my $part (@{$res->{'parts'}}) {
+            foreach my $res (&get_resources($navmap,$seq)) {
+                if (scalar(@{$res->parts}) > 1) {
+                    foreach my $part (@{$res->parts}) {
                         $excel_sheet->write($resource_name_row,
                                             $cols_output++,
-                                            $res->{'title'}.' part '.$part,
+                                            $res->compTitle.' part '.$res->part_display($part),
                                             $format->{'bold'});
                         $count++;
                     }
                 } else {
                     $excel_sheet->write($resource_name_row,
                                         $cols_output++,
-                                        $res->{'title'},$format->{'bold'});
+                                        $res->compTitle,$format->{'bold'});
                     $count++;
                 }
             }
         }
         # Determine ending cell
         if ($count <= 1) {
-            $seq->{'Excel:endcell'} = $seq->{'Excel:startcell'};
-            $seq->{'Excel:endcol'}  = $seq->{'Excel:startcol'};
+            $formula_data{$symb}->{'Excel:endcell'} = $formula_data{$symb}->{'Excel:startcell'};
+            $formula_data{$symb}->{'Excel:endcol'}  = $formula_data{$symb}->{'Excel:startcol'};
         } else {
-            $seq->{'Excel:endcell'} = 
+            $formula_data{$symb}->{'Excel:endcell'} = 
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
                 ($first_data_row,$cols_output-1);
-            $seq->{'Excel:endcol'} = $cols_output-1;
+            $formula_data{$symb}->{'Excel:endcol'} = $cols_output-1;
         }
         # Create the formula for summing up this sequence
-        if (! exists($seq->{'Excel:endcell'}) ||
-            ! defined($seq->{'Excel:endcell'})) {
-            $seq->{'Excel:endcell'} = $seq->{'Excel:startcell'};
-        }
-        $seq->{'Excel:sum'}= $excel_sheet->store_formula
-            ('=SUM('.$seq->{'Excel:startcell'}.
-             ':'.$seq->{'Excel:endcell'}.')');
+        if (! exists($formula_data{$symb}->{'Excel:endcell'}) ||
+            ! defined($formula_data{$symb}->{'Excel:endcell'})) {
+            $formula_data{$symb}->{'Excel:endcell'} = $formula_data{$symb}->{'Excel:startcell'};
+        }
+        $formula_data{$symb}->{'Excel:sum'}= $excel_sheet->store_formula
+            ('=SUM('.$formula_data{$symb}->{'Excel:startcell'}.
+             ':'.$formula_data{$symb}->{'Excel:endcell'}.')');
         # Determine cell the score is held in
-        $seq->{'Excel:scorecell'} = 
+        $formula_data{$symb}->{'Excel:scorecell'} = 
             &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
             ($first_data_row,$cols_output);
-        $seq->{'Excel:scorecol'}=$cols_output;
+        $formula_data{$symb}->{'Excel:scorecol'}=$cols_output;
         if ($chosen_output->{'base'} eq 'parts correct total') {
             $excel_sheet->write($resource_name_row,$cols_output++,
                                 'parts correct',
@@ -1165,10 +1190,10 @@
             $excel_sheet->write($resource_name_row,$cols_output,
                                 'maximum',
                                 $format->{'bold'});
-            $seq->{'Excel:maxcell'} = 
+            $formula_data{$symb}->{'Excel:maxcell'} = 
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
                 ($first_data_row,$cols_output);
-            $seq->{'Excel:maxcol'}=$cols_output;
+            $formula_data{$symb}->{'Excel:maxcol'}=$cols_output;
             $maximum_formula_string.='+'.
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
                 ($first_data_row,$cols_output);
@@ -1204,19 +1229,19 @@
         # Add the maximums for each sequence or assessment
         my %total_cell_translation;
         my %maximum_cell_translation;
-        foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
-            $cols_output=$seq->{'Excel:startcol'};
-            $total_cell_translation{$seq->{'Excel:scorecell'}} = 
+        foreach my $seq (@sequences) {
+            my $symb = $seq->symb;
+            $cols_output=$formula_data{$symb}->{'Excel:startcol'};
+            $total_cell_translation{$formula_data{$symb}->{'Excel:scorecell'}}=
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                ($maximum_data_row,$seq->{'Excel:scorecol'});
-            $maximum_cell_translation{$seq->{'Excel:maxcell'}} = 
+                ($maximum_data_row,$formula_data{$symb}->{'Excel:scorecol'});
+            $maximum_cell_translation{$formula_data{$symb}->{'Excel:maxcell'}}=
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                ($maximum_data_row,$seq->{'Excel:maxcol'});
+                ($maximum_data_row,$formula_data{$symb}->{'Excel:maxcol'});
             my $weight;
             my $max = 0;
-            foreach my $resource (@{$seq->{'contents'}}) {
-                next if ($resource->{'type'} ne 'assessment');
-                foreach my $part (@{$resource->{'parts'}}) {
+            foreach my $resource (&get_resources($navmap,$seq)) {
+                foreach my $part (@{$resource->parts}){
                     $weight = 1;
                     if ($chosen_output->{'scores'}) {
                         $weight = &Apache::lonnet::EXT
@@ -1238,12 +1263,12 @@
             if ($chosen_output->{'sequence_sum'} && 
                 $chosen_output->{'every_problem'}) {
 		my %replaceCells=
-		    ('^'.$seq->{'Excel:startcell'}.':'.
-		         $seq->{'Excel:endcell'}.'$' =>
-		     &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($maximum_data_row,$seq->{'Excel:startcol'}).':'.
-		     &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($maximum_data_row,$seq->{'Excel:endcol'}));
+		    ('^'.$formula_data{$symb}->{'Excel:startcell'}.':'.
+		         $formula_data{$symb}->{'Excel:endcell'}.'$' =>
+		     &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($maximum_data_row,$formula_data{$symb}->{'Excel:startcol'}).':'.
+		     &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($maximum_data_row,$formula_data{$symb}->{'Excel:endcol'}));
                 $excel_sheet->repeat_formula($maximum_data_row,$cols_output++,
-                                             $seq->{'Excel:sum'},undef,
+                                             $formula_data{$symb}->{'Excel:sum'},undef,
 					     %replaceCells);
 			
             } elsif ($chosen_output->{'sequence_sum'}) {
@@ -1284,25 +1309,26 @@
         $excel_sheet->write($summary_header_row,$cols_output++,
                             'Std Dev',$format->{'bold'});
         my $row = $summary_header_row+1;
-        foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+        foreach my $seq (@sequences) {
+            my $symb = $seq->symb;
             $cols_output = 0;
             $excel_sheet->write($row,$cols_output++,
-                                $seq->{'title'},
+                                $seq->compTitle,
                                 $format->{'bold'});
             if ($chosen_output->{'maximum_row'}) {
                 $excel_sheet->write
                     ($row,$cols_output++,
                      '='.
                      &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                     ($maximum_data_row,$seq->{'Excel:scorecol'})
+                     ($maximum_data_row,$formula_data{$symb}->{'Excel:scorecol'})
                      );
             }
             my $range = 
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                ($first_data_row,$seq->{'Excel:scorecol'}).
+                ($first_data_row,$formula_data{$symb}->{'Excel:scorecol'}).
                 ':'.
                 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                ($first_data_row+$num_students-1,$seq->{'Excel:scorecol'});
+                ($first_data_row+$num_students-1,$formula_data{$symb}->{'Excel:scorecol'});
             $excel_sheet->write($row,$cols_output++,
                                 '=AVERAGE('.$range.')');
             $excel_sheet->write($row,$cols_output++,
@@ -1344,8 +1370,9 @@
 
 sub excel_outputstudent {
     my ($r,$student) = @_;
-    return if ($request_aborted);
-    return if (! defined($excel_sheet));
+    if ($request_aborted || ! defined($navmap) || ! defined($excel_sheet)) {
+        return;
+    }
     $cols_output=0;
     #
     # Write out student data
@@ -1372,26 +1399,27 @@
     # Write out sequence scores and totals data
     my %total_cell_translation;
     my %maximum_cell_translation;
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
-        $cols_output = $seq->{'Excel:startcol'};
+    foreach my $seq (@sequences) {
+        my $symb = $seq->symb;
+        $cols_output = $formula_data{$symb}->{'Excel:startcol'};
         # Keep track of cells to translate in total cell
-        $total_cell_translation{$seq->{'Excel:scorecell'}} = 
+        $total_cell_translation{$formula_data{$symb}->{'Excel:scorecell'}} = 
             &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-                        ($rows_output,$seq->{'Excel:scorecol'});
+                        ($rows_output,$formula_data{$symb}->{'Excel:scorecol'});
         # and maximum cell
-        $maximum_cell_translation{$seq->{'Excel:maxcell'}} = 
+        $maximum_cell_translation{$formula_data{$symb}->{'Excel:maxcell'}} = 
             &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
-            ($rows_output,$seq->{'Excel:maxcol'});
+            ($rows_output,$formula_data{$symb}->{'Excel:maxcol'});
         #
         my ($performance,$performance_length,$score,$seq_max,$rawdata);
         if ($chosen_output->{'tries'} || $chosen_output->{'correct'}){
             ($performance,$performance_length,$score,$seq_max,$rawdata) =
-                &StudentTriesOnSequence($student,\%StudentsData,
-                                        $seq,'no');
+                &student_tries_on_sequence($student,\%StudentsData,
+                                           $navmap,$seq,'no');
         } else {
             ($performance,$performance_length,$score,$seq_max,$rawdata) =
-                &StudentPerformanceOnSequence($student,\%StudentsData,
-                                              $seq,'no');
+                &student_performance_on_sequence($student,\%StudentsData,
+                                                 $navmap,$seq,'no');
         } 
         if ($chosen_output->{'every_problem'}) {
             if ($chosen_output->{'correct'}) {
@@ -1416,14 +1444,14 @@
             $chosen_output->{'every_problem'}) {
             # Write a formula for the sum of this sequence
             my %replaceCells=
-		('^'.$seq->{'Excel:startcell'}.':'.$seq->{'Excel:endcell'}.'$'
+		('^'.$formula_data{$symb}->{'Excel:startcell'}.':'.$formula_data{$symb}->{'Excel:endcell'}.'$'
 		 => 
-		 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($rows_output,$seq->{'Excel:startcol'}).':'.
-		 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($rows_output,$seq->{'Excel:endcol'})
+		 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($rows_output,$formula_data{$symb}->{'Excel:startcol'}).':'.
+		 &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($rows_output,$formula_data{$symb}->{'Excel:endcol'})
 		 );
             # The undef is for the format	    
 	    $excel_sheet->repeat_formula($rows_output,$cols_output++,
-					 $seq->{'Excel:sum'},undef,
+					 $formula_data{$symb}->{'Excel:sum'},undef,
 					 %replaceCells);
         } elsif ($chosen_output->{'sequence_sum'}) {
             if ($score eq ' ') {
@@ -1459,8 +1487,9 @@
 
 sub excel_finish {
     my ($r) = @_;
-    return if ($request_aborted);
-    return if (! defined($excel_sheet));
+    if ($request_aborted || ! defined($navmap) || ! defined($excel_sheet)) {
+        return;
+    }
     #
     # Write the excel file
     $excel_workbook->close();
@@ -1502,6 +1531,8 @@
 my $filename;
 my $request_aborted;
 my %prog_state; # progress window state
+my $navmap;
+my @sequences;
 
 sub csv_initialize{
     my ($r) = @_;
@@ -1512,6 +1543,17 @@
     undef($request_aborted);
     undef(%prog_state);
     #
+    undef($navmap);
+    undef(@sequences);
+    ($navmap,@sequences) = 
+        &Apache::lonstatistics::selected_sequences_with_assessments();
+    if (! ref($navmap)) {
+        # Unable to get data, so bail out
+        $r->print("<h3>".
+                  &mt('Unable to retrieve course information.').
+                  '</h3>');
+    }
+    #
     # Deal with unimplemented requests
     $request_aborted = undef;
     if ($chosen_output->{'base'} =~ /final table/) {
@@ -1563,23 +1605,19 @@
         $sequence_row .='"",';
         $resource_row .= '"'.&Apache::loncommon::csv_translate($field).'",';
     }
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+    foreach my $seq (@sequences) {
         $sequence_row .= '"'.
-            &Apache::loncommon::csv_translate($seq->{'title'}).'",';
+            &Apache::loncommon::csv_translate($seq->compTitle).'",';
         my $count = 0;
         if ($chosen_output->{'every_problem'}) {
             foreach my $res (@{$seq->{'contents'}}) {
-                if ($res->{'type'} ne 'assessment'  || 
-                    ! exists($res->{'parts'})       ||
-                    ref($res->{'parts'}) ne 'ARRAY' ||
-                    scalar(@{$res->{'parts'}}) < 1) {
+                if (scalar(@{$res->parts}) < 1) {
                     next;
                 }
-                foreach my $part (@{$res->{'parts'}}) {
+                foreach my $part (@{$res->parts}) {
                     $resource_row .= '"'.
-                        &Apache::loncommon::csv_translate($res->{'title'}.
-                                                          ', Part '.$part
-                                                          ).'",';
+                        &Apache::loncommon::csv_translate
+                        ($res->compTitle.', Part '.$res->part_display($part)).'",';
                     $count++;
                 }
             }
@@ -1614,8 +1652,9 @@
 
 sub csv_outputstudent {
     my ($r,$student) = @_;
-    return if ($request_aborted);
-    return if (! defined($outputfile));
+    if ($request_aborted || ! defined($navmap) || ! defined($outputfile)) {
+        return;
+    }
     my $Str = '';
     #
     # Output student fields
@@ -1642,16 +1681,16 @@
     # Output performance data
     my $total = 0;
     my $maximum = 0;
-    foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+    foreach my $seq (@sequences) {
         my ($performance,$performance_length,$score,$seq_max,$rawdata);
         if ($chosen_output->{'tries'}){
             ($performance,$performance_length,$score,$seq_max,$rawdata) =
-                &StudentTriesOnSequence($student,\%StudentsData,
-                                        $seq,'no');
+                &student_tries_on_sequence($student,\%StudentsData,
+                                           $navmap,$seq,'no');
         } else {
             ($performance,$performance_length,$score,$seq_max,$rawdata) =
-                &StudentPerformanceOnSequence($student,\%StudentsData,
-                                              $seq,'no');
+                &student_performance_on_sequence($student,\%StudentsData,
+                                                 $navmap,$seq,'no');
         }
         if ($chosen_output->{'every_problem'}) {
             if ($chosen_output->{'correct'}) {
@@ -1694,8 +1733,9 @@
 
 sub csv_finish {
     my ($r) = @_;
-    return if ($request_aborted);
-    return if (! defined($outputfile));
+    if ($request_aborted || ! defined($navmap) || ! defined($outputfile)) {
+        return;
+    }
     close($outputfile);
     #
     my $c = $r->connection();
@@ -1748,9 +1788,7 @@
     my @TriesData = ();
     my $tries;
     my $hasdata = 0; # flag - true if the student has any data on the sequence
-    my @resources = 
-        $navmap->retrieveResources($seq,sub { shift->is_problem(); },0,0,0);
-    foreach my $resource (@resources) {
+    foreach my $resource (&get_resources($navmap,$seq)) {
         my $resource_data = $studentdata->{$resource->symb};
         my $value = '';
         foreach my $partnum (@{$resource->parts()}) {
@@ -1853,7 +1891,7 @@
 
 =pod
 
-=item &StudentPerformanceOnSequence()
+=item &student_performance_on_sequence
 
 Inputs:
 
@@ -1883,9 +1921,7 @@
     my @ScoreData = ();
     my $partscore;
     my $hasdata = 0; # flag, 0 if there were no submissions on the sequence
-    my @resources = 
-        $navmap->retrieveResources($seq,sub { shift->is_problem(); },0,0,0);
-    foreach my $resource (@resources) {
+    foreach my $resource (&get_resources($navmap,$seq)) {
         my $symb = $resource->symb;
         my $resource_data = $studentdata->{$symb};
         foreach my $part (@{$resource->parts()}) {

--matthew1109374344--