[LON-CAPA-cvs] cvs: loncom /interface/statistics lonproblemstatistics.pm
matthew
lon-capa-cvs@mail.lon-capa.org
Wed, 26 Mar 2003 21:47:47 -0000
This is a MIME encoded message
--matthew1048715267
Content-Type: text/plain
matthew Wed Mar 26 16:47:47 2003 EDT
Modified files:
/loncom/interface/statistics lonproblemstatistics.pm
Log:
Added graph output.
Added problem number accounting to &output_html* subroutines.
Added parameter $option to &output_html_ungrouped to deal with the display
of problem numbers.
Removed &stats_row_from_hash because it was dumb.
Modified &statistics_html_table_data to take an $options string instead
of a flag.
Removed &BuildGraphicChart, &CreateProblemStatisticsTableHeading
&BuildStatisticsTable, &TableRow, &setbgcolor, and
&ProblemStatisticsButtons.
Added &plot_statistics
Rewrote &DrawGraph entirely. Requires version 1.21 of graph.png.
--matthew1048715267
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20030326164747.txt"
Index: loncom/interface/statistics/lonproblemstatistics.pm
diff -u loncom/interface/statistics/lonproblemstatistics.pm:1.44 loncom/interface/statistics/lonproblemstatistics.pm:1.45
--- loncom/interface/statistics/lonproblemstatistics.pm:1.44 Wed Mar 26 12:03:41 2003
+++ loncom/interface/statistics/lonproblemstatistics.pm Wed Mar 26 16:47:47 2003
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: lonproblemstatistics.pm,v 1.44 2003/03/26 17:03:41 matthew Exp $
+# $Id: lonproblemstatistics.pm,v 1.45 2003/03/26 21:47:47 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -233,6 +233,12 @@
} elsif ($output_mode eq 'excel') {
$r->print("<h2>Preparing Excel Spreadsheet</h2>");
&output_excel($r);
+ } elsif ($output_mode eq 'plot') {
+ if ($show eq 'deg of diff') {
+ &plot_statistics($r,'DoDiff');
+ } elsif ($show eq 'per wrong') {
+ &plot_statistics($r,'%Wrng');
+ }
} else {
$r->print("<h1>Not implemented</h1>");
}
@@ -246,6 +252,7 @@
###############################################
sub output_html_grouped_by_sequence {
my ($r) = @_;
+ my $problem_num = 0;
#$r->print(&ProblemStatisticsLegend());
my @Header = ("Title","Part","#Stdnts","Tries","Mod",
"Mean","#YES","#yes","%Wrng","DoDiff",
@@ -262,6 +269,7 @@
foreach my $resource (@{$sequence->{'contents'}}) {
next if ($resource->{'type'} ne 'assessment');
foreach my $part (@{$resource->{'parts'}}) {
+ $problem_num++;
my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD,
$SKEW) = &Apache::loncoursedata::get_problem_statistics
(undef,$resource->{'symb'},$part,
@@ -274,10 +282,12 @@
if (defined($num) && $num > 0) {
$wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10;
}
+ my $option = '';
+ $option .= 'no part' if (! $show_part);
$r->print('<tr>'.&statistics_html_table_data
($resource,$part,$num,$tries,$mod,$mean,$Solved,
$solved,$wrongpercent,$DegOfDiff,$STD,$SKEW,
- $show_part).
+ $option).
"</tr>\n");
}
}
@@ -295,8 +305,9 @@
###############################################
###############################################
sub output_html_ungrouped {
- my ($r) = @_;
+ my ($r,$option) = @_;
#
+ my $problem_num = 0;
my $show_container = 0;
my $show_part = 0;
#$r->print(&ProblemStatisticsLegend());
@@ -313,12 +324,18 @@
if (! defined($sortby) || $sortby eq '') {
$sortby = 'Container';
}
- # #FFFFE6 #EEFFCC #DDFFFF FFDDDD #DDFFDD #FFDDFF
+ # If there is more than one sequence, list their titles
my @Sequences = &Apache::lonstatistics::Sequences_with_Assess();
if (@Sequences > 1) {
unshift(@Header,"Container");
$show_container = 1;
}
+ #
+ # If the option for showing the problem number is needed, push that
+ # on the list too
+ if (defined($option) && $option =~ /show probnum/) {
+ unshift(@Header,"P#");
+ }
#
$r->print('<table border="0"><tr><td bgcolor="#777777">'."\n");
$r->rflush();
@@ -330,6 +347,7 @@
foreach my $resource (@{$sequence->{'contents'}}) {
next if ($resource->{'type'} ne 'assessment');
foreach my $part (@{$resource->{'parts'}}) {
+ $problem_num++;
my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD,
$SKEW) = &Apache::loncoursedata::get_problem_statistics
(undef,$resource->{'symb'},$part,
@@ -357,6 +375,7 @@
'DoDiff' => $DegOfDiff,
'S.D.' => $STD,
'Skew' => $SKEW,
+ 'problem_num' => $problem_num,
});
}
}
@@ -368,7 +387,7 @@
foreach (@Header) {
next if ($_ eq 'Part' && !$show_part);
# Do not allow sorting on some fields
- if ($_ eq $sortby || /^(Part)$/) {
+ if ($_ eq $sortby || /^(Part|P\#)$/) {
$Str .= '<th>'.$_.'</th>';
} else {
$Str .= '<th>'.
@@ -417,13 +436,23 @@
} @Statsarray;
}
}
+ $option .= ',no part' if (! $show_part);
foreach my $row (@OutputOrder) {
$r->print('<tr>');
+ if (defined($option) && $option =~ /show probnum/) {
+ $r->print('<td bgcolor="#FFFFE6">'.$row->{'problem_num'}.'</td>');
+ }
if ($show_container) {
$r->print('<td bgcolor="#FFFFE6">'
.$row->{'sequence'}->{'title'}.'</td>');
}
- $r->print(&stats_row_from_hash($row,$show_part));
+ $r->print(&statistics_html_table_data
+ ($row->{'resource'},$row->{'Part'},$row->{'#Stdnts'},
+ $row->{'Tries'},$row->{'Mod'},$row->{'Mean'},
+ $row->{'#YES'},$row->{'#yes'},$row->{"\%Wrng"},
+ $row->{'DoDiff'},$row->{'S.D.'},$row->{'Skew'},
+ $option));
+
$r->print("</tr>\n");
}
$r->print("</table>\n");
@@ -433,16 +462,6 @@
return;
}
-sub stats_row_from_hash {
- my ($data,$show_part) = @_;
- return &statistics_html_table_data($data->{'resource'},$data->{'Part'},
- $data->{'#Stdnts'}, $data->{'Tries'},
- $data->{'Mod'}, $data->{'Mean'},
- $data->{'#YES'}, $data->{'#yes'},
- $data->{"\%Wrng"}, $data->{'DoDiff'},
- $data->{'S.D.'}, $data->{'Skew'},
- $show_part);
-}
###############################################
###############################################
@@ -565,17 +584,20 @@
return;
}
+###############################################
+###############################################
-
+###############################################
+###############################################
sub statistics_html_table_data {
my ($resource,$part,$num,$tries,$mod,$mean,$Solved,$solved,$wrongpercent,
- $DegOfDiff,$STD,$SKEW,$show_part) = @_;
+ $DegOfDiff,$STD,$SKEW,$options) = @_;
my $row = '';
$row .= '<td bgcolor="#FFFFE6">'.
'<a href="'.$resource->{'src'}.'" target="_blank" >'.
$resource->{'title'}.'</a>'.
'</td>';
- $row .= '<td bgcolor="#FFFFE6">'.$part.'</td>' if ($show_part);
+ $row .= '<td bgcolor="#FFFFE6">'.$part.'</td>' if ($options !~ /no part/);
foreach ($num,$tries) {
$row .= '<td bgcolor="#EEFFCC" align="right">'.$_.'</td>';
}
@@ -597,71 +619,110 @@
return $row;
}
-
###############################################
###############################################
-
-sub BuildGraphicChart {
- my ($graph,$cacheDB,$courseDescription,$students,$courseID,$r,$c)=@_;
- my %cache;
- my $max;
- my $title = '';
- if($graph eq 'DoDiffGraph') {
- $title = 'Degree-of-Difficulty';
- } else {
- $title = 'Wrong-Percentage';
- }
- my $currentSequence = -1;
- my $sortProblems = 'Sort Within Sequence';
- my ($result, $orderedProblems) =
- &InitializeProblemStatistics($cacheDB, $students, $courseID, $c, $r);
- if($result ne 'OK') {
- return;
+sub plot_statistics {
+ my ($r,$datafield) = @_;
+ my @Data;
+ #
+ my %Fields = ('#Stdnts'=> 0,
+ 'Tries' => 1,
+ 'Mod' => 2,
+ 'Mean' => 3,
+ '#YES' => 4,
+ '#yes' => 5,
+ '%Wrng' => 9,
+ 'DoDiff' => 6,
+ 'S.D.' => 7,
+ 'Skew' => 8,);
+ #
+ my $field = '%Wrng';
+ foreach (keys(%Fields)) {
+ $field = $_ if ($datafield eq $_);
}
- my @values = ();
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
- return 'Unable to tie database.7';
- }
- foreach(@$orderedProblems) {
- my ($sequence,$problem,$part)=split(':', $_);
- if($cache{'StatisticsMaps'} ne 'All Maps' &&
- $cache{'StatisticsMaps'} ne $cache{$sequence.':title'}) {
- next;
- }
- if( $currentSequence == -1 ||
- ($sortProblems eq 'Sort Within Sequence' &&
- $currentSequence != $sequence)) {
- if($currentSequence != -1) {
- &DrawGraph(\@values,$courseDescription,$title,$max,$r);
- }
- if($sortProblems eq 'Sort Within Sequence') {
- $r->print('<br><b>'.$cache{$sequence.':title'}.'</b>'."\n");
+ my $fieldindex = $Fields{$field};
+ #
+ my $Max = 0;
+ foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) {
+ next if ($sequence->{'num_assess'}<1);
+ foreach my $resource (@{$sequence->{'contents'}}) {
+ next if ($resource->{'type'} ne 'assessment');
+ foreach my $part (@{$resource->{'parts'}}) {
+ my @Results = &Apache::loncoursedata::get_problem_statistics
+ (undef,$resource->{'symb'},$part,
+ $ENV{'request.course.id'});
+ my ($num,$Solved,$solved) = @Results[0,4,5];
+ my $wrongpercent = 0;
+ if (defined($num) && $num > 0) {
+ $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10;
+ }
+ push (@Results,$wrongpercent);
+ my $data = $Results[$fieldindex];
+ $Max = $data if ($Max<$data);
+ push (@Data,$data);
}
- $currentSequence = $sequence;
- @values = ();
- $max=0;
- }
- my $data = 0;
- if($graph eq 'DoDiffGraph') {
- $data = sprintf("%.2f", $cache{$_.':degreeOfDifficulty'}),
- } else {
- $data = sprintf("%.1f", $cache{$_.':percentWrong'}),
}
- if($max < $data) {
- $max = $data;
+ }
+ #
+ # Print out plot request
+ my $title = 'Percent Wrong';
+ if ($field eq 'DoDiff') {
+ $title = 'Degree of Difficulty';
+ }
+ my $yaxis = 'Percent';
+ if ($field eq 'DoDiff') {
+ $yaxis = '';
+ } elsif ($field ne '%Wrng') {
+ $yaxis = '';
+ }
+ #
+ # Determine appropriate value for $Max
+ if ($field eq 'DoDiff') {
+ if ($Max > 0.5) {
+ $Max = 1;
+ } elsif ($Max > 0.2) {
+ $Max = 0.5;
+ } elsif ($Max > 0.1) {
+ $Max = 0.2;
+ }
+ } elsif ($field eq '%Wrng') {
+ if ($Max > 50) {
+ $Max = 100;
+ } elsif ($Max > 25) {
+ $Max = 50;
+ } elsif ($Max > 20) {
+ $Max = 25;
+ } elsif ($Max > 10) {
+ $Max = 20;
+ } elsif ($Max > 5) {
+ $Max = 10;
+ } else {
+ $Max = 5;
}
- push(@values, $data);
}
- untie(%cache);
- &DrawGraph(\@values,$courseDescription,$title,$max,$r);
+
+ $r->print("<p>".&DrawGraph(\@Data,$title,'Problem Number',$yaxis,
+ $Max)."</p>\n");
+ #
+ # Print out the data
+ $ENV{'form.sortby'} = 'Contents';
+ &output_html_ungrouped($r,'show probnum');
return;
}
+###############################################
+###############################################
+
+###############################################
+###############################################
sub DrawGraph {
- my ($values,$courseDescription,$title,$Max,$r)=@_;
+ my ($values,$title,$xaxis,$yaxis,$Max)=@_;
+ $title = '' if (! defined($title));
+ $xaxis = '' if (! defined($xaxis));
+ $yaxis = '' if (! defined($yaxis));
+ #
my $sendValues = join(',', @$values);
my $sendCount = scalar(@$values);
- $r->print("<br>The Maximum Value is: $Max");
if ( $Max > 1 ) {
if ($Max % 10) {
if ( int($Max) < $Max ) {
@@ -669,196 +730,19 @@
$Max = int($Max);
}
}
- #(10 - $Max % 10);
- } else { $Max = 1; }
- my @GData = ('','Problem_number',$title,$Max,$sendCount,$sendValues);
-# $r->print('</form>'."\n");
- $r->print('<br>'."\n");
- $r->print('<IMG src="/cgi-bin/graph.png?'.
- (join('&', @GData)).'" border="1" />');
-# $r->print('<form>'."\n");
- $r->print('<br>'."\n");
-}
-
-#---- Problem Statistics Web Page ---------------------------------------
-sub CreateProblemStatisticsTableHeading {
- my ($headings,$r)=@_;
- my $Str='';
- $Str .= '<tr>'."\n";
- $Str .= '<th bgcolor="#ffffe6">P#</th>'."\n";
- foreach(@$headings) {
- $Str .= '<th bgcolor="#ffffe6">';
- $Str .= '<a href="/adm/statistics?reportSelected=';
- $Str .= &Apache::lonnet::escape('Problem Statistics');
- $Str .= '&ProblemStatisticsSort=';
- $Str .= &Apache::lonnet::escape($_).'">'.$_.'</a> </th>'."\n";
- }
- $Str .= "\n".'</tr>'."\n";
- return $Str;
-}
-
-sub BuildStatisticsTable {
- my ($cache,$displayFormat,$sortProblems,$orderedProblems,$headings,
- $r,$color)=@_;
- my $count = 1;
- my $currentSequence = -1;
- foreach(@$orderedProblems) {
- my ($sequence,$problem,$part)=split(':', $_);
- if($cache->{'StatisticsMaps'} ne 'All Maps' &&
- $cache->{'StatisticsMaps'} ne $cache->{$sequence.':title'}) {
- next;
- }
- if($currentSequence == -1 ||
- ($sortProblems eq 'Sort Within Sequence' &&
- $currentSequence != $sequence)) {
- if($displayFormat ne 'Display CSV Format') {
- if($currentSequence ne -1) {
- $r->print('</table>');
- $r->print('</td></tr></table><br>');
- }
- if($sortProblems eq 'Sort Within Sequence') {
- $r->print('<b>'.$cache->{$sequence.':title'}.'</b>');
- }
- $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n");
- $r->print('<table border="0" cellpadding="3">'."\n");
- $r->print(&CreateProblemStatisticsTableHeading($headings, $r));
- } else {
- if($sortProblems eq 'Sort Within Sequence') {
- $r->print('"'.$cache->{$sequence.':title'}.'"');
- }
- $r->print('<br>');
- }
- $currentSequence = $sequence;
- }
- my $ref = '<a href="'.$cache->{$problem.':source'}.
- '" target="_blank">'.$cache->{$problem.':title'}.'</a>';
- my $title = $cache->{$problem.':title'};
- if($part != 0) {
- $title .= ' Part '.$part;
- }
- my $source = $cache->{$problem.':source'};
- my $tableData = join('&', $ref, $title, $source,
- $cache->{$_.':studentCount'},
- $cache->{$_.':totalTries'},
- $cache->{$_.':maxTries'},
- $cache->{$_.':mean'},
- $cache->{$_.':correct'},
- $cache->{$_.':correctByOverride'},
- $cache->{$_.':percentWrong'},
- $cache->{$_.':degreeOfDifficulty'},
- $cache->{$_.':standardDeviation'},
- $cache->{$_.':skewness'},
- $cache->{$_.':discriminationFactor1'},
- $cache->{$_.':discriminationFactor2'});
- &TableRow($displayFormat,$tableData,$count,$r,$color);
- $count++;
- }
- if($displayFormat ne 'Display CSV Format') {
- $r->print('</table>'."\n");
- $r->print('</td></tr></table>');
- } else {
- $r->print('<br>');
- }
- return;
-}
-
-sub TableRow {
- my ($displayFormat,$Str,$RealIdx,$r,$color)=@_;
- my($ref,$title,$source,$StdNo,$TotalTries,$MxTries,$Avg,$YES,$Override,
- $Wrng,$DoD,$SD,$Sk,$_D1,$_D2)=split(/\&/,$Str);
- my $Ptr;
- if($displayFormat eq 'Display CSV Format') {
- $Ptr='"'.$RealIdx.'",'."\n".
- '"'.$title.'",'."\n".
- '"'.$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".
- "<br>\n";
- $r->print("\n".$Ptr);
- } else {
- $Ptr='<tr>'."\n".
- '<td bgcolor="#ffffe6">'.$RealIdx.'</td>'."\n".
- '<td bgcolor="#ffffe6">'.$ref.'</td>'."\n".
- '<td bgcolor='.$color->{"yellow"}.'> '.$StdNo.'</td>'."\n".
- '<td bgcolor='.$color->{"yellow"}.'>'.$TotalTries.'</td>'."\n".
- '<td bgcolor='.$color->{"yellow"}.'>'.$MxTries.'</td>'."\n".
- '<td bgcolor='.$color->{"gb"}.'>'.$Avg.'</td>'."\n".
- '<td bgcolor='.$color->{"gb"}.'> '.$YES.'</td>'."\n".
- '<td bgcolor='.$color->{"gb"}.'> '.$Override.'</td>'."\n".
- '<td bgcolor='.$color->{"red"}.'> '.$Wrng.'</td>'."\n".
- '<td bgcolor='.$color->{"red"}.'> '.$DoD.'</td>'."\n".
- '<td bgcolor='.$color->{"green"}.'> '.$SD.'</td>'."\n".
- '<td bgcolor='.$color->{"green"}.'> '.$Sk.'</td>'."\n".
- '<td bgcolor='.$color->{"purple"}.'> '.$_D1.'</td>'."\n".
- '<td bgcolor='.$color->{"purple"}.'> '.$_D2.'</td>'."\n";
- $r->print($Ptr.'</tr>'."\n");
+ } else {
+ $Max = 1;
}
- return;
+ my @GData = ($title,$xaxis,$yaxis,$Max,$sendCount,$sendValues);
+ return '<IMG src="/cgi-bin/graph.png?'.
+ (join('&', @GData)).'" border="1" />';
}
-# 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;
-}
-
-sub ProblemStatisticsButtons {
- my ($displayFormat, $displayLegend, $sortProblems)=@_;
- my $Ptr = '<tr><td></td><td align="left">';
- $Ptr .= '<input type="submit" name="DoDiffGraph" ';
- $Ptr .= 'value="Plot Degree of Difficulty" />'."\n";
- $Ptr .= '</td><td align="left">';
- $Ptr .= '<input type="submit" name="PercentWrongGraph" ';
- $Ptr .= 'value="Plot Percent Wrong" />'."\n";
- $Ptr .= '</td></tr><tr><td></td><td>'."\n";
- $Ptr .= '<input type="submit" name="SortProblems" ';
- if($sortProblems eq 'Sort All Problems') {
- $Ptr .= 'value="Sort Within Sequence" />'."\n";
- } else {
- $Ptr .= 'value="Sort All Problems" />'."\n";
- }
- $Ptr .= '</td><td align="left">';
- $Ptr .= '<input type="submit" name="DisplayLegend" ';
- if($displayLegend eq 'Show Legend') {
- $Ptr .= 'value="Hide Legend" />'."\n";
- } else {
- $Ptr .= 'value="Show Legend" />'."\n";
- }
- $Ptr .= '</td><td align="left">';
- $Ptr .= '<input type="submit" name="DisplayCSVFormat" ';
- if($displayFormat eq 'Display CSV Format') {
- $Ptr .= 'value="Display Table Format" />'."\n";
- } else {
- $Ptr .= 'value="Display CSV Format" />'."\n";
- }
- $Ptr .= '</td></tr>';
- return $Ptr;
-}
+###############################################
+###############################################
+###############################################
+###############################################
sub ProblemStatisticsLegend {
my $Ptr = '';
$Ptr = '<table border="0">';
--matthew1048715267--