Annotation of capa/capa51/Historic/bubbler.c, revision 1.1.1.1
1.1 albertel 1: #include <stdio.h>
2: #include <sgtty.h>
3: #include <libc.h>
4: #include <sys/types.h>
5: #include <sys/uio.h>
6: #include <ctype.h>
7: #include "Capa/capaCommon.h"
8: #include "bubbler.h"
9:
10: int serportfd;
11: int readportfd;
12: FILE * readport;
13: int CheckPIN;
14: int CompareClassName;
15: int Anon;
16: int CheckSpaces;
17: int SurveyMode;
18: int SurveyHeader;
19: int formNumber;
20:
21: int GetProblems(Question questions[MAXQUEST],char * class,int * setId)
22: {
23: int i,q,length;
24: char clear[100];
25:
26: printf("What is the class name?");
27: scanf("%s",class);
28:
29: printf("What is the SetId?");
30: scanf("%d",setId);
31:
32: printf("Is this a survey or exam/quiz?(s or e)");
33: scanf("%s",clear);
34: if (clear[0]=='s' || clear[0]=='S')
35: {
36: SurveyMode=1;
37: printf("Does the form include a Header?(y or n)");
38: scanf("%s",clear);
39: if (clear[0]=='n' || clear[0]=='N')
40: {
41: SurveyHeader=0;
42: }
43: else
44: {
45: SurveyHeader=1;
46: }
47: printf("How many Questions are on the form?");
48: scanf("%d",&q);
49:
50: for (i=0;i<q;i++)
51: {
52: questions[i].type='d';
53: questions[i].leafs=questions[i].points=9;
54: }
55: }
56: else
57: {
58: SurveyMode=0;
59:
60: printf("Should bubbler compare the entered class name and SetId with \n");
61: printf("the encoded information on each paper?(y or n)");
62: scanf("%s",clear);
63: if (clear[0]=='N' || clear[0]=='n')
64: CompareClassName=0;
65: else
66: CompareClassName=1;
67:
68: printf("Should the student coded CAPA ID be checked for correctness?\n");
69: printf("(y or n)");
70: scanf("%s",clear);
71: if (clear[0]=='N' || clear[0]=='n')
72: CheckPIN=0;
73: else
74: {
75: CheckPIN=1;
76:
77: printf("Should bubbler run in Anonymous mode (search for correct \n");
78: printf("Student Number based on the CAPA ID)? (y or n)");
79: scanf("%s",clear);
80:
81: if (clear[0]=='N' || clear[0]=='n')
82: Anon=0;
83: else
84: Anon=1;
85: }
86:
87: printf("Should bubbler check for blank answers and issue a warning when \n");
88: printf("one is encountered? (y or n)");
89: scanf("%s",clear);
90: if (clear[0]=='N' || clear[0]=='n')
91: CheckSpaces=0;
92: else
93: CheckSpaces=1;
94:
95: length=strlen(class);
96: if (length < 8)
97: {
98: for(;length<8;length++)
99: {
100: class[length]=' ';
101: }
102: class[length]='\0';
103: }
104: printf("How many Questions are on the form?");
105: scanf("%d",&q);
106:
107: printf("For Each Question enter \"a\" for a one out of 8\n");
108: printf(" \"b\" for a GLE type\n");
109: printf(" \"c\" for a TF type.\n");
110: printf(" \"d\" for an assigned score.\n");
111: printf(" \"e\" for a multiple out of 8.\n");
112: printf(" \"f\" for single digit string matching.\n");
113: printf(" \"g\" for exact string matching/\n");
114:
115: for (i=0;i<q;i++)
116: {
117: printf("Question#%2d: ",i+1);
118: scanf("%1s",&questions[i].type);
119: fflush(stdin);
120: switch(questions[i].type)
121: {
122: case 'a':
123: case 'd':
124: case 'g':
125: case 'f':
126: printf("How many Points are possible?");
127: scanf("%d",&questions[i].points);
128: questions[i].leafs=questions[i].points;
129: break;
130: case 'b':
131: case 'c':
132: printf("How many parts to the problem?");
133: scanf("%d",&questions[i].points);
134: questions[i].leafs=questions[i].points;
135: break;
136: case 'e':
137: printf("How many possible answers are there?");
138: scanf("%d",&questions[i].points);
139: questions[i].leafs=questions[i].points;
140: break;
141: default:
142: printf("Unknown choice.\n");
143: break;
144: }
145: fflush(stdin);
146: }
147: }
148: return q;
149: }
150:
151: void serial_open(FILE ** streamserport,char * device)
152: {
153: struct sgttyb one;
154:
155: if ((serportfd=open(device,O_WRONLY,O_CREAT))==-1)
156: {
157: fprintf(stderr,"Unable to open serial port.\n");
158: exit(-1);
159: }
160:
161: if ((readportfd=open(device,O_RDONLY,O_CREAT))==-1)
162: {
163: fprintf(stderr,"Unable to open serial port for reading.\n");
164: exit(-1);
165: }
166:
167: one.sg_ispeed='\015';
168: one.sg_ospeed='\015';
169: one.sg_erase='\177';
170: one.sg_kill='\024';
171: one.sg_flags= (short) 3;
172:
173: #ifdef DEBUG
174: ioctl(serportfd,TIOCGETP,&two);
175: printf("%d %d %d %d %d\n",two.sg_ispeed,two.sg_ospeed,
176: two.sg_erase,two.sg_kill,two.sg_flags);
177: #endif
178:
179: ioctl(serportfd,TIOCSETN,&one);
180: ioctl(readportfd,TIOCSETN,&one);
181:
182: #ifdef DEBUG
183: ioctl(serportfd,TIOCGETP,&two);
184: printf("%d %d %d %d %d\n",two.sg_ispeed,two.sg_ospeed,
185: two.sg_erase,two.sg_kill,two.sg_flags);
186: printf("%d %d %d %d %d\n",one.sg_ispeed,one.sg_ospeed,
187: one.sg_erase,one.sg_kill,one.sg_flags);
188: #endif
189: *streamserport=fdopen(serportfd,"w");
190: readport=fdopen(readportfd,"r");
191: }
192:
193:
194: void print(FILE** serport,char * out,int shouldread)
195: {
196: int readamount;
197: char buf[100];
198:
199: #ifdef DEBUG
200: printf("%s\n",out);
201: #endif /*DEBUG*/
202:
203: write(serportfd,out,strlen(out));
204: if (shouldread)
205: {
206: readamount=read(readportfd,buf,1);
207: #ifdef DEBUG
208: printf("%d %d\n",readamount,buf[0]);
209: #endif
210: }
211: }
212:
213: void send_initform_strings(FILE ** serport,int numQuestions,
214: Question questions[MAXQUEST])
215: {
216: int i, scan,j,Points;
217: /* this sets up kermit and then sends the correct strings to the scantron
218: to define what the sheet looks like
219: */
220: char buffer[1024],answerString[1024];
221:
222: for(i=0;i<1000;i++)
223: {
224: buffer[i]='\0';
225: }
226:
227: scan=11+numQuestions;
228:
229: /* resets the scantron*/
230: sprintf(buffer,".srst\015");
231: print(serport,buffer, 1);
232:
233: /* sets the error character to be the '"' character */
234: sprintf(buffer,".err=34\015");
235: print(serport,buffer, 1);
236:
237: /* tell scantron how many scanlines there are*/
238: sprintf(buffer,".frm=fs %d 0 48 n n n\015",scan);
239: print(serport,buffer, 1);
240:
241: /* encoded class info*/
242: sprintf(buffer,".frm=pa 1 2 44 11 32 l 10 7\015");
243: print(serport,buffer, 1);
244:
245: /* the first letter of the student number*/
246: sprintf(buffer,".frm=mc n n 1 1 3 4 4 4 c 1 2 ab\015");
247: print(serport,buffer, 1);
248:
249: /* the remaining digits of the student number*/
250: sprintf(buffer,".frm=mc n n 1 1 2 6 11 20 c 8 10 0123456789\015");
251: print(serport,buffer, 1);
252:
253: /* the PIN number*/
254: sprintf(buffer,".frm=mc n n 1 1 2 24 11 30 c 4 10 0123456789\015");
255: print(serport,buffer, 1);
256:
257: #ifdef DEBUG
258: printf("%d\n",numQuestions);
259: #endif /*DEBUG*/
260:
261: /*sets each question line*/
262: for (i=0;i<numQuestions;i++)
263: {
264:
265: #ifdef DEBUG
266: printf("%c\n",questions[i].type);
267: #endif /*DEBUG*/
268:
269: switch (questions[i].type)
270: {
271: case 'a':
272: sprintf(buffer,".frm=mc n m 1 1 %d 6 %d 20 l 1 8 ABCDEFGH\015",
273: i+12,i+12);
274: print(serport,buffer,1);
275: break;
276: case 'b':
277: for(j=0;j<questions[i].points;j++)
278: {
279: sprintf(buffer,
280: ".frm=mc n m 1 1 %d %d %d %d l 1 3 GLE\015",
281: i+12,(j*8)+6,i+12,(j*8)+10);
282: print(serport,buffer,1);
283: }
284: break;
285: case 'c':
286: for(j=0;j<questions[i].points;j++)
287: {
288: sprintf(buffer,
289: ".frm=mc n m 1 1 %d %d %d %d l 1 2 TF\015",
290: i+12,(j*6)+6,i+12,(j*6)+8);
291: print(serport,buffer,1);
292: }
293: break;
294: case 'd':
295: answerString[0]='\0';
296: Points=questions[i].points;
297: for(j=0;j<=Points;j++)
298: {
299: sprintf(buffer,"%d",j);
300: strcat(answerString,buffer);
301: }
302: sprintf(buffer,".frm=mc n m 1 1 %d 6 %d %d l 1 %d %s\015",
303: i+12,i+12,(Points*2)+6,Points+1,answerString);
304: print(serport,buffer,1);
305: break;
306: case 'e':
307: case 'g':
308: sprintf(buffer,".frm=mc y n 1 1 %d 6 %d 20 l 1 8 ABCDEFGH\015",
309: i+12,i+12);
310: print(serport,buffer,1);
311: break;
312: case 'f':
313: sprintf(buffer,".frm=mc n m 1 1 %d 6 %d 24 l 1 10 0123456789\015",
314: i+12,i+12);
315: print(serport,buffer,1);
316: break;
317: default:
318: fprintf(stderr,"Booga Booga, couldn't find that question type to");
319: fprintf(stderr," tell Scantron about\n %c \n",questions[i].type);
320: break;
321: }
322: }
323:
324: /* end of the form*/
325: sprintf(buffer,".frm=ls\015");
326: print(serport,buffer, 1);
327: #ifdef DEBUG
328: fprintf(stderr,"We have sent the data\n");
329: #endif /*DEBUG*/
330: }
331:
332: void SetupScantron(FILE ** serport,int problems,
333: Question questions[MAXQUEST])
334: {
335: serial_open(serport,"/dev/ttyfb");
336: send_initform_strings(serport,problems,questions);
337: }
338:
339: /* stolen from allpin.c and modified by Guy Albertelli*/
340: int buildPIDandPINlist(int setId, PIDPINlist PIDandPINlist[MAX_SECTION_SIZE] )
341: {
342: int i=0,j=0,count=0,numStudents;
343: int SecCntArry[MAX_SECTION_COUNT], sectionIdx;
344: student_t Students[2048];
345:
346: if (count = capa_get_section_count(SecCntArry) != 0)
347: {
348: for (sectionIdx=1; sectionIdx <= SecCntArry[0]; sectionIdx++)
349: {
350: numStudents=0;
351: get_section(Students, &numStudents, sectionIdx);
352: for(i=0;i<numStudents;i++,j++)
353: {
354: strcpy(PIDandPINlist[j].PID,Students[i].student_number);
355: PIDandPINlist[j].PIN=
356: capa_PIN(Students[i].student_number,setId,0);
357: }
358: }
359: }
360: return j;
361: }
362:
363: /*searches all the possible PIN's for all matches and then asks for
364: confirmation of which PID to use*/
365: int findPID(Student* student,PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
366: int numOfStudents)
367: {
368: int i,j=0,matches[30],selection,error=ENONE;
369:
370: for(i=0;i<numOfStudents;i++)
371: {
372: if (atoi(student->PIN)==PIDandPINlist[i].PIN)
373: {
374: matches[j]=i;
375: j++;
376: }
377: }
378: matches[j]=-1;
379: switch(j)
380: {
381: case 0:
382: printf("No match for PIN %s\n",student->PIN);
383: error=ENOONE;
384: break;
385: case 1:
386: printf("Only one match assuming PID %s\n",PIDandPINlist[matches[0]].PID);
387: strcpy(student->questionPID,PIDandPINlist[matches[0]].PID);
388: break;
389: default:
390: printf("Please press\n");
391: for(i=0;i<30;i++)
392: {
393: if (matches[i]!=-1)
394: {
395: printf("%d) for student number %s\n",i,
396: PIDandPINlist[matches[i]].PID);
397: }
398: else
399: {
400: i=30;
401: }
402: }
403: scanf("%d",&selection);
404: if ((selection < j) && (selection > 0))
405: {
406: strcpy(student->questionPID,PIDandPINlist[matches[selection]].PID);
407: }
408: break;
409: }
410: return error;
411: }
412:
413: Student * getForm(int * status,FILE ** serport,
414: Question questions[MAXQUEST])
415: {
416: Student *newStudent;
417: char buffer[1024],buf[1024],buf2[1024];
418: int readamount=0,done=0,i=0,j=0,h=0,q=0,space=0;
419:
420: sprintf(buffer,".read 2\015");
421: print(serport,buffer,1);
422: while(!done)
423: {
424: readamount=read(readportfd,buf,100);
425: buf[readamount]='\0';
426: for(i=0;i<readamount;i++,j++)
427: {
428: if (buf[i]==13)
429: {
430: done=1;
431: break;
432: }
433: buf2[j]=buf[i];
434: }
435: buf2[j]='\0';
436: }
437:
438: printf("%s\n",buf2);
439:
440: switch(buf2[0])
441: {
442: case '\"':
443: *status=GFFAILED;
444: return NULL;
445: break;
446: default:
447: newStudent=(Student *)malloc(sizeof(Student));
448: if (SurveyMode)
449: sprintf(newStudent->answerPID,"a%08d",formNumber++);
450: else
451: strncpy(newStudent->answerPID,&buf2[10],9);
452: newStudent->answerPID[9]='\0';
453: strncpy(newStudent->class,&buf2[2],8);
454: newStudent->class[8]='\0';
455: strncpy(newStudent->SetId,&buf2[0],2);
456: newStudent->SetId[2]='\0';
457: strncpy(newStudent->PIN,&buf2[19],4);
458: newStudent->PIN[4]='\0';
459: i=23;h=0;
460: while(buf2[i]!='\0')
461: {
462: switch(questions[h].type)
463: {
464: case 'a':
465: case 'd':
466: case 'f':
467: newStudent->Answers[h][0]=buf2[i];
468: newStudent->Answers[h][1]='\0';
469: if (isspace(buf2[i])) space++;
470: i++;
471: break;
472: case 'b':
473: /*loop through each leaf*/
474: for(j=0;j<questions[h].points;j++)
475: {
476: newStudent->Answers[h][j]=buf2[i];
477: if (isspace(buf2[i])) space++;
478: i++;
479: }
480: newStudent->Answers[h][j]='\0';
481: break;
482: case 'c':
483: /*loop through each leaf*/
484: for(j=0;j<questions[h].points;j++)
485: {
486: newStudent->Answers[h][j]=buf2[i];
487: if (isspace(buf2[i])) space++;
488: i++;
489: }
490: newStudent->Answers[h][j]='\0';
491: break;
492: case 'e':
493: case 'g':
494: for (j=0,q=0;j<8;j++)
495: {
496: if (buf2[i]!=' ')
497: {
498: newStudent->Answers[h][q]=buf2[i];
499: q++;
500: }
501: i++;
502: }
503: if (isspace(buf2[i])) space++;
504: newStudent->Answers[h][q]='\0';
505: break;
506: default:
507: fprintf(stderr,"Wha? %c",questions[h].type);
508: i++;
509: break;
510: }
511: h++;
512: }
513: *status=GFSUCCESS;
514: break;
515: }
516: if (space!=0) *status=GFSPACES;
517: return newStudent;
518: }
519:
520: int checkForm(Student * student,int numQuestions,char *class,int setId)
521: {
522: int error,pin;
523: student_t capaStudent;
524:
525: #ifdef DEBUG
526: printf("PID:\t%s\nclass:\t%s\nSetId:\t%s\nPIN:\t%s\n",
527: student->answerPID,student->class,student->SetId,student->PIN);
528:
529: for(i=0,j=0;i<numQuestions;i++)
530: {
531: printf("Answer %d: %s\n",i,student->Answers[i]);
532: }
533: #endif /*DEBUG*/
534:
535: if (CompareClassName)
536: {
537: if (strncasecmp(student->class,class,8))
538: {
539: printf("Class: The Scantron reported:%s, You typed in:%s\n",
540: student->class,class);
541: return ECLASS;
542: }
543: }
544: else
545: {
546: strcpy(student->class,class);
547: sprintf(student->SetId,"%2d",setId);
548: }
549:
550: error=capa_get_student_info(student->answerPID, &capaStudent);
551: switch(error)
552: {
553: case 1:
554: printf("%s %d\n\n",capaStudent.name,capaStudent.section);
555: break;
556: case 0:
557: printf("PID: The Scantron reported:%s\n",student->answerPID);
558: return ESTID;
559: break;
560: case -1:
561: return ECLASSL;
562: break;
563: default:
564: fprintf(stderr,"capa_get_student returned an invalid result ");
565: fprintf(stderr,"in CheckForm.\n");
566: break;
567: }
568:
569: if (CheckPIN && !Anon)
570: {
571: pin=capa_PIN(student->answerPID,atoi(student->SetId),0);
572: if (pin!=atoi(student->PIN))
573: {
574: printf("PIN: The Scantron reported:%s, The Classl file has:%d\n",
575: student->PIN,pin);
576: return EPIN;
577: }
578: }
579: return 0;
580: }
581:
582: long getBubblerEntry(FILE ** outputFile,char *PID)
583: {
584: char oneline[512],fmtbuf[16],a_sn[32];
585: int done=0,found=0,offset=0,len=0,next_r=0;
586:
587: rewind(*outputFile);
588: sprintf(fmtbuf,"%%%dc",MAX_STUDENT_NUMBER);
589: while(!done)
590: {
591: done=!fgets(oneline,511,*outputFile);
592: len=strlen(oneline);
593: if (!done)
594: {
595: sscanf(oneline,fmtbuf,a_sn);
596: if (!strncasecmp(a_sn,PID,MAX_STUDENT_NUMBER))
597: {
598: next_r=ftell(*outputFile);
599: offset = next_r-len;
600: done=1;
601: found=1;
602: }
603: else
604: {
605: }
606: }
607: else
608: {
609: fseek(*outputFile,0L,SEEK_END);
610: offset=ftell(*outputFile);
611: fseek(*outputFile,-1L,SEEK_END);
612: while (fgetc(*outputFile)=='\n')
613: {
614: offset--;
615: fseek(*outputFile,offset,SEEK_SET);
616: }
617: offset= offset+2;
618: found=0;
619: done=1;
620: }
621: }
622: if(!found)
623: {
624: offset=-offset;
625: }
626: return offset;
627: }
628:
629:
630: void setBubblerEntry(FILE ** outputFile,char* answerPID,char* name,
631: char* answers,int score, int section,
632: char* answerstring,char* questionPID, int offset)
633: {
634: int len=0;
635: char buf[1024];
636:
637: rewind(*outputFile);
638: sprintf(buf,"%s %s %s %3d %2d %s %s\n",answerPID,name,answers,score,section,
639: answerstring,questionPID);
640: len=strlen(buf);
641: fseek(*outputFile,abs(offset),0);
642: if(!fwrite(buf,len,1,*outputFile))
643: {
644: fprintf(stderr,"Failed write.\n");
645: }
646: }
647:
648:
649: /* Checks if answers are right and gives a point for each right.*/
650: void writeForm(Student * student,FILE ** outputFile,
651: Question questions[MAXQUEST],int numQuestions)
652: {
653: int result,capaQuestions,questionIndex,leafs,numRight,error,total=0;
654: int offset2;
655: char one=1,zero=0;
656: char *ansOn[20],*stuOn[20];
657: Problem_t *problems,*oldproblem;
658: char answerstring[1024],grade[1024];
659: student_t capaStudent;
660:
661: if (!SurveyMode)
662: {
663: error=capa_get_student_info(student->answerPID, &capaStudent);
664: result=capa_parse(atoi(student->SetId),&problems,student->questionPID,
665: &capaQuestions);
666: oldproblem=problems;
667: if (result==0)
668: {
669: fprintf(stderr,"Parse failed: %d\n",result);
670: return;
671: }
672: }
673: else
674: {
675: strcpy(capaStudent.name,"Unknown ");
676: capaStudent.section=0;
677: oldproblem=problems=NULL;
678: }
679: offset2=getBubblerEntry(outputFile,student->answerPID);
680: for(questionIndex=0;questionIndex<numQuestions;questionIndex++)
681: {
682: switch(questions[questionIndex].type)
683: {
684: case 'a':
685: case 'b':
686: case 'c':
687: case 'f':
688: numRight=0;
689: printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
690: for(leafs=0;problems->answer[leafs]!='\0';leafs++)
691: {
692: if (problems->answer[leafs]==
693: student->Answers[questionIndex][leafs])
694: {
695: numRight++;
696: }
697: }
698: total+=numRight;
699: grade[questionIndex]='0'+(char)numRight;
700: break;
701: case 'd':
702: printf("%s\n",student->Answers[questionIndex]);
703: grade[questionIndex]=student->Answers[questionIndex][0];
704: if (isspace(student->Answers[questionIndex][0]))
705: total+=0;
706: else
707: total+=(int)(student->Answers[questionIndex][0]-'0');
708: break;
709: case 'e':
710: printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
711: numRight=0;
712: for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
713: {
714: ansOn[leafs]=strchr(problems->answer,('A'+(char)leafs));
715: }
716: for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
717: {
718: if (ansOn[leafs] != NULL ) { ansOn[leafs]=&one;}
719: else { ansOn[leafs]=&zero;}
720: }
721: for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
722: {
723: stuOn[leafs]=strchr(student->Answers[questionIndex],
724: ('A'+(char)leafs));
725: }
726: for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
727: {
728: if (stuOn[leafs] != NULL) {stuOn[leafs]=&one;}
729: else {stuOn[leafs]=&zero;}
730: }
731: for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
732: {
733: if (ansOn[leafs] == stuOn[leafs]) numRight++;
734: }
735: fprintf(stderr,"%d\n",numRight);
736: total+=numRight;
737: grade[questionIndex]='0'+(char)numRight;
738: break;
739: case 'g':
740: printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
741: if (!(strcasecmp(problems->answer,student->Answers[questionIndex])))
742: {
743: total+=questions[questionIndex].points;
744: grade[questionIndex]='0'+questions[questionIndex].points;
745: }
746: else
747: {
748: grade[questionIndex]='0';
749: }
750: break;
751: default:
752: printf("No points since don't know question type.\n");
753: break;
754: }
755: if (!SurveyMode) problems=problems->next;
756: }
757:
758: answerstring[0]='\0';
759:
760: for(questionIndex=0;questionIndex<numQuestions;questionIndex++)
761: {
762: strcat(answerstring,student->Answers[questionIndex]);
763: }
764:
765: setBubblerEntry(outputFile,student->answerPID,capaStudent.name,grade,
766: total,capaStudent.section,answerstring,student->questionPID,
767: offset2);
768:
769: if (!SurveyMode)
770: {
771: problems=oldproblem;
772: for(questionIndex=0;problems!=NULL;questionIndex++)
773: {
774: oldproblem=problems;
775: problems=problems->next;
776: free(oldproblem);
777: }
778: #ifdef DEBUG
779: fprintf(stderr,"Freed: %d\n",questionIndex);
780: #endif /*DEBUG*/
781: }
782: }
783:
784: void processForms(FILE ** serport,int numQuestions,
785: Question questions[MAXQUEST],char* class,int setId)
786: {
787:
788: int done=0,error,i,numOfStudents=0;
789: int status;
790: char buf[128],filename[128];
791: Student * student;
792: FILE * outputFile;
793: PIDPINlist PIDandPINlist[MAX_SECTION_SIZE];
794:
795: sprintf(filename,"bubbler.output.%d",setId);
796: outputFile=fopen(filename,"r+");
797: if (outputFile != NULL)
798: {
799: rewind(outputFile);
800: fscanf(outputFile,"%s",buf);
801: }
802: if (outputFile==NULL || buf[0]=='\0')
803: {
804: outputFile=fopen(filename,"w+");
805: fprintf(outputFile,"%s %d ",class,setId);
806: for(i=0;i<numQuestions;i++)
807: {
808: fprintf(outputFile,"%c%d",questions[i].type,questions[i].points);
809: }
810: fprintf(outputFile,"\n");
811: }
812: if (Anon)
813: {
814: numOfStudents=buildPIDandPINlist(setId,PIDandPINlist);
815: if (numOfStudents==0)
816: {
817: fprintf(stderr,"buildPIDandPINlists returned 0 students.");
818: exit(-2);
819: }
820: }
821:
822: while(!done)
823: {
824: student=getForm(&status,serport,questions);
825: switch (status)
826: {
827: case GFSPACES:
828: if (CheckSpaces)
829: {
830: printf("The current form appears to have some questions left\n");
831: printf("blank. Please enter yes if you wish to continue \n");
832: printf("grading of this form.\n");
833: scanf("%s",buf);
834: if (buf[0]=='y' || buf[0]=='Y') ;
835: else break;
836: }
837: case GFSUCCESS:
838: if ((!SurveyMode) &&
839: (error=checkForm(student,numQuestions,class,setId)))
840: {
841: switch(error)
842: {
843: case ECLASS:
844: printf("The current form has a class string that is \n");
845: printf("different from the one entered at the start.\n");
846: printf("Please place that form to the side and type ");
847: printf("start to continue.\n");
848: scanf("%s",buf);
849: break;
850: case ESTID:
851: printf("The current form's Student Id is incorrect.\n");
852: printf("Please set the form aside and type start to ");
853: printf("continue.\n");
854: scanf("%s",buf);
855: break;
856: case ECLASSL:
857: fprintf(stderr,"The classl file was not found in the");
858: fprintf(stderr," current directory.\n");
859: fprintf(stderr,"Please try again.\n");
860: done=1;
861: break;
862: case EPIN:
863: fprintf(stderr,"The current form's PIN is incorrect.\n");
864: fprintf(stderr,"Please set the form aside and type ");
865: fprintf(stderr,"start to continue.\n");
866: scanf("%s",buf);
867: break;
868: default:
869: fprintf(stderr,"Unimplemented error in checkForm %d\n",
870: error);
871: break;
872: }
873: }
874: else
875: {
876: if (Anon)
877: {
878: error=findPID(student,PIDandPINlist,numOfStudents);
879: }
880: else
881: {
882: error=ENONE;
883: strcpy(student->questionPID,student->answerPID);
884: }
885: switch(error)
886: {
887: case ENONE:
888: writeForm(student,&outputFile,questions,numQuestions);
889: break;
890: case ENOONE:
891: break;
892: default:
893: fprintf(stderr,"Unimplemented error in findPID %d\n",
894: error);
895: break;
896: }
897: }
898: break;
899: case GFFAILED:
900: printf("The Scantron has returned an error.\n");
901: printf("Are there still more forms to process?");
902: scanf("%s",buf);
903: if (buf[0]=='n')
904: {
905: done=1;
906: }
907: else
908: {
909: printf("Please put that last read form to the side.\n");
910: printf("Enter start to continue\n");
911: scanf("%s",buf);
912: }
913: break;
914: case GFEOF:
915: done=1;
916: break;
917: default:
918: printf("Unimplened return code in GetForm %d\n",status);
919: break;
920: }
921: if (student != NULL)
922: {
923: free(student);
924: }
925: }
926: }
927:
928: void CloseScantron(FILE ** serport)
929: {
930: fprintf(*serport,".srst\r");
931: fclose(*serport);
932: }
933:
934: int main(int argc, char *argv[])
935: {
936: FILE * serport;
937: Question questions[MAXQUEST];
938: char class[10];
939: int numQuestions,setId;
940:
941: 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\n\n");
942: 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\n\n");
943: 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\n\n");
944: printf("Welcome to Bubbler, the Automated CAPA grader.\n");
945: printf("Version 0.05.02\n\n\n");
946: numQuestions=GetProblems(questions,class,&setId);
947: SetupScantron(&serport,numQuestions,questions);
948: processForms(&serport,numQuestions,questions,class,setId);
949: CloseScantron(&serport);
950: return 0;
951: }
952:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>