Annotation of capa/capa51/Historic/bubblersurveyexam.c, revision 1.2
1.2 ! albertel 1: /* scantron control program for named surveys
! 2: Copyright (C) 1992-2000 Michigan State University
! 3:
! 4: The CAPA system is free software; you can redistribute it and/or
! 5: modify it under the terms of the GNU Library General Public License as
! 6: published by the Free Software Foundation; either version 2 of the
! 7: License, or (at your option) any later version.
! 8:
! 9: The CAPA system is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 12: Library General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU Library General Public
! 15: License along with the CAPA system; see the file COPYING. If not,
! 16: write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
! 17: Boston, MA 02111-1307, USA.
! 18:
! 19: As a special exception, you have permission to link this program
! 20: with the TtH/TtM library and distribute executables, as long as you
! 21: follow the requirements of the GNU GPL in regard to all of the
! 22: software in the executable aside from TtH/TtM.
! 23: */
! 24:
1.1 albertel 25: #include <stdio.h>
26: #include "Capa/capaCommon.h"
27: #include "bubbler.h"
28:
29:
30: #include <ctype.h>
31:
32: #ifdef __sun
33: #include <unistd.h> /* lockf() */
34: #endif
35:
36: #include "capaParser.h"
37: #include "capaToken.h"
38: #include "ranlib.h"
39: /*********************************************/
40: /* flock() in SUN is in BSD compatibility lib */
41: /* #include <sys/file.h> */
42:
43: #ifdef F_DBUG
44: extern FILE *dfp;
45: #endif
46:
47:
48: /********************************************************** file locking */
49: int
50: flockstream_sh(sp) FILE *sp;
51: {
52: int fd;
53:
54: fd = fileno(sp);
55:
56: #ifdef __sun
57: return ( lockf(fd,F_LOCK, 0L) );
58: #else
59: return (flock(fd,LOCK_SH));
60: #endif
61: }
62:
63: int
64: flockstream(sp) FILE *sp;
65: {
66: int fd;
67:
68: fd = fileno(sp);
69:
70: #ifdef __sun
71: return ( lockf(fd,F_LOCK, 0L) );
72: #else
73: return (flock(fd,LOCK_EX));
74: #endif
75: }
76: int
77: funlockstream(sp) FILE *sp;
78: {
79: int fd;
80:
81: fd = fileno(sp);
82:
83: #ifdef __sun
84: return ( lockf(fd,F_ULOCK, 0L) );
85: #else
86: return (flock(fd,LOCK_UN));
87: #endif
88: }
89:
90: char *
91: capa_malloc(num,sz) unsigned num,sz;
92: {
93: char *p;
94: p = calloc(num, sz);
95: return (p);
96: }
97:
98:
99: /****************************************************** Database Entry */
100: int /* RETURNS: error code */
101: capa_set_entry(entry, student_number, set, offset)
102: T_entry *entry; /* pointer to entry structure to fill in */
103: char *student_number;
104: int set;
105: long offset;
106: {
107: FILE *fp;
108: int errcode=0;
109: int len;
110: char filename[FILE_NAME_LENGTH];
111: char a_line[512];
112:
113: sprintf(filename,"records/set%d.db",set);
114: if ((fp=fopen(filename,"r+"))==NULL) {
115: printf("Error: can't open %s\n",filename); return (-1);
116: }
117: sprintf(a_line,"%s %s,%s\n",entry->student_number,entry->answers,entry->tries);
118: len = strlen(a_line);
119: flockstream(fp);
120: fseek(fp,offset,0);
121: if (!fwrite(a_line,len,1,fp) ) {
122: printf("Error writing data to file\n");
123: errcode= (-1);
124: }
125: funlockstream(fp);
126: fclose(fp);
127: return (errcode);
128: }
129:
130: /**************************************************** Get db entry*/
131:
132: long /* RETURNS: byte offset to start of record, 0 if error,
133: -offset if not found & newly created */
134: capa_get_entry(entry, student_number, set)
135: T_entry *entry;
136: char *student_number;
137: int set;
138: {
139: char filename[FILE_NAME_LENGTH];
140: FILE *fp;
141: int len, nq;
142: char *ans_p, *tries_p, oneline[512],fmtbuf[128];
143: long offset, next_r;
144: int ii, done=0, found=0;
145: char a_sn[MAX_STUDENT_NUMBER+1];
146:
147: sprintf(filename,"records/set%d.db",set);
148: if ((fp=fopen(filename,"r"))==NULL) {
149: printf("Error: can't open %s\n",filename);
150: return (-1);
151: }
152: sprintf(entry->student_number,"%s",student_number);
153: sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
154: flockstream(fp);
155: fgets(oneline,511,fp); len = strlen(oneline); sscanf(oneline,"%d",&nq);
156: ans_p = capa_malloc(nq+1,1); tries_p = capa_malloc(3*nq,1);
157: fgets(oneline,511,fp); /* skip weight line */
158: fgets(oneline,511,fp); /* hand grading */
159: done = 0;
160: while(!done) {
161: done = !fgets(oneline,511,fp); len = strlen(oneline);
162: if( !done ) {
163: sscanf(oneline,fmtbuf,a_sn);
164: if( !strncasecmp(a_sn,student_number,MAX_STUDENT_NUMBER) ) { /* Found */
165: next_r = ftell(fp); offset = next_r - len; done = 1; found = 1;
166: }
167: } else {
168: fseek(fp,0L,SEEK_END);
169: offset = ftell(fp); /* last byte, if last bye is cr, back up one */
170: fseek(fp,-1L,SEEK_END);
171: while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
172: offset = offset +2; /* last char and cr */
173: found = 0; done=1;
174: }
175: }
176: funlockstream(fp); fclose(fp);
177: if(!found) {
178: for(ii=0;ii<nq;ii++) { /* Initialize answer string and tries string */
179: ans_p[ii] = '-'; tries_p[3*ii] = ' '; tries_p[3*ii + 1] = '0';
180: if(ii < nq-1) tries_p[3*ii + 2] = ',';
181: }
182: entry->answers = ans_p;
183: entry->tries = tries_p;
184: capa_set_entry(entry,student_number,set,offset);
185: offset = -offset;
186: } else {
187: sprintf(fmtbuf, "%%%dc",nq);
188: sscanf(oneline + MAX_STUDENT_NUMBER+1,fmtbuf,ans_p);
189: sprintf(fmtbuf, "%%%dc",(3*nq-1));
190: sscanf(oneline + MAX_STUDENT_NUMBER+1+nq+1,fmtbuf,tries_p);
191: entry->answers = ans_p;
192: entry->tries = tries_p;
193: }
194: return (offset);
195: }
196:
197: int main()
198: {
199: T_entry grade,examgrade;
200: FILE * inputFile, * outputFile;
201: int i=0,setnumber,score,section,setId,done=0,numQuestions,examSetId;
202: char class[10],set[3],name[MAX_NAME_CHAR+1],buf,buffmt[128],
203: studentnumber[MAX_STUDENT_NUMBER+1],filename[128];
204: int q=0,r=0,answerTop[MAXQUEST][11],answerMid[MAXQUEST][11],
205: answerBot[MAXQUEST][11],examtotal=0,firstDiv,secondDiv;
206: Question questions[MAXQUEST];
207:
208: printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
209: printf("Covert form Bubbler output to survey results ");
210: printf("Version 0.1.00\n");
211: printf("Please enter the Set Id number. of survey");
212: scanf("%d",&setId);
213: printf("Please enter the SetId of the Final exam.");
214: scanf("%d",&examSetId);
215: printf("Please enter score of first divison.");
216: scanf("%d",&firstDiv);
217: printf("Please enter score of second divison.");
218: scanf("%d",&secondDiv);
219: sprintf(filename,"bubbler.output.%d",setId);
220: inputFile=fopen(filename,"r");
221:
222: if (inputFile==NULL)
223: {
224: fprintf(stderr,"%s not found\n",filename);
225: exit(-1);
226: }
227:
228: fscanf(inputFile,"%s %s",class,set);
229: printf("%s %s\n",class,set);
230: setnumber=atoi(set);
231:
232: i=0;
233: fscanf(inputFile,"%c",&buf);
234: while(!done)
235: {
236: buf=fgetc(inputFile);
237: if (buf!='\n')
238: {
239: questions[i].type=buf;
240: buf=fgetc(inputFile);
241: questions[i].points=questions[i].leafs=(int)(buf-'0');
242: i++;
243: }
244: else
245: {
246: done=1;
247: }
248: }
249:
250: numQuestions=i;
251:
252: for(q=0;q<MAXQUEST;q++)
253: for(r=0;r<11;r++)
254: {
255: answerTop[q][r]=0;
256: answerMid[q][r]=0;
257: answerBot[q][r]=0;
258: }
259:
260: printf("Processing");
261: while(fscanf(inputFile,"%s",studentnumber)!=EOF)
262: {
263: examtotal=0;
264: printf(".");
265: fflush(stdout);
266: fscanf(inputFile,"%32c",name);
267: sprintf(buffmt,"%%%dc",numQuestions);
268: fscanf(inputFile,buffmt,grade.answers);
269: fscanf(inputFile,"%d",&score);
270: fscanf(inputFile,"%d",§ion);
271: buf='\0';
272: while(buf!='\n')
273: {
274: buf=fgetc(inputFile);
275: }
276: capa_get_entry(&examgrade,studentnumber,examSetId);
277:
278: #ifdef DEBUG
279: printf("%d %d\n",numQuestions,strlen(grade.answers));
280: #endif /*DEBUG*/
281:
282: for(i=0;i<numQuestions;i++)
283: {
284: switch(examgrade.answers[i])
285: {
286: case 'Y':
287: case 'y':
288: i=0;
289: fprintf(stderr,"Skipping %s b/c of Ys\n",studentnumber);
290: goto skip_student;
291: break;
292: case 'N':
293: case 'n':
294: i=0;
295: fprintf(stderr,"Skipping %s b/c of Ns\n",studentnumber);
296: goto skip_student;
297: break;
298: case ' ':
299: case '-':
300: i=0;
301: fprintf(stderr,"Skipping %s b/c not complete\n",studentnumber);
302: goto skip_student;
303: break;
304: default:
305: if (isdigit(examgrade.answers[i]))
306: {
307: examtotal+=(int)(examgrade.answers[i]-'0');
308: }
309: else
310: {
311: i=0;
312: fprintf(stderr,"Skipping %s b/c weird\n",studentnumber);
313: goto skip_student;
314: }
315: break;
316: }
317: }
318: for(i=0;i<numQuestions;i++)
319: {
320: switch(questions[i].type)
321: {
322: case 'a':
323: case 'f':
324: case 'g':
325: case 'b':
326: case 'c':
327: case 'e':
328: case 'd':
329: if (isdigit(grade.answers[i]))
330: {
331: if (examtotal < firstDiv)
332: answerBot[i][grade.answers[i]-'0']++;
333: else if (examtotal < secondDiv)
334: answerMid[i][grade.answers[i]-'0']++;
335: else
336: answerTop[i][grade.answers[i]-'0']++;
337: }
338: else if(isspace(grade.answers[i]))
339: {
340: if (examtotal < firstDiv)
341: answerBot[i][10]++;
342: else if (examtotal < secondDiv)
343: answerMid[i][10]++;
344: else
345: answerTop[i][10]++;
346: }
347: break;
348: default:
349: printf("Unknown question type\n");
350: break;
351: }
352: }
353: skip_student:
354: grade.answers[i]='\0';
355: #ifdef DEBUG
356: printf("%s\n",studentnumber);
357: #endif /*DEBUG*/
358: }
359:
360: sprintf(filename,"surveyexam.%d",setId);
361: outputFile=fopen(filename,"w");
362: if (outputFile==NULL)
363: {
364: fprintf(stderr,"%s not found\n",filename);
365: exit(-1);
366: }
367:
368: fprintf(outputFile,"Bottom Third:\n");
369: for(q=0;q<numQuestions;q++)
370: {
371: fprintf(outputFile,"Question: %d\n",q+1);
372: fprintf(outputFile," 0 1 2 3 4 5 6 7 8 9 S\n");
373: for(r=0;r<11;r++)
374: {
375: fprintf(outputFile,"%3d ",answerBot[q][r]);
376: }
377: fprintf(outputFile,"\n");
378: }
379: fprintf(outputFile,"\014Middle Third:\n");
380: for(q=0;q<numQuestions;q++)
381: {
382: fprintf(outputFile,"Question: %d\n",q+1);
383: fprintf(outputFile," 0 1 2 3 4 5 6 7 8 9 S\n");
384: for(r=0;r<11;r++)
385: {
386: fprintf(outputFile,"%3d ",answerMid[q][r]);
387: }
388: fprintf(outputFile,"\n");
389: }
390: fprintf(outputFile,"\014Top Third:\n");
391: for(q=0;q<numQuestions;q++)
392: {
393: fprintf(outputFile,"Question: %d\n",q+1);
394: fprintf(outputFile," 0 1 2 3 4 5 6 7 8 9 S\n");
395: for(r=0;r<11;r++)
396: {
397: fprintf(outputFile,"%3d ",answerTop[q][r]);
398: }
399: fprintf(outputFile,"\n");
400: }
401: printf("\nProcessing completed. Look in survey.%d for results.\n",
402: setId);
403: return 0;
404: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>