--- loncom/interface/statistics/lonstudentassessment.pm 2004/07/13 15:03:34 1.102 +++ loncom/interface/statistics/lonstudentassessment.pm 2005/01/21 18:52:40 1.110 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonstudentassessment.pm,v 1.102 2004/07/13 15:03:34 matthew Exp $ +# $Id: lonstudentassessment.pm,v 1.110 2005/01/21 18:52:40 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -357,6 +357,9 @@ sub CreateInterface { $Str .= ''; $Str .= ' 'x5; + $Str .= + &mt('Status[_1]', + ''); $Str .= '
'; return $Str; } @@ -516,6 +519,7 @@ my @OutputDataOptions = maximum_row => 0, shortdesc => 'Number of Tries before success on each Problem Part', longdesc =>'The number of tries before success on each problem part.', + non_html_notes => 'negative values indicate an incorrect problem', }, { name =>'Parts Correct', base =>'tries', @@ -694,6 +698,10 @@ sub html_outputstudent { my @to_show = &get_student_fields_to_show(); foreach my $field (@to_show) { my $title=$student->{$field}; + # Deal with 'comments' - how I love special cases + if ($field eq 'comments') { + $title = ''.&mt('Comments').''; + } my $base = length($title); my $width=$Apache::lonstatistics::StudentData{$field}->{'width'}; $Str .= $title.' 'x($width-$base).$padding; @@ -772,6 +780,8 @@ sub html_outputstudent { } if (! defined($score)) { $score = ' ' x $total_sum_width; + } else { + $score = sprintf("%.0f",$score); } $Str .= ' '.' 'x($total_sum_width-length($score)).$score.' / '.$max; $Str .= " \n"; @@ -799,18 +809,16 @@ sub html_finish { } sub StudentAverageTotal { - my $Str = "

Summary Tables

\n"; -# my $max_students; -# my $total_ave = 0; -# my $total_max = 0; + my $Str = '

'.&mt('Summary Tables').'

'.$/; $Str .= ''."\n"; - $Str .= "\n"; + $Str .= ''. + ''. + ''. + ''. + ''.$/; foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) { my $ave; my $num_students = $Statistics->{$seq->{'symb'}}->{'num_students'}; -# if ($num_students > $max_students) { -# $max_students = $num_students; -# } if ($num_students > 0) { $ave = int(100* ($Statistics->{$seq->{'symb'}}->{'score'}/$num_students) @@ -818,34 +826,32 @@ sub StudentAverageTotal { } else { $ave = 0; } -# $total_ave += $ave; my $max = $Statistics->{$seq->{'symb'}}->{'max'}; -# $total_max += $max; $ave = sprintf("%.2f",$ave); $Str .= ''. ''. ''."\n"; } -# $total_ave = sprintf('%.2f',$total_ave); # only two digit $Str .= "
TitleAverageMaximum
'.&mt('Title').''.&mt('Average').''.&mt('Maximum').'
'.$seq->{'title'}.''.$ave.' '.$max.' '.'
\n"; -# $Str .= ''."\n"; -# $Str .= ''. -# "\n"; -# $Str .= ''. -# ''. -# ''. -# ''; -# $Str .= "
Number of StudentsAverageMaximum
'.$max_students.''.$total_ave.' '.''.$total_max.' '.'
\n"; return $Str; } sub SingleStudentTotal { my $student = &Apache::lonstatistics::current_student(); - my $Str = "

Summary table for ".$student->{'fullname'}." ". - $student->{'username'}.'@'.$student->{'domain'}."

\n"; + my $Str = '

'.&mt('Summary table for [_1] ([_2]@[_3])', + $student->{'fullname'}, + $student->{'username'},$student->{'domain'}).'

'; + $Str .= $/; $Str .= ''."\n"; $Str .= - "\n"; + ''. + ''; + if ($chosen_output->{'base'} eq 'tries') { + $Str .= ''; + } else { + $Str .= ''; + } + $Str .= ''."\n"; my $total = 0; my $total_max = 0; foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) { @@ -857,7 +863,7 @@ sub SingleStudentTotal { $total += $value; $total_max +=$max; } - $Str .= ''. + $Str .= ''. ''. '\n"; $Str .= "
Sequence or FolderScoreMaximum
'.&mt('Sequence or Folder').''.&mt('Parts Correct').''.&mt('Score').''.&mt('Maximum').'
Total
'.&mt('Total').''.$total.''.$total_max."
\n"; @@ -921,39 +927,18 @@ sub excel_initialize { # Add 2 because we need a 'sequence_sum' and 'total' column for each $total_columns += 2; } + my $too_many_cols_error_message = + '

'.&mt('Unable to Complete Request').'

'.$/. + '

'.&mt('LON-CAPA is unable to produce your Excel spreadsheet because your selections will result in more than 255 columns. Excel allows only 255 columns in a spreadsheet.').'

'.$/. + '

'.&mt('You may consider reducing the number of Sequences or Folders you have selected.').'

'.$/. + '

'.&mt('LON-CAPA can produce CSV files of this data or Excel files of the Scores Summary data.').'

'.$/; if ($chosen_output->{'base'} eq 'tries' && $total_columns > 255) { - $r->print(<Unable to Complete Request -

-LON-CAPA is unable to produce your Excel spreadsheet because your selections -will result in more than 255 columns. Excel allows only 255 columns in a -spreadsheet. -

-You may consider reducing the number of Sequences or Folders you -have selected. -

-LON-CAPA can produce CSV files of this data or Excel files of the -summary data (Parts Correct or Parts Correct & Totals). -

-END - $request_aborted = 1; + $r->print($too_many_cols_error_message); + $request_aborted = 1; } if ($chosen_output->{'base'} eq 'scores' && $total_columns > 255) { - $r->print(<Unable to Complete Request -

-LON-CAPA is unable to produce your Excel spreadsheet because your selections -will result in more than 255 columns. Excel allows only 255 columns in a -spreadsheet. -

-You may consider reducing the number of Sequences or Folders you -have selected. -

-LON-CAPA can produce CSV files of this data or Excel files of the -Scores Summary data. -

-END - $request_aborted = 1; + $r->print($too_many_cols_error_message); + $request_aborted = 1; } return if ($request_aborted); # @@ -970,6 +955,7 @@ END # Determine rows my $header_row = $rows_output++; my $description_row = $rows_output++; + my $notes_row = $rows_output++; $rows_output++; # blank row my $summary_header_row; if ($chosen_output->{'summary_table'}) { @@ -1044,7 +1030,13 @@ END $cols_output = 0; $excel_sheet->write($description_row,$cols_output++, $chosen_output->{'shortdesc'}, - $format->{'h3'}); + $format->{'b'}); + # + $cols_output = 0; + $excel_sheet->write($notes_row,$cols_output++, + $chosen_output->{'non_html_notes'}, + $format->{'i'}); + ############################################## # Output headings for the raw data ############################################## @@ -1083,13 +1075,14 @@ END $cols_output++, $res->{'title'}.' part '.$part, $format->{'bold'}); + $count++; } } else { $excel_sheet->write($resource_name_row, $cols_output++, $res->{'title'},$format->{'bold'}); + $count++; } - $count++; } } # Determine ending cell @@ -1211,16 +1204,15 @@ END # if ($chosen_output->{'sequence_sum'} && $chosen_output->{'every_problem'}) { - my %replaceCells; - $replaceCells{$seq->{'Excel:startcell'}} = - &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$seq->{'Excel:startcol'}); - $replaceCells{$seq->{'Excel:endcell'}} = - &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($maximum_data_row,$seq->{'Excel:endcol'}); + 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'})); $excel_sheet->repeat_formula($maximum_data_row,$cols_output++, $seq->{'Excel:sum'},undef, - %replaceCells); + %replaceCells); + } elsif ($chosen_output->{'sequence_sum'}) { $excel_sheet->write($maximum_data_row,$cols_output++,$max); } @@ -1237,7 +1229,7 @@ END if ($chosen_output->{'grand_maximum'}) { $excel_sheet->repeat_formula($maximum_data_row,$cols_output++, $maximum_formula,undef, - %total_cell_translation); + %maximum_cell_translation); } } # End of MAXIMUM row output if ($chosen_output->{'maximum_row'}) { $rows_output = $first_data_row; @@ -1309,7 +1301,8 @@ END # Initialize progress window %prog_state=&Apache::lonhtmlcommon::Create_PrgWin ($r,'Excel File Compilation Status', - 'Excel File Compilation Progress', $studentcount); + 'Excel File Compilation Progress', $studentcount, + 'inline',undef,'Statistics','stats_status'); # &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, 'Processing first student'); @@ -1325,7 +1318,12 @@ sub excel_outputstudent { # 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}); + my $value = $student->{$field}; + if ($field eq 'comments') { + $value = &Apache::lonmsg::retrieve_instructor_comments + ($student->{'username'},$student->{'domain'}); + } + $excel_sheet->write($rows_output,$cols_output++,$value); } # # Get student assessment data @@ -1347,6 +1345,10 @@ sub excel_outputstudent { $total_cell_translation{$seq->{'Excel:scorecell'}} = &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell ($rows_output,$seq->{'Excel:scorecol'}); + # and maximum cell + $maximum_cell_translation{$seq->{'Excel:maxcell'}} = + &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell + ($rows_output,$seq->{'Excel:maxcol'}); # my ($performance,$performance_length,$score,$seq_max,$rawdata); if ($chosen_output->{'tries'} || $chosen_output->{'correct'}){ @@ -1380,23 +1382,16 @@ sub excel_outputstudent { if ($chosen_output->{'sequence_sum'} && $chosen_output->{'every_problem'}) { # Write a formula for the sum of this sequence - my %replaceCells; - $replaceCells{$seq->{'Excel:startcell'}} = - &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($rows_output,$seq->{'Excel:startcol'}); - $replaceCells{$seq->{'Excel:endcell'}} = - &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell - ($rows_output,$seq->{'Excel:endcol'}); - # The undef is for the format - if (scalar(keys(%replaceCells)) == 1) { - $excel_sheet->repeat_formula($rows_output,$cols_output++, - $seq->{'Excel:sum'},undef, - %replaceCells,%replaceCells); - } else { - $excel_sheet->repeat_formula($rows_output,$cols_output++, - $seq->{'Excel:sum'},undef, - %replaceCells); - } + my %replaceCells= + ('^'.$seq->{'Excel:startcell'}.':'.$seq->{'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'}) + ); + # The undef is for the format + $excel_sheet->repeat_formula($rows_output,$cols_output++, + $seq->{'Excel:sum'},undef, + %replaceCells); } elsif ($chosen_output->{'sequence_sum'}) { if ($score eq ' ') { $cols_output++; @@ -1417,7 +1412,7 @@ sub excel_outputstudent { if ($chosen_output->{'grand_maximum'}) { $excel_sheet->repeat_formula($rows_output,$cols_output++, $maximum_formula,undef, - %total_cell_translation); + %maximum_cell_translation); } # # Bookkeeping @@ -1501,7 +1496,8 @@ END my $studentcount = scalar(@Apache::lonstatistics::Students); %prog_state=&Apache::lonhtmlcommon::Create_PrgWin ($r,'CSV File Compilation Status', - 'CSV File Compilation Progress', $studentcount); + 'CSV File Compilation Progress', $studentcount, + 'inline',undef,'Statistics','stats_status'); # # Open a file $filename = '/prtspool/'. @@ -1520,6 +1516,12 @@ END print $outputfile '"'.&Apache::loncommon::csv_translate($description).'",'. '"'.&Apache::loncommon::csv_translate(scalar(localtime(time))).'"'. "\n"; + foreach my $item ('shortdesc','non_html_notes') { + next if (! exists($chosen_output->{$item})); + print $outputfile + '"'.&Apache::loncommon::csv_translate($chosen_output->{$item}).'"'. + "\n"; + } # # Print out the headings my $sequence_row = ''; @@ -1586,7 +1588,12 @@ sub csv_outputstudent { # Output student fields my @to_show = &get_student_fields_to_show(); foreach my $field (@to_show) { - $Str .= '"'.&Apache::loncommon::csv_translate($student->{$field}).'",'; + my $value = $student->{$field}; + if ($field eq 'comments') { + $value = &Apache::lonmsg::retrieve_instructor_comments + ($student->{'username'},$student->{'domain'}); + } + $Str .= '"'.&Apache::loncommon::csv_translate($value).'",'; } # # Get student assessment data @@ -1773,9 +1780,15 @@ sub StudentTriesOnSequence { } # if (! defined($tries)) { - $tries = $symbol; + $tries = 0; + } + if ($status =~ /^(incorrect|ungraded)/) { + # Bug 3390: show '-' for tries on incorrect problems + # (csv & excel only) + push(@TriesData,-$tries); + } else { + push (@TriesData,$tries); } - push (@TriesData,$tries); # if ( ($links eq 'yes' && $symbol ne ' ') || ($links eq 'all')) {