Diff for /loncom/interface/lonstatistics.pm between versions 1.76 and 1.123

version 1.76, 2003/06/10 19:19:57 version 1.123, 2005/04/07 06:56:23
Line 38  lonstatistics Line 38  lonstatistics
   
 Main handler for statistics and chart.  Main handler for statistics and chart.
   
 =head1 PACKAGES USED  
   
     use strict;  
     use Apache::Constants qw(:common :http);  
     use Apache::lonnet();  
     use Apache::lonhomework;  
     use Apache::loncommon;  
     use Apache::loncoursedata;  
     use Apache::lonhtmlcommon;  
     use Apache::lonproblemanalysis;  
     use Apache::lonproblemstatistics;  
     use Apache::lonstudentassessment;  
     use Apache::lonpercentage;  
     use Apache::lonmysql;  
 =over 4  =over 4
   
 =cut  =cut
Line 64  use vars qw( Line 50  use vars qw(
     @FullClasslist       @FullClasslist 
     @Students      @Students
     @Sections       @Sections 
     @SelectedSections  
     %StudentData      %StudentData
     @StudentDataOrder      @StudentDataOrder
     @SelectedStudentData      @SelectedStudentData
     $top_map       $enrollment_status);
     @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::lonmysql;
   use Apache::lonlocal;
   use Time::HiRes;
   #
   # Statistics Packages
 use Apache::lonproblemanalysis();  use Apache::lonproblemanalysis();
   use Apache::lonsubmissiontimeanalysis();
   use Apache::loncorrectproblemplot();
 use Apache::lonproblemstatistics();  use Apache::lonproblemstatistics();
 use Apache::lonstudentassessment();  use Apache::lonstudentassessment();
 use Apache::lonpercentage;  use Apache::lonpercentage;
 use Apache::lonmysql;  use Apache::lonstudentsubmissions();
 use Time::HiRes;  use Apache::lonsurveyreports();
   
 #######################################################  #######################################################
 #######################################################  #######################################################
Line 134  undef the following package variables: Line 123  undef the following package variables:
   
 =item @Sections  =item @Sections
   
 =item @SelectedSections  
   
 =item %StudentData  =item %StudentData
   
 =item @StudentDataOrder  =item @StudentDataOrder
Line 158  sub clear_classlist_variables { Line 145  sub clear_classlist_variables {
     undef(@FullClasslist);      undef(@FullClasslist);
     undef(@Students);      undef(@Students);
     undef(@Sections);      undef(@Sections);
     undef(@SelectedSections);  
     undef(%StudentData);      undef(%StudentData);
     undef(@SelectedStudentData);      undef(@SelectedStudentData);
     undef($curr_student);      undef($curr_student);
Line 184  the following package variables: Line 170  the following package variables:
   
 =item @Sections  =item @Sections
   
 =item @SelectedSections  
   
 =item %StudentData  =item %StudentData
   
 =item @SelectedStudentData  =item @SelectedStudentData
Line 210  sub PrepareClasslist { Line 194  sub PrepareClasslist {
     &clear_classlist_variables();      &clear_classlist_variables();
     #      #
     # Retrieve the classlist      # Retrieve the classlist
     my $cid  = $ENV{'request.course.id'};      my $cid  = $env{'request.course.id'};
     my $cdom = $ENV{'course.'.$cid.'.domain'};      my $cdom = $env{'course.'.$cid.'.domain'};
     my $cnum = $ENV{'course.'.$cid.'.num'};      my $cnum = $env{'course.'.$cid.'.num'};
     my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,      my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,
                                                                   $cdom,$cnum);                                                                    $cdom,$cnum);
     if (exists($ENV{'form.Section'})) {      my @selected_sections = &get_selected_sections();
         if (ref($ENV{'form.Section'})) {  
             @SelectedSections = @{$ENV{'form.Section'}};  
         } elsif ($ENV{'form.Section'} !~ /^\s*$/) {  
             @SelectedSections = ($ENV{'form.Section'});  
         }  
     }  
     @SelectedSections = ('all') if (! @SelectedSections);  
     foreach (@SelectedSections) {  
         if ($_ eq 'all') {  
             @SelectedSections = ('all');  
         }  
     }  
     #      #
     # Deal with instructors with restricted section access      # Deal with instructors with restricted section access
     if ($ENV{'request.course.sec'} !~ /^\s*$/) {      if ($env{'request.course.sec'} !~ /^\s*$/) {
         @SelectedSections = ($ENV{'request.course.sec'});          @selected_sections = ($env{'request.course.sec'});
     }      }
     #      #
     # Set up %StudentData      # Set up %StudentData
     @StudentDataOrder = qw/fullname username domain id section status/;      @StudentDataOrder = qw/fullname username domain id section status comments/;
     foreach my $field (@StudentDataOrder) {      foreach my $field (@StudentDataOrder) {
         $StudentData{$field}->{'title'} = $field;          $StudentData{$field}->{'title'} = &mt($field);
         $StudentData{$field}->{'base_width'} = length($field);          $StudentData{$field}->{'base_width'} = length(&mt($field));
         $StudentData{$field}->{'width'} =           $StudentData{$field}->{'width'} = 
                                $StudentData{$field}->{'base_width'};                                 $StudentData{$field}->{'base_width'};
     }      }
     #      #
     # get the status requested      # get the status requested
     my $requested_status = 'Active';      $enrollment_status = 'Active';
     $requested_status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));      $enrollment_status = $env{'form.Status'} if (exists($env{'form.Status'}));
     #      #
     # Process the classlist      # Process the classlist
     while (my ($student,$student_data) = each (%$classlist)) {      while (my ($student,$student_data) = each (%$classlist)) {
Line 272  sub PrepareClasslist { Line 244  sub PrepareClasslist {
         $Sections{$section}++;          $Sections{$section}++;
         #          #
         # 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 (@selected_sections) {
             if ( (($sect eq 'all') ||               if ( (($sect eq 'all') || 
                   ($section eq $sect)) &&                    ($section eq $sect)) &&
                  (($studenthash->{'status'} eq $requested_status) ||                    (($studenthash->{'status'} eq $enrollment_status) || 
                   ($requested_status eq 'Any'))                     ($enrollment_status eq 'Any')) 
                  ){                   ){
                 push (@Students,$studenthash);                  push (@Students,$studenthash);
                 last;                  last;
Line 285  sub PrepareClasslist { Line 257  sub PrepareClasslist {
     }      }
     #      #
     # Put the consolidated section data in the right place      # Put the consolidated section data in the right place
     if ($ENV{'request.course.sec'} !~ /^\s*$/) {      if ($env{'request.course.sec'} !~ /^\s*$/) {
         @Sections = ($ENV{'request.course.sec'});          @Sections = ($env{'request.course.sec'});
     } else {      } else {
         @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          unshift(@Sections,'all'); # Put 'all' at the front of the list
Line 294  sub PrepareClasslist { Line 266  sub PrepareClasslist {
     #      #
     # 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....
     $curr_student = undef;      $curr_student = undef;
     if (exists($ENV{'form.SelectedStudent'})) {      if (exists($env{'form.SelectedStudent'})) {
         my ($current_uname,$current_dom) =           my ($current_uname,$current_dom) = 
             split(':',$ENV{'form.SelectedStudent'});              split(':',$env{'form.SelectedStudent'});
         my $i;          my $i;
         for ($i = 0; $i<=$#Students; $i++) {          for ($i = 0; $i<=$#Students; $i++) {
             next if (($Students[$i]->{'username'} ne $current_uname) ||               next if (($Students[$i]->{'username'} ne $current_uname) || 
Line 325  sub PrepareClasslist { Line 297  sub PrepareClasslist {
         }          }
     }      }
     #      #
     if (exists($ENV{'form.StudentData'})) {      if (exists($env{'form.StudentData'})) {
         if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {          if (ref($env{'form.StudentData'}) eq 'ARRAY') {
             @SelectedStudentData = @{$ENV{'form.StudentData'}};              @SelectedStudentData = @{$env{'form.StudentData'}};
         } else {          } else {
             @SelectedStudentData = ($ENV{'form.StudentData'});              @SelectedStudentData = ($env{'form.StudentData'});
         }          }
     } else {      } else {
         @SelectedStudentData = ('username');          @SelectedStudentData = ('username');
Line 344  sub PrepareClasslist { Line 316  sub PrepareClasslist {
     return;      return;
 }  }
   
   
 #######################################################  #######################################################
 #######################################################  #######################################################
   
 =pod  =pod
   
 =item get_students  =item get_selected_sections
   
 Returns a list of the selected students  Returns an array of the selected sections
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub get_students {  sub get_selected_sections {
     if (! @Students) {      my @selected_sections;
         &PrepareClasslist()      if (exists($env{'form.Section'})) {
           if (ref($env{'form.Section'})) {
               @selected_sections = @{$env{'form.Section'}};
           } elsif ($env{'form.Section'} !~ /^\s*$/) {
               @selected_sections = ($env{'form.Section'});
           }
     }      }
     return @Students;      @selected_sections = ('all') if (! @selected_sections);
 }      foreach (@selected_sections) {
           if ($_ eq 'all') {
 #######################################################              @selected_sections = ('all');
 #######################################################          }
       }
 =pod      #
       # Deal with instructors with restricted section access
 =item &current_student()      if ($env{'request.course.sec'} !~ /^\s*$/) {
           @selected_sections = ($env{'request.course.sec'});
 Returns a pointer to a hash containing data about the currently      }
 selected student.      return @selected_sections;
   
 =cut  
   
 #######################################################  
 #######################################################  
 sub current_student {   
     return $curr_student;  
 }  
   
 #######################################################  
 #######################################################  
   
 =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 {   
     return $prev_student;  
 }  }
   
 #######################################################  #######################################################
Line 406  sub previous_student { Line 357  sub previous_student {
   
 =pod  =pod
   
 =item &next_student()  =item &section_and_enrollment_description
   
 Returns a pointer to a hash containing data about the next student  Returns a string describing the currenly selected section(s) and 
 to be viewed.  enrollment status.  
   
 =cut  Inputs: mode = 'plaintext' or 'localized'  (defaults to 'localized')
       'plaintext' is used for example in Excel spreadsheets.
 #######################################################  Returns: scalar description string.
 #######################################################  
 sub next_student {   
     return $next_student;  
 }  
   
 #######################################################  
 #######################################################  
   
 =pod  
   
 =item &clear_sequence_variables()  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub clear_sequence_variables {  sub section_and_enrollment_description {
     undef($top_map);      my ($mode) = @_;
     undef(@Sequences);      if (! defined($mode)) { $mode = 'localized'; }
     undef(@Assessments);      my @sections = &Apache::lonstatistics::get_selected_sections();
       my $description;
       if ($mode eq 'localized') {
           $description = &mt('Unable to determine section and enrollment');
       } elsif ($mode eq 'plaintext') {
           $description = 'Unable to determine section and enrollment';
       } else {
           $description = 'Bad parameter passed to lonstatistics::section_and_enrollment_description';
           &Apache::lonnet::logthis($description);
       }
       if (scalar(@sections) == 1 && $sections[0] ne 'all') {
           if ($mode eq 'localized') {
               $description = &mt('Section [_1]. [_2] enrollment status.',
                                  $sections[0],$env{'form.Status'});
           } elsif ($mode eq 'plaintext') {
               $description = 'Section '.$sections[0].'. '.
                   $env{'form.Status'}.' enrollment status.';
           }
       } elsif (scalar(@sections) && $sections[0] eq 'all') {
           if ($mode eq 'localized') {
               $description = &mt('All sections. [_1] enrollment status.',
                                  $env{'form.Status'});
           } elsif ($mode eq 'plaintext') {
               $description = 'All sections. '.
                   $env{'form.Status'}.' enrollment status.';
           }
       } elsif (scalar(@sections)) {
           my $lastsection = pop(@sections);
           if ($mode eq 'localized') {
               $description = &mt('Sections [_1] and [_2]. [_3] enrollment status.',
                                  join(', ',@sections),$lastsection,
                                  $env{'form.Status'});
           } elsif ($mode eq 'plaintext') {
               $description = 
                   'Sections '.join(', ',@sections).' and '.$lastsection.'. '.
                   $env{'form.Status'}.' enrollment status.';
           }
       }
       return $description;
 }  }
   
 #######################################################  #######################################################
Line 441  sub clear_sequence_variables { Line 419  sub clear_sequence_variables {
   
 =pod  =pod
   
 =item &SetSelectedMaps($elementname)  =item get_students
   
 Sets the @SelectedMaps array from $ENV{'form.'.$elementname};  Returns a list of the selected students
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub SetSelectedMaps {  sub get_students {
     my $elementname = shift;      if (! @Students) {
     if (exists($ENV{'form.'.$elementname})) {          &PrepareClasslist()
         if (ref($ENV{'form.'.$elementname})) {  
             @SelectedMaps = @{$ENV{'form.'.$elementname}};  
         } else {  
             @SelectedMaps = ($ENV{'form.'.$elementname});  
         }  
     } else {  
         @SelectedMaps = ('all');  
     }      }
       return @Students;
 }  }
   
   
 #######################################################  #######################################################
 #######################################################  #######################################################
   
 =pod  =pod
   
 =item &Sequences_with_Assess()  =item &current_student()
   
 Returns an array containing the subset of @Sequences which contain  Returns a pointer to a hash containing data about the currently
 assessments.  selected student.
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub Sequences_with_Assess {  sub current_student { 
     my @Sequences_to_Show;      return $curr_student;
     foreach my $map_symb (@SelectedMaps) {  
         foreach my $sequence (@Sequences) {  
             next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all');  
             next if ($sequence->{'num_assess'} < 1);  
             push (@Sequences_to_Show,$sequence);  
         }  
     }  
     return @Sequences_to_Show;  
 }  }
   
 #######################################################  #######################################################
Line 494  sub Sequences_with_Assess { Line 457  sub Sequences_with_Assess {
   
 =pod  =pod
   
 =item &PrepareCourseData($r)  =item &previous_student()
   
   Returns a pointer to a hash containing data about the student prior
   in the list of students.  Or something.  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub PrepareCourseData {  sub previous_student { 
     my ($r) = @_;      return $prev_student;
     &clear_sequence_variables();  
     my ($top,$sequences,$assessments) =   
         &Apache::loncoursedata::get_sequence_assessment_data();  
     if (! defined($top) || ! ref($top)) {  
         # There has been an error, better report it  
         &Apache::lonnet::logthis('top is undefined');  
         return;  
     }  
     $top_map = $top if (ref($top));  
     @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  
     @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');  
     #  
     # Compute column widths  
     foreach my $seq (@Sequences) {  
         my $name_length = length($seq->{'title'});  
         my $num_parts = $seq->{'num_assess_parts'};  
         #  
         # Use 3 digits for each the sum and total, which means 7 total...  
         my $num_col = $num_parts+7;  
         if ($num_col < $name_length) {  
             $num_col = $name_length;  
         }  
         $seq->{'base_width'} = $name_length;  
         $seq->{'width'} = $num_col;  
     }  
     return;  
 }  }
   
 #######################################################  #######################################################
Line 535  sub PrepareCourseData { Line 475  sub PrepareCourseData {
   
 =pod  =pod
   
 =item &log_sequence($sequence,$recursive,$padding)  =item &next_student()
   
 Write data about the sequence to a logfile.  If $recursive is not  Returns a pointer to a hash containing data about the next student
 undef the data is written recursively.  $padding is used for recursive  to be viewed.
 calls.  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub log_sequence {  sub next_student { 
     my ($seq,$recursive,$padding) = @_;      return $next_student;
     $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;  
 }  }
   
 ##############################################  ##############################################
Line 654  sub StudentDataSelect { Line 551  sub StudentDataSelect {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &get_selected_maps($elementname)
   
   Input: Name of the <select> form element used to specify the maps.
   
   Returns: Array of symbs of selected maps or the description 'all'.
      If form.$elementname does not exist, 'all' is returned.
   
   =cut
   
   #######################################################
   #######################################################
   sub get_selected_maps {
       my ($elementname) = @_;
       my @selected_maps;
       if (exists($env{'form.'.$elementname})) {
           if (ref($env{'form.'.$elementname})) {
               @selected_maps = @{$env{'form.'.$elementname}};
           } else {
               @selected_maps = ($env{'form.'.$elementname});
           }
       } else {
           @selected_maps = ('all');
       }
       foreach my $map (@selected_maps) {
           if ($map eq 'all') {
               @selected_maps = ('all');
               last;
           }
       }
       return @selected_maps;
   }
   
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &selected_sequences_with_assessments
   
   Retrieve the sequences which were selected by the user to show.  
   
   Input: $mode: scalar.  Either 'selected' or 'all'.  If not specified,
       'selected' is used.
   
   Returns: an array containing a navmap object and navmap resources, 
       or an array containing a scalar with an error message.
   
   =cut
   
   #######################################################
   #######################################################
   sub selected_sequences_with_assessments {
       my ($mode) = @_;
       $mode = 'selected' if (! defined($mode));
       my $navmap = Apache::lonnavmaps::navmap->new();
       if (!defined($navmap)) {
           return ('Can not open Coursemap');
       }
       #
       my @sequences = $navmap->retrieveResources(undef,
                                                  sub { shift->is_map(); },1,0,1);
       my @sequences_with_assessments;
       for my $sequence ($navmap->getById('0.0'), @sequences) {
    if ($navmap->hasResource($sequence,sub { shift->is_problem(); },0,1)){
               push(@sequences_with_assessments,$sequence);
           }
       }
       #
       my @sequences_to_show;
       foreach my $sequence (@sequences_with_assessments) {
           if ($mode eq 'all') {
               push (@sequences_to_show,$sequence);
           } elsif ($mode eq 'selected') {
               foreach my $map_symb (&get_selected_maps('Maps')) {
                   if ($sequence->symb eq $map_symb || $map_symb eq 'all'){
                       push (@sequences_to_show,$sequence);
                       last; # Only put it in once
                   }
               }
           }
   
       }
       return $navmap,@sequences_to_show;
   }
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   
 =pod   =pod 
   
 =item &MapSelect($elementname,$status,$numvisible,$restriction)   =item &map_select($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 673  If the top sequence is selected, the val Line 661  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 $restriction Code reference to subroutine which returns true or   
 false.  The code must expect a reference to a sequence data structure.  
   
 =back  =back
   
 =cut  =cut
   
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub MapSelect {  sub map_select {
     my ($elementname,$status,$numvisible,$restriction)=@_;      my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {      if ($numvisible < 1) {
         return;          return;
     }      }
     #      #
     # Set up array of selected items      # Set up array of selected items
     &SetSelectedMaps($elementname);      my @selected_maps = &get_selected_maps($elementname);
     #  
     # Set up the restriction call  
     if (! defined($restriction)) {  
         $restriction = sub { 1; };  
     }  
     #      #
     # Build the form element      # Build the form element
     my $Str = "\n";      my $form = "\n";
     $Str .= '<select name="'.$elementname.'" ';      $form .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {      if ($status ne 'single') {
         $Str .= 'multiple="true" ';          $form .= 'multiple="true" ';
     }  
     $Str .= 'size="'.$numvisible.'" >'."\n";  
     #  
     # Deal with 'all'  
     foreach (@SelectedMaps) {  
         if ($_ eq 'all') {  
             @SelectedMaps = ('all');  
             last;  
         }  
     }      }
       $form .= 'size="'.$numvisible.'" >'."\n";
     #      #
     # Put in option for 'all'      # Put in option for 'all'
     $Str .= '    <option value="all" ';      $form .= '    <option value="all" ';
     foreach (@SelectedMaps) {      if ($selected_maps[0] eq 'all') {
         if ($_ eq 'all') {          $form .= 'selected ';
             $Str .= 'selected ';  
             last;  
         }  
     }      }
     $Str .= ">all</option>\n";      $form .= ">all</option>\n";
     #      #
     # Loop through the sequences      # Loop through the sequences
     foreach my $seq (@Sequences) {      my @sequences = &selected_sequences_with_assessments('all');
         next if (! $restriction->($seq));      my $navmap;
         $Str .= '    <option value="'.$seq->{'symb'}.'" ';      if (!ref($sequences[0])) {
         foreach (@SelectedMaps) {          return $sequences[0];
             if ($seq->{'symb'} eq $_) {      } else {
                 $Str .= 'selected ';          $navmap = shift(@sequences);
       }
       foreach my $seq (@sequences){
           $form .= '    <option value="'.$seq->symb.'" ';
           foreach (@selected_maps) {
               if ($seq->symb eq $_) {
                   $form .= 'selected ';
                 last;                  last;
             }              }
         }          }
         $Str .= '>'.$seq->{'title'}."</option>\n";          $form .= '>'.$seq->compTitle."</option>\n";
     }      }
     $Str .= "</select>\n";      $form .= "</select>\n";
     return $Str;      return $form;
 }  }
   
 ##############################################  ##############################################
Line 748  sub MapSelect { Line 723  sub MapSelect {
 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 sections in the course.    of the sections in the course.  
   
 Uses the package variables @Sections and @SelectedSections  Uses the package variables @Sections
 =over 4  =over 4
   
 =item $elementname The name of the HTML form element  =item $elementname The name of the HTML form element
Line 785  sub SectionSelect { Line 760  sub SectionSelect {
     # Loop through the sequences      # Loop through the sequences
     foreach my $s (@Sections) {      foreach my $s (@Sections) {
         $Str .= '    <option value="'.$s.'" ';          $Str .= '    <option value="'.$s.'" ';
         foreach (@SelectedSections) {          foreach (&get_selected_sections()) {
             if ($s eq $_) {              if ($s eq $_) {
                 $Str .= 'selected ';                  $Str .= 'selected ';
                 last;                  last;
Line 801  sub SectionSelect { Line 776  sub SectionSelect {
 ##################################################  ##################################################
 sub DisplayClasslist {  sub DisplayClasslist {
     my ($r)=@_;      my ($r)=@_;
       &Apache::lonhtmlcommon::add_breadcrumb
           ({text=>'Select One Student'});
     #      #
     my @Fields = ('fullname','username','domain','id','section');      # Output some of the standard interface components
       my $Str;
       $Str .= &Apache::lonhtmlcommon::breadcrumbs(undef,'Select One Student');
       $Str .= '<p><table cellspacing="5">'."\n";
       $Str .= '<tr>';
       $Str .= '<th align="center"><b>'.&mt('Sections').'</b></th>';
       $Str .= '<th align="center"><b>'.&mt('Enrollment Status').'</b></th>';
       $Str .= '</tr>'.$/;
       $Str .= '<tr>';
       $Str .= '<td>'.
           &Apache::lonstatistics::SectionSelect('Section','multiple',5).
           '</td>';
       $Str .= '<td>'.
           &Apache::lonhtmlcommon::StatusOptions(undef,undef,5).
           '</td>';
       
       $Str .= '</tr>'.$/;
       $Str .= '</table></p>';
       $Str .= '<input type="submit" name="selectstudent" value="'.
           &mt('Update Display').'" />';
       $r->print($Str);
       $r->rflush();
     #      #
     my $Str='';      my @Fields = ('fullname','username','domain','id','section','status');
       #
       $Str = '';
       my @selected_sections = &get_selected_sections();
       if (! @Students) {
           if ($selected_sections[0] eq 'all') { 
               if (lc($env{'form.Status'}) eq 'any') {
                   $Str .= '<h2>'.
                       &mt('There are no students in the course.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'active') {
                   $Str .= '<h2>'.
                   &mt('There are no currently enrolled students in the course.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'expired') {
                   $Str .= '<h2>'.
                       &mt('There are no previously enrolled students in the course.').
                           '</h2>';
               }
           } else { 
               my $sections;
               if (lc($env{'form.Status'}) eq 'any') {
                   $Str .= '<h2>'.
                       &mt('There are no students in the selected sections.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'active') {
                   $Str .= '<h2>'.
                       &mt('There are no currently enrolled students in the selected sections.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'expired') {
                   $Str .= '<h2>'.
                       &mt('There are no previously enrolled students in the selected sections.').
                       '</h2>';
               }
           }
           $Str.= '<a href="/adm/statistics?reportSelected=student_assessment">'.
               &mt('Click here to return to the chart').'</a>';
           $r->print($Str);
           $r->rflush();
           return;
       }
   
     # "Click" is asinine but it is probably not my place to change the world.      # "Click" is asinine but it is probably not my place to change the world.
     $Str .= '<h2>Click on a users name to view their chart</h2>';      $Str .= '<h2>Click on a students name or username to view their chart</h2>';
     $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";      $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
     $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";      $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
     foreach my $field (@Fields) {      foreach my $field (@Fields) {
         $Str .= '<th><a href="/adm/statistics?reportSelected=classlist&sort='.$field.'">'.$field.          $Str .= '<th><a href="/adm/statistics?'.
               'reportSelected=student_assessment&'.
               'selectstudent=1&'.
               'sort='.$field.'">'.&mt($field).
             '</a></th>';              '</a></th>';
     }      }
     $Str .= '</tr>'."\n";      $Str .= '</tr>'."\n";
Line 827  sub DisplayClasslist { Line 869  sub DisplayClasslist {
         #          #
         foreach my $field (@Fields) {          foreach my $field (@Fields) {
             $Str .= '<td>';              $Str .= '<td>';
             if ($field eq 'fullname') {              if ($field eq 'fullname' || $field eq 'username') {
                 $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 .= '&sort='.&Apache::lonnet::escape($ENV{'form.sort'});                  $Str .= '&sort='.&Apache::lonnet::escape($env{'form.sort'});
                 $Str .= '&SelectedStudent=';                  $Str .= '&SelectedStudent=';
                 $Str .= &Apache::lonnet::escape($sname).'">';                  $Str .= &Apache::lonnet::escape($sname).'">';
                 $Str .= $student->{$field}.'&nbsp';                  $Str .= $student->{$field}.'&nbsp';
                 $Str .= '</a>';                  $Str .= '</a>';
               } elsif ($field eq 'status') {
                   $Str .= &mt($student->{$field});
             } else {              } else {
                 $Str .= $student->{$field};                  $Str .= $student->{$field};
             }              }
Line 853  sub DisplayClasslist { Line 897  sub DisplayClasslist {
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub CreateMainMenu {  sub CreateMainMenu {
     my ($status,$reports,$current)=@_;  
     #      #
     my $Str = '';      # Define menu data
       my @reports = ({ internal_name => 'problem_statistics',
                        name => &mt('Overall Problem Statistics'),
                        short_description => 
       &mt('Student performance statistics on all problems.'),
                    },
                      { internal_name => 'problem_analysis',
                        name => &mt('Detailed Problem Analysis'),
                        short_description => 
       &mt('Detailed statistics and graphs of student performance on problems.'),
                    },
                      { internal_name => 'submissiontime_analysis',
                        name => &mt('Submission Time Plots'),
                        short_description => 
       &mt('Display and analysis of submission times on assessments.'),
                    },
                      { internal_name => 'student_submission_reports',
                        name => &mt('Student Submission Reports'),
                        short_description => 
       &mt('Prepare reports of student submissions.'),
                    },
                      { internal_name => 'survey_reports',
                        name => &mt('Survey Reports'),
                        short_description => 
       &mt('Prepare reports on survey results.'),
                    },
                      { internal_name => 'correct_problems_plot',
                        name => &mt('Correct Problems Plot'),
                        short_description => 
       &mt('Display a histogram of student performance in the course.'),
                    },
   #                   { internal_name => 'student_assessment',
   #                     name => &mt('Problem Status Chart'),
   #                     short_description => 
   #    &mt('Brief view of each students performance in course.'),
   #                 },
                      # 'percentage'  => 'Correct-problems Plot',
                      # 'activitylog' => 'Activity Log',
                      );
     #      #
     $Str .= '<table border="0"><tbody><tr>'."\n";      # Create the menu
     $Str .= '<td align="center"><b>Report:</b></td>'."\n";      my $Str;
     $Str .= '<td align="center">';      $Str .= '<h2>'.&mt('Please select a report to generate').'</h2>';
     $Str .= '<select name="reportSelected" '.      foreach my $reportdata (@reports) {
         'onchange="document.Statistics.submit()">'."\n";          $Str .='    <h3><a href="/adm/statistics?reportSelected='.
     foreach (sort(keys(%$reports))) {              $reportdata->{'internal_name'}.'" >'.
         $Str .= '<option value="'.$_.'"';              $reportdata->{'name'}."</a></h3>\n";
         if($current eq $_) {          $Str .= '    '.('&nbsp;'x8).$reportdata->{'short_description'}.
             $Str .= ' selected';              "\n";
         }      }
         $Str .= '>'.$reports->{$_}.'</option>'."\n";      $Str .="</dl>\n";
     }  
     $Str .= '</select></td>'."\n";  
     #  
     $Str .= '<td>'.('&nbsp;'x30).'</td>';  
     $Str .= '<td align="center">'.  
         '<input type="submit" name="ClearCache" value="Clear Caches" />'.  
             "</td>\n";  
     $Str .= '</tr></tbody></table>'."\n";  
     $Str .= '<hr>'."\n";  
     #      #
     return $Str;      return $Str;
 }  }
Line 892  sub handler { Line 964  sub handler {
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
     $loaderror=      $loaderror=
        &Apache::lonnet::overloaderror($r,         &Apache::lonnet::overloaderror($r,
          $ENV{'course.'.$ENV{'request.course.id'}.'.home'});           $env{'course.'.$env{'request.course.id'}.'.home'});
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
     #      #
     # Check for access      # Check for access
     if (! &Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {      if (! &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
         $ENV{'user.error.msg'}=          $env{'user.error.msg'}=
             $r->uri.":vgr:0:0:Cannot view grades for complete course";              $r->uri.":vgr:0:0:Cannot view grades for complete course";
         if (! &Apache::lonnet::allowed('vgr',          if (! &Apache::lonnet::allowed('vgr',
                       $ENV{'request.course.id'}.'/'.$ENV{'request.course.sec'})) {                        $env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
             $ENV{'user.error.msg'}=              $env{'user.error.msg'}=
                 $r->uri.":vgr:0:0:Cannot view grades with given role";                  $r->uri.":vgr:0:0:Cannot view grades with given role";
             return HTTP_NOT_ACCEPTABLE;              return HTTP_NOT_ACCEPTABLE;
         }          }
     }      }
     #      #
     # Set document type for header only  
     if($r->header_only) {  
         if ($ENV{'browser.mathml'}) {  
             $r->content_type('text/xml');  
         } else {  
             $r->content_type('text/html');  
         }  
         &Apache::loncommon::no_cache($r);  
         $r->send_http_header;  
         return OK;  
     }  
     #  
     # Send the header      # Send the header
     $r->content_type('text/html');      &Apache::loncommon::no_cache($r);
       &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
       if ($r->header_only) { return OK; }
     #      #
     # Extract form elements from query string      # Extract form elements from query string
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['sort','reportSelected',                                              ['sort','reportSelected',
                                              'SelectedStudent']);                                               'SelectedStudent']);
     if (! exists($ENV{'form.reportSelected'})) {  
         $ENV{'form.reportSelected'} = 'student_assessment';  
     }  
     #      #
     # Give the LON-CAPA page header      # Give the LON-CAPA page header
     $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));      my $style = <<ENDSTYLE;
     $r->rflush();  <style type="text/css">
     #      ul.sub_studentans { list-style-type: none }
     if (! &Apache::lonmysql::verify_sql_connection()) {      ul.sub_correctans { list-style-type: none }
         my $serveradmin = $r->dir_config('lonAdmEMail');      tr.even           { background-color: \#CCCCCC }
         $r->print(<<END);      td.essay          { border: 1px solid gray; }
 <h2><font color="Red">Unable to connect to database!</font></h2>  </style>
 <p>  ENDSTYLE
 Please notify the server administrator <b>$serveradmin</b>.      my $html=&Apache::lonxml::xmlbegin();
 </p><p>      $r->print($html.'<head><title>'.
 Course Statistics and Charts cannot be retrieved until the database is                &mt('Course Statistics and Charts').
 restarted.  Your data is intact but cannot be displayed at this time.                '</title>'.$style.
 </p>                "</head>\n".
 </body>                &Apache::loncommon::bodytag('Course Statistics and Charts'));
 </html>  
 END  
         return;  
     }  
     #  
     # Clean out the caches  
     if (exists($ENV{'form.ClearCache'})) {  
         &Apache::loncoursedata::delete_caches($ENV{'requres.course.id'});  
     }  
     #  
     # Set up the statistics and chart environment  
     &PrepareClasslist();  
     &PrepareCourseData($r);  
     #  
     # Begin form output  
     $r->print('<form name="Statistics" ');  
     $r->print('method="post" action="/adm/statistics">');  
     #  
     # Print main menu  
     my %reports = ('classlist'          => 'Class list',  
                    'problem_statistics' => 'Problem Statistics',  
                    'student_assessment' => 'Problem Status Chart',  
 #                   'percentage'         => 'Correct-problems Plot',  
 #                   'option_response'    => 'Option Response Analysis',  
 #                   'activitylog'        => 'Activity Log',  
                    );  
     $r->print(&CreateMainMenu($ENV{'form.status'},  
                               \%reports,$ENV{'form.reportSelected'}));  
     $r->rflush();      $r->rflush();
       # 
       # Either print out a menu for them or send them to a report
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/statistics',
                                               title=>'Statistics',
                                               text =>'Statistics',
                                               faq=>139,
                                               bug=>'Statistics and Charts'});
       if (! exists($env{'form.reportSelected'}) || 
           $env{'form.reportSelected'} eq '') {
           $r->print(&Apache::lonhtmlcommon::breadcrumbs
                     (undef,&mt('Statistics Main Page')).
                     &CreateMainMenu());
       } else {
     #      #
     my $GoToPage = $ENV{'form.reportSelected'};          if (! &Apache::lonmysql::verify_sql_connection()) {
     if($GoToPage eq 'activitylog') {              my $serveradmin = $r->dir_config('lonAdmEMail');
               $r->print('<h2><font color="Red">'.
                         &mt('Unable to connect to database!').
                         '</font></h2>');
               $r->print('<p>'.
                         &mt('Please notify the server administrator ').
                         '<b>'.$serveradmin.'</b></p>');
               $r->print('<p>'.
                         &mt('Course Statistics and Charts cannot be '.
                             'retrieved until the database is restarted.  '.
                             'Your data is intact but cannot be displayed '.
                             'at this time.').'</p>');
               $r->print('</body></html>');
               return;
           }
           #
           # Clean out the caches
           if (exists($env{'form.ClearCache'})) {
               &Apache::loncoursedata::delete_caches($env{'requres.course.id'});
           }
           #
           # Begin form output
           $r->print('<form name="Statistics" ');
           $r->print('method="post" action="/adm/statistics">');
           $r->rflush();
           #
           my $GoToPage = $env{'form.reportSelected'};
           #
           $r->print('<input type="hidden" name="reportSelected" value="'.
                     $GoToPage.'">');
           if($GoToPage eq 'activitylog') {
 #        &Apache::lonproblemstatistics::Activity();  #        &Apache::lonproblemstatistics::Activity();
     } elsif($GoToPage eq 'problem_statistics') {          } elsif($GoToPage eq 'problem_statistics') {
         &Apache::lonproblemstatistics::BuildProblemStatisticsPage($r,$c);              &Apache::lonhtmlcommon::add_breadcrumb
     } elsif($GoToPage eq 'option_response') {                  ({href=>'/adm/statistics?reportselected=problem_statistics',
 #        &Apache::lonproblemanalysis::BuildProblemAnalysisPage($r,$c);                    text=>'Overall Problem Statistics'});
     } elsif($GoToPage eq 'student_assessment') {              &Apache::lonproblemstatistics::BuildProblemStatisticsPage($r,$c);
         &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);          } elsif($GoToPage eq 'problem_analysis') {
     } elsif($GoToPage eq 'DoDiffGraph' || $GoToPage eq 'PercentWrongGraph') {              &Apache::lonhtmlcommon::add_breadcrumb
 #        &Apache::lonproblemstatistics::BuildGraphicChart($r,$c);                  ({href=>'/adm/statistics?reportselected=problem_analysis',
     } elsif($GoToPage eq 'classlist') {                    text=>'Detailed Problem Analysis'});
         &DisplayClasslist($r);              &Apache::lonproblemanalysis::BuildProblemAnalysisPage($r,$c);
     } elsif($GoToPage eq 'Correct-problems Plot') {          } elsif($GoToPage eq 'submissiontime_analysis') {
 # &Apache::lonpercentage::BuildPercentageGraph($r,$c);              &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                         '/adm/statistics?reportselected=submissiontime_analysis',
                         text=>'Submission Time Plots'});
               &Apache::lonsubmissiontimeanalysis::BuildSubmissionTimePage($r,$c);
           } elsif($GoToPage eq 'student_submission_reports') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                     '/adm/statistics?reportselected=student_submission_reports',
                     text=>'Student Submission Reports'});
               &Apache::lonstudentsubmissions::BuildStudentSubmissionsPage($r,$c);
           } elsif($GoToPage eq 'survey_reports') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                     '/adm/statistics?reportselected=survey_reports',
                     text=>'Survey Reports'});
               &Apache::lonsurveyreports::BuildSurveyReportsPage($r,$c);
           } elsif($GoToPage eq 'correct_problems_plot') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>'/adm/statistics?reportselected=correct_problems_plot',
                     text=>'Correct Problems Plot'});
               &Apache::loncorrectproblemplot::BuildCorrectProblemsPage($r,$c);
           } elsif($GoToPage eq 'student_assessment') {
               &Apache::lonhtmlcommon::clear_breadcrumbs();
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>'/adm/statistics?reportselected=student_assessment',
                     text=>'Chart'});
               &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);
           }
           #
           $r->print("</form>\n");
     }      }
     #  
     $r->print("</form>\n");  
     $r->print("</body>\n</html>\n");      $r->print("</body>\n</html>\n");
     $r->rflush();      $r->rflush();
     #      #

Removed from v.1.76  
changed lines
  Added in v.1.123


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