Total Number of Students opened the problem.';
- $Ptr .= '
';
- $Ptr .= 'Tries:
';
- $Ptr .= '
Total Number of Tries for solving the problem.';
- $Ptr .= '
';
- $Ptr .= 'Mod:
';
- $Ptr .= '
Maximunm Number of Tries for solving the problem.';
- $Ptr .= '
';
- $Ptr .= 'Mean:
';
- $Ptr .= '
Average Number of the tries. [ Tries / #Stdnts ]';
- $Ptr .= '
';
- $Ptr .= '#YES:
';
- $Ptr .= '
Number of students solved the problem correctly.';
- $Ptr .= '
';
- $Ptr .= '#yes:
';
- $Ptr .= '
Number of students solved the problem by override.';
- $Ptr .= '
';
- $Ptr .= '%Wrng:
';
- $Ptr .= '
Percentage of students tried to solve the problem ';
- $Ptr .= 'but still incorrect. [ 100*((#Stdnts-(#YES+#yes))/#Stdnts) ]';
- $Ptr .= '
';
-# Kashy formula
-# ' DoDiff : Degree of Difficulty of the problem. '.
-# '[ Tries/(#YES+#yes+0.1) ] '.
- #Gerd formula
- $Ptr .= 'DoDiff:
';
- $Ptr .= '
Degree of Difficulty of the problem. ';
- $Ptr .= '[ 1 - ((#YES+#yes) / Tries) ]';
- $Ptr .= '
';
- $Ptr .= 'S.D.:
';
- $Ptr .= '
Standard Deviation of the tries. ';
- $Ptr .= '[ sqrt(sum((Xi - Mean)^2)) / (#Stdnts-1) ';
- $Ptr .= 'where Xi denotes every student\'s tries ]';
- $Ptr .= '
';
- $Ptr .= 'Skew.:
';
- $Ptr .= '
Skewness of the students tries.';
- $Ptr .= '[(sqrt( sum((Xi - Mean)^3) / #Stdnts)) / (S.D.^3)]';
- $Ptr .= '
';
- $Ptr .= 'Dis.F.:
';
- $Ptr .= '
Discrimination Factor: A Standard for evaluating the ';
- $Ptr .= 'problem according to a Criterion ';
- $Ptr .= '[Applied Criterion in %27 Upper Students - ';
- $Ptr .= 'Applied the same Criterion in %27 Lower Students] ';
- $Ptr .= '1st Criterion for Sorting the Students: ';
- $Ptr .= 'Sum of Partial Credit Awarded / Total Number of Tries ';
- $Ptr .= '2nd Criterion for Sorting the Students: ';
- $Ptr .= 'Total number of Correct Answers / Total Number of Tries';
- $Ptr .= '
';
+=item $next_student
- return $Ptr;
-}
+=back
-#---- END Problem Statistics Web Page ----------------------------------------
+$curr_student, $prev_student, and $next_student may not be defined, depending
+upon the calling context.
-#---- Problem Statistics Graph Web Page --------------------------------------
+=cut
-sub GetGraphData {
- my ($whichGraph, $courseID)=@_;
- my $Col=0;
- my $graphTitle='';
- my $data='';
- my $count = 0;
- my $Max = 0;
- my $graphData='Graph data does not exist.';
- my $GraphDB = "/home/httpd/perl/tmp/$ENV{'user.name'}".
- "_$ENV{'user.domain'}_$courseID\_graph.db";
- if(-e $GraphDB) {
- if(tie(%GraphDat,'GDBM_File',"$GraphDB",&GDBM_READER,0640)) {
- if($whichGraph eq 'DiffGraph') {
- $graphTitle = 'Degree-of-Difficulty';
- $Col = 0;
- } else {
- $graphTitle = 'Wrong-Percentage';
- $Col = 1;
- }
- foreach (sort NumericSort keys %GraphDat) {
- my @Temp=split(/\:/,$GraphDat{$_});
- my $inf = $Temp[$Col];
- if($Max < $inf) {
- $Max = $inf;
+#######################################################
+#######################################################
+sub PrepareClasslist {
+ my %Sections;
+ &clear_classlist_variables();
+ #
+ # Retrieve the classlist
+ my $cid = $env{'request.course.id'};
+ my $cdom = $env{'course.'.$cid.'.domain'};
+ my $cnum = $env{'course.'.$cid.'.num'};
+ my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cdom,
+ $cnum);
+ my @selected_sections = &get_selected_sections();
+ my @selected_groups = &get_selected_groups();
+ #
+ # Deal with instructors with restricted section access
+ if ($env{'request.course.sec'} !~ /^\s*$/) {
+ @selected_sections = ($env{'request.course.sec'});
+ }
+ #
+ # Set up %StudentData
+ @StudentDataOrder = qw/fullname username domain id section status groups comments/;
+ foreach my $field (@StudentDataOrder) {
+ $StudentData{$field}->{'title'} = &mt($field);
+ $StudentData{$field}->{'base_width'} = length(&mt($field));
+ $StudentData{$field}->{'width'} =
+ $StudentData{$field}->{'base_width'};
+ }
+ #
+ # get the status requested
+ $enrollment_status = 'Active';
+ $enrollment_status = $env{'form.Status'} if (exists($env{'form.Status'}));
+ #
+ # Get groupmembership
+ my (%curr_groups,$classgroups,$studentgroups);
+ my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
+ if ($numgroups) {
+ ($classgroups,$studentgroups) =
+ &Apache::loncoursedata::get_group_memberships($classlist,
+ $cdom,$cnum);
+ }
+ my $now = time;
+
+ # Process the classlist
+ while (my ($student,$student_data) = each (%$classlist)) {
+ my $studenthash = ();
+ for (my $i=0; $i< scalar(@$field_names);$i++) {
+ my $field = $field_names->[$i];
+ # Store the data
+ $studenthash->{$field}=$student_data->[$i];
+ # Keep track of the width of the fields
+ next if (! exists($StudentData{$field}));
+ my $length = length($student_data->[$i]);
+ if ($StudentData{$field}->{'width'} < $length) {
+ $StudentData{$field}->{'width'} = $length;
+ }
+ }
+ my @studentsgroups = &Apache::loncoursedata::get_students_groups
+ ($student,$enrollment_status,
+ $classgroups);
+ if (@studentsgroups) {
+ $studenthash->{'groups'} = join(', ',@studentsgroups);
+ $studenthash->{'groupref'} = \@studentsgroups;
+ } else {
+ $studenthash->{'groups'} = 'none';
+ $studenthash->{'groupref'} = [];
+ }
+ push (@FullClasslist,$studenthash);
+ #
+ # Build up a list of sections
+ my $section = $studenthash->{'section'};
+ if (! defined($section) || $section =~/^\s*$/ || $section == -1) {
+ $studenthash->{'section'} = 'none';
+ $section = $studenthash->{'section'};
+ }
+ $Sections{$section}++;
+ #
+ # Only put in the list those students we are interested in
+ foreach my $sect (@selected_sections) {
+ if ( (($sect eq 'all') ||
+ ($section eq $sect)) &&
+ (($studenthash->{'status'} eq $enrollment_status) ||
+ ($enrollment_status eq 'Any'))
+ ){
+ my $groupcheck = 0;
+ if (grep/^all$/,@selected_groups) {
+ push (@Students,$studenthash);
+ last;
+ } elsif (grep/^none$/,@selected_groups) {
+ if ($studenthash->{'groups'} eq 'none') {
+ push (@Students,$studenthash);
+ last;
+ }
+ } else {
+ foreach my $group (@selected_groups) {
+ if (grep/^$group$/,@studentsgroups) {
+ push (@Students,$studenthash);
+ $groupcheck = 1;
+ last;
+ }
+ }
+ if ($groupcheck) {
+ last;
+ }
}
- $data .= $inf.',';
- $count++;
- }
- if($Max > 1) {
- $Max += (10 - $Max % 10);
- $Max = int($Max);
- } else {
- $Max = 1;
}
- untie(%GraphDat);
- my $Course = $ENV{'course.'.$courseID.'.description'};
- $Course =~ s/\ /"_"/eg;
- $graphData = $Course.'&'.'Problems'.'&'.$graphTitle.'&'.$Max.'&';
- $graphData .= $count.'&'.$data;
- } else {
- $graphData = "Unable to tie hash to db file";
- }
+ }
}
-
- return $graphData;
-}
-
-#---- END Problem Statistics Graph Web Page ----------------------------------
-
-#---- Problem Analysis Web Page ----------------------------------------------
-
-sub IntervalOptions {
- my ($cache)=@_;
-
- my $interval = 1;
- for(my $n=1; $n<=7; $n++) {
- if($cache->{'Interval'} == $n) {
- $interval = $n;
+ #
+ # Put the consolidated section data in the right place
+ if ($env{'request.course.sec'} !~ /^\s*$/) {
+ @Sections = ($env{'request.course.sec'});
+ } else {
+ @Sections = sort {$a cmp $b} keys(%Sections);
+ unshift(@Sections,'all'); # Put 'all' at the front of the list
+ }
+ # Sort the groups
+ @Groups = sort {$a cmp $b} keys(%{$studentgroups});
+ unshift(@Groups,'all'); # Put 'all' at the front of the list
+
+ #
+ # Sort the Students
+ my $sortby = 'fullname';
+ $sortby = $env{'form.sort'} if (exists($env{'form.sort'}));
+ my @TmpStudents = sort { lc($a->{$sortby}) cmp lc($b->{$sortby}) ||
+ lc($a->{'fullname'}) cmp lc($b->{'fullname'}) ||
+ lc($a->{'username'}) cmp lc($b->{'username'}) } @Students;
+ @Students = @TmpStudents;
+ #
+ # Now deal with that current student thing....
+ $curr_student = undef;
+ if (exists($env{'form.SelectedStudent'})) {
+ my ($current_uname,$current_dom) =
+ split(':',$env{'form.SelectedStudent'});
+ my $i;
+ for ($i = 0; $i<=$#Students; $i++) {
+ next if (($Students[$i]->{'username'} ne $current_uname) ||
+ ($Students[$i]->{'domain'} ne $current_dom));
+ $curr_student = $Students[$i];
+ last; # If we get here, we have our student.
+ }
+ if (defined($curr_student)) {
+ if ($i == 0) {
+ $prev_student = undef;
+ } else {
+ $prev_student = $Students[$i-1];
+ }
+ if ($i == $#Students) {
+ $next_student = undef;
+ } else {
+ $next_student = $Students[$i+1];
+ }
}
}
-
- my $Ptr = ' Select number of intervals'."\n".
- ''."\n";
-
- return $Ptr;
+ #
+ return;
}
-sub OptionResponseTable {
- my ($cache)=@_;
- my $Str = '';
- $Str .= ' Option Response Problems in this course:'."\n";
- $Str .= '
'."\n";
- $Str .= "
\#
Problem Title
";
- $Str .= '
Resource
Analysis
'."\n";
-
- my $number=1;
- foreach (split(':::',$cache->{'OptionResponses'})) {
- my ($uri,$title,$part,$problem)=split('::',$_);
- my $Temp = ''.$title.'';
- $Str .= '
';
- $Str .= '
'.$number.'
';
- $Str .= '
'.$Temp.'
';
- $Str .= '
'.$uri.'
';
- $Str .= '
'."\n";
- $number++;
- }
- $Str .= '
'."\n";
+#######################################################
+#######################################################
- return $Str;
-}
+=pod
-#---- END Problem Analysis Web Page ------------------------------------------
+=item get_selected_sections
-#---- Student Assessment Web Page --------------------------------------------
+Returns an array of the selected sections
-sub MapOptions {
- my ($cache, $page)=@_;
- my $Ptr = '
';
- $Ptr .= '
Select Map
'."\n";
- $Ptr .= '
'."\n";
-
- return $Ptr;
+ return $text;
}
-# ------ Create different Student Report
-sub StudentReport {
- my ($cache, $name)=@_;
-
- my $Str = '';
- if($cache->{$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;
- }
- 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'}='-';
- }
+=pod
- # 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;
- }
+=item get_students
- my $tries=0;
- my $code='U';
+Returns a list of the selected students
- $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;
- }
- }
+=cut
- # 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'}.',';
- }
- }
- $codes =~ s/,$//;
- $attempts =~ s/,$//;
- $Str .= '
');
-
- $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);
+##############################################
+##############################################
- $r->print('');
+=pod
- untie(%cache);
+=item &map_select($elementname,$status,$numvisible,$restriction)
- return;
-}
+Returns html for a selection box allowing the user to choose one (or more)
+of the sequences in the course. The values of the sequences are the symbs.
+If the top sequence is selected, the value 'top' will result.
-sub BuildDiffGraph {
- my ($courseID)=@_;
-
- my $graphData = &GetGraphData('DiffGraph', $courseID);
- $r->print('');
+=over 4
- return;
-}
+=item $elementname The name of the HTML form element
-sub BuildWrongGraph {
- my ($courseID)=@_;
+=item $status 'multiple' or 'single' selection box
- my $graphData = &GetGraphData('WrongGraph', $courseID);
- $r->print('');
+=item $numvisible The number of options to be visible
- return;
-}
+=back
-sub BuildAnalyzePage {
- my ($cacheDB, $students, $courseID)=@_;
+=cut
- my %cache;
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER,0640)) {
- $r->print('Unable to tie database.');
+##############################################
+##############################################
+sub map_select {
+ my ($elementname,$status,$numvisible)=@_;
+ if ($numvisible < 1) {
return;
}
+ #
+ # Set up array of selected items
+ my @selected_maps = &get_selected_maps($elementname);
+ #
+ # Build the form element
+ my $form = "\n";
+ $form .= '\n";
+ return $form;
+}
- &ShowOpGraph(\%cache, $students, $courseID);
+##############################################
+##############################################
- untie(%cache);
+=pod
- return;
-}
+=item &SectionSelect($elementname,$status,$numvisible)
-sub BuildProblemAnalysisPage {
- my ($cacheDB)=@_;
+Returns html for a selection box allowing the user to choose one (or more)
+of the sections in the course.
- my %cache;
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER,0640)) {
- $r->print('Unable to tie database.');
- return;
- }
-
- $r->print(''."\n");
+Uses the package variables @Sections
+=over 4
- untie(%cache);
+=item $elementname The name of the HTML form element
- return;
-}
+=item $status 'multiple' or 'single' selection box
-sub BuildStudentAssessmentPage {
- my ($cacheDB, $students, $courseID)=@_;
+=item $numvisible The number of options to be visible
- my %cache;
+=back
- my $Ptr = '';
- $Ptr .= '