# The LearningOnline Network with CAPA # # $Id: lonstudentsubmissions.pm,v 1.1 2004/02/19 20:17:01 matthew Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonstudentsubmissions; use strict; use Apache::lonnet(); use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::loncoursedata(); use Apache::lonstatistics; use Apache::lonlocal; use Apache::lonstathelpers; use HTML::Entities(); use Time::Local(); use Spreadsheet::WriteExcel(); my @SubmitButtons = ({ name => 'PrevProblem', text => 'Previous Problem' }, { name => 'NextProblem', text => 'Next Problem' }, { name => 'break'}, { name => 'ClearCache', text => 'Clear Caches' }, { name => 'updatecaches', text => 'Update Student Data' }, { name => 'SelectAnother', text => 'Choose a different Problem' }, { name => 'Generate', text => 'Generate Spreadsheet'}, ); sub BuildStudentSubmissionsPage { my ($r,$c)=@_; # my %Saveable_Parameters = ('Status' => 'scalar', 'Section' => 'array', 'NumPlots' => 'scalar', ); &Apache::loncommon::store_course_settings('student_submissions', \%Saveable_Parameters); &Apache::loncommon::restore_course_settings('student_submissions', \%Saveable_Parameters); # &Apache::lonstatistics::PrepareClasslist(); # $r->print('

'.&mt('Student Submissions Report').'

'); $r->print(&CreateInterface()); # my @Students = @Apache::lonstatistics::Students; # if (@Students < 1) { $r->print('

There are no students in the sections selected

'); } # &Apache::loncoursedata::clear_internal_caches(); if (exists($ENV{'form.ClearCache'}) || exists($ENV{'form.updatecaches'}) || (exists($ENV{'form.firstanalysis'}) && $ENV{'form.firstanalysis'} ne 'no')) { &Apache::lonstatistics::Gather_Full_Student_Data($r); } if (! exists($ENV{'form.firstanalysis'})) { $r->print(''); } else { $r->print(''); } $r->rflush(); # if (exists($ENV{'form.problemchoice'}) && ! exists($ENV{'form.SelectAnother'})) { foreach my $button (@SubmitButtons) { if ($button->{'name'} eq 'break') { $r->print("
\n"); } else { $r->print(''); $r->print(' 'x5); } } # $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; } # # Store the current problem choice and send it out in the form $ENV{'form.problemchoice'} = &Apache::lonstathelpers::make_target_id($current_problem); $r->print(''); # if (! defined($current_problem->{'resource'})) { $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); } $r->print('
'); } else { $r->print(''); $r->print(' 'x5); $r->print('

'.&mt('Please select a problem to analyze').'

'); $r->print(&Apache::lonstathelpers::ProblemSelector('.')); } } ######################################################### ######################################################### ## ## Excel output of student answers and correct answers ## ######################################################### ######################################################### sub prepare_excel_output { my ($r,$problem,$ProblemData,$Students) = @_; my ($resource,$respid,$partid) = ($problem->{'resource'}, $problem->{'respid'}, $problem->{'part'}); $r->print('

'. &mt('Preparing Excel spreadsheet of student responses'). '

'); # &GetStudentAnswers($r,$problem,$Students); # my @Columns = ( 'username','domain','attempt','time', 'submission','correct', 'grading','awarded','weight', 'score'); my $awarded_col = 7; my $weight_col = 8; # # 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('

'.&mt("Unable to create new Excel file. ". "This error has been logged. ". "Please alert your LON-CAPA administrator"). '

'); 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) { 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 { foreach my $response (@$results) { 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('

'. &mt('Your Excel spreadsheet.'). '

'."\n"); } sub GetStudentAnswers { my ($r,$problem,$Students) = @_; my %Answers; my ($resource,$partid,$respid) = ($problem->{'resource'}, $problem->{'part'}, $problem->{'respid'}); # Open progress window my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin ($r,'Student Answer Compilation Status', 'Student Answer Compilation Progress', scalar(@$Students)); $r->print("\n"); $r->rflush(); foreach my $student (@$Students) { my $sname = $student->{'username'}; my $sdom = $student->{'domain'}; my $answer = &Apache::lonstathelpers::analyze_problem_as_student ($resource,$sname,$sdom,$partid,$respid); &Apache::lonnet::logthis('answer = "'.$answer.'"'); &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, &mt('last student')); $student->{'answer'} = $answer; } $r->print("
\n"); $r->rflush(); # close progress window &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); return; } ######################################################### ######################################################### ## ## Generic Interface Routines ## ######################################################### ######################################################### sub CreateInterface { ## ## Environment variable initialization my $Str = ''; $Str .= ''."\n"; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''."\n"; ## ## $Str .= ''; # $Str .= ''; # my $only_seq_with_assessments = sub { my $s=shift; if ($s->{'num_assess'} < 1) { return 0; } else { return 1; } }; ## ## $Str .= ''."\n"; $Str .= '
'.&mt('Sections').''.&mt('Enrollment Status').' 
'."\n"; $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5); $Str .= ''; $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5); $Str .= '
'."\n"; # # We do this to make sure the sequence information is initialized &Apache::lonstatistics::MapSelect('Maps','multiple,all',5, $only_seq_with_assessments); # return $Str; } 1; __END__