--- loncom/interface/statistics/lonstudentsubmissions.pm 2004/08/31 15:22:51 1.13
+++ loncom/interface/statistics/lonstudentsubmissions.pm 2004/09/23 13:50:45 1.22
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstudentsubmissions.pm,v 1.13 2004/08/31 15:22:51 matthew Exp $
+# $Id: lonstudentsubmissions.pm,v 1.22 2004/09/23 13:50:45 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -38,15 +38,10 @@ use HTML::Entities();
use Time::Local();
use Spreadsheet::WriteExcel();
-my @SubmitButtons = ({ name => 'PrevProblem',
- text => 'Previous Problem' },
- { name => 'NextProblem',
- text => 'Next Problem' },
- { name => 'break'},
- { name => 'SelectAnother',
+my @SubmitButtons = ({ name => 'SelectAnother',
text => 'Choose a different Problem' },
{ name => 'Generate',
- text => 'Generate Spreadsheet'},
+ text => 'Generate Report'},
);
sub BuildStudentSubmissionsPage {
@@ -72,7 +67,8 @@ sub BuildStudentSubmissionsPage {
}
#
my @CacheButtonHTML =
- &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');
+ &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status',
+ '
'.&mt('Loading student data').'
');
$r->rflush();
#
if (exists($ENV{'form.problemchoice'}) &&
@@ -90,110 +86,445 @@ sub BuildStudentSubmissionsPage {
$r->print($html.(' 'x5));
}
#
- $r->print('');
+ $r->print(''.$/);
$r->rflush();
#
- # Determine which problem we are to analyze
- my $current_problem = &Apache::lonstathelpers::get_target_from_id
- ($ENV{'form.problemchoice'});
- #
- my ($prev,$curr,$next) =
- &Apache::lonstathelpers::get_prev_curr_next($current_problem,
- '.',
- 'response',
- );
- if (exists($ENV{'form.PrevProblem'}) && defined($prev)) {
- $current_problem = $prev;
- } elsif (exists($ENV{'form.NextProblem'}) && defined($next)) {
- $current_problem = $next;
- } else {
- $current_problem = $curr;
+ # Determine which problems we are to analyze
+ my @Symbs =
+ &Apache::lonstathelpers::get_selected_symbs('problemchoice');
+ foreach my $selected (@Symbs) {
+ $r->print(''.$/);
}
#
- # Store the current problem choice and send it out in the form
- $ENV{'form.problemchoice'} =
- &Apache::lonstathelpers::make_target_id($current_problem);
- $r->print('');
+ # Get resource objects
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (!defined($navmap)) {
+ $r->print('
'.&mt("Internal error").'
');
+ return;
+ }
+ my %already_seen;
+ my @Problems;
+ foreach my $symb (@Symbs) {
+ my $resource = $navmap->getBySymb($symb);
+ push(@Problems,$resource);
+ }
#
- if (! defined($current_problem->{'resource'})) {
+ if (! scalar(@Problems) || ! defined($Problems[0])) {
$r->print('resource is undefined');
} else {
- my $resource = $current_problem->{'resource'};
- $r->print('
'.$resource->{'title'}.'
');
- $r->print('
'.$resource->{'src'}.'
');
- $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,
- $ProblemData,\@Students);
+ if (scalar(@Problems) == 1) {
+ my $resource = $Problems[0];
+ $r->print('
}.
+ $headers{'response'};
+ }
+ my $full_header = $/.'
'.$/;
+ $full_header .= '
'.$headers{'problem'}.'
'.$/;
+ if ($nonempty_part_headers) {
+ $full_header .= '
'.$headers{'part'}.'
'.$/;
+ }
+ $full_header .= '
'.$headers{'response'}.'
'.$/;
+ $full_header .= '
'.$headers{'student'}.'
'.$/;
+ #
+ # Main loop
+ my $count;
+ $r->print($/.$full_header.$/);
+ my $row_class = 'odd'; # css
+ foreach my $student (@$students) {
+ my $student_row_data;
+ if ($count++ >= 30) {
+ $r->print('
'.$/.$full_header.$/);
+ $count = 0;
+ }
+ last if ($c->aborted());
+ foreach my $field (@student_columns) {
+ $student_row_data .=
+ '
'.$student->{$field}.'
';
+ }
+ #
+ # Figure out what it is we need to output for this student
+ my @essays;
+ my %problem_data;
+ my $maxrow;
+ foreach my $prob (@$problems) {
+ my $symb = $prob->symb;
+ $problem_data{$symb}={};
+ foreach my $partid (@{$prob->parts}) {
+ my @responses = $prob->responseIds($partid);
+ my @response_type = $prob->responseType($partid);
+ for (my $i=0;$i<=$#responses;$i++) {
+ my $respid = $responses[$i];
+ my $resptype = $response_type[$i];
+ my $width = scalar(@response_headers);
+ $problem_data{$symb}->{$partid}->{$respid}={};
+ my $resp_data = $problem_data{$symb}->{$partid}->{$respid};
+ $resp_data->{'fake'} = qq{
 
};
+ my $results =
+ &Apache::loncoursedata::get_response_data_by_student
+ ($student,$prob->symb(),$respid);
+ if (! defined($results)) {
+ $results = [];
+ }
+ #
+ if (scalar(@$results) > $maxrow && $resptype ne 'essay') {
+ $maxrow = scalar(@$results);
+ }
+ for (my $j=scalar(@$results)-1;$j>=0;$j--) {
+ my $response = $results->[$j];
+ if ($ENV{'form.all_sub'} ne 'true') {
+ next if ($j ne scalar(@$results)-1);
+ }
+ if ($resptype eq 'essay') {
+ push(@essays,
+ &html_essay_results($student,
+ $prob,$partid,$respid,
+ $response,
+ $single_response).
+ '');
+ } else {
+ push(@{$resp_data->{'real'}},
+ &html_results($student,
+ $prob,$partid,$respid,
+ $response,$resptype));
+ }
+ }
+ } # end of $i loop
+ } # end of partid loop
+ } # end of prob loop
+ #
+ # if there is no data, skip this student.
+ next if (! $maxrow && ! scalar(@essays));
+ #
+ # Go through the problem data and output a row.
+ if ($row_class eq 'even') {
+ $row_class = 'odd';
+ } else {
+ $row_class = 'even';
+ }
+ my $printed_something;
+ for (my $rows_output = 0;$rows_output<$maxrow;$rows_output++) {
+ my $html;
+ my $no_data = 1;
+ foreach my $prob (@$problems) {
+ my $symb = $prob->symb;
+ foreach my $partid (@{$prob->parts}) {
+ my @responses = $prob->responseIds($partid);
+ my @response_type = $prob->responseType($partid);
+ for (my $i=0;$i<=$#responses;$i++) {
+ my $respid = $responses[$i];
+ my $resp_data =
+ $problem_data{$symb}->{$partid}->{$respid};
+ next if ($response_type[$i] eq 'essay');
+ if (defined($resp_data->{'real'}->[$rows_output])) {
+ $html .= $resp_data->{'real'}->[$rows_output];
+ $no_data = 0;
+ } else {
+ $html .= $resp_data->{'fake'};
+ }
+ }
+ }
+ }
+ if (! $no_data) {
+ $r->print(qq{
$student_row_data$html
}.$/);
+ $printed_something=1;
+ }
+ }
+ if (@essays) {
+ my $tr = qq{
};
+ my $td = qq{
};
+ if (! $printed_something) {
+ $r->print($tr.$student_row_data.'
';
+ }
+ return $submission;
+}
+
+#########################################################
+#########################################################
+##
+## Excel Output Routines
+##
+#########################################################
+#########################################################
+sub prepare_excel_output {
+ my ($r,$Problems,$Students) = @_;
+ my $c = $r->connection();
+ #
+ #
+ # Determine the number of columns in the spreadsheet
+ my $columncount = 3; # username, domain, id
+ my $response_multiplier = 1;
+ $response_multiplier ++ if ($ENV{'form.correctans'} eq 'true');
+ $response_multiplier += 4 if ($ENV{'form.prob_status'} eq 'true');
+ my $lastprob;
+ foreach my $prob (@$Problems) {
+ $columncount += ($response_multiplier * $prob->countResponses);
+ last if ($columncount > 255);
+ $lastprob = $prob;
+ }
+ if ($columncount > 255) {
+ $r->print('
'.&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('Consider selecting fewer problems to generate reports on, or reducing the number of items per problem. Or use HTML or CSV output.').'
'.$/.
+ '
'.&mt('The last problem that will fit in the current spreadsheet is [_1].',&get_title($lastprob->title,$lastprob->src)).'
');
+ $r->rflush();
+ return;
+ }
+ #
+ # Print out a message telling them what we are doing
+ if (scalar(@$Problems) > 1) {
+ $r->print('
'.
+ &mt('Preparing Excel spreadsheet of student responses to [_1] problems',
+ scalar(@$Problems)).
+ '