--- loncom/interface/statistics/lonproblemstatistics.pm 2004/04/01 20:02:56 1.79
+++ loncom/interface/statistics/lonproblemstatistics.pm 2012/05/03 11:21:33 1.122
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemstatistics.pm,v 1.79 2004/04/01 20:02:56 matthew Exp $
+# $Id: lonproblemstatistics.pm,v 1.122 2012/05/03 11:21:33 goltermann Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -50,15 +50,19 @@ 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;
+use LONCAPA::lonmetadata();
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
@@ -95,13 +99,17 @@ my %SeqStat; # keys are symbs, values
## statistics display?
## selected yes (yes|no) Is the column selected by default?
##
+## format no sprintf format string
+##
+## excel_format no excel format type
+## (see &Apache::loncommon::define_excel_formats
my @Fields = (
{ name => 'problem_num',
title => 'P#',
align => 'right',
color => '#FFFFE6',
selectable => 'no',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'container',
title => 'Sequence or Folder',
@@ -109,23 +117,23 @@ my @Fields = (
color => '#FFFFE6',
sortable => 'yes',
selectable => 'no',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'title',
title => 'Title',
align => 'left',
color => '#FFFFE6',
special => 'link',
- sortable => 'yes',
+ sortable => 'yes',
selectable => 'no',
- selected => 'yes',
+ defaultselected => 'yes',
},
- { name => 'part',
+ { name => 'part',
title => 'Part',
align => 'left',
color => '#FFFFE6',
selectable => 'no',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'num_students',
title => '#Stdnts',
@@ -136,7 +144,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Number of Students Attempting Problem',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'tries',
title => 'Tries',
@@ -147,7 +155,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Total Number of Tries',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'max_tries',
title => 'Max Tries',
@@ -158,7 +166,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Maximum Number of Tries',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'min_tries',
title => 'Min Tries',
@@ -169,7 +177,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Minumum Number of Tries',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'mean_tries',
title => 'Mean Tries',
@@ -180,7 +188,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Average Number of Tries',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'std_tries',
title => 'S.D. tries',
@@ -191,7 +199,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Standard Deviation of Number of Tries',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'skew_tries',
title => 'Skew Tries',
@@ -202,7 +210,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Skew of Number of Tries',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'num_solved',
title => '#YES',
@@ -213,7 +221,7 @@ my @Fields = (
graphable => 'yes',
long_title => 'Number of Students able to Solve',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'num_override',
title => '#yes',
@@ -224,7 +232,18 @@ my @Fields = (
graphable => 'yes',
long_title => 'Number of Students given Override',
selectable => 'yes',
- selected => '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',
@@ -233,9 +252,20 @@ 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',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'deg_of_diff',
title => 'DoDiff',
@@ -247,7 +277,7 @@ my @Fields = (
long_title => 'Degree of Difficulty'.
'[ 1 - ((#YES+#yes) / Tries) ]',
selectable => 'yes',
- selected => 'yes',
+ defaultselected => 'yes',
},
{ name => 'deg_of_disc',
title => 'DoDisc',
@@ -258,8 +288,86 @@ my @Fields = (
graphable => 'yes',
long_title => 'Degree of Discrimination',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'yes',
},
+## duedate included for research purposes. Commented out most of the time.
+# { name => 'duedate',
+# title => 'Due Date',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'yes',
+# graphable => 'no',
+# long_title => 'Due date of resource for instructor',
+# selectable => 'no',
+# defaultselected => 'yes',
+# },
+## opendate included for research purposes. Commented out most of the time.
+# { name => 'opendate',
+# title => 'Open Date',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'yes',
+# graphable => 'no',
+# long_title => 'date resource became answerable',
+# selectable => 'no',
+# defaultselected => 'yes',
+# },
+## symb included for research purposes. Commented out most of the time.
+# { name => 'symb',
+# title => 'Symb',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'yes',
+# graphable => 'no',
+# long_title => 'Unique LON-CAPA identifier for problem',
+# selectable => 'no',
+# defaultselected => 'yes',
+# },
+## resptypes included for research purposes. Commented out most of the time.
+# { name => 'resptypes',
+# title => 'Response Types',
+# align => 'left',
+# color => '#FFFFFF',
+# sortable => 'no',
+# graphable => 'no',
+# long_title => 'Response Types used in this problem',
+# 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 = (
@@ -268,9 +376,9 @@ my @SeqFields = (
align => 'left',
color => '#FFFFE6',
special => 'no',
- sortable => 'no',
+ sortable => 'no',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'items',
title => '#Items',
@@ -281,7 +389,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Number of Items in Sequence',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'scoremean',
title => 'Score Mean',
@@ -292,7 +400,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Mean Sequence Score',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'scorestd',
title => 'Score STD',
@@ -303,7 +411,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Standard Deviation of Sequence Scores',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'scoremax',
title => 'Score Max',
@@ -314,7 +422,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Maximum Sequence Score',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'scoremin',
title => 'Score Min',
@@ -325,7 +433,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Minumum Sequence Score',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'scorecount',
title => 'Score N',
@@ -336,7 +444,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Number of Students in score computations',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'countmean',
title => 'Count Mean',
@@ -347,7 +455,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Mean Sequence Score',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'countstd',
title => 'Count STD',
@@ -358,7 +466,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Standard Deviation of Sequence Scores',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'countmax',
title => 'Count Max',
@@ -369,7 +477,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Maximum Number of Correct Problems',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'countmin',
title => 'Count Min',
@@ -380,7 +488,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Minumum Number of Correct Problems',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'count',
title => 'Count N',
@@ -391,7 +499,7 @@ my @SeqFields = (
graphable => 'no',
long_title => 'Number of Students in score computations',
selectable => 'yes',
- selected => 'no',
+ defaultselected => 'no',
},
{ name => 'KR-21',
title => 'KR-21',
@@ -402,8 +510,8 @@ my @SeqFields = (
graphable => 'no',
long_title => 'KR-21 reliability statistic',
selectable => 'yes',
- selected => 'no',
- },
+ defaultselected => 'no',
+ },
);
my %SelectedFields;
@@ -411,38 +519,66 @@ 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->{'selected'} eq 'yes') {
- push(@{$ENV{'form.fieldselections'}},$field->{'name'});
+ if ($field->{'defaultselected'} eq 'yes') {
+ 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') {
+ $NeededFields{'deg_of_diff'}++;
+ $NeededFields{'deg_of_disc'}++;
+ } elsif ($env{'form.plot'} eq 'tries statistics') {
+ $NeededFields{'mean_tries'}++;
+ $NeededFields{'std_tries'}++;
+ $NeededFields{'problem_num'}++;
+ } else {
+ $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)
undef(%SelectedFields);
foreach my $field (@Fields) {
- next if ($field->{'selectable'} ne 'yes');
- $field->{'selected'} = 'no';
- foreach my $selection (@{$ENV{'form.fieldselections'}}) {
+ if ($field->{'selectable'} ne 'yes') {
+ $field->{'selected'} = 'yes';
+ } else {
+ $field->{'selected'} = 'no';
+ }
+ if (exists($NeededFields{$field->{'name'}})) {
+ $field->{'selected'} = 'yes';
+ $SelectedFields{$field->{'name'}}++;
+ }
+ foreach my $selection (@{$env{'form.fieldselections'}}) {
if ($selection eq $field->{'name'} || $selection eq 'all') {
$field->{'selected'} = 'yes';
$SelectedFields{$field->{'name'}}++;
}
}
}
+ #
+ # Always show all the sequence statistics (for now)
+ foreach my $field (@SeqFields) {
+ $field->{'selected'} = 'yes';
+ }
return;
}
sub field_selection_input {
- my $Str = '
';
$Str .= '';
- $Str .= ' 'x5;
- $Str .= 'Plot '.&plot_dropdown().(' 'x10);
- $Str .= '';
- $Str .= ' 'x5;
- $Str .= '';
- $Str .= ' 'x5;
- $Str .= '';
- $Str .= ' 'x5;
+ $Str .= (' 'x10);
+ #
return $Str;
}
@@ -532,12 +665,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');
@@ -553,28 +697,34 @@ sub BuildProblemStatisticsPage {
undef(%SeqStat);
#
# Finally let the user know we are here
- my $interface = &CreateInterface();
+ $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('');
#
- if (! exists($ENV{'form.statsfirstcall'})) {
- $r->print('');
- $r->print('
'.
+ my @CacheButtonHTML =
+ &Apache::lonstathelpers::manage_caches($r,'Statistics','stats_status');
+ my $Str;
+ foreach my $html (@CacheButtonHTML) {
+ $Str.=$html.(' 'x5);
+ }
+ #
+ $r->print($Str);
+ 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;
- } elsif ($ENV{'form.statsfirstcall'} eq 'yes' ||
- exists($ENV{'form.UpdateCache'}) ||
- exists($ENV{'form.ClearCache'}) ) {
- $r->print('');
- &Apache::lonstatistics::Gather_Student_Data($r);
- } else {
- $r->print('');
}
$r->rflush();
#
@@ -582,12 +732,31 @@ 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)) {
@@ -708,8 +876,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;
}
@@ -727,7 +895,7 @@ sub statistics_html_table_data {
foreach my $field (@Fields) {
next if ($options =~ /no $field->{'name'}/);
next if ($field->{'selected'} ne 'yes');
- $row .= '