--- loncom/interface/lonstatistics.pm 2003/02/18 20:27:33 1.59 +++ loncom/interface/lonstatistics.pm 2003/02/25 20:47:47 1.60 @@ -1,7 +1,6 @@ # The LearningOnline Network with CAPA -# (Publication Handler # -# $Id: lonstatistics.pm,v 1.59 2003/02/18 20:27:33 matthew Exp $ +# $Id: lonstatistics.pm,v 1.60 2003/02/25 20:47:47 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,12 +25,6 @@ # http://www.lon-capa.org/ # # (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,25/7,29/7 Behrouz Minaei # ### @@ -47,18 +40,18 @@ 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 GDBM_File; + 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 GDBM_File; =over 4 @@ -79,9 +72,42 @@ use Apache::lonstudentassessment; use Apache::lonpercentage; use GDBM_File; +use vars qw/@FullClasslist @Students @Sections @SelectedSections + $curr_student $prev_student $next_student + $top_map @Sequences @Assessments /; + +####################################################### +####################################################### + +=pod + +=item Package Variables + +=item @FullClasslist The full classlist + +=item @Students The students we are concerned with for this invocation + +=item @Sections The sections available in this class + +=item $curr_student The student currently being examined + +=item $prev_student The student previous in the classlist + +=item $next_student The student next in the classlist + +=over + +=cut + +####################################################### +####################################################### +# +# Classlist variables +# my @FullClasslist; my @Students; my @Sections; +my @SelectedSections; my $curr_student; my $prev_student; my $next_student; @@ -97,17 +123,19 @@ undef the following package variables: =over -=item @FullClasslist The full classlist +=item @FullClasslist -=item @Students The students we are concerned with for this invocation +=item @Students -=item @Sections The sections available in this class +=item @Sections -=item $curr_student The student currently being examined +=item @SelectedSections -=item $prev_student The student previous in the classlist +=item $curr_student -=item $next_student The student next in the classlist +=item $prev_student + +=item $next_student =back @@ -119,6 +147,7 @@ sub clear_classlist_variables { undef(@FullClasslist); undef(@Students); undef(@Sections); + undef(@SelectedSections); undef($curr_student); undef($prev_student); undef($next_student); @@ -136,17 +165,19 @@ the following package variables: =over -=item @FullClasslist The full classlist +=item @FullClasslist -=item @Students The students we are concerned with for this invocation +=item @Students -=item @Sections The sections available in this class +=item @Sections -=item $curr_student The student currently being examined +=item @SelectedSections -=item $prev_student The student previous in the classlist +=item $curr_student -=item $next_student The student next in the classlist +=item $prev_student + +=item $next_student =back @@ -168,16 +199,22 @@ sub PrepareClasslist { my $cnum = $ENV{'course.'.$cid.'.num'}; my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid, $cdom,$cnum); - my %valid_section; - if (exists($ENV{'form.Section'}) && $ENV{'form.Section'} !~ /(all|any)/) { + if (exists($ENV{'form.Section'})) { if (ref($ENV{'form.Section'})) { - foreach (@$ENV{'form.section'}) { - $valid_section{$_}++; + @SelectedSections = @$ENV{'form.Section'}; + # Remove the empty sections + for (my $i=0; $i<=$#SelectedSections; $i++) { + if ($SelectedSections[$i] =~ /^\s*$/) { + splice(@SelectedSections,$i,1); + } } } else { - $valid_section{$_}++; + if ($ENV{'form.Section'} !~ /^\s*$/) { + @SelectedSections = ($ENV{'form.Section'}); + } } } + @SelectedSections = ('any') if (! @SelectedSections); # # Process the classlist while (my ($student,$student_data) = each (%$classlist)) { @@ -189,24 +226,31 @@ sub PrepareClasslist { # # Build up a list of sections my $section = $studenthash->{'section'}; - $section = 'no section' if (! defined($section) || $section =~/^\s*/ ); + if (! defined($section) || $section =~/^\s*$/ || $section == -1) { + $studenthash->{'section'} = 'none'; + $section = $studenthash->{'section'}; + } $Sections{$section}++; # # Only put in the list those students we are interested in - if (defined($ENV{'form.Section'}) && - $ENV{'form.Section'} !~ /(all|any)/ && - ! exists($valid_section{$section})) { - next; + foreach my $sect (@SelectedSections) { + if (($sect eq 'any') || ($section eq $sect)) { + push (@Students,$studenthash); + last; + } } - push (@Students,$studenthash); } # # Put the consolidated section data in the right place - @Sections = sort {$a<=>$b} keys(%Sections); + @Sections = sort {$a cmp $b} keys(%Sections); # # Sort the Students my $sortby = 'fullname'; - @Students = sort {$a->{$sortby} <=> $b->{$sortby}} @Students; + $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'})); + my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} || + $a->{'fullname'} cmp $b->{'fullname'} } @Students; + + @Students = @TmpStudents; # # Now deal with that current student thing.... if (exists($ENV{'form.StudentAssessmentStudent'})) { @@ -216,6 +260,7 @@ sub PrepareClasslist { for ($i = 0; $i<=$#Students; $i++) { next if (($Students[$i]->{'username'} ne $current_uname) || ($Students[$i]->{'domain'} ne $current_dom)); + $curr_student = $Students[$i]; last; # If we get here, we have our student. } if ($i == 0) { @@ -233,6 +278,227 @@ sub PrepareClasslist { ####################################################### ####################################################### +# +# Course Sequences variables +# +my $top_map; +my @Sequences; +my @Assessments; + +####################################################### +####################################################### + +=pod + +=item &clear_sequence_variables() + +=cut + +####################################################### +####################################################### +sub clear_sequence_variables { + undef($top_map); + undef(@Sequences); + undef(@Assessments); +} + +####################################################### +####################################################### + +=pod + +=item &PrepareCourseData($r) + +=cut + +####################################################### +####################################################### +sub PrepareCourseData { + my ($r) = @_; + &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 'HASH'); + +=pod + + ## + ## Debugging code + ## + foreach my $s (@Sequences) { + next if ($s->{'title'} ne 'Bioenergetics: Enzyme Regulation'); + &Apache::lonnet::logthis('-----------------------------------'); + &Apache::lonnet::logthis('title = '.$s->{'title'}); + &Apache::lonnet::logthis('symb = '.$s->{'symb'}); + &Apache::lonnet::logthis('num_assess = '.$s->{'num_assess'}); + foreach my $a (@{$s->{'contents'}}) { + &Apache::lonnet::logthis(' --------------------------------'); + &Apache::lonnet::logthis(' title = '.$a->{'title'}); + &Apache::lonnet::logthis(' symb = '.$a->{'symb'}); + } + } + +=cut + + return; +} + +############################################## +############################################## + +=pod + +=item &MapSelect($elementname,$status,$numvisible,$selected,$restriction) + +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. +If the top sequence is selected, the value 'top' will result. + +=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 + +=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 +false. The code must expect a reference to a sequence data structure. + +=back + +=cut + +############################################## +############################################## +sub MapSelect { + my ($elementname,$status,$numvisible,$selected,$restriction)=@_; + if ($numvisible < 1) { + return; + } + # + # Set up array of selected items + my @Selected; + 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 + if (! defined($restriction)) { + $restriction = sub { 1; }; + } + # + # Build the form element + my $Str = "\n"; + $Str .= '\n"; + return $Str; +} + + +############################################## +############################################## + +=pod + +=item &SectionSelect($elementname,$status,$numvisible) + +Returns html for a selection box allowing the user to choose one (or more) +of the sections in the course. + +=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 + +=item $selected Array ref to the names of the already selected sections. +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 +false. The code must expect a reference to a sequence data structure. + +=back + +=cut + +############################################## +############################################## +sub SectionSelect { + my ($elementname,$status,$numvisible)=@_; + if ($numvisible < 1) { + return; + } + # + # Build the form element + my $Str = "\n"; + $Str .= '\n"; + return $Str; +} + +############################################## +############################################## sub CheckFormElement { my ($cache, $ENVName, $cacheName, $default)=@_; @@ -241,8 +507,9 @@ sub CheckFormElement { $cache->{$cacheName} = $ENV{'form.'.$ENVName}; } elsif(!defined($cache->{$cacheName})) { $cache->{$cacheName} = $default; + } else { + $ENV{'form.'.$ENVName} = $cache->{$cacheName}; } - return; } @@ -252,7 +519,7 @@ sub ProcessFormData{ $cache->{'reportKey'} = 'false'; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['sort','download', + ['download', 'reportSelected', 'StudentAssessmentStudent', 'ProblemStatisticsSort']); @@ -598,6 +865,54 @@ sub PrepareData { return ('OK', $students); } +sub DisplayClasslist { + my ($r)=@_; + # + my @Fields = ('fullname','username','domain','id','section'); + # + my $Str=''; + $Str .= '
'."\n"; + $Str .= ''."\n"; + foreach my $field (@Fields) { + $Str .= ''; + } + $Str .= ''."\n"; + # + my $alternate = 0; + foreach my $student (@Students) { + my $sname = $student->{'username'}.':'.$student->{'domain'}; + if($alternate) { + $Str .= ''; + } else { + $Str .= ''; + } + $alternate = ($alternate + 1) % 2; + # + foreach my $field (@Fields) { + $Str .= ''; + } + $Str .= "\n"; + } + $Str .= '
'.$field. + '
'; + if ($field eq 'fullname') { + $Str .= ''; + $Str .= $student->{$field}.' '; + $Str .= ''; + } else { + $Str .= $student->{$field}; + } + $Str .= '
'."\n"; + # + $r->print($Str); + $r->rflush(); + # + return; +} + sub BuildClasslist { my ($cacheDB,$students,$studentInformation,$headings,$r)=@_; @@ -806,8 +1121,9 @@ sub BuildStatistics { $students, $courseID, $r, $c); } elsif($GoToPage eq 'Class list') { - &BuildClasslist($cacheDB, $students, \@studentInformation, - \@headings, $r); + &DisplayClasslist($r); +# &BuildClasslist($cacheDB, $students, \@studentInformation, +# \@headings, $r); } elsif($GoToPage eq 'Correct-problems Plot') { &Apache::lonpercentage::BuildPercentageGraph($cacheDB, $students, $courseID, $c, $r); @@ -861,8 +1177,13 @@ sub handler { $r->content_type('text/html'); $r->send_http_header; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['sort']); + &PrepareClasslist($r); + &PrepareCourseData($r); + &BuildStatistics($r); return OK;