Diff for /loncom/interface/statistics/lonstudentassessment.pm between versions 1.23 and 1.29

version 1.23, 2002/12/24 21:00:21 version 1.29, 2003/02/25 20:47:47
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # (Publication Handler  
 #  #
 # $Id$  # $Id$
 #  #
Line 25 Line 24
 # 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,12/24  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 150  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 182  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 222  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:
   
   =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'
   
 #---- Student Assessment Web Page --------------------------------------------  =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 210  sub CreateInterface { Line 296  sub CreateInterface {
     $Str .= '<tr><td align="center">'."\n";      $Str .= '<tr><td align="center">'."\n";
     my @sections = split(':',$cache->{'sectionList'});      my @sections = split(':',$cache->{'sectionList'});
     my @selectedSections = split(':',$cache->{'sectionsSelected'});      my @selectedSections = split(':',$cache->{'sectionsSelected'});
     $Str .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections,      $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
                                                           \@selectedSections,  
                                                           'Statistics');  
     $Str .= '</td><td align="center">';      $Str .= '</td><td align="center">';
     $Str .= &CreateColumnSelectionBox($doNotShow);      $Str .= &CreateColumnSelectionBox($doNotShow);
     $Str .= '</td><td>'."\n";      $Str .= '</td><td>'."\n";
Line 233  sub CreateInterface { Line 317  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 393  sub CreateTableHeadings {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &FormatStudentData()  =item &StudentReport()
   
   This is the workhorse subroutine - it handles formatting and display of a
   students performance data.  It processes one row of the chart.
   
 First, FormatStudentInformation is called and prefixes the course information.  Input: 
 This function produces a formatted string of the student\'s course information.  
 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  
 for that problem.  
   
 =over 4  =over 4
   
 Input: $name, $studentInformation, $ChartDB  =item $cache The ubiquitous cache
   
 $name: The name and domain of the current student in name:domain format  =item $name The name and domain of the current student in name:domain format
   
 $studentInformation: A pointer to an array holding the names used to   =item $spacing A string containing spaces.
 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   =item $showSequences Array ref containing the sequences to display
 database.  
   =back
   
 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 521  sub StudentReport {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   #######################################################
   #######################################################
 sub StudentAverageTotal {  sub StudentAverageTotal {
     my ($cache, $students, $sequenceKeys)=@_;      my ($cache, $students, $sequenceKeys)=@_;
     my $Str = "\n<b>Summary Tables:</b>\n";      my $Str = "\n<b>Summary Tables:</b>\n";
Line 415  sub StudentAverageTotal { Line 543  sub StudentAverageTotal {
  $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", 
                                    $ProblemsSolved/$StudentCount);
     $Str .= '<table border=2 cellspacing="5">'."\n";          $TotalProblems /= $StudentCount;
       } else {
           $ProblemsSolved = 0;
           $TotalProblems  = 0;
       }
   
       $Str .= '<table border=2 cellspacing="1">'."\n";
     $Str .= '<tr><td><b>Students Count</b></td><td><b>'.      $Str .= '<tr><td><b>Students Count</b></td><td><b>'.
             $StudentCount.'</b></td></tr>'."\n";              $StudentCount.'</b></td></tr>'."\n";
     $Str .= '<tr><td><b>Total Problems</b></td><td><b>'.      $Str .= '<tr><td><b>Total Problems</b></td><td><b>'.
Line 427  sub StudentAverageTotal { Line 561  sub StudentAverageTotal {
             $ProblemsSolved.'</b></td></tr>'."\n";              $ProblemsSolved.'</b></td></tr>'."\n";
     $Str .= '</table>'."\n";      $Str .= '</table>'."\n";
   
     $Str .= '<table border=2 cellspacing="5">'."\n";      $Str .= '<table border=2 cellspacing="1">'."\n";
     $Str .= '<tr><th>Title</th><th>Total Problems</th>'.      $Str .= '<tr><th>Title</th><th>Total Problems</th>'.
             '<th>Average Correct</th></tr>'."\n";              '<th>Average Correct</th></tr>'."\n";
     foreach my $S(@$sequenceKeys) {      foreach my $S(@$sequenceKeys) {
         my $title=$cache->{$S.':title'};          my $title=$cache->{$S.':title'};
  #$Str .= $cache->{$S.':problems'};   #$Str .= $cache->{$S.':problems'};
  #my @problems=split(':', $cache->{$S.':problems'});    #my @problems=split(':', $cache->{$S.':problems'});
  #my $pCount=scalar @problems;   #my $pCount=scalar @problems;
  my $pCount=MaxSeqPr($cache,@$students[0],$S);   my $pCount=MaxSeqPr($cache,@$students[0],$S);
  my $crr=sprintf( "%.2f", $Correct{$S}/$StudentCount );          my $crr;
    if ($StudentCount) {
               $crr=sprintf( "%.2f", $Correct{$S}/$StudentCount );
           } else {
               $crr="0.00";
           }
         $Str .= '<tr><td>'.$title.          $Str .= '<tr><td>'.$title.
                 '</td><td align=center>'.$pCount.                  '</td><td align=center>'.$pCount.
                 '</td><td align=center>'.$crr.                  '</td><td align=center>'.$crr.
Line 448  sub StudentAverageTotal { Line 587  sub StudentAverageTotal {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   #######################################################
   #######################################################
 sub MaxSeqPr {  sub MaxSeqPr {
     my ($cache, $name, $sequence)=@_;      my ($cache, $name, $sequence)=@_;
     my $prCount=0;      my $prCount=0;
Line 468  sub MaxSeqPr { Line 610  sub MaxSeqPr {
     return $prCount;      return $prCount;
 }  }
   
   #######################################################
   #######################################################
   
   
 =pod  =pod
   
Line 482  problems. Line 623  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 497  sub CreateLegend { Line 640  sub CreateLegend {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &CreateColumnSelectionBox()  =item &CreateColumnSelectionBox()
Line 510  to the interface table. Line 656  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 526  which has a size of four. Line 671  which has a size of four.
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub CreateColumnSelectionBox {  sub CreateColumnSelectionBox {
     my ($doNotShow)=@_;      my ($doNotShow)=@_;
   
Line 545  sub CreateColumnSelectionBox { Line 692  sub CreateColumnSelectionBox {
     return $notThere;      return $notThere;
 }  }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
 =item &CreateColumnSelectors()  =item &CreateColumnSelectors()
Line 571  for consistency of location over the col Line 721  for consistency of location over the col
   
 =cut  =cut
   
   #######################################################
   #######################################################
 sub CreateColumnSelectors {  sub CreateColumnSelectors {
     my ($infoHeadings, $sequenceHeadings, $sequenceKeys)=@_;      my ($infoHeadings, $sequenceHeadings, $sequenceKeys)=@_;
   
Line 592  sub CreateColumnSelectors { Line 744  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 633  sub FindSelectedStudent { Line 796  sub FindSelectedStudent {
   
     return 'No Student Selected';      return 'No Student Selected';
 }  }
   #######################################################
   #######################################################
   
 =pod  =pod
   
Line 649  $cache: A pointer to the hash tied to th Line 814  $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 699  sub ShouldShowColumns { Line 864  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.23  
changed lines
  Added in v.1.29


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