';
@@ -401,7 +404,7 @@ my @OutputOptions =
},
{ name => 'CSV',
value => 'csv',
- description => 'Output a comma seperated values file suitable for '.
+ description => 'Output a comma separated values file suitable for '.
'import into a spreadsheet program. Using this method as opposed '.
'to Excel output allows you to organize your data before importing'.
' it into a spreadsheet program.',
@@ -473,7 +476,9 @@ my @OutputDataOptions =
sequence_sum => 1,
sequence_max => 1,
grand_total => 1,
+ grand_maximum => 1,
summary_table => 1,
+ maximum_row => 1,
shortdesc => 'Total Score and Maximum Possible for each '.
'Sequence or Folder',
longdesc => 'The score of each student as well as the '.
@@ -489,7 +494,9 @@ my @OutputDataOptions =
sequence_sum => 1,
sequence_max => 1,
grand_total => 1,
+ grand_maximum => 1,
summary_table => 1,
+ maximum_row => 1,
shortdesc => 'Score on each Problem Part',
longdesc =>'The students score on each problem part, computed as'.
'the part weight * part awarded',
@@ -504,7 +511,9 @@ my @OutputDataOptions =
sequence_sum => 0,
sequence_max => 0,
grand_total => 0,
- summary_table => 1,
+ grand_maximum => 0,
+ summary_table => 0,
+ maximum_row => 0,
shortdesc => 'Number of Tries before success on each Problem Part',
longdesc =>'The number of tries before success on each problem part.',
},
@@ -518,7 +527,9 @@ my @OutputDataOptions =
sequence_sum => 1,
sequence_max => 1,
grand_total => 1,
+ grand_maximum => 1,
summary_table => 1,
+ maximum_row => 0,
shortdesc => 'Number of Problem Parts completed successfully.',
longdesc => 'The Number of Problem Parts completed successfully and '.
'the maximum possible for each student',
@@ -596,6 +607,7 @@ Return a line of the chart for a student
my $nodata_count; # The number of students for which there is no data
my %prog_state; # progress state used by loncommon PrgWin routines
+ my $total_sum_width;
sub html_initialize {
my ($r) = @_;
@@ -622,13 +634,19 @@ 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;
if ($chosen_output->{'sequence_sum'}) {
+ if ($chosen_output->{'every_problem'}) {
+ # Use 1 digit for a space
+ $sequence->{'width_sum'} += 1;
+ }
+ $total_count += $sequence->{'num_assess_parts'};
# Use 3 digits for the sum
- $sequence->{'width_sum'} = 3;
+ $sequence->{'width_sum'} += 3;
}
if ($chosen_output->{'sequence_max'}) {
if ($sequence->{'width_sum'}>0) {
@@ -638,6 +656,7 @@ sub html_initialize {
# Use 3 digits for the total
$sequence->{'width_sum'}+=3;
}
+ #
if ($chosen_output->{'every_problem'}) {
# one problem per digit
$sequence->{'width_problem'} = $sequence->{'num_assess_parts'};
@@ -646,10 +665,8 @@ sub html_initialize {
}
$sequence->{'width_total'} = $sequence->{'width_problem'} +
$sequence->{'width_sum'};
- if ($sequence->{'width_total'} < length($sequence->{'title'})) {
- $sequence->{'width_total'} = length($sequence->{'title'});
- $sequence->{'width_problem'} =
- $sequence->{'width_total'} - $sequence->{'width_sum'};
+ if ($sequence->{'width_total'} < length(&HTML::Entities::decode($sequence->{'title'}))) {
+ $sequence->{'width_total'} = length(&HTML::Entities::decode($sequence->{'title'}));
}
#
# Output the sequence titles
@@ -658,7 +675,8 @@ sub html_initialize {
length($sequence->{'title'})
).$padding;
}
- $Str .= "total\n";
+ $total_sum_width = length($total_count)+1;
+ $Str .= " total\n";
$Str .= "";
$r->print($Str);
$r->rflush();
@@ -676,6 +694,10 @@ sub html_outputstudent {
my @to_show = &get_student_fields_to_show();
foreach my $field (@to_show) {
my $title=$student->{$field};
+ # Deal with 'comments' - how I love special cases
+ if ($field eq 'comments') {
+ $title = ''.&mt('Comments').'';
+ }
my $base = length($title);
my $width=$Apache::lonstatistics::StudentData{$field}->{'width'};
$Str .= $title.' 'x($width-$base).$padding;
@@ -711,20 +733,26 @@ sub html_outputstudent {
$seq,$show_links);
}
my $ratio='';
- if ($chosen_output->{'sequence_sum'}) {
- $ratio .= sprintf("%3d",$score);
+ if ($chosen_output->{'every_problem'}) {
+ $ratio .= ' ';
+ }
+ if ($chosen_output->{'sequence_sum'} && $score ne ' ') {
+ $ratio .= sprintf("%3.0f",$score);
+ } elsif($chosen_output->{'sequence_sum'}) {
+ $ratio .= ' 'x3;
}
if ($chosen_output->{'sequence_max'}) {
if ($chosen_output->{'sequence_sum'}) {
$ratio .= '/';
}
- $ratio .= sprintf("%3d",$seq_max);
+ $ratio .= sprintf("%3.0f",$seq_max);
}
#
if (! $chosen_output->{'every_problem'}) {
$performance = '';
+ $performance_length=0;
}
- $performance .= ' 'x($seq->{'width_problem'}-$performance_length).
+ $performance .= ' 'x($seq->{'width_total'}-$performance_length-$seq->{'width_sum'}).
$ratio;
#
$Str .= $performance.$padding;
@@ -734,16 +762,22 @@ sub html_outputstudent {
}
#
# Total it up and store the statistics info.
- my ($score,$max) = (0,0);
+ my ($score,$max);
while (my ($symb,$seq_stats) = each (%{$studentstats})) {
$Statistics->{$symb}->{'score'} += $seq_stats->{'score'};
if ($Statistics->{$symb}->{'max'} < $seq_stats->{'max'}) {
$Statistics->{$symb}->{'max'} = $seq_stats->{'max'};
}
- $score += $seq_stats->{'score'};
+ if ($seq_stats->{'score'} ne ' ') {
+ $score += $seq_stats->{'score'};
+ $Statistics->{$symb}->{'num_students'}++;
+ }
$max += $seq_stats->{'max'};
}
- $Str .= ' '.' 'x(length($max)-length($score)).$score.'/'.$max;
+ if (! defined($score)) {
+ $score = ' ' x $total_sum_width;
+ }
+ $Str .= ' '.' 'x($total_sum_width-length($score)).$score.' / '.$max;
$Str .= " \n";
#
$r->print($Str);
@@ -757,10 +791,12 @@ sub html_finish {
#
# Check for suppressed output and close the progress window if so
$r->print("
\n");
- if ($single_student_mode) {
- $r->print(&SingleStudentTotal());
- } else {
- $r->print(&StudentAverageTotal());
+ if ($chosen_output->{'summary_table'}) {
+ if ($single_student_mode) {
+ $r->print(&SingleStudentTotal());
+ } else {
+ $r->print(&StudentAverageTotal());
+ }
}
$r->rflush();
return;
@@ -768,37 +804,42 @@ sub html_finish {
sub StudentAverageTotal {
my $Str = "Summary Tables
\n";
- my $num_students = scalar(@Apache::lonstatistics::Students);
- my $total_ave = 0;
- my $total_max = 0;
+# my $max_students;
+# my $total_ave = 0;
+# my $total_max = 0;
$Str .= ''."\n";
$Str .= "Title | Average | Maximum |
\n";
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
my $ave;
- if ($num_students > $nodata_count) {
- $ave = int(100*($Statistics->{$seq->{'symb'}}->{'score'}/
- ($num_students-$nodata_count)))/100;
+ my $num_students = $Statistics->{$seq->{'symb'}}->{'num_students'};
+# if ($num_students > $max_students) {
+# $max_students = $num_students;
+# }
+ if ($num_students > 0) {
+ $ave = int(100*
+ ($Statistics->{$seq->{'symb'}}->{'score'}/$num_students)
+ )/100;
} else {
$ave = 0;
}
- $total_ave += $ave;
+# $total_ave += $ave;
my $max = $Statistics->{$seq->{'symb'}}->{'max'};
- $total_max += $max;
+# $total_max += $max;
$ave = sprintf("%.2f",$ave);
$Str .= ''.$seq->{'title'}.' | '.
''.$ave.' | '.
''.$max.' '.' |
'."\n";
}
- $total_ave = sprintf('%.2f',$total_ave); # only two digit
- $Str .= "
\n";
- $Str .= ''."\n";
- $Str .= 'Number of Students | Average | '.
- "Maximum |
\n";
- $Str .= ''.
- ''.($num_students-$nodata_count).' | '.
- ''.$total_ave.' '.' | '.
- ''.$total_max.' '.' | ';
+# $total_ave = sprintf('%.2f',$total_ave); # only two digit
$Str .= "
\n";
+# $Str .= ''."\n";
+# $Str .= 'Number of Students | Average | '.
+# "Maximum |
\n";
+# $Str .= ''.
+# ''.$max_students.' | '.
+# ''.$total_ave.' '.' | '.
+# ''.$total_max.' '.' | ';
+# $Str .= "
\n";
return $Str;
}
@@ -859,6 +900,7 @@ my %prog_state; # progress window state
my $request_aborted;
my $total_formula;
+my $maximum_formula;
sub excel_initialize {
my ($r) = @_;
@@ -871,9 +913,11 @@ sub excel_initialize {
undef (%prog_state);
undef ($request_aborted);
undef ($total_formula);
+ undef ($maximum_formula);
#
my $total_columns = scalar(&get_student_fields_to_show());
-
+ my $num_students = scalar(@Apache::lonstatistics::Students);
+ #
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
if ($chosen_output->{'every_problem'}) {
$total_columns += $seq->{'num_assess_parts'};
@@ -927,6 +971,24 @@ END
$rows_output = 0;
$cols_output = 0;
#
+ # Determine rows
+ my $header_row = $rows_output++;
+ my $description_row = $rows_output++;
+ $rows_output++; # blank row
+ my $summary_header_row;
+ if ($chosen_output->{'summary_table'}) {
+ $summary_header_row = $rows_output++;
+ $rows_output+= scalar(&Apache::lonstatistics::Sequences_with_Assess());
+ $rows_output++;
+ }
+ my $sequence_name_row = $rows_output++;
+ my $resource_name_row = $rows_output++;
+ my $maximum_data_row = $rows_output++;
+ if (! $chosen_output->{'maximum_row'}) {
+ $rows_output--;
+ }
+ my $first_data_row = $rows_output++;
+ #
# Create sheet
$excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
#
@@ -945,25 +1007,15 @@ END
# File::Temp is used to determine the temporary directory.
$excel_workbook->set_tempdir($Apache::lonnet::tmpdir);
#
+ my $format = &Apache::loncommon::define_excel_formats($excel_workbook);
+ #
# Add a worksheet
my $sheetname = $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
$sheetname = &Apache::loncommon::clean_excel_name($sheetname);
$excel_sheet = $excel_workbook->addworksheet($sheetname);
#
- # Define some potentially useful formats
- my $format;
- $format->{'header'} = $excel_workbook->add_format(bold => 1,
- bottom => 1,
- align => 'center');
- $format->{'bold'} = $excel_workbook->add_format(bold=>1);
- $format->{'h1'} = $excel_workbook->add_format(bold=>1, size=>18);
- $format->{'h2'} = $excel_workbook->add_format(bold=>1, size=>16);
- $format->{'h3'} = $excel_workbook->add_format(bold=>1, size=>14);
- $format->{'date'} = $excel_workbook->add_format(num_format=>
- 'mmm d yyyy hh:mm AM/PM');
- #
# Put the course description in the header
- $excel_sheet->write($rows_output,$cols_output++,
+ $excel_sheet->write($header_row,$cols_output++,
$ENV{'course.'.$ENV{'request.course.id'}.'.description'},
$format->{'h1'});
$cols_output += 3;
@@ -985,24 +1037,21 @@ END
$sectionstring = "Section ".$Sections[0];
}
}
- $excel_sheet->write($rows_output,$cols_output++,$sectionstring,
+ $excel_sheet->write($header_row,$cols_output++,$sectionstring,
$format->{'h3'});
$cols_output += scalar(@Sections);
#
# Put the date in there too
- $excel_sheet->write($rows_output++,$cols_output++,
+ $excel_sheet->write($header_row,$cols_output++,
'Compiled on '.localtime(time),$format->{'h3'});
#
$cols_output = 0;
- $excel_sheet->write($rows_output++,$cols_output++,
+ $excel_sheet->write($description_row,$cols_output++,
$chosen_output->{'shortdesc'},
$format->{'h3'});
- #
- # Figure out the rows we need
- my $sequence_name_row = $rows_output+1;
- my $resource_name_row = $sequence_name_row+1;
- my $maximum_data_row = $sequence_name_row+2;
- my $first_data_row = $sequence_name_row+3;
+ ##############################################
+ # Output headings for the raw data
+ ##############################################
#
# Add the student headers
$cols_output = 0;
@@ -1013,13 +1062,14 @@ END
#
# Add the remaining column headers
my $total_formula_string = '=0';
+ my $maximum_formula_string = '=0';
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
$excel_sheet->write($sequence_name_row,,
- $cols_output,$seq->{'title'},$format->{'h3'});
+ $cols_output,$seq->{'title'},$format->{'bold'});
# Determine starting cell
$seq->{'Excel:startcell'}=
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
- ($maximum_data_row,$cols_output);
+ ($first_data_row,$cols_output);
$seq->{'Excel:startcol'}=$cols_output;
my $count = 0;
if ($chosen_output->{'every_problem'}) {
@@ -1053,7 +1103,7 @@ END
} else {
$seq->{'Excel:endcell'} =
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
- ($maximum_data_row,$cols_output-1);
+ ($first_data_row,$cols_output-1);
$seq->{'Excel:endcol'} = $cols_output-1;
}
# Create the formula for summing up this sequence
@@ -1067,7 +1117,7 @@ END
# Determine cell the score is held in
$seq->{'Excel:scorecell'} =
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
- ($maximum_data_row,$cols_output);
+ ($first_data_row,$cols_output);
$seq->{'Excel:scorecol'}=$cols_output;
if ($chosen_output->{'base'} eq 'parts correct total') {
$excel_sheet->write($resource_name_row,$cols_output++,
@@ -1088,21 +1138,36 @@ END
#
$total_formula_string.='+'.
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
- ($maximum_data_row,$cols_output-1);
+ ($first_data_row,$cols_output-1);
if ($chosen_output->{'sequence_max'}) {
- $excel_sheet->write($resource_name_row,$cols_output++,
+ $excel_sheet->write($resource_name_row,$cols_output,
'maximum',
$format->{'bold'});
+ $seq->{'Excel:maxcell'} =
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($first_data_row,$cols_output);
+ $seq->{'Excel:maxcol'}=$cols_output;
+ $maximum_formula_string.='+'.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($first_data_row,$cols_output);
+ $cols_output++;
+
}
}
if ($chosen_output->{'grand_total'}) {
$excel_sheet->write($resource_name_row,$cols_output++,'Total',
$format->{'bold'});
}
+ if ($chosen_output->{'grand_maximum'}) {
+ $excel_sheet->write($resource_name_row,$cols_output++,'Max. Total',
+ $format->{'bold'});
+ }
$total_formula = $excel_sheet->store_formula($total_formula_string);
- #
+ $maximum_formula = $excel_sheet->store_formula($maximum_formula_string);
+ ##############################################
# Output a row for MAX, if appropriate
- if ($chosen_output->{'scores'}) {
+ ##############################################
+ if ($chosen_output->{'maximum_row'}) {
$cols_output = 0;
foreach my $field (&get_student_fields_to_show()) {
if ($field eq 'username' || $field eq 'fullname' ||
@@ -1116,11 +1181,15 @@ END
#
# Add the maximums for each sequence or assessment
my %total_cell_translation;
+ my %maximum_cell_translation;
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
$cols_output=$seq->{'Excel:startcol'};
$total_cell_translation{$seq->{'Excel:scorecell'}} =
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
($maximum_data_row,$seq->{'Excel:scorecol'});
+ $maximum_cell_translation{$seq->{'Excel:maxcell'}} =
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($maximum_data_row,$seq->{'Excel:maxcol'});
my $weight;
my $max = 0;
foreach my $resource (@{$seq->{'contents'}}) {
@@ -1169,8 +1238,62 @@ END
$total_formula,undef,
%total_cell_translation);
}
- } # End of MAXIMUM row output if ($chosen_output->{'scores'}) {
+ if ($chosen_output->{'grand_maximum'}) {
+ $excel_sheet->repeat_formula($maximum_data_row,$cols_output++,
+ $maximum_formula,undef,
+ %total_cell_translation);
+ }
+ } # End of MAXIMUM row output if ($chosen_output->{'maximum_row'}) {
$rows_output = $first_data_row;
+ ##############################################
+ # Output summary table, which actually is above the sequence name row.
+ ##############################################
+ if ($chosen_output->{'summary_table'}) {
+ $cols_output = 0;
+ $excel_sheet->write($summary_header_row,$cols_output++,
+ 'Summary Table',$format->{'bold'});
+ if ($chosen_output->{'maximum_row'}) {
+ $excel_sheet->write($summary_header_row,$cols_output++,
+ 'Maximum',$format->{'bold'});
+ }
+ $excel_sheet->write($summary_header_row,$cols_output++,
+ 'Average',$format->{'bold'});
+ $excel_sheet->write($summary_header_row,$cols_output++,
+ 'Median',$format->{'bold'});
+ $excel_sheet->write($summary_header_row,$cols_output++,
+ 'Std Dev',$format->{'bold'});
+ my $row = $summary_header_row+1;
+ foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
+ $cols_output = 0;
+ $excel_sheet->write($row,$cols_output++,
+ $seq->{'title'},
+ $format->{'bold'});
+ if ($chosen_output->{'maximum_row'}) {
+ $excel_sheet->write
+ ($row,$cols_output++,
+ '='.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($maximum_data_row,$seq->{'Excel:scorecol'})
+ );
+ }
+ my $range =
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($first_data_row,$seq->{'Excel:scorecol'}).
+ ':'.
+ &Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
+ ($first_data_row+$num_students-1,$seq->{'Excel:scorecol'});
+ $excel_sheet->write($row,$cols_output++,
+ '=AVERAGE('.$range.')');
+ $excel_sheet->write($row,$cols_output++,
+ '=MEDIAN('.$range.')');
+ $excel_sheet->write($row,$cols_output++,
+ '=STDEV('.$range.')');
+ $row++;
+ }
+ }
+ ##############################################
+ # Take care of non-excel initialization
+ ##############################################
#
# Let the user know what we are doing
my $studentcount = scalar(@Apache::lonstatistics::Students);
@@ -1206,7 +1329,12 @@ sub excel_outputstudent {
# Write out student data
my @to_show = &get_student_fields_to_show();
foreach my $field (@to_show) {
- $excel_sheet->write($rows_output,$cols_output++,$student->{$field});
+ my $value = $student->{$field};
+ if ($field eq 'comments') {
+ $value = &Apache::lonmsg::retrieve_instructor_comments
+ ($student->{'username'},$student->{'domain'});
+ }
+ $excel_sheet->write($rows_output,$cols_output++,$value);
}
#
# Get student assessment data
@@ -1221,6 +1349,7 @@ sub excel_outputstudent {
#
# Write out sequence scores and totals data
my %total_cell_translation;
+ my %maximum_cell_translation;
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
$cols_output = $seq->{'Excel:startcol'};
# Keep track of cells to translate in total cell
@@ -1248,7 +1377,12 @@ sub excel_outputstudent {
}
} else {
foreach my $value (@$rawdata) {
- $excel_sheet->write($rows_output,$cols_output++,$value);
+ if ($score eq ' ' || !defined($value)) {
+ $cols_output++;
+ } else {
+ $excel_sheet->write($rows_output,$cols_output++,
+ $value);
+ }
}
}
}
@@ -1273,7 +1407,11 @@ sub excel_outputstudent {
%replaceCells);
}
} elsif ($chosen_output->{'sequence_sum'}) {
- $excel_sheet->write($rows_output,$cols_output++,$score);
+ if ($score eq ' ') {
+ $cols_output++;
+ } else {
+ $excel_sheet->write($rows_output,$cols_output++,$score);
+ }
}
if ($chosen_output->{'sequence_max'}) {
$excel_sheet->write($rows_output,$cols_output++,$seq_max);
@@ -1285,6 +1423,11 @@ sub excel_outputstudent {
$total_formula,undef,
%total_cell_translation);
}
+ if ($chosen_output->{'grand_maximum'}) {
+ $excel_sheet->repeat_formula($rows_output,$cols_output++,
+ $maximum_formula,undef,
+ %total_cell_translation);
+ }
#
# Bookkeeping
$rows_output++;
@@ -1432,6 +1575,10 @@ END
$sequence_row.= '"",';
$resource_row.= '"Total",';
}
+ if ($chosen_output->{'grand_maximum'}) {
+ $sequence_row.= '"",';
+ $resource_row.= '"Maximum",';
+ }
chomp($sequence_row);
chomp($resource_row);
print $outputfile $sequence_row."\n";
@@ -1448,7 +1595,12 @@ sub csv_outputstudent {
# Output student fields
my @to_show = &get_student_fields_to_show();
foreach my $field (@to_show) {
- $Str .= '"'.&Apache::loncommon::csv_translate($student->{$field}).'",';
+ my $value = $student->{$field};
+ if ($field eq 'comments') {
+ $value = &Apache::lonmsg::retrieve_instructor_comments
+ ($student->{'username'},$student->{'domain'});
+ }
+ $Str .= '"'.&Apache::loncommon::csv_translate($value).'",';
}
#
# Get student assessment data
@@ -1463,6 +1615,7 @@ sub csv_outputstudent {
#
# Output performance data
my $total = 0;
+ my $maximum = 0;
foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
my ($performance,$performance_length,$score,$seq_max,$rawdata);
if ($chosen_output->{'tries'}){
@@ -1496,10 +1649,14 @@ sub csv_outputstudent {
$Str .= '"'.$seq_max.'",';
}
$total+=$score;
+ $maximum += $seq_max;
}
if ($chosen_output->{'grand_total'}) {
$Str .= '"'.$total.'",';
}
+ if ($chosen_output->{'grand_maximum'}) {
+ $Str .= '"'.$maximum.'",';
+ }
chop($Str);
$Str .= "\n";
print $outputfile $Str;
@@ -1523,7 +1680,7 @@ sub csv_finish {
#
# Tell the user where to get their csv file
$r->print('
'.
- 'Your csv file.'."\n");
+ ''.&mt('Your csv file.').''."\n");
$r->rflush();
return;
@@ -1564,6 +1721,7 @@ sub StudentTriesOnSequence {
my $performance_length = 0;
my @TriesData = ();
my $tries;
+ my $hasdata = 0; # flag - true if the student has any data on the sequence
foreach my $resource (@{$seq->{'contents'}}) {
next if ($resource->{'type'} ne 'assessment');
my $resource_data = $studentdata->{$resource->{'symb'}};
@@ -1588,6 +1746,7 @@ sub StudentTriesOnSequence {
my $tries = 0;
if(exists($resource_data->{'resource.'.$partnum.'.tries'})) {
$tries = $resource_data->{'resource.'.$partnum.'.tries'};
+ $hasdata =1;
}
#
if ($awarded > 0) {
@@ -1650,6 +1809,9 @@ sub StudentTriesOnSequence {
if ($seq->{'randompick'}) {
$max = $seq->{'randompick'};
}
+ if (! $hasdata && $sum == 0) {
+ $sum = ' ';
+ }
return ($Str,$performance_length,$sum,$max,\@TriesData);
}
@@ -1687,6 +1849,7 @@ sub StudentPerformanceOnSequence {
my $symbol;
my @ScoreData = ();
my $partscore;
+ my $hasdata = 0; # flag, 0 if there were no submissions on the sequence
foreach my $resource (@{$seq->{'contents'}}) {
next if ($resource->{'type'} ne 'assessment');
my $resource_data = $studentdata->{$resource->{'symb'}};
@@ -1705,13 +1868,17 @@ sub StudentPerformanceOnSequence {
$performance_length++; # one character per part
$symbol = ' '; # default to space
#
- my $awarded = 0;
+ my $awarded;
if (exists($resource_data->{'resource.'.$part.'.awarded'})) {
$awarded = $resource_data->{'resource.'.$part.'.awarded'};
$awarded = 0 if (! $awarded);
+ $hasdata = 1;
}
#
$partscore = $weight*$awarded;
+ if (! defined($awarded)) {
+ $partscore = undef;
+ }
$score += $partscore;
$symbol = $partscore;
if (abs($symbol - sprintf("%.0f",$symbol)) < 0.001) {
@@ -1726,10 +1893,12 @@ sub StudentPerformanceOnSequence {
$symbol = 'x';
$max -= $weight; # Do not count 'excused' problems.
}
+ $hasdata = 1;
} else {
# Unsolved. Did they try?
if (exists($resource_data->{'resource.'.$part.'.tries'})){
$symbol = '.';
+ $hasdata = 1;
} else {
$symbol = ' ';
}
@@ -1750,6 +1919,9 @@ sub StudentPerformanceOnSequence {
$Str .= $symbol;
}
}
+ if (! $hasdata && $score == 0) {
+ $score = ' ';
+ }
return ($Str,$performance_length,$score,$max,\@ScoreData);
}