--- loncom/interface/statistics/lonstudentassessment.pm 2003/03/03 19:28:29 1.31
+++ loncom/interface/statistics/lonstudentassessment.pm 2003/03/03 22:54:05 1.32
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstudentassessment.pm,v 1.31 2003/03/03 19:28:29 matthew Exp $
+# $Id: lonstudentassessment.pm,v 1.32 2003/03/03 22:54:05 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -83,7 +83,7 @@ my $Statistics;
=item $output_mode 'html', 'excel', or 'csv' for output mode
-=item $show 'all' or 'totals' determines how much data is output
+=item $show 'all', 'totals', or 'scores' determines how much data is output
=cut
@@ -270,14 +270,41 @@ sub CreateInterface {
#######################################################
#######################################################
+my @OutputOptions =
+ ({ name => 'HTML, with links',
+ value => 'html, with links',
+ description => ''},
+ { name => 'HTML, without links',
+ value => 'html, without links',
+ description => ''},
+ { name => 'HTML, totals',
+ value => 'html, totals',
+ description => ''},
+ { name => 'HTML, scores only',
+ value => 'html, scores only',
+ description => ''},
+ { name => 'Excel, totals',
+ value => 'excel, totals',
+ description => ''},
+ { name => 'Excel, scores only',
+ value => 'excel, scores only',
+ description => ''},
+ { name => 'CSV, totals',
+ value => 'csv, totals',
+ description => ''},
+ { name => 'CSV, scores only',
+ value => 'csv, scores only',
+ description => ''},
+ { name => 'CSV, everything',
+ value => 'csv, everything',
+ description => ''}
+ );
+
sub CreateAndParseOutputSelector {
my $Str = '';
my $elementname = 'outputmode';
#
# Format for output options is 'mode, restrictions';
- my @Options = ('html, with links','html, without links',
- 'html, totals only','excel, totals only',
- 'csv, totals only','csv, everything');
my $selected = 'html, with links';
if (exists($ENV{'form.'.$elementname})) {
if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
@@ -303,18 +330,20 @@ sub CreateAndParseOutputSelector {
} else {
$show_links = 'no';
}
- if ($restriction eq 'totals only') {
+ if ($restriction eq 'totals') {
$show = 'totals';
+ } elsif ($restriction eq 'scores only') {
+ $show = 'scores';
} else {
$show = 'everything';
}
#
# Build the form element
$Str = qq/";
return $Str;
@@ -412,6 +441,9 @@ sub html_outputstudent {
if ($show eq 'totals') {
$performance = ' 'x(length($seq_max)-length($score)).$ratio;
$performance .= ' 'x($seq->{'width'}-length($performance));
+ } elsif ($show eq 'scores') {
+ $performance = $score;
+ $performance .= ' 'x($seq->{'width'}-length($performance));
} else {
# Pad with extra spaces
$performance .= ' 'x($seq->{'width'}-$seq_max-
@@ -475,42 +507,173 @@ sub html_finish {
{
my $excel_sheet;
+my $excel_workbook;
+
+my $filename;
+my $rows_output;
+my $cols_output;
+
+my $num_students;
+my $start_time;
sub excel_initialize {
my ($r) = @_;
#
- $r->print("
Not implemented yet
");
- return;
- my $filename = '/prtspool/'.
+ $filename = '/prtspool/'.
$ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
time.'_'.rand(1000000000).'.xls';
- $excel_sheet = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
- if (! defined($excel_sheet)) {
+ #
+ $excel_workbook = undef;
+ $excel_sheet = undef;
+ #
+ $rows_output = 0;
+ $cols_output = 0;
+ #
+ $num_students = 0;
+ $start_time = time;
+ #
+ # Create sheet
+ $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
+ #
+ # Check for errors
+ if (! defined($excel_workbook)) {
$r->log_error("Error creating excel spreadsheet $filename: $!");
$r->print("Problems creating new Excel file. ".
"This error has been logged. ".
"Please alert your LON-CAPA administrator");
- return 0;
+ return ;
}
#
# The excel spreadsheet stores temporary data in files, then put them
# together. If needed we should be able to disable this (memory only).
# The temporary directory must be specified before calling 'addworksheet'.
# File::Temp is used to determine the temporary directory.
- $excel_sheet->set_tempdir($Apache::lonnet::tmpdir);
+ $excel_workbook->set_tempdir($Apache::lonnet::tmpdir);
+ #
+ # Add a worksheet
+ $excel_sheet = $excel_workbook->addworksheet
+ ($ENV{'course.'.$ENV{'request.course.id'}.'.description'});
+ #
+ # Add the student headers
+ foreach my $field (&get_student_fields_to_show()) {
+ $excel_sheet->write(1,$cols_output++,$field);
+ }
+ #
+ # Add the Sequence Headers
+ foreach my $seq (&get_sequences_to_show) {
+ $excel_sheet->write(0,$cols_output,$seq->{'title'});
+ if ($show eq 'totals') {
+ $excel_sheet->write(1,$cols_output,'score');
+ $excel_sheet->write(1,$cols_output+1,'maximum');
+ $cols_output += 2;
+ } else {
+ $cols_output++;
+ }
+ }
+ #
+ # Bookkeeping
+ if ($show eq 'totals') {
+ $rows_output = 2;
+ } else {
+ $rows_output = 1;
+ }
+ #
+ # Let the user know what we are doing
+ my $studentcount = scalar(@Apache::lonstatistics::Students);
+ $r->print("Compiling Excel spreadsheet for ".
+ $studentcount.' student');
+ $r->print('s') if ($studentcount > 1);
+ $r->print("
\n");
+ $r->rflush();
#
- # Determine the name to give the worksheet
-# $excel_sheet->addworksheet();
-
return;
}
sub excel_outputstudent {
my ($r,$student) = @_;
+ return if (! defined($excel_sheet));
+ $cols_output=0;
+ #
+ # 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});
+ }
+ #
+ # Get student assessment data
+ my %StudentsData;
+ my @tmp = &Apache::loncoursedata::get_current_state($student->{'username'},
+ $student->{'domain'},
+ undef,
+ $ENV{'request.course.id'});
+ if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
+ %StudentsData = @tmp;
+ }
+ #
+ # Write out sequence scores and totals data
+ foreach my $seq (&get_sequences_to_show) {
+ my ($performance,$score,$seq_max) =
+ &StudentPerformanceOnSequence($student,\%StudentsData,
+ $seq,'no');
+ if ($show eq 'totals' || $show eq 'scores') {
+ $excel_sheet->write($rows_output,$cols_output++,$score);
+ }
+ if ($show eq 'totals') {
+ $excel_sheet->write($rows_output,$cols_output++,$seq_max);
+ }
+ }
+ #
+ # Bookkeeping
+ $rows_output++;
+ $cols_output=0;
+ #
+ # Time estimate
+ $num_students++;
+ if ($num_students % 10 == 0) {
+ my $time_est = (time - $start_time)/$num_students *
+ (scalar(@Apache::lonstatistics::Students)-$num_students);
+ $time_est = int($time_est);
+ if (int ($time_est/60) > 0) {
+ my $min = int($time_est/60);
+ my $sec = $time_est % 60;
+ $time_est = $min.' minutes';
+ if ($sec > 1) {
+ $time_est.= ', '.$sec.' seconds';
+ } elsif ($sec > 0) {
+ $time_est.= ', '.$sec.' second';
+ }
+ } else {
+ $time_est .= ' seconds';
+ }
+ $r->print($num_students.' out of '.
+ (scalar(@Apache::lonstatistics::Students)).
+ " students processed. ".
+ $time_est." remain.
\n");
+ $r->rflush();
+ }
+ return;
}
sub excel_finish {
my ($r) = @_;
+ return if (! defined($excel_sheet));
+ #
+ # Write the excel file
+ $excel_workbook->close();
+ my $c = $r->connection();
+ #
+ return if($c->aborted());
+ #
+ # Tell the user where to get their excel file
+ $r->print('
'.
+ 'Your Excel spreadsheet.'."\n");
+ my $total_time = time - $start_time;
+ if (int ($total_time / 60) > 0) {
+ $total_time = int($total_time/60).' minutes, '.($total_time % 60);
+ }
+ $r->print('
'.$total_time.' seconds total');
+ $r->rflush();
+ return;
}
}
@@ -575,8 +738,7 @@ Inputs:
#######################################################
#######################################################
sub StudentPerformanceOnSequence {
- my ($student,$studentdata,$seq,$links,$totalonly) = @_;
- $totalonly = 0 if (! defined($totalonly));
+ my ($student,$studentdata,$seq,$links) = @_;
$links = 'no' if (! defined($links));
my $Str = '';
my ($sum,$max) = (0,0);