Annotation of capa/capa51/CapaTools/examanalysis.pl, revision 1.3
1.1 albertel 1: #!/usr/local/bin/perl
1.2 albertel 2: # exam statistics for CAPA
3: # Copyright (C) 1992-2000 Michigan State University
4: #
5: # The CAPA system is free software; you can redistribute it and/or
1.3 ! albertel 6: # modify it under the terms of the GNU General Public License as
1.2 albertel 7: # published by the Free Software Foundation; either version 2 of the
8: # License, or (at your option) any later version.
9: #
10: # The CAPA system is distributed in the hope that it will be useful,
11: # but WITHOUT ANY WARRANTY; without even the implied warranty of
12: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.3 ! albertel 13: # General Public License for more details.
1.2 albertel 14: #
1.3 ! albertel 15: # You should have received a copy of the GNU General Public
1.2 albertel 16: # License along with the CAPA system; see the file COPYING. If not,
17: # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18: # Boston, MA 02111-1307, USA.
19: #
20: # As a special exception, you have permission to link this program
21: # with the TtH/TtM library and distribute executables, as long as you
22: # follow the requirements of the GNU GPL in regard to all of the
23: # software in the executable aside from TtH/TtM.
24:
1.1 albertel 25:
26: #
27: # June 17 1997 by Isaac Tsai
28: #
29:
30: require('getopts.pl');
31: $Usage = "USAGE: examanalysis.pl [-s start_set][-t end_set]";
32: #
33: # ask user to enter the absolute path to the class
34: #
35: sub S_Enterpath {
36: local($set,$to)=@_;
37: local($notdone,$path);
38: local($cfullpath);
39:
40: $notdone = 1;
41: while ($notdone) {
42: print "Please enter the CLASS absolute path:\n";
43: $path = <>; chomp($path);
44: if( $path =~ /\/$/ ) { # check if the path entered contains a trailing /
45: $Cfullpath = "$path" . "classl";
46: $Rfullpath = "$path" . "records";
47: $Sfullpath = "$path" . "records/set$set.db";
48: } else {
49: $Cfullpath = "$path" . "/classl";
50: $Rfullpath = "$path" . "/records";
51: $Sfullpath = "$path" . "/records/set$set.db";
52: }
53: if( -d $path ) { # check if the class directory exists
54: if( -d $Rfullpath ) { # check if the records directory exists
55: if( -f $Sfullpath ) { # check if the setX.db file exists
56: $notdone = 0;
57: } else {
58: print "File [$Sfullpath] does not exist!\n";
59: }
60: } else {
61: print "Directory [$Rfullpath] does not exist!\n";
62: }
63: } else {
64: print "Directory [$path] does not exist!\n";
65: }
66:
67: }
68: return ($path);
69: }
70:
71: #
72: # scan the setX.db file
73: #
74: sub S_ScanDB {
75: local($filename,$idx)=@_;
76: local($line_cnt)=0;
77: local($valid_cnt)=0;
78: local($valid);
79: local($ii);
80: local($head,$s_num,$ans_str,$rest);
81: local(@ans_char,@tries);
82: local($score,$Snum);
83:
84: open(IN, "<$filename") || die "Cannot open $filename file!";
85: while (<IN>) {
86: $line_cnt++; # line count in setX.db file
87: if( $line_cnt == 2 ) { # the second line is the weight information
88: chomp();
89: (@Weight) = split(/ */); # split the weight string into an integer array
90: }
91: if( $line_cnt > 3) { # valid student record begins with the fourth line
92: chomp(); # remove the trailing \n
93: ($head,$rest) = split(/,/,$_,2); # split the entry based on the first comma
94: ($s_num,$ans_str) = split(/ /,$head,2); # split the head part based on space char
95:
96: (@ans_char) = split(/ */,$ans_str); # split the answer string into an array of chars
97: (@tries) = split(/,/,$rest); # split the number of tries string into an array of integer
98: for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) { # if all char in the answer is '-', mark it as invalid
99: $valid = 'Y' if $ans_char[$ii] ne '-';
100: }
101: if( $valid eq 'Y' ) { # a valid entry, contains some scoring info
102: for($score=0,$ii=0;$ii<=$#ans_char;$ii++) { # number of elements in the answer char array
103: if($ans_char[$ii] eq 'Y') { # big Y, score adds the weight of that problem
104: $score += $Weight[$ii];
105: }
106: if($ans_char[$ii] eq 'y') { # small y, score adds the weight of that problem
107: $score += $Weight[$ii];
108: }
109: if( $ans_char[$ii] >= 0 && $ans_char[$ii] <= 9) { # hand graded problem has numerical value
110: $score += $ans_char[$ii];
111: }
112: }
113: $Snum = uc($s_num); # uppercase the student number
114: $$Snum[$idx] = $score; # put the score into an array named as the student number and indexed by
115: $valid_cnt++; # offset of set in the scoring report
116: }
117: }
118: }
119: close(IN) || die "Cannot close $filename file!";
120: return ($#tries+1,$valid_cnt);
121: }
122: # 1 2 3 4 - 5 6 7 8
123: #2345678901234567890123456789012345678901234567890123456789012345678901234567890
124: #nnnnnnnnnnnnnnnnn aaaaaaaaa sec scor scor scor
125: #
126: # produce the scoring report based on entries from classl file
127: #
128: sub S_ClassRpt {
129: local($filename)=@_;
130: local($code,$cn,$sec,$sid,$sname);
131: local($a_line,$cnt,$i);
132: local($score,$len,$pad);
133: local($sm,$Snum);
134:
135: open(IN, "<$filename") || die "cannot open file $filename!\n";
136: while(<IN>) {
137: $a_line = $_; # each line in the classl file
138: ($code,$cn,$sec,$sid,$sname) = split(/\s+/,$a_line,5); # use space to divide each field
139: chomp($sname); # chop off the last \n
140: $len = length($sname); # student name length
141: if( $len < 18 ) { # if name is less than 18 characters, padded to 18 chars
142: $pad = 18 - $len;
143: $sm = "$sname" . " " x $pad;
144: } else { # more than 18 chars, take the first 18 characters
145: $sm = substr("$sname",0,18); # take the first 18 characters
146: }
147: printf "%s %s %03d ", $sm,$sid,$sec; # print out student name, student number, section
148: $Snum = uc($sid); # uppercase the student number
149: if( defined @{$Snum} ) { # if we have the scores for this student
150: $cnt = $#{$Snum}; # the number of sets in this scoring array
151: for($i=0;$i<=$cnt;$i++) { # loop through the number of sets
152: $score = $$Snum[$i]; # assign the score to a variable, (extra step)
153: printf " %4d", $score;
154: }
155: }
156: print "\n"; # at the end of the record, place an \n
157: }
158: close(IN) || die "cannot close file $filename!\n";
159: }
160:
161:
162: if(! &Getopts('s:t:') ) {
163: print STDERR "$Usage\n";
164: exit 2;
165: }
166:
167: if( (!$opt_s) || ($opt_s <= 0 ) ) {
168: $opt_s = 1;
169: }
170: if( (!$opt_t) || ($opt_t <= 0 ) ) {
171: $opt_t = 1;
172: }
173: if( $opt_t < $opt_s ) {
174: $tmp = $opt_t;
175: $opt_t = $opt_s;
176: $opt_s = $tmp;
177: }
178: $CPath = S_Enterpath($opt_s,$opt_t); # get the class path
179:
180: for($set_idx=$opt_s;$set_idx<=$opt_t;$set_idx++) { # loop through each set
181: $set_offset = $set_idx - $opt_s;
182: $fullpath = "$CPath" . "/records/set$set_idx.db";
183: S_ScanDB("$fullpath",$set_offset);
184: }
185:
186: S_ClassRpt("$Cfullpath"); # produce the scoring report
187:
188:
189:
190:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>