\n");
+ my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
+ if (defined($starttime) || defined($endtime)) {
+ # Inform the user what the time limits on the data are.
+ $r->print('
'.&mt('Statistics on submissions from [_1] to [_2]',
+ &Apache::lonlocal::locallocaltime($starttime),
+ &Apache::lonlocal::locallocaltime($endtime)).
+ '
');
+ }
+ $r->print("
".&mt('Compiled on [_1]',
+ &Apache::lonlocal::locallocaltime(time))."
'+
- ''+
- '');
- popwin.document.close();
-
-ENDPOP
+=item &output_html_grouped_by_sequence()
- $r->rflush();
-}
+Presents the statistics data as an html table organized by the order
+the assessments appear in the course.
-# update progress
-sub Update_PrgWin {
- my ($totalStudents,$index,$name,$r)=@_;
- $r->print('');
- $r->rflush();
-}
+=cut
-# close Progress Line
-sub Close_PrgWin {
- my ($r)=@_;
- $r->print('');
- $r->rflush();
-}
-
-# ------ Dump the Student's DB file and handling the data for statistics table
-sub ExtractStudentData {
- my ($cache,$name,$list,$Discuss,$r,$discriminant)=@_;
- my $totalTries = 0;
- my $totalAwarded = 0;
- my $spent=0;
- my $spent_yes=0;
- my $TotDiscuss=0;
- my $TotalOpend = 0;
- my $ProbSolved = 0;
- my $ProbTot = 0;
- my $TotFirst = 0;
- my $TimeTot = 0;
- my $Discussed=0;
- my $discrim='';
- my $tempSequenceOrder=100;
-
-#$Apache::lonxml::debug=1;
-#&Apache::lonhomework::showhash(%$cache);
-#$Apache::lonxml::debug=0;
-
- foreach my $sequence (split(':', $cache->{'orderedSequences'})) {
- my $tempProblemOrder=100;
- if($cache->{'ProblemStatisticsMaps'} ne 'All Maps' &&
- $cache->{'ProblemStatisticsMaps'} ne $cache->{$sequence.':title'}) {
-# $r->print(" sequences=$cache->{'orderedSequences'}");
-# $r->print(" ".$cache->{$sequence.':title'});
- next;
- }
- $tempSequenceOrder++;
-
- #$discrim .= '&';
- foreach my $problemID (split(':', $cache->{$sequence.':problems'})) {
-# $r->print(" problems=$cache->{$sequence.':problems'}");
- my $problem = $cache->{$problemID.':problem'};
-# $r->print(" $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;
- $partData{'count'}=0;
- # 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'})) {
- $tempProblemOrder++;
- $partData{'count'}++;
-# $r->print(" parts=$cache->{$sequence.':'.$problemID.':parts'}");
- $partData{$part.':order'}=$tempProblemOrder;
- $partData{$part.':tries'}=0;
- $partData{$part.':code'}='-';
+###############################################
+###############################################
+sub output_html_grouped_by_sequence {
+ my ($r) = @_;
+ my $problem_num = 0;
+ #$r->print(&ProblemStatisticsLegend());
+ foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) {
+ next if ($sequence->{'num_assess'}<1);
+ $r->print("
".$sequence->{'title'}."
");
+ $r->print('
'."\n");
+ $r->print('
'."\n");
+ $r->print('
');
+ my $Str = &statistics_table_header('no container no plots');
+ $r->print('
'.$Str."
\n");
+ foreach my $resource (@{$sequence->{'contents'}}) {
+ next if ($resource->{'type'} ne 'assessment');
+ foreach my $part (@{$resource->{'parts'}}) {
+ $problem_num++;
+ my $data = &get_statistics($sequence,$resource,$part,
+ $problem_num);
+ my $option = '';
+ $r->print('
\n");
+ #
+ # Print out the data
+ $ENV{'form.sortby'} = 'Contents';
+# &output_html_ungrouped($r);
+ return;
}
+########################################################
+########################################################
=pod
- if ( $Pos == 0 ) {
- foreach my $sequence (split(':', $cache->{'orderedSequences'})) {
- if($cache->{'ProblemStatisticsMaps'} ne 'All Maps' &&
- $cache->{'ProblemStatisticsMaps'} ne $cache->{$sequence.':title'}) {
- next;
- }
- &CreateProblemStatisticsTableHeading($cache->{'DisplayFormat'},
- $cache->{$sequence.':source'},
- $cache->{$sequence.':title'},
- $headings,$r);
-
- my ($tar,$Tries,$Wrongs,$Code,$Disc)=split(/\&/,
- $list[$cIdx]);
- my ($SqOrd,$PrOrd,$Prob)=split(/\:/,$tar);
- $sequence+=100;
- while ($SqOrd==$sequence && $cIdx<$NoElements) {
- my %storestats=();
- my @lpr=split(/\&/,$pr);
- for (my $i=1; $i<=$#lpr; $i++) {
- my($Pre, $Post) = split(/\@/,$list[$nIndex]);
- #$r->print(' '.$Pre.'---'.$Post);
- &TableRow($cache,$Post,$i,$nIndex,$color,\%GraphDat);
- $nIndex++;
- }
- &CloseTable($cache);
- }
- }
- else {
- &CreateProblemStatisticsTableHeading($cache->{'DisplayFormat'},
- $cache->{$sequence.':source'},
- $cache->{$sequence.':title'},
- $headings,$r);
- for ( my $nIndex = 0; $nIndex < $p_count; $nIndex++ ) {
- my($Pre, $Post) = split(/\@/,$list[$nIndex]);
- &TableRow($cache,$Post,$nIndex,$nIndex,$color,\%GraphDat);
- }
- &CloseTable($cache);
- }
+=item &get_statistics()
- return \%TempCache;
-}
+Wrapper routine from the call to loncoursedata::get_problem_statistics.
+Calls lonstathelpers::get_time_limits() to limit the data set by time.
-=cut
+Inputs: $sequence, $resource, $part, $problem_num
+Returns: Hash reference with statistics data from
+loncoursedata::get_problem_statistics.
-sub TableRow {
- my ($cache,$Str,$Idx,$RealIdx,$r,$color,$GraphDat)=@_;
- my($PrOrd,$Temp,$StdNo,$TotalTries,$MxTries,$Avg,$YES,$Override,
- $Wrng,$DoD,$SD,$Sk,$_D1,$_D2,$DiscNo,$Prob)=split(/\&/,$Str);
- my $Ptr;
- if($cache->{'DisplayFormat'} eq 'Display CSV Format') {
- my ($ResId,$Dummy)=split(/\*/,$Prob);
- $Ptr="\n".' '.
- "\n".'"'.($RealIdx+1).'",'.
- "\n".'"'.$cache->{$ResId.':title'}.$Dummy.'",'.
- "\n".'"'.$cache->{$ResId.':source'}.'",'.
- "\n".'"'.$StdNo.'",'.
- "\n".'"'.$TotalTries.'",'.
- "\n".'"'.$MxTries.'",'.
- "\n".'"'.$Avg.'",'.
- "\n".'"'.$YES.'",'.
- "\n".'"'.$Override.'",'.
- "\n".'"'.$Wrng.'",'.
- "\n".'"'.$DoD.'",'.
- "\n".'"'.$SD.'",'.
- "\n".'"'.$Sk.'",'.
- "\n".'"'.$_D1.'",'.
- "\n".'"'.$_D2.'"'.
- "\n".'"'.$DiscNo.'"';
+=cut
- $r->print("\n".$Ptr);
- } else {
- $Ptr="\n".'
'.
- "\n".'
'.($RealIdx+1).'
'.
- # "\n".'
'.$PrOrd.$Temp.'
'.
- "\n".'
'.$Temp.'
'.
- "\n".'
'.$StdNo.'
'.
- "\n".'
'.$TotalTries.'
'.
- "\n".'
'.$MxTries.'
'.
- "\n".'
'.$Avg.'
'.
- "\n".'
'.$YES.'
'.
- "\n".'
'.$Override.'
'.
- "\n".'
'.$Wrng.'
'.
- "\n".'
'.$DoD.'
'.
- "\n".'
'.$SD.'
'.
- "\n".'
'.$Sk.'
'.
- "\n".'
'.$_D1.'
'.
- "\n".'
'.$_D2.'
'.
- "\n".'
'.$DiscNo.'
';
- $r->print("\n".$Ptr.'
' );
- }
- $GraphDat->{'graph_gif:'.$RealIdx}=$DoD.':'.$Wrng;
+########################################################
+########################################################
+sub get_statistics {
+ my ($sequence,$resource,$part,$problem_num) = @_;
+ #
+ my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
+ my $symb = $resource->{'symb'};
+ my $courseid = $ENV{'request.course.id'};
+ #
+ my $data = &Apache::loncoursedata::get_problem_statistics
+ (\@Apache::lonstatistics::SelectedSections,
+ $Apache::lonstatistics::enrollment_status,
+ $symb,$part,$courseid,$starttime,$endtime);
+ $data->{'part'} = $part;
+ $data->{'problem_num'} = $problem_num;
+ $data->{'container'} = $sequence->{'title'};
+ $data->{'title'} = $resource->{'title'};
+ $data->{'title.link'} = $resource->{'src'}.'?symb='.
+ &Apache::lonnet::escape($resource->{'symb'});
+ #
+ return $data;
}
+###############################################
+###############################################
-# For loading the colored table for display or un-colored for print
-sub setbgcolor {
- my $PrintTable=shift;
- my %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";
- }
-
- return \%color;
-}
+=pod
-sub ProblemStatisticsButtons {
- my ($displayFormat)=@_;
+=item &ProblemStatisticsLegend()
- my $Ptr = '
';
- $Ptr .= '';
$Ptr .= '
';
$Ptr .= '#Stdnts
';
- $Ptr .= '
Total Number of Students opened the problem.';
+ $Ptr .= '
Total number of students attempted the problem.';
$Ptr .= '
';
$Ptr .= 'Tries
';
- $Ptr .= '
Total Number of Tries for solving the problem.';
+ $Ptr .= '
Total number of tries for solving the problem.';
$Ptr .= '
';
- $Ptr .= 'Mod
';
- $Ptr .= '
Maximunm Number of Tries for solving the problem.';
+ $Ptr .= 'Max Tries
';
+ $Ptr .= '
Largest number of tries for solving the problem by a student.';
$Ptr .= '
';
$Ptr .= 'Mean
';
- $Ptr .= '
Average Number of the tries. [ Tries / #Stdnts ]';
+ $Ptr .= '
Average number of tries. [ Tries / #Stdnts ]';
$Ptr .= '
';
$Ptr .= '#YES
';
$Ptr .= '
Number of students solved the problem correctly.';
@@ -808,9 +887,9 @@ sub ProblemStatisticsLegend {
$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 .= '%Wrong
';
+ $Ptr .= '
Percentage of students who tried to solve the problem ';
+ $Ptr .= 'but is still incorrect. [ 100*((#Stdnts-(#YES+#yes))/#Stdnts) ]';
$Ptr .= '
';
$Ptr .= 'DoDiff
';
$Ptr .= '
Degree of Difficulty of the problem. ';
@@ -828,8 +907,8 @@ sub ProblemStatisticsLegend {
$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 .= '[Criterion to group students into %27 Upper Students - ';
+ $Ptr .= 'and %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: ';
@@ -838,151 +917,10 @@ sub ProblemStatisticsLegend {
$Ptr .= '
Disc.
';
$Ptr .= '
Number of Students had at least one discussion.';
$Ptr .= '
';
-
return $Ptr;
}
-#------- Processing upperlist and lowerlist according to each problem
-sub ProcessDiscriminant {
- my ($List,$r) = @_;
- my @sortedList = sort (@$List);
- my $Count = scalar @sortedList;
- my $Problem;
- my @Dis;
- my $Slvd=0;
- my $tmp;
- my $Sum1=0;
- my $Sum2=0;
- my $nIndex=0;
- my $nStudent=0;
- my %Proc=undef;
- while ($nIndex<$Count) {
-# $r->print(" $nIndex) $sortedList[$nIndex]");
- ($Problem,$tmp)=split(/\=/,$sortedList[$nIndex]);
- @Dis=split(/\+/,$tmp);
- my $Temp = $Problem;
- do {
- $nIndex++;
- $nStudent++;
- $Sum1 += $Dis[0];
- $Sum2 += $Dis[1];
- ($Problem,$tmp)=split(/\=/,$sortedList[$nIndex]);
- @Dis=split(/\+/,$tmp);
- } while ( $Problem eq $Temp && $nIndex < $Count );
- $Proc{$Temp}=($Sum1/$nStudent).':'.($Sum2/$nStudent);
-# $r->print(" $nIndex) $Temp --> ($nStudent) $Proc{$Temp}");
- $Sum1=0;
- $Sum2=0;
- $nStudent=0;
- }
-
- return %Proc;
-}
-
-#------- Creating Discimination factor
-sub Discriminant {
- my ($discriminant,$r)=@_;
-#$Apache::lonxml::debug=1;
-#&Apache::lonhomework::showhash(%$discriminant);
-#$Apache::lonxml::debug=0;
- my @discriminantKeys=keys(%$discriminant);
- my $Count = scalar @discriminantKeys;
-
- my $UpCnt = int(0.27*$Count);
- my $low=0;
- my $up=$Count-$UpCnt;
- my @UpList=();
- my @LowList=();
-
- $Count=0;
- foreach my $key (sort(@discriminantKeys)) {
- $Count++;
- if($low < $UpCnt || $Count > $up) {
- $low++;
- my $str=$discriminant->{$key};
- foreach(split(/\&/,$str)){
- if($_) {
- if($low<$UpCnt) { push(@LowList,$_); }
- else { push(@UpList,$_); }
- }
- }
- }
- }
- my %DisUp = &ProcessDiscriminant(\@UpList,$r);
- my %DisLow = &ProcessDiscriminant(\@LowList,$r);
-
- return (\%DisUp, \%DisLow);
-}
-
#---- END Problem Statistics Web Page ----------------------------------------
-#---- Problem Statistics Graph Web Page --------------------------------------
-
-# ------------------------------------------- Prepare data for Graphical chart
-
-sub BuildDiffGraph {
- my ($r)=@_;
-
- my $graphData = &GetGraphData('DiffGraph', $r);
- $r->print('');
-
- return;
-}
-
-sub BuildWrongGraph {
- my ($r)=@_;
-
- my $graphData = &GetGraphData('WrongGraph', $r);
- $r->print('');
-
- return;
-}
-
-
-sub GetGraphData {
- my ($ylab,$r,%GraphDat)=@_;
- my $Col;
- my $data='';
- my $count = 0;
- my $Max = 0;
- my $cid=$ENV{'request.course.id'};
- my $GraphDB = "/home/httpd/perl/tmp/$ENV{'user.name'}".
- "_$ENV{'user.domain'}_$cid\_graph.db";
- foreach (keys %GraphDat) {delete $GraphDat{$_};}
- if (-e "$GraphDB") {
- if (tie(%GraphDat,'GDBM_File',"$GraphDB",&GDBM_READER,0640)) {
- if ( $ylab eq 'DoDiff Graph' ) {
- $ylab = 'Degree-of-Difficulty';
- $Col = 0;
- }
- else {
- $ylab = 'Wrong-Percentage';
- $Col = 1;
- }
- foreach (sort NumericSort keys %GraphDat) {
- my @Temp=split(/\:/,$GraphDat{$_});
- my $inf = $Temp[$Col];
- if ( $Max < $inf ) {$Max = $inf;}
- $data .= $inf.',';
- $count++;
- }
- if ( $Max > 1 ) {
- $Max += (10 - $Max % 10);
- $Max = int($Max);
- }
- else { $Max = 1; }
- untie(%GraphDat);
- my $Course = $ENV{'course.'.$cid.'.description'};
- $Course =~ s/\ /"_"/eg;
- my $GData=$Course.'&'.'Problems'.'&'.$ylab.'&'.
- $Max.'&'.$count.'&'.$data;
- }
- else {
- $r->print("Unable to tie hash to db file");
- }
- }
-}
-
-
1;
__END__