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>