# The LearningOnline Network with CAPA # # $Id: loncorrectproblemplot.pm,v 1.7 2004/02/20 16:38:49 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::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' }, { name => 'ClearCache', text => 'Clear Caches' }, { name => 'updatecaches', text => 'Update Student Data' }, ); ######################################################### ######################################################### =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'). '

'); } # &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(''); } foreach my $button (@SubmitButtons) { $r->print(''); $r->print(' 'x5); } $r->rflush(); # # Determine which problem symbs we are to sum over if (exists($ENV{'form.CreatePlot'})) { my @ProblemSymbs; if ($Apache::lonstatistics::SelectedMaps[0] ne 'all') { foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()){ foreach my $res (@{$seq->{'contents'}}) { next if ($res->{'type'} ne 'assessment'); foreach my $part (@{$res->{'parts'}}) { push(@ProblemSymbs,{symb=>$res->{'symb'}, part=>$part}); } } } } my $score_data = &Apache::loncoursedata::get_student_scores (\@Apache::lonstatistics::SelectedSections, \@ProblemSymbs, $Apache::lonstatistics::enrollment_status); $r->print(&AnalyzeScoreData($score_data)); } 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) = @_; # # Basic check first if (@$score_data < 1) { return '

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 = ''."\n".''."\n"; while (my $bin = shift(@Bins)) { push (@Xdata,$bin->{'start'}); push (@Ydata,$bin->{'count'}); if ($bin->{'count'} > $max) { $max = $bin->{'count'}; } $Str.= ''. ''."\n"; } # scale max to an integer. $max = 5*(int($max/5)+1); my $title = 'Correct Problems Plot'; $Str .= "
RangeCount
'.$bin->{'start'}.' - '.$bin->{'end'}.''.$bin->{'count'}.'

\n"; $Str = "
\n".&Apache::loncommon::DrawBarGraph($title, 'Num Correct Problems', 'Number of students', $max, undef, # colors \@Xdata, \@Ydata). "\n
\n".$Str; 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) && ($binend-$endbin)<$binsize) { my $dataset = $data->[$idx++]; my ($x,$y) = @{$dataset}; while ($x > $binend) { # store the old data push (@Bins,{ start => $binstart, count => $count, end => $binend }); # start counting again $binstart += $binsize; $binend += $binsize; $count = 0; } $count+=$y; } 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,&mt('Correct Problems Plot')); $Str .= ''."\n"; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''; $Str .= ''."\n"; ## ## $Str .= ''; # $Str .= ''."\n"; $Str .= '
'.&mt('Sections').''.&mt('Enrollment Status').''.&mt('Sequences and Folders').'
'."\n"; $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5); $Str .= ''; $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5); $Str .= ''."\n"; # my $only_seq_with_assessments = sub { my $s=shift; if ($s->{'num_assess'} < 1) { return 0; } else { return 1; } }; $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5, $only_seq_with_assessments); $Str .= ''."\n"; ## $Str .= '
'."\n"; return $Str; } 1; __END__