version 1.30, 2003/02/28 21:19:00
|
version 1.33, 2003/03/04 14:21:36
|
Line 54 use Apache::lonstatistics;
|
Line 54 use Apache::lonstatistics;
|
use Apache::lonhtmlcommon; |
use Apache::lonhtmlcommon; |
use Apache::loncoursedata; |
use Apache::loncoursedata; |
use Apache::lonnet; # for logging porpoises |
use Apache::lonnet; # for logging porpoises |
use GDBM_File; |
use Spreadsheet::WriteExcel; |
|
|
|
####################################################### |
|
####################################################### |
|
=pod |
|
|
|
=item Package Variables |
|
|
|
=over 4 |
|
|
|
=item $Statistics Hash ref to store student data. Indexed by symb, |
|
contains hashes with keys 'score' and 'max'. |
|
|
|
=cut |
|
|
|
####################################################### |
|
####################################################### |
|
|
my $Statistics; |
my $Statistics; |
|
|
Line 63 my $Statistics;
|
Line 79 my $Statistics;
|
|
|
=pod |
=pod |
|
|
=item &BuildStudentAssessmentPage() |
=item $show_links 'yes' or 'no' for linking to student performance data |
|
|
Inputs: |
=item $output_mode 'html', 'excel', or 'csv' for output mode |
|
|
=over 4 |
=item $show 'all', 'totals', or 'scores' determines how much data is output |
|
|
|
=cut |
|
|
|
####################################################### |
|
####################################################### |
|
my $show_links; |
|
my $output_mode; |
|
my $show; |
|
|
|
####################################################### |
|
####################################################### |
|
# End of package variable declarations |
|
|
=item $cacheDB The name of the cache file used to store student data |
=pod |
|
|
=item $students Array ref containing the name(s) of the students |
=back |
selected for display |
|
|
|
=item $courseID The ID of the course |
=cut |
|
|
|
####################################################### |
|
####################################################### |
|
|
=item $formName The name of the html form - 'Statistics' |
=pod |
|
|
=item $headings Array ref of headings to show |
=item &BuildStudentAssessmentPage() |
|
|
=item $spacing A string of spaces |
Inputs: |
|
|
=item $studentInformation Array ref of possible headings for student info |
=over 4 |
('fullname','section',...) |
|
|
|
=item $r Apache Request |
=item $r Apache Request |
|
|
Line 98 selected for display
|
Line 127 selected for display
|
sub BuildStudentAssessmentPage { |
sub BuildStudentAssessmentPage { |
my ($r,$c)=@_; |
my ($r,$c)=@_; |
undef($Statistics); |
undef($Statistics); |
|
|
# |
# |
|
# 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(&CreateInterface()); |
|
$r->print('<input type="hidden" name="notfirstrun" value="true" />'); |
$r->rflush(); |
$r->rflush(); |
|
if (! exists($ENV{'form.notfirstrun'})) { |
|
$r->print(<<ENDMSG); |
|
<p> |
|
<font size="+1"> |
|
Please make your selections in the boxes above and hit |
|
the button marked "Update Display". |
|
</font> |
|
</p> |
|
ENDMSG |
|
# $r->print(&OutputDescriptions()); |
|
return; |
|
} |
|
# |
|
# |
|
my $initialize = \&html_initialize; |
|
my $output_student = \&html_outputstudent; |
|
my $finish = \&html_finish; |
|
# |
|
if ($output_mode eq 'excel') { |
|
$initialize = \&excel_initialize; |
|
$output_student = \&excel_outputstudent; |
|
$finish = \&excel_finish; |
|
} elsif ($output_mode eq 'csv') { |
|
$initialize = \&csv_initialize; |
|
$output_student = \&csv_outputstudent; |
|
$finish = \&csv_finish; |
|
} |
# |
# |
$r->print(&CreateTableHeadings()); |
|
if($c->aborted()) { return ; } |
if($c->aborted()) { return ; } |
|
# |
my $Count = 0; |
# Call the initialize routine selected above |
$r->print('<pre>'."\n"); |
$initialize->($r); |
foreach my $student (@Apache::lonstatistics::Students) { |
foreach my $student (@Apache::lonstatistics::Students) { |
if($c->aborted()) { return ; } |
if($c->aborted()) { |
$r->print(&ChartOutputStudent($student)); |
$finish->($r); |
# output it |
return ; |
|
|
$Count++; |
|
if($Count % 5 == 0) { |
|
$r->print("</pre>\n<pre>"); |
|
} |
} |
|
# Call the output_student routine selected above |
$r->rflush(); |
$output_student->($r,$student); |
} |
} |
$r->print('</pre>'."\n"); |
# Call the "finish" routine selected above |
my $Str; |
$finish->($r); |
|
# |
return; |
return; |
} |
} |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
|
|
|
sub get_student_fields_to_show { |
|
my @to_show = @Apache::lonstatistics::SelectedStudentData; |
|
foreach (@to_show) { |
|
if ($_ eq 'all') { |
|
@to_show = @Apache::lonstatistics::StudentDataOrder; |
|
last; |
|
} |
|
} |
|
return @to_show; |
|
} |
|
|
|
sub get_sequences_to_show { |
|
my @Sequences; |
|
foreach my $map_symb (@Apache::lonstatistics::SelectedMaps) { |
|
foreach my $sequence (@Apache::lonstatistics::Sequences) { |
|
next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all'); |
|
next if ($sequence->{'num_assess'} < 1); |
|
push (@Sequences,$sequence); |
|
} |
|
} |
|
return @Sequences; |
|
} |
|
|
|
|
|
####################################################### |
|
####################################################### |
|
|
=pod |
=pod |
|
|
=item &CreateInterface() |
=item &CreateInterface() |
Line 152 sub CreateInterface {
|
Line 234 sub CreateInterface {
|
$Str .= '<td align="center"><b>Sections</b></td>'; |
$Str .= '<td align="center"><b>Sections</b></td>'; |
$Str .= '<td align="center"><b>Student Data</b></td>'; |
$Str .= '<td align="center"><b>Student Data</b></td>'; |
$Str .= '<td align="center"><b>Sequences and Folders</b></td>'; |
$Str .= '<td align="center"><b>Sequences and Folders</b></td>'; |
|
$Str .= '<td align="center"><b>Output Format</b></td>'; |
$Str .= '</tr>'."\n"; |
$Str .= '</tr>'."\n"; |
# |
# |
$Str .= '<tr><td align="center">'."\n"; |
$Str .= '<tr><td align="center">'."\n"; |
Line 170 sub CreateInterface {
|
Line 253 sub CreateInterface {
|
$Str .= '</td><td>'."\n"; |
$Str .= '</td><td>'."\n"; |
$Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5, |
$Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5, |
$only_seq_with_assessments); |
$only_seq_with_assessments); |
|
$Str .= '</td><td>'."\n"; |
|
$Str .= &CreateAndParseOutputSelector(); |
$Str .= '</td></tr>'."\n"; |
$Str .= '</td></tr>'."\n"; |
$Str .= '</table>'."\n"; |
$Str .= '</table>'."\n"; |
return $Str; |
return $Str; |
} |
} |
|
|
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
|
|
=pod |
=pod |
|
|
=item Table Output Routines |
=item &CreateAndParseOutputSelector() |
|
|
=over 4 |
|
|
|
=cut |
=cut |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
{ |
my @OutputOptions = |
my $padding; |
({ name => 'HTML, with links', |
|
value => 'html, with links', |
|
description => 'Output HTML with each symbol linked to the problem '. |
|
'which generated it.'}, |
|
{ name => 'HTML, without links', |
|
value => 'html, without links', |
|
description => 'Output HTML. By not including links, the size of the'. |
|
' web page is greatly reduced. If your browser crashes on the '. |
|
'full display, try this.'}, |
|
{ name => 'HTML, scores only', |
|
value => 'html, scores only', |
|
description => 'Output HTML, only showing the total number of correct'. |
|
' problems (or problem parts) and not the maximum possible for '. |
|
'each student'}, |
|
{ name => 'HTML, totals', |
|
value => 'html, totals', |
|
description => 'Output HTML, but only the summary statistics for each'. |
|
' sequence selected.'}, |
|
{ name => 'Excel, scores only', |
|
value => 'excel, scores only', |
|
description => 'Output an Excel file (compatable with Excel 95), '. |
|
'with a single column for each sequence showing the students '. |
|
'score.'}, |
|
# { name => 'Excel, everything', |
|
# value => 'excel, everything', |
|
# 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.'}, |
|
{ name => 'Excel, totals', |
|
value => 'excel, totals', |
|
description => 'Output an Excel file (compatable with Excel 95), '. |
|
'with two columns for each sequence, the students score on the '. |
|
'sequence and the students maximum possible on the sequence'}, |
|
{ name => 'CSV, everything', |
|
value => 'csv, everything', |
|
description => ''}, |
|
{ name => 'CSV, scores only', |
|
value => 'csv, scores only', |
|
description => ''}, |
|
{ name => 'CSV, totals', |
|
value => 'csv, totals', |
|
description => ''}, |
|
); |
|
|
|
sub OutputDescriptions { |
|
my $Str = ''; |
|
$Str .= "<h2>Output Modes</h2>\n"; |
|
$Str .= "<dl>\n"; |
|
foreach my $outputmode (@OutputOptions) { |
|
$Str .=" <dt>".$outputmode->{'name'}."</dt>\n"; |
|
$Str .=" <dd>".$outputmode->{'description'}."</dd>\n"; |
|
} |
|
$Str .= "</dl>\n"; |
|
return $Str; |
|
} |
|
|
|
sub CreateAndParseOutputSelector { |
|
my $Str = ''; |
|
my $elementname = 'outputmode'; |
|
# |
|
# Format for output options is 'mode, restrictions'; |
|
my $selected = 'html, with links'; |
|
if (exists($ENV{'form.'.$elementname})) { |
|
if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) { |
|
$selected = $ENV{'form.'.$elementname}->[0]; |
|
} else { |
|
$selected = $ENV{'form.'.$elementname}; |
|
} |
|
} |
|
# |
|
# Set package variables describing output mode |
|
$show_links = 'no'; |
|
$output_mode = 'html'; |
|
$show = 'all'; |
|
my ($mode,$restriction) = split(',',$selected); |
|
$restriction =~ s/^\s*//; |
|
if ($mode =~ /^(html|excel|csv)$/) { |
|
$output_mode = $mode; |
|
} else { |
|
$output_mode = 'html'; |
|
} |
|
if ($restriction eq 'with links') { |
|
$show_links = 'yes'; |
|
} else { |
|
$show_links = 'no'; |
|
} |
|
if ($restriction eq 'totals') { |
|
$show = 'totals'; |
|
} elsif ($restriction eq 'scores only') { |
|
$show = 'scores'; |
|
} else { |
|
$show = 'everything'; |
|
} |
|
# |
|
# Build the form element |
|
$Str = qq/<select size="5" name="$elementname">/; |
|
foreach my $option (@OutputOptions) { |
|
$Str .= "\n".' <option value="'.$option->{'value'}.'"'; |
|
$Str .= " selected " if ($option->{'value'} eq $selected); |
|
$Str .= ">".$option->{'name'}."<\/option>"; |
|
} |
|
$Str .= "\n</select>"; |
|
return $Str; |
|
} |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
|
|
=pod |
=pod |
|
|
=item &CreateTableHeadings() |
=head2 HTML output routines |
|
|
Create HTML for the columns of student data to show. |
|
Called by &BuildStudentAssessmentPage(). Calls |
|
&Apache::lonhtmlcommon::CreateHeadings(). |
|
|
|
Inputs: |
=item &html_initialize($r) |
|
|
=over 4 |
|
|
|
=item $cache The ubiquitous cache |
|
|
|
=item $spacing A string of spaces |
Create labels for the columns of student data to show. |
|
|
=item $infoKeys Array ref to names of keys to display from the cache |
=item &html_outputstudent($r,$student) |
which describe students |
|
|
|
=item $infoHeadings Array ref to headings of columns for student info |
Return a line of the chart for a student. |
|
|
=item $sequenceKeys Array ref of names of keys to use to retrieve sequence |
|
data from the cache |
|
|
|
=item $sequenceHeadings Array ref of names of sequences used for output. |
|
|
|
=back |
|
|
|
Returns: A string containing the HTML of the table headings. |
=item &html_finish($r) |
|
|
=cut |
=cut |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
sub CreateTableHeadings { |
{ |
|
my $padding; |
|
my $count; |
|
|
|
sub html_initialize { |
|
my ($r) = @_; |
# |
# |
$padding = ' 'x3; |
$padding = ' 'x3; |
|
$count = 1; |
# |
# |
my $Str = '<pre>'; |
my $Str = "<pre>\n"; |
# First, the @StudentData fields need to be listed |
# First, the @StudentData fields need to be listed |
my @to_show = @Apache::lonstatistics::SelectedStudentData; |
my @to_show = &get_student_fields_to_show(); |
foreach (@to_show) { |
|
if ($_ eq 'all') { |
|
@to_show = @Apache::lonstatistics::StudentDataOrder; |
|
last; |
|
} |
|
} |
|
foreach my $field (@to_show) { |
foreach my $field (@to_show) { |
my $title=$Apache::lonstatistics::StudentData{$field}->{'title'}; |
my $title=$Apache::lonstatistics::StudentData{$field}->{'title'}; |
my $base =$Apache::lonstatistics::StudentData{$field}->{'base_width'}; |
my $base =$Apache::lonstatistics::StudentData{$field}->{'base_width'}; |
Line 249 sub CreateTableHeadings {
|
Line 420 sub CreateTableHeadings {
|
$Str .= $title.' 'x($width-$base).$padding; |
$Str .= $title.' 'x($width-$base).$padding; |
} |
} |
# Now the selected sequences need to be listed |
# Now the selected sequences need to be listed |
foreach my $map_symb (@Apache::lonstatistics::SelectedMaps) { |
foreach my $sequence (&get_sequences_to_show) { |
foreach my $sequence (@Apache::lonstatistics::Sequences) { |
my $title = $sequence->{'title'}; |
next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all'); |
my $base = $sequence->{'base_width'}; |
next if ($sequence->{'num_assess'} < 1); |
my $width = $sequence->{'width'}; |
my $title = $sequence->{'title'}; |
$Str .= $title.' 'x($width-$base).$padding; |
my $base = $sequence->{'base_width'}; |
|
my $width = $sequence->{'width'}; |
|
$Str .= $title.' 'x($width-$base).$padding; |
|
} |
|
} |
} |
$Str .= 'total'; |
$Str .= "total (of shown problems)</pre>\n"; |
$Str .= "</pre>\n"; |
$Str .= "<pre>"; |
return $Str; |
$r->print($Str); |
|
$r->rflush(); |
|
return; |
} |
} |
|
|
####################################################### |
sub html_outputstudent { |
####################################################### |
my ($r,$student) = @_; |
|
|
=pod |
|
|
|
=item &ChartOutputStudent($student) |
|
|
|
Return a line of the chart for a student. |
|
|
|
=cut |
|
|
|
####################################################### |
|
####################################################### |
|
sub ChartOutputStudent { |
|
my $student = shift; |
|
my $Str = ''; |
my $Str = ''; |
# First, the @StudentData fields need to be listed |
# First, the @StudentData fields need to be listed |
my @to_show = @Apache::lonstatistics::SelectedStudentData; |
my @to_show = &get_student_fields_to_show(); |
foreach (@to_show) { |
|
if ($_ eq 'all') { |
|
@to_show = @Apache::lonstatistics::StudentDataOrder; |
|
last; |
|
} |
|
} |
|
foreach my $field (@to_show) { |
foreach my $field (@to_show) { |
my $title=$student->{$field}; |
my $title=$student->{$field}; |
my $base =scalar(my @Tmp = split(//,$title)); |
my $base = length($title); |
my $width=$Apache::lonstatistics::StudentData{$field}->{'width'}; |
my $width=$Apache::lonstatistics::StudentData{$field}->{'width'}; |
$Str .= $title.' 'x($width-$base).$padding; |
$Str .= $title.' 'x($width-$base).$padding; |
} |
} |
Line 304 sub ChartOutputStudent {
|
Line 454 sub ChartOutputStudent {
|
} |
} |
if (scalar(@tmp) < 1) { |
if (scalar(@tmp) < 1) { |
$Str .= '<font color="blue">No Course Data</font>'."\n"; |
$Str .= '<font color="blue">No Course Data</font>'."\n"; |
return $Str; |
$r->print($Str); |
|
$r->rflush(); |
|
return; |
} |
} |
# |
# |
# By sequence build up the data |
# By sequence build up the data |
my $studentstats; |
my $studentstats; |
foreach my $map_symb (@Apache::lonstatistics::SelectedMaps) { |
my $PerformanceStr = ''; |
foreach my $seq (@Apache::lonstatistics::Sequences) { |
foreach my $seq (&get_sequences_to_show) { |
next if ($map_symb ne $seq->{'symb'} && $map_symb ne 'all'); |
my ($performance,$score,$seq_max) = |
next if ($seq->{'num_assess'} < 1); |
&StudentPerformanceOnSequence($student,\%StudentsData, |
my ($performance,$score,$seq_max) = |
$seq,$show_links); |
&StudentPerformanceOnSequence($student,\%StudentsData, |
my $ratio = $score.'/'.$seq_max; |
$seq,'linkify'); |
# |
$Str .= $performance.$padding; |
if ($show eq 'totals') { |
$studentstats->{$seq->{'symb'}}->{'score'}= $score; |
$performance = ' 'x(length($seq_max)-length($score)).$ratio; |
$studentstats->{$seq->{'symb'}}->{'max'} = $seq_max; |
$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- |
|
length($ratio) |
|
).$ratio; |
} |
} |
|
# |
|
$Str .= $performance.$padding; |
|
# |
|
$studentstats->{$seq->{'symb'}}->{'score'}= $score; |
|
$studentstats->{$seq->{'symb'}}->{'max'} = $seq_max; |
} |
} |
# |
# |
# Total it up and store the statistics info. |
# Total it up and store the statistics info. |
Line 330 sub ChartOutputStudent {
|
Line 495 sub ChartOutputStudent {
|
$score += $seq_stats->{'score'}; |
$score += $seq_stats->{'score'}; |
$max += $seq_stats->{'max'}; |
$max += $seq_stats->{'max'}; |
} |
} |
my $scorelength = scalar(my @tmp1 = split(//,$score)); |
$Str .= ' '.' 'x(length($max)-length($score)).$score.'/'.$max; |
my $maxlength = scalar(my @tmp2 = split(//,$max)); |
|
$Str .= ' '.' 'x($maxlength-$scorelength).$score.'/'.$max; |
|
$Str .= " \n"; |
$Str .= " \n"; |
return $Str; |
$r->print($Str); |
|
# |
|
$count++; |
|
if($count % 5 == 0) { |
|
$r->print("</pre><pre>"); |
|
} |
|
# |
|
$r->rflush(); |
|
return; |
} |
} |
|
|
|
sub html_finish { |
|
my ($r) = @_; |
|
$r->print("</pre>\n"); |
|
$r->rflush(); |
|
return; |
|
} |
|
|
|
} |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
|
|
=pod |
=pod |
|
|
=back |
=head2 EXCEL subroutines |
|
|
|
=item &excel_initialize($r) |
|
|
|
=item &excel_outputstudent($r,$student) |
|
|
|
=item &excel_finish($r) |
|
|
|
=cut |
|
|
|
####################################################### |
|
####################################################### |
|
{ |
|
|
|
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) = @_; |
|
# |
|
$filename = '/prtspool/'. |
|
$ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. |
|
time.'_'.rand(1000000000).'.xls'; |
|
# |
|
$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 ; |
|
} |
|
# |
|
# 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_workbook->set_tempdir($Apache::lonnet::tmpdir); |
|
# |
|
# Add a worksheet |
|
my $sheetname = $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; |
|
if (length($sheetname) > 31) { |
|
$sheetname = substr($sheetname,0,31); |
|
} |
|
$excel_sheet = $excel_workbook->addworksheet($sheetname); |
|
# |
|
# 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("<h1>Compiling Excel spreadsheet for ". |
|
$studentcount.' student'); |
|
$r->print('s') if ($studentcount > 1); |
|
$r->print("</h1>\n"); |
|
$r->rflush(); |
|
# |
|
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. <br />\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('<br /><br />'. |
|
'<a href="'.$filename.'">Your Excel spreadsheet.</a>'."\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('<br />'.$total_time.' seconds total'); |
|
$r->rflush(); |
|
return; |
|
} |
|
|
|
} |
|
####################################################### |
|
####################################################### |
|
|
|
=pod |
|
|
|
=head2 CSV output routines |
|
|
|
=item &csv_initialize($r) |
|
|
|
=item &csv_outputstudent($r,$student) |
|
|
|
=item &csv_finish($r) |
|
|
=cut |
=cut |
|
|
####################################################### |
####################################################### |
####################################################### |
####################################################### |
|
{ |
|
|
|
sub csv_initialize{ |
|
my ($r) = @_; |
|
$r->print("<h1>Not implemented yet</h1>"); |
|
return; |
|
} |
|
|
|
sub csv_outputstudent { |
|
my ($r,$student) = @_; |
|
} |
|
|
|
sub csv_finish { |
|
my ($r) = @_; |
|
} |
|
|
} |
} |
|
|
Line 378 Inputs:
|
Line 772 Inputs:
|
####################################################### |
####################################################### |
sub StudentPerformanceOnSequence { |
sub StudentPerformanceOnSequence { |
my ($student,$studentdata,$seq,$links) = @_; |
my ($student,$studentdata,$seq,$links) = @_; |
|
$links = 'no' if (! defined($links)); |
my $Str = ''; |
my $Str = ''; |
my $output_width = 0; |
|
my ($sum,$max) = (0,0); |
my ($sum,$max) = (0,0); |
foreach my $resource (@{$seq->{'contents'}}) { |
foreach my $resource (@{$seq->{'contents'}}) { |
next if ($resource->{'type'} ne 'assessment'); |
next if ($resource->{'type'} ne 'assessment'); |
Line 426 sub StudentPerformanceOnSequence {
|
Line 820 sub StudentPerformanceOnSequence {
|
} |
} |
} |
} |
# |
# |
$output_width++; |
if ($links eq 'yes' && $symbol ne ' ') { |
if (defined($links) && $symbol ne ' ') { |
|
$symbol = '<a href="/adm/grades'. |
$symbol = '<a href="/adm/grades'. |
'?symb='.&Apache::lonnet::escape($resource->{'symb'}). |
'?symb='.&Apache::lonnet::escape($resource->{'symb'}). |
'&student='.$student->{'username'}. |
'&student='.$student->{'username'}. |
Line 438 sub StudentPerformanceOnSequence {
|
Line 831 sub StudentPerformanceOnSequence {
|
} |
} |
$Str .= $value; |
$Str .= $value; |
} |
} |
# Put on the totals |
|
my $ratio = $sum.'/'.$max; |
|
my $ratio_length = scalar(my @tmp1 = split(//,$ratio)); |
|
# Pad with extra spaces |
|
my $width = $seq->{'width'}; |
|
$Str .= ' 'x($width-$output_width-$ratio_length).$ratio; |
|
# |
|
return ($Str,$sum,$max); |
return ($Str,$sum,$max); |
} |
} |
|
|