--- loncom/interface/statistics/lonproblemstatistics.pm 2006/12/06 22:22:38 1.111 +++ loncom/interface/statistics/lonproblemstatistics.pm 2017/12/18 23:51:19 1.127 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonproblemstatistics.pm,v 1.111 2006/12/06 22:22:38 albertel Exp $ +# $Id: lonproblemstatistics.pm,v 1.127 2017/12/18 23:51:19 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -52,6 +52,7 @@ package Apache::lonproblemstatistics; use strict; use Apache::lonnet; use Apache::loncommon(); +use Apache::lonquickgrades(); use Apache::lonhtmlcommon; use Apache::loncoursedata; use Apache::lonstatistics; @@ -73,6 +74,14 @@ my %SeqStat; # keys are symbs, values ## header for plots created with Graph.pm, both of which more than likely do ## 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. +## # # ## @@ -84,7 +93,7 @@ my %SeqStat; # keys are symbs, values ## title yes any scalar This is what the user sees to identify ## the field. Passed through &mt(). ## 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 ## color yes html color HTML cell background color ## used to visually group statistics @@ -123,11 +132,11 @@ my @Fields = ( align => 'left', color => '#FFFFE6', special => 'link', - sortable => 'yes', + sortable => 'yes', selectable => 'no', defaultselected => 'yes', }, - { name => 'part', + { name => 'part', title => 'Part', align => 'left', color => '#FFFFE6', @@ -174,7 +183,7 @@ my @Fields = ( format => '%d', sortable => 'yes', graphable => 'yes', - long_title => 'Minumum Number of Tries', + long_title => 'Minimum Number of Tries', selectable => 'yes', defaultselected => 'yes', }, @@ -274,7 +283,7 @@ my @Fields = ( sortable => 'yes', graphable => 'yes', long_title => 'Degree of Difficulty'. - '[ 1 - ((#YES+#yes) / Tries) ]', + ' ~[ 1 - ((#YES+#yes) / Tries) ~]', selectable => 'yes', defaultselected => 'yes', }, @@ -375,7 +384,7 @@ my @SeqFields = ( align => 'left', color => '#FFFFE6', special => 'no', - sortable => 'no', + sortable => 'no', selectable => 'yes', defaultselected => 'no', }, @@ -430,7 +439,7 @@ my @SeqFields = ( format => '%4.2f', sortable => 'no', graphable => 'no', - long_title => 'Minumum Sequence Score', + long_title => 'Minimum Sequence Score', selectable => 'yes', defaultselected => 'no', }, @@ -485,7 +494,7 @@ my @SeqFields = ( format => '%4.2f', sortable => 'no', graphable => 'no', - long_title => 'Minumum Number of Correct Problems', + long_title => 'Minimum Number of Correct Problems', selectable => 'yes', defaultselected => 'no', }, @@ -510,7 +519,7 @@ my @SeqFields = ( long_title => 'KR-21 reliability statistic', selectable => 'yes', defaultselected => 'no', - }, + }, ); my %SelectedFields; @@ -577,15 +586,15 @@ sub parse_field_selection { } sub field_selection_input { - my $Str = '<select name="fieldselections" multiple size="5">'."\n"; - $Str .= '<option value="all">all</option>'."\n"; + my $Str = '<select name="fieldselections" multiple="multiple" size="5">'."\n"; + $Str .= '<option value="all">'.&mt('all').'</option>'."\n"; foreach my $field (@Fields) { next if ($field->{'selectable'} ne 'yes'); $Str .= ' <option value="'.$field->{'name'}.'" '; if ($field->{'selected'} eq 'yes') { - $Str .= 'selected '; + $Str .= 'selected="selected" '; } - $Str .= '>'.$field->{'title'}.'</option>'."\n"; + $Str .= '>'.&mt($field->{'title'}).'</option>'."\n"; } $Str .= "</select>\n"; } @@ -610,42 +619,41 @@ sub CreateInterface { &parse_field_selection(); # my $Str = ''; - $Str .= &Apache::lonhtmlcommon::breadcrumbs('Overall Problem Statistics', - 'Statistics_Overall_Key'); - $Str .= '<table cellspacing="5">'."\n"; - $Str .= '<tr>'; - $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>'; - $Str .= '<td align="center"><b>'.&mt('Groups').'</b></td>'; - $Str .= '<td align="center"><b>'.&mt('Access Status').'</b></td>'; - $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>'; - $Str .= '<td align="center"><b>'.&mt('Statistics').'</b></td>'; - $Str .= '<td rowspan="2">'. - &Apache::lonstathelpers::limit_by_time_form().'</td>'; - $Str .= '</tr>'."\n"; + $Str .= &Apache::loncommon::start_data_table(); + $Str .= &Apache::loncommon::start_data_table_header_row(); + $Str .= '<th>'.&mt('Sections').'</th>'; + $Str .= '<th>'.&mt('Groups').'</th>'; + $Str .= '<th>'.&mt('Access Status').'</th>'; + $Str .= '<th>'.&mt('Sequences and Folders').'</th>'; + $Str .= '<th>'.&mt('Statistics').'</th>'; + $Str .= '<th>'.&mt('Plot Graph').'</th>'; + $Str .= '<th>'.&mt('Time Period').'</th>'; + $Str .= &Apache::loncommon::end_data_table_header_row(); # - $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 .= '</td><td align="center">'; + $Str .= '</td><td align="center" valign="top">'; $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 .= '</td><td align="center">'; + $Str .= '</td><td align="center" valign="top">'; # $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5); - $Str .= '</td><td>'.&field_selection_input(); - $Str .= '</td></tr>'."\n"; - $Str .= '</table>'."\n"; - # - $Str .= '<p>'.&mt('Status: [_1]', - '<input type="text" '. - 'name="stats_status" size="60" value="" />' - ). - '</nobr></p>'; + $Str .= '</td><td align="center" valign="top">'; + $Str .= &field_selection_input(); + $Str .= '</td><td align="center" valign="top">'; + $Str .= &plot_dropdown(); + $Str .= "\n"; + $Str .= '</td><td align="center" valign="top">'; + $Str .= &Apache::lonstathelpers::limit_by_time_form(); + $Str .= '</td>'."\n"; + $Str .= &Apache::loncommon::end_data_table_row(); + $Str .= &Apache::loncommon::end_data_table(); # $Str .= '<input type="submit" name="GenerateStatistics" value="'. &mt('Generate Statistics').'" />'; - $Str .= ' 'x5; - $Str .= 'Plot '.&plot_dropdown().(' 'x10); + $Str .= (' 'x10); # return $Str; } @@ -695,12 +703,16 @@ sub BuildProblemStatisticsPage { undef(%SeqStat); # # 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); $r->print($interface); $r->print('<input type="hidden" name="sortby" value="'.$env{'form.sortby'}. '" />'); # - my @CacheButtonHTML = + my @CacheButtonHTML = &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status'); my $Str; foreach my $html (@CacheButtonHTML) { @@ -709,12 +721,13 @@ sub BuildProblemStatisticsPage { # $r->print($Str); if (! exists($env{'form.firstrun'})) { - $r->print('<h3>'. + $r->print('<p class="LC_info"><b>'. &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 '. - 'for the first analysis. Future analysis this session '. - ' will not have this delay.'). + 'for the first analysis. Future analysis this session '. + 'will not have this delay.'). '</p>'); &clean_up(); return; @@ -725,38 +738,39 @@ sub BuildProblemStatisticsPage { # it does not slow things down noticably. &Apache::loncoursedata::populate_weight_table(); # - ($navmap,@sequences) = + ($navmap,@sequences) = &Apache::lonstatistics::selected_sequences_with_assessments(); if (! ref($navmap)) { - $r->print('<h1>'.&mt('A course-wide error occured.').'</h1>'. + $r->print('<div class="LC_error">'.&mt('A course-wide error occurred.').'</div>'. '<h3>'.$navmap.'</h3>'); &clean_up(); return; } if (exists($env{'form.Excel'})) { - $r->print('<h4>'. + $r->print('<p>'. &Apache::lonstatistics::section_and_enrollment_description(). - '</h4>'); + '</p>'); &Excel_output($r); - } else { + } else { $r->print('<input type="submit" name="Excel" value="'. &mt('Produce Excel Output').'" />'.' 'x5); $r->rflush(); - $r->print('<h4>'. + $r->print('<p>'. &Apache::lonstatistics::section_and_enrollment_description(). - '</h4>'); + '</p>'); my $count = 0; + my $include_tools = 1; foreach my $seq (@sequences) { - my @resources = - &Apache::lonstathelpers::get_resources($navmap,$seq); + my @resources = + &Apache::lonstathelpers::get_resources($navmap,$seq,$include_tools); $count += scalar(@resources); } if ($count > 10) { - $r->print('<h2>'. - &mt('Compiling statistics for [_1] problems',$count). - '</h2>'); + $r->print('<p>'. + &mt('Compiling statistics for [quant,_1,problem]',$count). + '</p>'); 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(); } @@ -788,17 +802,14 @@ sub output_sequence_statistics { $r->print('<h2>'.&mt('Sequence Statistics'). &Apache::loncommon::help_open_topic('Statistics_Sequence'). '</h2>'); - $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n". - '<table border="0" cellpadding="3">'."\n". - '<tr bgcolor="#FFFFE6">'); + $r->print(&Apache::loncommon::start_data_table()); $r->print(&sequence_html_header()); - foreach my $seq (@sequences) { + foreach my $seq (@sequences) { last if ($c->aborted); &compute_sequence_statistics($seq); $r->print(&sequence_html_output($seq)); } - $r->print('</table>'); - $r->print('</table>'); + $r->print(&Apache::loncommon::end_data_table()); $r->rflush(); return; } @@ -814,22 +825,22 @@ sub output_sequence_statistics { sub output_html_by_sequence { my ($r) = @_; my $c = $r->connection(); - $r->print(&html_preamble()); + $r->print('<br />'.&html_preamble()); # foreach my $seq (@sequences) { last if ($c->aborted); $r->print("<h3>".$seq->compTitle."</h3>". - '<table border="0"><tr><td bgcolor="#777777">'."\n". - '<table border="0" cellpadding="3">'."\n". - '<tr bgcolor="#FFFFE6">'. - &statistics_table_header('no container')."</tr>\n"); + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + &statistics_table_header('no container'). + &Apache::loncommon::end_data_table_header_row()."\n"); my @Data = &compute_statistics_on_sequence($seq); foreach my $data (@Data) { - $r->print('<tr>'.&statistics_html_table_data($data, - 'no container'). - "</tr>\n"); + $r->print(&Apache::loncommon::start_data_table_row(). + &statistics_html_table_data($data,'no container'). + &Apache::loncommon::end_data_table_row()."\n"); } - $r->print('</table>'."\n".'</table>'."\n"); + $r->print(&Apache::loncommon::end_data_table()."\n"); $r->rflush(); } return; @@ -844,17 +855,17 @@ sub output_html_stats { my $count=0; foreach my $data (@StatsArray) { if ($count++ % 50 == 0) { - $r->print("</table>\n</table>\n"); - $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n". - '<table border="0" cellpadding="3">'."\n". - '<tr bgcolor="#FFFFE6">'. - '<tr bgcolor="#FFFFE6">'. - &statistics_table_header(). - "</tr>\n"); - } - $r->print('<tr>'.&statistics_html_table_data($data)."</tr>\n"); + $r->print(&Apache::loncommon::end_data_table()); + $r->print(&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + &statistics_table_header(). + &Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::start_data_table_row(). + &statistics_html_table_data($data). + &Apache::loncommon::end_data_table_row()); } - $r->print("</table>\n</table>\n"); + $r->print(&Apache::loncommon::end_data_table_row()); return; } @@ -871,8 +882,8 @@ sub html_preamble { &Apache::lonlocal::locallocaltime($endtime) ).'</h3>'; } - $Str .= "<h3>".&mt('Compiled on [_1]', - &Apache::lonlocal::locallocaltime(time))."</h3>"; + $Str .= "<p>".&mt('Compiled on [_1]', + &Apache::lonlocal::locallocaltime(time))."</p>"; return $Str; } @@ -890,7 +901,7 @@ sub statistics_html_table_data { foreach my $field (@Fields) { next if ($options =~ /no $field->{'name'}/); next if ($field->{'selected'} ne 'yes'); - $row .= '<td bgcolor="'.$field->{'color'}.'"'; + $row .= '<td style="background-color:'.$field->{'color'}.'"'; if (exists($field->{'align'})) { $row .= ' align="'.$field->{'align'}.'"'; } @@ -918,14 +929,16 @@ sub statistics_table_header { next if ($options =~ /no $field->{'name'}/); next if ($field->{'selected'} ne 'yes'); $header_row .= '<th>'; + my $header_row_text = &mt($field->{'title'}); 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.submit();">'; - } - $header_row .= &mt($field->{'title'}); - if ($options =~ /sortable/) { - $header_row.= '</a>'; + ';document.Statistics.submit();">'. + $header_row_text. + '</a>'; + } else { + $header_row .= $header_row_text; } if ($options !~ /no plots/ && exists($field->{'graphable'}) && @@ -942,13 +955,13 @@ sub statistics_table_header { } sub sequence_html_header { - my $Str .= '<tr>'; + my $Str .= &Apache::loncommon::start_data_table_header_row(); foreach my $field (@SeqFields) { # next if ($field->{'selected'} ne 'yes'); $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; } @@ -956,7 +969,7 @@ sub sequence_html_header { sub sequence_html_output { my ($seq) = @_; my $data = $SeqStat{$seq->symb}; - my $row = '<tr>'; + my $row = &Apache::loncommon::start_data_table_row(); foreach my $field (@SeqFields) { next if ($field->{'selected'} ne 'yes'); $row .= '<td bgcolor="'.$field->{'color'}.'"'; @@ -971,7 +984,7 @@ sub sequence_html_output { } $row .= '</td>'; } - $row .= '</tr>'."\n"; + $row .= &Apache::loncommon::end_data_table_row()."\n"; return $row; } @@ -1002,20 +1015,20 @@ sub make_single_stat_plot { my $title; my $yaxis; foreach my $field (@Fields) { next if ($field->{'name'} ne $datafield); - $title = $field->{'long_title'}; - $yaxis = $field->{'title'}; + $title = &mt($field->{'long_title'}); + $yaxis = &mt($field->{'title'}); last; } if ($title eq '' || $yaxis eq '') { # 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.'). - '</h3>'); + '</p>'); return; } # # Build up the data sets to plot - my @Labels; + my @Labels; my @Data; my $max = 1; foreach my $data (@StatsArray) { @@ -1037,7 +1050,7 @@ sub make_single_stat_plot { } # $r->print("<p>".&Apache::loncommon::DrawBarGraph($title, - 'Problem Number', + &mt('Problem Number'), $yaxis, $max, undef, # colors @@ -1055,7 +1068,7 @@ sub degrees_plot { my $plot = ''; my $ymax = 0; my $ymin = 0; - my @Disc; my @Diff; my @Labels; + my @Disc; my @Diff; my @Labels; foreach my $data (@StatsArray) { push(@Labels,$data->{'problem_num'}); my $disc = $data->{'deg_of_disc'}; @@ -1102,10 +1115,14 @@ sub degrees_plot { my $diffdata .= '<data>'.join(',',@Labels).'</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) { - $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"; <gnuplot @@ -1117,7 +1134,7 @@ sub degrees_plot { align="center" border="on" transparent="on" - alttag="Degree of Discrimination and Degree of Difficulty Plot" + alttag="$lt{'alttag'}" samples="100" bgcolor="xffffff" height="$height" @@ -1128,7 +1145,7 @@ sub degrees_plot { box="off" /> <title>$title</title> <axis xmin="0" ymin="$ymin" xmax="$xmax" ymax="$ymax" color="x000000" /> - <xlabel>Problem Number</xlabel> + <xlabel>$lt{'xlabel'}</xlabel> <curve linestyle="linespoints" name="DoDisc" @@ -1145,7 +1162,7 @@ sub degrees_plot { </curve> </gnuplot> END - my $plotresult = + my $plotresult = '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/; $r->print($plotresult); return; @@ -1190,11 +1207,16 @@ sub tries_data_plot { '<data>'.join(',',@Mean).'</data>'.$/. '<data>'.join(',',@STD).'</data>'.$/; # - my $title = 'Mean and S.D. of Tries'; - if ($xmax > 25) { - $title = 'Mean and Standard Deviation of Tries'; + my $title = &mt('Mean and S.D. of Tries'); + if ($xmax > 30) { + $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"; <gnuplot texfont="10" @@ -1205,15 +1227,15 @@ sub tries_data_plot { align="center" border="on" transparent="on" - alttag="Mean and S.D of Tries Plot" + alttag="$lt{'alttag'}" samples="100" bgcolor="xffffff" height="$height" width="$width"> <title>$title</title> <axis xmin="0" ymin="0" xmax="$xmax" ymax="$ymax" color="x000000" /> - <xlabel>Problem Number</xlabel> - <ylabel>Number of Tries</ylabel> + <xlabel>$lt{'xlabel'}</xlabel> + <ylabel>$lt{'ylabel'}</ylabel> <curve linestyle="yerrorbars" name="S.D. Tries" @@ -1230,7 +1252,7 @@ sub tries_data_plot { </curve> </gnuplot> END - my $plotresult = + my $plotresult = '<p>'.&Apache::lonxml::xmlparse($r,'web',$plot).'</p>'.$/; $r->print($plotresult); return; @@ -1238,6 +1260,7 @@ END sub plot_dropdown { my $current = ''; + my $title; # if (defined($env{'form.plot'})) { $current = $env{'form.plot'}; @@ -1253,7 +1276,7 @@ sub plot_dropdown { # my $Str= "\n".'<select name="plot" size="1">'; $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) { if (! exists($field->{'graphable'}) || $field->{'graphable'} ne 'yes') { @@ -1261,9 +1284,11 @@ sub plot_dropdown { } $Str .= '<option value="'.$field->{'name'}.'"'; 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"; return $Str; @@ -1321,16 +1346,17 @@ sub Excel_output { # Time restrictions my $time_string; 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)) { - $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)) { - # See note above about lonlocal:locallocaltime - $time_string .= 'Data collected before '.localtime($endtime).'.'; + $time_string .= &mt('Data collected before [_1]', + &Apache::lonlocal::locallocaltime($endtime)); } if (defined($time_string)) { $excel_sheet->write($rows_output,$cols_output++,$time_string); @@ -1339,13 +1365,13 @@ sub Excel_output { # # Put the date in there too $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; ## ## Sequence Statistics - ## + ## &write_headers($excel_sheet,$format,\$rows_output,\$cols_output, \@SeqFields); foreach my $seq (@sequences) { @@ -1423,7 +1449,7 @@ sub write_headers { foreach my $field (@{$Fields}) { next if ($field->{'selected'} ne 'yes'); 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.... $excel_sheet->write($$rows_output,$$cols_output, $field->{'title'}, @@ -1444,10 +1470,11 @@ sub write_headers { ################################################## sub compute_statistics_on_sequence { my ($seq) = @_; + my $include_tools = 1; my @Data; - foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq)) { + foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq,$include_tools)) { 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 my $data = &get_statistics($seq,$res,$part,scalar(@StatsArray)+1); @@ -1536,13 +1563,13 @@ sub sort_data { =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 and &compute_discrimination_factor Inputs: $sequence, $resource, $part, $problem_num -Returns: Hash reference with statistics data from +Returns: Hash reference with statistics data from loncoursedata::get_problem_statistics. =cut @@ -1570,7 +1597,7 @@ sub get_statistics { &escape($resource->symb); # if ($SelectedFields{'deg_of_disc'}) { - $data->{'deg_of_disc'} = + $data->{'deg_of_disc'} = &compute_discrimination_factor($resource,$part,$sequence); } # @@ -1582,10 +1609,9 @@ sub get_statistics { $data->{'sections'}=$sections; $data->{'course'} = $env{'request.course.id'}; my $urlres=(&Apache::lonnet::decode_symb($resource->symb))[2]; - $data->{'urlres'}=$urlres; - my %storestats = + my %storestats = &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); } # @@ -1593,16 +1619,16 @@ sub get_statistics { ($data->{'num_solved'}+0.1); # # Get the due date for research purposes (commented out most of the time) -# $data->{'duedate'} = -# &Apache::lonnet::EXT('resource.'.$part.'.duedate',$symb); -# $data->{'opendate'} = -# &Apache::lonnet::EXT('resource.'.$part.'.opendate',$symb); -# $data->{'maxtries'} = -# &Apache::lonnet::EXT('resource.'.$part.'.maxtries',$symb); -# $data->{'hinttries'} = -# &Apache::lonnet::EXT('resource.'.$part.'.hinttries',$symb); - $data->{'weight'} = - &Apache::lonnet::EXT('resource.'.$part.'.weight',$symb); +# my $duedate = &Apache::lonnet::EXT('resource.'.$part.'.duedate',$symb);; +# my $opendate = &Apache::lonnet::EXT('resource.'.$part.'.opendate',$symb); +# my $maxtries = &Apache::lonnet::EXT('resource.'.$part.'.maxtries',$symb); +# my $hinttries = &Apache::lonnet::EXT('resource.'.$part.'.hinttries',$symb); + my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',$symb); + $data->{'weight'} = $weight; +# $data->{'duedate'} = $duedate; +# $data->{'opendate'} = $opendate; +# $data->{'maxtries'} = $maxtries; +# $data->{'hinttries'} = $hinttries; # $data->{'resptypes'} = join(',',@{$resource->{'partdata'}->{$part}->{'ResponseTypes'}}); return $data; } @@ -1624,16 +1650,17 @@ Returns: integer between -1 and 1 ############################################### sub compute_discrimination_factor { my ($resource,$part,$seq) = @_; + my $include_tools = 1; my $symb = $resource->symb; my @Resources; - foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq)){ + foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq,$include_tools)){ next if ($res->symb eq $symb); push (@Resources,$res->symb); } # # rank my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits(); - my $ranking = + my $ranking = &Apache::loncoursedata::rank_students_by_scores_on_resources (\@Resources, [&Apache::lonstatistics::get_selected_sections()], @@ -1644,20 +1671,20 @@ sub compute_discrimination_factor { # compute their percent scores on the problems in the sequence, my $number_to_grab = int(scalar(@{$ranking})/4); my $num_students = scalar(@{$ranking}); - my @BottomSet = map { $_->[&Apache::loncoursedata::RNK_student()]; + my @BottomSet = map { $_->[&Apache::loncoursedata::RNK_student()]; } @{$ranking}[0..$number_to_grab]; - my @TopSet = - map { - $_->[&Apache::loncoursedata::RNK_student()]; + my @TopSet = + map { + $_->[&Apache::loncoursedata::RNK_student()]; } @{$ranking}[-$number_to_grab..0]; if (! @BottomSet || (@BottomSet == 1 && $BottomSet[0] eq '') || ! @TopSet || (@TopSet == 1 && $TopSet[0] eq '')) { return 'nan'; } - my ($bottom_sum,$bottom_max) = + my ($bottom_sum,$bottom_max) = &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@BottomSet, undef,$starttime,$endtime); - my ($top_sum,$top_max) = + my ($top_sum,$top_max) = &Apache::loncoursedata::get_sum_of_scores($symb,$part,\@TopSet, undef,$starttime,$endtime); my $deg_of_disc; @@ -1680,27 +1707,28 @@ sub compute_discrimination_factor { ## ## K=the number of items in your 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: -## +## ## KR-21 rk= [K/(K-1)] * [1- (M*(K-M))/(K*s^2))] ## ############################################### ############################################### sub compute_sequence_statistics { my ($seq) = @_; + my $include_tools = 1; my $symb = $seq->symb; my @Resources; my $part_count; - foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq)) { + foreach my $res (&Apache::lonstathelpers::get_resources($navmap,$seq,$include_tools)) { push (@Resources,$res->symb); $part_count += scalar(@{$res->parts}); } my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits(); # # 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::lonstatistics::get_selected_sections()], [&Apache::lonstatistics::get_selected_groups()], @@ -1715,7 +1743,7 @@ sub compute_sequence_statistics { $SeqStat{$symb}->{'max_possible'} = $sMAX; # # 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)= &Apache::loncoursedata::count_stats ([&Apache::lonstatistics::get_selected_sections()],