Annotation of loncom/interface/statistics/loncorrectproblemplot.pm, revision 1.16

1.1       matthew     1: # The LearningOnline Network with CAPA
                      2: #
1.16    ! matthew     3: # $Id: loncorrectproblemplot.pm,v 1.15 2005/03/01 22:25:59 matthew Exp $
1.1       matthew     4: #
                      5: # Copyright Michigan State University Board of Trustees
                      6: #
                      7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      8: #
                      9: # LON-CAPA is free software; you can redistribute it and/or modify
                     10: # it under the terms of the GNU General Public License as published by
                     11: # the Free Software Foundation; either version 2 of the License, or
                     12: # (at your option) any later version.
                     13: #
                     14: # LON-CAPA is distributed in the hope that it will be useful,
                     15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17: # GNU General Public License for more details.
                     18: #
                     19: # You should have received a copy of the GNU General Public License
                     20: # along with LON-CAPA; if not, write to the Free Software
                     21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     22: #
                     23: # /home/httpd/html/adm/gpl.txt
                     24: #
                     25: # http://www.lon-capa.org/
                     26: #
                     27: 
                     28: package Apache::loncorrectproblemplot;
                     29: 
                     30: use strict;
                     31: use Apache::lonnet();
                     32: use Apache::loncommon();
                     33: use Apache::lonhtmlcommon();
                     34: use Apache::loncoursedata();
                     35: use Apache::lonstatistics;
                     36: use Apache::lonstathelpers;
                     37: use Apache::lonlocal;
                     38: 
                     39: my @SubmitButtons = (
                     40:                      { name => 'CreatePlot',
                     41:                        text => 'Create Plot' },
                     42:                      );
1.4       matthew    43: 
                     44: #########################################################
                     45: #########################################################
                     46: 
                     47: =pod
                     48: 
                     49: =item &BuildCorrectProblemsPage
                     50: 
                     51: Entry point from lonstatistics to the correct problems plot page.
                     52: 
                     53: =cut
                     54: 
                     55: #########################################################
                     56: #########################################################
1.1       matthew    57: 
                     58: sub BuildCorrectProblemsPage {
                     59:     my ($r,$c)=@_;
                     60:     #
                     61:     my %Saveable_Parameters = ('Status' => 'scalar',
                     62:                                'Section' => 'array');
                     63:     &Apache::loncommon::store_course_settings('correct_problems_plot',
                     64:                                               \%Saveable_Parameters);
                     65:     &Apache::loncommon::restore_course_settings('correct_problems_plot',
                     66:                                                 \%Saveable_Parameters);
                     67:     #
                     68:     &Apache::lonstatistics::PrepareClasslist();    
                     69:     #
                     70:     $r->print(&CreateInterface());
                     71:     #
                     72:     my @Students = @Apache::lonstatistics::Students;
                     73:     #
                     74:     if (@Students < 1) {
                     75:         $r->print('<h2>'.
                     76:                   &mt('There are no students in the sections selected').
                     77:                   '</h2>');
                     78:     }
                     79:     #
1.11      matthew    80:     my @CacheButtonHTML = 
                     81:         &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');
1.1       matthew    82:     foreach my $button (@SubmitButtons) {
                     83:         $r->print('<input type="submit" name="'.$button->{'name'}.'" '.
                     84:                   'value="'.&mt($button->{'text'}).'" />');
                     85:         $r->print('&nbsp;'x5);
                     86:     }
1.11      matthew    87:     foreach my $html (@CacheButtonHTML) {
                     88:         $r->print($html.('&nbsp;'x5));
                     89:     }
1.1       matthew    90:     $r->rflush();
                     91:     #
                     92:     # Determine which problem symbs we are to sum over
                     93:     if (exists($ENV{'form.CreatePlot'})) {
                     94:         my @ProblemSymbs;
1.16    ! matthew    95:         my $total_weights = 0;
1.9       matthew    96:         my $title = '';
1.15      matthew    97:         my @maps = &Apache::lonstatistics::get_selected_maps('Maps');
                     98:         my ($navmap,@sequences) =
                     99:             &Apache::lonstatistics::selected_sequences_with_assessments();
                    100:         if ($maps[0] ne 'all') {
                    101:             foreach my $seq (@sequences) {
1.9       matthew   102:                 if ($title eq '') {
1.15      matthew   103:                     $title = $seq->compTitle;
1.9       matthew   104:                 } else {
                    105:                     $title = 'Multiple Sequences';
                    106:                 }
1.1       matthew   107:             }
1.13      matthew   108:         } else {
1.16    ! matthew   109:             $title = 'All Problems';
        !           110:         }
        !           111:         foreach my $seq (@sequences) {
        !           112:             my @resources = 
        !           113:                 &Apache::lonstathelpers::get_resources($navmap,$seq);
        !           114:             foreach my $res (@resources) {
        !           115:                 foreach my $partid (@{$res->parts}) {
        !           116:                     push(@ProblemSymbs,{symb=>$res->symb,
        !           117:                                         part=>$partid});
        !           118:                     $total_weights += 
        !           119:                         &Apache::lonnet::EXT('resource.'.$partid.'.weight',
        !           120:                                              $res->symb,
        !           121:                                              undef,undef,undef);
1.13      matthew   122:                 }
                    123:             }
1.1       matthew   124:         }
1.9       matthew   125:         my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
1.10      matthew   126:         if (defined($starttime) || defined($endtime)) {
                    127:             # Inform the user what the time limits on the data are.
                    128:             $r->print(&mt('Statistics on submissions from [_1] to [_2]',
                    129:                           &Apache::lonlocal::locallocaltime($starttime),
                    130:                           &Apache::lonlocal::locallocaltime($endtime)));
                    131:         }
1.16    ! matthew   132:         &Apache::loncoursedata::populate_weight_table();
1.1       matthew   133:         my $score_data = &Apache::loncoursedata::get_student_scores
                    134:             (\@Apache::lonstatistics::SelectedSections,
                    135:              \@ProblemSymbs,
1.9       matthew   136:              $Apache::lonstatistics::enrollment_status,undef,
                    137:              $starttime,$endtime);
1.16    ! matthew   138:         $r->print(&AnalyzeScoreData($score_data,$title,$total_weights));
1.11      matthew   139:     } else {
                    140:         $r->print('<h3>'.&mt('Make a sequence selection from the "Sequences and Folders" menu and hit "Create Plot" to begin').'</h3>');
1.1       matthew   141:     }
                    142:     return;
                    143: }
                    144: 
                    145: #########################################################
                    146: #########################################################
                    147: 
                    148: =pod
                    149: 
1.2       matthew   150: =item & AnalyzeScoreData($score_data)
                    151: 
                    152: Analyze the result of &Apache::loncoursedata::get_student_scores() and
                    153: return html with a plot of the data and a table of the values and bins.
1.1       matthew   154: 
                    155: =cut
                    156: 
                    157: #########################################################
                    158: #########################################################
                    159: sub AnalyzeScoreData {
1.16    ! matthew   160:     my ($score_data,$title,$maximum) = @_;
1.1       matthew   161:     #
                    162:     # Basic check first
1.12      matthew   163:     if (ref($score_data) ne 'ARRAY' || @$score_data < 1) {
                    164:         return '<h2>'.&mt('There is no data to plot').'</h2>';
1.1       matthew   165:     }
                    166:     #
                    167:     # Determine which bins to use
                    168:     my $lowest  = $score_data->[0]->[0];
                    169:     $lowest = 0;
                    170:     my $highest = $score_data->[-1]->[0];
                    171:     my $binsize = 1;
                    172:     if ($highest > 50) { $binsize = 2; }
                    173:     if ($highest > 100) { $binsize = 5; }
                    174:     if ($highest > 200) { $binsize = 10; }
                    175:     if ($highest > 500) { $binsize = 20; }
                    176:     if ($highest > 1000) { $binsize = 50; }
                    177:     if ($highest > 2000) { $binsize = 100; }
                    178:     #
                    179:     # Get the data into the bins (destroying $score_data in the process)
                    180:     my @Bins = &bin_data($score_data,$binsize,$lowest,$highest);
                    181:     my @Xdata; my @Ydata; my $max;
1.11      matthew   182:     my $Str = 
1.16    ! matthew   183:         '<p>'.
        !           184:         &mt('Problem weights do not reflect individual student settings.')
        !           185:         .'</p>'.
1.11      matthew   186:         '<table border="1">'."\n".'<tr><th>Range</th><th>Count</th></tr>'."\n";
1.9       matthew   187:     my $sum = 0;
1.1       matthew   188:     while (my $bin = shift(@Bins)) {
                    189:         push (@Xdata,$bin->{'start'});
                    190:         push (@Ydata,$bin->{'count'});
1.9       matthew   191:         $sum += $bin->{'count'};
1.1       matthew   192:         if ($bin->{'count'} > $max) {
                    193:             $max = $bin->{'count'};
                    194:         }
                    195:         $Str.= '<tr><td>'.$bin->{'start'}.' - '.$bin->{'end'}.'</td>'.
                    196:             '<td>'.$bin->{'count'}.'</td></tr>'."\n";
                    197:     }
1.5       matthew   198:     # scale max to an integer.
                    199:     $max = 5*(int($max/5)+1);
1.1       matthew   200:     $Str .= "</table><br />\n";
1.9       matthew   201:     $title = &HTML::Entities::decode($title);
1.16    ! matthew   202:     $Str = "\n<p>".
        !           203:         &Apache::loncommon::DrawBarGraph($title.' ('.$sum.' students)',
        !           204:                               'Correct Problems (max possible = '.$maximum.')',
        !           205:                                          'Number of students',
        !           206:                                          $max,undef, # colors
        !           207:                                          \@Xdata,\@Ydata).
        !           208:                                          "\n<br />\n".$Str;
1.11      matthew   209:     $Str .= '</p>'."\n";
1.1       matthew   210:     return $Str;                                               
                    211: }
                    212: 
                    213: 
                    214: #########################################################
                    215: #########################################################
                    216: 
                    217: =pod
                    218: 
                    219: =item &bin_data($data,$binsize,$startbin,$endbin)
                    220: 
                    221: Note: This routine destroys the array of data passed to it.
                    222: 
                    223: Inputs: $data: array reference - the contents of @$data must
                    224:         be arrays with x and y data.  $data = [ [x1,y1],[x2,y2],...];
                    225:         $binsize: Width of bins to put data in
                    226:         $startbin: the starting bin.
                    227:         $endbin: the ending bin.
                    228: Returns: Array of Bins.  Each bin is a hash reference with the following
                    229:          keys: 'start', 'count', and 'end'.
                    230: 
                    231: =cut
                    232: 
                    233: #########################################################
                    234: #########################################################
                    235: sub bin_data {
                    236:     my ($data,$binsize,$startbin,$endbin)=@_;
                    237:     return () if (! defined($data) || ref($data) ne 'ARRAY');
                    238:     #
                    239:     # Determine bin geometry
                    240:     my $binstart = $startbin;
                    241:     my $binend = $startbin+$binsize;
                    242:     # put the data into bins
                    243:     my @Bins;
                    244:     my $count=0;
                    245:     my $idx=0;
1.9       matthew   246:     while ($idx < scalar(@$data) && ($endbin-$binend + $binsize)>0) {
1.1       matthew   247:         my $dataset = $data->[$idx++];
                    248:         my ($x,$y) = @{$dataset};
1.9       matthew   249:         while ($x > ($binend-.001)) {
1.1       matthew   250:             # store the old data
                    251:             push (@Bins,{ start => $binstart,
                    252:                           count => $count,
                    253:                           end   => $binend });
                    254:             # start counting again
                    255:             $binstart += $binsize;
                    256:             $binend += $binsize;
                    257:             $count = 0;
                    258:         }
                    259:         $count+=$y;
                    260:     }
1.9       matthew   261:     if ($count > 0) {
                    262:         push (@Bins,{ start => $binstart,
                    263:                       count => $count,
                    264:                       end   => $binend });
                    265:     }
1.1       matthew   266:     return @Bins;
                    267: }
                    268: 
                    269: #########################################################
                    270: #########################################################
                    271: 
                    272: =pod
                    273: 
1.2       matthew   274: =item &CreateInterface
                    275: 
                    276: Inputs: none.
                    277: 
                    278: Returns: HTML for the correct problems plot interface.
1.1       matthew   279: 
                    280: =cut
                    281: 
                    282: #########################################################
                    283: #########################################################
                    284: sub CreateInterface {
                    285:     ##
                    286:     ## Environment variable initialization
                    287:     my $Str;
1.15      matthew   288:     $Str .= &Apache::lonhtmlcommon::breadcrumbs(undef,'Correct Problems Plot');
1.11      matthew   289:     $Str .= '<p>';
                    290:     #
1.1       matthew   291:     $Str .= '<table cellspacing="5">'."\n";
                    292:     $Str .= '<tr>';
                    293:     $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>';
                    294:     $Str .= '<td align="center"><b>'.&mt('Enrollment Status').'</b></td>';
                    295:     $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>';
1.9       matthew   296:     $Str .= '<td rowspan="2">'.
                    297:         &Apache::lonstathelpers::limit_by_time_form().'</td>';
1.1       matthew   298:     $Str .= '</tr>'."\n";
1.11      matthew   299:     #
1.1       matthew   300:     $Str .= '<tr><td align="center">'."\n";
                    301:     $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
                    302:     $Str .= '</td>';
                    303:     #
                    304:     $Str .= '<td align="center">';
                    305:     $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
                    306:     $Str .= '</td><td>'."\n";
                    307:     #
1.15      matthew   308:     $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5);
1.9       matthew   309:     $Str .= '</td>';
                    310:     #
1.1       matthew   311:     $Str .= '</tr>'."\n";
                    312:     $Str .= '</table>'."\n";
1.11      matthew   313:     #
                    314:     $Str .= '<nobr>'.&mt('Status: [_1]',
                    315:                          '<input type="text" '.
                    316:                          'name="stats_status" size="60" value="" />').
                    317:             '</nobr>'.'</p>';
                    318:     ##
1.1       matthew   319:     return $Str;
                    320: }
                    321: 
                    322: 1;
                    323: 
                    324: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.