--- loncom/interface/statistics/lonproblemanalysis.pm 2003/10/30 16:24:36 1.47
+++ loncom/interface/statistics/lonproblemanalysis.pm 2003/12/10 23:09:26 1.50
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemanalysis.pm,v 1.47 2003/10/30 16:24:36 matthew Exp $
+# $Id: lonproblemanalysis.pm,v 1.50 2003/12/10 23:09:26 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -24,7 +24,6 @@
#
# http://www.lon-capa.org/
#
-
package Apache::lonproblemanalysis;
use strict;
@@ -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());
#
@@ -120,16 +133,13 @@ sub BuildProblemAnalysisPage {
$r->print(''.$resource->{'src'}.'
');
$r->print(&render_resource($resource));
$r->rflush();
+ my %Data = &get_problem_data($resource->{'src'});
+ my $ProblemData = $Data{$part.'.'.$resid};
if ($resptype eq 'option') {
- my %Data = &get_OR_problem_data($resource->{'src'});
- my $ProblemData = $Data{$part.'.'.$resid};
&OptionResponseAnalysis($r,$resource,$resid,$ProblemData,
\@Students);
} elsif ($resptype eq 'radiobutton') {
- $r->print('This analysis is not supported
');
- my %Data = &get_Radio_problem_data($resource->{'src'});
- my $ProblemData = $Data{$part.'.'.$resid};
- &RadioResponseAnalysis($r,$resource,$resid,$ProblemData,
+ &RadioResponseAnalysis($r,$resource,$part,$resid,$ProblemData,
\@Students);
} else {
$r->print('This analysis is not supported
');
@@ -145,6 +155,9 @@ sub BuildProblemAnalysisPage {
}
}
+=pod
+
+Removed code:
#########################################################
#########################################################
@@ -154,19 +167,186 @@ sub BuildProblemAnalysisPage {
#########################################################
#########################################################
sub RadioResponseAnalysis {
- my ($r,$resource,$resid,$ProblemData,$Students) = @_;
+ my ($r,$resource,$part,$respid,$ProblemData,$Students) = @_;
+ my $analysis_html;
my $PerformanceData =
&Apache::loncoursedata::get_response_data
- ($Students,$resource->{'symb'},$resid);
- if (! ref($PerformanceData)) {
- $r->print('There is no submission data for this resource
');
+ ($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;
}
-# foreach my $row (@$PerformanceData) {
-# &Apache::lonnet::logthis('row = '.join(',',@$row));
-# }
- 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
+
+
#########################################################
#########################################################
##
@@ -260,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) {
@@ -294,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});
}
@@ -523,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 {
@@ -739,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) {
@@ -787,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';
@@ -1044,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);
@@ -1160,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,
''.
''.
@@ -1302,16 +1482,24 @@ sub ProblemSelector {
for (my $i=0;$i{'ResponseTypes'}});$i++){
my $respid = $partdata->{'ResponseIds'}->[$i];
my $resptype = $partdata->{'ResponseTypes'}->[$i];
- if ($resptype eq 'option' || $resptype eq 'radiobutton') {
- my $value = &Apache::lonnet::escape($res->{'symb'}.':'.$part.':'.$respid.':'.$resptype);
+ if ($resptype eq 'option' ){
+# if ($resptype eq 'option' || $resptype eq 'radiobutton') {
+ my $value =
+ &Apache::lonnet::escape($res->{'symb'}.':'.$part.
+ ':'.$respid.':'.$resptype);
my $checked = '';
if ($ENV{'form.problemchoice'} eq $value) {
$checked = 'checked ';
}
+ my $title = $res->{'title'};
+ if (! defined($title) || $title eq '') {
+ ($title) = ($res->{'src'} =~ m:/([^/]*)$:);
+ }
$seq_str .= ''.
''.
' | '.
- ''.$resptype.' '.$res->{'title'}.' ';
+ ''.$title.' ';
+# ''.$resptype.' '.$res->{'title'}.' ';
if ($partdata->{'option'} > 1) {
$seq_str .= &mt('response').' '.$respid;
}
@@ -1379,6 +1567,16 @@ sub get_tries_from_row {
return undef;
}
+sub hashify_attempt {
+ my ($row) = @_;
+ my %attempt;
+ $attempt{'tries'} = $row->[&Apache::loncoursedata::RD_tries()];
+ $attempt{'submission'} = $row->[&Apache::loncoursedata::RD_submission()];
+ $attempt{'award'} = $row->[&Apache::loncoursedata::RD_awarddetail()];
+ $attempt{'timestamp'} = $row->[&Apache::loncoursedata::RD_timestamp()];
+ return %attempt;
+}
+
sub Process_OR_Row {
my ($row) = @_;
my %RowData;
@@ -1414,7 +1612,7 @@ sub Process_OR_Row {
## note: we must force each foil and option to not begin or end with
## spaces as they are stored without such data.
##
-sub get_OR_problem_data {
+sub get_problem_data {
my ($url) = @_;
my $Answ=&Apache::lonnet::ssi($url,('grade_target' => 'analyze'));
(my $garbage,$Answ)=split(/_HASH_REF__/,$Answ,2);
@@ -1427,25 +1625,25 @@ sub get_OR_problem_data {
$key =~ s/^$part\.//;
if (ref($value) eq 'ARRAY') {
if ($key eq 'options') {
- $Partdata{$part}->{'Options'}=$value;
+ $Partdata{$part}->{'_Options'}=$value;
} elsif ($key eq 'concepts') {
- $Partdata{$part}->{'Concepts'}=$value;
+ $Partdata{$part}->{'_Concepts'}=$value;
} elsif ($key =~ /^concept\.(.*)$/) {
my $concept = $1;
foreach my $foil (@$value) {
- $Partdata{$part}->{'Foils'}->{$foil}->{'Concept'}=
+ $Partdata{$part}->{'_Foils'}->{$foil}->{'_Concept'}=
$concept;
}
}
} else {
if ($key=~ /^foil\.text\.(.*)$/) {
my $foil = $1;
- $Partdata{$part}->{'Foils'}->{$foil}->{'name'}=$foil;
+ $Partdata{$part}->{'_Foils'}->{$foil}->{'name'}=$foil;
$value =~ s/(\s*$|^\s*)//g;
- $Partdata{$part}->{'Foils'}->{$foil}->{'text'}=$value;
+ $Partdata{$part}->{'_Foils'}->{$foil}->{'text'}=$value;
} elsif ($key =~ /^foil\.value\.(.*)$/) {
my $foil = $1;
- $Partdata{$part}->{'Foils'}->{$foil}->{'value'}=$value;
+ $Partdata{$part}->{'_Foils'}->{$foil}->{'value'}=$value;
}
}
}
@@ -1453,50 +1651,14 @@ sub get_OR_problem_data {
return %Partdata;
}
-#########################################################
-#########################################################
-##
-## Misc Radio Response functions
-##
-#########################################################
-#########################################################
-sub get_Radio_problem_student_data {
- my ($row) = @_;
-}
-
-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;
- %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;
-}
-
1;
__END__
+
+#####
+# partdata{part}->{_Foils}->{foilid}->{'name'} = $
+# ->{'text'} = $
+# ->{'value'} = $
+# ->{'_Concept'} = $
+# partdata{part}->{_Options} = @
+# partdata{part}->{_Concepts} = @
| |