[LON-CAPA-cvs] cvs: loncom /interface/statistics lonstudentsubmissions.pm
matthew
lon-capa-cvs@mail.lon-capa.org
Wed, 01 Sep 2004 21:13:04 -0000
This is a MIME encoded message
--matthew1094073184
Content-Type: text/plain
matthew Wed Sep 1 17:13:04 2004 EDT
Modified files:
/loncom/interface/statistics lonstudentsubmissions.pm
Log:
The beginnings of extensive HTML output.
Still in hack phase of development. The code is ugly, the output
is broken, and I'm going to rewrite it but I need a backup made now.
--matthew1094073184
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20040901171304.txt"
Index: loncom/interface/statistics/lonstudentsubmissions.pm
diff -u loncom/interface/statistics/lonstudentsubmissions.pm:1.14 loncom/interface/statistics/lonstudentsubmissions.pm:1.15
--- loncom/interface/statistics/lonstudentsubmissions.pm:1.14 Tue Aug 31 11:52:13 2004
+++ loncom/interface/statistics/lonstudentsubmissions.pm Wed Sep 1 17:13:04 2004
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstudentsubmissions.pm,v 1.14 2004/08/31 15:52:13 matthew Exp $
+# $Id: lonstudentsubmissions.pm,v 1.15 2004/09/01 21:13:04 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -122,15 +122,19 @@
my $resource = $current_problem->{'resource'};
$r->print('<h1>'.$resource->{'title'}.'</h1>');
$r->print('<h3>'.$resource->{'src'}.'</h3>');
- $r->print(&Apache::lonstathelpers::render_resource($resource));
+ if ($ENV{'form.renderprob'} eq 'true') {
+ $r->print(&Apache::lonstathelpers::render_resource($resource));
+ }
$r->rflush();
my %Data = &Apache::lonstathelpers::get_problem_data
($resource->{'src'});
my $ProblemData = $Data{$current_problem->{'part'}.
'.'.
$current_problem->{'respid'}};
- &prepare_excel_output($r,$current_problem,
+ &prepare_html_output($r,$current_problem,
$ProblemData,\@Students);
+# &prepare_excel_output($r,$current_problem,
+# $ProblemData,\@Students);
}
$r->print('<hr />');
} else {
@@ -145,6 +149,432 @@
#########################################################
#########################################################
##
+## prepare_html_output
+##
+#########################################################
+#########################################################
+sub prepare_html_output {
+ my ($r,$problem,$ProblemData,$Students) = @_;
+ my $c = $r->connection();
+ my ($resource,$respid,$partid) = ($problem->{'resource'},
+ $problem->{'respid'},
+ $problem->{'part'});
+ $r->print('<h2>'.&mt('Student Responses').'</h2>');
+ #
+ if ($ENV{'form.correctans'} eq 'true') {
+ &Apache::lonstathelpers::GetStudentAnswers($r,$problem,$Students,
+ 'Statistics',
+ 'stats_status');
+ }
+ #
+ $r->rflush();
+ my $response_type;
+ for (my $i=0;
+ $i<scalar(@{$resource->{'partdata'}->{$partid}->{'ResponseIds'}});
+ $i++) {
+ if($resource->{'partdata'}->{$partid}->{'ResponseIds'}->[$i] eq $respid){
+ $response_type =
+ $resource->{'partdata'}->{$partid}->{'ResponseTypes'}->[$i];
+ last;
+ }
+ }
+ if (! defined($response_type)) {
+ $r->print('<h2>'.&mt('Unable to determine response type').'</h2>');
+ } else {
+ my $count = 0;
+ my $header;
+ if ($response_type eq 'essay') {
+ $header = &html_essay_header();
+ } elsif ($response_type eq 'radiobutton') {
+ $header = &html_radiobutton_header();
+ } elsif ($response_type eq 'option') {
+ $header = &html_option_header();
+ } else {
+ $header = &html_generic_header();
+ }
+ $header = '<tr>'.$header.'</tr>';
+ #
+ $r->print($/.'<table>'.$/.$header.$/);
+ foreach my $student (@$Students) {
+ if ($count >= 50) {
+ $r->print('</table>'.$/.'<table>'.$/.$header.$/);
+ $count = 0;
+ }
+ last if ($c->aborted());
+ my $results = &Apache::loncoursedata::get_response_data_by_student
+ ($student,$resource->{'symb'},$respid);
+ next if (! defined($results) || ref($results) ne 'ARRAY');
+ for (my $i=0;$i<scalar(@$results);$i++) {
+ my $response = $results->[$i];
+ if ($ENV{'form.last_sub_only'} eq 'true' &&
+ $i < (scalar(@$results)-1)) {
+ next;
+ }
+ my $data;
+ $data->{'sname'} = $student->{'username'}.'@'.
+ $student->{'domain'};
+ $data->{'time'} = &Apache::lonlocal::locallocaltime
+ ($response->[&Apache::loncoursedata::RDs_timestamp()]);
+ $data->{'attempt'} =
+ $response->[&Apache::loncoursedata::RDs_tries()];
+ $data->{'submission'} =
+ $response->[&Apache::loncoursedata::RDs_submission()];
+ $data->{'correct'} = $student->{'answer'};
+ my $row;
+ if ($response_type eq 'essay') {
+ $row = &html_essay($data);
+ } elsif ($response_type eq 'radiobutton') {
+ $row = &html_radiobutton($data);
+ } elsif ($response_type eq 'option') {
+ $row = &html_option($data);
+ } else {
+ $row = &html_generic($data);
+ }
+ $r->print($row.$/);
+ $count++;
+ }
+ }
+ $r->print('</table>'.$/);
+ }
+ return;
+}
+
+#####################################################
+##
+## HTML helper routines
+##
+#####################################################
+my @FullHeaders = (
+ {name=>'sname',
+ display=>'Student'},
+ {name => 'id',
+ display => 'Id'},
+ {name => 'time',
+ display =>'Time'},
+ {name => 'attempt',
+ display =>'Attempt'},
+ {name => 'grading',
+ display =>'Grading'},
+ );
+
+sub html_essay_header {
+ my $header;
+ if ($ENV{'form.subdata'} eq 'true') {
+ foreach (@FullHeaders) {
+ $header .= '<th>'.&mt($_->{'display'}).'</th>';
+ }
+ } else {
+ $header = '<th>'.&mt('Username and Submission').'</th>';
+ }
+ return $header;
+}
+
+sub html_essay {
+ my ($data)=@_;
+ #
+ $data->{'submission'} =~ s|\\r\\n|$/|g;
+ $data->{'submission'} =
+ &HTML::Entities::encode($data->{'submission'},'<>&"');
+ $data->{'submission'} =~ s|$/\s*$/|$/</p><p>$/|g;
+ $data->{'submission'} =~ s|\\||g;
+ $data->{'submission'} = '<p>'.$data->{'submission'}.'</p>';
+ #
+ my $Str = '<tr>';
+ if ($ENV{'form.subdata'} eq 'true') {
+ $Str .=
+ '<td><b>'.$data->{'sname'}.'</b></td>'.
+ '<td>'.$data->{'time'}.'</td>'.
+ '<td>'.$data->{'attempt'}.'</td>';
+ $Str .= '</tr>';
+ $Str .= '<tr><td colspan="'.scalar(@FullHeaders).'">'.
+ $data->{'submission'}.'</td>';
+ } else {
+ $Str .= '<td><b>'.$data->{'sname'}.'</b>'.
+ $data->{'submission'}.'</td>';
+ }
+ if ($ENV{'form.correctans'} eq 'true') {
+ $Str .= '</tr>';
+ if (defined($data->{'correct'}) && $data->{'correct'} !~ /^\s*$/) {
+ $Str .= '<tr><td colspan="'.scalar(@FullHeaders).'">'.
+ '<b>'.&mt('Correct Answer:').'</b>'.$data->{'correct'}.'</td>';
+ }
+ }
+ $Str .= '</tr>';
+ #
+ return $Str;
+}
+
+sub html_radiobutton_header {
+ my $header;
+ if ($ENV{'form.subdata'} eq 'true') {
+ foreach (@FullHeaders) {
+ $header .= '<th>'.&mt($_->{'display'}).'</th>';
+ }
+ } else {
+ $header =
+ '<th>'.&mt('Username').'</th>';
+ }
+ $header .='<th>'.&mt('Submission').'</th>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $header .= '<th>'.&mt('Correct').'</th>';
+ }
+ return $header;
+}
+
+sub html_radiobutton {
+ my ($data)=@_;
+ #
+ $data->{'submission'} =~ s/=([^=])$//;
+ #
+ my $Str = '<tr>';
+ if ($ENV{'form.subdata'} eq 'true') {
+ $Str .=
+ '<td>'.'<b>'.$data->{'sname'}.'</b></td>'.
+ '<td>'.$data->{'time'}.'</td>'.
+ '<td>'.$data->{'attempt'}.'</td>';
+ $Str .= '<td>'.$data->{'submission'}.'</td>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $Str .= '<td>'.$data->{'correct'}.'</td>';
+ }
+ } else {
+ $Str .= '<td><b>'.$data->{'sname'}.'</b></td>';
+ $Str .= '<td>'.$data->{'submission'}.'</td>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $Str .= '<td>'.$data->{'correct'}.'</td>';
+ }
+ }
+ $Str .= '</tr>';
+ #
+ return $Str;
+}
+
+sub html_generic_header {
+ my $header;
+ if ($ENV{'form.subdata'} eq 'true') {
+ foreach (@FullHeaders) {
+ $header .= '<th>'.&mt($_->{'display'}).'</th>';
+ }
+ } else {
+ $header =
+ '<th>'.&mt('Username').'</th>';
+ }
+ $header .= '<th>'.&mt('Submission').'</th>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $header .= '<th>'.&mt('Correct').'</th>';
+ }
+ return $header;
+}
+
+sub html_generic {
+ my ($data)=@_;
+ $data->{'submission'} = &Apache::lonnet::unescape($data->{'submission'});
+ my $Str = '<tr>';
+ if ($ENV{'form.subdata'} eq 'true') {
+ $Str .=
+ '<td><b>'.$data->{'sname'}.'</b></td>'.
+ '<td>'.$data->{'time'}.'</td>'.
+ '<td>'.$data->{'attempt'}.'</td>';
+ } else {
+ $Str .= '<td><b>'.$data->{'sname'}.'</b></td>';
+ }
+ $Str .= '<td>'.$data->{'submission'}.'</td>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $Str .= '<td>'.$data->{'correct'}.'</td>';
+ }
+ $Str .= '</tr>';
+ return $Str;
+}
+
+sub html_option_header {
+ my $header;
+ if ($ENV{'form.subdata'} eq 'true') {
+ foreach (@FullHeaders) {
+ $header .= '<th>'.&mt($_->{'display'}).'</th>';
+ }
+ } else {
+ $header =
+ '<th>'.&mt('Username').'</th>';
+ }
+ $header .= '<th>'.&mt('Submission').'</th>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $header .= '<th>'.&mt('Correct').'</th>';
+ }
+ return $header;
+}
+
+sub html_option {
+ my ($data)=@_;
+ $data->{'submission'} = '<ul class="studentans">'.
+ '<li>'.join('</li><li>',
+ map {
+ &Apache::lonnet::unescape($_) ;
+ } sort split('&',$data->{'submission'})).
+ '</li><ul>';
+ $data->{'correct'} = '<ul class="correctans">'.
+ '<li>'.join('</li><li>',
+ map {
+ &Apache::lonnet::unescape($_) ;
+ } sort split('&',$data->{'correct'})).'</li></ul>';
+ my $Str = '<tr>';
+ if ($ENV{'form.subdata'} eq 'true') {
+ $Str .=
+ '<td><b>'.$data->{'sname'}.'</b></td>'.
+ '<td>'.$data->{'time'}.'</td>'.
+ '<td>'.$data->{'attempt'}.'</td>';
+ } else {
+ $Str .= '<td><b>'.$data->{'sname'}.'</b></td>';
+ }
+ $Str .= '<td>'.$data->{'submission'}.'</td>';
+ if ($ENV{'form.correctans'} eq 'true') {
+ $Str .= '<td>'.$data->{'correct'}.'</td>';
+ }
+ $Str .= '</tr>';
+ return $Str;
+}
+
+
+=pod
+
+ my @Columns;
+ push(@Columns,'username');
+ push(@Columns,'domain');
+ push(@Columns,'attempt');
+ push(@Columns,'time');
+ push(@Columns,'submission');
+ if ($ENV{'form.correctans'} eq 'true') { push(@Columns,'correct'); }
+ push(@Columns,'grading');
+ push(@Columns,'awarded');
+ my $awarded_col = $#Columns;
+ push(@Columns,'weight');
+ my $weight_col = $#Columns;
+ push(@Columns,'score');
+ #
+ # Create excel worksheet
+ my $filename = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.xls';
+ my $workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
+ if (! defined($workbook)) {
+ $r->log_error("Error creating excel spreadsheet $filename: $!");
+ $r->print('<p>'.&mt("Unable to create new Excel file. ".
+ "This error has been logged. ".
+ "Please alert your LON-CAPA administrator").
+ '</p>');
+ return undef;
+ }
+ #
+ $workbook->set_tempdir('/home/httpd/perl/tmp');
+ #
+ my $format = &Apache::loncommon::define_excel_formats($workbook);
+ my $worksheet = $workbook->addworksheet('Student Submission Data');
+ #
+ # Make sure we get new weight data instead of data on a 10 minute delay
+ &Apache::lonnet::clear_EXT_cache_status();
+ #
+ # Put on the standard headers and whatnot
+ my $rows_output=0;
+ $worksheet->write($rows_output++,0,$resource->{'title'},$format->{'h1'});
+ $worksheet->write($rows_output++,0,$resource->{'src'},$format->{'h3'});
+ $rows_output++;
+ $worksheet->write_row($rows_output++,0,\@Columns,$format->{'bold'});
+ #
+ # Populate the worksheet with the student data
+ foreach my $student (@$Students) {
+ last if ($c->aborted());
+ my $results = &Apache::loncoursedata::get_response_data_by_student
+ ($student,$resource->{'symb'},$respid);
+ my %row;
+ $row{'username'} = $student->{'username'};
+ $row{'domain'} = $student->{'domain'};
+ $row{'correct'} = $student->{'answer'};
+ $row{'weight'} = &Apache::lonnet::EXT
+ ('resource.'.$partid.'.weight',$resource->{'symb'},
+ undef,undef,undef);
+ if (! defined($results) || ref($results) ne 'ARRAY') {
+ $row{'score'} = '='.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($rows_output,$awarded_col)
+ .'*'.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($rows_output,$weight_col);
+ my $cols_output = 0;
+ foreach my $col (@Columns) {
+ if (! exists($row{$col})) {
+ $cols_output++;
+ next;
+ }
+ $worksheet->write($rows_output,$cols_output++,$row{$col});
+ }
+ $rows_output++;
+ } else {
+ for (my $i=0;$i<scalar(@$results);$i++) {
+ my $response = $results->[$i];
+ if ($ENV{'form.last_sub_only'} eq 'true' &&
+ $i < (scalar(@$results)-1)) {
+ next;
+ }
+ delete($row{'time'});
+ delete($row{'attempt'});
+ delete($row{'submission'});
+ delete($row{'awarded'});
+ delete($row{'grading'});
+ delete($row{'score'});
+ my %row_format;
+ #
+ # Time is handled differently
+ $row{'time'} = &Apache::lonstathelpers::calc_serial
+ ($response->[&Apache::loncoursedata::RDs_timestamp()]);
+ $row_format{'time'}=$format->{'date'};
+ #
+ $row{'attempt'} = $response->[
+ &Apache::loncoursedata::RDs_tries()];
+ $row{'submission'} = $response->[
+ &Apache::loncoursedata::RDs_submission()];
+ if ($row{'submission'} =~ m/^=/) {
+ # This will be interpreted as a formula. That is bad!
+ $row{'submission'} = " ".$row{'submission'};
+ }
+ $row{'grading'} = $response->[
+ &Apache::loncoursedata::RDs_awarddetail()];
+ $row{'awarded'} = $response->[
+ &Apache::loncoursedata::RDs_awarded()];
+ $row{'score'} = '='.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($rows_output,$awarded_col)
+ .'*'.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($rows_output,$weight_col);
+ my $cols_output = 0;
+ foreach my $col (@Columns) {
+ $worksheet->write($rows_output,$cols_output++,$row{$col},
+ $row_format{$col});
+ }
+ $rows_output++;
+ }
+ } # End of else clause on if (! defined($results) ....
+ }
+ #
+ # Close the excel file
+ $workbook->close();
+ #
+ # Write a link to allow them to download it
+ $r->print('<p><a href="'.$filename.'">'.
+ &mt('Your Excel spreadsheet.').
+ '</a></p>'."\n");
+ $r->print('<script>'.
+ 'window.document.Statistics.stats_status.value="'.
+ 'Done compiling spreadsheet. See link below to download.'.
+ '";</script>');
+ $r->rflush();
+ return;
+
+}
+
+=cut
+
+#########################################################
+#########################################################
+##
## Excel output of student answers and correct answers
##
#########################################################
@@ -245,7 +675,12 @@
}
$rows_output++;
} else {
- foreach my $response (@$results) {
+ for (my $i=0;$i<scalar(@$results);$i++) {
+ my $response = $results->[$i];
+ if ($ENV{'form.last_sub_only'} eq 'true' &&
+ $i < (scalar(@$results)-1)) {
+ next;
+ }
delete($row{'time'});
delete($row{'attempt'});
delete($row{'submission'});
@@ -299,7 +734,7 @@
'Done compiling spreadsheet. See link below to download.'.
'";</script>');
$r->rflush();
-
+ return;
}
#########################################################
@@ -331,13 +766,45 @@
$Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
$Str .= '</td>';
#
- my $checkbox = '<input type="checkbox" name="correctans" ';
+ # Render problem checkbox
+ my $prob_checkbox = '<input type="checkbox" name="renderprob" ';
+ if (exists($ENV{'form.renderprob'}) && $ENV{'form.renderprob'} eq 'true') {
+ $prob_checkbox .= 'checked ';
+ }
+ $prob_checkbox .= 'value="true" />';
+ #
+ # Compute correct answers checkbox
+ my $ans_checkbox = '<input type="checkbox" name="correctans" ';
if (exists($ENV{'form.correctans'}) && $ENV{'form.correctans'} eq 'true') {
- $checkbox .= ' checked ';
+ $ans_checkbox .= 'checked ';
}
- $checkbox .= 'value="true" />';
- $Str .= '<td align="center">'.'<label><b>'.
- &mt('compute correct answers [_1]',$checkbox).'</b></label>'.'</td>';
+ $ans_checkbox .= 'value="true" />';
+ #
+ # Only show last submission checkbox
+ my $last_sub_checkbox = '<input type="checkbox" name="last_sub_only" ';
+ if (exists($ENV{'form.last_sub_only'}) &&
+ $ENV{'form.last_sub_only'} eq 'true') {
+ $last_sub_checkbox .= 'checked ';
+ }
+ $last_sub_checkbox.= 'value="true" />';
+ #
+ # extra submission data checkbox
+ my $subdata_checkbox = '<input type="checkbox" name="subdata" ';
+ if (exists($ENV{'form.subdata'}) &&
+ $ENV{'form.subdata'} eq 'true') {
+ $subdata_checkbox .= 'checked ';
+ }
+ $subdata_checkbox.= 'value="true" />';
+ #
+ $Str .= '<td align="right" halign="top">'.'<label><b>'.
+ &mt('show problem [_1]',$prob_checkbox).'</b></label><br />'.
+ '<label><b>'.
+ &mt('compute correct answers [_1]',$ans_checkbox).'</b></label><br />'.
+ '<label><b>'.
+ &mt('final answer only [_1]',$last_sub_checkbox).'</b></label><br />'.
+ '<label><b>'.&mt('show extra submission data [_1]',$subdata_checkbox).
+ '</b></label><br />'.
+ '</td>';
#
$Str .= '</tr>'."\n";
$Str .= '</table>'."\n";
@@ -350,8 +817,6 @@
return $Str;
}
-
-
1;
__END__
--matthew1094073184--