File:  [LON-CAPA] / capa / capa51 / Historic / bubbler.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Sep 28 21:26:52 1999 UTC (24 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
Initial revision

    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>