Diff for /loncom/interface/statistics/lonproblemstatistics.pm between versions 1.114 and 1.125

version 1.114, 2008/10/23 09:07:51 version 1.125, 2014/02/03 18:52:30
Line 52  package Apache::lonproblemstatistics; Line 52  package Apache::lonproblemstatistics;
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lonquickgrades();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonstatistics;  use Apache::lonstatistics;
Line 73  my %SeqStat;    # keys are symbs, values Line 74  my %SeqStat;    # keys are symbs, values
 ## header for plots created with Graph.pm, both of which more than likely do  ## header for plots created with Graph.pm, both of which more than likely do
 ## not support localization.  ## not support localization.
 ##  ##
   ## Additional Notes:
   ## Localization can be done and is done before passing the phrases
   ## to the output.
   ## This might conflict with special characters, e.g. German Umlaute or
   ## chinese characters. Do not use such characters in this case.
   ## If this failed, consider that the sequence and folder names
   ## are also passed to the output and would fail the same way.
   ##
 #  #
 #  #
 ##  ##
Line 84  my %SeqStat;    # keys are symbs, values Line 93  my %SeqStat;    # keys are symbs, values
 ## title           yes      any scalar  This is what the user sees to identify  ## title           yes      any scalar  This is what the user sees to identify
 ##                                      the field.  Passed through &mt().  ##                                      the field.  Passed through &mt().
 ## long_title      yes      any scalar  Used as graph heading and in excel  ## long_title      yes      any scalar  Used as graph heading and in excel
 ##                                      output.  NOT translated  ##                                      output.  Passed through &mt().
 ## align           no    (left|right|center)  HTML cell contents alignment  ## align           no    (left|right|center)  HTML cell contents alignment
 ## color           yes      html color  HTML cell background color  ## color           yes      html color  HTML cell background color
 ##                                      used to visually group statistics  ##                                      used to visually group statistics
Line 123  my @Fields = ( Line 132  my @Fields = (
              align  => 'left',               align  => 'left',
              color  => '#FFFFE6',               color  => '#FFFFE6',
              special  => 'link',               special  => 'link',
              sortable => 'yes',                sortable => 'yes',
              selectable => 'no',               selectable => 'no',
              defaultselected => 'yes',               defaultselected => 'yes',
            },             },
            { name   => 'part',              { name   => 'part',
              title  => 'Part',               title  => 'Part',
              align  => 'left',               align  => 'left',
              color  => '#FFFFE6',               color  => '#FFFFE6',
Line 274  my @Fields = ( Line 283  my @Fields = (
              sortable  => 'yes',               sortable  => 'yes',
              graphable => 'yes',               graphable => 'yes',
              long_title => 'Degree of Difficulty'.               long_title => 'Degree of Difficulty'.
                            '[ 1 - ((#YES+#yes) / Tries) ]',                             ' ~[ 1 - ((#YES+#yes) / Tries) ~]',
              selectable => 'yes',               selectable => 'yes',
              defaultselected => 'yes',               defaultselected => 'yes',
            },             },
Line 375  my @SeqFields = ( Line 384  my @SeqFields = (
              align  => 'left',               align  => 'left',
              color  => '#FFFFE6',               color  => '#FFFFE6',
              special  => 'no',               special  => 'no',
              sortable => 'no',                sortable => 'no',
              selectable => 'yes',               selectable => 'yes',
              defaultselected => 'no',               defaultselected => 'no',
            },             },
Line 510  my @SeqFields = ( Line 519  my @SeqFields = (
              long_title => 'KR-21 reliability statistic',               long_title => 'KR-21 reliability statistic',
              selectable => 'yes',               selectable => 'yes',
              defaultselected => 'no',               defaultselected => 'no',
            },                        },
 );  );
   
 my %SelectedFields;  my %SelectedFields;
Line 577  sub parse_field_selection { Line 586  sub parse_field_selection {
 }  }
   
 sub field_selection_input {  sub field_selection_input {
     my $Str = '<select name="fieldselections" multiple size="5">'."\n";      my $Str = '<select name="fieldselections" multiple="multiple" size="5">'."\n";
     $Str .= '<option value="all">all</option>'."\n";      $Str .= '<option value="all">'.&mt('all').'</option>'."\n";
     foreach my $field (@Fields) {      foreach my $field (@Fields) {
         next if ($field->{'selectable'} ne 'yes');          next if ($field->{'selectable'} ne 'yes');
         $Str .= '    <option value="'.$field->{'name'}.'" ';          $Str .= '    <option value="'.$field->{'name'}.'" ';
         if ($field->{'selected'} eq 'yes') {          if ($field->{'selected'} eq 'yes') {
             $Str .= 'selected ';              $Str .= 'selected="selected" ';
         }          }
         $Str .= '>'.$field->{'title'}.'</option>'."\n";          $Str .= '>'.&mt($field->{'title'}).'</option>'."\n";
     }      }
     $Str .= "</select>\n";      $Str .= "</select>\n";
 }  }
Line 610  sub CreateInterface { Line 619  sub CreateInterface {
     &parse_field_selection();      &parse_field_selection();
     #      #
     my $Str = '';      my $Str = '';
     $Str .= &Apache::lonhtmlcommon::breadcrumbs('Overall Problem Statistics',      $Str .= &Apache::loncommon::start_data_table();
  'Statistics_Overall_Key');      $Str .= &Apache::loncommon::start_data_table_header_row();
     $Str .= '<table cellspacing="5">'."\n";      $Str .= '<th>'.&mt('Sections').'</th>';
     $Str .= '<tr>';      $Str .= '<th>'.&mt('Groups').'</th>';
     $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>';      $Str .= '<th>'.&mt('Access Status').'</th>';
     $Str .= '<td align="center"><b>'.&mt('Groups').'</b></td>';      $Str .= '<th>'.&mt('Sequences and Folders').'</th>';
     $Str .= '<td align="center"><b>'.&mt('Access Status').'</b></td>';      $Str .= '<th>'.&mt('Statistics').'</th>';
     $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>';      $Str .= '<th>'.&mt('Plot Graph').'</th>';
     $Str .= '<td align="center"><b>'.&mt('Statistics').'</b></td>';      $Str .= '<th>'.&mt('Time Period').'</th>';
     $Str .= '<td rowspan="2">'.      $Str .= &Apache::loncommon::end_data_table_header_row();
         &Apache::lonstathelpers::limit_by_time_form().'</td>';  
     $Str .= '</tr>'."\n";  
     #      #
     $Str .= '<tr><td align="center">'."\n";      $Str .= &Apache::loncommon::start_data_table_row();
       $Str .= '<td align="center" valign="top">'."\n";
     $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);      $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
     $Str .= '</td><td align="center">';      $Str .= '</td><td align="center" valign="top">';
     $Str .= &Apache::lonstatistics::GroupSelect('Group','multiple',5);      $Str .= &Apache::lonstatistics::GroupSelect('Group','multiple',5);
     $Str .= '</td><td align="center">';      $Str .= '</td><td align="center" valign="top">';
     $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);      $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
     $Str .= '</td><td align="center">';      $Str .= '</td><td align="center" valign="top">';
     #      #
     $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5);      $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5);
     $Str .= '</td><td>'.&field_selection_input();      $Str .= '</td><td align="center" valign="top">';
     $Str .= '</td></tr>'."\n";      $Str .= &field_selection_input();
     $Str .= '</table>'."\n";      $Str .= '</td><td align="center" valign="top">';
     #      $Str .= &plot_dropdown();
     $Str .= '<p><span class="LC_nobreak">'      $Str .= "\n";
            .&mt('Status: [_1]',      $Str .= '</td><td align="center" valign="top">';
                     '<input type="text" name="stats_status"'      $Str .= &Apache::lonstathelpers::limit_by_time_form();
                    .' size="60" value="" readonly="readonly" />')      $Str .= '</td>'."\n";
            .'</span></p>';      $Str .=  &Apache::loncommon::end_data_table_row();
       $Str .= &Apache::loncommon::end_data_table();
     #      #
     $Str .= '<input type="submit" name="GenerateStatistics" value="'.      $Str .= '<input type="submit" name="GenerateStatistics" value="'.
         &mt('Generate Statistics').'" />';          &mt('Generate Statistics').'" />';
     $Str .= '&nbsp;'x5;      $Str .= ('&nbsp;'x10);
     $Str .= 'Plot '.&plot_dropdown().('&nbsp;'x10);  
     #      #
     return $Str;      return $Str;
 }  }
Line 695  sub BuildProblemStatisticsPage { Line 703  sub BuildProblemStatisticsPage {
     undef(%SeqStat);      undef(%SeqStat);
     #      #
     # Finally let the user know we are here      # Finally let the user know we are here
       $r->print(&Apache::lonhtmlcommon::breadcrumbs('Overall Problem Statistics',
                                                   'Statistics_Overall_Key'));
       &Apache::lonquickgrades::startGradeScreen($r,'statistics');
   
     my $interface = &CreateInterface($r);      my $interface = &CreateInterface($r);
     $r->print($interface);      $r->print($interface);
     $r->print('<input type="hidden" name="sortby" value="'.$env{'form.sortby'}.      $r->print('<input type="hidden" name="sortby" value="'.$env{'form.sortby'}.
               '" />');                '" />');
     #      #
     my @CacheButtonHTML =       my @CacheButtonHTML =
         &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');          &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');
     my $Str;      my $Str;
     foreach my $html (@CacheButtonHTML) {      foreach my $html (@CacheButtonHTML) {
Line 709  sub BuildProblemStatisticsPage { Line 721  sub BuildProblemStatisticsPage {
     #      #
     $r->print($Str);      $r->print($Str);
     if (! exists($env{'form.firstrun'})) {      if (! exists($env{'form.firstrun'})) {
         $r->print('<h3>'.          $r->print('<p class="LC_info"><b>'.
                   &mt('Press "Generate Statistics" when you are ready.').                    &mt('Press "Generate Statistics" when you are ready.').
                   '</h3><p>'.                    '</b></p>'.
                     '<p class="LC_info">'.
                   &mt('It may take some time to update the student data '.                    &mt('It may take some time to update the student data '.
                       'for the first analysis.  Future analysis this session '.                        'for the first analysis. Future analysis this session '.
                       'will not have this delay.').                        'will not have this delay.').
                   '</p>');                    '</p>');
  &clean_up();   &clean_up();
Line 725  sub BuildProblemStatisticsPage { Line 738  sub BuildProblemStatisticsPage {
     # it does not slow things down noticably.      # it does not slow things down noticably.
     &Apache::loncoursedata::populate_weight_table();      &Apache::loncoursedata::populate_weight_table();
     #      #
     ($navmap,@sequences) =       ($navmap,@sequences) =
         &Apache::lonstatistics::selected_sequences_with_assessments();          &Apache::lonstatistics::selected_sequences_with_assessments();
     if (! ref($navmap)) {      if (! ref($navmap)) {
         $r->print('<h1>'.&mt('A course-wide error occurred.').'</h1>'.          $r->print('<div class="LC_error">'.&mt('A course-wide error occurred.').'</div>'.
                   '<h3>'.$navmap.'</h3>');                    '<h3>'.$navmap.'</h3>');
  &clean_up();   &clean_up();
         return;          return;
     }      }
     if (exists($env{'form.Excel'})) {      if (exists($env{'form.Excel'})) {
         $r->print('<h4>'.          $r->print('<p>'.
                   &Apache::lonstatistics::section_and_enrollment_description().                    &Apache::lonstatistics::section_and_enrollment_description().
                   '</h4>');                    '</p>');
         &Excel_output($r);          &Excel_output($r);
     } else {       } else {
         $r->print('<input type="submit" name="Excel" value="'.          $r->print('<input type="submit" name="Excel" value="'.
                   &mt('Produce Excel Output').'" />'.'&nbsp;'x5);                    &mt('Produce Excel Output').'" />'.'&nbsp;'x5);
         $r->rflush();          $r->rflush();
         $r->print('<h4>'.          $r->print('<p>'.
                   &Apache::lonstatistics::section_and_enrollment_description().                    &Apache::lonstatistics::section_and_enrollment_description().
                   '</h4>');                    '</p>');
         my $count = 0;          my $count = 0;
         foreach my $seq (@sequences) {          foreach my $seq (@sequences) {
             my @resources =               my @resources =
                 &Apache::lonstathelpers::get_resources($navmap,$seq);                  &Apache::lonstathelpers::get_resources($navmap,$seq);
             $count += scalar(@resources);              $count += scalar(@resources);
         }          }
         if ($count > 10) {          if ($count > 10) {
             $r->print('<h2>'.              $r->print('<p>'.
                       &mt('Compiling statistics for [_1] problems',$count).                        &mt('Compiling statistics for [quant,_1,problem]',$count).
                       '</h2>');                        '</p>');
             if ($count > 30) {              if ($count > 30) {
                 $r->print('<h3>'.&mt('This will take some time.').'</h3>');                  $r->print('<p class="LC_info">'.&mt('This will take some time.').'</p>');
             }              }
             $r->rflush();              $r->rflush();
         }          }
Line 788  sub output_sequence_statistics { Line 801  sub output_sequence_statistics {
     $r->print('<h2>'.&mt('Sequence Statistics').      $r->print('<h2>'.&mt('Sequence Statistics').
       &Apache::loncommon::help_open_topic('Statistics_Sequence').        &Apache::loncommon::help_open_topic('Statistics_Sequence').
       '</h2>');        '</h2>');
     $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n".      $r->print(&Apache::loncommon::start_data_table());
               '<table border="0" cellpadding="3">'."\n".  
               '<tr bgcolor="#FFFFE6">');  
     $r->print(&sequence_html_header());      $r->print(&sequence_html_header());
     foreach my $seq (@sequences) {       foreach my $seq (@sequences) {
         last if ($c->aborted);          last if ($c->aborted);
         &compute_sequence_statistics($seq);          &compute_sequence_statistics($seq);
         $r->print(&sequence_html_output($seq));          $r->print(&sequence_html_output($seq));
     }      }
     $r->print('</table>');      $r->print(&Apache::loncommon::end_data_table());
     $r->print('</table>');  
     $r->rflush();      $r->rflush();
     return;      return;
 }  }
Line 814  sub output_sequence_statistics { Line 824  sub output_sequence_statistics {
 sub output_html_by_sequence {  sub output_html_by_sequence {
     my ($r) = @_;      my ($r) = @_;
     my $c = $r->connection();      my $c = $r->connection();
     $r->print(&html_preamble());      $r->print('<br />'.&html_preamble());
     #      #
     foreach my $seq (@sequences) {      foreach my $seq (@sequences) {
         last if ($c->aborted);          last if ($c->aborted);
         $r->print("<h3>".$seq->compTitle."</h3>".          $r->print("<h3>".$seq->compTitle."</h3>".
                   '<table border="0"><tr><td bgcolor="#777777">'."\n".                      &Apache::loncommon::start_data_table().
                   '<table border="0" cellpadding="3">'."\n".                      &Apache::loncommon::start_data_table_header_row().
                   '<tr bgcolor="#FFFFE6">'.                      &statistics_table_header('no container').
                   &statistics_table_header('no container')."</tr>\n");                      &Apache::loncommon::end_data_table_header_row()."\n");
         my @Data = &compute_statistics_on_sequence($seq);          my @Data = &compute_statistics_on_sequence($seq);
         foreach my $data (@Data) {          foreach my $data (@Data) {
             $r->print('<tr>'.&statistics_html_table_data($data,              $r->print(&Apache::loncommon::start_data_table_row().
                                                          'no container').                      &statistics_html_table_data($data,'no container').
                       "</tr>\n");                      &Apache::loncommon::end_data_table_row()."\n");
         }          }
         $r->print('</table>'."\n".'</table>'."\n");          $r->print(&Apache::loncommon::end_data_table()."\n");
         $r->rflush();          $r->rflush();
     }      }
     return;      return;
Line 844  sub output_html_stats { Line 854  sub output_html_stats {
     my $count=0;      my $count=0;
     foreach my $data (@StatsArray) {      foreach my $data (@StatsArray) {
         if ($count++ % 50 == 0) {          if ($count++ % 50 == 0) {
             $r->print("</table>\n</table>\n");              $r->print(&Apache::loncommon::end_data_table());
             $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n".              $r->print(&Apache::loncommon::start_data_table().
                       '<table border="0" cellpadding="3">'."\n".                      &Apache::loncommon::start_data_table_row().
                       '<tr bgcolor="#FFFFE6">'.                      &statistics_table_header().
                       '<tr bgcolor="#FFFFE6">'.                      &Apache::loncommon::end_data_table_row());
                       &statistics_table_header().          }
                       "</tr>\n");          $r->print(&Apache::loncommon::start_data_table_row().
         }                  &statistics_html_table_data($data).
         $r->print('<tr>'.&statistics_html_table_data($data)."</tr>\n");                  &Apache::loncommon::end_data_table_row());
     }      }
     $r->print("</table>\n</table>\n");      $r->print(&Apache::loncommon::end_data_table_row());
     return;      return;
 }  }
   
Line 871  sub html_preamble { Line 881  sub html_preamble {
                            &Apache::lonlocal::locallocaltime($endtime)                             &Apache::lonlocal::locallocaltime($endtime)
                            ).'</h3>';                             ).'</h3>';
     }      }
     $Str .= "<h3>".&mt('Compiled on [_1]',      $Str .= "<p>".&mt('Compiled on [_1]',
                        &Apache::lonlocal::locallocaltime(time))."</h3>";                         &Apache::lonlocal::locallocaltime(time))."</p>";
     return $Str;      return $Str;
 }  }
   
Line 890  sub statistics_html_table_data { Line 900  sub statistics_html_table_data {
     foreach my $field (@Fields) {      foreach my $field (@Fields) {
         next if ($options =~ /no $field->{'name'}/);          next if ($options =~ /no $field->{'name'}/);
         next if ($field->{'selected'} ne 'yes');          next if ($field->{'selected'} ne 'yes');
         $row .= '<td bgcolor="'.$field->{'color'}.'"';          $row .= '<td style="background-color:'.$field->{'color'}.'"';
         if (exists($field->{'align'})) {          if (exists($field->{'align'})) {
             $row .= ' align="'.$field->{'align'}.'"';              $row .= ' align="'.$field->{'align'}.'"';
             }              }
Line 918  sub statistics_table_header { Line 928  sub statistics_table_header {
         next if ($options =~ /no $field->{'name'}/);          next if ($options =~ /no $field->{'name'}/);
         next if ($field->{'selected'} ne 'yes');          next if ($field->{'selected'} ne 'yes');
         $header_row .= '<th>';          $header_row .= '<th>';
           my $header_row_text = &mt($field->{'title'});
         if (exists($field->{'sortable'}) && $field->{'sortable'} eq 'yes') {          if (exists($field->{'sortable'}) && $field->{'sortable'} eq 'yes') {
             $header_row .= '<a href="javascript:'.              $header_row .=
                   '<a href="javascript:'.
                 'document.Statistics.sortby.value='."'".$field->{'name'}."'".                  'document.Statistics.sortby.value='."'".$field->{'name'}."'".
                     ';document.Statistics.submit();">';                  ';document.Statistics.submit();">'.
         }                  $header_row_text.
         $header_row .= &mt($field->{'title'});                  '</a>';
         if ($options =~ /sortable/) {          } else {
             $header_row.= '</a>';              $header_row .= $header_row_text;
         }          }
         if ($options !~ /no plots/        &&           if ($options !~ /no plots/        && 
             exists($field->{'graphable'}) &&               exists($field->{'graphable'}) && 
Line 942  sub statistics_table_header { Line 954  sub statistics_table_header {
 }  }
   
 sub sequence_html_header {  sub sequence_html_header {
     my $Str .= '<tr>';      my $Str .= &Apache::loncommon::start_data_table_header_row();
     foreach my $field (@SeqFields) {      foreach my $field (@SeqFields) {
 #        next if ($field->{'selected'} ne 'yes');  #        next if ($field->{'selected'} ne 'yes');
         $Str .= '<th bgcolor="'.$field->{'color'}.'"';          $Str .= '<th bgcolor="'.$field->{'color'}.'"';
         $Str .= '>'.$field->{'title'}.'</th>';          $Str .= '>'.&mt($field->{'title'}).'</th>';
     }      }
     $Str .= '</tr>';      $Str .= &Apache::loncommon::end_data_table_header_row();
     return $Str;      return $Str;
 }  }
   
Line 956  sub sequence_html_header { Line 968  sub sequence_html_header {
 sub sequence_html_output {  sub sequence_html_output {
     my ($seq) = @_;      my ($seq) = @_;
     my $data = $SeqStat{$seq->symb};      my $data = $SeqStat{$seq->symb};
     my $row = '<tr>';      my $row = &Apache::loncommon::start_data_table_row();
     foreach my $field (@SeqFields) {      foreach my $field (@SeqFields) {
         next if ($field->{'selected'} ne 'yes');          next if ($field->{'selected'} ne 'yes');
         $row .= '<td bgcolor="'.$field->{'color'}.'"';          $row .= '<td bgcolor="'.$field->{'color'}.'"';
Line 971  sub sequence_html_output { Line 983  sub sequence_html_output {
         }          }
         $row .= '</td>';          $row .= '</td>';
     }      }
     $row .= '</tr>'."\n";      $row .= &Apache::loncommon::end_data_table_row()."\n";
     return $row;      return $row;
 }  }
   
Line 1002  sub make_single_stat_plot { Line 1014  sub make_single_stat_plot {
     my $title; my $yaxis;      my $title; my $yaxis;
     foreach my $field (@Fields) {      foreach my $field (@Fields) {
         next if ($field->{'name'} ne $datafield);          next if ($field->{'name'} ne $datafield);
         $title = $field->{'long_title'};          $title = &mt($field->{'long_title'});
         $yaxis = $field->{'title'};          $yaxis = &mt($field->{'title'});
         last;          last;
     }      }
     if ($title eq '' || $yaxis eq '') {      if ($title eq '' || $yaxis eq '') {
         # datafield is something we do not know enough about to plot          # datafield is something we do not know enough about to plot
         $r->print('<h3>'.          $r->print('<p class="LC_warning">'.
                   &mt('Unable to plot the requested statistic.').                    &mt('Unable to plot the requested statistic.').
                   '</h3>');                    '</p>');
         return;          return;
     }      }
     #      #
     # Build up the data sets to plot      # Build up the data sets to plot
     my @Labels;       my @Labels;
     my @Data;      my @Data;
     my $max = 1;      my $max = 1;
     foreach my $data (@StatsArray) {      foreach my $data (@StatsArray) {
Line 1037  sub make_single_stat_plot { Line 1049  sub make_single_stat_plot {
     }      }
     #      #
     $r->print("<p>".&Apache::loncommon::DrawBarGraph($title,      $r->print("<p>".&Apache::loncommon::DrawBarGraph($title,
                                                      'Problem Number',                                                       &mt('Problem Number'),
                                                      $yaxis,                                                       $yaxis,
                                                      $max,                                                       $max,
                                                      undef, # colors                                                       undef, # colors
Line 1055  sub degrees_plot { Line 1067  sub degrees_plot {
     my $plot = '';      my $plot = '';
     my $ymax = 0;      my $ymax = 0;
     my $ymin = 0;      my $ymin = 0;
     my @Disc; my @Diff; my @Labels;          my @Disc; my @Diff; my @Labels;
     foreach my $data (@StatsArray) {      foreach my $data (@StatsArray) {
         push(@Labels,$data->{'problem_num'});          push(@Labels,$data->{'problem_num'});
         my $disc = $data->{'deg_of_disc'};          my $disc = $data->{'deg_of_disc'};
Line 1102  sub degrees_plot { Line 1114  sub degrees_plot {
     my $diffdata .= '<data>'.join(',',@Labels).'</data>'.$/.      my $diffdata .= '<data>'.join(',',@Labels).'</data>'.$/.
                     '<data>'.join(',',@Diff).'</data>'.$/;                      '<data>'.join(',',@Diff).'</data>'.$/;
     #      #
     my $title = 'Degree of Discrimination\nand Degree of Difficulty';      my $title = &mt('Degree of Discrimination[_1]and Degree of Difficulty','\n');
     if ($xmax > 50) {      if ($xmax > 50) {
         $title = 'Degree of Discrimination and Degree of Difficulty';          $title = &mt('Degree of Discrimination and Degree of Difficulty');
     }      }
       my %lt = &Apache::lonlocal::texthash(
           'alttag' => 'Degree of Discrimination and Degree of Difficulty Plot',
           'xlabel' => 'Problem Number',
       );
     #      #
     $plot=<<"END";      $plot=<<"END";
 <gnuplot   <gnuplot 
Line 1117  sub degrees_plot { Line 1133  sub degrees_plot {
     align="center"      align="center"
     border="on"      border="on"
     transparent="on"      transparent="on"
     alttag="Degree of Discrimination and Degree of Difficulty Plot"      alttag="$lt{'alttag'}"
     samples="100"      samples="100"
     bgcolor="xffffff"      bgcolor="xffffff"
     height="$height"      height="$height"
Line 1128  sub degrees_plot { Line 1144  sub degrees_plot {
         box="off" />          box="off" />
     <title>$title</title>      <title>$title</title>
     <axis xmin="0" ymin="$ymin" xmax="$xmax" ymax="$ymax" color="x000000" />      <axis xmin="0" ymin="$ymin" xmax="$xmax" ymax="$ymax" color="x000000" />
     <xlabel>Problem Number</xlabel>      <xlabel>$lt{'xlabel'}</xlabel>
     <curve       <curve 
         linestyle="linespoints"           linestyle="linespoints" 
         name="DoDisc"           name="DoDisc" 
Line 1145  sub degrees_plot { Line 1161  sub degrees_plot {
     </curve>      </curve>
 </gnuplot>  </gnuplot>
 END  END
     my $plotresult =       my $plotresult =
         '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/;          '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/;
     $r->print($plotresult);      $r->print($plotresult);
     return;      return;
Line 1190  sub tries_data_plot { Line 1206  sub tries_data_plot {
                           '<data>'.join(',',@Mean).'</data>'.$/.                            '<data>'.join(',',@Mean).'</data>'.$/.
                           '<data>'.join(',',@STD).'</data>'.$/;                            '<data>'.join(',',@STD).'</data>'.$/;
     #      #
     my $title = 'Mean and S.D. of Tries';      my $title = &mt('Mean and S.D. of Tries');
     if ($xmax > 25) {      if ($xmax > 30) {
         $title = 'Mean and Standard Deviation of Tries';          $title = &mt('Mean and Standard Deviation of Tries');
     }      }
     #      #
       my %lt = &Apache::lonlocal::texthash(
           'alttag' => 'Mean and S.D of Tries Plot',
           'xlabel' => 'Problem Number',
           'ylabel' => 'Number of Tries',
       );
     $plot=<<"END";      $plot=<<"END";
 <gnuplot   <gnuplot 
     texfont="10"      texfont="10"
Line 1205  sub tries_data_plot { Line 1226  sub tries_data_plot {
     align="center"      align="center"
     border="on"      border="on"
     transparent="on"      transparent="on"
     alttag="Mean and S.D of Tries Plot"      alttag="$lt{'alttag'}"
     samples="100"      samples="100"
     bgcolor="xffffff"      bgcolor="xffffff"
     height="$height"      height="$height"
     width="$width">      width="$width">
     <title>$title</title>      <title>$title</title>
     <axis xmin="0" ymin="0" xmax="$xmax" ymax="$ymax" color="x000000" />      <axis xmin="0" ymin="0" xmax="$xmax" ymax="$ymax" color="x000000" />
     <xlabel>Problem Number</xlabel>      <xlabel>$lt{'xlabel'}</xlabel>
     <ylabel>Number of Tries</ylabel>      <ylabel>$lt{'ylabel'}</ylabel>
     <curve       <curve 
         linestyle="yerrorbars"          linestyle="yerrorbars"
         name="S.D. Tries"           name="S.D. Tries" 
Line 1230  sub tries_data_plot { Line 1251  sub tries_data_plot {
     </curve>      </curve>
 </gnuplot>  </gnuplot>
 END  END
     my $plotresult =       my $plotresult =
         '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/;          '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/;
     $r->print($plotresult);      $r->print($plotresult);
     return;      return;
Line 1238  END Line 1259  END
   
 sub plot_dropdown {  sub plot_dropdown {
     my $current = '';      my $current = '';
       my $title;
     #      #
     if (defined($env{'form.plot'})) {      if (defined($env{'form.plot'})) {
         $current = $env{'form.plot'};          $current = $env{'form.plot'};
Line 1253  sub plot_dropdown { Line 1275  sub plot_dropdown {
     #      #
     my $Str= "\n".'<select name="plot" size="1">';      my $Str= "\n".'<select name="plot" size="1">';
     $Str .= '<option name="none"></option>'."\n";      $Str .= '<option name="none"></option>'."\n";
     $Str .= '<option name="none2">none</option>'."\n";      $Str .= '<option name="none2">'.&mt('none').'</option>'."\n";
     foreach my $field (@Additional_Plots,@Fields) {      foreach my $field (@Additional_Plots,@Fields) {
         if (! exists($field->{'graphable'}) ||          if (! exists($field->{'graphable'}) ||
             $field->{'graphable'} ne 'yes') {              $field->{'graphable'} ne 'yes') {
Line 1261  sub plot_dropdown { Line 1283  sub plot_dropdown {
         }          }
         $Str .= '<option value="'.$field->{'name'}.'"';          $Str .= '<option value="'.$field->{'name'}.'"';
         if ($field->{'name'} eq $current) {          if ($field->{'name'} eq $current) {
             $Str .= ' selected ';              $Str .= ' selected="selected"';
         }          }
         $Str.= '>'.&mt($field->{'title'}).'</option>'."\n";          $title = &mt($field->{'long_title'});
           $title = &mt($field->{'title'}) if (!$title);
           $Str.= '>'.$title.'</option>'."\n";
     }      }
     $Str .= '</select>'."\n";      $Str .= '</select>'."\n";
     return $Str;      return $Str;
Line 1321  sub Excel_output { Line 1345  sub Excel_output {
     # Time restrictions      # Time restrictions
     my $time_string;      my $time_string;
     if (defined($starttime)) {      if (defined($starttime)) {
         # call localtime but not lonlocal:locallocaltime because excel probably  
         # cannot handle localized text.  Probably.  
         $time_string .= 'Data collected from '.localtime($time_string);  
         if (defined($endtime)) {          if (defined($endtime)) {
             $time_string .= ' to '.localtime($endtime);              $time_string .=  &mt('Data collected from [_1] to [_2]',
                                    &Apache::lonlocal::locallocaltime($starttime),
                                    &Apache::lonlocal::locallocaltime($endtime));
           } else {
               $time_string .=  &mt('Data collected from [_1]',
                                    &Apache::lonlocal::locallocaltime($starttime));
         }          }
         $time_string .= '.';  
     } elsif (defined($endtime)) {      } elsif (defined($endtime)) {
         # See note above about lonlocal:locallocaltime          $time_string .=  &mt('Data collected before [_1]',
         $time_string .= 'Data collected before '.localtime($endtime).'.';                               &Apache::lonlocal::locallocaltime($endtime));
     }      }
     if (defined($time_string)) {      if (defined($time_string)) {
         $excel_sheet->write($rows_output,$cols_output++,$time_string);          $excel_sheet->write($rows_output,$cols_output++,$time_string);
Line 1339  sub Excel_output { Line 1364  sub Excel_output {
     #      #
     # Put the date in there too      # Put the date in there too
     $excel_sheet->write($rows_output,$cols_output++,      $excel_sheet->write($rows_output,$cols_output++,
                         'Compiled on '.localtime(time));                          &mt('Compiled on [_1]',&Apache::lonlocal::locallocaltime(time)));
     #      #
     $rows_output++;       $rows_output++;
     $cols_output=0;      $cols_output=0;
     ##      ##
     ## Sequence Statistics      ## Sequence Statistics
     ##       ##
     &write_headers($excel_sheet,$format,\$rows_output,\$cols_output,      &write_headers($excel_sheet,$format,\$rows_output,\$cols_output,
                    \@SeqFields);                     \@SeqFields);
     foreach my $seq (@sequences) {      foreach my $seq (@sequences) {
Line 1423  sub write_headers { Line 1448  sub write_headers {
     foreach my $field (@{$Fields}) {      foreach my $field (@{$Fields}) {
         next if ($field->{'selected'} ne 'yes');          next if ($field->{'selected'} ne 'yes');
         next if ($field->{'name'} eq 'problem_num');          next if ($field->{'name'} eq 'problem_num');
         # Use english for excel as I am not sure how well excel handles           # Use english for excel as I am not sure how well excel handles
         # other character sets....          # other character sets....
         $excel_sheet->write($$rows_output,$$cols_output,          $excel_sheet->write($$rows_output,$$cols_output,
                             $field->{'title'},                              $field->{'title'},
Line 1447  sub compute_statistics_on_sequence { Line 1472  sub compute_statistics_on_sequence {
     my @Data;      my @Data;
     foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq)) {      foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq)) {
         foreach my $part (@{$res->parts}) {          foreach my $part (@{$res->parts}) {
             next if ($res->is_survey($part));              next if (($res->is_survey($part)) || ($res->is_anonsurvey($part))) ;
             #              #
             # This is where all the work happens              # This is where all the work happens
             my $data = &get_statistics($seq,$res,$part,scalar(@StatsArray)+1);              my $data = &get_statistics($seq,$res,$part,scalar(@StatsArray)+1);
Line 1536  sub sort_data { Line 1561  sub sort_data {
   
 =item &get_statistics()  =item &get_statistics()
   
 Wrapper routine from the call to loncoursedata::get_problem_statistics.    Wrapper routine from the call to loncoursedata::get_problem_statistics.
 Calls lonstathelpers::get_time_limits() to limit the data set by time  Calls lonstathelpers::get_time_limits() to limit the data set by time
 and &compute_discrimination_factor  and &compute_discrimination_factor
   
 Inputs: $sequence, $resource, $part, $problem_num  Inputs: $sequence, $resource, $part, $problem_num
   
 Returns: Hash reference with statistics data from   Returns: Hash reference with statistics data from
 loncoursedata::get_problem_statistics.  loncoursedata::get_problem_statistics.
   
 =cut  =cut
Line 1570  sub get_statistics { Line 1595  sub get_statistics {
         &escape($resource->symb);          &escape($resource->symb);
     #      #
     if ($SelectedFields{'deg_of_disc'}) {      if ($SelectedFields{'deg_of_disc'}) {
         $data->{'deg_of_disc'} =           $data->{'deg_of_disc'} =
             &compute_discrimination_factor($resource,$part,$sequence);              &compute_discrimination_factor($resource,$part,$sequence);
     }      }
     #      #
Line 1582  sub get_statistics { Line 1607  sub get_statistics {
         $data->{'sections'}=$sections;          $data->{'sections'}=$sections;
         $data->{'course'} = $env{'request.course.id'};          $data->{'course'} = $env{'request.course.id'};
         my $urlres=(&Apache::lonnet::decode_symb($resource->symb))[2];          my $urlres=(&Apache::lonnet::decode_symb($resource->symb))[2];
         $data->{'urlres'}=$urlres;          my %storestats =
         my %storestats =   
             &LONCAPA::lonmetadata::dynamic_metadata_storage($data);              &LONCAPA::lonmetadata::dynamic_metadata_storage($data);
         my ($dom,$user) = ($urlres=~m{^($LONCAPA::domain_re)/($LONCAPA::username_re)});           my ($dom,$user) = ($urlres=~m{^($LONCAPA::domain_re)/($LONCAPA::username_re)});
         &Apache::lonnet::put('nohist_resevaldata',\%storestats,$dom,$user);          &Apache::lonnet::put('nohist_resevaldata',\%storestats,$dom,$user);
     }      }
     #      #
Line 1599  sub get_statistics { Line 1623  sub get_statistics {
 #    my $hinttries = &Apache::lonnet::EXT('resource.'.$part.'.hinttries',$symb);  #    my $hinttries = &Apache::lonnet::EXT('resource.'.$part.'.hinttries',$symb);
     my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',$symb);      my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',$symb);
     $data->{'weight'} = $weight;      $data->{'weight'} = $weight;
 #    $data->{'duedate'} = $duedate;   #    $data->{'duedate'} = $duedate;
 #    $data->{'opendate'} = $opendate;  #    $data->{'opendate'} = $opendate;
 #    $data->{'maxtries'} = $maxtries;  #    $data->{'maxtries'} = $maxtries;
 #    $data->{'hinttries'} = $hinttries;  #    $data->{'hinttries'} = $hinttries;
Line 1633  sub compute_discrimination_factor { Line 1657  sub compute_discrimination_factor {
     #      #
     # rank      # rank
     my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();      my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
     my $ranking =       my $ranking =
         &Apache::loncoursedata::rank_students_by_scores_on_resources          &Apache::loncoursedata::rank_students_by_scores_on_resources
         (\@Resources,          (\@Resources,
          [&Apache::lonstatistics::get_selected_sections()],           [&Apache::lonstatistics::get_selected_sections()],
Line 1644  sub compute_discrimination_factor { Line 1668  sub compute_discrimination_factor {
     # compute their percent scores on the problems in the sequence,      # compute their percent scores on the problems in the sequence,
     my $number_to_grab = int(scalar(@{$ranking})/4);      my $number_to_grab = int(scalar(@{$ranking})/4);
     my $num_students = scalar(@{$ranking});      my $num_students = scalar(@{$ranking});
     my @BottomSet = map { $_->[&Apache::loncoursedata::RNK_student()];       my @BottomSet = map { $_->[&Apache::loncoursedata::RNK_student()];
                       } @{$ranking}[0..$number_to_grab];                        } @{$ranking}[0..$number_to_grab];
     my @TopSet    =       my @TopSet    =
         map {           map {
             $_->[&Apache::loncoursedata::RNK_student()];               $_->[&Apache::loncoursedata::RNK_student()];
           } @{$ranking}[-$number_to_grab..0];            } @{$ranking}[-$number_to_grab..0];
     if (! @BottomSet || (@BottomSet == 1 && $BottomSet[0] eq '') ||      if (! @BottomSet || (@BottomSet == 1 && $BottomSet[0] eq '') ||
         ! @TopSet    || (@TopSet    == 1 && $TopSet[0]    eq '')) {          ! @TopSet    || (@TopSet    == 1 && $TopSet[0]    eq '')) {
         return 'nan';          return 'nan';
     }      }
     my ($bottom_sum,$bottom_max) =       my ($bottom_sum,$bottom_max) =
         &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@BottomSet,          &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@BottomSet,
                                                   undef,$starttime,$endtime);                                                    undef,$starttime,$endtime);
     my ($top_sum,$top_max) =       my ($top_sum,$top_max) =
         &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@TopSet,          &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@TopSet,
                                                   undef,$starttime,$endtime);                                                    undef,$starttime,$endtime);
     my $deg_of_disc;      my $deg_of_disc;
Line 1680  sub compute_discrimination_factor { Line 1704  sub compute_discrimination_factor {
 ##  ##
 ## K=the number of items in your test  ## K=the number of items in your test
 ## M=the mean score on the test  ## M=the mean score on the test
 ## s=the standard deviation of the scores on your test   ## s=the standard deviation of the scores on your test
 ##  ##
 ## then:  ## then:
 ##   ##
 ## KR-21 rk= [K/(K-1)] * [1- (M*(K-M))/(K*s^2))]  ## KR-21 rk= [K/(K-1)] * [1- (M*(K-M))/(K*s^2))]
 ##  ##
 ###############################################  ###############################################
Line 1700  sub compute_sequence_statistics { Line 1724  sub compute_sequence_statistics {
     my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();      my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
     #      #
     # First compute statistics based on student scores      # First compute statistics based on student scores
     my ($smin,$smax,$sMean,$sSTD,$scount,$sMAX) =       my ($smin,$smax,$sMean,$sSTD,$scount,$sMAX) =
         &Apache::loncoursedata::score_stats          &Apache::loncoursedata::score_stats
                     ([&Apache::lonstatistics::get_selected_sections()],                      ([&Apache::lonstatistics::get_selected_sections()],
                      [&Apache::lonstatistics::get_selected_groups()],                       [&Apache::lonstatistics::get_selected_groups()],
Line 1715  sub compute_sequence_statistics { Line 1739  sub compute_sequence_statistics {
     $SeqStat{$symb}->{'max_possible'} = $sMAX;      $SeqStat{$symb}->{'max_possible'} = $sMAX;
     #      #
     # Compute statistics based on the number of correct problems      # Compute statistics based on the number of correct problems
     # 'correct' is taken to mean       # 'correct' is taken to mean
     my ($cmin,$cmax,$cMean,$cSTD,$ccount)=      my ($cmin,$cmax,$cMean,$cSTD,$ccount)=
         &Apache::loncoursedata::count_stats          &Apache::loncoursedata::count_stats
         ([&Apache::lonstatistics::get_selected_sections()],          ([&Apache::lonstatistics::get_selected_sections()],

Removed from v.1.114  
changed lines
  Added in v.1.125


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>