[LON-CAPA-cvs] cvs: loncom /interface lonstatistics.pm
matthew
lon-capa-cvs@mail.lon-capa.org
Fri, 28 Feb 2003 20:50:33 -0000
This is a MIME encoded message
--matthew1046465433
Content-Type: text/plain
matthew Fri Feb 28 15:50:33 2003 EDT
Modified files:
/loncom/interface lonstatistics.pm
Log:
Many changes.
&PrepareClasslist - big changes related to keeping track of column widths
and sections.
&SetSelectedMaps - Added.
&PrepareCourseData - Fixed bug with @Assessments. Now compute column widths.
&log_sequence - Added. Debugging routine, dumps a sequence data structure to
logfile
&StudentDataSelect - Added. For presenting a multi-select box for student
data.
&MapSelect - now deals with 'all'. Changed variable $s to $seq.
--matthew1046465433
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20030228155033.txt"
Index: loncom/interface/lonstatistics.pm
diff -u loncom/interface/lonstatistics.pm:1.60 loncom/interface/lonstatistics.pm:1.61
--- loncom/interface/lonstatistics.pm:1.60 Tue Feb 25 15:47:47 2003
+++ loncom/interface/lonstatistics.pm Fri Feb 28 15:50:33 2003
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstatistics.pm,v 1.60 2003/02/25 20:47:47 matthew Exp $
+# $Id: lonstatistics.pm,v 1.61 2003/02/28 20:50:33 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -61,20 +61,30 @@
use strict;
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::lonhomework;
use Apache::loncommon;
use Apache::loncoursedata;
use Apache::lonhtmlcommon;
-use Apache::lonproblemanalysis;
-use Apache::lonproblemstatistics;
-use Apache::lonstudentassessment;
+use Apache::lonproblemanalysis();
+use Apache::lonproblemstatistics();
+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 /;
#######################################################
#######################################################
@@ -104,10 +114,6 @@
#
# Classlist variables
#
-my @FullClasslist;
-my @Students;
-my @Sections;
-my @SelectedSections;
my $curr_student;
my $prev_student;
my $next_student;
@@ -131,6 +137,12 @@
=item @SelectedSections
+=item %StudentData
+
+=item @StudentDataOrder
+
+=item @SelectedStudentData
+
=item $curr_student
=item $prev_student
@@ -148,6 +160,8 @@
undef(@Students);
undef(@Sections);
undef(@SelectedSections);
+ undef(%StudentData);
+ undef(@SelectedStudentData);
undef($curr_student);
undef($prev_student);
undef($next_student);
@@ -173,6 +187,10 @@
=item @SelectedSections
+=item %StudentData
+
+=item @SelectedStudentData
+
=item $curr_student
=item $prev_student
@@ -201,26 +219,42 @@
$cdom,$cnum);
if (exists($ENV{'form.Section'})) {
if (ref($ENV{'form.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 {
- if ($ENV{'form.Section'} !~ /^\s*$/) {
- @SelectedSections = ($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');
}
}
- @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
while (my ($student,$student_data) = each (%$classlist)) {
my $studenthash = ();
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);
#
@@ -234,7 +268,7 @@
#
# Only put in the list those students we are interested in
foreach my $sect (@SelectedSections) {
- if (($sect eq 'any') || ($section eq $sect)) {
+ if (($sect eq 'all') || ($section eq $sect)) {
push (@Students,$studenthash);
last;
}
@@ -243,13 +277,13 @@
#
# Put the consolidated section data in the right place
@Sections = sort {$a cmp $b} keys(%Sections);
+ unshift(@Sections,'all'); # Put 'all' at the front of the list
#
# Sort the Students
my $sortby = 'fullname';
$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....
@@ -274,16 +308,91 @@
$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
-#
-my $top_map;
-my @Sequences;
-my @Assessments;
+
+=pod
+
+=item ¤t_student()
+
+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';
+ }
+}
#######################################################
#######################################################
@@ -307,6 +416,32 @@
=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)
=cut
@@ -316,7 +451,8 @@
sub PrepareCourseData {
my ($r) = @_;
&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)) {
# There has been an error, better report it
&Apache::lonnet::logthis('top is undefined');
@@ -324,29 +460,148 @@
}
$top_map = $top if (ref($top));
@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
- ##
- ## 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'});
+=item &log_sequence($sequence,$recursive,$padding)
+
+Write data about the sequence to a logfile. If $recursive is not
+undef the data is written recursively. $padding is used for recursive
+calls.
+
+=cut
+
+#######################################################
+#######################################################
+sub log_sequence {
+ my ($seq,$recursive,$padding) = @_;
+ $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
- 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;
}
##############################################
@@ -354,7 +609,7 @@
=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)
of the sequences in the course. The values of the sequences are the symbs.
@@ -368,10 +623,6 @@
=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.
@@ -382,30 +633,13 @@
##############################################
##############################################
sub MapSelect {
- my ($elementname,$status,$numvisible,$selected,$restriction)=@_;
+ my ($elementname,$status,$numvisible,$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);
- }
- }
+ &SetSelectedMaps($elementname);
#
# Set up the restriction call
if (! defined($restriction)) {
@@ -420,23 +654,40 @@
}
$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
- foreach my $s (@Sequences) {
- next if (! $restriction->($s));
- $Str .= ' <option value="'.$s->{'symb'}.'" ';
- foreach (@Selected) {
- if ($s->{'symb'} eq $_) {
+ foreach my $seq (@Sequences) {
+ next if (! $restriction->($seq));
+ $Str .= ' <option value="'.$seq->{'symb'}.'" ';
+ foreach (@SelectedMaps) {
+ if ($seq->{'symb'} eq $_) {
$Str .= 'selected ';
last;
}
}
- $Str .= '>'.$s->{'title'}."</option>\n";
+ $Str .= '>'.$seq->{'title'}."</option>\n";
}
$Str .= "</select>\n";
return $Str;
}
-
##############################################
##############################################
@@ -486,7 +737,7 @@
foreach my $s (@Sections) {
$Str .= ' <option value="'.$s.'" ';
foreach (@SelectedSections) {
- if ($s eq $_ || $_ =~ /^(any|all)$/) {
+ if ($s eq $_) {
$Str .= 'selected ';
last;
}
@@ -666,6 +917,9 @@
return;
}
+##################################################
+##################################################
+
=pod
=item &SortStudents()
@@ -895,7 +1149,7 @@
$Str .= '<a href="/adm/statistics?reportSelected=';
$Str .= &Apache::lonnet::escape('Student Assessment');
$Str .= '&StudentAssessmentStudent=';
- $Str .= &Apache::lonnet::escape($student->{$field}).'">';
+ $Str .= &Apache::lonnet::escape($sname).'">';
$Str .= $student->{$field}.' ';
$Str .= '</a>';
} else {
@@ -1178,7 +1432,8 @@
$r->send_http_header;
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['sort']);
+ ['sort',
+ 'StudentAssessmentStudent']);
&PrepareClasslist($r);
--matthew1046465433--