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

matthew lon-capa-cvs@mail.lon-capa.org
Mon, 13 Oct 2003 19:17:42 -0000


This is a MIME encoded message

--matthew1066072662
Content-Type: text/plain

matthew		Mon Oct 13 15:17:42 2003 EDT

  Modified files:              
    /loncom/interface/statistics	lonproblemanalysis.pm 
  Log:
  First attempt at 'time' based analysis - actually, just taking a fixed
  percent of the responses and graphing them.
  Added 'Update Student Data' button because, when viewing a 2100 student
  course it takes a while to even check the status of the students data.
  The data is checked the first time a problem is analyzed but only on
  request after that.
  Added &build_foil_index as every analysis will have to have an index
  of the foils.
  Some comments and code reorganization.
  
  
--matthew1066072662
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20031013151742.txt"

Index: loncom/interface/statistics/lonproblemanalysis.pm
diff -u loncom/interface/statistics/lonproblemanalysis.pm:1.32 loncom/interface/statistics/lonproblemanalysis.pm:1.33
--- loncom/interface/statistics/lonproblemanalysis.pm:1.32	Fri Oct 10 17:49:20 2003
+++ loncom/interface/statistics/lonproblemanalysis.pm	Mon Oct 13 15:17:42 2003
@@ -1,6 +1,7 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonproblemanalysis.pm,v 1.32 2003/10/10 21:49:20 matthew Exp $
+
+# $Id: lonproblemanalysis.pm,v 1.33 2003/10/13 19:17:42 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -42,13 +43,27 @@
     #
     my @Students = @Apache::lonstatistics::Students;
     #
-    if (exists($ENV{'form.problemchoice'}) && !exists($ENV{'SelectAnother'})) {
+    if (exists($ENV{'form.updatecaches'}) ||
+        (exists($ENV{'form.firstanalysis'}) &&
+         $ENV{'form.firstanalysis'} ne 'no')) {
+        &Apache::lonstatistics::Gather_Full_Student_Data($r);
+    }
+    if (! exists($ENV{'form.firstanalysis'})) {
+        $r->print('<input type="hidden" name="firstanalysis" value="yes" />');
+    } else {
+        $r->print('<input type="hidden" name="firstanalysis" value="no" />');
+    }
+    if (exists($ENV{'form.problemchoice'}) && 
+        ! exists($ENV{'form.SelectAnother'})) {
         $r->print('<input type="submit" name="ProblemAnalysis" value="'.
                   &mt('Analyze Problem Again').'" />');
         $r->print('&nbsp;'x5);
         $r->print('<input type="submit" name="ClearCache" value="'.
                   &mt('Clear Caches').'" />');
         $r->print('&nbsp;'x5);
+        $r->print('<input type="submit" name="updatecaches" value="'.
+                  &mt('Update Student Data').'" />');
+        $r->print('&nbsp;'x5);
         $r->print('<input type="hidden" name="problemchoice" value="'.
                   $ENV{'form.problemchoice'}.'" />');
         $r->print('<input type="submit" name="SelectAnother" value="'.
@@ -56,7 +71,6 @@
         $r->print('&nbsp;'x5);
         #
         $r->print('<hr />');
-        &Apache::lonstatistics::Gather_Full_Student_Data($r);
         #
         my ($symb,$part,$resid) = &get_problem_symb(
                      &Apache::lonnet::unescape($ENV{'form.problemchoice'})
@@ -87,13 +101,13 @@
             if (defined($PerformanceData) && 
                 ref($PerformanceData) eq 'ARRAY') {
                 if ($ENV{'form.AnalyzeBy'} eq 'Tries') {
-                    my $analysis_html = &DoTriesAnalysis($PerformanceData,
+                    my $analysis_html = &tries_analysis($PerformanceData,
+                                                         $ORdata);
+                    $r->print($analysis_html);
+                } elsif ($ENV{'form.AnalyzeBy'} eq 'Time') {
+                    my $analysis_html = &time_analysis($PerformanceData,
                                                          $ORdata);
                 $r->print($analysis_html);
-#                } elsif ($ENV{'form.AnalyzeBy'} eq 'Time') {
-#                    my $analysis_html = &DoTimeAnalysis($PerformanceData,
-#                                                         $ORdata);
-#                $r->print($analysis_html);
                 } else {
                     $r->print('<h2>'.
                               &mt('The analysis you have selected is '.
@@ -119,13 +133,16 @@
 }
 
 
-sub DoTriesAnalysis {
-    my ($PerformanceData,$ORdata) = @_;
-    my $mintries = 1;
-    my $maxtries = $ENV{'form.NumPlots'};
-    my %ResponseData = &analyze_option_data_by_tries($PerformanceData,
-                                                 $mintries,$maxtries);
-    my @Foils = sort(keys(%ResponseData));
+#########################################################
+#########################################################
+##
+##      Misc interface routines use by analysis code
+##
+#########################################################
+#########################################################
+sub build_foil_index {
+    my ($ORdata) = @_;
+    my @Foils = sort(keys(%{$ORdata->{'Foiltext'}}));
     my %Row_Label;
     foreach my $foilid (@Foils) {
         my $value = $ORdata->{'Foiltext'}->{$foilid};
@@ -144,6 +161,23 @@
         $index++;
     }
     $table .= "</table>\n";
+    return ($table,@Foils);
+}
+
+#########################################################
+#########################################################
+##
+##         Tries Analysis
+##
+#########################################################
+#########################################################
+sub tries_analysis {
+    my ($PerformanceData,$ORdata) = @_;
+    my $mintries = 1;
+    my $maxtries = $ENV{'form.NumPlots'};
+    my %ResponseData = &analyze_option_data_by_tries($PerformanceData,
+                                                 $mintries,$maxtries);
+    my ($table,@Foils) = &build_foil_index($ORdata);
     #
     # Compute the data neccessary to make the plots
     my @PlotData;
@@ -263,12 +297,105 @@
     return %Trydata;
 }
 
-sub get_problem_symb {
-    my $problemstring = shift();
-    my ($symb,$partid,$resid) = ($problemstring=~ /^(.*):([^:]*):([^:]*)$/);
-    return ($symb,$partid,$resid);
+#########################################################
+#########################################################
+##
+##                 Time Analysis
+##
+#########################################################
+#########################################################
+sub time_analysis {
+    my ($PerformanceData,$ORdata) = @_;
+    my $num_plots = $ENV{'form.NumPlots'};
+    my ($table,@Foils) = &build_foil_index($ORdata);
+    my ($begin_index,$end_index);
+    my $num_data = scalar(@$PerformanceData)-1;
+    my $percent = sprintf('%2f',100/$num_plots);
+    for (my $i=0;$i<$num_plots;$i++) {
+        $begin_index = $i*int($num_data/$num_plots);
+        $end_index = ($i+1)*int($num_data/$num_plots);
+        my $lownum  = sprintf('%2.1f',$i*$percent);
+        $lownum =~ s/(\.0)$//;
+        my $highnum = sprintf('%2.1f',($i+1)*$percent);
+        $highnum =~ s/(\.0)$//;
+        my ($plothtml,$starttime,$endtime,$data) = 
+            &analyze_option_data_by_time($PerformanceData,
+                                         $begin_index,$end_index,
+            $lownum.'% to '.$highnum.'% of submissions',
+                                         @Foils);
+        $table.=$plothtml;
+    }
+    return $table;
 }
 
+sub analyze_option_data_by_time {
+    my ($PerformanceData,$begin_index,$end_index,$description,@Foils) = @_;
+    my %TimeData;
+    #
+    # Get the start and end times for this segment of the plot
+    my $starttime = $PerformanceData->[$begin_index]->[2];
+    my $endtime   = $PerformanceData->[$end_index  ]->[2];
+    #
+    # Compute the number getting the foils correct or incorrects
+    for (my $i=$begin_index;$i<=$end_index;$i++) {
+        my $row = $PerformanceData->[$i];
+        next if (! defined($row));
+        my ($grading,$submission,$time,$tries) = @$row;
+        my @Foilgrades = split('&',$grading);
+        my @Foilsubs   = split('&',$submission);
+        foreach my $foilgrade (@Foilgrades) {
+            my ($foilid,$correct) = split('=',$foilgrade);
+            if ($correct) {
+                $TimeData{$foilid}->{'correct'}++;
+            } else {
+                $TimeData{$foilid}->{'incorrect'}++;
+            }
+        }
+    }
+    #
+    # Compute the total and percent correct
+    my @Plotdata1;
+    my @Plotdata2;
+    foreach my $foilid (@Foils) {
+        if (! exists($TimeData{$foilid}->{'correct'})) {
+            $TimeData{$foilid}->{'correct'} = 0;
+        }
+        if (! exists($TimeData{$foilid}->{'incorrect'})) {
+            $TimeData{$foilid}->{'incorrect'} = 0;
+        }
+        $TimeData{$foilid}->{'total'} = $TimeData{$foilid}->{'correct'} +
+                                $TimeData{$foilid}->{'incorrect'};
+        $TimeData{$foilid}->{'percent_corr'} = 100 *
+            $TimeData{$foilid}->{'correct'} / 
+            $TimeData{$foilid}->{'total'};
+        push (@Plotdata1,    $TimeData{$foilid}->{'percent_corr'});
+        push (@Plotdata2,100-$TimeData{$foilid}->{'percent_corr'});
+    }
+    #
+    # Create the plot
+    my $graphlink = &Apache::loncommon::DrawGraph
+        ($description,#'Time Interval Analysis',
+         'Foil Number',
+         'Percent Correct / Incorrect',
+         100,
+         \@Plotdata1,\@Plotdata2);
+    $graphlink .= "<br />\n".
+        "<b>Start Time</b>: ".localtime($starttime)."<br />\n".
+        "<b>End Time</b>: ".localtime($endtime)."<br />\n";
+    #
+    return ($graphlink,$starttime,$endtime,\%TimeData);
+}
+
+
+
+
+#########################################################
+#########################################################
+##
+##             Interface 
+##
+#########################################################
+#########################################################
 sub CreateInterface {
     ##
     ## Environment variable initialization
@@ -329,7 +456,7 @@
     if (! exists($ENV{'form.NumPlots'}) 
         || $ENV{'form.NumPlots'} < 1 
         || $ENV{'form.NumPlots'} > 20) {
-        $ENV{'form.NumPlots'} = 7;
+        $ENV{'form.NumPlots'} = 5;
     }
     foreach my $i (1,2,3,4,5,6,7,8,10,15,20) {
         $Str .= '<option value="'.$i.'" ';
@@ -387,6 +514,19 @@
     }
     $Str .= "</table>\n";
     return $Str;
+}
+
+#########################################################
+#########################################################
+##
+##              Misc functions
+##
+#########################################################
+#########################################################
+sub get_problem_symb {
+    my $problemstring = shift();
+    my ($symb,$partid,$resid) = ($problemstring=~ /^(.*):([^:]*):([^:]*)$/);
+    return ($symb,$partid,$resid);
 }
 
 sub get_resource_from_symb {

--matthew1066072662--