# The LearningOnline Network with CAPA # # $Id: lonsurveyreports.pm,v 1.2 2004/07/06 15:56:42 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::lonsurveyreports; 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(); my @SubmitButtons = ({ name => 'PrevProblem', text => 'Previous Survey' }, { name => 'NextProblem', text => 'Next Survey' }, { name => 'break'}, { name => 'SelectAnother', text => 'Choose a different Survey Problem' }, { name => 'Generate', text => 'Generate Report'}, ); sub BuildSurveyReportsPage { my ($r,$c)=@_; # my %Saveable_Parameters = ('Status' => 'scalar', 'Section' => 'array', 'NumPlots' => 'scalar', ); &Apache::loncommon::store_course_settings('survey_reports', \%Saveable_Parameters); &Apache::loncommon::restore_course_settings('survey_resports', \%Saveable_Parameters); # &Apache::lonstatistics::PrepareClasslist(); # $r->print(&CreateInterface()); # my @Students = @Apache::lonstatistics::Students; # if (@Students < 1) { $r->print('

There are no students in the sections selected

'); } # my @CacheButtonHTML = &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status'); $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); } } foreach my $html (@CacheButtonHTML) { $r->print($html.(' '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, '.', 'part_survey', ); 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'}); &make_HTML_report($r,$current_problem,\%Data,\@Students); } $r->print('
'); } else { $r->print(''); $r->print(' 'x5); $r->print('

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

'); $r->print(&SurveyProblemSelector()); } } ########################################################## ########################################################## ## ## SurveyProblemSelector ## ########################################################## ########################################################## sub SurveyProblemSelector { my $Str = ''; my @SurveyProblems; foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess('all')) { next if ($seq->{'num_assess'}<1); foreach my $res (@{$seq->{'contents'}}) { next if ($res->{'type'} ne 'assessment'); foreach my $part (@{$res->{'parts'}}) { if ($res->{'partdata'}->{$part}->{'Survey'}) { push(@SurveyProblems,{res=>$res,seq=>$seq,part=>$part}); last; } } } } if (! scalar(@SurveyProblems)) { $Str = '

'. &mt('There are no survey problems in this course'). '

'.$/; return $Str; } $Str .= ''.$/; $Str .= ''.''. ''. ''. ''.$/; foreach my $problem (@SurveyProblems) { my $value = &Apache::lonstathelpers::make_target_id ({symb=>$problem->{'res'}->{'symb'}, part=>$problem->{'part'}, respid=>undef, resptype=>undef}); my $checked = ''; if ($ENV{'form.problemchoice'} eq $value) { $checked = 'checked '; } $Str .= ''.''. ''. ''. ''.$/; } $Str .= '
'.&mt('Sequence').''.&mt('Problem').'
'. ''.''.$problem->{'seq'}->{'title'}.''.$problem->{'res'}->{'title'}.'
'; return $Str; } ######################################################### ######################################################### ## ## Compile Student Answers ## ######################################################### ######################################################### sub Compile_Student_Answers { my ($problem,$ProblemData,$Students) = @_; my $resource = $problem->{'resource'}; foreach my $student (@$Students) { foreach my $partid (@{$resource->{'parts'}}) { my $partdata = $resource->{'partdata'}->{$partid}; for (my $i=0;$i<=@{$partdata->{'ResponseIds'}};$i++) { my $respid = $partdata->{'ResponseIds'}->[$i]; my $resptype = $partdata->{'ResponseTypes'}->[$i]; my $results = &Apache::loncoursedata::get_response_data_by_student ($student,$resource->{'symb'},$respid); next if (! defined($results) || ref($results) ne 'ARRAY' || ref($results->[0]) ne 'ARRAY'); my $student_response = $results->[0]->[&Apache::loncoursedata::RDs_submission()]; $problem->{'responsedata'}->{$partid}->{$respid}->{'_count'}++; my $data = $problem->{'responsedata'}->{$partid}->{$respid}; if ($resptype =~ /^(radiobutton|optionresponse)$/) { # Restricted response type can be categorized. # # Assume responses were not randomized and the order # represents their value. This is probably a dumb thing # to do... # my ($foil,$value) = split('=',$student_response); $value += 1; # explicitly increment it... $data->{'foil_responses'}->{$foil}++; $data->{'foil_values'}->{$value}++; if (! exists($data->{'map'}->{$value})) { $data->{'map'}->{$value} = $foil; } } else { # Variable stuff (essays, raw numbers, strings) go here push(@{$data->{'responses'}},$student_response); } } } } return; } ######################################################### ######################################################### ## ## make_HTML_report ## ######################################################### ######################################################### sub make_HTML_report { my ($r,$problem,$ProblemData,$Students) = @_; &Compile_Student_Answers($problem,$ProblemData,$Students); # &output_hash('',$ProblemData); my $resource = $problem->{'resource'}; foreach my $partid (@{$resource->{'parts'}}) { my $partdata = $resource->{'partdata'}->{$partid}; for (my $i=0;$i<=@{$partdata->{'ResponseIds'}};$i++) { my $Str = ''.$/; my $respid = $partdata->{'ResponseIds'}->[$i]; my $resptype = $partdata->{'ResponseTypes'}->[$i]; my $data = $problem->{'responsedata'}->{$partid}->{$respid}; next if (! defined($data) || ref($data) ne 'HASH'); # Debugging code # $Str .= ''. # ''. # ''. # ''. # ''.$/; $Str .= ''. ''. ''. ''. ''.$/; if (exists($data->{'responses'}) && ref($data->{'responses'}) eq 'ARRAY') { &randomize_array($data->{'responses'}); foreach my $response (@{$data->{'responses'}}) { $response =~ s/\\r\\n/\n/g; $response =~ s/\\'/'/g; $response =~ s/\\"/"/g; $Str .= ''. ''. ''.$/; } } elsif (exists($data->{'_count'}) && exists($data->{'foil_values'}) && exists($data->{'map'})) { # This is an option or radiobutton survey response my $total = $data->{'_count'}; my $sum = 0; my $tmp; foreach my $value (sort(keys(%{$data->{'foil_values'}}))) { my $count = $data->{'foil_values'}->{$value}; my $foilid = $data->{'map'}->{$value}; my $foiltext = $ProblemData->{$partid.'.'.$respid}->{'_Foils'}->{$foilid}->{'text'}; my $foilname = $ProblemData->{$partid.'.'.$respid}->{'_Foils'}->{$foilid}->{'name'}; $sum = $value * $data->{'foil_values'}->{$value}; $tmp .= ''. ''. ''. ''. ''. ''.$/; } $Str .= ''. ''. ''. ''. ''. ''.$/. $tmp; } $Str.= '
'.$partid.''.$respid.''.$resptype.'
'.&mt('Total').''.$data->{'_count'}.''.&mt('Part [_1], Response [_2]',$partid,$respid).'
'.
                        &HTML::Entities::encode($response,'<>&').
                        '

'.$foilname.''.$foiltext.''.$count.''. sprintf("%.2f",$count/$total*100).'%
'.&mt('Foil Name').''.&mt('Text').''.&mt('Freq').''.&mt('Percent').'

'; $r->print($Str); $r->rflush(); } } return; } sub randomize_array { # Fisher Yates shuffle, lifted from p 121 of "The Perl Cookbook" my ($array) = @_; for (my $i=scalar(@$array);--$i;) { my $j = int(rand($i+1)); next if ($i == $j); @$array[$i,$j]=@$array[$j,$i]; } } ######################################################### ######################################################### ## ## Generic Interface Routines ## ######################################################### ######################################################### sub CreateInterface { ## ## Environment variable initialization my $Str = ''; $Str .= &Apache::lonhtmlcommon::breadcrumbs (undef,'Student Submission Reports'); $Str .= '

'; $Str .= ''."\n"; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''."\n"; # $Str .= ''; # $Str .= ''; # $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"; # $Str .= ''.&mt('Status: [_1]', ''). ''.'

'; ## return $Str; } 1; __END__