Diff for /loncom/interface/statistics/lonstudentassessment.pm between versions 1.21 and 1.28

version 1.21, 2002/12/16 23:35:46 version 1.28, 2003/02/21 18:41:56
Line 25 Line 25
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 # (Navigate problems for statistical reports  # (Navigate problems for statistical reports
 # YEAR=2001  
 # 5/5,7/9,7/25/1,8/11,9/13,9/26,10/5,10/9,10/22,10/26 Behrouz Minaei  
 # 11/1,11/4,11/16,12/14,12/16,12/18,12/20,12/31 Behrouz Minaei  
 # YEAR=2002  
 # 1/22,2/1,2/6,2/25,3/2,3/6,3/17,3/21,3/22,3/26,4/7,5/6 Behrouz Minaei  
 # 5/12,5/14,5/15,5/19,5/26,7/16  Behrouz Minaei  
 #  #
 ###  #######################################################
   #######################################################
   
   =pod
   
   =head1 NAME
   
   lonstudentassessment
   
   =head1 SYNOPSIS
   
   Presents assessment data about a student or a group of students.
   
   =head1 Subroutines
   
   =over 4 
   
   =cut
   
   #######################################################
   #######################################################
   
 package Apache::lonstudentassessment;  package Apache::lonstudentassessment;
   
 use strict;  use strict;
   use Apache::lonstatistics;
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
 use Apache::loncoursedata;  use Apache::loncoursedata;
   use Apache::lonnet; # for logging porpoises
 use GDBM_File;  use GDBM_File;
   
 #my $jr;  #######################################################
   #######################################################
   
   =pod
   
   =item &BuildStudentAssessmentPage()
   
   Inputs: 
   
   =over 4
   
   =item $cacheDB The name of the cache file used to store student data
   
   =item $students Array ref containing the name(s) of the students 
   selected for display
   
   =item $courseID The ID of the course
   
   =item $formName The name of the html form - 'Statistics'
   
   =item $headings Array ref of headings to show
   
   =item $spacing A string of spaces
   
   =item $studentInformation Array ref of possible headings for student info
   ('fullname','section',...)
   
   =item $r Apache Request
   
   =item $c Apache Connection 
   
   =back
   
   =cut
   
   #######################################################
   #######################################################
 sub BuildStudentAssessmentPage {  sub BuildStudentAssessmentPage {
     my ($cacheDB,$students,$courseID,$formName,$headings,$spacing,      my ($cacheDB,$students,$courseID,$formName,$headings,$spacing,
         $studentInformation,$r,$c)=@_;          $studentInformation,$r,$c)=@_;
 #    $jr = $r;  
     my %cache;      my %cache;
     unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {      unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
         $r->print('<html><body>Unable to tie database.</body></html>');          $r->print('<html><body>Unable to tie database.</body></html>');
Line 101  sub BuildStudentAssessmentPage { Line 151  sub BuildStudentAssessmentPage {
     if($c->aborted()) {  return $Str; }      if($c->aborted()) {  return $Str; }
   
     my $selected=0;      my $selected=0;
       my $Count = 0;
     $r->print('<pre>'."\n");      $r->print('<pre>'."\n");
     foreach (@$students) {      foreach (@$students) {
         if($c->aborted()) { return $Str; }          if($c->aborted()) { return $Str; }
Line 132  sub BuildStudentAssessmentPage { Line 183  sub BuildStudentAssessmentPage {
                     push(@before, $_);                      push(@before, $_);
                 }                  }
             }              }
             my $displayString = 'DISPLAYDATA'.$spacing;              $Count++;
             $r->print(&Apache::lonhtmlcommon::FormatStudentInformation(      my $out = '';
       $out .= sprintf("%3d) ", $Count);
               if($Count % 2) {
                   $out .= '<bgcolor="#FFFFFF">';
               } else {
                   $out .= '<bgcolor="#505050">';
               }
       my $displayString = $out.'DISPLAYDATA'.$spacing;
       $r->print(&Apache::lonhtmlcommon::FormatStudentInformation(
                                                          \%cache, $_,                                                           \%cache, $_,
                                                          \@before,                                                           \@before,
                                                          $displayString,                                                           $displayString,
Line 164  sub BuildStudentAssessmentPage { Line 223  sub BuildStudentAssessmentPage {
             untie(%cache);              untie(%cache);
         }          }
     }      }
       $r->print('</pre>'."\n"); 
     if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {  
         $r->print(&StudentAverageTotal(\%cache, $students, $sequenceKeys));  
         untie(%cache);  
     }  
     $r->print('</pre>'."\n");  
     if($selected == 0) {      if($selected == 0) {
  $Str .= '<h3><font color=blue>WARNING: ';   $Str .= '<h3><font color=blue>WARNING: ';
         $Str .= 'Please select a student</font></h3>';          $Str .= 'No Students enrolled OR Please select a student</font></h3>';
         $r->print($Str);          $r->print($Str);
       } else {
    if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
       $r->print(&StudentAverageTotal(\%cache, $students, $sequenceKeys));
       untie(%cache);
    }
     }      }
   
     return;      return;
 }  }
   #######################################################
   #######################################################
   
   =pod
   
   =item &CreateInterface()
   
   Called by &BuildStudentAssessmentPage to create the top part of the
   page which displays the chart.
   
   Inputs:
   
 #---- Student Assessment Web Page --------------------------------------------  =over 4
   
   =item $cache The ubiquitous cache
   
   =item $selectedName The name of the currently selected student, or
   'All Students' or 'No Student Selected'.
   
   =item $students Array ref containing the name(s) of the students selected
   for display.
   
   =item $formName The name of the HTML form to use, 'Statistics'
   
   =item $doNotShow Array ref containing the names of columns to not show
   
   =back
   
   Returns:  A string containing the HTML for the headers and top table for 
   the chart page.
   
   =cut
   
   #######################################################
   #######################################################
 sub CreateInterface {  sub CreateInterface {
     my($cache,$selectedName,$students,$formName,$doNotShow)=@_;      my($cache,$selectedName,$students,$formName,$doNotShow)=@_;
   
Line 233  sub CreateInterface { Line 320  sub CreateInterface {
   
     return $Str;      return $Str;
 }  }
   #######################################################
   #######################################################
   
   =pod
   
   =item &CreateTableHeadings()
   
   Create HTML for the columns of student data to show.
   Called by &BuildStudentAssessmentPage().  Calls
   &Apache::lonhtmlcommon::CreateHeadings().
   
   Inputs:
   
   =over 4
   
   =item $cache The ubiquitous cache
   
   =item $spacing A string of spaces
   
   =item $infoKeys Array ref to names of keys to display from the cache 
   which describe students
   
   =item $infoHeadings Array ref to headings of columns for student info
   
   =item $sequenceKeys Array ref of names of keys to use to retrieve sequence
   data from the cache
   
   =item $sequenceHeadings Array ref of names of sequences used for output.
   
   =back
   
   Returns: A string containing the HTML of the table headings.
   
   =cut
   
   #######################################################
   #######################################################
 sub CreateTableHeadings {  sub CreateTableHeadings {
     my($cache,$spacing,$infoKeys,$infoHeadings,$sequenceKeys,      my($cache,$spacing,$infoKeys,$infoHeadings,$sequenceKeys,
        $sequenceHeadings)=@_;         $sequenceHeadings)=@_;
   
   #    my $Str = '&nbsp&nbsp&nbsp&nbsp&nbsp';
     my $Str = '';      my $Str = '';
     $Str .= '<table border="0" cellpadding="0" cellspacing="0">'."\n";      $Str .= '<table border="0" cellpadding="0" cellspacing="0">'."\n";
   
     $Str .= '<tr>'."\n";      $Str .= '<tr>'."\n";
       $Str .= '<td><pre>     </pre></td>'."\n";
     $Str .= &CreateColumnSelectors($infoHeadings, $sequenceHeadings,      $Str .= &CreateColumnSelectors($infoHeadings, $sequenceHeadings,
                                    $sequenceKeys);                                     $sequenceKeys);
     $Str .= '<td></td></tr>'."\n";      $Str .= '<td></td></tr>'."\n";
   
     $Str .= '<tr>'."\n";      $Str .= '<tr>'."\n";
     my $displayString = '<td align="left"><pre><a href="/adm/statistics?';      my $displayString = '';
       $displayString .= '<td><pre>     </pre></td>'."\n";
       $displayString .= '<td align="left"><pre><a href="/adm/statistics?';
     $displayString .= 'sort=LINKDATA">DISPLAYDATA</a>FORMATTING';      $displayString .= 'sort=LINKDATA">DISPLAYDATA</a>FORMATTING';
     $displayString .= $spacing.'</pre></td>'."\n";      $displayString .= $spacing.'</pre></td>'."\n";
     $Str .= &Apache::lonhtmlcommon::CreateHeadings($cache,      $Str .= &Apache::lonhtmlcommon::CreateHeadings($cache,
Line 270  sub CreateTableHeadings { Line 396  sub CreateTableHeadings {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &FormatStudentData()  =item &StudentReport()
   
 First, FormatStudentInformation is called and prefixes the course information.  This is the workhorse subroutine - it handles formatting and display of a
 This function produces a formatted string of the student\'s course information.  students performance data.  It processes one row of the chart.
 Each column of data represents all the problems for a given sequence.  For  
 valid grade data, a link is created for that problem to a submission record  Input: 
 for that problem.  
   
 =over 4  =over 4
   
 Input: $name, $studentInformation, $ChartDB  =item $cache The ubiquitous cache
   
   =item $name The name and domain of the current student in name:domain format
   
 $name: The name and domain of the current student in name:domain format  =item $spacing A string containing spaces.
   
 $studentInformation: A pointer to an array holding the names used to   =item $showSequences Array ref containing the sequences to display
 remove data from the hash.  They represent   
 the name of the data to be removed.  
   
 $ChartDB: The name of the cached data database which will be tied to that   =back
 database.  
   
 Output: $Str  Output: $Str
   
 $Str: Formatted string that is an entire row of the chart.  It is a  $Str: Formatted string that is an entire row of the chart.  It is a
 concatenation of student information and student course information.  concatenation of student information and student course information.
   
 =back  
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub StudentReport {  sub StudentReport {
     my ($cache,$name,$spacing,$showSequences)=@_;      my ($cache,$name,$spacing,$showSequences)=@_;
     my ($username,$domain)=split(':',$name);      my ($username,$domain)=split(':',$name);
Line 397  sub StudentReport { Line 524  sub StudentReport {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   #######################################################
   #######################################################
 sub StudentAverageTotal {  sub StudentAverageTotal {
     my ($cache, $students, $sequenceKeys)=@_;      my ($cache, $students, $sequenceKeys)=@_;
     my $Str = "\nAverageTotal\n";      my $Str = "\n<b>Summary Tables:</b>\n";
     my %Correct = ();      my %Correct = ();
     my $ProblemsSolved = 0;      my $ProblemsSolved = 0;
     my $TotalProblems = 0;      my $TotalProblems = 0;
Line 409  sub StudentAverageTotal { Line 540  sub StudentAverageTotal {
     foreach my $name (@$students) {      foreach my $name (@$students) {
         $StudentCount++;          $StudentCount++;
         foreach my $sequence (@$sequenceKeys) {          foreach my $sequence (@$sequenceKeys) {
             $Correct{$cache->{$sequence.':title'}} +=              $Correct{$sequence} +=
         $cache->{$name.':'.$sequence.':problemsCorrect'};         $cache->{$name.':'.$sequence.':problemsCorrect'};
         }          }
  $ProblemsSolved += $cache->{$name.':problemsSolved'};   $ProblemsSolved += $cache->{$name.':problemsSolved'};
         $TotalProblems += $cache->{$name.':totalProblems'};          $TotalProblems += $cache->{$name.':totalProblems'};
     }      }
     $ProblemsSolved /= $StudentCount;      if ($StudentCount) { 
     $TotalProblems /= $StudentCount;          $ProblemsSolved = sprintf( "%.2f", 
     $Str .= "AvgSlvd:$ProblemsSolved  AvgTotal: $TotalProblems\n";                               $ProblemsSolved/$StudentCount);
               $TotalProblems /= $StudentCount;
     foreach (%Correct) {      } else {
         $Str .= "$_  : $Correct{$_}\n";          $ProblemsSolved = 0;
           $TotalProblems  = 0;
     }      }
   
       $Str .= '<table border=2 cellspacing="1">'."\n";
       $Str .= '<tr><td><b>Students Count</b></td><td><b>'.
               $StudentCount.'</b></td></tr>'."\n";
       $Str .= '<tr><td><b>Total Problems</b></td><td><b>'.
               $TotalProblems.'</b></td></tr>'."\n";
       $Str .= '<tr><td><b>Average Correct</b></td><td><b>'.
               $ProblemsSolved.'</b></td></tr>'."\n";
       $Str .= '</table>'."\n";
   
       $Str .= '<table border=2 cellspacing="1">'."\n";
       $Str .= '<tr><th>Title</th><th>Total Problems</th>'.
               '<th>Average Correct</th></tr>'."\n";
       foreach my $S(@$sequenceKeys) {
           my $title=$cache->{$S.':title'};
    #$Str .= $cache->{$S.':problems'};
    #my @problems=split(':', $cache->{$S.':problems'});
    #my $pCount=scalar @problems;
    my $pCount=MaxSeqPr($cache,@$students[0],$S);
           my $crr;
    if ($StudentCount) {
               $crr=sprintf( "%.2f", $Correct{$S}/$StudentCount );
           } else {
               $crr="0.00";
           }
           $Str .= '<tr><td>'.$title.
                   '</td><td align=center>'.$pCount.
                   '</td><td align=center>'.$crr.
                   '</td></tr>'."\n";
       }
   
       $Str .= '</table>'."\n";
   
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   #######################################################
   #######################################################
   sub MaxSeqPr {
       my ($cache, $name, $sequence)=@_;
       my $prCount=0;
       foreach my $problemID (split(':', $cache->{$sequence.':problems'})) {
           my $problem = $cache->{$problemID.':problem'};
           foreach(split(/\:/,$cache->{$sequence.':'.$problemID.':parts'})) {
               if($cache->{$name.':'.$problemID.':NoVersion'} eq 'true' ||
                  $cache->{$name.':'.$problemID.':'.$_.':code'} eq ' ' ||
                  $cache->{$name.':'.$problemID.':'.$_.':code'} eq '') {
                    $prCount++;
                    next;
               }
               $prCount++;
           }
       }
       return $prCount;
   }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
Line 438  problems. Line 626  problems.
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub CreateLegend {  sub CreateLegend {
     my $Str = "<p><pre>".      my $Str = "<p><pre>".
               "   1  correct by student in 1 try\n".                "   1  correct by student in 1 try\n".
Line 453  sub CreateLegend { Line 643  sub CreateLegend {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &CreateColumnSelectionBox()  =item &CreateColumnSelectionBox()
Line 466  to the interface table. Line 659  to the interface table.
 =over 4  =over 4
 Input: $CacheData, $headings  Input: $CacheData, $headings
   
   
 $CacheData: A pointer to a hash tied to the cached data  $CacheData: A pointer to a hash tied to the cached data
   
 $headings:  An array of the names of the columns for the student information.  $headings:  An array of the names of the columns for the student information.
Line 482  which has a size of four. Line 674  which has a size of four.
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub CreateColumnSelectionBox {  sub CreateColumnSelectionBox {
     my ($doNotShow)=@_;      my ($doNotShow)=@_;
   
Line 501  sub CreateColumnSelectionBox { Line 695  sub CreateColumnSelectionBox {
     return $notThere;      return $notThere;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &CreateColumnSelectors()  =item &CreateColumnSelectors()
Line 527  for consistency of location over the col Line 724  for consistency of location over the col
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub CreateColumnSelectors {  sub CreateColumnSelectors {
     my ($infoHeadings, $sequenceHeadings, $sequenceKeys)=@_;      my ($infoHeadings, $sequenceHeadings, $sequenceKeys)=@_;
   
Line 548  sub CreateColumnSelectors { Line 747  sub CreateColumnSelectors {
     return $present;      return $present;
 }  }
   
 #---- END Student Assessment Web Page ----------------------------------------  #######################################################
   #######################################################
   
   =pod
   
   =back
   
   =head1 HELPER FUNCTIONS
   
   =over 4
   
 #---- Student Assessment Worker Functions ------------------------------------  =cut 
   
   #######################################################
   #######################################################
 sub FindSelectedStudent {  sub FindSelectedStudent {
     my($cache, $selectedName, $students)=@_;      my($cache, $selectedName, $students)=@_;
   
Line 589  sub FindSelectedStudent { Line 799  sub FindSelectedStudent {
   
     return 'No Student Selected';      return 'No Student Selected';
 }  }
   #######################################################
   #######################################################
   
 =pod  =pod
   
Line 605  $cache: A pointer to the hash tied to th Line 817  $cache: A pointer to the hash tied to th
 $test: The form name of the column (heading.$headingIndex) or   $test: The form name of the column (heading.$headingIndex) or 
 (sequence.$sequenceIndex)  (sequence.$sequenceIndex)
   
 Output: 0 (false), 1 (true)  
   
 =back  =back
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub ShouldShowColumns {  sub ShouldShowColumns {
     my ($cache,$headings,$cacheKey)=@_;      my ($cache,$headings,$cacheKey)=@_;
   
Line 655  sub ShouldShowColumns { Line 867  sub ShouldShowColumns {
     return (\@infoHeadings, \@infoKeys, \@sequenceHeadings,      return (\@infoHeadings, \@infoKeys, \@sequenceHeadings,
             \@sequenceKeys, \%doNotShow);              \@sequenceKeys, \%doNotShow);
 }  }
   1;
   
 #---- END Student Assessment Worker Functions --------------------------------  #######################################################
   #######################################################
   
   =pod 
   
   =back
   
   =cut
   
   #######################################################
   #######################################################
   
 1;  
 __END__  __END__

Removed from v.1.21  
changed lines
  Added in v.1.28


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>