';
- $Ptr .= 'Select Map '."\n";
- $Ptr .= ''."\n";
-
- my $selected = 0;
- foreach my $sequence (split(':',$cache->{'orderedSequences'})) {
- $Ptr .= '{$page.'Map'} eq $cache->{$sequence.':title'}) {
- $Ptr .= ' selected';
- $selected = 1;
- }
- $Ptr .= '>'.$cache->{$sequence.':title'}.' '."\n";
- }
- $Ptr .= '';
- $Ptr .= 'Select Student '."\n";
- $Ptr .= ''."\n";
-
- my $selected=0;
- foreach (@$students) {
- my ($name) = split(':',$_);
- $Ptr .= ''."\n";
+ #
+ # Loop through the groups
+ foreach my $s (@Groups) {
+ $Str .= ' '."\n";
+ $Str .= '>'.$s." \n";
}
+ $Str .= " \n";
+}
- $Ptr .= '{$name.':error'} =~ /course/) {
- my ($username)=split(':',$name);
- $Str .= 'No course data for student ';
- $Str .= ''.$username.'. ';
- return $Str;
- }
-
- $Str .= " \# Set Title ";
- $Str .= ' Results Tries '."\n";
-
- my $codes;
- my $attempts;
- foreach my $sequence (split(':', $cache->{'orderedSequences'})) {
- if($cache->{'StudentAssessmentMap'} ne 'All Maps' &&
- $cache->{'StudentAssessmentMap'} ne $cache->{$sequence.':title'}) {
- next;
- }
-
- $Str .= ''.$sequence.' ';
- $Str .= ''.$cache->{$sequence.':title'}.' ';
-
- $codes = '';
- $attempts = '';
- foreach my $problemID (split(':', $cache->{$sequence.':problems'})) {
- my $problem = $cache->{$problemID.':problem'};
- my $LatestVersion = $cache->{$name.':version:'.$problem};
-
- # Output dashes for all the parts of this problem if there
- # is no version information about the current problem.
- if(!$LatestVersion) {
- foreach my $part (split(/\:/,$cache->{$sequence.':'.
- $problemID.
- ':parts'})) {
- $codes .= "-,";
- $attempts .= "0,";
- }
- next;
+sub DisplayClasslist {
+ my ($r)=@_;
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({text=>'Select One Student'});
+ #
+ # Output some of the standard interface components
+ my $Str;
+ $Str .= &Apache::lonhtmlcommon::breadcrumbs('Select One Student');
+ $Str .= ''."\n";
+ $Str .= '';
+ $Str .= ''.&mt('Sections').' ';
+ $Str .= ''.&mt('Groups').' ';
+ $Str .= ''.&mt('Access Status').' ';
+ $Str .= ' '.$/;
+ $Str .= '';
+ $Str .= ''.
+ &Apache::lonstatistics::SectionSelect('Section','multiple',5).
+ ' ';
+ $Str .= ''.
+ &Apache::lonstatistics::GroupSelect('Group','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','groups');
+ #
+ $Str = '';
+ my @selected_sections = &get_selected_sections();
+ if (! @Students) {
+ if ($selected_sections[0] eq 'all') {
+ if (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.').
+ '
';
+ } elsif (lc($env{'form.Status'}) eq 'future') {
+ $Str .= ''.
+ &mt('There are no students with future access in the course.').
+ '
';
+ } else { # 'any' and any others
+ $Str .= ''.
+ &mt('There are no students in the course.').
+ '
';
}
-
- my %partData=undef;
- # Initialize part data, display skips correctly
- # Skip refers to when a student made no submissions on that
- # part/problem.
- foreach my $part (split(/\:/,$cache->{$sequence.':'.
- $problemID.
- ':parts'})) {
- $partData{$part.':tries'}=0;
- $partData{$part.':code'}='-';
+ } else {
+ if (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.').
+ '
';
+ } elsif (lc($env{'form.Status'}) eq 'future') {
+ $Str .= ''.
+ &mt('There are no students with future access in the selected sections.').
+ '
';
+ } else { # 'any' and any others
+ $Str .= ''.
+ &mt('There are no students in the selected sections.').
+ '
';
}
+ }
+ $Str.= ''
+ .''
+ .&mt('Return to the chart').' '
+ .'
';
+ $r->print($Str);
+ $r->rflush();
+ return;
+ }
- # 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(/\:/,$cache->{$sequence.':'.
- $problemID.
- ':parts'})) {
-
- if(!defined($cache->{$name.":$Version:$problem".
- ":resource.$part.solved"})) {
- # No grade for this submission, so skip
- next;
- }
-
- my $tries=0;
- my $code='U';
-
- $tries = $cache->{$name.":$Version:$problem".
- ":resource.$part.tries"};
- $partData{$part.':tries'}=($tries) ? $tries : 0;
-
- my $val = $cache->{$name.":$Version:$problem".
- ":resource.$part.solved"};
- if ($val eq 'correct_by_student') {$code = 'Y';}
- elsif ($val eq 'correct_by_override') {$code = 'y';}
- elsif ($val eq 'incorrect_attempted') {$code = 'N';}
- elsif ($val eq 'incorrect_by_override'){$code = 'N';}
- elsif ($val eq 'excused') {$code = 'x';}
- $partData{$part.':code'}=$code;
+ $Str .= ''.&mt('Select One Student').' '
+ .''.&mt("Click on a student's name or username to view their chart.").'
'
+ .&Apache::loncommon::start_data_table()
+ .&Apache::loncommon::start_data_table_header_row();
+ foreach my $field (@Fields) {
+ $Str .= ''.&mt($field).
+ ' ';
+ }
+ $Str .= &Apache::loncommon::end_data_table_header_row();
+ #
+ foreach my $student (@Students) { # @Students is a package variable
+ my $sname = $student->{'username'}.':'.$student->{'domain'};
+ $Str .= &Apache::loncommon::start_data_table_row();
+ #
+ foreach my $field (@Fields) {
+ $Str .= '';
+ if ($field eq 'fullname' || $field eq 'username') {
+ $Str .= '';
+ $Str .= $student->{$field};
+ $Str .= ' ';
+ } elsif ($field eq 'status') {
+ $Str .= &mt($student->{$field});
+ } else {
+ if ($student->{$field} eq 'none') {
+ $Str .= &mt('none')
+ } else {
+ $Str .= $student->{$field};
}
}
-
- # Loop through all the parts for the current problem in the
- # correct order and prepare the output
- foreach (split(/\:/,$cache->{$sequence.':'.$problemID.
- ':parts'})) {
- $codes .= $partData{$_.':code'}.',';
- $attempts .= $partData{$_.':tries'}.',';
- }
+ $Str .= ' ';
}
- $codes =~ s/,$//;
- $attempts =~ s/,$//;
- $Str .= ''.$codes.' ';
- $Str .= ''.$attempts.' ';
- $Str .= ' '."\n";
+ $Str .= &Apache::loncommon::end_data_table_row();
}
-
- $Str .= '
'."\n";
-
- return $Str;
+ $Str .= &Apache::loncommon::end_data_table();
+ #
+ $r->print($Str);
+ $r->rflush();
+ #
+ return;
}
-#---- END Student Assessment Web Page ----------------------------------------
-#---- Menu Web Page ----------------------------------------------------------
-sub Title {
- my ($downloadTime)=@_;
+sub CreateMainMenu {
+ #
+ # Define menu data
+ my @reports = (
+ {categorytitle => 'Statistics and Analyses',
+ items => [
+ {url => '/adm/statistics?reportSelected=problem_statistics',
+ permission => 'F',
+ icon => 'document-open.png',
+ linktext => ('Overall Problem Statistics'),
+ linktitle => ('Student performance statistics on all problems.')},
+
+ {url => '/adm/statistics?reportSelected=problem_analysis',
+ permission => 'F',
+ icon => 'prob_ana.png',
+ linktext => ('Detailed Problem Analysis'),
+ linktitle => ('Detailed statistics and graphs of student performance on problems.')},
+ ]},
+ {categorytitle => 'Plots',
+ items => [
+ {url => '/adm/statistics?reportSelected=submissiontime_analysis',
+ permission => 'F',
+ icon => 'subtimpl.png',
+ linktext => ('Submission Time Plots'),
+ linktitle => ('Display and analysis of submission times on assessments.')},
+
+ {url => '/adm/statistics?reportSelected=correct_problems_plot',
+ permission => 'F',
+ icon => 'coprplot.png',
+ linktext => ('Correct Problems Plot'),
+ linktitle => ('Display a histogram of student performance in the course.')},
+ ]},
+ {categorytitle => 'Reports',
+ items => [
+ {url => '/adm/statistics?reportSelected=student_submission_reports',
+ permission => 'F',
+ icon => 'edit-copy.png',
+ linktext => ('Student Submission Reports'),
+ linktitle => ('Prepare reports of student submissions.')},
+
+ {url => '/adm/statistics?reportSelected=survey_reports',
+ permission => 'F',
+ icon => 'survey_rep.png',
+ linktext => ('Survey Reports'),
+ linktitle => ('Prepare reports on survey results.')},
+ ]});
+
+return &Apache::lonhtmlcommon::generate_menu(@reports);
+
+}
- my $Ptr = '';
- $Ptr .= 'LON-CAPA Statistics '."\n";
- $Ptr .= ''."\n";
- $Ptr .= ''."\n";
- $Ptr .= ' '."\n";
- $Ptr .= ' Course : "';
- $Ptr .= $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
- $Ptr .= '" '."\n";
- $Ptr .= ''.$downloadTime.' ';
- return $Ptr;
+sub handler {
+ my $r=shift;
+ my $c = $r->connection();
+ #
+ # Check for access
+ if (! &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
+ $env{'user.error.msg'}=
+ $r->uri.":vgr:0:0:Cannot view grades for complete course";
+ if (! &Apache::lonnet::allowed('vgr',
+ $env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
+ $env{'user.error.msg'}=
+ $r->uri.":vgr:0:0:Cannot view grades with given role";
+ return HTTP_NOT_ACCEPTABLE;
+ }
+ }
+ #
+ # Send the header
+ &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',
+ 'SelectedStudent']);
+ #
+ # Give the LON-CAPA page header
+ my $style = <
+ ul.sub_studentans { list-style-type: none }
+ ul.sub_correctans { list-style-type: none }
+ tr.even { background-color: \#CCCCCC }
+ td.essay { border: 1px solid gray; }
+
+ENDSTYLE
+
+ $r->print(&Apache::loncommon::start_page('Course Statistics and Charts',
+ $style));
+ $r->rflush();
+ #
+ # Either print out a menu for them or send them to a report
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/statistics',
+ title=>'Statistics',
+ text =>'Statistics',
+ faq=>139,
+ bug=>'Statistics and Charts'});
+ if (! exists($env{'form.reportSelected'}) ||
+ $env{'form.reportSelected'} eq '') {
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Statistics Main Page'));
+ &Apache::lonquickgrades::startGradeScreen($r,'statistics');
+ $r->print(&CreateMainMenu());
+ } else {
+ #
+ if (! &Apache::lonmysql::verify_sql_connection()) {
+ my $serveradmin = $r->dir_config('lonAdmEMail');
+ $r->print(''.
+ &mt('Unable to connect to database!').
+ '
');
+ $r->print(''
+ .&mt('Please notify the server administrator [_1]',
+ ,''.$serveradmin.' ')
+ .'
');
+ $r->print(''.
+ &mt('Course Statistics and Charts cannot be '.
+ 'retrieved until the database is restarted. '.
+ 'Your data is intact but cannot be displayed '.
+ 'at this time.').'
');
+ $r->print(&Apache::loncommon::end_page());
+ return;
+ }
+ #
+ # Clean out the caches
+ if (exists($env{'form.ClearCache'})) {
+ &Apache::loncoursedata::delete_caches($env{'requres.course.id'});
+ }
+ #
+ my $GoToPage = $env{'form.reportSelected'};
+ #
+ # Begin form output
+ $r->print('\n");
+ }
+ &Apache::lonquickgrades::endGradeScreen($r);
+ $r->print(&Apache::loncommon::end_page());
+ $r->rflush();
+ #
+ return OK;
}
-sub CreateMenuForm {
- my ($cache)=@_;
- my $Ptr = '';
- $Ptr .= ' {'OptionResponses'})) {
- $Ptr .= ' {$cacheName} = $ENV{'form.'.$ENVName};
- } elsif(!defined($cache->{$cacheName})) {
- $cache->{$cacheName} = $default;
- }
+Main handler for statistics and chart.
- return;
-}
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
-sub ProcessFormData{
- my ($cacheDB, $isCached)=@_;
- my %cache;
-
- if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT,0640)) {
- # Select page to display
- if(defined($ENV{'form.ProblemStatistics'}) ||
- defined($ENV{'form.ProblemStatisticsRecalculate'}) ||
- defined($ENV{'form.DisplayCSVFormat'})) {
- $cache{'GoToPage'} = 'ProblemStatistics';
- &CheckFormElement(\%cache, 'DisplayCSVFormat',
- 'DisplayFormat', 'Display Table Format');
- &CheckFormElement(\%cache, 'Ascend','ProblemStatisticsAscend',
- 'Ascending');
- &CheckFormElement(\%cache, 'Maps', 'ProblemStatisticsMap',
- 'All Maps');
- } elsif(defined($ENV{'form.ProblemAnalysis'})) {
- $cache{'GoToPage'} = 'ProblemAnalysis';
- &CheckFormElement(\%cache, 'Interval', 'Interval', '1');
- } elsif(defined($ENV{'form.StudentAssessment'}) ||
- defined($ENV{'form.CreateStudentAssessment'}) ||
- defined($ENV{'form.NextStudent'}) ||
- defined($ENV{'form.PreviousStudent'})) {
- $cache{'GoToPage'} = 'StudentAssessment';
- if(defined($ENV{'form.NextStudent'})) {
- $cache{'StudentAssessmentMove'} = 'next';
- } elsif(defined($ENV{'form.PreviousStudent'})) {
- $cache{'StudentAssessmentMove'} = 'previous';
- } else {
- $cache{'StudentAssessmentMove'} = 'selected';
- }
- &CheckFormElement(\%cache, 'Maps', 'StudentAssessmentMap',
- 'All Maps');
- &CheckFormElement(\%cache, 'Students', 'StudentAssessmentStudent',
- 'No Student Selected');
- } elsif(defined($ENV{'form.DoDiffGraph'})) {
- $cache{'GoToPage'} = 'DoDiffGraph';
- } elsif(defined($ENV{'form.PercentWrongGraph'})) {
- $cache{'GoToPage'} = 'PercentWrongGraph';
- } elsif(defined($ENV{'form.ActivityLog'})) {
- $cache{'GoToPage'} = 'ActivityLog';
- } else {
- $cache{'GoToPage'} = 'Menu';
- }
+=head1 PACKAGE VARIABLES
- &CheckFormElement(\%cache, 'Status', 'Status', 'Active');
+=over
- foreach (keys(%ENV)) {
- if(/form\.Analyze:::/) {
- $cache{'GoToPage'} = 'Analyze';
- my ($uri, $title, $part, $problem);
- (undef, $uri, $title, $part, $problem)=split(':::', $_);
- $cache{'AnalyzeURI'} = $uri;
- $cache{'AnalyzeTitle'} = $title;
- $cache{'AnalyzePart'} = $part;
- $cache{'AnalyzeProblem'} = $problem;
+=item @FullClasslist The full classlist
- &CheckFormElement(\%cache, 'Interval', 'Interval', '1');
- }
- }
- }
+=item @Students The students we are concerned with for this invocation
- return;
-}
+=item @Sections The sections available in this class
-=pod
+=item @Groups The groups available in the class
-=item &SortStudents()
+=item $curr_student The student currently being examined
-Determines which students to display and in which order. Which are
-displayed are determined by their status(active/expired). The order
-is determined by the sort button pressed (default to username). The
-type of sorting is username, lastname, or section.
+=item $prev_student The student previous in the classlist
-=over 4
+=item $next_student The student next in the classlist
-Input: $students, $CacheData
+=back
-$students: A array pointer to a list of students (username:domain)
+=head1 SUBROUTINES
-$CacheData: A pointer to the hash tied to the cached data
+=over
-Output: \@order
+=item &clear_classlist_variables()
-@order: An ordered list of students (username:domain)
+undef the following package variables:
-=back
+=over 4
-=cut
+=item * @FullClasslist
-sub SortStudents {
- my ($students,$cache)=@_;
+=item * @Students
- my @sorted1Students=();
- foreach (@$students) {
- push(@sorted1Students, $_);
- }
-# my ($end,$start)=split(/\:/,$cache->{$_.':date'});
-# my $active=1;
-# my $now=time;
-# my $Status=$cache->{'form.Status'};
-# $Status = ($Status) ? $Status : 'Active';
-# if((($end) && $now > $end) && (($Status eq 'Active'))) {
-# $active=0;
-# }
-# if(($Status eq 'Expired') && ($end == 0 || $now < $end)) {
-# $active=0;
-# }
-# if($active) {
-# push(@sorted1Students, $_);
-# }
-# }
-
- my $Pos = $cache->{'form.ChartSort'};
- my %sortData;
- if($Pos eq 'Last Name') {
- for(my $index=0; $index{$sorted1Students[$index].':fullname'}}=
- $sorted1Students[$index];
- }
- } elsif($Pos eq 'Section') {
- for(my $index=0; $index{$sorted1Students[$index].':section'}.
- $sorted1Students[$index]}=$sorted1Students[$index];
- }
- } else {
- # Sort by user name
- for(my $index=0; $indexaborted()) {
- untie(%cache);
- return 'aborted';
- }
+=item &PrepareClasslist()
- my $classlist=&Apache::loncoursedata::DownloadStudentNamePIDSection(
- $courseID,
- $c);
- my ($checkForError)=keys(%$classlist);
- if($checkForError =~ /^(con_lost|error|no_such_host)/i ||
- defined($classlist->{'error'})) {
- untie(%cache);
- return "Error getting student data.";
- }
+Build up the classlist information. The classlist information is kept in
+the following package variables:
- if($c->aborted()) {
- untie(%cache);
- return 'aborted';
- }
+=over 4
- # Active is a temporary solution, remember to change
- @students=&Apache::loncoursedata::ProcessClassList(\%cache,
- $classlist,
- $courseID,
- 'Active', $c);
+=item * @FullClasslist
- if($c->aborted()) {
- untie(%cache);
- return 'aborted';
- }
+=item * @Students
- untie(%cache);
- } else {
- if(!$c->aborted() && tie(%cache,'GDBM_File',$cacheDB,
- &GDBM_READER,0640)) {
- @students=split(/:::/,$cache{'NamesOfStudents'});
- } else {
- return 'aborted';
- }
- }
+=item * @Sections
- return ('OK', $isCached, \@students);
-}
+=item * @Groups
-# Create progress
-sub Create_PrgWin {
- $r->print(<
- popwin=open('','popwin','width=400,height=100');
- popwin.document.writeln(''+
- 'LON-CAPA Statistics '+
- 'Computation Progress '+
- ''+
- '');
- popwin.document.close();
-
-ENDPOP
+=item * %StudentData
- $r->rflush();
-}
+=item * @SelectedStudentData
-# update progress
-sub Update_PrgWin {
- my ($totalStudents,$index,$name)=@_;
- $r->print('');
- $r->rflush();
-}
+=item * $curr_student
-# close Progress Line
-sub Close_PrgWin {
- $r->print('');
- $r->rflush();
-}
+=item * $prev_student
-# For loading the colored table for display or un-colored for print
-sub setbgcolor {
- my $PrintTable=shift;
- undef %color;
- if ($PrintTable){
- $color{"gb"}="#FFFFFF";
- $color{"red"}="#FFFFFF";
- $color{"yellow"}="#FFFFFF";
- $color{"green"}="#FFFFFF";
- $color{"purple"}="#FFFFFF";
- } else {
- $color{"gb"}="#DDFFFF";
- $color{"red"}="#FFDDDD";
- $color{"yellow"}="#EEFFCC";
- $color{"green"}="#DDFFDD";
- $color{"purple"}="#FFDDFF";
- }
+=item * $next_student
- return;
-}
+=back
-sub initial {
- undef %hash;
- undef %CachData;
- undef %GraphDat;
- undef %ConceptData;
- undef $Pos;
- undef $GData;
-}
+$curr_student, $prev_student, and $next_student may not be defined, depending
+upon the calling context.
-#---- END HELPER FUNCTIONS ---------------------------------------------------
+=item get_selected_sections()
-sub BuildProblemStatisticsPage {
- my ($cacheDB, $students)=@_;
+Returns an array of the selected sections
- my %cache;
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER,0640)) {
- $r->print('Unable to tie database.');
- return;
- }
+=item get_selected_groups()
+
+Returns an array of the selected groups
- my $Ptr = '';
- $Ptr .= '
');
-
- $r->print(&ProblemStatisticsLegend());
-
-# my $discriminantFactor;
-# my $list;
-# foreach (@$students) {
-# ($discriminantFactor, $list) = &ExtractStudentData($_);
-# }
-
-# my ($upper, $lower) = &Discriminant($discriminantFactor);
-# my %Header = (0,"Homework Sets Order",1,"#Stdnts",2,"Tries",3,"Mod",
-# 4,"Mean",5,"#YES",6,"#yes",7,"%Wrng",8,"DoDiff",
-# 9,"S.D.",10,"Skew.",11,"D.F.1st",12,"D.F.2nd");
-# &BuildStatisticsTable(\%cache, $discriminantFactor, $list, \%Header);
+=item §ion_and_enrollment_description()
- $r->print('');
+Returns a string describing the currently selected section(s), group(s) and
+access status.
- untie(%cache);
+Inputs: mode = 'plaintext' or 'localized' (defaults to 'localized')
+ 'plaintext' is used for example in Excel spreadsheets.
+Returns: scalar description string.
- return;
-}
+=item section_or_group_text()
-sub BuildDiffGraph {
- my ($courseID)=@_;
+=item get_students()
- my $graphData = &GetGraphData('DiffGraph', $courseID);
- $r->print(' ');
+Returns a list of the selected students
- return;
-}
+=item ¤t_student()
-sub BuildWrongGraph {
- my ($courseID)=@_;
+Returns a pointer to a hash containing data about the currently
+selected student.
- my $graphData = &GetGraphData('WrongGraph', $courseID);
- $r->print(' ');
+=item &previous_student()
- return;
-}
+Returns a pointer to a hash containing data about the student prior
+in the list of students. Or something.
-sub BuildAnalyzePage {
- my ($cacheDB, $students, $courseID)=@_;
+=item &next_student()
- my %cache;
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER,0640)) {
- $r->print('Unable to tie database.');
- return;
- }
+Returns a pointer to a hash containing data about the next student
+to be viewed.
- &ShowOpGraph(\%cache, $students, $courseID);
+=item &StudentDataSelect($elementname,$status,$numvisible,$selected)
- untie(%cache);
+Returns html for a selection box allowing the user to choose one (or more)
+of the fields of student data available (fullname, username, id, section, etc)
- return;
-}
+=over 4
-sub BuildProblemAnalysisPage {
- my ($cacheDB)=@_;
+=item * $elementname The name of the HTML form element
- my %cache;
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER,0640)) {
- $r->print('Unable to tie database.');
- return;
- }
+=item * $status 'multiple' or 'single' selection box
- $r->print(''."\n");
+=item * $numvisible The number of options to be visible
- untie(%cache);
+=back
- return;
-}
+=item &get_selected_maps($elementname)
-sub BuildStudentAssessmentPage {
- my ($cacheDB, $students, $courseID)=@_;
+Input: Name of the form element used to specify the maps.
- my %cache;
+Returns: Array of symbs of selected maps or the description 'all'.
+ If form.$elementname does not exist, 'all' is returned.
- my $Ptr = '';
- $Ptr .= '