');
+ if ($env{'form.show_prob'} eq 'true') {
$r->print(&Apache::lonstathelpers::render_resource($resource));
}
$r->rflush();
my %Data = &Apache::lonstathelpers::get_problem_data
- ($resource->{'src'});
+ ($resource->src);
my $problem_data = $Data{$current_problem->{'part'}.
'.'.
$current_problem->{'respid'}};
@@ -155,12 +166,14 @@ sub BuildProblemAnalysisPage {
}
$r->print('');
} else {
- $r->print('');
+ my $submit_button = '';
+ $r->print($submit_button);
$r->print(' 'x5);
$r->print('
'.&mt('Please select a problem to analyze').'
');
- $r->print(&Apache::lonstathelpers::ProblemSelector
- ($problem_types));
+ $r->print(&Apache::lonstathelpers::problem_selector($problem_types,
+ $submit_button));
}
}
@@ -175,7 +188,7 @@ sub numerical_response_analysis {
my ($r,$problem,$problem_analysis,$students) = @_;
my $c = $r->connection();
#
- if ($ENV{'form.AnalyzeOver'} !~ /^(tries|time)$/) {
+ if ($env{'form.AnalyzeOver'} !~ /^(tries|time)$/) {
$r->print('Bad request');
}
#
@@ -184,9 +197,10 @@ sub numerical_response_analysis {
$problem->{'respid'});
# Gather student data
my $response_data = &Apache::loncoursedata::get_response_data
- (\@Apache::lonstatistics::SelectedSections,
+ ([&Apache::lonstatistics::get_selected_sections()],
+ [&Apache::lonstatistics::get_selected_groups()],
$Apache::lonstatistics::enrollment_status,
- $resource->{'symb'},$respid);
+ $resource->symb,$respid);
#
$problem_analysis->{'answercomputed'} = 1;
if ($problem_analysis->{'answercomputed'}) {
@@ -204,14 +218,14 @@ sub numerical_response_analysis {
return;
}
my $analysis_html = '
';
- for (my $plot_num = 1;$plot_num<=$ENV{'form.NumPlots'};$plot_num++) {
+ for (my $plot_num = 1;$plot_num<=$env{'form.NumPlots'};$plot_num++) {
my $restriction_function;
my $header_message;
my $stats_message;
my $post_message; # passed through &mt sooner rather than later
my $no_data_message;
my @extra_data;
- if ($ENV{'form.AnalyzeOver'} eq 'tries') {
+ if ($env{'form.AnalyzeOver'} eq 'tries') {
$restriction_function = sub {($_[0]->{'tries'} == $plot_num?1:0)};
$header_message = 'Attempt [_1]';
$stats_message =
@@ -303,21 +317,31 @@ sub numerical_plot_percent {
#
my $total = $stats->{'submission_count'};
return '' if ($total == 0);
- my $min_bin_size = $stats->{'min_percent'};
- my $low_bin = $stats->{'lowest_ans'}-$stats->{'max_bin_size'};
- my $high_bin = $stats->{'highest_ans'}+$stats->{'max_bin_size'};
- if ($high_bin > 0 && $low_bin > -$high_bin) {
- $low_bin = -$high_bin;
- } elsif ($low_bin < 0 && $high_bin < -$low_bin) {
- $high_bin = -$low_bin;
+ my $max_bins = 50;
+ my $lowest_percent = $stats->{'min_percent'};
+ my $highest_percent = $stats->{'max_percent'};
+ my $percent_spread = $highest_percent - $lowest_percent;
+ foreach (qw/20 30 40 50 100 200/) {
+ if ($percent_spread < $_) {
+ $highest_percent =$_/2;
+ last;
+ }
}
- if (($high_bin -$low_bin)/$min_bin_size > 1000) {
- $min_bin_size = abs($high_bin - $low_bin) / 1000;
+ 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;
+ }
}
my @bins;
- for (my $num = $low_bin;$num <= $high_bin;$num+=($min_bin_size/2)) {
- push(@bins,$num);
+ for (my $bin = -$highest_percent;$bin<0;$bin+=$bin_size) {
+ push (@bins,$bin);
}
+ for (my $bin = 0; $bin<$highest_percent;$bin+=$bin_size) {
+ push (@bins,$bin);
+ }
+ push(@bins,$highest_percent);
#
my @correct;
my @incorrect;
@@ -325,46 +349,42 @@ 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 = ($submission-$ans)/$ans;
- my $bin=0;
- for ($bin=0;$bin<$#bins;$bin++) { # not <= for a reason
+ my $scaled_value =
+ ($ans) ? 100*($submission-$ans)/abs($ans)
+ : 0;
+ if ($scaled_value < $bins[0]) {
+ $bins[0]=$scaled_value -1;
+ }
+ my $bin;
+ for ($bin=0;$bin<$#bins;$bin++) {
last if ($bins[$bin]>$scaled_value);
}
- $correct[$bin]+=$correct_count;
- $incorrect[$bin]+=$incorrect_count;
- $count[$bin]+=$correct_count+$incorrect_count;
+ $correct[$bin-1]+=$correct_count;
+ $incorrect[$bin-1]+=$incorrect_count;
+ $count[$bin-1]+=$correct_count+$incorrect_count;
}
}
#
- # Skip empty bins
- my (@plot_correct,@plot_incorrect,@new_bins,@new_count);
- my $min_skip = 2;
- for (my $i=0;$i<=$#bins;$i++) {
- my $sum=0;
- for (my $j=-$min_skip;$j<=$min_skip && $i+$j<=$#bins;$j++) {
- $sum += $correct[$i+$j] + $incorrect[$i+$j];
- }
- if ($sum) {
- push(@new_bins,$bins[$i]);
- push(@plot_correct,$correct[$i]);
- push(@plot_incorrect,$incorrect[$i]);
- push(@new_count,$correct[$i]+$incorrect[$i]);
- }
- }
- @correct = @plot_correct;
- @incorrect = @plot_incorrect;
- @count = @new_count;
- @bins = @new_bins;
- for (my $i=0;$i<=$#bins;$i++) {
+ my @plot_correct = @correct;
+ my @plot_incorrect = @incorrect;
+ my $max;
+ for (my $i=0;$i<$#bins;$i++) {
$plot_correct[$i] *= 100/$total;
$plot_incorrect[$i] *= 100/$total;
+ if (! defined($max) ||
+ $max < $plot_correct[$i]+$plot_incorrect[$i] ) {
+ $max = $plot_correct[$i]+$plot_incorrect[$i];
+ }
+ }
+ foreach (qw/1 5 10 15 20 25 30 40 50 75 100/) {
+ if ($max <$_) { $max = $_; last; }
}
#
my $title = &mt('Percent Difference');
- my @labels = (1..scalar(@bins));
+ my @labels = (1..scalar(@bins)-1);
my $graph = &Apache::loncommon::DrawBarGraph
- ($title,'Percent difference from correct','Number of answers',
- 100,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
+ ($title,'Percent Difference from Correct','Percent of Answers',
+ $max,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
{xskip=>1});
#
my $table = $graph.$/.
@@ -377,7 +397,7 @@ sub numerical_plot_differences {
#
my $total = $stats->{'submission_count'};
return '' if ($total == 0);
- my $max_bins = 50;
+ my $max_bins = 21;
my $min_bin_size = $stats->{'min_abs'};
my $low_bin = $stats->{'lowest_ans'}-$stats->{'max_bin_size'};
my $high_bin = $stats->{'highest_ans'}+$stats->{'max_bin_size'};
@@ -386,7 +406,8 @@ 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 (!$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;
@@ -401,27 +422,38 @@ sub numerical_plot_differences {
while (my ($submission,$counts) = each(%$submissions)) {
my ($correct_count,$incorrect_count) = @$counts;
my $scaled_value = $submission-$ans;
+ if ($scaled_value < $bins[0]) {
+ $bins[0]=$scaled_value-1;
+ }
my $bin=0;
- for ($bin=0;$bin<$#bins;$bin++) { # not <= for a reason
+ for ($bin=0;$bin<$#bins;$bin++) {
last if ($bins[$bin]>$scaled_value);
}
- $correct[$bin]+=$correct_count;
- $incorrect[$bin]+=$incorrect_count;
- $count[$bin]+=$correct_count+$incorrect_count;
+ $correct[$bin-1]+=$correct_count;
+ $incorrect[$bin-1]+=$incorrect_count;
+ $count[$bin-1]+=$correct_count+$incorrect_count;
}
}
my @plot_correct = @correct;
my @plot_incorrect = @incorrect;
+ my $max;
for (my $i=0;$i<=$#bins;$i++) {
$plot_correct[$i] *= 100/$total;
$plot_incorrect[$i] *= 100/$total;
+ if (! defined($max) ||
+ $max < $plot_correct[$i]+$plot_incorrect[$i] ) {
+ $max = $plot_correct[$i]+$plot_incorrect[$i];
+ }
+ }
+ foreach (qw/1 5 10 15 20 25 30 40 50 75 100/) {
+ if ($max <$_) { $max = $_; last; }
}
#
my $title = &mt('Difference between submission and correct');
- my @labels = (1..scalar(@bins));
+ my @labels = (1..scalar(@bins)-1);
my $graph = &Apache::loncommon::DrawBarGraph
- ($title,'Difference from Correct','Number of answers',
- 100,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
+ ($title,'Difference from Correct','Percent of Answers',
+ $max,['#33FF00','#FF3300'],\@labels,\@plot_correct,\@plot_incorrect,
{xskip=>1});
#
my $table = $graph.$/.
@@ -464,8 +496,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;
@@ -498,7 +534,7 @@ sub numerical_classify_responses {
&capa::caparesponse_get_real_response($myunit,
$mysub,
\$scaled);
- &Apache::lonnet::logthis('scaled = '.$scaled.' result ='.$result);
+# &Apache::lonnet::logthis('scaled = '.$scaled.' result ='.$result);
next if (! defined($scaled));
# next if ($result ne '6');
my $submission = $scaled;
@@ -513,6 +549,8 @@ sub numerical_classify_responses {
}
}
}
+ $stats{'correct_count'} |= 0;
+ $stats{'incorrect_count'} |= 0;
$stats{'students'}=scalar(keys(%students));
return (\%submission_data,\%stats);
}
@@ -546,7 +584,9 @@ sub numerical_bin_table {
''.$/;
for (my $i=0;$i[$i];
+ if ($i == 0) { $lownum = '-∞'; }
my $highnum = $bins->[$i+1];
+ if ($i == scalar(@{$bins})-2) { $highnum = '∞'; }
$table .=
'
'.
'
'.$labels->[$i].'
'.
@@ -717,7 +757,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');
}
#
@@ -746,9 +786,10 @@ sub radio_response_analysis {
$analysis_html .= $table;
# Gather student data
my $response_data = &Apache::loncoursedata::get_response_data
- (\@Apache::lonstatistics::SelectedSections,
+ ([&Apache::lonstatistics::get_selected_sections()],
+ [&Apache::lonstatistics::get_selected_groups()],
$Apache::lonstatistics::enrollment_status,
- $resource->{'symb'},$respid);
+ $resource->symb,$respid);
my $correct; # either a hash reference or a scalar
if ($problem_analysis->{'answercomputed'} || scalar(@$concepts) > 1) {
# This takes a while for large classes...
@@ -759,7 +800,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)) {
@@ -778,13 +819,13 @@ sub radio_response_analysis {
}
#
$analysis_html.='
';
- for (my $plot_num = 1;$plot_num<=$ENV{'form.NumPlots'};$plot_num++) {
+ for (my $plot_num = 1;$plot_num<=$env{'form.NumPlots'};$plot_num++) {
# classify data ->correct foil -> selected foil
my ($restriction_function,
$correct_foil_title,$incorrect_foil_title,
$pre_graph_text,$post_graph_text,
$no_data_text,@extra_data);
- if ($ENV{'form.AnalyzeOver'} eq 'tries') {
+ if ($env{'form.AnalyzeOver'} eq 'tries') {
$restriction_function = sub {($_[0]->{'tries'} == $plot_num?1:0)};
$correct_foil_title = 'Attempt '.$plot_num;
$incorrect_foil_title = 'Attempt '.$plot_num;
@@ -792,7 +833,7 @@ sub radio_response_analysis {
'Attempt [_1], [_2] submissions, [_3] correct, [_4] incorrect';
$post_graph_text = '';
$no_data_text = 'No data exists for attempt [_1]';
- } elsif ($ENV{'form.AnalyzeOver'} eq 'time') {
+ } elsif ($env{'form.AnalyzeOver'} eq 'time') {
my $starttime = &Apache::lonhtmlcommon::get_date_from_form
('startdate_'.$plot_num);
my $endtime = &Apache::lonhtmlcommon::get_date_from_form
@@ -862,16 +903,14 @@ sub radio_response_analysis {
$choice_plot ne '' ||
$stacked_plot ne '') {
my $correct = $foil_choice_data->{'_correct'};
- if (! defined($correct) || $correct eq '') {
- $correct = 0;
- }
- my $incorrect =
+ $correct |= 0;
+ my $incorrect = $foil_choice_data->{'_count'}-$correct;
$analysis_html.= '