--- loncom/interface/statistics/lonproblemstatistics.pm 2004/06/16 16:22:52 1.89
+++ loncom/interface/statistics/lonproblemstatistics.pm 2013/12/30 13:51:37 1.124
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemstatistics.pm,v 1.89 2004/06/16 16:22:52 matthew Exp $
+# $Id: lonproblemstatistics.pm,v 1.124 2013/12/30 13:51:37 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -50,8 +50,9 @@ Excel files, and plots.
package Apache::lonproblemstatistics;
use strict;
-use Apache::lonnet();
+use Apache::lonnet;
use Apache::loncommon();
+use Apache::lonquickgrades();
use Apache::lonhtmlcommon;
use Apache::loncoursedata;
use Apache::lonstatistics;
@@ -60,6 +61,8 @@ use Apache::lonlocal;
use Spreadsheet::WriteExcel;
use Apache::lonstathelpers();
use Time::HiRes;
+use LONCAPA;
+
my @StatsArray;
my %SeqStat; # keys are symbs, values are hash refs
@@ -71,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.
+##
#
#
##
@@ -82,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
@@ -121,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',
@@ -231,6 +242,17 @@ my @Fields = (
selectable => 'yes',
defaultselected => 'yes',
},
+ { name => 'tries_per_correct',
+ title => 'tries/correct',
+ align => 'right',
+ color => '#FFDDDD',
+ format => '%4.1f',
+ sortable => 'yes',
+ graphable => 'yes',
+ long_title => 'Tries per Correct Answer',
+ selectable => 'yes',
+ defaultselected => 'yes',
+ },
{ name => 'num_wrong',
title => '#Wrng',
align => 'right',
@@ -238,6 +260,17 @@ my @Fields = (
format => '%4.1f',
sortable => 'yes',
graphable => 'yes',
+ long_title => 'Number of students whose final answer is wrong',
+ selectable => 'yes',
+ defaultselected => 'yes',
+ },
+ { name => 'per_wrong',
+ title => '%Wrng',
+ align => 'right',
+ color => '#FFDDDD',
+ format => '%4.1f',
+ sortable => 'yes',
+ graphable => 'yes',
long_title => 'Percent of students whose final answer is wrong',
selectable => 'yes',
defaultselected => 'yes',
@@ -250,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',
},
@@ -309,6 +342,40 @@ my @Fields = (
# selectable => 'no',
# defaultselected => 'yes',
# },
+## maxtries included for research purposes. Commented out most of the time.
+# { name => 'maxtries',
+# title => 'Maxtries',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'no',
+# graphable => 'no',
+# long_title => 'Maximum number of tries',
+# selectable => 'no',
+# defaultselected => 'yes',
+# },
+## hinttries included for research purposes. Commented out most of the time.
+# { name => 'hinttries',
+# title => 'hinttries',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'no',
+# graphable => 'no',
+# long_title => 'Number of tries before a hint appears',
+# selectable => 'no',
+# defaultselected => 'yes',
+# },
+#
+## problem weight for instructor
+ { name => 'weight',
+ title => 'weight',
+ align => 'right',
+ color => '#FFFFFF',
+ sortable => 'no',
+ graphable => 'no',
+ long_title => 'Problem weight (for instructor)',
+ selectable => 'yes',
+ defaultselected => 'yes',
+ },
);
my @SeqFields = (
@@ -317,7 +384,7 @@ my @SeqFields = (
align => 'left',
color => '#FFFFE6',
special => 'no',
- sortable => 'no',
+ sortable => 'no',
selectable => 'yes',
defaultselected => 'no',
},
@@ -452,7 +519,7 @@ my @SeqFields = (
long_title => 'KR-21 reliability statistic',
selectable => 'yes',
defaultselected => 'no',
- },
+ },
);
my %SelectedFields;
@@ -460,35 +527,35 @@ my %SelectedFields;
sub parse_field_selection {
#
# Pull out the defaults
- if (! defined($ENV{'form.fieldselections'})) {
- $ENV{'form.fieldselections'} = [];
+ if (! defined($env{'form.fieldselections'})) {
+ $env{'form.fieldselections'} = [];
foreach my $field (@Fields) {
next if ($field->{'selectable'} ne 'yes');
if ($field->{'defaultselected'} eq 'yes') {
- push(@{$ENV{'form.fieldselections'}},$field->{'name'});
+ push(@{$env{'form.fieldselections'}},$field->{'name'});
}
}
}
#
# Make sure the data we are plotting is there
my %NeededFields;
- if (exists($ENV{'form.plot'}) && $ENV{'form.plot'} ne '' &&
- $ENV{'form.plot'} ne 'none') {
- if ($ENV{'form.plot'} eq 'degrees') {
+ if (exists($env{'form.plot'}) && $env{'form.plot'} ne '' &&
+ $env{'form.plot'} ne 'none') {
+ if ($env{'form.plot'} eq 'degrees') {
$NeededFields{'deg_of_diff'}++;
$NeededFields{'deg_of_disc'}++;
- } elsif ($ENV{'form.plot'} eq 'tries statistics') {
+ } elsif ($env{'form.plot'} eq 'tries statistics') {
$NeededFields{'mean_tries'}++;
$NeededFields{'std_tries'}++;
$NeededFields{'problem_num'}++;
} else {
- $NeededFields{$ENV{'form.plot'}}++;
+ $NeededFields{$env{'form.plot'}}++;
}
}
#
# This should not happen, but in case it does...
- if (ref($ENV{'form.fieldselections'}) ne 'ARRAY') {
- $ENV{'form.fieldselections'} = [$ENV{'form.fieldselections'}];
+ if (ref($env{'form.fieldselections'}) ne 'ARRAY') {
+ $env{'form.fieldselections'} = [$env{'form.fieldselections'}];
}
#
# Set the field data and the selected fields (for easier checking)
@@ -503,7 +570,7 @@ sub parse_field_selection {
$field->{'selected'} = 'yes';
$SelectedFields{$field->{'name'}}++;
}
- foreach my $selection (@{$ENV{'form.fieldselections'}}) {
+ foreach my $selection (@{$env{'form.fieldselections'}}) {
if ($selection eq $field->{'name'} || $selection eq 'all') {
$field->{'selected'} = 'yes';
$SelectedFields{$field->{'name'}}++;
@@ -519,7 +586,7 @@ sub parse_field_selection {
}
sub field_selection_input {
- my $Str = '
';
$Str .= '';
- $Str .= ' 'x5;
- $Str .= 'Plot '.&plot_dropdown().(' 'x10);
+ $Str .= (' 'x10);
#
return $Str;
}
@@ -611,12 +673,23 @@ Main interface to problem statistics.
###############################################
###############################################
+my $navmap;
+my @sequences;
+
+sub clean_up {
+ undef($navmap);
+ undef(@sequences);
+}
+
sub BuildProblemStatisticsPage {
my ($r,$c)=@_;
+ undef($navmap);
+ undef(@sequences);
#
my %Saveable_Parameters = ('Status' => 'scalar',
'statsoutputmode' => 'scalar',
'Section' => 'array',
+ 'Groups' => 'array',
'StudentData' => 'array',
'Maps' => 'array',
'fieldselections'=> 'array');
@@ -632,12 +705,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('');
#
- my @CacheButtonHTML =
+ my @CacheButtonHTML =
&Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');
my $Str;
foreach my $html (@CacheButtonHTML) {
@@ -645,14 +722,16 @@ sub BuildProblemStatisticsPage {
}
#
$r->print($Str);
- if (! exists($ENV{'form.firstrun'})) {
- $r->print('
'.
+ if (! exists($env{'form.firstrun'})) {
+ $r->print('
'.
&mt('Press "Generate Statistics" when you are ready.').
- '
'.
+ '
'.
+ '
'.
&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.').
'
');
+ &clean_up();
return;
}
$r->rflush();
@@ -661,29 +740,45 @@ sub BuildProblemStatisticsPage {
# it does not slow things down noticably.
&Apache::loncoursedata::populate_weight_table();
#
- if (exists($ENV{'form.Excel'})) {
+ ($navmap,@sequences) =
+ &Apache::lonstatistics::selected_sequences_with_assessments();
+ if (! ref($navmap)) {
+ $r->print('
\n";
my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
if (defined($starttime) || defined($endtime)) {
@@ -790,8 +884,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;
}
@@ -809,7 +903,7 @@ sub statistics_html_table_data {
foreach my $field (@Fields) {
next if ($options =~ /no $field->{'name'}/);
next if ($field->{'selected'} ne 'yes');
- $row .= '