[LON-CAPA-cvs] cvs: loncom /interface/statistics lonproblemanalysis.pm

matthew lon-capa-cvs@mail.lon-capa.org
Tue, 11 Nov 2003 22:07:46 -0000


This is a MIME encoded message

--matthew1068588466
Content-Type: text/plain

matthew		Tue Nov 11 17:07:46 2003 EDT

  Modified files:              
    /loncom/interface/statistics	lonproblemanalysis.pm 
  Log:
  Old changes that need to be committed.  Initial stab at radioresponse analysis
  is 'POD'ed out.  It works.  Trust me.
  
  
--matthew1068588466
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20031111170746.txt"

Index: loncom/interface/statistics/lonproblemanalysis.pm
diff -u loncom/interface/statistics/lonproblemanalysis.pm:1.47 loncom/interface/statistics/lonproblemanalysis.pm:1.48
--- loncom/interface/statistics/lonproblemanalysis.pm:1.47	Thu Oct 30 11:24:36 2003
+++ loncom/interface/statistics/lonproblemanalysis.pm	Tue Nov 11 17:07:46 2003
@@ -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.48 2003/11/11 22:07:46 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,7 @@
 
 sub BuildProblemAnalysisPage {
     my ($r,$c)=@_;
+    #
     $r->print('<h2>'.&mt('Option Response Problem Analysis').'</h2>');
     $r->print(&CreateInterface());
     #
@@ -120,16 +120,13 @@
             $r->print('<h3>'.$resource->{'src'}.'</h3>');
             $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('<h2>This analysis is not supported</h2>');
-                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('<h2>This analysis is not supported</h2>');
@@ -145,6 +142,9 @@
     }
 }
 
+=pod
+
+Removed code:
 
 #########################################################
 #########################################################
@@ -154,19 +154,186 @@
 #########################################################
 #########################################################
 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('<h2>There is no submission data for this resource</h2>');
+        ($Students,$resource->{'symb'},$respid);
+    if (! defined($PerformanceData) || 
+        ref($PerformanceData) ne 'ARRAY' ) {
+        $analysis_html = '<h2>'.
+            &mt('There is no submission data for this resource').
+            '</h2>';
+        $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 .= '<h2>'.
+           &mt('The analysis you have selected is not supported at this time').
+           '</h2>';
+    }
+    $r->print($analysis_html);
+}
+
+
+sub RR_Excel_output   { 
+    my ($r,$PerformanceData,$ProblemData) = @_;
+    return '<h1>No!</h1>';
+}
+
+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 = '<h3>'.
+            &mt('Not enough data for concept analysis.  '.
+                'Performing Foil Analysis').
+            '</h3>'.$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 +427,7 @@
                      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 +461,7 @@
         }
         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 +690,7 @@
         }
         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 +906,7 @@
         @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 +954,7 @@
     ##
     ## 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 +1211,12 @@
 
 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 +1327,7 @@
     my $table = "<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,
               '<tr>'.
               '<td bgcolor="'.$plotcolors->[$optionindex++].'">'.
@@ -1302,8 +1469,11 @@
                 for (my $i=0;$i<scalar(@{$partdata->{'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 ';
@@ -1311,7 +1481,8 @@
                         $seq_str .= '<tr><td>'.
   '<input type="radio" name="problemchoice" value="'.$value.'" '.$checked.'/>'.
   '</td><td>'.
-  '<a href="'.$res->{'src'}.'">'.$resptype.' '.$res->{'title'}.'</a> ';
+  '<a href="'.$res->{'src'}.'">'.$res->{'title'}.'</a> ';
+#  '<a href="'.$res->{'src'}.'">'.$resptype.' '.$res->{'title'}.'</a> ';
                         if ($partdata->{'option'} > 1) {
                             $seq_str .= &mt('response').' '.$respid;
                         }
@@ -1379,6 +1550,16 @@
     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 +1595,7 @@
 ## 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 +1608,25 @@
             $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 +1634,14 @@
     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} = @

--matthew1068588466--