--- loncom/interface/statistics/lonproblemanalysis.pm 2005/03/14 20:28:22 1.118 +++ loncom/interface/statistics/lonproblemanalysis.pm 2014/02/03 18:50:58 1.145 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonproblemanalysis.pm,v 1.118 2005/03/14 20:28:22 matthew Exp $ +# $Id: lonproblemanalysis.pm,v 1.145 2014/02/03 18:50:58 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,10 +27,11 @@ package Apache::lonproblemanalysis; use strict; -use Apache::lonnet(); +use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::loncoursedata(); +use Apache::lonquickgrades(); use Apache::lonstatistics; use Apache::lonlocal; use Apache::lonstathelpers(); @@ -38,6 +39,9 @@ use Apache::lonstudentsubmissions(); use HTML::Entities(); use Time::Local(); use capa; +use lib '/home/httpd/lib/perl/'; +use LONCAPA; + my $plotcolors = ['#33ff00', '#0033cc', '#990000', '#aaaa66', '#663399', '#ff9933', @@ -59,6 +63,7 @@ sub BuildProblemAnalysisPage { # my %Saveable_Parameters = ('Status' => 'scalar', 'Section' => 'array', + 'Groups' => 'array', 'NumPlots' => 'scalar', 'AnalyzeOver' => 'scalar', ); @@ -69,12 +74,18 @@ sub BuildProblemAnalysisPage { # &Apache::lonstatistics::PrepareClasslist(); # + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Detailed Problem Analysis')); + &Apache::lonquickgrades::startGradeScreen($r,'statistics'); + $r->print(&CreateInterface()); # my @Students = @Apache::lonstatistics::Students; # - if (@Students < 1 && exists($ENV{'form.firstrun'})) { - $r->print('
'.&Apache::lonstatistics::section_and_enrollment_description().'
'); + if ($env{'form.show_prob'} eq 'true') { + $r->print(''.
+ ' '.
&mt($no_data_message,$plot_num,@extra_data).
- ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.
@@ -316,11 +344,14 @@ sub numerical_plot_percent {
last;
}
}
+ $percent_spread = $highest_percent - $lowest_percent;
my $bin_size = 1;
foreach (qw/0.01 0.05 0.1 0.5 1 2 5 10 20 25 50 100/) {
if ($lowest_percent/2 < $_){
$bin_size = $_;
- last;
+ if ( ($percent_spread/$bin_size) < $max_bins ) {
+ last;
+ }
}
}
my @bins;
@@ -338,7 +369,9 @@ sub numerical_plot_percent {
while (my ($ans,$submissions) = each(%$responses)) {
while (my ($submission,$counts) = each(%$submissions)) {
my ($correct_count,$incorrect_count) = @$counts;
- my $scaled_value = 100*($submission-$ans)/abs($ans);
+ my $scaled_value =
+ ($ans) ? 100*($submission-$ans)/abs($ans)
+ : 0;
if ($scaled_value < $bins[0]) {
$bins[0]=$scaled_value -1;
}
@@ -367,10 +400,13 @@ sub numerical_plot_percent {
if ($max <$_) { $max = $_; last; }
}
#
- my $title = &mt('Percent Difference');
+ my %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Percent Difference',
+ 'xlabel' => 'Percent Difference from Correct',
+ 'ylabel' => 'Percent of Answers');
my @labels = (1..scalar(@bins)-1);
my $graph = &Apache::loncommon::DrawBarGraph
- ($title,'Percent Difference from Correct','Percent of Answers',
+ ($lt{'title'},$lt{'xlabel'},$lt{'ylabel'},
$max,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
{xskip=>1});
#
@@ -393,7 +429,12 @@ sub numerical_plot_differences {
} elsif ($low_bin < 0 && $high_bin < -$low_bin) {
$high_bin = -$low_bin;
}
- if (($high_bin -$low_bin)/$min_bin_size * 2 > $max_bins) {
+ if ($high_bin == $low_bin) {
+ $high_bin+=1;
+ $low_bin-=1;
+ }
+ if (!$min_bin_size ||
+ ($high_bin -$low_bin)/$min_bin_size * 2 > $max_bins) {
$min_bin_size = abs($high_bin - $low_bin) / $max_bins * 2;
}
my @bins;
@@ -435,10 +476,13 @@ sub numerical_plot_differences {
if ($max <$_) { $max = $_; last; }
}
#
- my $title = &mt('Difference between submission and correct');
+ my %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Difference between submission and correct',
+ 'xlabel' => 'Difference from Correct',
+ 'ylabel' => 'Percent of Answers');
my @labels = (1..scalar(@bins)-1);
my $graph = &Apache::loncommon::DrawBarGraph
- ($title,'Difference from Correct','Percent of Answers',
+ ($lt{'title'},$lt{'xlabel'},$lt{'ylabel'},
$max,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
{xskip=>1});
#
@@ -482,8 +526,12 @@ sub numerical_classify_responses {
if ($stats{'max_abs'} < $abs_high) {
$stats{'max_abs'} = $abs_high;
}
- my $low_percent = 100 * abs($abs_low / $subm{'correct'});
- my $high_percent = 100 * abs($abs_high / $subm{'correct'});
+ my $low_percent;
+ my $high_percent;
+ if (defined($subm{'correct'}) && $subm{'correct'} != 0) {
+ $low_percent = 100 * abs($abs_low / $subm{'correct'});
+ $high_percent = 100 * abs($abs_high / $subm{'correct'});
+ }
if (! defined($stats{'min_percent'}) ||
$stats{'min_percent'} > $low_percent) {
$stats{'min_percent'} = $low_percent;
@@ -531,6 +579,8 @@ sub numerical_classify_responses {
}
}
}
+ $stats{'correct_count'} |= 0;
+ $stats{'incorrect_count'} |= 0;
$stats{'students'}=scalar(keys(%students));
return (\%submission_data,\%stats);
}
@@ -586,10 +636,7 @@ sub numerical_determine_answers {
my ($r,$resource,$partid,$respid,$students)=@_;
my $c = $r->connection();
#
- my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
- ($r,'Student Answer Compilation Status',
- 'Student Answer Compilation Progress', scalar(@$students),
- 'inline',undef,'Statistics','stats_status');
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,scalar(@$students));
#
# Read in the cache (if it exists) before we start timing things.
&Apache::lonstathelpers::ensure_proper_cache($resource->{'symb'});
@@ -607,13 +654,23 @@ sub numerical_determine_answers {
$sdom);
# make the key
my $key = $partid.'.'.$respid;
+ # pick one of the possible answers
+ my $which = 'INTERNAL';
+ if (!exists($analysis->{$key}{$which})) {
+ $which = (sort(keys(%{ $analysis->{$key} })))[0];
+ }
foreach my $item ('answer','unit','ans_high','ans_low') {
- $correct->{$sname.':'.$sdom}->{$item} =
- $analysis->{$key.'.'.$item}->[0];
+ if (ref($analysis->{$key.'.'.$item}) eq 'ARRAY') {
+ $correct->{$sname.':'.$sdom}->{$item} =
+ $analysis->{$key.'.'.$item}[0];
+ } else {
+ $correct->{$sname.':'.$sdom}->{$item} =
+ $analysis->{$key.'.'.$item}{$which}[0][0];
+ }
}
- $answers{$analysis->{$key.'.answer'}->[0]}++;
+ $answers{$correct->{$sname.':'.$sdom}{'answer'}}++;
&Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- &mt('last student'));
+ 'last student');
}
&Apache::lonstathelpers::write_analysis_cache();
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
@@ -737,7 +794,7 @@ sub circle {
sub radio_response_analysis {
my ($r,$problem,$problem_analysis,$students) = @_;
#
- if ($ENV{'form.AnalyzeOver'} !~ /^(tries|time)$/) {
+ if ($env{'form.AnalyzeOver'} !~ /^(tries|time)$/) {
$r->print('Bad request');
}
#
@@ -767,6 +824,7 @@ sub radio_response_analysis {
# Gather student data
my $response_data = &Apache::loncoursedata::get_response_data
([&Apache::lonstatistics::get_selected_sections()],
+ [&Apache::lonstatistics::get_selected_groups()],
$Apache::lonstatistics::enrollment_status,
$resource->symb,$respid);
my $correct; # either a hash reference or a scalar
@@ -779,7 +837,7 @@ sub radio_response_analysis {
my ($idx,@remainder) = split('&',$student->{'answer'});
my ($answer) = ($remainder[$idx]=~/^(.*)=([^=]*)$/);
$correct->{$student->{'username'}.':'.$student->{'domain'}}=
- &Apache::lonnet::unescape($answer);
+ &unescape($answer);
}
} else {
foreach my $foil (keys(%$foildata)) {
@@ -790,29 +848,29 @@ sub radio_response_analysis {
}
#
if (! defined($response_data) || ref($response_data) ne 'ARRAY' ) {
- $analysis_html = ''. - &mt('There is no submission data for this resource'). - ''; + $analysis_html = ''
+ .&mt('There is no submission data for this resource.')
+ .' ';
$r->print($analysis_html);
return;
}
#
$analysis_html.='
'.&mt('There is no data to plot').'',''); + return (''
+ .&mt('There is no data to plot.')
+ .' '
+ ,''
+ );
}
my $analysis_html;
my @plotdata;
@@ -1542,9 +1633,13 @@ sub OR_Foil_Time_Analysis {
}
#
# Create the plot
- my $correct_plot = &Apache::loncommon::DrawBarGraph('Correct Statements',
- 'Statement Number',
- 'Percent Correct',
+ my %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Correct Statements',
+ 'xlabel' => 'Statement Number',
+ 'ylabel' => 'Percent Correct');
+ my $correct_plot = &Apache::loncommon::DrawBarGraph($lt{'title'},
+ $lt{'xlabel'},
+ $lt{'ylabel'},
100,
$plotcolors,
undef,
@@ -1553,10 +1648,14 @@ sub OR_Foil_Time_Analysis {
for (my $j=0; $j< scalar(@{$plotdata[0]});$j++) {
$plotdata[0]->[$j]=0;
}
+ %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Incorrect Statements',
+ 'xlabel' => 'Statement Number',
+ 'ylabel' => 'Incorrect Option Choice');
my $incorrect_plot =
- &Apache::loncommon::DrawBarGraph('Incorrect Statements',
- 'Statement Number',
- 'Incorrect Option Choice',
+ &Apache::loncommon::DrawBarGraph($lt{'title'},
+ $lt{'xlabel'},
+ $lt{'ylabel'},
100,
$plotcolors,
undef,
@@ -1585,9 +1684,13 @@ sub OR_Concept_Time_Analysis {
}
#
# Create the plot
- return &Apache::loncommon::DrawBarGraph('Correct Concepts',
- 'Concept Number',
- 'Percent Correct',
+ my %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Correct Concepts',
+ 'xlabel' => 'Concept Number',
+ 'ylabel' => 'Percent Correct');
+ return &Apache::loncommon::DrawBarGraph($lt{'title'},
+ $lt{'xlabel'},
+ $lt{'ylabel'},
100,
$plotcolors,
undef,
@@ -1683,23 +1786,23 @@ sub build_foil_index {
}
#
# Build up the table of row labels.
- my $table = '
|