Diff for /loncom/interface/lonstatistics.pm between versions 1.60 and 1.61

version 1.60, 2003/02/25 20:47:47 version 1.61, 2003/02/28 20:50:33
Line 61  package Apache::lonstatistics; Line 61  package Apache::lonstatistics;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
   use vars qw(
       @FullClasslist 
       @Students
       @Sections 
       @SelectedSections
       %StudentData
       @StudentDataOrder
       @SelectedStudentData
       $top_map 
       @Sequences 
       @SelectedMaps
       @Assessments);
   
 use Apache::lonnet();  use Apache::lonnet();
 use Apache::lonhomework;  use Apache::lonhomework;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
 use Apache::lonproblemanalysis;  use Apache::lonproblemanalysis();
 use Apache::lonproblemstatistics;  use Apache::lonproblemstatistics();
 use Apache::lonstudentassessment;  use Apache::lonstudentassessment();
 use Apache::lonpercentage;  use Apache::lonpercentage;
 use GDBM_File;  use GDBM_File;
   
 use vars qw/@FullClasslist @Students @Sections @SelectedSections  
     $curr_student $prev_student $next_student   
     $top_map @Sequences @Assessments /;  
   
 #######################################################  #######################################################
 #######################################################  #######################################################
Line 104  use vars qw/@FullClasslist @Students @Se Line 114  use vars qw/@FullClasslist @Students @Se
 #  #
 # Classlist variables  # Classlist variables
 #  #
 my @FullClasslist;  
 my @Students;  
 my @Sections;  
 my @SelectedSections;  
 my $curr_student;  my $curr_student;
 my $prev_student;  my $prev_student;
 my $next_student;  my $next_student;
Line 131  undef the following package variables: Line 137  undef the following package variables:
   
 =item @SelectedSections  =item @SelectedSections
   
   =item %StudentData
   
   =item @StudentDataOrder
   
   =item @SelectedStudentData
   
 =item $curr_student  =item $curr_student
   
 =item $prev_student  =item $prev_student
Line 148  sub clear_classlist_variables { Line 160  sub clear_classlist_variables {
     undef(@Students);      undef(@Students);
     undef(@Sections);      undef(@Sections);
     undef(@SelectedSections);      undef(@SelectedSections);
       undef(%StudentData);
       undef(@SelectedStudentData);
     undef($curr_student);      undef($curr_student);
     undef($prev_student);      undef($prev_student);
     undef($next_student);      undef($next_student);
Line 173  the following package variables: Line 187  the following package variables:
   
 =item @SelectedSections  =item @SelectedSections
   
   =item %StudentData
   
   =item @SelectedStudentData
   
 =item $curr_student  =item $curr_student
   
 =item $prev_student  =item $prev_student
Line 201  sub PrepareClasslist { Line 219  sub PrepareClasslist {
                                                                   $cdom,$cnum);                                                                    $cdom,$cnum);
     if (exists($ENV{'form.Section'})) {      if (exists($ENV{'form.Section'})) {
         if (ref($ENV{'form.Section'})) {          if (ref($ENV{'form.Section'})) {
             @SelectedSections = @$ENV{'form.Section'};              @SelectedSections = @{$ENV{'form.Section'}};
             # Remove the empty sections          } elsif ($ENV{'form.Section'} !~ /^\s*$/) {
             for (my $i=0; $i<=$#SelectedSections; $i++) {              @SelectedSections = ($ENV{'form.Section'});
                 if ($SelectedSections[$i] =~ /^\s*$/) {          }
                     splice(@SelectedSections,$i,1);      }
                 }      @SelectedSections = ('all') if (! @SelectedSections);
             }      foreach (@SelectedSections) {
         } else {          if ($_ eq 'all') {
             if ($ENV{'form.Section'} !~ /^\s*$/) {              @SelectedSections = ('all');
                 @SelectedSections = ($ENV{'form.Section'});  
             }  
         }          }
     }      }
     @SelectedSections = ('any') if (! @SelectedSections);      #
       # Set up %StudentData
       @StudentDataOrder = qw/fullname username domain id section status/;
       foreach my $field (@StudentDataOrder) {
           $StudentData{$field}->{'title'} = $field;
           $StudentData{$field}->{'base_width'} = 
                                  scalar (my @Tmp = split(//,$field));
           $StudentData{$field}->{'width'} = 
                                  $StudentData{$field}->{'base_width'};
       }
   
     #      #
     # Process the classlist      # Process the classlist
     while (my ($student,$student_data) = each (%$classlist)) {      while (my ($student,$student_data) = each (%$classlist)) {
         my $studenthash = ();          my $studenthash = ();
         for (my $i=0; $i< scalar(@$field_names);$i++) {          for (my $i=0; $i< scalar(@$field_names);$i++) {
             $studenthash->{$field_names->[$i]}=$student_data->[$i];              my $field = $field_names->[$i];
               # Store the data
               $studenthash->{$field}=$student_data->[$i];
               # Keep track of the width of the fields
               next if (! exists($StudentData{$field}));
               my $length = scalar(my @Tmp1 = split(//,$student_data->[$i]));
               if ($StudentData{$field}->{'width'} < $length) {
                   $StudentData{$field}->{'width'} = $length; 
               }
         }          }
         push (@FullClasslist,$studenthash);          push (@FullClasslist,$studenthash);
         #          #
Line 234  sub PrepareClasslist { Line 268  sub PrepareClasslist {
         #          #
         # Only put in the list those students we are interested in          # Only put in the list those students we are interested in
         foreach my $sect (@SelectedSections) {          foreach my $sect (@SelectedSections) {
             if (($sect eq 'any') || ($section eq $sect)) {              if (($sect eq 'all') || ($section eq $sect)) {
                 push (@Students,$studenthash);                  push (@Students,$studenthash);
                 last;                  last;
             }              }
Line 243  sub PrepareClasslist { Line 277  sub PrepareClasslist {
     #      #
     # Put the consolidated section data in the right place      # Put the consolidated section data in the right place
     @Sections = sort {$a cmp $b} keys(%Sections);      @Sections = sort {$a cmp $b} keys(%Sections);
       unshift(@Sections,'all'); # Put 'all' at the front of the list
     #      #
     # Sort the Students      # Sort the Students
     my $sortby = 'fullname';      my $sortby = 'fullname';
     $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));      $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));
     my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||      my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||
                              $a->{'fullname'} cmp $b->{'fullname'} } @Students;                               $a->{'fullname'} cmp $b->{'fullname'} } @Students;
   
     @Students = @TmpStudents;      @Students = @TmpStudents;
     #       # 
     # Now deal with that current student thing....      # Now deal with that current student thing....
Line 274  sub PrepareClasslist { Line 308  sub PrepareClasslist {
             $next_student = $Students[$i+1];              $next_student = $Students[$i+1];
         }          }
     }      }
       #
       if (exists($ENV{'form.StudentData'})) {
           if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {
               @SelectedStudentData = @{$ENV{'form.StudentData'}};
           } else {
               @SelectedStudentData = ($ENV{'form.StudentData'});
           }
       } else {
           @SelectedStudentData = ('fullname');
       }
       foreach (@SelectedStudentData) {
           if ($_ eq 'all') {
               @SelectedStudentData = ('all');
               last;
           }
       }
       #
       return;
 }  }
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 #  
 # Course Sequences variables  =pod
 #  
 my $top_map;  =item &current_student()
 my @Sequences;  
 my @Assessments;  Returns a pointer to a hash containing data about the currently
   selected student.
   
   =cut
   
   #######################################################
   #######################################################
   sub current_student { 
       if (defined($curr_student)) {
           return $curr_student;
       } else {
           return 'All Students';
       }
   }
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &previous_student()
   
   Returns a pointer to a hash containing data about the student prior
   in the list of students.  Or something.  
   
   =cut
   
   #######################################################
   #######################################################
   sub previous_student { 
       if (defined($prev_student)) {
           return $prev_student;
       } else {
           return 'No Student Selected';
       }
   }
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &next_student()
   
   Returns a pointer to a hash containing data about the next student
   to be viewed.
   
   =cut
   
   #######################################################
   #######################################################
   sub next_student { 
       if (defined($next_student)) {
           return $next_student;
       } else {
           return 'No Student Selected';
       }
   }
   
 #######################################################  #######################################################
 #######################################################  #######################################################
Line 307  sub clear_sequence_variables { Line 416  sub clear_sequence_variables {
   
 =pod  =pod
   
   =item &SetSelectedMaps($elementname)
   
   Sets the @SelectedMaps array from $ENV{'form.'.$elementname};
   
   =cut
   
   #######################################################
   #######################################################
   sub SetSelectedMaps {
       my $elementname = shift;
       if (exists($ENV{'form.'.$elementname})) {
           if (ref($ENV{'form.'.$elementname})) {
               @SelectedMaps = @{$ENV{'form.'.$elementname}};
           } else {
               @SelectedMaps = ($ENV{'form.'.$elementname});
           }
       } else {
           @SelectedMaps = ('all');
       }
   }
   
   #######################################################
   #######################################################
   
   =pod
   
 =item &PrepareCourseData($r)  =item &PrepareCourseData($r)
   
 =cut  =cut
Line 316  sub clear_sequence_variables { Line 451  sub clear_sequence_variables {
 sub PrepareCourseData {  sub PrepareCourseData {
     my ($r) = @_;      my ($r) = @_;
     &clear_sequence_variables();      &clear_sequence_variables();
     my ($top,$sequences,$assessments) = &Apache::loncoursedata::get_sequence_assessment_data();      my ($top,$sequences,$assessments) = 
           &Apache::loncoursedata::get_sequence_assessment_data();
     if (! defined($top) || ! ref($top)) {      if (! defined($top) || ! ref($top)) {
         # There has been an error, better report it          # There has been an error, better report it
         &Apache::lonnet::logthis('top is undefined');          &Apache::lonnet::logthis('top is undefined');
Line 324  sub PrepareCourseData { Line 460  sub PrepareCourseData {
     }      }
     $top_map = $top if (ref($top));      $top_map = $top if (ref($top));
     @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');      @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');
     @Assessments = @{$assessments} if (ref($assessments) eq 'HASH');      @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');
       #
       # Compute column widths
       foreach my $seq (@Sequences) {
           my $name_length = scalar(my @Tmp1 = split(//,$seq->{'title'}));
           my $num_parts = $seq->{'num_assess_parts'};
           #
           # The number of columns needed for the summation text: 
           #    " 1/5" = 1+3 columns, " 10/99" = 1+5 columns
           my $sum_length = 1+1+2*(scalar(my @Tmp2 = split(//,$num_parts)));
           my $num_col = $num_parts+$sum_length;
           if ($num_col < $name_length) {
               $num_col = $name_length;
           }
           $seq->{'base_width'} = $name_length;
           $seq->{'width'} = $num_col;
       }
       return;
   }
   
   #######################################################
   #######################################################
   
 =pod  =pod
   
     ##  =item &log_sequence($sequence,$recursive,$padding)
     ## Debugging code  
     ##  Write data about the sequence to a logfile.  If $recursive is not
     foreach my $s (@Sequences) {  undef the data is written recursively.  $padding is used for recursive
         next if ($s->{'title'} ne 'Bioenergetics: Enzyme Regulation');  calls.
         &Apache::lonnet::logthis('-----------------------------------');  
         &Apache::lonnet::logthis('title      = '.$s->{'title'});  =cut
         &Apache::lonnet::logthis('symb       = '.$s->{'symb'});  
         &Apache::lonnet::logthis('num_assess = '.$s->{'num_assess'});  #######################################################
         foreach my $a (@{$s->{'contents'}}) {  #######################################################
             &Apache::lonnet::logthis('   --------------------------------');  sub log_sequence {
             &Apache::lonnet::logthis('   title      = '.$a->{'title'});      my ($seq,$recursive,$padding) = @_;
             &Apache::lonnet::logthis('   symb       = '.$a->{'symb'});      $padding = '' if (! defined($padding));
       if (ref($seq) ne 'HASH') {
           &Apache::lonnet::logthis('log_sequence passed bad sequnce');
           return;
       }
       &Apache::lonnet::logthis($padding.'sequence '.$seq->{'title'});
       while (my($key,$value) = each(%$seq)) {
           next if ($key eq 'contents');
           if (ref($value) eq 'ARRAY') {
               for (my $i=0;$i< scalar(@$value);$i++) {
                   &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
                                            $value->[$i]);
               }
           } else {
               &Apache::lonnet::logthis($padding.$key.'='.$value);
           }
       }
       if (defined($recursive)) {
           &Apache::lonnet::logthis($padding.'-'x20);
           &Apache::lonnet::logthis($padding.'contains:');
           foreach my $item (@{$seq->{'contents'}}) {
               if ($item->{'type'} eq 'container') {
                   &log_sequence($item,$recursive,$padding.'    ');
               } else {
                   &Apache::lonnet::logthis($padding.'title = '.$item->{'title'});
                   while (my($key,$value) = each(%$item)) {
                       next if ($key eq 'title');
                       if (ref($value) eq 'ARRAY') {
                           for (my $i=0;$i< scalar(@$value);$i++) {
                               &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
                                                        $value->[$i]);
                           }
                       } else {
                           &Apache::lonnet::logthis($padding.$key.'='.$value);
                       }
                   }
               }
         }          }
           &Apache::lonnet::logthis($padding.'end contents of '.$seq->{'title'});
           &Apache::lonnet::logthis($padding.'-'x20);
     }      }
       return;
   }
   
   ##############################################
   ##############################################
   
   =pod 
   
   =item &StudentDataSelect($elementname,$status,$numvisible,$selected)
   
   Returns html for a selection box allowing the user to choose one (or more) 
   of the fields of student data available (fullname, username, id, section, etc)
   
   =over 4
   
   =item $elementname The name of the HTML form element
   
   =item $status 'multiple' or 'single' selection box
   
   =item $numvisible The number of options to be visible
   
   =back
   
 =cut  =cut
   
     return;  ##############################################
   ##############################################
   sub StudentDataSelect {
       my ($elementname,$status,$numvisible)=@_;
       if ($numvisible < 1) {
           return;
       }
       #
       # Build the form element
       my $Str = "\n";
       $Str .= '<select name="'.$elementname.'" ';
       if ($status ne 'single') {
           $Str .= 'multiple="true" ';
       }
       $Str .= 'size="'.$numvisible.'" >'."\n";
       #
       # Deal with 'all'
       $Str .= '    <option value="all" ';
       foreach (@SelectedStudentData) {
           if ($_ eq 'all') {
               $Str .= 'selected ';
               last;
           }
       }
       $Str .= ">all</option>\n";
       #
       # Loop through the student data fields
       foreach my $item (@StudentDataOrder) {
           $Str .= '    <option value="'.$item.'" ';
           foreach (@SelectedStudentData) {
               if ($item eq $_ ) {
                   $Str .= 'selected ';
                   last;
               }
           }
           $Str .= '>'.$item."</option>\n";
       }
       $Str .= "</select>\n";
       return $Str;
 }  }
   
 ##############################################  ##############################################
Line 354  sub PrepareCourseData { Line 609  sub PrepareCourseData {
   
 =pod   =pod 
   
 =item &MapSelect($elementname,$status,$numvisible,$selected,$restriction)   =item &MapSelect($elementname,$status,$numvisible,$restriction) 
   
 Returns html for a selection box allowing the user to choose one (or more)   Returns html for a selection box allowing the user to choose one (or more) 
 of the sequences in the course.  The values of the sequences are the symbs.  of the sequences in the course.  The values of the sequences are the symbs.
Line 368  If the top sequence is selected, the val Line 623  If the top sequence is selected, the val
   
 =item $numvisible The number of options to be visible  =item $numvisible The number of options to be visible
   
 =item $selected Array ref to the names of the already selected maps.  
 If undef, $ENV{'form.'.$elementname} is used.    
 If $ENV{'form.'.$elementname} is also empty, none will be selected.  
   
 =item $restriction Code reference to subroutine which returns true or   =item $restriction Code reference to subroutine which returns true or 
 false.  The code must expect a reference to a sequence data structure.  false.  The code must expect a reference to a sequence data structure.
   
Line 382  false.  The code must expect a reference Line 633  false.  The code must expect a reference
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub MapSelect {  sub MapSelect {
     my ($elementname,$status,$numvisible,$selected,$restriction)=@_;      my ($elementname,$status,$numvisible,$restriction)=@_;
     if ($numvisible < 1) {      if ($numvisible < 1) {
         return;          return;
     }      }
     #      #
     # Set up array of selected items      # Set up array of selected items
     my @Selected;      &SetSelectedMaps($elementname);
     if (! defined($selected)) {  
         if (exists($ENV{'form.'.$elementname})) {  
             if (ref($ENV{'form.'.$elementname})) {  
                 @Selected = @$ENV{'form.'.$elementname};  
             } else {  
                 @Selected = ($ENV{'form.'.$elementname});  
             }  
         } else {  
             @Selected = ();  
         }  
     } else {  
         if (ref($selected)) {  
             @Selected = @$selected;  
         } else {  
             @Selected = ($selected);  
         }  
     }  
     #      #
     # Set up the restriction call      # Set up the restriction call
     if (! defined($restriction)) {      if (! defined($restriction)) {
Line 420  sub MapSelect { Line 654  sub MapSelect {
     }      }
     $Str .= 'size="'.$numvisible.'" >'."\n";      $Str .= 'size="'.$numvisible.'" >'."\n";
     #      #
       # Deal with 'all'
       foreach (@SelectedMaps) {
           if ($_ eq 'all') {
               @SelectedMaps = ('all');
               last;
           }
       }
       #
       # Put in option for 'all'
       $Str .= '    <option value="all" ';
       foreach (@SelectedMaps) {
           if ($_ eq 'all') {
               $Str .= 'selected ';
               last;
           }
       }
       $Str .= ">all</option>\n";
       #
     # Loop through the sequences      # Loop through the sequences
     foreach my $s (@Sequences) {      foreach my $seq (@Sequences) {
         next if (! $restriction->($s));          next if (! $restriction->($seq));
         $Str .= '    <option value="'.$s->{'symb'}.'" ';          $Str .= '    <option value="'.$seq->{'symb'}.'" ';
         foreach (@Selected) {          foreach (@SelectedMaps) {
             if ($s->{'symb'} eq $_) {              if ($seq->{'symb'} eq $_) {
                 $Str .= 'selected ';                  $Str .= 'selected ';
                 last;                  last;
             }              }
         }          }
         $Str .= '>'.$s->{'title'}."</option>\n";          $Str .= '>'.$seq->{'title'}."</option>\n";
     }      }
     $Str .= "</select>\n";      $Str .= "</select>\n";
     return $Str;      return $Str;
 }  }
   
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   
Line 486  sub SectionSelect { Line 737  sub SectionSelect {
     foreach my $s (@Sections) {      foreach my $s (@Sections) {
         $Str .= '    <option value="'.$s.'" ';          $Str .= '    <option value="'.$s.'" ';
         foreach (@SelectedSections) {          foreach (@SelectedSections) {
             if ($s eq $_ || $_ =~ /^(any|all)$/) {              if ($s eq $_) {
                 $Str .= 'selected ';                  $Str .= 'selected ';
                 last;                  last;
             }              }
Line 666  sub ProcessFormData{ Line 917  sub ProcessFormData{
     return;      return;
 }  }
   
   ##################################################
   ##################################################
   
 =pod  =pod
   
 =item &SortStudents()  =item &SortStudents()
Line 895  sub DisplayClasslist { Line 1149  sub DisplayClasslist {
                 $Str .= '<a href="/adm/statistics?reportSelected=';                  $Str .= '<a href="/adm/statistics?reportSelected=';
                 $Str .= &Apache::lonnet::escape('Student Assessment');                  $Str .= &Apache::lonnet::escape('Student Assessment');
                 $Str .= '&StudentAssessmentStudent=';                  $Str .= '&StudentAssessmentStudent=';
                 $Str .= &Apache::lonnet::escape($student->{$field}).'">';                  $Str .= &Apache::lonnet::escape($sname).'">';
                 $Str .= $student->{$field}.'&nbsp';                  $Str .= $student->{$field}.'&nbsp';
                 $Str .= '</a>';                  $Str .= '</a>';
             } else {              } else {
Line 1178  sub handler { Line 1432  sub handler {
     $r->send_http_header;      $r->send_http_header;
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['sort']);                                              ['sort',
                                                'StudentAssessmentStudent']);
   
     &PrepareClasslist($r);      &PrepareClasslist($r);
   

Removed from v.1.60  
changed lines
  Added in v.1.61


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