--- loncom/interface/Attic/lonchart.pm 2002/07/08 13:38:52 1.55
+++ loncom/interface/Attic/lonchart.pm 2002/07/08 16:50:03 1.58
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# (Publication Handler
#
-# $Id: lonchart.pm,v 1.55 2002/07/08 13:38:52 stredwic Exp $
+# $Id: lonchart.pm,v 1.58 2002/07/08 16:50:03 stredwic Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -245,6 +245,8 @@ sub FormatStudentData {
my $problem = $CacheData{$problemID.':problem'};
my $LatestVersion = $CacheData{$name.":version:$problem"};
+ # Output blanks for all the parts of this problem if there
+ # is no version information about the current problem.
if(!$LatestVersion) {
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
@@ -257,13 +259,19 @@ sub FormatStudentData {
}
my %partData=undef;
- #initialize data, displays skips correctly
+ # Initialize part data, display skips correctly
+ # Skip refers to when a student made no submissions on that
+ # part/problem.
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
':parts'})) {
$partData{$part.':tries'}=0;
$partData{$part.':code'}=' ';
}
+
+ # Looping through all the versions of each part, starting with the
+ # oldest version. Basically, it gets the most recent
+ # set of grade data for each part.
for(my $Version=1; $Version<=$LatestVersion; $Version++) {
foreach my $part (split(/\:/,$CacheData{$sequence.':'.
$problemID.
@@ -271,6 +279,7 @@ sub FormatStudentData {
if(!defined($CacheData{$name.":$Version:$problem".
":resource.$part.solved"})) {
+ # No grade for this submission, so skip
next;
}
@@ -294,6 +303,9 @@ sub FormatStudentData {
}
}
+ # All grades (except for versionless parts) are displayed as links
+ # to their submission record. Loop through all the parts for the
+ # current problem in the correct order and prepare the output links
$Str.='';
@@ -319,6 +331,9 @@ sub FormatStudentData {
$Str.='';
}
+ # Output the number of correct answers for the current sequence.
+ # This part takes up 6 character slots, but is formated right
+ # justified.
my $spacesNeeded=$CacheData{$sequence.':columnWidth'}-$characterCount;
$spacesNeeded -= 3;
$Str .= (' 'x$spacesNeeded);
@@ -331,6 +346,9 @@ sub FormatStudentData {
$Str .= $spacePadding;
}
+ # Output the total correct problems over the total number of problems.
+ # I don't like this type of formatting, but it is a solution. Need
+ # a way to dynamically determine the space requirements.
my $outputProblemsSolved = sprintf( "%4d", $problemsSolved );
my $outputTotalProblems = sprintf( "%4d", $totalProblems );
$Str .= ''.$outputProblemsSolved.
@@ -672,7 +690,7 @@ here in the future.
=item &DownloadPrerequisiteData()
-Collects lastname, generation, middlename, firstname PID, and section for each
+Collects lastname, generation, middlename, firstname, PID, and section for each
student from their environment database. The list of students is built from
collecting a classlist for the course that is to be displayed.
@@ -793,6 +811,28 @@ tie hash to database later.
=pod
+=item &ProcessTopResourceMap()
+
+Trace through the "big hash" created in rat/lonuserstate.pm::loadmap.
+Basically, this function organizes a subset of the data and stores it in
+cached data. The data stored is the problems, sequences, sequence titles,
+parts of problems, and their ordering. Column width information is also
+partially handled here on a per sequence basis.
+
+=over 4
+
+Input: $ChartDB, $c
+
+$ChartDB: The name of the cache database file
+
+$c: The connection class used to determine if an abort has been sent to the
+browser
+
+Output: A string that contains an error message or "OK" if everything went
+smoothly.
+
+=back
+
=cut
sub ProcessTopResourceMap {
@@ -821,6 +861,7 @@ sub ProcessTopResourceMap {
return 'Could not tie cache hash.';
}
+ # Initialize state machine. Set information pointing to top level map.
my (@sequences, @currentResource, @finishResource);
my ($currentSequence, $currentResourceID, $lastResourceID);
@@ -889,7 +930,7 @@ sub ProcessTopResourceMap {
':'.$currentResourceID;
}
- #Get Parts for problem
+ # Get Parts for problem
my $meta=$hash{'src_'.$currentResourceID};
foreach (split(/\,/,&Apache::lonnet::metadata($meta,'keys'))) {
if($_=~/^stores\_(\d+)\_tries$/) {
@@ -906,9 +947,9 @@ sub ProcessTopResourceMap {
}
}
- #if resource == finish resource
+ # if resource == finish resource, then it is the end of a sequence/page
if($currentResourceID eq $lastResourceID) {
- #pop off last resource of sequence
+ # pop off last resource of sequence
$currentResourceID=pop(@currentResource);
$lastResourceID=pop(@finishResource);
@@ -940,6 +981,8 @@ sub ProcessTopResourceMap {
(scalar @titleLength);
}
} else {
+ # Remove sequence from list, if it contains no problems to
+ # display.
$CacheData{'orderedSequences'}=~s/$currentSequence//;
$CacheData{'orderedSequences'}=~s/::/:/g;
$CacheData{'orderedSequences'}=~s/^:|:$//g;
@@ -952,7 +995,7 @@ sub ProcessTopResourceMap {
}
# MOVE!!!
- #move to next resource
+ # move to next resource
unless(defined($hash{'to_'.$currentResourceID})) {
# big problem, need to handle. Next is probably wrong
last;
@@ -981,6 +1024,35 @@ sub ProcessTopResourceMap {
return 'OK';
}
+=pod
+
+=item &ProcessSection()
+
+Determine the section number for a student for the class. A student can have
+multiple sections for the same class. The correct one is chosen.
+
+=over 4
+
+Input: $sectionData, $courseid, $ActiveFlag
+
+$sectionData: A pointer to a hash containing all section data for this
+student for the class
+
+$courseid: The course ID.
+
+$ActiveFlag: The student's active status (Active/Expired)
+
+Output: $oldsection, $cursection, or -1
+
+$oldsection and $cursection and sections number that will be displayed in the
+chart.
+
+-1 is returned if an error occurs.
+
+=back
+
+=cut
+
sub ProcessSection {
my ($sectionData, $courseid,$ActiveFlag)=@_;
$courseid=~s/\_/\//g;
@@ -1035,8 +1107,44 @@ sub ProcessSection {
return '-1';
}
+=pod
+
+=item &ProcessStudentInformation()
+
+Takes data downloaded for a student and breaks it up into managable pieces and
+stored in cache data. The username, domain, class related date, PID,
+full name, and section are all processed here.
+
+=over 4
+
+Input: $CacheData, $studentInformation, $section, $date, $name, $courseID
+
+$CacheData: A hash pointer to the cached data
+
+$studentInformation: Student information is what was requested in
+&DownloadPrerequistedData(). See that function for what data is requested.
+
+$section: A hash pointer to class section related information.
+
+$date: A composite of the start and end date for this class for this
+student. Format: end:start
+
+$name: the username:domain information
+
+$courseID: The course ID
+
+Output: None
+
+*NOTE: There is no return value, but if an error occurs a key is added to
+the cache data with the value being the error message. The key is
+username:domain:error. It will only exist if an error occurs.
+
+=back
+
+=cut
+
sub ProcessStudentInformation {
- my ($CacheData,$studentInformation,$section,$date,$name,$courseID,$c)=@_;
+ my ($CacheData,$studentInformation,$section,$date,$name,$courseID)=@_;
my ($studentName,$studentDomain) = split(/\:/,$name);
$CacheData->{$name.':username'}=$studentName;
@@ -1066,9 +1174,43 @@ sub ProcessStudentInformation {
$CacheData->{$name.':section'}='';
}
- return 0;
+ return;
}
+=pod
+
+=item &ProcessClassList()
+
+Taking the class list dumped from &DownloadPrerequisiteData(), all the
+students and their non-class information is processed using the
+&ProcessStudentInformation() function. A date stamp is also recorded for
+when the data was processed.
+
+=over 4
+
+Input: $classlist, $courseID, $ChartDB, $c
+
+$classlist: The hash of data collected about a student from
+&DownloadPrerequisteData(). The hash contains a list of students, a pointer
+to a hash of student information for each student, and each student's section
+number.
+
+$courseID: The course ID
+
+$ChartDB: The name of the cache database file.
+
+$c: The connection class used to determine if an abort has been sent to the
+browser
+
+Output: @names
+
+@names: An array of students whose information has been processed, and are to
+be considered in an arbitrary order.
+
+=back
+
+=cut
+
sub ProcessClassList {
my ($classlist,$courseID,$ChartDB,$c)=@_;
my @names=();
@@ -1089,7 +1231,7 @@ sub ProcessClassList {
$classlist->{$name.':studentInformation'},
$classlist->{$name.':section'},
$classlist->{$name},
- $name,$courseID,$c);
+ $name,$courseID);
}
# Time of download
@@ -1100,6 +1242,40 @@ sub ProcessClassList {
return @names;
}
+=pod
+
+=item &ProcessStudentData()
+
+Takes the course data downloaded for a student in
+&DownloadStudentCourseInformation() and breaks it up into key value pairs
+to be stored in the cached data. The keys are comprised of the
+$username:$domain:$keyFromCourseDatabase. The student username:domain is
+stored away signifying that the student's information has been downloaded and
+can be reused from cached data.
+
+=over 4
+
+Input: $courseData, $name, $ChartDB
+
+$courseData: A hash pointer that points to the course data downloaded for a
+student.
+
+$name: username:domain
+
+$ChartDB: The name of the cache database file which will allow the data to
+be written to the cache.
+
+Output: None
+
+*NOTE: There is no output, but an error message is stored away in the cache
+data. This is checked in &FormatStudentData(). The key username:domain:error
+will only exist if an error occured. The error is an error from
+&DownloadStudentCourseInformation().
+
+=back
+
+=cut
+
sub ProcessStudentData {
my ($courseData, $name, $ChartDB)=@_;
@@ -1147,26 +1323,29 @@ Output: None
=cut
+# For all data, if ENV data doesn't exist for it, default values is used.
sub ProcessFormData {
my ($ChartDB, $isCached)=@_;
my %CacheData;
if(tie(%CacheData,'GDBM_File',$ChartDB,&GDBM_WRCREAT,0640)) {
+ # Ignore $ENV{'form.refresh'}
+ # Ignore $ENV{'form.recalculate'}
+
if(defined($ENV{'form.sort'})) {
$CacheData{'form.sort'}=$ENV{'form.sort'};
} elsif(!defined($CacheData{'form.sort'})) {
$CacheData{'form.sort'}='username';
}
- # Ignore $ENV{'form.refresh'}
- # Ignore $ENV{'form.recalculate'}
-
if(defined($ENV{'form.status'})) {
$CacheData{'form.status'}=$ENV{'form.status'};
} elsif(!defined($CacheData{'form.status'})) {
$CacheData{'form.status'}='Active';
}
+ # $found checks for any instances of form data in the ENV. If it is
+ # missing I assume the chrt button on the remote has been pressed.
my @headings=();
my @sequences=();
my $found=0;
@@ -1200,6 +1379,8 @@ sub ProcessFormData {
}
}
+ # !$found and !$isCached are how I determine if the chrt button
+ # on the remote was pressed and needs to reset all the selections
if(defined($ENV{'form.reset'}) || (!$found && !$isCached)) {
$CacheData{'form.reset'}='true';
$CacheData{'form.status'}='Active';
@@ -1287,7 +1468,8 @@ jobs.
=item &ProcessFullName()
Takes lastname, generation, firstname, and middlename (or some partial
-set of this data) and returns the full name version as a string.
+set of this data) and returns the full name version as a string. Format
+is Lastname generation, firstname middlename or a subset of this.
=cut
@@ -1519,16 +1701,16 @@ functions return strings to BuildChart t
=item &BuildChart()
- The following is the process that BuildChart goes through to create the
- html document.
+ The following is the process that BuildChart goes through to
+ create the html document.
-Start the lonchart document
-Test for access to the CacheData
-Download class list information if not using cached data
-Sort students and print out table desciptive data
-Output student data
- -If recalculating, store a list of students, but only if all their data was
- downloaded. Leave off the others.
+ -If recalculating, store a list of students, but only if all
+ their data was downloaded. Leave off the others.
-End document
=over 4
@@ -1715,7 +1897,7 @@ sub handler {
$r->send_http_header;
return OK;
}
-
+
unless($ENV{'request.course.fn'}) {
my $requrl=$r->uri;
$ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";