--- loncom/interface/statistics/lonstudentsubmissions.pm 2004/09/22 15:38:49 1.21 +++ 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.21 2004/09/22 15:38:49 matthew Exp $ +# $Id: lonstudentsubmissions.pm,v 1.22 2004/09/23 13:50:45 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -126,6 +126,8 @@ sub BuildStudentSubmissionsPage { } if ($ENV{'form.output'} eq 'excel') { &prepare_excel_output($r,\@Problems,\@Students); + } elsif ($ENV{'form.output'} eq 'csv') { + &prepare_csv_output($r,\@Problems,\@Students); } else { &prepare_html_output($r,\@Problems,\@Students); } @@ -723,41 +725,6 @@ sub excel_format_response { return $answer; } -## -## Currently not used -sub get_problem_data { - my ($r,$Problems) = @_; - # - # Analyze - my %Data; - if (scalar(@$Problems) > 5) { - # progress window - my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin - ($r,'Problem Analysis Status', - 'Problem Analysis Progress', - scalar(@$Problems), - 'inline',undef,'Statistics','stats_status'); - foreach my $problem (@$Problems) { - $Data{$problem->symb} = - {&Apache::lonstathelpers::get_problem_data - ($problem->src)}; - &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, - 'last problem'); - } - &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); - } else { - foreach my $problem (@$Problems) { - $Data{$problem->symb} = - {&Apache::lonstathelpers::get_problem_data - ($problem->src)}; - } - } - return \%Data; -} - - -=pod - ######################################################### ######################################################### ## @@ -766,20 +733,8 @@ sub get_problem_data { ######################################################### ######################################################### sub prepare_csv_output { - my ($r,$Problems,$Students) = @_; - my $problem; - # + my ($r,$problems,$students) = @_; my $c = $r->connection(); - my ($resource,$respid,$partid) = ($problem->{'resource'}, - $problem->{'respid'}, - $problem->{'part'}); - # - if ($ENV{'form.correctans'} eq 'true') { - $r->print('

'.&mt('Generating Correct Answers').'

'); - &Apache::lonstathelpers::GetStudentAnswers($r,$problem,$Students, - 'Statistics', - 'stats_status'); - } # $r->print('

'. &mt('Generating CSV report of student responses').'

'); @@ -788,8 +743,8 @@ sub prepare_csv_output { my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin ($r,'CSV File Compilation Status', 'CSV File Compilation Progress', - scalar(@$Students),'inline',undef,'Statistics','stats_status'); - + scalar(@$students),'inline',undef,'Statistics','stats_status'); + $r->rflush(); # # Open a file @@ -805,80 +760,110 @@ sub prepare_csv_output { $outputfile = undef; } # + # Compute the number of columns per response + my @response_headers = ('Submission'); + if ($ENV{'form.correctans'} eq 'true') { + push(@response_headers,'Correct'); + } + if ($ENV{'form.prob_status'} eq 'true') { + push(@response_headers,'Award Detail'); + push(@response_headers,'Time'); + push(@response_headers,'Attempt'); + push(@response_headers,'Awarded'); + } + my $response_multiplier = scalar(@response_headers); + # + # Create the table header + my @student_columns = ('username','domain','id'); # - my @Columns; - if (exists($ENV{'form.concise'}) && $ENV{'form.concise'} eq 'true') { - foreach (@DefaultColumns) { - if ($_->{'name'} =~ /^(username|domain|id)$/){ - push(@Columns,$_); - } + my %headers; + push(@{$headers{'student'}},@student_columns); + # Pad for the student data + foreach my $row ('problem','part','response') { + foreach (@student_columns) { + push(@{$headers{$row}},''); } - } else { - @Columns = @DefaultColumns; } # - my $response_type = &get_response_type($resource,$partid,$respid); - if (! defined($response_type) || $response_type eq '') { - $r->print('

'.&mt('Unable to determine response type').'

'); - return; + # we put the headers into the %headers hash + my $prob_start_idx = 0; + foreach my $prob (@$problems) { + $headers{'problem'}->[$prob_start_idx] = + &get_title($prob->title,$prob->src); + my $part_start_idx = $prob_start_idx; + foreach my $partid (@{$prob->parts}) { + $headers{'part'}->[$part_start_idx] = &mt('Part [_1]',$partid); + my $responses = [$prob->responseIds($partid)]; + for (my $i=0;$i[$resp_idx]= + &mt('Response [_1]',$responses->[$i]); + for (my $j=0;$j<=$#response_headers;$j++) { + $headers{'student'}->[$resp_idx+$j]=$response_headers[$j]; + } + } + $part_start_idx += scalar(@$responses)*$response_multiplier; + } + $prob_start_idx += $prob->countResponses * $response_multiplier; + } + foreach my $row ('problem','part','response','student') { + print $outputfile '"'.join('","',map { ''; } @student_columns).'","'. + join('","', + map { + &Apache::loncommon::csv_translate($_); + } @{$headers{$row}}).'"'.$/; } # - my $header = &csv_headers(\@Columns).','.&csv_generic_headers(); - print $outputfile $header.$/; - # - foreach my $student (@$Students) { - 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[$i]; - if ($ENV{'form.last_sub_only'} eq 'true' && - $i < (scalar(@$results)-1)) { - next; - } - my $data; - $data->{'username'} = $student->{'username'}; - $data->{'domain'} = $student->{'domain'}; - $data->{'id'} = $student->{'id'}; - $data->{'fullname'} = $student->{'fullanem'}; - $data->{'status'} = $student->{'status'}; - $data->{'time'} = &Apache::lonlocal::locallocaltime - ($response->[&Apache::loncoursedata::RDs_timestamp()]); - $data->{'attempt'} = - $response->[&Apache::loncoursedata::RDs_tries()]; - $data->{'awarded'} = - $response->[&Apache::loncoursedata::RDs_awarded()]; - $data->{'awarddetail'} = - $response->[&Apache::loncoursedata::RDs_awarddetail()]; - $data->{'weight'} = &Apache::lonnet::EXT - ('resource.'.$partid.'.weight',$resource->{'symb'}, - undef,undef,undef); - $data->{'score'} = $data->{'weight'} * $data->{'awarded'}; - my $rowextra = ''; - my $row; - foreach my $col (@Columns) { - $row .= '"'. - &Apache::loncommon::csv_translate($data->{$col->{'name'}}).'",'; - } - if ($response_type eq 'option') { - $row .= &csv_option_results - ($response->[&Apache::loncoursedata::RDs_submission()], - $student->{'answer'}, - scalar(@Columns),$rowextra); - } elsif ($response_type eq 'radiobutton') { - $row .= &csv_radiobutton_results - ($response->[&Apache::loncoursedata::RDs_submission()], - $student->{'answer'}, - scalar(@Columns),$rowextra); - } else { - $row .= &csv_generic_results - ($response->[&Apache::loncoursedata::RDs_submission()], - $student->{'answer'}, - scalar(@Columns),$rowextra); + # Main loop + foreach my $student (@$students) { + my @rows; + my $prob_start_idx = 0; + foreach my $prob (@$problems) { + my $part_start_idx = 0; + foreach my $partid (@{$prob->parts}) { + my @responses = $prob->responseIds($partid); + my @response_type = $prob->responseType($partid); + for (my $i=0;$i<=$#responses;$i++) { + my $resp_start_idx = $response_multiplier * $i; + my $respid = $responses[$i]; + my $results = + &Apache::loncoursedata::get_response_data_by_student + ($student,$prob->symb(),$respid); + if (! defined($results)) { + $results = []; + } + for (my $j=0; $j[$idx]; + my @data = &compile_response_data($response,$student, + $prob,$partid, + $respid); + for (my $k=0;$k<=$#data;$k++) { + $rows[$j]->[$prob_start_idx + $part_start_idx + + $resp_start_idx + $k] = $data[$k]; + } + } + } + $part_start_idx += scalar(@responses)*$response_multiplier; + } + $prob_start_idx += $prob->countResponses * $response_multiplier; + } + foreach my $row (@rows) { + print $outputfile '"'.join('","', + map { $student->{$_}; } + @student_columns).'"'; + + for (my $i=0;$i<$prob_start_idx;$i++) { + my $value = &Apache::loncommon::csv_translate($row->[$i]); + $value ||=''; + print $outputfile ',"'.$value.'"'; } - print $outputfile $row.$/; + print $outputfile $/; } + undef(@rows); &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, 'last student'); } @@ -894,76 +879,26 @@ sub prepare_csv_output { return; } -sub csv_headers { - my ($Columns) = @_; - my $Str; - foreach my $column (@$Columns) { - $Str .= - '"'.&Apache::loncommon::csv_translate($column->{'display'}).'",'; - } - chop($Str); - return $Str; -} - -sub csv_generic_headers { - my ($title) = @_; - if (! defined($title)) { - $title = &mt('Submission'); - } - my $header = '"'.&Apache::loncommon::csv_translate($title).'"'; +sub compile_response_data { + my ($response,$student,$prob,$partid,$respid) = @_; + my @rowdata; + push(@rowdata,$response->[&Apache::loncoursedata::RDs_submission()]); if ($ENV{'form.correctans'} eq 'true') { - $header .= ',"'.&Apache::loncommon::csv_translate(&mt('Correct')).'"'; - } - return $header; -} - -#------------------------------------------ -sub csv_essay_results { - my ($submission,$correct,$tablewidth,$rowextra)=@_; - # - $submission =~ s|\\r|\\\\r|g; - $submission =~ s|\\n|\\\\n|g; - # - return &csv_generic_results($submission,$correct,$tablewidth); -} - -#------------------------------------------ -sub csv_radiobutton_results { - my ($submission,$correct,$tablewidth,$rowclass)=@_; - $submission =~ s/=[^=]*$//; - return &csv_generic_results($submission,$correct,$tablewidth,$rowclass); -} - -#------------------------------------------ -sub csv_option_results { - my ($submission,$correct,$tablewidth,$rowclass)=@_; - $submission = join(',', - map { - &Apache::lonnet::unescape($_) ; - } sort split('&',$submission) - ); - if (defined($correct) && $correct !~ /^\s*$/) { - $correct =join(',', - map { - &Apache::lonnet::unescape($_) ; - } sort split('&',$submission)); + my $correct = &Apache::lonstathelpers::analyze_problem_as_student + ($prob,$student->{'username'},$student->{'domain'}, + $partid,$respid); + push(@rowdata,$correct); } - return &csv_generic_results($submission,$correct,$tablewidth,$rowclass); -} - -#------------------------------------------ -sub csv_generic_results { - my ($submission,$correct,$tablewidth,$rowclass)=@_; - my $Str .= - '"'.&Apache::loncommon::csv_translate($submission).'"'; - if ($ENV{'form.correctans'} eq 'true') { - $Str .= ',"'.&Apache::loncommon::csv_translate($correct).'"'; + if ($ENV{'form.prob_status'}) { + push(@rowdata,$response->[&Apache::loncoursedata::RDs_awarddetail()]); + push(@rowdata,&Apache::lonlocal::locallocaltime + ($response->[&Apache::loncoursedata::RDs_timestamp()])); + push(@rowdata,$response->[&Apache::loncoursedata::RDs_tries()]); + push(@rowdata,$response->[&Apache::loncoursedata::RDs_awarded()]); } - return $Str; + return @rowdata; } -=cut - ######################################################### ######################################################### ## @@ -975,8 +910,7 @@ sub CreateInterface { ## ## Output Selection my $output_selector = $/.'