#!/usr/bin/perl # Reads in grades on exam problems and spits out stats formatted as an # html table. Each line consists of the grades for a single student (tab # separated). The first line consists of the headers; the second line is # the maximum score for each column. Use this by copying & pasting the # gradebook entries from Excel or OpenOffice into a textfile (it should # automatically tab-delimit them) and then pointing the script at the file. # This assumes you are storing each student as a row and each grade item # as a column. use lib "/home/math/gbutler/lib/perl5"; use Statistics::Descriptive; $indent = 4 x " "; $headerLine = <>; chomp($headerLine); @headerList = split(/\t/,$headerLine); $maxLine = <>; chomp($maxLine); @maxList = split(/\t/,$maxLine); @stud = (); while(<>) { chomp; @line = split(/\t/); push(@stud,[@line]); } @stat = (); @notAttempted = (); for($i = 0; $i <= $#headerList; $i++) { #assumes all lines have the same numer of fields, expect runtime errors otherwise @gradeCol = (); #list of all student's grades for a single gradebook entry $numNotSubmitted[$i] = 0; for($j = 0; $j <= $#stud; $j++) { if(defined($stud[$j][$i]) && $stud[$j][$i] ne "") { push(@gradeCol,$stud[$j][$i]); } else { $numNotSubmitted[$i]++; } } push(@stat,Statistics::Descriptive::Full->new()); $stat[$#stat]->add_data(@gradeCol); } print "\n"; print $indent . "\n"; for($i = 0; $i <= $#stat; $i++) { $stat[$i]->sort_data(); @gradeCol = $stat[$i]->get_data(); $indf = 0; $inddm = -1; $indd = -1; $inddp = -1; $indcm = -1; $indc = -1; $indcp = -1; $indbm = -1; $indb = -1; $indbp = -1; $indam = -1; $inda = -1; $indap = -1; for($j = 0; $j <= $#gradeCol; $j++) { if($inddm == -1 && $gradeCol[$j] >= 0.57*$maxList[$i]) { $inddm = $j; } if($indd == -1 && $gradeCol[$j] >= 0.60*$maxList[$i]) { $indd = $j; } if($inddp == -1 && $gradeCol[$j] >= 0.63*$maxList[$i]) { $inddp = $j; } if($indcm == -1 && $gradeCol[$j] >= 0.67*$maxList[$i]) { $indcm = $j; } if($indc == -1 && $gradeCol[$j] >= 0.70*$maxList[$i]) { $indc = $j; } if($indcp == -1 && $gradeCol[$j] >= 0.73*$maxList[$i]) { $indcp = $j; } if($indbm == -1 && $gradeCol[$j] >= 0.77*$maxList[$i]) { $indbm = $j; } if($indb == -1 && $gradeCol[$j] >= 0.80*$maxList[$i]) { $indb = $j; } if($indbp == -1 && $gradeCol[$j] >= 0.83*$maxList[$i]) { $indbp = $j; } if($indam == -1 && $gradeCol[$j] >= 0.87*$maxList[$i]) { $indam = $j; } if($inda == -1 && $gradeCol[$j] >= 0.90*$maxList[$i]) { $inda = $j; } if($indap == -1 && $gradeCol[$j] > $maxList[$i]) { $indap = $j; } } $numf = ($indf >= 0) ? (($inddm >= 0) ? ($inddm - $indf ) : (1 + $#gradeCol - $indf )) : 0; $numdm = ($inddm >= 0) ? (($indd >= 0) ? ($indd - $inddm) : (1 + $#gradeCol - $inddm)) : 0; $numd = ($indd >= 0) ? (($inddp >= 0) ? ($inddp - $indd ) : (1 + $#gradeCol - $indd )) : 0; $numdp = ($inddp >= 0) ? (($indcm >= 0) ? ($indcm - $inddp) : (1 + $#gradeCol - $inddp)) : 0; $numcm = ($indcm >= 0) ? (($indc >= 0) ? ($indc - $indcm) : (1 + $#gradeCol - $indcm)) : 0; $numc = ($indc >= 0) ? (($indcp >= 0) ? ($indcp - $indc ) : (1 + $#gradeCol - $indc )) : 0; $numcp = ($indcp >= 0) ? (($indbm >= 0) ? ($indbm - $indcp) : (1 + $#gradeCol - $indcp)) : 0; $numbm = ($indbm >= 0) ? (($indb >= 0) ? ($indb - $indbm) : (1 + $#gradeCol - $indbm)) : 0; $numb = ($indb >= 0) ? (($indbp >= 0) ? ($indbp - $indb ) : (1 + $#gradeCol - $indb )) : 0; $numbp = ($indbp >= 0) ? (($indam >= 0) ? ($indam - $indbp) : (1 + $#gradeCol - $indbp)) : 0; $numam = ($indam >= 0) ? (($inda >= 0) ? ($inda - $indam) : (1 + $#gradeCol - $indam)) : 0; $numa = ($inda >= 0) ? (($indap >= 0) ? ($indap - $inda ) : (1 + $#gradeCol - $inda )) : 0; $numap = ($indap >= 0) ? (1 + $#gradeCol - $indap) : 0; ($p75,$p75i)=$stat[$i]->percentile(75); ($p25,$p25i)=$stat[$i]->percentile(25); $p25 = $stat[$i]->median() if($p25 == ""); $p75 = $stat[$i]->median() if($p75 == ""); print $indent . "\n"; } print "
 Points PossibleA+ (>100)A (90-100)A- (87-89)B+ (83-86)B (80-82)B- (77-79)C+ (73-76)C (70-72)C- (67-69)D+ (63-66)D (60-62)D- (57-59)F (0-56)Not SubmittedMeanStandard DeviationMaxQ3MedianQ1Min
" . $headerList[$i] . "" . join("",($maxList[$i],$numap,$numa,$numam,$numbp,$numb,$numbm,$numcp,$numc,$numcm,$numdp,$numd,$numdm,$numf,$numNotSubmitted[$i],sprintf("%.3lf",$stat[$i]->mean()),sprintf("%.3lf",$stat[$i]->standard_deviation()),$stat[$i]->max(),$p75,$stat[$i]->median(),$p25,$stat[$i]->min())) . "
\n";