--- loncom/interface/statistics/lonstudentassessment.pm 2005/01/14 21:15:09 1.109
+++ loncom/interface/statistics/lonstudentassessment.pm 2005/04/07 07:34:52 1.122
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonstudentassessment.pm,v 1.109 2005/01/14 21:15:09 matthew Exp $
+# $Id: lonstudentassessment.pm,v 1.122 2005/04/07 07:34:52 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -56,6 +56,7 @@ use Apache::loncommon();
use Apache::loncoursedata;
use Apache::lonnet; # for logging porpoises
use Apache::lonlocal;
+use Time::HiRes;
use Spreadsheet::WriteExcel;
use Spreadsheet::WriteExcel::Utility();
@@ -152,10 +153,10 @@ sub BuildStudentAssessmentPage {
&Apache::lonstatistics::PrepareClasslist();
#
$single_student_mode = 0;
- $single_student_mode = 1 if ($ENV{'form.SelectedStudent'});
+ $single_student_mode = 1 if ($env{'form.SelectedStudent'});
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['selectstudent']);
- if ($ENV{'form.selectstudent'}) {
+ if ($env{'form.selectstudent'}) {
&Apache::lonstatistics::DisplayClasslist($r);
return;
}
@@ -166,12 +167,15 @@ sub BuildStudentAssessmentPage {
$r->print(&CreateInterface());
$r->print('');
$r->print('');
+ $env{'form.sort'}.'" />');
$r->rflush();
#
- if (! exists($ENV{'form.notfirstrun'}) && ! $single_student_mode) {
+ if (! exists($env{'form.notfirstrun'}) && ! $single_student_mode) {
return;
}
+ $r->print('
'."\n";
$Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
$Str .= ' | ';
- 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 .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
$Str .= ' | '."\n";
- $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
- $only_seq_with_assessments);
+ $Str .= &Apache::lonstatistics::map_select('Maps','multiple,all',5);
$Str .= ' | '."\n";
$Str .= &CreateAndParseOutputSelector();
$Str .= ' | '."\n";
@@ -435,14 +430,9 @@ sub CreateAndParseOutputSelector {
[$elementname]);
#
# Format for output options is 'mode, restrictions';
- my $selected = 'html, without links';
- if (exists($ENV{'form.'.$elementname})) {
- if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
- $selected = $ENV{'form.'.$elementname}->[0];
- } else {
- $selected = $ENV{'form.'.$elementname};
- }
- }
+ my $selected = (&Apache::loncommon::get_env_multiple('form.'.$elementname))[0];
+ $selected = 'html, without links' if (!$selected);
+
#
# Set package variables describing output mode
$show_links = 'no';
@@ -556,14 +546,9 @@ sub CreateAndParseOutputDataSelector {
my $Str = '';
my $elementname = 'chartoutputdata';
#
- my $selected = 'scores';
- if (exists($ENV{'form.'.$elementname})) {
- if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
- $selected = $ENV{'form.'.$elementname}->[0];
- } else {
- $selected = $ENV{'form.'.$elementname};
- }
- }
+ my $selected = (&Apache::loncommon::get_env_multiple('form.'.$elementname))[0];
+ $selected = 'scores' if (!$selected);
+
#
$chosen_output = $OutputDataOptions[0];
foreach my $option (@OutputDataOptions) {
@@ -586,6 +571,26 @@ sub CreateAndParseOutputDataSelector {
#######################################################
#######################################################
+sub count_parts {
+ my ($navmap,$sequence) = @_;
+ my @resources = &get_resources($navmap,$sequence);
+ my $count = 0;
+ foreach my $res (@resources) {
+ $count += scalar(@{$res->parts});
+ }
+ return $count;
+}
+
+sub get_resources {
+ my ($navmap,$sequence) = @_;
+ my @resources = $navmap->retrieveResources($sequence,
+ sub { shift->is_problem(); },
+ 0,0,0);
+ return @resources;
+}
+
+#######################################################
+#######################################################
=pod
@@ -613,6 +618,10 @@ Return a line of the chart for a student
my %prog_state; # progress state used by loncommon PrgWin routines
my $total_sum_width;
+ my %width; # Holds sequence width information
+ my @sequences;
+ my $navmap; # Have to keep this around since weakref is a bit zealous
+
sub html_initialize {
my ($r) = @_;
#
@@ -620,10 +629,22 @@ sub html_initialize {
$count = 0;
$nodata_count = 0;
undef(%prog_state);
+ undef(%width);
#
- $r->print("".$ENV{'course.'.$ENV{'request.course.id'}.'.description'}.
+ undef($navmap);
+ undef(@sequences);
+ ($navmap,@sequences) =
+ &Apache::lonstatistics::selected_sequences_with_assessments();
+ if (! ref($navmap)) {
+ # Unable to get data, so bail out
+ $r->print("".
+ &mt('Unable to retrieve course information.').
+ '');
+ }
+ #
+ $r->print("".$env{'course.'.$env{'request.course.id'}.'.description'}.
" ".localtime(time)."");
-
+ #
if ($chosen_output->{'base'} !~ /^final table/) {
$r->print("".$chosen_output->{'shortdesc'}."");
}
@@ -639,45 +660,50 @@ sub html_initialize {
#
# Compute the column widths and output the sequence titles
my $total_count;
- foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()){
- #
- # Comptue column widths
- $sequence->{'width_sum'} = 0;
+ #
+ # Compute sequence widths
+ my $starttime = Time::HiRes::time;
+ foreach my $seq (@sequences) {
+ my $symb = $seq->symb;
+ my $title = $seq->compTitle;
+ $width{$symb}->{'width_sum'} = 0;
+ # Compute width of sum
if ($chosen_output->{'sequence_sum'}) {
if ($chosen_output->{'every_problem'}) {
# Use 1 digit for a space
- $sequence->{'width_sum'} += 1;
+ $width{$symb}->{'width_sum'} += 1;
}
- $total_count += $sequence->{'num_assess_parts'};
+ $total_count += &count_parts($navmap,$seq);
# Use 3 digits for the sum
- $sequence->{'width_sum'} += 3;
+ $width{$symb}->{'width_sum'} += 3;
}
+ # Compute width of maximum
if ($chosen_output->{'sequence_max'}) {
- if ($sequence->{'width_sum'}>0) {
+ if ($width{$symb}->{'width_sum'}>0) {
# One digit for the '/'
- $sequence->{'width_sum'} +=1;
+ $width{$symb}->{'width_sum'} +=1;
}
# Use 3 digits for the total
- $sequence->{'width_sum'}+=3;
+ $width{$symb}->{'width_sum'}+=3;
}
#
if ($chosen_output->{'every_problem'}) {
# one problem per digit
- $sequence->{'width_problem'} = $sequence->{'num_assess_parts'};
+ $width{$symb}->{'width_parts'}= &count_parts($navmap,$seq);
+ $width{$symb}->{'width_problem'} += $width{$symb}->{'width_parts'};
} else {
- $sequence->{'width_problem'} = 0;
+ $width{$symb}->{'width_problem'} = 0;
}
- $sequence->{'width_total'} = $sequence->{'width_problem'} +
- $sequence->{'width_sum'};
- if ($sequence->{'width_total'} < length(&HTML::Entities::decode($sequence->{'title'}))) {
- $sequence->{'width_total'} = length(&HTML::Entities::decode($sequence->{'title'}));
+ $width{$symb}->{'width_total'} = $width{$symb}->{'width_problem'} +
+ $width{$symb}->{'width_sum'};
+ if ($width{$symb}->{'width_total'} < length(&HTML::Entities::decode($title))) {
+ $width{$symb}->{'width_total'} = length(&HTML::Entities::decode($title));
}
#
# Output the sequence titles
- $Str .=
- $sequence->{'title'}.' 'x($sequence->{'width_total'}-
- length($sequence->{'title'})
- ).$padding;
+ $Str .= $title.(' 'x($width{$symb}->{'width_total'}-
+ length($title)
+ )).$padding;
}
$total_sum_width = length($total_count)+1;
$Str .= " total\n";
@@ -690,6 +716,7 @@ sub html_initialize {
sub html_outputstudent {
my ($r,$student) = @_;
my $Str = '';
+ return if (! defined($navmap));
#
if($count++ % 5 == 0 && $count > 0) {
$r->print("");
@@ -710,7 +737,7 @@ sub html_outputstudent {
my %StudentsData;
my @tmp = &Apache::loncoursedata::get_current_state
($student->{'username'},$student->{'domain'},undef,
- $ENV{'request.course.id'});
+ $env{'request.course.id'});
if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
%StudentsData = @tmp;
}
@@ -725,23 +752,26 @@ sub html_outputstudent {
# By sequence build up the data
my $studentstats;
my $PerformanceStr = '';
- foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+ foreach my $seq (@sequences) {
+ my $symb = $seq->symb;
my ($performance,$performance_length,$score,$seq_max,$rawdata);
if ($chosen_output->{'tries'}) {
($performance,$performance_length,$score,$seq_max,$rawdata) =
- &StudentTriesOnSequence($student,\%StudentsData,
- $seq,$show_links);
+ &student_tries_on_sequence($student,\%StudentsData,
+ $navmap,$seq,$show_links);
} else {
($performance,$performance_length,$score,$seq_max,$rawdata) =
- &StudentPerformanceOnSequence($student,\%StudentsData,
- $seq,$show_links);
+ &student_performance_on_sequence($student,\%StudentsData,
+ $navmap,$seq,$show_links);
}
my $ratio='';
- if ($chosen_output->{'every_problem'}) {
+ if ($chosen_output->{'every_problem'} &&
+ $chosen_output->{'sequence_sum'}) {
$ratio .= ' ';
}
if ($chosen_output->{'sequence_sum'} && $score ne ' ') {
- $ratio .= sprintf("%3.0f",$score);
+ my $score .= sprintf("%3.0f",$score);
+ $ratio .= (' 'x(3-length($score))).$score;
} elsif($chosen_output->{'sequence_sum'}) {
$ratio .= ' 'x3;
}
@@ -756,13 +786,15 @@ sub html_outputstudent {
$performance = '';
$performance_length=0;
}
- $performance .= ' 'x($seq->{'width_total'}-$performance_length-$seq->{'width_sum'}).
+ $performance .= ' 'x($width{$symb}->{'width_total'} -
+ $performance_length -
+ $width{$symb}->{'width_sum'}).
$ratio;
#
$Str .= $performance.$padding;
#
- $studentstats->{$seq->{'symb'}}->{'score'}= $score;
- $studentstats->{$seq->{'symb'}}->{'max'} = $seq_max;
+ $studentstats->{$symb}->{'score'}= $score;
+ $studentstats->{$symb}->{'max'} = $seq_max;
}
#
# Total it up and store the statistics info.
@@ -782,6 +814,7 @@ sub html_outputstudent {
$score = ' ' x $total_sum_width;
} else {
$score = sprintf("%.0f",$score);
+ $score = (' 'x(3-length($score))).$score;
}
$Str .= ' '.' 'x($total_sum_width-length($score)).$score.' / '.$max;
$Str .= " \n";
@@ -794,6 +827,7 @@ sub html_outputstudent {
sub html_finish {
my ($r) = @_;
+ return if (! defined($navmap));
#
# Check for suppressed output and close the progress window if so
$r->print(" \n");
@@ -805,6 +839,7 @@ sub html_finish {
}
}
$r->rflush();
+ undef($navmap);
return;
}
@@ -816,19 +851,20 @@ sub StudentAverageTotal {
''.&mt('Average').' | '.
''.&mt('Maximum').' | '.
' |
'.$/;
- foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+ foreach my $seq (@sequences) {
+ my $symb = $seq->symb;
my $ave;
- my $num_students = $Statistics->{$seq->{'symb'}}->{'num_students'};
+ my $num_students = $Statistics->{$symb}->{'num_students'};
if ($num_students > 0) {
$ave = int(100*
- ($Statistics->{$seq->{'symb'}}->{'score'}/$num_students)
+ ($Statistics->{$symb}->{'score'}/$num_students)
)/100;
} else {
$ave = 0;
}
- my $max = $Statistics->{$seq->{'symb'}}->{'max'};
+ my $max = $Statistics->{$symb}->{'max'};
$ave = sprintf("%.2f",$ave);
- $Str .= '