--- loncom/interface/statistics/lonproblemanalysis.pm 2003/10/24 13:38:06 1.46
+++ loncom/interface/statistics/lonproblemanalysis.pm 2004/01/08 19:20:12 1.53
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemanalysis.pm,v 1.46 2003/10/24 13:38:06 matthew Exp $
+# $Id: lonproblemanalysis.pm,v 1.53 2004/01/08 19:20:12 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -24,7 +24,6 @@
#
# http://www.lon-capa.org/
#
-
package Apache::lonproblemanalysis;
use strict;
@@ -50,7 +49,7 @@ my @SubmitButtons = ({ name => 'ProblemA
{ name => 'updatecaches',
text => 'Update Student Data' },
{ name => 'SelectAnother',
- text => 'Choose a different resource' },
+ text => 'Choose a different Problem' },
{ name => 'ExcelOutput',
text => 'Produce Excel Output' });
@@ -73,6 +72,20 @@ sub render_resource {
sub BuildProblemAnalysisPage {
my ($r,$c)=@_;
+ #
+ my %Saveable_Parameters = ('Status' => 'scalar',
+ 'Section' => 'array',
+ 'NumPlots' => 'scalar',
+ 'AnalyzeAs' => 'scalar',
+ 'AnalyzeOver' => 'scalar',
+ );
+ &Apache::loncommon::store_course_settings('problem_analysis',
+ \%Saveable_Parameters);
+ &Apache::loncommon::restore_course_settings('problem_analysis',
+ \%Saveable_Parameters);
+ #
+ &Apache::lonstatistics::PrepareClasslist();
+ #
$r->print('
'.&mt('Option Response Problem Analysis').'
');
$r->print(&CreateInterface());
#
@@ -108,21 +121,29 @@ sub BuildProblemAnalysisPage {
#
$r->print('
');
#
- my ($symb,$part,$resid) = &get_problem_symb(
+ my ($symb,$part,$resid,$resptype) = &get_problem_symb(
&Apache::lonnet::unescape($ENV{'form.problemchoice'}));
$r->rflush();
#
my $resource = &get_resource_from_symb($symb);
- if (! defined($resource)) {
+ if (! defined($resource) || ! defined($resptype)) {
$r->print('resource is undefined');
} else {
$r->print(''.$resource->{'title'}.'
');
$r->print(''.$resource->{'src'}.'
');
+ $r->print(&render_resource($resource));
$r->rflush();
my %Data = &get_problem_data($resource->{'src'});
my $ProblemData = $Data{$part.'.'.$resid};
- &OptionResponseAnalysis($r,$resource,$resid,$ProblemData,
- \@Students);
+ if ($resptype eq 'option') {
+ &OptionResponseAnalysis($r,$resource,$resid,$ProblemData,
+ \@Students);
+ } elsif ($resptype eq 'radiobutton') {
+ &RadioResponseAnalysis($r,$resource,$part,$resid,$ProblemData,
+ \@Students);
+ } else {
+ $r->print('This analysis is not supported
');
+ }
}
$r->print('
');
} else {
@@ -134,6 +155,198 @@ sub BuildProblemAnalysisPage {
}
}
+=pod
+
+Removed code:
+
+#########################################################
+#########################################################
+##
+## Radio Response Routines
+##
+#########################################################
+#########################################################
+sub RadioResponseAnalysis {
+ my ($r,$resource,$part,$respid,$ProblemData,$Students) = @_;
+ my $analysis_html;
+ my $PerformanceData =
+ &Apache::loncoursedata::get_response_data
+ ($Students,$resource->{'symb'},$respid);
+ if (! defined($PerformanceData) ||
+ ref($PerformanceData) ne 'ARRAY' ) {
+ $analysis_html = ''.
+ &mt('There is no submission data for this resource').
+ '
';
+ $r->print($analysis_html);
+ return;
+ }
+ if (exists($ENV{'form.ExcelOutput'})) {
+ $analysis_html .= &RR_Excel_output($r,$resource,$PerformanceData,
+ $ProblemData);
+ } elsif ($ENV{'form.AnalyzeOver'} eq 'Tries') {
+ $analysis_html .= &RR_Tries_Analysis($r,$resource,$PerformanceData,
+ $ProblemData);
+ } elsif ($ENV{'form.AnalyzeOver'} eq 'Time') {
+ $analysis_html .= &RR_Time_Analysis($r,$resource,$PerformanceData,
+ $ProblemData);
+ } else {
+ $analysis_html .= ''.
+ &mt('The analysis you have selected is not supported at this time').
+ '
';
+ }
+ $r->print($analysis_html);
+}
+
+
+sub RR_Excel_output {
+ my ($r,$PerformanceData,$ProblemData) = @_;
+ return 'No!
';
+}
+
+sub RR_Tries_Analysis {
+ my ($r,$resource,$PerformanceData,$ProblemData) = @_;
+ my $analysis_html;
+ my $mintries = 1;
+ my $maxtries = $ENV{'form.NumPlots'};
+ my ($table,$Foils,$Concepts) = &build_foil_index($ProblemData);
+ if ((@$Concepts < 2) && ($ENV{'form.AnalyzeAs'} ne 'Foils')) {
+ $table = ''.
+ &mt('Not enough data for concept analysis. '.
+ 'Performing Foil Analysis').
+ '
'.$table;
+ $ENV{'form.AnalyzeAs'} = 'Foils';
+ }
+ $analysis_html .= $table;
+ my @TryData = &RR_tries_data_analysis($r,$PerformanceData);
+ if ($ENV{'form.AnalyzeAs'} eq 'Foils') {
+ $analysis_html = &RR_Tries_Foil_Analysis($mintries,$maxtries,$Foils,
+ \@TryData,$ProblemData);
+ } else {
+ $analysis_html = &RR_Tries_Concept_Analysis($mintries,$maxtries,
+ $Concepts,
+ \@TryData,
+ $ProblemData);
+ }
+ return $analysis_html;
+}
+
+sub RR_tries_data_analysis {
+ my ($r,$Attempt_data) = @_;
+ my @TryData;
+ foreach my $attempt (@$Attempt_data) {
+ my %Attempt = &hashify_attempt($attempt);
+ my ($answer,undef) = split('=',$Attempt{'submission'});
+ $TryData[$Attempt{'tries'}]->{$answer}++;
+ }
+ return @TryData;
+}
+
+sub RR_Time_Analysis {
+ my ($r,$PerformanceData,$ProblemData) = @_;
+ my $html;
+ return $html;
+}
+
+sub RR_Tries_Foil_Analysis {
+ my ($min,$max,$Foils,$TryData,$ProblemData) = @_;
+ my $html;
+ #
+ # Compute the data neccessary to make the plots
+ for (my $try=$min;$try<=$max;$try++) {
+ my @PlotData_Correct;
+ my @PlotData_Incorrect;
+ next if ($try > scalar(@{$TryData}));
+ next if (! defined($TryData->[$try-1]));
+ my %DataSet = %{$TryData->[$try-1]};
+ my $total = 0;
+ foreach my $foilid (@$Foils) {
+ $total += $DataSet{$foilid};
+ }
+ foreach my $foilid (@$Foils) {
+ if ($total == 0) {
+ push (@PlotData_Correct,0);
+ push (@PlotData_Incorrect,0);
+ } else {
+ if ($ProblemData->{'_Foils'}->{$foilid}->{'value'} eq 'true') {
+ push (@PlotData_Correct,
+ int(100*$DataSet{$foilid}/$total));
+ push (@PlotData_Incorrect,0);
+ } else {
+ push (@PlotData_Correct,0);
+ push (@PlotData_Incorrect,
+ int(100*$DataSet{$foilid}/$total));
+ }
+ }
+ }
+ my $title='Attempt '.$try;
+ my $xlabel = $total.' Submissions';
+ $html.= &Apache::loncommon::DrawBarGraph($title,
+ $xlabel,
+ 'Percent Choosing',
+ 100,
+ ['#33ff00','#ff3300'],
+ \@PlotData_Correct,
+ \@PlotData_Incorrect);
+ }
+ &Apache::lonnet::logthis('plot = '.$html);
+ return $html;
+}
+
+sub RR_Tries_Concept_Analysis {
+ my ($min,$max,$Concepts,$ResponseData,$ProblemData) = @_;
+ my $html;
+ return $html;
+}
+
+sub RR_Time_Foil_Analysis {
+ my ($min,$max,$Foils,$ResponseData,$ProblemData) = @_;
+ my $html;
+ return $html;
+}
+
+sub RR_Time_Concept_Analysis {
+ my ($min,$max,$Concepts,$ResponseData,$ProblemData) = @_;
+ my $html;
+ return $html;
+}
+
+
+
+sub get_Radio_problem_data {
+ my ($url) = @_;
+ my $Answ=&Apache::lonnet::ssi($url,('grade_target' => 'analyze'));
+ (my $garbage,$Answ)=split('_HASH_REF__',$Answ,2);
+ my %Answer = &Apache::lonnet::str2hash($Answ);
+ my %Partdata;
+ &Apache::lonnet::logthis('url = '.$url);
+ foreach my $part (@{$Answer{'parts'}}) {
+ while (my($key,$value) = each(%Answer)) {
+# if (ref($value) eq 'ARRAY') {
+# &Apache::lonnet::logthis('is ref part:'.$part.' '.$key.'='.join(',',@$value));
+# } else {
+# &Apache::lonnet::logthis('notref part:'.$part.' '.$key.'='.$value);
+# }
+ next if ($key !~ /^$part/);
+ $key =~ s/^$part\.//;
+ if ($key eq 'foils') {
+ $Partdata{$part}->{'_Foils'}=$value;
+ } elsif ($key eq 'options') {
+ $Partdata{$part}->{'_Options'}=$value;
+ } elsif ($key eq 'shown') {
+ $Partdata{$part}->{'_Shown'}=$value;
+ } elsif ($key =~ /^foil.value.(.*)$/) {
+ $Partdata{$part}->{$1}->{'value'}=$value;
+ } elsif ($key =~ /^foil.text.(.*)$/) {
+ $Partdata{$part}->{$1}->{'text'}=$value;
+ }
+ }
+ }
+ return %Partdata;
+}
+
+=cut
+
+
#########################################################
#########################################################
##
@@ -143,9 +356,8 @@ sub BuildProblemAnalysisPage {
#########################################################
sub OptionResponseAnalysis {
my ($r,$resource,$resid,$ProblemData,$Students) = @_;
- &Apache::lonnet::logthis('resid = '.$resid);
my $PerformanceData =
- &Apache::loncoursedata::get_optionresponse_data
+ &Apache::loncoursedata::get_response_data
($Students,$resource->{'symb'},$resid);
if (! defined($PerformanceData) ||
ref($PerformanceData) ne 'ARRAY' ) {
@@ -153,7 +365,6 @@ sub OptionResponseAnalysis {
&mt('There is no student data for this problem.').
'');
} else {
- $r->print(&render_resource($resource));
$r->rflush();
if (exists($ENV{'form.ExcelOutput'})) {
my $result = &prepare_optionresponse_excel_sheet($r,$resource,
@@ -229,7 +440,7 @@ sub Tries_Foil_Analysis {
100*$ResponseData{$foilid}->[$i]->{'_correct'}/
$ResponseData{$foilid}->[$i]->{'_total'});
}
- foreach my $option (@{$ORdata->{'Options'}}) {
+ foreach my $option (@{$ORdata->{'_Options'}}) {
push(@{$PlotData[$i]->{'_total'}},
$ResponseData{$foilid}->[$i]->{'_total'});
if ($ResponseData{$foilid}->[$i]->{'_total'} == 0) {
@@ -263,7 +474,7 @@ sub Tries_Foil_Analysis {
}
my $title = 'Attempt '.$i.', '.$count;
my @Datasets;
- foreach my $option ('_correct',@{$ORdata->{'Options'}}) {
+ foreach my $option ('_correct',@{$ORdata->{'_Options'}}) {
next if (! exists($PlotData[$i]->{$option}));
push(@Datasets,$PlotData[$i]->{$option});
}
@@ -368,7 +579,7 @@ sub analyze_option_data_by_tries {
$maxtries = $mintries if (! defined($maxtries) || $maxtries < $mintries);
foreach my $row (@$PerformanceData) {
next if (! defined($row));
- my $tries = &get_tries_from_OR_row($row);
+ my $tries = &get_tries_from_row($row);
my %Row = &Process_OR_Row($row);
next if (! %Row);
while (my ($foilid,$href) = each(%Row)) {
@@ -412,14 +623,14 @@ sub time_analysis {
('enddate_'.$i);
if (! defined($starttime) || ! defined($endtime)) {
my $sec_in_day = 86400;
- my $last_sub_time = &get_time_from_OR_row($PerformanceData->[-1]);
+ my $last_sub_time = &get_time_from_row($PerformanceData->[-1]);
my ($sday,$smon,$syear);
(undef,undef,undef,$sday,$smon,$syear) =
localtime($last_sub_time - $sec_in_day*$i);
$starttime = &Time::Local::timelocal(0,0,0,$sday,$smon,$syear);
$endtime = $starttime + $sec_in_day;
if ($i == ($num_plots -1 )) {
- $starttime = &get_time_from_OR_row($PerformanceData->[0]);
+ $starttime = &get_time_from_row($PerformanceData->[0]);
}
}
my $startdateform = &Apache::lonhtmlcommon::date_setter
@@ -431,12 +642,12 @@ sub time_analysis {
my $end_index;
my $j;
while (++$j < scalar(@$PerformanceData)) {
- last if (&get_time_from_OR_row($PerformanceData->[$j])
+ last if (&get_time_from_row($PerformanceData->[$j])
> $starttime);
}
$begin_index = $j;
while (++$j < scalar(@$PerformanceData)) {
- last if (&get_time_from_OR_row($PerformanceData->[$j]) > $endtime);
+ last if (&get_time_from_row($PerformanceData->[$j]) > $endtime);
}
$end_index = $j;
##
@@ -492,7 +703,7 @@ sub Foil_Time_Analysis {
}
my $total_incorrect = $total - $TimeData{$foil}->{'_correct'};
my $optionidx = 1;
- foreach my $option (@{$ORdata->{'Options'}}) {
+ foreach my $option (@{$ORdata->{'_Options'}}) {
if ($total_incorrect == 0) {
push(@{$Plotdata[$optionidx]},0);
} else {
@@ -708,7 +919,7 @@ sub build_problem_data_worksheet {
@Headers = ('Foil Number','FoilName','Foil Text','Correct value');
}
$worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'});
- my %Foildata = %{$ORdata->{'Foils'}};
+ my %Foildata = %{$ORdata->{'_Foils'}};
my $conceptindex = 1;
my $foilindex = 1;
foreach my $concept (@$Concepts) {
@@ -756,7 +967,7 @@ sub build_problem_data_worksheet {
##
## Option data output
$worksheet->write($rows_output++,0,'Options',$format->{'header'});
- foreach my $string (@{$ORdata->{'Options'}}) {
+ foreach my $string (@{$ORdata->{'_Options'}}) {
$worksheet->write($rows_output++,0,$string);
}
return 'okay';
@@ -1013,12 +1224,12 @@ sub _adjustment {
sub build_foil_index {
my ($ORdata) = @_;
- return if (! exists($ORdata->{'Foils'}));
- my %Foildata = %{$ORdata->{'Foils'}};
+ return if (! exists($ORdata->{'_Foils'}));
+ my %Foildata = %{$ORdata->{'_Foils'}};
my @Foils = sort(keys(%Foildata));
my %Concepts;
foreach my $foilid (@Foils) {
- push(@{$Concepts{$Foildata{$foilid}->{'Concept'}}},
+ push(@{$Concepts{$Foildata{$foilid}->{'_Concept'}}},
$foilid);
}
undef(@Foils);
@@ -1129,7 +1340,7 @@ sub build_option_index {
my $table = "\n";
my $optionindex = 0;
my @Rows;
- foreach my $option (&mt('correct option chosen'),@{$ORdata->{'Options'}}) {
+ foreach my $option (&mt('correct option chosen'),@{$ORdata->{'_Options'}}) {
push (@Rows,
''.
''.
@@ -1192,6 +1403,8 @@ sub CreateInterface {
{ # These braces are here to organize the code, not scope it.
{
$Str .= ''.&mt('Analyze Over ');
+ $Str .= &Apache::loncommon::help_open_topic
+ ('Analysis_Analyze_Over');
$Str .=' ';
+ $Str .= '';
+ $Str .= ' ';
}
{
$Str .= ''.&mt('Analyze as ');
+ $Str .= &Apache::loncommon::help_open_topic
+ ('Analysis_Analyze_as');
$Str .=' |