--- loncom/interface/statistics/lonstudentassessment.pm 2004/02/12 14:47:55 1.88 +++ loncom/interface/statistics/lonstudentassessment.pm 2004/02/12 21:15:47 1.90 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonstudentassessment.pm,v 1.88 2004/02/12 14:47:55 matthew Exp $ +# $Id: lonstudentassessment.pm,v 1.90 2004/02/12 21:15:47 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -473,6 +473,8 @@ my @OutputDataOptions = sequence_sum => 1, sequence_max => 1, grand_total => 1, + summary_table => 1, + maximum_row => 1, shortdesc => 'Total Score and Maximum Possible for each '. 'Sequence or Folder', longdesc => 'The score of each student as well as the '. @@ -488,6 +490,8 @@ my @OutputDataOptions = sequence_sum => 1, sequence_max => 1, grand_total => 1, + summary_table => 1, + maximum_row => 1, shortdesc => 'Score on each Problem Part', longdesc =>'The students score on each problem part, computed as'. 'the part weight * part awarded', @@ -502,6 +506,8 @@ my @OutputDataOptions = sequence_sum => 0, sequence_max => 0, grand_total => 0, + summary_table => 0, + maximum_row => 0, shortdesc => 'Number of Tries before success on each Problem Part', longdesc =>'The number of tries before success on each problem part.', }, @@ -515,6 +521,8 @@ my @OutputDataOptions = sequence_sum => 1, sequence_max => 1, grand_total => 1, + summary_table => 1, + maximum_row => 0, shortdesc => 'Number of Problem Parts completed successfully.', longdesc => 'The Number of Problem Parts completed successfully and '. 'the maximum possible for each student', @@ -616,12 +624,43 @@ sub html_initialize { my $width=$Apache::lonstatistics::StudentData{$field}->{'width'}; $Str .= $title.' 'x($width-$base).$padding; } - # Now the selected sequences need to be listed + # + # Compute the column widths and output the sequence titles foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()){ - my $title = $sequence->{'title'}; - my $base = $sequence->{'base_width'}; - my $width = $sequence->{'width'}; - $Str .= $title.' 'x($width-$base).$padding; + # + # Comptue column widths + $sequence->{'width_sum'} = 0; + if ($chosen_output->{'sequence_sum'}) { + # Use 3 digits for the sum + $sequence->{'width_sum'} = 3; + } + if ($chosen_output->{'sequence_max'}) { + if ($sequence->{'width_sum'}>0) { + # One digit for the '/' + $sequence->{'width_sum'} +=1; + } + # Use 3 digits for the total + $sequence->{'width_sum'}+=3; + } + if ($chosen_output->{'every_problem'}) { + # one problem per digit + $sequence->{'width_problem'} = $sequence->{'num_assess_parts'}; + } else { + $sequence->{'width_problem'} = 0; + } + $sequence->{'width_total'} = $sequence->{'width_problem'} + + $sequence->{'width_sum'}; + if ($sequence->{'width_total'} < length($sequence->{'title'})) { + $sequence->{'width_total'} = length($sequence->{'title'}); + $sequence->{'width_problem'} = + $sequence->{'width_total'} - $sequence->{'width_sum'}; + } + # + # Output the sequence titles + $Str .= + $sequence->{'title'}.' 'x($sequence->{'width_total'}- + length($sequence->{'title'}) + ).$padding; } $Str .= "total\n"; $Str .= "
";
@@ -675,17 +714,22 @@ sub html_outputstudent {
                 &StudentPerformanceOnSequence($student,\%StudentsData,
                                               $seq,$show_links);
         }
-        my $ratio = sprintf("%3d",$score).'/'.sprintf("%3d",$seq_max);
-        #
+        my $ratio='';
         if ($chosen_output->{'sequence_sum'}) {
-            $performance  = $ratio;
-            $performance .= ' 'x($seq->{'width'}-length($ratio));
-        } else {
-            # Pad with extra spaces
-            $performance .= ' 'x($seq->{'width'}-$performance_length-
-                                 length($ratio)
-                                 ).$ratio;
+            $ratio .= sprintf("%3d",$score);
+        }
+        if ($chosen_output->{'sequence_max'}) {
+            if ($chosen_output->{'sequence_sum'}) {
+                $ratio .= '/';
+            }
+            $ratio .= sprintf("%3d",$seq_max);
+        }
+        #
+        if (! $chosen_output->{'every_problem'}) {
+            $performance = '';
         }
+        $performance .= ' 'x($seq->{'width_problem'}-$performance_length).
+            $ratio;
         #
         $Str .= $performance.$padding;
         #
@@ -717,10 +761,12 @@ sub html_finish {
     #
     # Check for suppressed output and close the progress window if so
     $r->print("
\n"); - if ($single_student_mode) { - $r->print(&SingleStudentTotal()); - } else { - $r->print(&StudentAverageTotal()); + if ($chosen_output->{'summary_table'}) { + if ($single_student_mode) { + $r->print(&SingleStudentTotal()); + } else { + $r->print(&StudentAverageTotal()); + } } $r->rflush(); return; @@ -833,7 +879,8 @@ sub excel_initialize { undef ($total_formula); # my $total_columns = scalar(&get_student_fields_to_show()); - + my $num_students = scalar(@Apache::lonstatistics::Students); + # foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) { if ($chosen_output->{'every_problem'}) { $total_columns += $seq->{'num_assess_parts'}; @@ -887,6 +934,24 @@ END $rows_output = 0; $cols_output = 0; # + # Determine rows + my $header_row = $rows_output++; + my $description_row = $rows_output++; + $rows_output++; # blank row + my $summary_header_row; + if ($chosen_output->{'summary_table'}) { + $summary_header_row = $rows_output++; + $rows_output+= scalar(&Apache::lonstatistics::Sequences_with_Assess()); + $rows_output++; + } + my $sequence_name_row = $rows_output++; + my $resource_name_row = $rows_output++; + my $maximum_data_row = $rows_output++; + if (! $chosen_output->{'maximum_row'}) { + $rows_output--; + } + my $first_data_row = $rows_output++; + # # Create sheet $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename); # @@ -923,7 +988,7 @@ END 'mmm d yyyy hh:mm AM/PM'); # # Put the course description in the header - $excel_sheet->write($rows_output,$cols_output++, + $excel_sheet->write($header_row,$cols_output++, $ENV{'course.'.$ENV{'request.course.id'}.'.description'}, $format->{'h1'}); $cols_output += 3; @@ -945,24 +1010,21 @@ END $sectionstring = "Section ".$Sections[0]; } } - $excel_sheet->write($rows_output,$cols_output++,$sectionstring, + $excel_sheet->write($header_row,$cols_output++,$sectionstring, $format->{'h3'}); $cols_output += scalar(@Sections); # # Put the date in there too - $excel_sheet->write($rows_output++,$cols_output++, + $excel_sheet->write($header_row,$cols_output++, 'Compiled on '.localtime(time),$format->{'h3'}); # $cols_output = 0; - $excel_sheet->write($rows_output++,$cols_output++, + $excel_sheet->write($description_row,$cols_output++, $chosen_output->{'shortdesc'}, $format->{'h3'}); - # - # Figure out the rows we need - my $sequence_name_row = $rows_output+1; - my $resource_name_row = $sequence_name_row+1; - my $maximum_data_row = $sequence_name_row+2; - my $first_data_row = $sequence_name_row+3; + ############################################## + # Output headings for the raw data + ############################################## # # Add the student headers $cols_output = 0; @@ -975,11 +1037,11 @@ END my $total_formula_string = '=0'; foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) { $excel_sheet->write($sequence_name_row,, - $cols_output,$seq->{'title'},$format->{'h3'}); + $cols_output,$seq->{'title'},$format->{'bold'}); # Determine starting cell $seq->{'Excel:startcell'}= &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$cols_output); + ($first_data_row,$cols_output); $seq->{'Excel:startcol'}=$cols_output; my $count = 0; if ($chosen_output->{'every_problem'}) { @@ -1013,7 +1075,7 @@ END } else { $seq->{'Excel:endcell'} = &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$cols_output-1); + ($first_data_row,$cols_output-1); $seq->{'Excel:endcol'} = $cols_output-1; } # Create the formula for summing up this sequence @@ -1027,7 +1089,7 @@ END # Determine cell the score is held in $seq->{'Excel:scorecell'} = &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$cols_output); + ($first_data_row,$cols_output); $seq->{'Excel:scorecol'}=$cols_output; if ($chosen_output->{'base'} eq 'parts correct total') { $excel_sheet->write($resource_name_row,$cols_output++, @@ -1048,7 +1110,7 @@ END # $total_formula_string.='+'. &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$cols_output-1); + ($first_data_row,$cols_output-1); if ($chosen_output->{'sequence_max'}) { $excel_sheet->write($resource_name_row,$cols_output++, 'maximum', @@ -1060,9 +1122,10 @@ END $format->{'bold'}); } $total_formula = $excel_sheet->store_formula($total_formula_string); - # + ############################################## # Output a row for MAX, if appropriate - if ($chosen_output->{'scores'}) { + ############################################## + if ($chosen_output->{'maximum_row'}) { $cols_output = 0; foreach my $field (&get_student_fields_to_show()) { if ($field eq 'username' || $field eq 'fullname' || @@ -1129,8 +1192,57 @@ END $total_formula,undef, %total_cell_translation); } - } # End of MAXIMUM row output if ($chosen_output->{'scores'}) { + } # End of MAXIMUM row output if ($chosen_output->{'maximum_row'}) { $rows_output = $first_data_row; + ############################################## + # Output summary table, which actually is above the sequence name row. + ############################################## + if ($chosen_output->{'summary_table'}) { + $cols_output = 0; + $excel_sheet->write($summary_header_row,$cols_output++, + 'Summary Table',$format->{'bold'}); + if ($chosen_output->{'maximum_row'}) { + $excel_sheet->write($summary_header_row,$cols_output++, + 'Maximum',$format->{'bold'}); + } + $excel_sheet->write($summary_header_row,$cols_output++, + 'Average',$format->{'bold'}); + $excel_sheet->write($summary_header_row,$cols_output++, + 'Median',$format->{'bold'}); + $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()) { + $cols_output = 0; + $excel_sheet->write($row,$cols_output++, + $seq->{'title'}, + $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'}) + ); + } + my $range = + &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell + ($first_data_row,$seq->{'Excel:scorecol'}). + ':'. + &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell + ($first_data_row+$num_students-1,$seq->{'Excel:scorecol'}); + $excel_sheet->write($row,$cols_output++, + '=AVERAGE('.$range.')'); + $excel_sheet->write($row,$cols_output++, + '=MEDIAN('.$range.')'); + $excel_sheet->write($row,$cols_output++, + '=STDEV('.$range.')'); + $row++; + } + } + ############################################## + # Take care of non-excel initialization + ############################################## # # Let the user know what we are doing my $studentcount = scalar(@Apache::lonstatistics::Students);