# The LearningOnline Network with CAPA
# (Publication Handler
#
# $Id: lonchart.pm,v 1.52 2002/07/02 21:48:36 stredwic Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
# Homework Performance Chart
#
# (Navigate Maps Handler
#
# (Page Handler
#
# (TeX Content Handler
# YEAR=2000
# 05/29/00,05/30 Gerd Kortemeyer)
# 08/30,08/31,09/06,09/14,09/15,09/16,09/19,09/20,09/21,09/23,
# 10/02,10/10,10/14,10/16,10/18,10/19,10/31,11/6,11/14,11/16 Gerd Kortemeyer)
# YEAR=2001
# 3/1/1,6/1,17/1,29/1,30/1,31/1 Gerd Kortemeyer)
# 7/10/01 Behrouz Minaei
# 9/8 Gerd Kortemeyer
# 10/1, 10/19, 11/17, 11/22, 11/24, 11/28 12/18 Behrouz Minaei
# YEAR=2002
# 2/1, 2/6, 2/19, 2/28 Behrouz Minaei
#
###
=pod
=cut
package Apache::lonchart;
use strict;
use Apache::Constants qw(:common :http);
use Apache::lonnet();
use Apache::loncommon();
use HTML::TokeParser;
use GDBM_File;
#my $jr;
# ----- FORMAT PRINT DATA ----------------------------------------------
sub FormatStudentInformation {
my ($cache,$name,$studentInformation,$spacePadding)=@_;
my $Str='';
for(my $index=0; $index<(scalar @$studentInformation); $index++) {
if(!&ShouldShowColumn($cache, 'heading'.$index)) {
next;
}
my $data=$cache->{$name.':'.$studentInformation->[$index]};
$Str .= $data;
my @dataLength=split(//,$data);
my $length=scalar @dataLength;
$Str .= (' 'x($cache->{$studentInformation->[$index].'Length'}-
$length));
$Str .= $spacePadding;
}
return $Str;
}
sub FormatStudentData {
my ($name,$coid,$studentInformation,$spacePadding,$ChartDB)=@_;
my ($sname,$sdom) = split(/\:/,$name);
my $Str;
my %CacheData;
unless(tie(%CacheData,'GDBM_File',$ChartDB,&GDBM_READER,0640)) {
return '';
}
# Handle Student information ------------------------------------------
# Handle user data
$Str=&FormatStudentInformation(\%CacheData, $name, $studentInformation,
$spacePadding);
# Handle errors
if($CacheData{$name.':error'} =~ /environment/) {
$Str .= '
';
untie(%CacheData);
return $Str;
}
if($CacheData{$name.':error'} =~ /course/) {
$Str .= '
';
untie(%CacheData);
return $Str;
}
# Handle problem data ------------------------------------------------
my $Version;
my $problemsCorrect = 0;
my $totalProblems = 0;
my $problemsSolved = 0;
my $numberOfParts = 0;
foreach my $sequence (split(/\:/,$CacheData{'orderedSequences'})) {
if(!&ShouldShowColumn(\%CacheData, 'sequence'.$sequence)) {
next;
}
my $characterCount=0;
foreach my $problemID (split(/\:/,$CacheData{$sequence.':problems'})) {
my $problem = $CacheData{$problemID.':problem'};
my $LatestVersion = $CacheData{$name.":version:$problem"};
if(!$LatestVersion) {
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
':parts'})) {
$Str .= ' ';
$totalProblems++;
$characterCount++;
}
next;
}
my %partData=undef;
#initialize data, displays skips correctly
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
':parts'})) {
$partData{$part.':tries'}=0;
$partData{$part.':code'}=' ';
}
for(my $Version=1; $Version<=$LatestVersion; $Version++) {
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
':parts'})) {
if(!defined($CacheData{$name.":$Version:$problem".
":resource.$part.solved"})) {
next;
}
my $tries=0;
my $code=' ';
$tries = $CacheData{$name.":$Version:$problem".
":resource.$part.tries"};
$partData{$part.':tries'}=($tries) ? $tries : 0;
my $val = $CacheData{$name.":$Version:$problem".
":resource.$part.solved"};
if ($val eq 'correct_by_student') {$code = '*';}
elsif ($val eq 'correct_by_override') {$code = '+';}
elsif ($val eq 'incorrect_attempted') {$code = '.';}
elsif ($val eq 'incorrect_by_override'){$code = '-';}
elsif ($val eq 'excused') {$code = 'x';}
elsif ($val eq 'ungraded_attempted') {$code = '#';}
else {$code = ' ';}
$partData{$part.':code'}=$code;
}
}
$Str.='';
foreach(split(/\:/,$CacheData{$sequence.':'.$problemID.
':parts'})) {
if($partData{$_.':code'} eq '*') {
$problemsCorrect++;
if (($partData{$_.':tries'}<10) &&
($partData{$_.':tries'} ne '')) {
$partData{$_.':code'}=$partData{$_.':tries'};
}
} elsif($partData{$_.':code'} eq '+') {
$problemsCorrect++;
}
$Str .= $partData{$_.':code'};
$characterCount++;
if($partData{$_.':code'} ne 'x') {
$totalProblems++;
}
}
$Str.='';
}
my $spacesNeeded=$CacheData{$sequence.':columnWidth'}-$characterCount;
$spacesNeeded -= 3;
$Str .= (' 'x$spacesNeeded);
my $outputProblemsCorrect = sprintf( "%3d", $problemsCorrect );
$Str .= ''.$outputProblemsCorrect.'';
$problemsSolved += $problemsCorrect;
$problemsCorrect=0;
$Str .= $spacePadding;
}
my $outputProblemsSolved = sprintf( "%4d", $problemsSolved );
my $outputTotalProblems = sprintf( "%4d", $totalProblems );
$Str .= ''.$outputProblemsSolved.
' / '.$outputTotalProblems.'
';
untie(%CacheData);
return $Str;
}
sub CreateTableHeadings {
my ($CacheData,$studentInformation,$headings,$spacePadding)=@_;
my $Str='
'; for(my $index=0; $index<(scalar @$headings); $index++) { if(!&ShouldShowColumn($CacheData, 'heading'.$index)) { next; } my $data=$$headings[$index]; $Str .= $data; my @dataLength=split(//,$data); my $length=scalar @dataLength; $Str .= (' 'x($CacheData->{$$studentInformation[$index].'Length'}- $length)); $Str .= $spacePadding; } foreach my $sequence (split(/\:/,$CacheData->{'orderedSequences'})) { if(!&ShouldShowColumn($CacheData, 'sequence'.$sequence)) { next; } my $name = $CacheData->{$sequence.':title'}; $Str .= $name; my @titleLength=split(//,$CacheData->{$sequence.':title'}); my $leftover=$CacheData->{$sequence.':columnWidth'}- (scalar @titleLength); $Str .= (' 'x$leftover); $Str .= $spacePadding; } $Str .= 'Total Solved/Total Problems'; $Str .= ''; return $Str; } sub CreateColumnSelectionBox { my ($CacheData,$studentInformation,$headings,$spacePadding)=@_; my $missing=0; my $notThere='
'; for(my $index=0; $index<(scalar @$headings); $index++) { if(!&ShouldShowColumn($CacheData, 'heading'.$index)) { next; } $name = $headings->[$index]; $length=$CacheData->{$$studentInformation[$index].'Length'}; $position=int($length/2); $present .= (' 'x($position)); $present .= ''; $position+=2; $present .= (' 'x($length-$position)); $present .= $spacePadding; $found++; } foreach my $sequence (split(/\:/,$CacheData->{'orderedSequences'})) { if(!&ShouldShowColumn($CacheData, 'sequence'.$sequence)) { next; } $name = $CacheData->{$sequence.':title'}; $length=$CacheData->{$sequence.':columnWidth'}; $position=int($length/2); $present .= (' 'x($position)); $present .= ''; $position+=2; $present .= (' 'x($length-$position)); $present .= $spacePadding; $found++; } if($found) { $present .= ''; $present = $present; } else { $present = ''; } return $present.''."\n";; } sub CreateForm { my ($CacheData)=@_; my $OpSel1=''; my $OpSel2=''; my $OpSel3=''; my $Status = $CacheData->{'form.status'}; if ( $Status eq 'Any' ) { $OpSel3='selected'; } elsif ($Status eq 'Expired' ) { $OpSel2 = 'selected'; } else { $OpSel1 = 'selected'; } my $Ptr .= '