--- loncom/interface/statistics/lonproblemanalysis.pm 2004/02/20 16:24:20 1.72
+++ loncom/interface/statistics/lonproblemanalysis.pm 2004/04/01 15:32:06 1.84
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemanalysis.pm,v 1.72 2004/02/20 16:24:20 matthew Exp $
+# $Id: lonproblemanalysis.pm,v 1.84 2004/04/01 15:32:06 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -160,13 +160,17 @@ sub BuildProblemAnalysisPage {
$ProblemData,
\@Students);
} elsif ($current_problem->{'resptype'} eq 'numerical') {
-# if (exists($ENV{'form.ExcelOutput'})) {
- &Apache::lonstudentsubmissions::prepare_excel_output
- ($r,$current_problem,$ProblemData,\@Students);
-# } else {
-# &NumericalResponseAnalysis($r,$current_problem,
-# $ProblemData,\@Students);
-# }
+ ##
+ ## analyze all responses of a problem at once
+ my $res = $current_problem->{'resource'};
+ foreach my $partid (@{$res->{'parts'}}) {
+ $current_problem->{'part'} = $partid;
+ foreach my $respid (@{$res->{'partdata'}->{$partid}->{'ResponseIds'}}) {
+ $current_problem->{'respid'}=$respid;
+ &NumericalResponseAnalysis($r,$current_problem,
+ $ProblemData,\@Students);
+ }
+ }
} else {
$r->print('
.
+## These should probably go somewhere more suitable soon.
+sub line {
+ my ($x1,$y1,$x2,$y2,$color,$thickness) = @_;
+ return qq{$/};
+}
+
+sub text {
+ my ($x,$y,$color,$text,$font,$direction) = @_;
+ if (! defined($font) || $font !~ /^(tiny|small|medium|large|giant)$/) {
+ $font = 'medium';
+ }
+ if (! defined($direction) || $direction ne 'vertical') {
+ $direction = '';
+ }
+ return qq{$text};
+}
+
+sub rectangle {
+ my ($x1,$y1,$x2,$y2,$color,$thickness,$filled) = @_;
+ return qq{};
+}
+
+sub arc {
+ my ($x,$y,$width,$height,$start,$end,$color,$thickness,$filled)=@_;
+ return qq{};
+}
+
+sub circle {
+ my ($x,$y,$radius,$color,$thickness,$filled)=@_;
+ return &arc($x,$y,$radius,$radius,0,360,$color,$thickness,$filled);
}
sub build_student_data_worksheet {
@@ -308,9 +387,10 @@ sub RadioResponseAnalysis {
my ($resource,$respid) = ($problem->{'resource'},
$problem->{'respid'});
my $analysis_html;
- my $PerformanceData =
- &Apache::loncoursedata::get_response_data
- ($Students,$resource->{'symb'},$respid);
+ my $PerformanceData = &Apache::loncoursedata::get_response_data
+ (\@Apache::lonstatistics::SelectedSections,
+ $Apache::lonstatistics::enrollment_status,
+ $resource->{'symb'},$respid);
if (! defined($PerformanceData) ||
ref($PerformanceData) ne 'ARRAY' ) {
$analysis_html = ''.
@@ -493,9 +573,10 @@ sub OptionResponseAnalysis {
my ($resource,$respid) = ($problem->{'resource'},
$problem->{'respid'});
# Note: part data is not needed.
- my $PerformanceData =
- &Apache::loncoursedata::get_response_data
- ($Students,$resource->{'symb'},$respid);
+ my $PerformanceData = &Apache::loncoursedata::get_response_data
+ (\@Apache::lonstatistics::SelectedSections,
+ $Apache::lonstatistics::enrollment_status,
+ $resource->{'symb'},$respid);
if (! defined($PerformanceData) ||
ref($PerformanceData) ne 'ARRAY' ) {
$r->print(''.
@@ -541,7 +622,8 @@ sub OR_tries_analysis {
my $mintries = 1;
my $maxtries = $ENV{'form.NumPlots'};
my ($table,$Foils,$Concepts) = &build_foil_index($ORdata);
- if ((@$Concepts < 2) && ($ENV{'form.AnalyzeAs'} ne 'Foils')) {
+ if (! defined($Concepts) ||
+ ((@$Concepts < 2) && ($ENV{'form.AnalyzeAs'} ne 'Foils'))) {
$table = ''.
&mt('Not enough data for concept analysis. '.
'Performing Foil Analysis').
@@ -552,7 +634,7 @@ sub OR_tries_analysis {
$mintries,$maxtries);
my $analysis = '';
if ($ENV{'form.AnalyzeAs'} eq 'Foils') {
- $analysis = &OR_Tries_Foil_Analysis($mintries,$maxtries,$Foils,
+ $analysis = &OR_Tries_Foil_Analysis($mintries,$maxtries,$Concepts,
\%ResponseData,$ORdata);
} else {
$analysis = &OR_Tries_Concept_Analysis($mintries,$maxtries,
@@ -563,82 +645,100 @@ sub OR_tries_analysis {
}
sub OR_Tries_Foil_Analysis {
- my ($mintries,$maxtries,$Foils,$respdat,$ORdata) = @_;
+ my ($mintries,$maxtries,$Concepts,$respdat,$ORdata) = @_;
my %ResponseData = %$respdat;
#
# Compute the data neccessary to make the plots
my @PlotData;
- foreach my $foilid (@$Foils) {
- for (my $i=$mintries;$i<=$maxtries;$i++) {
- if ($ResponseData{$foilid}->[$i]->{'_total'} == 0) {
- push(@{$PlotData[$i]->{'_correct'}},0);
- } else {
- push(@{$PlotData[$i]->{'_correct'}},
- 100*$ResponseData{$foilid}->[$i]->{'_correct'}/
- $ResponseData{$foilid}->[$i]->{'_total'});
- }
- foreach my $option (@{$ORdata->{'_Options'}}) {
- push(@{$PlotData[$i]->{'_total'}},
- $ResponseData{$foilid}->[$i]->{'_total'});
- if ($ResponseData{$foilid}->[$i]->{'_total'} == 0) {
- push (@{$PlotData[$i]->{$option}},0);
+ foreach my $concept (@$Concepts) {
+ foreach my $foilid (@{$concept->{'foils'}}) {
+ for (my $try=$mintries;$try<=$maxtries;$try++) {
+ if ($ResponseData{$foilid}->[$try]->{'_total'} == 0) {
+ push(@{$PlotData[$try]->{'_correct'}},0);
} else {
- if ($ResponseData{$foilid}->[$i]->{'_total'} ==
- $ResponseData{$foilid}->[$i]->{'_correct'}) {
- push(@{$PlotData[$i]->{$option}},0);
+ push(@{$PlotData[$try]->{'_correct'}},
+ 100*$ResponseData{$foilid}->[$try]->{'_correct'}/
+ $ResponseData{$foilid}->[$try]->{'_total'});
+ }
+ foreach my $option (@{$ORdata->{'_Options'}}) {
+ push(@{$PlotData[$try]->{'_total'}},
+ $ResponseData{$foilid}->[$try]->{'_total'});
+ if ($ResponseData{$foilid}->[$try]->{'_total'} == 0) {
+ push (@{$PlotData[$try]->{$option}},0);
} else {
- push (@{$PlotData[$i]->{$option}},
- 100 * $ResponseData{$foilid}->[$i]->{$option} /
- ($ResponseData{$foilid}->[$i]->{'_total'} -
- $ResponseData{$foilid}->[$i]->{'_correct'}));
+ if ($ResponseData{$foilid}->[$try]->{'_total'} ==
+ $ResponseData{$foilid}->[$try]->{'_correct'}) {
+ push(@{$PlotData[$try]->{$option}},0);
+ } else {
+ push (@{$PlotData[$try]->{$option}},
+ 100 *
+ $ResponseData{$foilid}->[$try]->{$option} /
+ ($ResponseData{$foilid}->[$try]->{'_total'}
+ -
+ $ResponseData{$foilid}->[$try]->{'_correct'}
+ ));
+ }
}
- }
+ } # End of foreach my $option
}
- }
- }
+ } # End of foreach my $foilid
+ } # End of foreach my $concept
#
# Build a table for the plots
my $analysis_html = "
\n";
- my $foilkey = &build_option_index($ORdata);
- for (my $i=$mintries;$i<=$maxtries;$i++) {
- my $count = $ResponseData{'_total'}->[$i];
- if ($count == 0) {
- $count = 'no submissions';
- } elsif ($count == 1) {
- $count = '1 submission';
- } else {
- $count = $count.' submissions';
- }
- my $title = 'Attempt '.$i.', '.$count;
+ my $optionkey = &build_option_index($ORdata);
+ for (my $try=$mintries;$try<=$maxtries;$try++) {
+ my $count = $ResponseData{'_total'}->[$try];
+ my $title = 'Submission '.$try.' (N='.$count.')';
my @Datasets;
foreach my $option ('_correct',@{$ORdata->{'_Options'}}) {
- next if (! exists($PlotData[$i]->{$option}));
- push(@Datasets,$PlotData[$i]->{$option});
+ next if (! exists($PlotData[$try]->{$option}));
+ push(@Datasets,$PlotData[$try]->{$option});
+ }
+ #
+ # Put a blank in the data set between concepts
+ for (my $set =0;$set<=$#Datasets;$set++) {
+ my @Data = @{$Datasets[$set]};
+ my $idx = 0;
+ foreach my $concept (@{$Concepts}) {
+ foreach my $foilid (@{$concept->{'foils'}}) {
+ $Datasets[$set]->[$idx++]=shift(@Data);
+ }
+ if ($concept->{'name'} ne $Concepts->[-1]->{'name'}) {
+ $Datasets[$set]->[$idx++] = 0;
+ }
+ }
}
+ #
+ # Set up the labels needed for the bar graph
+ my @Labels;
+ my $idx = 1;
+ foreach my $concept (@{$Concepts}) {
+ foreach my $foilid (@{$concept->{'foils'}}) {
+ push(@Labels,$idx++);
+ }
+ push(@Labels,'');
+ }
+ #
my $correctgraph = &Apache::loncommon::DrawBarGraph
($title,'Foil Number','Percent Correct',
- 100,$plotcolors,undef,$Datasets[0]);
+ 100,$plotcolors,\@Labels,$Datasets[0]);
$analysis_html.= ''.$correctgraph.' | ';
- ##
- ##
+
+ #
+ #
next if (! defined($Datasets[0]));
for (my $i=0; $i< scalar(@{$Datasets[0]});$i++) {
$Datasets[0]->[$i]=0;
}
- $count = $ResponseData{'_total'}->[$i]-$ResponseData{'_correct'}->[$i];
- if ($count == 0) {
- $count = 'no submissions';
- } elsif ($count == 1) {
- $count = '1 submission';
- } else {
- $count = $count.' submissions';
- }
- $title = 'Attempt '.$i.', '.$count;
+ $count = $ResponseData{'_total'}->[$try] -
+ $ResponseData{'_correct'}->[$try];
+ $title = 'Submission '.$try.' (N='.$count.')';
my $incorrectgraph = &Apache::loncommon::DrawBarGraph
($title,'Foil Number','% Option Chosen Incorrectly',
- 100,$plotcolors,undef,@Datasets);
+ 100,$plotcolors,\@Labels,@Datasets);
$analysis_html.= ''.$incorrectgraph.' | ';
- $analysis_html.= ''.$foilkey." | |
\n";
+ $analysis_html.= ''.$optionkey." | \n";
}
$analysis_html .= " |
\n";
return $analysis_html;
@@ -1220,18 +1320,18 @@ sub build_foil_index {
if (@Concepts > 1) {
$table .= ''.
''.$conceptindex.' | '.
- ''.&HTML::Entities::encode($concept->{'name'}).' | '.
+ ''.&HTML::Entities::encode($concept->{'name'},'<>&"').' | '.
''.$foilindex++.' | '.
- ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'},'<>&"').' | '.
''.$Foildata{$firstfoil}->{'text'}.' | '.
- ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'},'<>&"').' | '.
"
\n";
} else {
$table .= ''.
''.$foilindex++.' | '.
- ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'},'<>&"').' | '.
''.$Foildata{$firstfoil}->{'text'}.' | '.
- ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'},'<>&"').' | '.
"
\n";
}
foreach my $foilid (@FoilsInConcept) {
@@ -1240,16 +1340,16 @@ sub build_foil_index {
' | '.
' | '.
''.$foilindex.' | '.
- ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'},'<>&"').' | '.
''.$Foildata{$foilid}->{'text'}.' | '.
- ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'},'<>&"').' | '.
"\n";
} else {
$table .= ''.
''.$foilindex.' | '.
- ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'},'<>&"').' | '.
''.$Foildata{$foilid}->{'text'}.' | '.
- ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'}).' | '.
+ ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'},'<>&"').' | '.
"
\n";
}
} continue {
@@ -1274,7 +1374,7 @@ sub build_option_index {
''.
''.
(' 'x4).' | '.
- ''.&HTML::Entities::encode($option).' | '.
+ ''.&HTML::Entities::encode($option,'<>&"').' | '.
"
\n");
}
shift(@Rows); # Throw away 'correct option chosen' color