--- loncom/interface/statistics/lonproblemstatistics.pm 2009/03/05 09:12:14 1.117
+++ loncom/interface/statistics/lonproblemstatistics.pm 2023/09/08 00:07:30 1.122.2.4.2.1
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemstatistics.pm,v 1.117 2009/03/05 09:12:14 bisitz Exp $
+# $Id: lonproblemstatistics.pm,v 1.122.2.4.2.1 2023/09/08 00:07:30 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -73,6 +73,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 +92,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
@@ -174,7 +182,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 +282,7 @@ my @Fields = (
sortable => 'yes',
graphable => 'yes',
long_title => 'Degree of Difficulty'.
- '[ 1 - ((#YES+#yes) / Tries) ]',
+ ' ~[ 1 - ((#YES+#yes) / Tries) ~]',
selectable => 'yes',
defaultselected => 'yes',
},
@@ -430,7 +438,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 +493,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',
},
@@ -578,14 +586,14 @@ sub parse_field_selection {
sub field_selection_input {
my $Str = ''."\n";
- $Str .= 'all '."\n";
+ $Str .= ''.&mt('all').' '."\n";
foreach my $field (@Fields) {
next if ($field->{'selectable'} ne 'yes');
- $Str .= ' {'name'}.'"';
if ($field->{'selected'} eq 'yes') {
- $Str .= 'selected ';
+ $Str .= ' selected="selected"';
}
- $Str .= '>'.$field->{'title'}.' '."\n";
+ $Str .= '>'.&mt($field->{'title'}).''."\n";
}
$Str .= " \n";
}
@@ -610,9 +618,6 @@ sub CreateInterface {
&parse_field_selection();
#
my $Str = '';
- $Str .= &Apache::lonhtmlcommon::breadcrumbs('Overall Problem Statistics',
- 'Statistics_Overall_Key');
- $Str .= '
';
$Str .= &Apache::loncommon::start_data_table();
$Str .= &Apache::loncommon::start_data_table_header_row();
$Str .= '
'.&mt('Sections').' ';
@@ -638,20 +643,13 @@ sub CreateInterface {
$Str .= &field_selection_input();
$Str .= '';
$Str .= &plot_dropdown();
- $Str .= ' '."\n";
+ $Str .= "\n";
$Str .= '';
$Str .= &Apache::lonstathelpers::limit_by_time_form();
$Str .= ' '."\n";
$Str .= &Apache::loncommon::end_data_table_row();
$Str .= &Apache::loncommon::end_data_table();
#
- $Str .= ''
- .&mt('Status: [_1]',
- ' ')
- .'
';
- #
- $Str .= '';
$Str .= ' ';
$Str .= (' 'x10);
@@ -704,6 +702,9 @@ sub BuildProblemStatisticsPage {
undef(%SeqStat);
#
# Finally let the user know we are here
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Overall Problem Statistics',
+ 'Statistics_Overall_Key'));
+
my $interface = &CreateInterface($r);
$r->print($interface);
$r->print(' '.' 'x5);
$r->rflush();
- $r->print(''.
+ $r->print(' '.
&Apache::lonstatistics::section_and_enrollment_description().
- '');
+ '
');
my $count = 0;
+ my $include_tools = 1;
foreach my $seq (@sequences) {
my @resources =
- &Apache::lonstathelpers::get_resources($navmap,$seq);
+ &Apache::lonstathelpers::get_resources($navmap,$seq,$include_tools);
$count += scalar(@resources);
}
if ($count > 10) {
- $r->print(''.
- &mt('Compiling statistics for [_1] problems',$count).
- ' ');
+ $r->print(''.
+ &mt('Compiling statistics for [quant,_1,problem]',$count).
+ '
');
if ($count > 30) {
- $r->print(''.&mt('This will take some time.').' ');
+ $r->print(''.&mt('This will take some time.').'
');
}
$r->rflush();
}
@@ -798,17 +800,14 @@ sub output_sequence_statistics {
$r->print(''.&mt('Sequence Statistics').
&Apache::loncommon::help_open_topic('Statistics_Sequence').
' ');
- $r->print(''."\n".
- ''."\n".
- '');
+ $r->print(&Apache::loncommon::start_data_table());
$r->print(&sequence_html_header());
foreach my $seq (@sequences) {
last if ($c->aborted);
&compute_sequence_statistics($seq);
$r->print(&sequence_html_output($seq));
}
- $r->print('
');
- $r->print('
');
+ $r->print(&Apache::loncommon::end_data_table());
$r->rflush();
return;
}
@@ -824,22 +823,22 @@ sub output_sequence_statistics {
sub output_html_by_sequence {
my ($r) = @_;
my $c = $r->connection();
- $r->print(&html_preamble());
+ $r->print(' '.&html_preamble());
#
foreach my $seq (@sequences) {
last if ($c->aborted);
$r->print("".$seq->compTitle." ".
- ''."\n".
- ''."\n".
- ''.
- &statistics_table_header('no container')." \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(''.&statistics_html_table_data($data,
- 'no container').
- " \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('
'."\n".'
'."\n");
+ $r->print(&Apache::loncommon::end_data_table()."\n");
$r->rflush();
}
return;
@@ -854,17 +853,17 @@ sub output_html_stats {
my $count=0;
foreach my $data (@StatsArray) {
if ($count++ % 50 == 0) {
- $r->print("\n\n");
- $r->print(''."\n".
- ''."\n".
- ''.
- ' '.
- &statistics_table_header().
- " \n");
- }
- $r->print(''.&statistics_html_table_data($data)." \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("
\n
\n");
+ $r->print(&Apache::loncommon::end_data_table_row());
return;
}
@@ -881,8 +880,8 @@ sub html_preamble {
&Apache::lonlocal::locallocaltime($endtime)
).'';
}
- $Str .= "".&mt('Compiled on [_1]',
- &Apache::lonlocal::locallocaltime(time))." ";
+ $Str .= "".&mt('Compiled on [_1]',
+ &Apache::lonlocal::locallocaltime(time))."
";
return $Str;
}
@@ -900,7 +899,7 @@ sub statistics_html_table_data {
foreach my $field (@Fields) {
next if ($options =~ /no $field->{'name'}/);
next if ($field->{'selected'} ne 'yes');
- $row .= '{'color'}.'"';
if (exists($field->{'align'})) {
$row .= ' align="'.$field->{'align'}.'"';
}
@@ -928,14 +927,16 @@ sub statistics_table_header {
next if ($options =~ /no $field->{'name'}/);
next if ($field->{'selected'} ne 'yes');
$header_row .= ' ';
+ my $header_row_text = &mt($field->{'title'});
if (exists($field->{'sortable'}) && $field->{'sortable'} eq 'yes') {
- $header_row .= '{'name'}."'".
- ';document.Statistics.submit();">';
- }
- $header_row .= &mt($field->{'title'});
- if ($options =~ /sortable/) {
- $header_row.= ' ';
+ ';document.Statistics.submit();">'.
+ $header_row_text.
+ '';
+ } else {
+ $header_row .= $header_row_text;
}
if ($options !~ /no plots/ &&
exists($field->{'graphable'}) &&
@@ -952,13 +953,13 @@ sub statistics_table_header {
}
sub sequence_html_header {
- my $Str .= ' ';
+ my $Str .= &Apache::loncommon::start_data_table_header_row();
foreach my $field (@SeqFields) {
# next if ($field->{'selected'} ne 'yes');
$Str .= '{'title'}.' ';
+ $Str .= '>'.&mt($field->{'title'}).'';
}
- $Str .= ' ';
+ $Str .= &Apache::loncommon::end_data_table_header_row();
return $Str;
}
@@ -966,7 +967,7 @@ sub sequence_html_header {
sub sequence_html_output {
my ($seq) = @_;
my $data = $SeqStat{$seq->symb};
- my $row = '';
+ my $row = &Apache::loncommon::start_data_table_row();
foreach my $field (@SeqFields) {
next if ($field->{'selected'} ne 'yes');
$row .= '{'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(''.
+ $r->print(' '.
&mt('Unable to plot the requested statistic.').
- '');
+ '
');
return;
}
#
@@ -1047,7 +1048,7 @@ sub make_single_stat_plot {
}
#
$r->print("".&Apache::loncommon::DrawBarGraph($title,
- 'Problem Number',
+ &mt('Problem Number'),
$yaxis,
$max,
undef, # colors
@@ -1112,10 +1113,14 @@ sub degrees_plot {
my $diffdata .= ''.join(',',@Labels).' '.$/.
''.join(',',@Diff).' '.$/;
#
- 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";
$title
- Problem Number
+ $lt{'xlabel'}
'.join(',',@Mean).''.$/.
''.join(',',@STD).' '.$/;
#
- 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";
$title
- Problem Number
- Number of Tries
+ $lt{'xlabel'}
+ $lt{'ylabel'}
';
$Str .= ' '."\n";
- $Str .= 'none '."\n";
+ $Str .= ''.&mt('none').' '."\n";
foreach my $field (@Additional_Plots,@Fields) {
if (! exists($field->{'graphable'}) ||
$field->{'graphable'} ne 'yes') {
@@ -1271,9 +1282,11 @@ sub plot_dropdown {
}
$Str .= '{'name'} eq $current) {
- $Str .= ' selected ';
+ $Str .= ' selected="selected"';
}
- $Str.= '>'.&mt($field->{'title'}).' '."\n";
+ $title = &mt($field->{'long_title'});
+ $title = &mt($field->{'title'}) if (!$title);
+ $Str.= '>'.$title.''."\n";
}
$Str .= ''."\n";
return $Str;
@@ -1331,16 +1344,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);
@@ -1349,7 +1363,7 @@ 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++;
$cols_output=0;
@@ -1454,10 +1468,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);
@@ -1592,7 +1607,6 @@ 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 =
&LONCAPA::lonmetadata::dynamic_metadata_storage($data);
my ($dom,$user) = ($urlres=~m{^($LONCAPA::domain_re)/($LONCAPA::username_re)});
@@ -1634,9 +1648,10 @@ 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);
}
@@ -1655,11 +1670,11 @@ sub compute_discrimination_factor {
my $number_to_grab = int(scalar(@{$ranking})/4);
my $num_students = scalar(@{$ranking});
my @BottomSet = map { $_->[&Apache::loncoursedata::RNK_student()];
- } @{$ranking}[0..$number_to_grab];
+ } @{$ranking}[0..$number_to_grab-1];
my @TopSet =
map {
$_->[&Apache::loncoursedata::RNK_student()];
- } @{$ranking}[-$number_to_grab..0];
+ } @{$ranking}[-$number_to_grab..-1];
if (! @BottomSet || (@BottomSet == 1 && $BottomSet[0] eq '') ||
! @TopSet || (@TopSet == 1 && $TopSet[0] eq '')) {
return 'nan';
@@ -1700,10 +1715,11 @@ sub compute_discrimination_factor {
###############################################
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});
}