# The LearningOnline Network with CAPA # # $Id: loncorrectproblemplot.pm,v 1.18 2005/04/07 06:56:24 albertel 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::loncorrectproblemplot; use strict; use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::loncoursedata(); use Apache::lonstatistics; use Apache::lonstathelpers; use Apache::lonlocal; my @SubmitButtons = ( { name => 'CreatePlot', text => 'Create Plot' }, ); ######################################################### ######################################################### =pod =item &BuildCorrectProblemsPage Entry point from lonstatistics to the correct problems plot page. =cut ######################################################### ######################################################### sub BuildCorrectProblemsPage { my ($r,$c)=@_; # my %Saveable_Parameters = ('Status' => 'scalar', 'Section' => 'array'); &Apache::loncommon::store_course_settings('correct_problems_plot', \%Saveable_Parameters); &Apache::loncommon::restore_course_settings('correct_problems_plot', \%Saveable_Parameters); # &Apache::lonstatistics::PrepareClasslist(); # $r->print(&CreateInterface()); # my @Students = @Apache::lonstatistics::Students; # if (@Students < 1) { $r->print('

'. &mt('There are no students in the sections selected'). '

'); } # my @CacheButtonHTML = &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status'); foreach my $button (@SubmitButtons) { $r->print(''); $r->print(' 'x5); } foreach my $html (@CacheButtonHTML) { $r->print($html.(' 'x5)); } $r->rflush(); # # Determine which problem symbs we are to sum over if (exists($env{'form.CreatePlot'})) { my @ProblemSymbs; my $total_weights = 0; my $title = ''; my @maps = &Apache::lonstatistics::get_selected_maps('Maps'); my ($navmap,@sequences) = &Apache::lonstatistics::selected_sequences_with_assessments(); if ($maps[0] ne 'all') { foreach my $seq (@sequences) { if ($title eq '') { $title = $seq->compTitle; } else { $title = 'Multiple Sequences'; } } } else { $title = 'All Problems'; } foreach my $seq (@sequences) { my @resources = &Apache::lonstathelpers::get_resources($navmap,$seq); foreach my $res (@resources) { foreach my $partid (@{$res->parts}) { push(@ProblemSymbs,{symb=>$res->symb, part=>$partid}); $total_weights += &Apache::lonnet::EXT('resource.'.$partid.'.weight', $res->symb, undef,undef,undef); } } } $r->print('

'. &Apache::lonstatistics::section_and_enrollment_description(). '

'); my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits(); if (defined($starttime) || defined($endtime)) { # Inform the user what the time limits on the data are. $r->print(&mt('Statistics on submissions from [_1] to [_2]', &Apache::lonlocal::locallocaltime($starttime), &Apache::lonlocal::locallocaltime($endtime))); } &Apache::loncoursedata::populate_weight_table(); my $score_data = &Apache::loncoursedata::get_student_scores ([&Apache::lonstatistics::get_selected_sections()], \@ProblemSymbs, $Apache::lonstatistics::enrollment_status,undef, $starttime,$endtime); $r->print(&AnalyzeScoreData($score_data,$title,$total_weights)); } else { $r->print('

'.&mt('Make a sequence selection from the "Sequences and Folders" menu and hit "Create Plot" to begin').'

'); } return; } ######################################################### ######################################################### =pod =item & AnalyzeScoreData($score_data) Analyze the result of &Apache::loncoursedata::get_student_scores() and return html with a plot of the data and a table of the values and bins. =cut ######################################################### ######################################################### sub AnalyzeScoreData { my ($score_data,$title,$maximum) = @_; # # Basic check first if (ref($score_data) ne 'ARRAY' || @$score_data < 1) { return '

'.&mt('There is no data to plot').'

'; } # # Determine which bins to use my $lowest = $score_data->[0]->[0]; $lowest = 0; my $highest = $score_data->[-1]->[0]; my $binsize = 1; if ($highest > 50) { $binsize = 2; } if ($highest > 100) { $binsize = 5; } if ($highest > 200) { $binsize = 10; } if ($highest > 500) { $binsize = 20; } if ($highest > 1000) { $binsize = 50; } if ($highest > 2000) { $binsize = 100; } # # Get the data into the bins (destroying $score_data in the process) my @Bins = &bin_data($score_data,$binsize,$lowest,$highest); my @Xdata; my @Ydata; my $max; my $Str = '

'. &mt('Problem weights do not reflect individual student settings.') .'

'. ''."\n".''."\n"; my $sum = 0; while (my $bin = shift(@Bins)) { push (@Xdata,$bin->{'start'}); push (@Ydata,$bin->{'count'}); $sum += $bin->{'count'}; if ($bin->{'count'} > $max) { $max = $bin->{'count'}; } $Str.= ''. ''."\n"; } # scale max to an integer. $max = 5*(int($max/5)+1); $Str .= "
RangeCount
'.$bin->{'start'}.' - '.$bin->{'end'}.''.$bin->{'count'}.'

\n"; $title = &HTML::Entities::decode($title); $Str = "\n

". &Apache::loncommon::DrawBarGraph($title.' ('.$sum.' students)', 'Correct Problems (max possible = '.$maximum.')', 'Number of students', $max,undef, # colors \@Xdata,\@Ydata). "\n
\n".$Str; $Str .= '

'."\n"; return $Str; } ######################################################### ######################################################### =pod =item &bin_data($data,$binsize,$startbin,$endbin) Note: This routine destroys the array of data passed to it. Inputs: $data: array reference - the contents of @$data must be arrays with x and y data. $data = [ [x1,y1],[x2,y2],...]; $binsize: Width of bins to put data in $startbin: the starting bin. $endbin: the ending bin. Returns: Array of Bins. Each bin is a hash reference with the following keys: 'start', 'count', and 'end'. =cut ######################################################### ######################################################### sub bin_data { my ($data,$binsize,$startbin,$endbin)=@_; return () if (! defined($data) || ref($data) ne 'ARRAY'); # # Determine bin geometry my $binstart = $startbin; my $binend = $startbin+$binsize; # put the data into bins my @Bins; my $count=0; my $idx=0; while ($idx < scalar(@$data) && ($endbin-$binend + $binsize)>0) { my $dataset = $data->[$idx++]; my ($x,$y) = @{$dataset}; while ($x > ($binend-.001)) { # store the old data push (@Bins,{ start => $binstart, count => $count, end => $binend }); # start counting again $binstart += $binsize; $binend += $binsize; $count = 0; } $count+=$y; } if ($count > 0) { push (@Bins,{ start => $binstart, count => $count, end => $binend }); } return @Bins; } ######################################################### ######################################################### =pod =item &CreateInterface Inputs: none. Returns: HTML for the correct problems plot interface. =cut ######################################################### ######################################################### sub CreateInterface { ## ## Environment variable initialization my $Str; $Str .= &Apache::lonhtmlcommon::breadcrumbs(undef,'Correct Problems Plot'); $Str .= '

'; # $Str .= ''."\n"; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''."\n"; # $Str .= ''; # $Str .= ''; # $Str .= ''."\n"; $Str .= '
'.&mt('Sections').''.&mt('Enrollment Status').''.&mt('Sequences and Folders').''. &Apache::lonstathelpers::limit_by_time_form().'
'."\n"; $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5); $Str .= ''; $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5); $Str .= ''."\n"; # $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5); $Str .= '
'."\n"; # $Str .= ''.&mt('Status: [_1]', ''). ''.'

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