--- loncom/interface/statistics/lonstudentassessment.pm 2003/01/09 16:37:48 1.26 +++ loncom/interface/statistics/lonstudentassessment.pm 2003/03/03 19:28:29 1.31 @@ -1,7 +1,6 @@ # The LearningOnline Network with CAPA -# (Publication Handler # -# $Id: lonstudentassessment.pm,v 1.26 2003/01/09 16:37:48 minaeibi Exp $ +# $Id: lonstudentassessment.pm,v 1.31 2003/03/03 19:28:29 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,388 +24,623 @@ # 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,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; use strict; +use Apache::lonstatistics; use Apache::lonhtmlcommon; use Apache::loncoursedata; -use GDBM_File; +use Apache::lonnet; # for logging porpoises +use Spreadsheet::WriteExcel; -#my $jr; +####################################################### +####################################################### +=pod -sub BuildStudentAssessmentPage { - my ($cacheDB,$students,$courseID,$formName,$headings,$spacing, - $studentInformation,$r,$c)=@_; -# $jr = $r; - my %cache; - unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) { - $r->print('Unable to tie database.'); - return; - } +=item Package Variables - # Remove students who don't have the proper section. - my @sectionsSelected = split(':',$cache{'sectionsSelected'}); - for(my $studentIndex=((scalar @$students)-1); $studentIndex>=0; - $studentIndex--) { - my $value = $cache{$students->[$studentIndex].':section'}; - my $found = 0; - foreach (@sectionsSelected) { - if($_ eq 'none') { - if($value eq '' || !defined($value) || $value eq ' ') { - $found = 1; - last; - } - } else { - if($value eq $_) { - $found = 1; - last; - } - } - } - if($found == 0) { - splice(@$students, $studentIndex, 1); - } - } - my ($infoHeadings, $infoKeys, $sequenceHeadings, $sequenceKeys, - $doNotShow) = - &ShouldShowColumns(\%cache, $headings, $studentInformation); - - my $selectedName = &FindSelectedStudent(\%cache, - $cache{'StudentAssessmentStudent'}, - $students); - $r->print(&CreateInterface(\%cache, $selectedName, $students, $formName, - $doNotShow)); - $r->rflush(); +=over 4 - my $Str = ''; - if($selectedName eq 'No Student Selected') { - $Str .= '

WARNING: '; - $Str .= 'Please select a student

'; - $r->print($Str); +=item $Statistics Hash ref to store student data. Indexed by symb, + contains hashes with keys 'score' and 'max'. + +=cut + +####################################################### +####################################################### + +my $Statistics; + +####################################################### +####################################################### + +=pod + +=item $show_links 'yes' or 'no' for linking to student performance data + +=item $output_mode 'html', 'excel', or 'csv' for output mode + +=item $show 'all' or 'totals' determines how much data is output + +=cut + +####################################################### +####################################################### +my $show_links; +my $output_mode; +my $show; + +####################################################### +####################################################### +# End of package variable declarations + +=pod + +=back + +=cut + +####################################################### +####################################################### + +=pod + +=item &BuildStudentAssessmentPage() + +Inputs: + +=over 4 + +=item $r Apache Request + +=item $c Apache Connection + +=back + +=cut + +####################################################### +####################################################### +sub BuildStudentAssessmentPage { + my ($r,$c)=@_; + undef($Statistics); + # + # Print out the HTML headers for the interface + # This also parses the output mode selector + # This step must always be done. + $r->print(&CreateInterface()); + $r->print(''); + $r->rflush(); + if (! exists($ENV{'form.notfirstrun'})) { + $r->print(< + +Please make your selections in the boxes above and hit +the button marked "Update Display". + +

+ENDMSG return; } + # + # + my $initialize = \&html_initialize; + my $output_student = \&html_outputstudent; + my $finish = \&html_finish; + # + if ($output_mode eq 'excel') { + $initialize = \&excel_initialize; + $output_student = \&excel_outputstudent; + $finish = \&excel_finish; + } elsif ($output_mode eq 'csv') { + $initialize = \&csv_initialize; + $output_student = \&csv_outputstudent; + $finish = \&csv_finish; + } + # + if($c->aborted()) { return ; } + # + # Call the initialize routine selected above + $initialize->($r); + foreach my $student (@Apache::lonstatistics::Students) { + if($c->aborted()) { + $finish->($r); + return ; + } + # Call the output_student routine selected above + $output_student->($r,$student); + } + # Call the "finish" routine selected above + $finish->($r); + # + return; +} - $r->print(&CreateTableHeadings(\%cache, $spacing, $infoKeys, $infoHeadings, - $sequenceKeys, $sequenceHeadings)); - untie(%cache); - if($c->aborted()) { return $Str; } - - my $selected=0; - my $Count = 0; - $r->print('
'."\n");
-    foreach (@$students) {
-        if($c->aborted()) { return $Str; }
-        next if ($_ ne $selectedName &&
-                 $selectedName ne 'All Students');
-        $selected = 1;
-
-        my @who = ($_);
-        next if(&Apache::loncoursedata::DownloadStudentCourseData(\@who, 'true',
-                                                             $cacheDB, 'true',
-                                                             'false', $courseID,
-                                                             $r, $c) ne 'OK');
-        next if($c->aborted());
-
-        if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
-            my @before=();
-            my @after=();
-            my @updateColumn=();
-            my $foundUpdate = 0;
-            foreach(@$infoKeys) {
-                if(/updateTime/) {
-                    $foundUpdate=1;
-                    push(@updateColumn, $_);
-                    next;
-                }
-                if($foundUpdate) {
-                    push(@after, $_);
-                } else {
-                    push(@before, $_);
-                }
-            }
-            $Count++;
-	    my $out = '';
-#	    $out .= sprintf("%3d", $Count);
-            if($Count % 2) {
-                $out .= '';
-            } else {
-                $out .= '';
-            }
-	    my $displayString = $out.'DISPLAYDATA'.$spacing;
-	    $r->print(&Apache::lonhtmlcommon::FormatStudentInformation(
-                                                         \%cache, $_,
-                                                         \@before,
-                                                         $displayString,
-                                                         'preformatted'));
-
-            if($foundUpdate) {
-                $displayString = '';
-                $displayString .= '';
-                $displayString .= 'DISPLAYDATA'.$spacing;
-                $r->print(&Apache::lonhtmlcommon::FormatStudentInformation(
-                                                                   \%cache, $_,
-                                                                   \@updateColumn,
-                                                                   $displayString,
-                                                                   'preformatted'));
-            }
+#######################################################
+#######################################################
 
-            $displayString = 'DISPLAYDATA'.$spacing;
-            $r->print(&Apache::lonhtmlcommon::FormatStudentInformation(
-                                                         \%cache, $_,
-                                                         \@after,
-                                                         $displayString,
-                                                         'preformatted'));
-            $r->print(&StudentReport(\%cache, $_, $spacing, $sequenceKeys));
-            $r->print("\n");
-            $r->rflush();
-            untie(%cache);
+sub get_student_fields_to_show {
+    my @to_show = @Apache::lonstatistics::SelectedStudentData;
+    foreach (@to_show) {
+        if ($_ eq 'all') {
+            @to_show = @Apache::lonstatistics::StudentDataOrder;
+            last;
         }
     }
-    $r->print('
'."\n"); - if($selected == 0) { - $Str .= '

WARNING: '; - $Str .= 'No Students enrolled OR Please select a student

'; - $r->print($Str); - } else { - if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) { - $r->print(&StudentAverageTotal(\%cache, $students, $sequenceKeys)); - untie(%cache); - } + return @to_show; +} + +sub get_sequences_to_show { + my @Sequences; + foreach my $map_symb (@Apache::lonstatistics::SelectedMaps) { + foreach my $sequence (@Apache::lonstatistics::Sequences) { + next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all'); + next if ($sequence->{'num_assess'} < 1); + push (@Sequences,$sequence); + } } - return; + return @Sequences; } +####################################################### +####################################################### +=pod -#---- Student Assessment Web Page -------------------------------------------- +=item &CreateInterface() -sub CreateInterface { - my($cache,$selectedName,$students,$formName,$doNotShow)=@_; +Called by &BuildStudentAssessmentPage to create the top part of the +page which displays the chart. - my $Str = ''; - $Str .= &CreateLegend(); - $Str .= '
'."\n"; - $Str .= '{'sectionList'}); - my @selectedSections = split(':',$cache->{'sectionsSelected'}); - $Str .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections, - \@selectedSections, - 'Statistics'); + $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5); $Str .= ''; - $Str .= &CreateColumnSelectionBox($doNotShow); + my $only_seq_with_assessments = sub { + my $s=shift; + if ($s->{'num_assess'} < 1) { + return 0; + } else { + return 1; + } + }; + $Str .= &Apache::lonstatistics::StudentDataSelect('StudentData','multiple', + 5,undef); $Str .= ''."\n"; - $Str .= '[0]; + } else { + $selected = $ENV{'form.'.$elementname}; + } + } + # + # Set package variables describing output mode + $show_links = 'no'; + $output_mode = 'html'; + $show = 'all'; + my ($mode,$restriction) = split(',',$selected); + $restriction =~ s/^\s*//; + if ($mode =~ /^(html|excel|csv)$/) { + $output_mode = $mode; } else { - $Str .= 'value="Display with links" />'; + $output_mode = 'html'; } - $Str .= "\n"; - $Str .= '
'."\n"; - + if ($restriction eq 'with links') { + $show_links = 'yes'; + } else { + $show_links = 'no'; + } + if ($restriction eq 'totals only') { + $show = 'totals'; + } else { + $show = 'everything'; + } + # + # Build the form element + $Str = qq/{'count'}; $index++) { - my $name = $doNotShow->{$index.':name'}; - $notThere .= ''."\n"; - } - - $notThere .= ''; - - return $notThere; -} - -=pod - -=item &CreateColumnSelectors() - -This function generates the checkboxes above the column headings. The -column will be removed if the checkbox is unchecked. - -=over 4 - -Input: $CacheData, $headings - -$CacheData: A pointer to a hash tied to the cached data - -$headings: An array of the names of the columns for the student -information. They are used to know what are the student information columns - -Output: $present - -$present: The string contains the first row of a table. Each column contains -a checkbox which is left justified. Currently left justification is used -for consistency of location over the column in which it presides. - -=back - -=cut - -sub CreateColumnSelectors { - my ($infoHeadings, $sequenceHeadings, $sequenceKeys)=@_; - - my $present = ''; - for(my $index=0; $index<(scalar @$infoHeadings); $index++) { - $present .= ''; - $present .= '[$index].'" />'; - $present .= ''."\n"; - } - - for(my $index=0; $index<(scalar @$sequenceHeadings); $index++) { - $present .= ''; - $present .= '[$index].'" />'; - $present .= ''."\n"; - } - - return $present; -} - -#---- END Student Assessment Web Page ---------------------------------------- - -#---- Student Assessment Worker Functions ------------------------------------ - -sub FindSelectedStudent { - my($cache, $selectedName, $students)=@_; - - if($selectedName eq 'All Students' || - $selectedName eq 'No Student Selected') { - return $selectedName; - } - - for(my $index=0; $index<(scalar @$students); $index++) { - my $fullname = $cache->{$students->[$index].':fullname'}; - if($fullname eq $selectedName) { - if($cache->{'StudentAssessmentMove'} eq 'next') { - if($index == ((scalar @$students) - 1)) { - $selectedName = $students->[0]; - return $selectedName; - } else { - $selectedName = $students->[$index+1]; - return $selectedName; - } - } elsif($cache->{'StudentAssessmentMove'} eq 'previous') { - if($index == 0) { - $selectedName = $students->[-1]; - return $selectedName; - } else { - $selectedName = $students->[$index-1]; - return $selectedName; - } - } else { - $selectedName = $students->[$index]; - return $selectedName; - } - last; - } - } - - return 'No Student Selected'; -} - -=pod - -=item &ShouldShowColumn() - -Determine if a specified column should be shown on the chart. - -=over 4 - -Input: $cache, $test - -$cache: A pointer to the hash tied to the cached data - -$test: The form name of the column (heading.$headingIndex) or -(sequence.$sequenceIndex) - -Output: 0 (false), 1 (true) - -=back - -=cut - -sub ShouldShowColumns { - my ($cache,$headings,$cacheKey)=@_; - - my @infoKeys=(); - my @infoHeadings=(); - - my @sequenceKeys=(); - my @sequenceHeadings=(); - - my %doNotShow; - - my $index; - my $count = 0; - my $check = ''; - for($index=0; $index < scalar @$headings; $index++) { - $check = 'HeadingColumn'.$headings->[$index]; - if($cache->{'HeadingsFound'} =~ /$check/) { - push(@infoHeadings, $headings->[$index]); - push(@infoKeys, $cacheKey->[$index]); - } else { - $doNotShow{$count.':name'} = $headings->[$index]; - $doNotShow{$count.':id'} = 'HeadingColumn'.$headings->[$index]; - $count++; - } - } - - foreach my $sequence (split(/\:/,$cache->{'orderedSequences'})) { - $check = 'SequenceColumn'.$sequence; - if($cache->{'SequencesFound'} eq 'All Sequences' || - $cache->{'SequencesFound'} =~ /$check/) { - push(@sequenceHeadings, $cache->{$sequence.':title'}); - push(@sequenceKeys, $sequence); - } else { - $doNotShow{$count.':name'} = $cache->{$sequence.':title'}; - $doNotShow{$count.':id'} = 'SequenceColumn'.$sequence; - $count++; - } - } - - $doNotShow{'count'} = $count; - - return (\@infoHeadings, \@infoKeys, \@sequenceHeadings, - \@sequenceKeys, \%doNotShow); -} - -#---- END Student Assessment Worker Functions -------------------------------- +####################################################### +####################################################### 1; + __END__