#!/usr/local/bin/perl # # generate a file fit for the MSU scoring office # Copyright (C) 1992-2000 Michigan State University # # The CAPA system is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # The CAPA system is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public # License along with the CAPA system; see the file COPYING. If not, # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # As a special exception, you have permission to link this program # with the TtH/TtM library and distribute executables, as long as you # follow the requirements of the GNU GPL in regard to all of the # software in the executable aside from TtH/TtM. # Feb. 19 1997 by Isaac Tsai # require('getopts.pl'); $Usage = "USAGE: so.rpt.pl [-s start_set][-t end_set]"; # # ask user to enter the absolute path to the class # sub S_Enterpath { local($set,$to)=@_; local($notdone,$path); local($cfullpath); $notdone = 1; while ($notdone) { print "Please enter the CLASS absolute path:\n"; $path = <>; chomp($path); if( $path =~ /\/$/ ) { # check if the path entered contains a trailing / $Cfullpath = "$path" . "classl"; $Rfullpath = "$path" . "records"; $Sfullpath = "$path" . "records/set$set.db"; } else { $Cfullpath = "$path" . "/classl"; $Rfullpath = "$path" . "/records"; $Sfullpath = "$path" . "/records/set$set.db"; } if( -d $path ) { # check if the class directory exists if( -d $Rfullpath ) { # check if the records directory exists if( -f $Sfullpath ) { # check if the setX.db file exists $notdone = 0; } else { print "File [$Sfullpath] does not exist!\n"; } } else { print "Directory [$Rfullpath] does not exist!\n"; } } else { print "Directory [$path] does not exist!\n"; } } return ($path); } # # scan the setX.db file # sub S_ScanDB { local($filename,$idx)=@_; local($line_cnt)=0; local($valid_cnt)=0; local($valid); local($ii); local($head,$s_num,$ans_str,$rest); local(@ans_char,@tries); local($score,$Snum); open(IN, "<$filename") || die "Cannot open $filename file!"; while () { $line_cnt++; # line count in setX.db file if( $line_cnt == 2 ) { # the second line is the weight information chomp(); (@Weight) = split(/ */); # split the weight string into an integer array } if( $line_cnt > 3) { # valid student record begins with the fourth line chomp(); # remove the trailing \n ($head,$rest) = split(/,/,$_,2); # split the entry based on the first comma ($s_num,$ans_str) = split(/ /,$head,2); # split the head part based on space char (@ans_char) = split(/ */,$ans_str); # split the answer string into an array of chars (@tries) = split(/,/,$rest); # split the number of tries string into an array of integer for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) { # if all char in the answer is '-', mark it as invalid $valid = 'Y' if $ans_char[$ii] ne '-'; } if( $valid eq 'Y' ) { # a valid entry, contains some scoring info for($score=0,$ii=0;$ii<=$#ans_char;$ii++) { # number of elements in the answer char array if($ans_char[$ii] eq 'Y') { # big Y, score adds the weight of that problem $score += $Weight[$ii]; } if($ans_char[$ii] eq 'y') { # small y, score adds the weight of that problem $score += $Weight[$ii]; } if( $ans_char[$ii] >= 0 && $ans_char[$ii] <= 9) { # hand graded problem has numerical value $score += $ans_char[$ii]; } } $Snum = uc($s_num); # uppercase the student number $$Snum[$idx] = $score; # put the score into an array named as the student number and indexed by $valid_cnt++; # offset of set in the scoring report } } } close(IN) || die "Cannot close $filename file!"; return ($#tries+1,$valid_cnt); } # 1 2 3 4 - 5 6 7 8 #2345678901234567890123456789012345678901234567890123456789012345678901234567890 #nnnnnnnnnnnnnnnnn aaaaaaaaa sec scor scor scor # # produce the scoring report based on entries from classl file # sub S_ClassRpt { local($filename)=@_; local($code,$cn,$sec,$sid,$sname); local($a_line,$cnt,$i); local($score,$len,$pad); local($sm,$Snum); open(IN, "<$filename") || die "cannot open file $filename!\n"; while() { $a_line = $_; # each line in the classl file ($code,$cn,$sec,$sid,$sname) = split(/\s+/,$a_line,5); # use space to divide each field chomp($sname); # chop off the last \n $len = length($sname); # student name length if( $len < 18 ) { # if name is less than 18 characters, padded to 18 chars $pad = 18 - $len; $sm = "$sname" . " " x $pad; } else { # more than 18 chars, take the first 18 characters $sm = substr("$sname",0,18); # take the first 18 characters } printf "%s %s %03d ", $sm,$sid,$sec; # print out student name, student number, section $Snum = uc($sid); # uppercase the student number if( defined @{$Snum} ) { # if we have the scores for this student $cnt = $#{$Snum}; # the number of sets in this scoring array for($i=0;$i<=$cnt;$i++) { # loop through the number of sets $score = $$Snum[$i]; # assign the score to a variable, (extra step) printf " %4d", $score; } } print "\n"; # at the end of the record, place an \n } close(IN) || die "cannot close file $filename!\n"; } if(! &Getopts('s:t:') ) { print STDERR "$Usage\n"; exit 2; } if( (!$opt_s) || ($opt_s <= 0 ) ) { $opt_s = 1; } if( (!$opt_t) || ($opt_t <= 0 ) ) { $opt_t = 1; } if( $opt_t < $opt_s ) { $tmp = $opt_t; $opt_t = $opt_s; $opt_s = $tmp; } $CPath = S_Enterpath($opt_s,$opt_t); # get the class path for($set_idx=$opt_s;$set_idx<=$opt_t;$set_idx++) { # loop through each set $set_offset = $set_idx - $opt_s; $fullpath = "$CPath" . "/records/set$set_idx.db"; S_ScanDB("$fullpath",$set_offset); } S_ClassRpt("$Cfullpath"); # produce the scoring report