--- loncom/interface/lonstatistics.pm 2003/05/13 14:30:26 1.70
+++ loncom/interface/lonstatistics.pm 2005/02/01 15:15:28 1.113
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstatistics.pm,v 1.70 2003/05/13 14:30:26 matthew Exp $
+# $Id: lonstatistics.pm,v 1.113 2005/02/01 15:15:28 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -38,20 +38,6 @@ lonstatistics
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
=cut
@@ -71,19 +57,27 @@ use vars qw(
$top_map
@Sequences
@SelectedMaps
- @Assessments);
+ @Assessments
+ $enrollment_status);
use Apache::lonnet();
use Apache::lonhomework;
use Apache::loncommon;
use Apache::loncoursedata;
use Apache::lonhtmlcommon;
+use Apache::lonmysql;
+use Apache::lonlocal;
+use Time::HiRes;
+#
+# Statistics Packages
use Apache::lonproblemanalysis();
+use Apache::lonsubmissiontimeanalysis();
+use Apache::loncorrectproblemplot();
use Apache::lonproblemstatistics();
use Apache::lonstudentassessment();
use Apache::lonpercentage;
-use Apache::lonmysql;
-use Time::HiRes;
+use Apache::lonstudentsubmissions();
+use Apache::lonsurveyreports();
#######################################################
#######################################################
@@ -206,7 +200,6 @@ upon the calling context.
#######################################################
#######################################################
sub PrepareClasslist {
- my $r = shift;
my %Sections;
&clear_classlist_variables();
#
@@ -236,17 +229,17 @@ sub PrepareClasslist {
}
#
# Set up %StudentData
- @StudentDataOrder = qw/fullname username domain id section status/;
+ @StudentDataOrder = qw/fullname username domain id section status comments/;
foreach my $field (@StudentDataOrder) {
- $StudentData{$field}->{'title'} = $field;
- $StudentData{$field}->{'base_width'} = length($field);
+ $StudentData{$field}->{'title'} = &mt($field);
+ $StudentData{$field}->{'base_width'} = length(&mt($field));
$StudentData{$field}->{'width'} =
$StudentData{$field}->{'base_width'};
}
#
# get the status requested
- my $requested_status = 'Active';
- $requested_status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));
+ $enrollment_status = 'Active';
+ $enrollment_status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));
#
# Process the classlist
while (my ($student,$student_data) = each (%$classlist)) {
@@ -276,8 +269,8 @@ sub PrepareClasslist {
foreach my $sect (@SelectedSections) {
if ( (($sect eq 'all') ||
($section eq $sect)) &&
- (($studenthash->{'status'} eq $requested_status) ||
- ($requested_status eq 'Any'))
+ (($studenthash->{'status'} eq $enrollment_status) ||
+ ($enrollment_status eq 'Any'))
){
push (@Students,$studenthash);
last;
@@ -301,9 +294,10 @@ sub PrepareClasslist {
@Students = @TmpStudents;
#
# Now deal with that current student thing....
- if (exists($ENV{'form.StudentAssessmentStudent'})) {
+ $curr_student = undef;
+ if (exists($ENV{'form.SelectedStudent'})) {
my ($current_uname,$current_dom) =
- split(':',$ENV{'form.StudentAssessmentStudent'});
+ split(':',$ENV{'form.SelectedStudent'});
my $i;
for ($i = 0; $i<=$#Students; $i++) {
next if (($Students[$i]->{'username'} ne $current_uname) ||
@@ -311,15 +305,17 @@ sub PrepareClasslist {
$curr_student = $Students[$i];
last; # If we get here, we have our student.
}
- if ($i == 0) {
- $prev_student = 'none';
- } else {
- $prev_student = $Students[$i-1];
- }
- if ($i == $#Students) {
- $next_student = 'none';
- } else {
- $next_student = $Students[$i+1];
+ if (defined($curr_student)) {
+ if ($i == 0) {
+ $prev_student = undef;
+ } else {
+ $prev_student = $Students[$i-1];
+ }
+ if ($i == $#Students) {
+ $next_student = undef;
+ } else {
+ $next_student = $Students[$i+1];
+ }
}
}
#
@@ -330,7 +326,7 @@ sub PrepareClasslist {
@SelectedStudentData = ($ENV{'form.StudentData'});
}
} else {
- @SelectedStudentData = ('fullname');
+ @SelectedStudentData = ('username');
}
foreach (@SelectedStudentData) {
if ($_ eq 'all') {
@@ -342,6 +338,27 @@ sub PrepareClasslist {
return;
}
+
+#######################################################
+#######################################################
+
+=pod
+
+=item get_students
+
+Returns a list of the selected students
+
+=cut
+
+#######################################################
+#######################################################
+sub get_students {
+ if (! @Students) {
+ &PrepareClasslist()
+ }
+ return @Students;
+}
+
#######################################################
#######################################################
@@ -357,11 +374,7 @@ selected student.
#######################################################
#######################################################
sub current_student {
- if (defined($curr_student)) {
- return $curr_student;
- } else {
- return 'All Students';
- }
+ return $curr_student;
}
#######################################################
@@ -379,11 +392,7 @@ in the list of students. Or something.
#######################################################
#######################################################
sub previous_student {
- if (defined($prev_student)) {
- return $prev_student;
- } else {
- return 'No Student Selected';
- }
+ return $prev_student;
}
#######################################################
@@ -401,11 +410,7 @@ to be viewed.
#######################################################
#######################################################
sub next_student {
- if (defined($next_student)) {
- return $next_student;
- } else {
- return 'No Student Selected';
- }
+ return $next_student;
}
#######################################################
@@ -467,13 +472,22 @@ assessments.
#######################################################
#######################################################
sub Sequences_with_Assess {
+ my ($mode) = @_;
+ $mode = 'selected' if (! defined($mode));
my @Sequences_to_Show;
- 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);
+ foreach my $sequence (@Sequences) {
+ next if ($sequence->{'num_assess'} < 1);
+ if ($mode eq 'all') {
push (@Sequences_to_Show,$sequence);
+ } elsif ($mode eq 'selected') {
+ foreach my $map_symb (@SelectedMaps) {
+ if ($sequence->{'symb'} eq $map_symb || $map_symb eq 'all'){
+ push (@Sequences_to_Show,$sequence);
+ last; # Only put it in once
+ }
+ }
}
+
}
return @Sequences_to_Show;
}
@@ -502,22 +516,6 @@ sub PrepareCourseData {
$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'};
- #
- # 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*(length($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;
}
@@ -739,6 +737,7 @@ sub MapSelect {
Returns html for a selection box allowing the user to choose one (or more)
of the sections in the course.
+Uses the package variables @Sections and @SelectedSections
=over 4
=item $elementname The name of the HTML form element
@@ -747,13 +746,6 @@ of the sections in the course.
=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
@@ -766,6 +758,11 @@ sub SectionSelect {
return;
}
#
+ # Make sure we have the data we need to continue
+ if (! @Sections) {
+ &PrepareClasslist()
+ }
+ #
# Build the form element
my $Str = "\n";
$Str .= ''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 .= '
'."\n";
+ $Str .= '';
+ $Str .= ''.&mt('Sections').' ';
+ $Str .= ''.&mt('Enrollment Status').' ';
+ $Str .= ' '.$/;
+ $Str .= '';
+ $Str .= ''.
+ &Apache::lonstatistics::SectionSelect('Section','multiple',5).
+ ' ';
+ $Str .= ''.
+ &Apache::lonhtmlcommon::StatusOptions(undef,undef,5).
+ ' ';
+
+ $Str .= ' '.$/;
+ $Str .= '
';
+ $Str .= ' ';
+ $r->print($Str);
+ $r->rflush();
+ #
+ my @Fields = ('fullname','username','domain','id','section','status');
#
- my $Str='';
+ $Str = '';
+ if (! @Students) {
+ if ($SelectedSections[0] eq 'all') {
+ if (lc($ENV{'form.Status'}) eq 'any') {
+ $Str .= ''.
+ &mt('There are no students in the course.').
+ ' ';
+ } elsif (lc($ENV{'form.Status'}) eq 'active') {
+ $Str .= ''.
+ &mt('There are no currently enrolled students in the course.').
+ ' ';
+ } elsif (lc($ENV{'form.Status'}) eq 'expired') {
+ $Str .= ''.
+ &mt('There are no previously enrolled students in the course.').
+ ' ';
+ }
+ } else {
+ my $sections;
+ if (lc($ENV{'form.Status'}) eq 'any') {
+ $Str .= ''.
+ &mt('There are no students in the selected sections.').
+ ' ';
+ } elsif (lc($ENV{'form.Status'}) eq 'active') {
+ $Str .= ''.
+ &mt('There are no currently enrolled students in the selected sections.').
+ ' ';
+ } elsif (lc($ENV{'form.Status'}) eq 'expired') {
+ $Str .= ''.
+ &mt('There are no previously enrolled students in the selected sections.').
+ ' ';
+ }
+ }
+ $Str.= ''.
+ &mt('Click here to return to the chart').' ';
+ $r->print($Str);
+ $r->rflush();
+ return;
+ }
+
+ # "Click" is asinine but it is probably not my place to change the world.
+ $Str .= 'Click on a students name or username to view their chart ';
$Str .= ''."\n";
$Str .= ''."\n";
foreach my $field (@Fields) {
- $Str .= ''.$field.
+ $Str .= ' '.&mt($field).
' ';
}
$Str .= ' '."\n";
@@ -817,13 +882,16 @@ sub DisplayClasslist {
#
foreach my $field (@Fields) {
$Str .= '';
- if ($field eq 'fullname') {
+ if ($field eq 'fullname' || $field eq 'username') {
$Str .= '';
$Str .= $student->{$field}.' ';
$Str .= ' ';
+ } elsif ($field eq 'status') {
+ $Str .= &mt($student->{$field});
} else {
$Str .= $student->{$field};
}
@@ -842,36 +910,58 @@ sub DisplayClasslist {
##############################################
##############################################
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 .= ''."\n";
- $Str .= ' '."\n";
+ $Str .="\n";
#
return $Str;
}
@@ -902,93 +992,126 @@ sub handler {
}
}
#
- # 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
- $r->content_type('text/html');
+ &Apache::loncommon::no_cache($r);
+ &Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
+ if ($r->header_only) { return OK; }
#
# Extract form elements from query string
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['sort','reportSelected',
- 'StudentAssessmentStudent']);
- if (! exists($ENV{'form.reportSelected'})) {
- $ENV{'form.reportSelected'} = 'student_assessment';
- }
+ 'SelectedStudent']);
#
# Give the LON-CAPA page header
- $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));
- $r->rflush();
- #
- if (! &Apache::lonmysql::verify_sql_connection()) {
- my $serveradmin = $r->dir_config('lonAdmEMail');
- $r->print(<Unable to connect to database!
-
-Please notify the server administrator $serveradmin .
-
-Course Statistics and Charts cannot be retrieved until the database is
-restarted. Your data is intact but cannot be displayed at this time.
-
-