Annotation of capa/capa51/Historic/Scorer/scorer.c, revision 1.1

1.1     ! albertel    1: /*
        !             2:  * scorer.c
        !             3:  * Copyright Guy Albertelli II 1997
        !             4:  */
        !             5: #include <stdio.h>
        !             6: #include <stdlib.h>
        !             7: #include <ctype.h>
        !             8: #include <string.h>
        !             9: #ifdef NeXT
        !            10: #endif
        !            11: #ifdef linux
        !            12: #include <sys/types.h>
        !            13: #include <sys/stat.h>
        !            14: #include <fcntl.h>
        !            15: #include <termios.h>
        !            16: #include <unistd.h>
        !            17: #endif
        !            18: #include "Capa/capaCommon.h"
        !            19: #include "scorer.h"
        !            20: 
        !            21: extern int Parsemode_f;
        !            22: 
        !            23: void initScreen()
        !            24: {
        !            25:   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");
        !            26:   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");
        !            27:   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");
        !            28:   printf("Welcome to Scorer, the Automated Scoring Office converter.\n");
        !            29:   printf("By: Guy Albertelli II\n");
        !            30:   printf("Version %s.%s for %s\n\n\n",MAJORVER,MINORVER,ARCHSTR);
        !            31: }
        !            32: 
        !            33: void getClassInfo(Flags *flags,FILE** scantron)
        !            34: {
        !            35:   char buffer[MAX_LINE_LENGTH],buffer2[MAX_LINE_LENGTH];
        !            36:   int done=FALSE;
        !            37: 
        !            38:   printf("What is the class name?");
        !            39:   scanf("%s",flags->Class);
        !            40:   flags->Class[8]='\0';
        !            41:   printf("What is the SetId?");
        !            42:   scanf("%d",&(flags->SetId));
        !            43:   
        !            44:   while(!done)
        !            45:     {
        !            46:       printf("What is the name of the scoring offices report file?");
        !            47:       scanf("%s",buffer);
        !            48:       *scantron=fopen(buffer,"r");
        !            49:       if (*scantron != NULL)
        !            50: 	{
        !            51: 	  rewind(*scantron);
        !            52: 	  if (EOF == fscanf(*scantron,"%s",buffer2))
        !            53: 	    printf("This file appears to be empty. Please enter a new name.\n");
        !            54: 	  else
        !            55: 	    {
        !            56: 	      rewind(*scantron);
        !            57: 	      done=1;
        !            58: 	    }
        !            59: 	}
        !            60:       else
        !            61: 	printf("Unable to open the report file %s\n",buffer);
        !            62:     }
        !            63: }
        !            64: 
        !            65: int openOutputFile(char filename[MAX_LINE_LENGTH], FILE ** outputFile)
        !            66: {
        !            67:   char buf[MAX_LINE_LENGTH];
        !            68: 
        !            69:   *outputFile=fopen(filename,"r+");
        !            70: 
        !            71:   if (*outputFile != NULL)
        !            72:     {
        !            73:       rewind(*outputFile);
        !            74:       if (EOF == fscanf(*outputFile,"%s",buf))
        !            75: 	  buf[0]='\0';
        !            76:     }
        !            77:   
        !            78:   if (*outputFile==NULL || buf[0]=='\0')
        !            79:     {
        !            80:       if (*outputFile != NULL)
        !            81: 	fclose(*outputFile);
        !            82:       *outputFile=fopen(filename,"w+");
        !            83:       if (*outputFile==NULL)
        !            84: 	{
        !            85: 	  fprintf(stderr,"Unable to open the output file %s\n",filename);
        !            86: 	  return SCO_FATALERROR;
        !            87: 	}
        !            88:       else
        !            89: 	return SCO_NEW;
        !            90:     }
        !            91:   else
        !            92:     {
        !            93:       rewind(*outputFile);
        !            94:       return SCO_EXIST;
        !            95:     }  
        !            96: }
        !            97: 
        !            98: void initValues(Question questions[MAX_QUEST],Flags *flags)
        !            99: {
        !           100:   int i;
        !           101:   flags->NumQuestions=0;
        !           102:   flags->CheckPIN=TRUE;
        !           103:   flags->AnonMode=FALSE;
        !           104:   flags->CheckSpaces=FALSE;
        !           105:   flags->SurveyMode=FALSE;
        !           106:   flags->SurveyHeader=FALSE;
        !           107:   flags->Pause=FALSE;
        !           108:   flags->PauseTime=0.0;
        !           109:   flags->IdFormat=ANUMBER_FORMAT;
        !           110:   flags->CheckMultipleMarks=FALSE;
        !           111:   flags->QueryAboutPID=FALSE;
        !           112:   flags->log=TRUE;
        !           113:   for(i=0;i<MAX_QUEST;i++)
        !           114:     {
        !           115:       questions[i].type='\0';
        !           116:       questions[i].points=0;
        !           117:       questions[i].leafs=0;
        !           118:     }
        !           119: }
        !           120: 
        !           121: int getPreviousValues(FILE *outputFile, Question questions[MAX_QUEST],
        !           122: 		      Flags *flags)
        !           123: 
        !           124: {
        !           125:   char prevClass[MAX_LINE_LENGTH],prevFlags[MAX_LINE_LENGTH],
        !           126:     prevQuestions[MAX_LINE_LENGTH],buf[MAX_LINE_LENGTH];
        !           127:   int prevSetId,prevNumQuestions,done,i;
        !           128:   float pauseTime;
        !           129: 
        !           130:   rewind(outputFile);
        !           131:   fscanf(outputFile,"%s %d %d %s %f %s",prevClass,&prevSetId,&prevNumQuestions,
        !           132: 	 prevFlags,&pauseTime,prevQuestions);
        !           133:   if ( strcmp(prevClass,flags->Class)!=0)
        !           134:     {
        !           135:       printf("Classname as found in the current scorer.output file: %s\n",
        !           136: 	     prevClass);
        !           137:       printf("Classname as entered: %s\n",flags->Class);
        !           138:       printf("Please select one as correct. previous or new (p/n).\n");
        !           139:       done=FALSE;
        !           140:       while(!done)
        !           141: 	{
        !           142: 	  scanf("%s",buf);
        !           143: 	  switch(buf[0])
        !           144: 	    {
        !           145: 	    case 'n':case'N':
        !           146: 	      done=TRUE;
        !           147: 	      break;
        !           148: 	    case 'p':case'P':
        !           149: 	      done=TRUE;
        !           150: 	      strcpy(flags->Class,prevClass);
        !           151: 	      break;
        !           152: 	    default:
        !           153: 	      printf("Please enter one of previous(p) or new(n).\n");
        !           154: 	      break;
        !           155: 	    }
        !           156: 	}
        !           157:     }
        !           158:   if ( prevSetId != flags->SetId )
        !           159:     {
        !           160:       printf("SetId as found in the current scorer.output file: %d\n",
        !           161: 	     prevSetId);
        !           162:       printf("SetId as entered: %d\n",flags->SetId);
        !           163:       printf("Please select one as correct. previous or new (p/n).\n");
        !           164:       done=FALSE;
        !           165:       while(!done)
        !           166: 	{
        !           167: 	  scanf("%s",buf);
        !           168: 	  switch(buf[0])
        !           169: 	    {
        !           170: 	    case 'n':case'N':
        !           171: 	      done=TRUE;
        !           172: 	      break;
        !           173: 	    case 'p':case'P':
        !           174: 	      done=TRUE;
        !           175: 	      flags->SetId=prevSetId;
        !           176: 	      break;
        !           177: 	    default:
        !           178: 	      printf("Please enter one of previous(p) or new(n).\n");
        !           179: 	      break;
        !           180: 	    }
        !           181: 	}
        !           182:     }
        !           183:   flags->NumQuestions=prevNumQuestions;
        !           184:   flags->CheckPIN=(int)(prevFlags[0]-'0');
        !           185:   flags->AnonMode=(int)(prevFlags[1]-'0');
        !           186:   flags->CheckSpaces=(int)(prevFlags[2]-'0');
        !           187:   flags->SurveyMode=(int)(prevFlags[3]-'0');
        !           188:   flags->SurveyHeader=(int)(prevFlags[4]-'0');
        !           189:   flags->Pause=(int)(prevFlags[5]-'0');
        !           190:   flags->PauseTime=pauseTime;
        !           191:   flags->IdFormat=(int)(prevFlags[6]-'0');
        !           192:   flags->CheckMultipleMarks=(int)(prevFlags[7]-'0');
        !           193:   flags->QueryAboutPID=(int)(prevFlags[8]-'0');
        !           194:   flags->log=(int)(prevFlags[9]-'0');
        !           195:   for(i=0;i<flags->NumQuestions;i++)
        !           196:     {
        !           197:       questions[i].type=prevQuestions[3*i];
        !           198:       questions[i].points=(int)(prevQuestions[3*i+1]-'0');
        !           199:       questions[i].leafs=(int)(prevQuestions[3*i+2]-'0');
        !           200:     }
        !           201:   for(i=flags->NumQuestions;i<MAX_QUEST;i++)
        !           202:     {
        !           203:       questions[i].type='\0';
        !           204:       questions[i].points=0;
        !           205:       questions[i].leafs=0;
        !           206:     }
        !           207:   return 0;
        !           208: }
        !           209: 
        !           210: int printFlagMenu(Flags *flags, int *flagToModify)
        !           211: {
        !           212:   int i=0;
        !           213:   if(flags->SurveyMode)
        !           214:     {
        !           215:       printf("%d. The Paper being graded is a Survey.\n",++i);
        !           216:       flagToModify[i]=SURVEY_MODE;
        !           217:       if(flags->SurveyHeader)
        !           218: 	printf("%d. The Survey has a header.\n",++i);
        !           219:       else
        !           220: 	printf("%d. The Survey does not have a header.\n",++i);
        !           221:       flagToModify[i]=SURVEY_HEADER;
        !           222:     }
        !           223:   else
        !           224:     {
        !           225:       printf("%d. The paper being graded is an Exam or Quiz.\n",++i);
        !           226:       flagToModify[i]=SURVEY_MODE;
        !           227:       if(flags->CheckPIN)
        !           228: 	{
        !           229: 	  printf("%d. The coded CAPA ID will be checked for validity.\n",++i);
        !           230: 	  flagToModify[i]=CHECK_PIN;
        !           231: 	  if(flags->AnonMode)
        !           232: 	    {
        !           233: 	      printf("%d. Scorer will run in Anonymous Mode. (search for \n\tthe correct Student Number based on the CAPA ID)\n",++i);
        !           234: 	      flagToModify[i]=ANON_MODE;
        !           235: 	      if(flags->QueryAboutPID)
        !           236: 		printf("%d. Scorer will ask which PID to use if multiple are found.\n",++i);
        !           237: 	      else
        !           238: 		printf("%d. Scorer will pick highest score if multiple PIDs found.\n",++i);
        !           239: 	      flagToModify[i]=QUERY_ABOUT_PID;
        !           240: 	    }
        !           241: 	  else
        !           242: 	    {
        !           243: 	      printf("%d. Scorer will not run in Anonymous Mode. (Bubbled \n\tstudent number is correct for the CAPA ID.)\n",++i);
        !           244: 	      flagToModify[i]=ANON_MODE;
        !           245: 	    }
        !           246: 	}
        !           247:       else
        !           248: 	{
        !           249: 	  printf("%d. The coded CAPA ID will be ignored.\n",++i);
        !           250: 	  flagToModify[i]=CHECK_PIN;
        !           251: 	}
        !           252:       if(flags->CheckSpaces)
        !           253: 	{
        !           254: 	  if (flags->log)
        !           255: 	    printf("%d. Scorer will log sheets containing blank answers.\n",++i);
        !           256: 	  else
        !           257: 	    printf("%d. Scorer will issue a warning and pause when encountering blank answers.\n",++i);
        !           258: 	}
        !           259:       else
        !           260: 	{
        !           261: 	  printf("%d. Scorer will ignore blank answers.\n",++i);
        !           262: 	}
        !           263:       flagToModify[i]=CHECK_SPACES;
        !           264:       if(flags->CheckMultipleMarks)
        !           265: 	{
        !           266: 	  if (flags->log)
        !           267: 	    printf("%d. Scorer will log answer sheets containing multiple marks.\n",++i);
        !           268: 	  else
        !           269: 	    printf("%d. Scorer will issue a warning and pause when encountering multiple marks.\n",++i);
        !           270: 	}
        !           271:       else
        !           272: 	{
        !           273: 	  printf("%d. Scorer will mark multiple marks wrong.\n",++i);
        !           274: 	}
        !           275:       flagToModify[i]=MULTIPLE_MARKS;
        !           276:       switch(flags->IdFormat)
        !           277: 	{
        !           278: 	case ANUMBER_FORMAT:
        !           279: 	  printf("%d. The StudentId is in A<number> format.\n",++i);
        !           280: 	  break;
        !           281: 	case SOC_SEC_FORMAT:
        !           282: 	  printf("%d. The StudentId is in Social Security format.\n",++i);
        !           283: 	  break;
        !           284: 	default:
        !           285: 	  flags->IdFormat=ANUMBER_FORMAT;
        !           286: 	  printf("%d. The StudentId is in A<number> format.\n",++i);
        !           287: 	  break;
        !           288: 	}
        !           289:       flagToModify[i]=ID_FORMAT;
        !           290:     }
        !           291:   if (flags->Pause)
        !           292:     printf("%d. The program will pause %.2f seconds between papers.\n",++i,
        !           293: 	   flags->PauseTime);
        !           294:   else
        !           295:     printf("%d. The program will process papers as quickly as possible.\n",
        !           296: 	   ++i);
        !           297:   flagToModify[i]=PAUSE_TIME;
        !           298:   if (flags->log)
        !           299:     printf("%d. The program will log all errors.\n",++i);
        !           300:   else
        !           301:     printf("%d. The program will query user on all errors.\n",++i);
        !           302:   flagToModify[i]=LOGGING;
        !           303:   return i;
        !           304: }
        !           305: 
        !           306: int getYesOrNo()
        !           307: {
        !           308:   int done=FALSE;
        !           309:   char buf[MAX_LINE_LENGTH];
        !           310:   while(!done)
        !           311:     {
        !           312:       scanf("%s",buf);
        !           313:       switch(buf[0])
        !           314: 	{
        !           315: 	case 'n':case'N':
        !           316: 	  return NO;
        !           317: 	  done=TRUE;
        !           318: 	  break;
        !           319: 	case 'y':case'Y':
        !           320: 	  return YES;
        !           321: 	  done=TRUE;
        !           322: 	  break;
        !           323: 	default:
        !           324: 	  printf("Please enter y or n.");
        !           325: 	  done=FALSE;
        !           326: 	  break;
        !           327: 	}
        !           328:     }
        !           329:   exit(E_GETYESNO);
        !           330:   return -1;
        !           331: }
        !           332:   
        !           333: void modifyFlag(Flags *flags,int *flagToModify,int i)
        !           334: {
        !           335:   int valid=FALSE;
        !           336:   int done=FALSE;
        !           337:   char buf[MAX_LINE_LENGTH];
        !           338:   switch(flagToModify[i])
        !           339:     {
        !           340:     case CHECK_PIN:
        !           341:       printf("Should the student coded CAPA ID be checked for correctness?\n");
        !           342:       printf("(y or n)");
        !           343:       flags->CheckPIN=getYesOrNo();
        !           344:       break;
        !           345:     case ANON_MODE:
        !           346:       printf("Should scorer run in Anonymous mode (search for correct \n");
        !           347:       printf("Student Number based on the CAPA ID)? (y or n)");
        !           348:       flags->AnonMode=getYesOrNo();
        !           349:       break;
        !           350:     case QUERY_ABOUT_PID:
        !           351:       printf("Should scorer Query you when multiple PIDs match a single PIN.(y or n)\n");
        !           352:       flags->QueryAboutPID=getYesOrNo();
        !           353:       break;
        !           354:     case CHECK_SPACES:
        !           355:       printf("Should scorer check for blank answers and issue a warning \n");
        !           356:       printf("when one is encountered? (y or n)");
        !           357:       flags->CheckSpaces=getYesOrNo();
        !           358:       break;
        !           359:     case MULTIPLE_MARKS:
        !           360:       printf("Should scorer check for multiple marks and issue a warning \n");
        !           361:       printf("when encountered? (y or n)");
        !           362:       flags->CheckMultipleMarks=getYesOrNo();
        !           363:       break;
        !           364:     case SURVEY_MODE:
        !           365:       printf("Is this a survey?(y or n)");
        !           366:       flags->SurveyMode=getYesOrNo();
        !           367:       break;
        !           368:     case SURVEY_HEADER:
        !           369:       printf("Does the form include a Header?(y or n)");
        !           370:       flags->SurveyHeader=getYesOrNo();
        !           371:       break;
        !           372:     case PAUSE_TIME:
        !           373:       printf("Do you wish for there to be a pause between papers?(y or n)");
        !           374:       flags->Pause=getYesOrNo();
        !           375:       if (flags->Pause)
        !           376: 	{
        !           377: 	  printf("Please enter the minimum delay between papers in seconds.\n");
        !           378: 	  valid=FALSE;
        !           379: 	  while(!valid)
        !           380: 	    {
        !           381: 	      scanf("%s",buf);
        !           382: 	      flags->PauseTime=(float)atof(buf);
        !           383: 	      if (flags->PauseTime < 0.00001)
        !           384: 		{
        !           385: 		  printf("You have entered a rather short time, are you sure you meant %f seconds?",flags->PauseTime);
        !           386: 		  switch(getYesOrNo())
        !           387: 		    {
        !           388: 		    case NO:
        !           389: 		      printf("Please enter the minimum delay between papers.\n");
        !           390: 		      break;
        !           391: 		    case YES:
        !           392: 		      valid=TRUE;
        !           393: 		      break;
        !           394: 		    default:
        !           395: 		      fprintf(stderr,"getYesOrNo returned a bad result\n");
        !           396: 		      exit(E_GETYESNO);
        !           397: 		      break;
        !           398: 		    }
        !           399: 		}
        !           400: 	      else
        !           401: 		valid=TRUE;
        !           402: 	    }
        !           403: 	}
        !           404:       else
        !           405: 	flags->PauseTime=0.0;
        !           406:       break;
        !           407:     case ID_FORMAT:
        !           408:       printf("Is the StudentID Format A<number> or Social Security? (a or s)");
        !           409:       while(!done)
        !           410: 	{
        !           411: 	  scanf("%s",buf);
        !           412: 	  switch(buf[0])
        !           413: 	    {
        !           414: 	    case 'a':case'A':
        !           415: 	      flags->IdFormat=ANUMBER_FORMAT;
        !           416: 	      done=TRUE;
        !           417: 	      break;
        !           418: 	    case 's':case'S':
        !           419: 	      flags->IdFormat=SOC_SEC_FORMAT;
        !           420: 	      done=TRUE;
        !           421: 	      break;
        !           422: 	    default:
        !           423: 	      printf("Please enter a or s.");
        !           424: 	      done=FALSE;
        !           425: 	      break;
        !           426: 	    }
        !           427: 	}
        !           428:       break;
        !           429:     case LOGGING:
        !           430:       printf("Should Scorer log errors?(y or n)");
        !           431:       flags->log=getYesOrNo();
        !           432:       break;
        !           433:     default:
        !           434:       fprintf(stderr,"Corrupted information in modifyFlag, i=%d\n",i);
        !           435:       fprintf(stderr,"flagToModify[i]=%d",flagToModify[i]);
        !           436:       exit(E_MODIFYFLAG);
        !           437:       break;
        !           438:     }
        !           439: }
        !           440: 
        !           441: void checkFlagConsistency(Flags *flags)
        !           442: {
        !           443:   if(flags->SurveyMode)
        !           444:     {
        !           445:       flags->CheckPIN=FALSE;
        !           446:       flags->AnonMode=FALSE;
        !           447:       flags->QueryAboutPID=FALSE;
        !           448:       flags->CheckSpaces=FALSE;
        !           449:       flags->CheckMultipleMarks=FALSE;
        !           450:     }
        !           451:   else
        !           452:     {
        !           453:       flags->SurveyHeader=FALSE;
        !           454:       if(flags->CheckPIN);
        !           455:       else
        !           456: 	flags->AnonMode=FALSE;
        !           457:     }
        !           458:   if (!flags->AnonMode) flags->QueryAboutPID=FALSE;
        !           459: }
        !           460:   
        !           461: void getFlags(Flags *flags)
        !           462: {
        !           463:   int done=FALSE,valid=FALSE,i,flagToModify[MAX_NUM_FLAG];
        !           464:   char buf[MAX_LINE_LENGTH];
        !           465:   while(!done)
        !           466:     {
        !           467:       i=printFlagMenu(flags,flagToModify);
        !           468:       printf("Please select which one of the above (1-%d) you wish to \n",i);
        !           469:       printf("change. Otherwise enter 0 (zero) to continue.\n");
        !           470:       valid=FALSE;
        !           471:       while(!valid)
        !           472: 	{
        !           473: 	  scanf("%s",buf);
        !           474: 	  if (isdigit(buf[0]))
        !           475: 	    {
        !           476: 	      i=atoi(buf);
        !           477: 	      valid=TRUE;
        !           478: 	    }
        !           479: 	  else
        !           480: 	    printf("Please enter a number between (0-%d)\n",i);
        !           481: 	}
        !           482:       if (i)
        !           483: 	modifyFlag(flags,flagToModify,i);
        !           484:       else
        !           485: 	done=TRUE;
        !           486:     }
        !           487:   checkFlagConsistency(flags);
        !           488: }
        !           489: 
        !           490: void printQuestions(Question questions[MAX_QUEST],int numQuestions)
        !           491: {
        !           492:   int i;
        !           493:   for(i=0;i<numQuestions;i++)
        !           494:     {
        !           495:       printf("%d. ",i+1);
        !           496:       switch(questions[i].type)
        !           497: 	{
        !           498: 	case ONE_OUT_OF_8:
        !           499: 	  printf("One out of 8.                                 ");
        !           500: 	  break;
        !           501: 	case GLE:
        !           502: 	  printf("Choose one of >, <, =,                        ");
        !           503: 	  break;
        !           504: 	case TF:
        !           505: 	  printf("True or False.                                ");
        !           506: 	  break;
        !           507: 	case ASSIGNED:
        !           508: 	  printf("Assigned Score.                               ");
        !           509: 	  break;
        !           510: 	case N_OUT_OF_M:
        !           511: 	  printf("Pick N out of M.                              ");
        !           512: 	  break;
        !           513: 	case SINGLE_DIGIT:
        !           514: 	  printf("Single digit answer.                          ");
        !           515: 	  break;
        !           516: 	case STRING_MATCH:
        !           517: 	  printf("Exact string matching.(10 or less bubbles)    ");
        !           518: 	  break;
        !           519: 	default:
        !           520: 	  fprintf(stderr,"\nCorrupt data in Questions struct while inside printQuestions. Dying\n");
        !           521: 	  exit(E_PRINTQUESTIONS);
        !           522: 	  break;
        !           523: 	}
        !           524:       printf(" %d leafs, Worth: %d points\n",questions[i].leafs,
        !           525: 	     questions[i].points);
        !           526:     }  
        !           527: }
        !           528: 
        !           529: int wantToChangeQuestions()
        !           530: {
        !           531:   int done=FALSE;
        !           532:   char buf[MAX_LINE_LENGTH];
        !           533:   printf("Do you want to change any of the above?(y or n)\n");
        !           534:   while(!done)
        !           535:     {
        !           536:       scanf("%s",buf);
        !           537:       switch(buf[0])
        !           538: 	{
        !           539: 	case 'n':case'N':
        !           540: 	  return 0;
        !           541: 	  done=TRUE;
        !           542: 	  break;
        !           543: 	case 'y':case 'Y':
        !           544: 	  return 1;
        !           545: 	  done=TRUE;
        !           546: 	  break;
        !           547: 	default:
        !           548: 	  printf("Please enter either (y or n).\n");
        !           549: 	  break;
        !           550: 	}
        !           551:     }
        !           552:   return -1;
        !           553: }
        !           554: 
        !           555: void printQuestionMenu()
        !           556: {
        !           557:   printf("For Each Question enter \"%c\" for a one out of 8\n",ONE_OUT_OF_8);
        !           558:   printf("                        \"%c\" for a GLE type\n",GLE);
        !           559:   printf("                        \"%c\" for a TF type.\n",TF);
        !           560:   printf("                        \"%c\" for an assigned score.\n",ASSIGNED);
        !           561:   printf("                        \"%c\" for an n out of m.\n",N_OUT_OF_M);
        !           562:   printf("                        \"%c\" for single digit answer.\n",
        !           563: 	 SINGLE_DIGIT);
        !           564:   printf("                        \"%c\" for exact string matching (8 or less bubbles)\n",
        !           565: 	 STRING_MATCH);
        !           566:   printf("                        \"%c\" to print this menu again\n",
        !           567: 	 QUESTION_MENU);
        !           568:   printf("                        \"%c\" to stop entering questions\n",
        !           569: 	 QUESTION_STOP);
        !           570: }
        !           571: 
        !           572: int getSingleDigit()
        !           573: {  
        !           574:   int done=FALSE;
        !           575:   char buf[MAX_LINE_LENGTH];
        !           576:   while(!done)
        !           577:     {
        !           578:       scanf("%s",buf);
        !           579:       if (isdigit(buf[0]) && (atoi(buf) >=1) && (atoi(buf) <=9))
        !           580: 	{
        !           581: 	  done=TRUE;
        !           582: 	  return atoi(buf);
        !           583: 	}
        !           584:       else
        !           585: 	printf("Please enter a digit between 1 and 9\n");
        !           586:     }
        !           587:   return 0;
        !           588: }
        !           589: 
        !           590: int getNewQuestion(Question questions[MAX_QUEST],int numQuestions)
        !           591: {
        !           592:   int done=FALSE;
        !           593:   char buf[MAX_LINE_LENGTH];
        !           594:   printf("Question#%2d: (enter %c to see menu): ",numQuestions+1,QUESTION_MENU);
        !           595:   while(!done)
        !           596:     {
        !           597:       scanf("%s",buf);
        !           598:       questions[numQuestions].leafs=1;
        !           599:       switch(buf[0])
        !           600: 	{
        !           601: 	case GLE:
        !           602: 	case TF:
        !           603: 	  printf("How many parts to the problem?");
        !           604: 	  if (!(questions[numQuestions].leafs=getSingleDigit())) 
        !           605: 	    {
        !           606: 	      fprintf(stderr,"Weird result from getSingleDigit\n");
        !           607: 	      exit(E_SINGLEDIGIT);
        !           608: 	    }
        !           609: 	case ONE_OUT_OF_8:
        !           610: 	case ASSIGNED:
        !           611: 	case SINGLE_DIGIT:
        !           612: 	case STRING_MATCH:
        !           613: 	  printf("How many points are possible?");
        !           614: 	  done=TRUE;
        !           615: 	  break;
        !           616: 	case N_OUT_OF_M:
        !           617: 	  printf("What is m in the problem?");
        !           618: 	  if (!(questions[numQuestions].leafs=getSingleDigit())) 
        !           619: 	    {
        !           620: 	      fprintf(stderr,"Weird result from getSingleDigit\n");
        !           621: 	      exit(E_SINGLEDIGIT);
        !           622: 	    }
        !           623: 	  printf("How many points are possible?");
        !           624: 	  done=TRUE;
        !           625: 	  break;
        !           626: 	case QUESTION_MENU:
        !           627: 	  printQuestionMenu();
        !           628: 	  printf("Question#%2d: ",numQuestions+1);
        !           629: 	  break;
        !           630: 	case QUESTION_STOP:
        !           631: 	  return 0;
        !           632: 	  break;
        !           633: 	default:
        !           634: 	  printf("Please enter one of %c,%c,%c,%c,%c,%c,%c,%c,%c.\n",
        !           635: 		 ONE_OUT_OF_8,GLE,TF,ASSIGNED,N_OUT_OF_M,SINGLE_DIGIT,
        !           636: 		 STRING_MATCH,QUESTION_MENU,QUESTION_STOP);
        !           637: 	  printf("Question#%2d: ",numQuestions+1);
        !           638: 	  break;
        !           639: 	}
        !           640:     }
        !           641:   questions[numQuestions].type=buf[0];
        !           642:   if (!(questions[numQuestions].points=getSingleDigit())) 
        !           643:     {
        !           644:       fprintf(stderr,"Weird result from getSingleDigit\n");
        !           645:       exit(E_SINGLEDIGIT);
        !           646:     }
        !           647:   return 1;
        !           648: }
        !           649: 
        !           650: void printModifyQuestionMenu()
        !           651: {
        !           652:   printf("(a)dd a question\n");
        !           653:   printf("(c)hange a question\n");
        !           654:   printf("(d)elete a question\n");
        !           655:   printf("(f)inished changing\n");
        !           656: }
        !           657: 
        !           658: void addQuestion(Question questions[MAX_QUEST],int *numQuestions)
        !           659: {
        !           660:   printQuestionMenu();
        !           661:   if (getNewQuestion(questions,*numQuestions))
        !           662:     (*numQuestions)=(*numQuestions)+1;
        !           663: }
        !           664: 
        !           665: void changeQuestion(Question questions[MAX_QUEST],int numQuestions)
        !           666: {
        !           667:   int done=FALSE;
        !           668:   char buf[MAX_LINE_LENGTH];
        !           669:   printf("Which question do you wish to change?(1-%d) ",numQuestions);
        !           670:   printf("Or 0 for none\n");
        !           671:   while(!done)
        !           672:     {
        !           673:       scanf("%s",buf);
        !           674:       if(isdigit(buf[0]) && (atoi(buf) >= 0) && (atoi(buf) <= numQuestions))
        !           675: 	  done=TRUE;
        !           676:       else
        !           677: 	  printf("Please enter a number between 0 and %d.\n",numQuestions);
        !           678:     }
        !           679:   if (atoi(buf) !=0)
        !           680:     {
        !           681:       printQuestionMenu();
        !           682:       getNewQuestion(questions,atoi(buf)-1);
        !           683:     }
        !           684: }
        !           685: 
        !           686: void deleteQuestion(Question questions[MAX_QUEST],int *numQuestions)
        !           687: {
        !           688:   int done=FALSE,i;
        !           689:   char buf[MAX_LINE_LENGTH];
        !           690:   printf("Which question do you wish to delete?(1-%d) ",*numQuestions);
        !           691:   printf("Or 0 for none\n");
        !           692:   while(!done)
        !           693:     {
        !           694:       scanf("%s",buf);
        !           695:       if(isdigit(buf[0]) && (atoi(buf) >= 0) && (atoi(buf) <= (*numQuestions)))
        !           696: 	done=TRUE;
        !           697:       else
        !           698: 	printf("Please enter a number between 0 and %d.\n",*numQuestions);
        !           699:     }
        !           700:   if (atoi(buf) !=0)
        !           701:     {
        !           702:       for(i=atoi(buf)-1;i<(*numQuestions)-1;i++)
        !           703: 	{
        !           704: 	  questions[i].type=questions[i+1].type;
        !           705: 	  questions[i].points=questions[i+1].points;
        !           706: 	  questions[i].leafs=questions[i+1].leafs;
        !           707: 	}
        !           708:       (*numQuestions)=(*numQuestions)-1;
        !           709:     }
        !           710: }
        !           711: 
        !           712: void modifyQuestions(Question questions[MAX_QUEST],int *numQuestions)
        !           713: {
        !           714:   int done=FALSE;
        !           715:   char buf[MAX_LINE_LENGTH];
        !           716:   while(!done)
        !           717:     {
        !           718:       printQuestions(questions,*numQuestions);
        !           719:       printModifyQuestionMenu();
        !           720:       scanf("%s",buf);
        !           721:       switch(buf[0])
        !           722: 	{
        !           723: 	case 'a':
        !           724: 	  addQuestion(questions,numQuestions);
        !           725: 	  break;
        !           726: 	case 'c':
        !           727: 	  changeQuestion(questions,*numQuestions);
        !           728: 	  break;
        !           729: 	case 'd':
        !           730: 	  deleteQuestion(questions,numQuestions);
        !           731: 	  break;
        !           732: 	case 'f':
        !           733: 	  done=TRUE;
        !           734: 	  break;
        !           735: 	default:
        !           736: 	  printf("Please enter one of a, c, d, f\n");
        !           737: 	  break;
        !           738: 	}
        !           739:     }
        !           740: }
        !           741: 
        !           742: int getNumSurveyQuest()
        !           743: {
        !           744:   int numQuestions=0,done=FALSE;
        !           745:   char buf[MAX_LINE_LENGTH];
        !           746: 
        !           747:   printf("Please enter the number of questions on the Survey.\n");
        !           748:   while(!done)
        !           749:     {
        !           750:       scanf("%s",buf);
        !           751:       if(isdigit(buf[0]))
        !           752: 	{
        !           753: 	  numQuestions=atoi(buf);
        !           754: 	  done=TRUE;
        !           755: 	}
        !           756:       else
        !           757: 	{
        !           758: 	  printf("Please enter a number.\n");
        !           759: 	}
        !           760:     }
        !           761:   return numQuestions;
        !           762: }
        !           763: 
        !           764: void getQuestionInfo(Question questions[MAX_QUEST],Flags *flags)
        !           765: {
        !           766:   int done=FALSE,i;
        !           767:   if (flags->SurveyMode)
        !           768:     {
        !           769:       flags->NumQuestions=getNumSurveyQuest();
        !           770:       for (i=0;i<flags->NumQuestions;i++)
        !           771: 	{
        !           772: 	  questions[i].type=ASSIGNED;
        !           773: 	  questions[i].points=9;
        !           774: 	  questions[i].leafs=1;
        !           775: 	}
        !           776:     }
        !           777:   else
        !           778:     {
        !           779:       if (flags->NumQuestions!=0)
        !           780: 	{
        !           781: 	  printQuestions(questions,flags->NumQuestions);
        !           782: 	  if (!wantToChangeQuestions())
        !           783: 	    return;
        !           784: 	}
        !           785:       else
        !           786: 	{
        !           787: 	  printQuestionMenu();
        !           788: 	  while(!done)
        !           789: 	    if (getNewQuestion(questions,flags->NumQuestions))
        !           790: 	      flags->NumQuestions++;
        !           791: 	    else
        !           792: 	      done=TRUE;
        !           793: 	}
        !           794:       modifyQuestions(questions,&(flags->NumQuestions));
        !           795:     }
        !           796: } 
        !           797: 
        !           798: void getInfo(FILE ** outputFile,FILE **scantron,
        !           799: 	     Question questions[MAX_QUEST],Flags *flags)
        !           800: {
        !           801:   char filename[MAX_LINE_LENGTH];
        !           802: 
        !           803:   getClassInfo(flags,scantron);
        !           804:   sprintf(filename,"records/scorer.output.%d",flags->SetId);
        !           805:   switch(openOutputFile(filename,outputFile))
        !           806:     {
        !           807:     case SCO_FATALERROR:
        !           808:       exit (E_OPENOUTPUT);
        !           809:       break;
        !           810:     case SCO_NEW:
        !           811:       initValues(questions,flags);
        !           812:       break;
        !           813:     case SCO_EXIST:
        !           814:       getPreviousValues(*outputFile,questions,flags);
        !           815:       break;
        !           816:     default:
        !           817:       fprintf(stderr,"openOutputFile returned an invalid code. Dying\n");
        !           818:       exit(E_OPENOUTPUTRETURN);
        !           819:       break;
        !           820:     }
        !           821:   getFlags(flags);
        !           822:   getQuestionInfo(questions,flags);
        !           823: }
        !           824: 
        !           825: void saveInfo(FILE *outputFile,Question questions[MAX_QUEST],Flags *flags)
        !           826: {
        !           827:   char configLine[CONFIG_LINE_LENGTH+2],buf[MAX_LINE_LENGTH],
        !           828:     buf2[MAX_LINE_LENGTH],logname[MAX_LINE_LENGTH];
        !           829:   int i;
        !           830:   for(i=0;i<flags->NumQuestions;i++)
        !           831:     {
        !           832:       buf[3*i]=questions[i].type;
        !           833:       buf[3*i+1]=((char)questions[i].points)+'0';
        !           834:       buf[3*i+2]=((char)questions[i].leafs)+'0';
        !           835:     }
        !           836:   buf[3*i]='\0';
        !           837:   buf2[0]=((char)flags->CheckPIN)+'0';
        !           838:   buf2[1]=((char)flags->AnonMode)+'0';
        !           839:   buf2[2]=((char)flags->CheckSpaces)+'0';
        !           840:   buf2[3]=((char)flags->SurveyMode)+'0';
        !           841:   buf2[4]=((char)flags->SurveyHeader)+'0';
        !           842:   buf2[5]=((char)flags->Pause)+'0';
        !           843:   buf2[6]=((char)flags->IdFormat)+'0';
        !           844:   buf2[7]=((char)flags->CheckMultipleMarks)+'0';
        !           845:   buf2[8]=((char)flags->QueryAboutPID)+'0';
        !           846:   buf2[9]=((char)flags->log)+'0';
        !           847:   buf2[10]='\0';
        !           848:   sprintf(configLine,"%s %d %d %s %f %s",flags->Class,flags->SetId,
        !           849: 	  flags->NumQuestions,buf2,flags->PauseTime,buf);
        !           850:   for(i=strlen(configLine);i<CONFIG_LINE_LENGTH;i++)
        !           851:     configLine[i]=' ';
        !           852:   configLine[CONFIG_LINE_LENGTH]='\n';
        !           853:   configLine[CONFIG_LINE_LENGTH+1]='\0';
        !           854:   rewind(outputFile);
        !           855:   fprintf(outputFile,configLine);
        !           856: 
        !           857:   if(flags->log)
        !           858:     {
        !           859:       sprintf(logname,"records/scorer.log.%d",flags->SetId);
        !           860:       
        !           861:       flags->logFile=fopen(logname,"w");
        !           862:       if (flags->logFile == NULL)
        !           863: 	{
        !           864: 	  fprintf(stderr,"Unable to open the logFile %s\n",logname);
        !           865: 	  exit(E_LOGERROR);
        !           866: 	}
        !           867:     }
        !           868: }
        !           869: 
        !           870: void logMultipleAnon(PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
        !           871: 		     int matches[MAX_PID_MATCHES],Student* student,
        !           872: 		     Flags* flags,int maxTotal,int total[MAX_PID_MATCHES])
        !           873: {
        !           874:   int i;
        !           875: 
        !           876:   fprintf(flags->logFile,"#Multiple matching PINs for PID %s :",
        !           877: 	  student->answerPID);
        !           878:   for(i=0;i<MAX_PID_MATCHES;i++)
        !           879:     {
        !           880:       if (matches[i]==-1) break;
        !           881:       fprintf(flags->logFile," %s score: %d,",
        !           882: 	      PIDandPINlist[matches[i]].PID,total[i]);
        !           883:     }
        !           884:   
        !           885:   flags->loggedErrors++;
        !           886:   fprintf(flags->logFile," picked: %s, serialNumber: %s\n",
        !           887: 	  PIDandPINlist[matches[maxTotal]].PID,student->serialNumber);
        !           888:   fprintf(flags->logFile,"%s",student->origString);  
        !           889: }
        !           890: 
        !           891: void logError(Student *student,Flags *flags,int errorCode)
        !           892: {
        !           893:   flags->loggedErrors++;
        !           894:   student->error=1;
        !           895:   switch(errorCode)
        !           896:     {
        !           897:     case LOG_NOPINFOUND:
        !           898:       fprintf(flags->logFile,"#In Anonymous Mode no Student ID could be found for the PIN encoded, PIN=%s (not graded)",student->PIN);
        !           899:       break;
        !           900:     case LOG_PINWRONG:
        !           901:       if (flags->AnonMode)
        !           902: 	fprintf(flags->logFile,"#The coded PIN had errors (not graded)");
        !           903:       else
        !           904: 	fprintf(flags->logFile,"#The coded PIN had errors, assumed zero for bad responses");
        !           905:       break;
        !           906:     case LOG_STUDENTNOTEXIST:
        !           907:       fprintf(flags->logFile,"#The Student ID %s was not found in the classl file(not graded)",student->answerPID);
        !           908:       break;
        !           909:     case LOG_PINNOTMATCH:
        !           910:       fprintf(flags->logFile,"#The student coded an incorrect PIN(%s) for the specified PID(%s) using the classl PIN, %04d",student->PIN,student->answerPID,student->classlPIN); 
        !           911:       break;
        !           912:     case LOG_BADPID:
        !           913:       fprintf(flags->logFile,"#The coded Student ID(%s) was not found in the classl file (not graded)",student->answerPID);
        !           914:       break;
        !           915:     case LOG_BADPIN:
        !           916:       fprintf(flags->logFile,"#The coded PIN (%s) was incorrect(notGraded)",student->PIN);
        !           917:       break;
        !           918:     case LOG_SPACES:
        !           919:       fprintf(flags->logFile,"#The student had blank answers");
        !           920:       break;
        !           921:     case LOG_MULTIPLEMARKS:
        !           922:       fprintf(flags->logFile,"#The student had multiple marks on single mark questions");
        !           923:       break;
        !           924:     default:
        !           925:       fprintf(flags->logFile,"#And unknown error %d occured with this student",errorCode);
        !           926:       break;
        !           927:     }
        !           928:   fprintf(flags->logFile," serialNumber: %s.\n",student->serialNumber);
        !           929: }
        !           930: 
        !           931: /* stolen from allpin.c and modified by Guy Albertelli*/
        !           932: int buildPIDandPINlist(int setId, PIDPINlist PIDandPINlist[MAX_SECTION_SIZE] )
        !           933: {
        !           934:   int i=0,numStudents;
        !           935:   T_student *curStudent,*headStudent;
        !           936: 
        !           937:   printf("Building lists of CapaIDs and PIDs\n");
        !           938:   numStudents=capa_get_section(&headStudent, 0);
        !           939:   curStudent=headStudent;
        !           940:   for(i=0;curStudent;curStudent=curStudent->s_next,i++)
        !           941:     {
        !           942:       strcpy(PIDandPINlist[i].PID,curStudent->s_sn);
        !           943:       PIDandPINlist[i].PIN=capa_PIN(curStudent->s_sn,setId,0);
        !           944:     }
        !           945:   free_students(headStudent);
        !           946:   printf("\nDone\n");
        !           947:   return numStudents;
        !           948: }
        !           949: 
        !           950: int getForm(Student **newStudent,FILE *scantron,
        !           951: 		  Question questions[MAX_QUEST],Flags *flags)
        !           952: {
        !           953:   char buffer[MAX_LINE_LENGTH];
        !           954:   char *eof;
        !           955:   int i=0,h=0,j=0,q=0,space=0,found,stepsize,pin,result=0,multiplemarks=0;
        !           956:   int done=FALSE,pinWrong=FALSE;
        !           957:   static int formNumber;
        !           958:   char * array;
        !           959: 
        !           960:   if (flags->Pause)
        !           961:       usleep(flags->PauseTime*1000000);
        !           962:   while(!done)
        !           963:     {
        !           964:       eof=fgets(buffer,MAX_LINE_LENGTH,scantron);
        !           965:       if (eof==NULL) return GF_EOF;
        !           966:       if (buffer[0]!='#') done=TRUE;
        !           967:     }
        !           968:   flags->linesRead++;
        !           969:   if (!flags->log)
        !           970:     printf("The Next line is:\n%s\n",buffer);
        !           971: 
        !           972: #ifdef DEBUG
        !           973:   printf("Interpreting the line.\n");
        !           974: #endif
        !           975: 
        !           976:   *newStudent=(Student *)malloc(sizeof(Student));
        !           977:   if (flags->SurveyMode) 
        !           978:     /* assign a unique student number since there isn't one on the sheet*/
        !           979:     switch(flags->IdFormat)
        !           980:       {
        !           981:       case ANUMBER_FORMAT:
        !           982: 	sprintf((*newStudent)->answerPID,"a%08d",formNumber++);
        !           983: 	break;
        !           984:       case SOC_SEC_FORMAT:
        !           985: 	sprintf((*newStudent)->answerPID,"%09d",formNumber++);
        !           986: 	break;
        !           987:       default:
        !           988: 	fprintf(stderr,"Invalid IdFormat data in interpretForm,%d\n",
        !           989: 		flags->IdFormat);
        !           990: 	exit(E_INVALIDIDFORMAT);
        !           991: 	break;
        !           992:       }
        !           993:   else
        !           994:     strncpy((*newStudent)->answerPID,&buffer[56],9);
        !           995:   (*newStudent)->answerPID[9]='\0';
        !           996:   strncpy((*newStudent)->Name,&buffer[40],16);
        !           997:   (*newStudent)->Name[16]='\0';
        !           998:   strncpy((*newStudent)->serialNumber,&buffer[3],6);
        !           999:   (*newStudent)->serialNumber[6]='\0';
        !          1000:   strncpy((*newStudent)->origString,buffer,SCAN_INPUT_LENGTH);
        !          1001:   (*newStudent)->origString[SCAN_INPUT_LENGTH]='\0';
        !          1002:   (*newStudent)->error=0;
        !          1003:   /* i is the current position in buffer and h is the current question*/
        !          1004:   for(i=0;i<flags->NumQuestions;i++)
        !          1005:     {
        !          1006:       array=LETTER;
        !          1007:       stepsize=2;
        !          1008:       switch(questions[i].type)
        !          1009: 	{
        !          1010: 	case ASSIGNED:
        !          1011: 	case SINGLE_DIGIT:
        !          1012: 	  /*the first 5 are special for Anon mode, only first 4 for 
        !          1013: 	   *otherwise
        !          1014: 	   */
        !          1015: 	  if (flags->AnonMode) 
        !          1016: 	    if (i > 4)
        !          1017: 	      array=NUMBER;
        !          1018: 	  else
        !          1019: 	    if (i > 3)
        !          1020: 	      array=NUMBER;
        !          1021: 	case ONE_OUT_OF_8:
        !          1022: 	  found=0;
        !          1023: 	  for(j=(i*10)+76;j<((i+1)*10)+76;j++)
        !          1024: 	    {
        !          1025: 	      if (buffer[j]=='1') 
        !          1026: 		{
        !          1027: 		  h=j;
        !          1028: 		  found++;
        !          1029: 		}
        !          1030: 	    }
        !          1031: 	  if (found > 1)
        !          1032: 	    {
        !          1033: 	      (*newStudent)->Answers[i][0]=' ';
        !          1034: 	      multiplemarks++;
        !          1035: 	    }
        !          1036: 	  if (found < 1)
        !          1037: 	    {
        !          1038: 	      (*newStudent)->Answers[i][0]=' ';
        !          1039: 	      space++;
        !          1040: 	    }
        !          1041: 	  if (found == 1)
        !          1042: 	    (*newStudent)->Answers[i][0]=array[h-(i*10+76)];
        !          1043: 	  (*newStudent)->Answers[i][1]='\0';
        !          1044: 	  break;
        !          1045: 	case GLE:
        !          1046: 	  stepsize=3;
        !          1047: 	case TF:
        !          1048: 	  for(j=0; j<questions[i].leafs; j++)
        !          1049: 	    {
        !          1050: 	      found=0;
        !          1051: 	      for(h = (i*10+76)+j*stepsize; h<(i*10+76)+(j+1)*stepsize; h++)
        !          1052: 		{
        !          1053: 		  if (buffer[h]=='1')
        !          1054: 		    {
        !          1055: 		      q=h;
        !          1056: 		      found++;
        !          1057: 		    }
        !          1058: 		  if (found > 1)
        !          1059: 		    {
        !          1060: 		      (*newStudent)->Answers[i][j]=' ';
        !          1061: 		      multiplemarks++;
        !          1062: 		    }
        !          1063: 		  if (found < 1)
        !          1064: 		    {
        !          1065: 		      (*newStudent)->Answers[i][j]=' ';
        !          1066: 		      space++;
        !          1067: 		    }
        !          1068: 		  if (found == 1)
        !          1069: 		    (*newStudent)->Answers[i][j]=array[q-(i*10+76)];
        !          1070: 		}
        !          1071: 	    }
        !          1072: 	  (*newStudent)->Answers[i][questions[i].leafs]='\0';
        !          1073: 	  break;
        !          1074: 	case N_OUT_OF_M:
        !          1075: 	case STRING_MATCH:
        !          1076: 	  found=0;
        !          1077: 	  for(j=(i*10)+76;j<((i+1)*10)+76;j++)
        !          1078: 	    {
        !          1079: 	      if (buffer[j]=='1')
        !          1080: 		{
        !          1081: 		  (*newStudent)->Answers[i][found]=array[j-(i*10+76)];
        !          1082: 		  found++;
        !          1083: 		}
        !          1084: 	    }
        !          1085: 	  if (found==0) space++;
        !          1086: 	  (*newStudent)->Answers[i][found]='\0';
        !          1087: 	  break;
        !          1088: 	default:
        !          1089: 	  fprintf(stderr,"Invalid question type %c for question %d in Interpret form.\n Dying\n",questions[h].type,h);
        !          1090: 	  exit(E_INTREPRETFORM);
        !          1091: 	  break;
        !          1092: 	}
        !          1093:     }
        !          1094:   pin=0;
        !          1095:   for(i=0;i<4;i++)
        !          1096:     {
        !          1097:       pin*=10;
        !          1098:       switch((*newStudent)->Answers[i][0])
        !          1099: 	{
        !          1100: 	case 'A': pin+=1;break;
        !          1101: 	case 'B': pin+=2;break;
        !          1102: 	case 'C': pin+=3;break;
        !          1103: 	case 'D': pin+=4;break;
        !          1104: 	case 'E': pin+=5;break;
        !          1105: 	case 'F': pin+=6;break;
        !          1106: 	case 'G': pin+=7;break;
        !          1107: 	case 'H': pin+=8;break;
        !          1108: 	case 'I': pin+=9;break;
        !          1109: 	case 'J': pin+=0;break;
        !          1110: 	case ' ':
        !          1111: 	default: 
        !          1112: 	  if (!flags->log)
        !          1113: 	    fprintf(stderr,"Garbage answer '%c' for PIN question %d",
        !          1114: 		    (*newStudent)->Answers[i][0],i);
        !          1115: 	  result|=GF_PINWRONG;
        !          1116: 	  pinWrong=TRUE;
        !          1117: 	  pin+=0;break;
        !          1118: 	}
        !          1119:     }
        !          1120:   if (pinWrong && flags->log)
        !          1121:     logError((*newStudent),flags,LOG_PINWRONG);
        !          1122:   sprintf((*newStudent)->PIN,"%04d",pin);
        !          1123:   if (space!=0) result|=GF_SPACES;
        !          1124:   if (multiplemarks!=0) result|=GF_MULTIPLEMARKS;
        !          1125:   return result;
        !          1126: }
        !          1127: 
        !          1128: int gradeQuestion(Question questions[MAX_QUEST],int questionIndex,
        !          1129: 		  Problem_t *problem,Student *student,Flags* flags)
        !          1130: {
        !          1131:   int numRight=0,leafs;
        !          1132:   char one=1,zero=0;
        !          1133:   char *ansOn[20],*stuOn[20];
        !          1134:   int i,j;
        !          1135:   int sortArray[256]; 
        !          1136:   char newAnswer[MAX_LINE_LENGTH],*oldAnswer;
        !          1137: 
        !          1138:   switch(questions[questionIndex].type)
        !          1139:     {
        !          1140:     case ONE_OUT_OF_8:
        !          1141:     case GLE:
        !          1142:     case TF:
        !          1143:     case SINGLE_DIGIT:
        !          1144:       if (!flags->log)
        !          1145: 	printf("The correct answer:%10s  The student's answer:%10s, \t",
        !          1146: 	       problem->answer,student->Answers[questionIndex]);
        !          1147:       for(leafs=0;problem->answer[leafs]!='\0';leafs++)
        !          1148: 	if (problem->answer[leafs]==student->Answers[questionIndex][leafs])
        !          1149: 	  numRight++;
        !          1150:       if (!flags->log)
        !          1151: 	printf("%d right\n",numRight);
        !          1152:       break;
        !          1153:     case ASSIGNED:
        !          1154:       if (!flags->log)
        !          1155: 	printf("The student got a %s out of %d\n",
        !          1156: 	       student->Answers[questionIndex],
        !          1157: 	       questions[questionIndex].points);
        !          1158:       if (isspace(student->Answers[questionIndex][0]))
        !          1159: 	numRight=0;
        !          1160:       else
        !          1161: 	numRight=(int)(student->Answers[questionIndex][0]-'0');
        !          1162:       break;
        !          1163:     case N_OUT_OF_M:
        !          1164:       if (!flags->log)
        !          1165: 	printf("The correct answer:%10s  The student's answer:%10s, \t",
        !          1166: 	       problem->answer,student->Answers[questionIndex]);
        !          1167:       if (problem->ans_type == ANSWER_IS_CHOICE) {
        !          1168: 	for(i=0;i<255;i++) sortArray[i]=0;
        !          1169: 	for(i=0;i< strlen(problem->answer);i++)
        !          1170: 	  sortArray[(int)problem->answer[i]]=1;
        !          1171: 	for(i=0,j=0;i<255;i++) {
        !          1172: 	  if (sortArray[i]) {
        !          1173: 	    newAnswer[j]=i;
        !          1174: 	    j++;
        !          1175: 	  }
        !          1176: 	}
        !          1177: 	newAnswer[j]='\0';
        !          1178: 	if (!flags->log) 
        !          1179: 	  printf("\nThe sorted correct answer:%10s\t\t\t",newAnswer);
        !          1180: 	oldAnswer=problem->answer;
        !          1181: 	problem->answer=newAnswer;
        !          1182:       }
        !          1183:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !          1184: 	{
        !          1185: 	  ansOn[leafs]=strchr(problem->answer,('A'+(char)leafs));
        !          1186: 	}
        !          1187:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !          1188: 	{
        !          1189: 	  if (ansOn[leafs] != NULL ) 
        !          1190: 	    ansOn[leafs]=&one; 
        !          1191: 	  else
        !          1192: 	    ansOn[leafs]=&zero;
        !          1193: 	}
        !          1194:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !          1195: 	{
        !          1196: 	  stuOn[leafs]=strchr(student->Answers[questionIndex],
        !          1197: 			      ('A'+(char)leafs));
        !          1198: 	}
        !          1199:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !          1200: 	{
        !          1201: 	  if (stuOn[leafs] != NULL)
        !          1202: 	    stuOn[leafs]=&one; 
        !          1203: 	  else 
        !          1204: 	    stuOn[leafs]=&zero;
        !          1205: 	}
        !          1206:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !          1207: 	if (ansOn[leafs] == stuOn[leafs]) 
        !          1208: 	  numRight++;
        !          1209:       if (!flags->log)
        !          1210: 	printf("%d right\n",numRight);
        !          1211:       if (problem->ans_type == ANSWER_IS_CHOICE) problem->answer=oldAnswer;
        !          1212:       break;
        !          1213:     case STRING_MATCH:
        !          1214:       if (!flags->log)
        !          1215: 	printf("The correct answer:%10s  The student's answer:%10s, ",
        !          1216: 	       problem->answer,student->Answers[questionIndex]);
        !          1217:       if (problem->ans_type == ANSWER_IS_CHOICE) {
        !          1218: 	for(i=0;i<255;i++) sortArray[i]=0;
        !          1219: 	for(i=0;i< strlen(problem->answer);i++)
        !          1220: 	  sortArray[(int)problem->answer[i]]=1;
        !          1221: 	for(i=0,j=0;i<255;i++) {
        !          1222: 	  if (sortArray[i]) {
        !          1223: 	    newAnswer[j]=i;
        !          1224: 	    j++;
        !          1225: 	  }
        !          1226: 	}
        !          1227: 	newAnswer[j]='\0';
        !          1228: 	if (!flags->log) 
        !          1229: 	  printf("\nThe sorted correct answer:%10s\t\t\t",newAnswer);
        !          1230: 	oldAnswer=problem->answer;
        !          1231: 	problem->answer=newAnswer;
        !          1232:       }
        !          1233:       if (!(strcasecmp(problem->answer,student->Answers[questionIndex]))) {
        !          1234: 	if (!flags->log) printf("Answer is correct\n");
        !          1235: 	numRight=questions[questionIndex].points;
        !          1236:       } else {
        !          1237: 	if (!flags->log) printf("Answer is wrong\n");
        !          1238: 	numRight=0;
        !          1239:       }
        !          1240:       if (problem->ans_type == ANSWER_IS_CHOICE) problem->answer=oldAnswer;
        !          1241:       break;
        !          1242:     default:
        !          1243:       fprintf(stderr,"Unknown question type while grading, %c.\nDying.\n",
        !          1244: 	      questions[questionIndex].type);
        !          1245:       exit(E_UNKNOWN_QTYPE);
        !          1246:       break;
        !          1247:     }
        !          1248:   return numRight;
        !          1249: }
        !          1250: 
        !          1251: int surveyQuestion(Question questions[MAX_QUEST],int questionIndex,
        !          1252: 		  Problem_t *problem,Student *student,Flags* flags)
        !          1253: {
        !          1254:   int numRight=0;
        !          1255: 
        !          1256:   switch(questions[questionIndex].type)
        !          1257:     {
        !          1258:     case ASSIGNED:
        !          1259:       if (!flags->log)
        !          1260: 	printf("The student responded with %s\n",student->Answers[questionIndex]);
        !          1261:       if (isspace(student->Answers[questionIndex][0]))
        !          1262: 	numRight=0;
        !          1263:       else
        !          1264: 	numRight=(int)(student->Answers[questionIndex][0]-'0');
        !          1265:       break;
        !          1266:     case ONE_OUT_OF_8:
        !          1267:     case GLE:
        !          1268:     case TF:
        !          1269:     case SINGLE_DIGIT:
        !          1270:     case N_OUT_OF_M:
        !          1271:     case STRING_MATCH:
        !          1272:     default:
        !          1273:       fprintf(stderr,"Illegal question type while in SurveyMode, %c.\nDying.\n",
        !          1274: 	      questions[questionIndex].type);
        !          1275:       exit(E_UNKNOWN_QTYPE);
        !          1276:       break;
        !          1277:     }
        !          1278:   return numRight;
        !          1279: }
        !          1280: 
        !          1281: long getScorerEntry(FILE *outputFile,char *PID)
        !          1282: {
        !          1283:   char oneline[MAX_LINE_LENGTH],fmtbuf[MAX_LINE_LENGTH],
        !          1284:     studentNumber[MAX_STUDENT_NUMBER];
        !          1285:   int done=FALSE,found=FALSE,offset=0,len=0,next_r=0;
        !          1286: 
        !          1287:   rewind(outputFile);
        !          1288:   sprintf(fmtbuf,"%%%dc",MAX_STUDENT_NUMBER);
        !          1289:   while(!done)
        !          1290:     {
        !          1291:       done=!fgets(oneline,MAX_LINE_LENGTH-1,outputFile);
        !          1292:       len=strlen(oneline);
        !          1293:       if (!done)
        !          1294: 	{
        !          1295: 	  sscanf(oneline,fmtbuf,studentNumber);
        !          1296: 	  if (strncasecmp(studentNumber,PID,MAX_STUDENT_NUMBER)==0)
        !          1297: 	    {
        !          1298: 	      next_r=ftell(outputFile);
        !          1299: 	      offset = next_r-len;
        !          1300: 	      done=TRUE;
        !          1301: 	      found=TRUE;
        !          1302: 	    }
        !          1303: 	}
        !          1304:       else
        !          1305: 	{
        !          1306: 	  fseek(outputFile,0L,SEEK_END);
        !          1307: 	  offset=ftell(outputFile);
        !          1308: 	  fseek(outputFile,-1L,SEEK_END);
        !          1309: 	  while (fgetc(outputFile)=='\n')
        !          1310: 	    {
        !          1311: 	      offset--;
        !          1312: 	      fseek(outputFile,offset,SEEK_SET);
        !          1313: 	    }
        !          1314: 	  offset= offset+2;
        !          1315: 	  found=FALSE;
        !          1316: 	  done=TRUE;
        !          1317: 	}
        !          1318:     }
        !          1319:   if(!found) offset=-offset;
        !          1320:   return offset;
        !          1321: }
        !          1322: 	  
        !          1323: void setScorerEntry(FILE * outputFile,char* answerPID,char* name,
        !          1324: 		    char* answers,int score, int section, 
        !          1325: 		    char* answerstring,char* questionPID, 
        !          1326: 		    char* serialNumber,int offset)
        !          1327: {
        !          1328:   int len=0;
        !          1329:   char buf[MAX_LINE_LENGTH];
        !          1330:   
        !          1331:   rewind(outputFile);
        !          1332:   sprintf(buf,"%s %-30s %s %3d %2d %s %s %s\n",answerPID,name,answers,
        !          1333: 	  score,section,answerstring,questionPID,serialNumber);
        !          1334:   len=strlen(buf);
        !          1335:   fseek(outputFile,abs(offset),0);
        !          1336:   if(!fwrite(buf,len,1,outputFile))
        !          1337:     fprintf(stderr,"Failed write.\n");
        !          1338: }
        !          1339: 
        !          1340: void saveForm(Student *student,FILE *outputFile,
        !          1341: 	       Question questions[MAX_QUEST],Flags *flags)
        !          1342: {
        !          1343:   int result,capaQuestions,questionIndex,numRight,total=0;
        !          1344:   int offset;
        !          1345:   Problem_t *curProblem,*headProblem;
        !          1346:   char answerstring[MAX_LINE_LENGTH],grade[MAX_LINE_LENGTH];
        !          1347:   char buf[MAX_LINE_LENGTH];
        !          1348:   T_student capaStudent;
        !          1349: 
        !          1350:   if (!flags->SurveyMode)
        !          1351:     {
        !          1352:       switch(capa_get_student(student->answerPID, &capaStudent))
        !          1353: 	{
        !          1354: 	case 1: break;
        !          1355: 	case 0:
        !          1356: 	  if (flags->log)
        !          1357: 	    logError(student,flags,LOG_STUDENTNOTEXIST);
        !          1358: 	  else
        !          1359: 	    {
        !          1360: 	      fprintf(stderr,"Student %s was not found.\n",student->answerPID);
        !          1361: 	      printf("Type start to continue");
        !          1362: 	      scanf("%s",buf);
        !          1363: 	    }
        !          1364: 	  return;
        !          1365: 	  break;
        !          1366: 	case -1:
        !          1367: 	  fprintf(stderr,"Unable to find the classl file while grading\n");
        !          1368: 	  exit(E_CAPA_GET_STUDENT); break;
        !          1369: 	default:
        !          1370: 	  fprintf(stderr,"Unknow error from capa_get_student while grading\n");
        !          1371: 	  exit(E_CAPA_GET_STUDENT); break;
        !          1372: 	}	
        !          1373:       result=capa_parse(flags->SetId,&headProblem,student->questionPID,
        !          1374: 			&capaQuestions);
        !          1375:       curProblem=headProblem;
        !          1376:       if (result==0 || result == -1)
        !          1377: 	{
        !          1378: 	  fprintf(stderr,"The Parse failed: %d\nDying\n",result);
        !          1379: 	  exit(E_PARSER);
        !          1380: 	}
        !          1381:       else if (result != flags->NumQuestions)
        !          1382: 	{
        !          1383: 	  fprintf(stderr,"The parser found %d questions, there were supposed to be %d questions.\nDying\n",result,flags->NumQuestions);
        !          1384: 	  exit(E_PARSER_DIFFERENT);
        !          1385: 	}
        !          1386:       for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1387: 	{
        !          1388: 	  numRight=gradeQuestion(questions,questionIndex,curProblem,
        !          1389: 				 student,flags);
        !          1390: 	  total+=numRight;
        !          1391: 	  grade[questionIndex]='0'+(char)numRight;
        !          1392: 	  curProblem=curProblem->next;
        !          1393: 	}
        !          1394:       grade[questionIndex]='\0';
        !          1395:       printf("Total right for student %s is %d\n\n",capaStudent.s_nm,total);
        !          1396:       free_problems(headProblem);
        !          1397:     }
        !          1398:   else
        !          1399:     {
        !          1400:       strcpy(capaStudent.s_nm,"Unknown                       ");
        !          1401:       capaStudent.s_sec=0;
        !          1402:       headProblem=curProblem=NULL;      
        !          1403:       for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1404: 	{
        !          1405: 	  numRight=surveyQuestion(questions,questionIndex,curProblem,
        !          1406: 				  student,flags);
        !          1407: 	  total+=numRight;
        !          1408: 	  grade[questionIndex]='0'+(char)numRight;
        !          1409: 	} 
        !          1410:       grade[questionIndex]='\0';
        !          1411:     }
        !          1412:   
        !          1413:   answerstring[0]='\0';
        !          1414: 
        !          1415:   for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1416:     strcat(answerstring,student->Answers[questionIndex]);
        !          1417: 
        !          1418:   offset=getScorerEntry(outputFile,student->answerPID);  
        !          1419:      
        !          1420:   setScorerEntry(outputFile,student->answerPID,capaStudent.s_nm,grade,
        !          1421: 		  total,capaStudent.s_sec,answerstring,student->questionPID,
        !          1422: 		  student->serialNumber,offset);
        !          1423: }
        !          1424: 
        !          1425: int getScore(Student *student,Question questions[MAX_QUEST],Flags *flags,
        !          1426: 	     char* grade,int gradingMethod)
        !          1427: {
        !          1428:   int score=0,numRight=0,tempScore,i,leafs,points,unit;
        !          1429:   for(i=0;i<flags->NumQuestions;i++)
        !          1430:     {
        !          1431:       switch(questions[i].type)
        !          1432: 	{
        !          1433: 	case ONE_OUT_OF_8:
        !          1434: 	case SINGLE_DIGIT:
        !          1435: 	  numRight= (int) (grade[i]-'0');
        !          1436: 	  score+=numRight*questions[i].points;
        !          1437: 	  break;
        !          1438: 	case STRING_MATCH:
        !          1439: 	  /*for STRING_MATCH the score is stroed as the NumRight*/
        !          1440: 	  numRight= (int) (grade[i]-'0');
        !          1441: 	  score+=numRight;
        !          1442: 	  break;
        !          1443: 	case GLE:
        !          1444: 	case TF:
        !          1445: 	case N_OUT_OF_M:
        !          1446: 	  numRight=(int) (grade[i]-'0');
        !          1447: 	  leafs=questions[i].leafs;
        !          1448: 	  points=questions[i].points;
        !          1449: 	  unit=(int)ceil((double)points/(double)leafs);
        !          1450: 	  if (unit==0) unit=points;
        !          1451: 	  switch (gradingMethod)
        !          1452: 	    {
        !          1453: 	    case CAPA_METHOD:
        !          1454: 	      tempScore=points-(2*unit*(leafs-numRight));
        !          1455: 	      break;
        !          1456: 	    case LENIENT_METHOD:
        !          1457: 	      tempScore=points-(unit*(leafs-numRight));
        !          1458: 	      break;
        !          1459: 	    case STRICT:
        !          1460: 	      if (numRight==leafs) tempScore=points;
        !          1461: 	      else tempScore=0;
        !          1462: 	      break;
        !          1463: 	    default:
        !          1464: 	      fprintf(stderr,"Unknown grading Method. %d\n",gradingMethod);
        !          1465: 	      exit(E_GRADINGMETHOD);
        !          1466: 	      break;
        !          1467: 	    }
        !          1468: 	  if (tempScore<0)
        !          1469: 	    tempScore=0;
        !          1470: 	  score+=tempScore;
        !          1471: 	  break;
        !          1472: 	case ASSIGNED:
        !          1473: 	  numRight= (int) (grade[i]-'0');
        !          1474: 	  score+=numRight;
        !          1475: 	  break;
        !          1476: 	default:
        !          1477: 	  fprintf(stderr,"Unknown question type %c\n",questions[i].type);
        !          1478: 	  break;
        !          1479: 	}
        !          1480:     }
        !          1481:   return score;
        !          1482: }
        !          1483: 
        !          1484: void saveAnonForm(Student *student,FILE *outputFile,
        !          1485: 		  Question questions[MAX_QUEST],
        !          1486: 		  PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
        !          1487: 		  Flags *flags)
        !          1488: {
        !          1489:   int i,j=0,matches[MAX_PID_MATCHES],done=FALSE;
        !          1490:   int result,capaQuestions,questionIndex,numRight,total[MAX_PID_MATCHES];
        !          1491:   int offset,maxTotal=0,score,correctID=-1;
        !          1492:   Problem_t *curProblem,*headProblem;
        !          1493:   char answerstring[MAX_LINE_LENGTH],buf[MAX_LINE_LENGTH],
        !          1494:     grade[MAX_PID_MATCHES][MAX_LINE_LENGTH],buffer[MAX_LINE_LENGTH];
        !          1495:   T_student capaStudent;
        !          1496: 
        !          1497:   if (!flags->log)
        !          1498:     printf("Attempting to find a student with CAPA PIN %s.\n",student->PIN);
        !          1499: 
        !          1500:   for(i=0;i<flags->NumOfStudents;i++)
        !          1501:     {
        !          1502:       if (atoi(student->PIN)==PIDandPINlist[i].PIN)
        !          1503: 	{
        !          1504: 	  matches[j]=i;
        !          1505: 	  j++;
        !          1506: 	}
        !          1507:     }
        !          1508:   matches[j]=-1;
        !          1509:   switch(j)
        !          1510:     {
        !          1511:     case 0:
        !          1512:       if(flags->log)
        !          1513: 	logError(student,flags,LOG_NOPINFOUND);  
        !          1514:       else
        !          1515: 	{
        !          1516: 	  printf("No match for PIN %s\n",student->PIN);
        !          1517: 	  printf("The current form's PIN is incorrect.\n");
        !          1518: 	  printf("Please type start to continue.\n");
        !          1519: 	  scanf("%s",buf);
        !          1520: 	}
        !          1521:       return;
        !          1522:       break;
        !          1523:     case 1:
        !          1524:       if (!flags->log)
        !          1525: 	printf("Only one match assuming PID %s\n",
        !          1526: 	       PIDandPINlist[matches[0]].PID);
        !          1527:       strcpy(student->questionPID,PIDandPINlist[matches[0]].PID);
        !          1528:       saveForm(student,outputFile,questions,flags);
        !          1529:       return;
        !          1530:       break;
        !          1531:     default:
        !          1532:       break;
        !          1533:     }
        !          1534: 
        !          1535:   /* Only get here if there is more than one valid PID*/
        !          1536:   if (!flags->log)
        !          1537:     printf("Found %d matches.\n",j);
        !          1538: 
        !          1539:   maxTotal=-1;
        !          1540:   for(i=0;i<MAX_PID_MATCHES;i++)
        !          1541:     {
        !          1542:       total[i]=0;
        !          1543:       if (matches[i]==-1) break;
        !          1544:       switch(capa_get_student(student->answerPID, &capaStudent))
        !          1545: 	{
        !          1546: 	case 1: break;
        !          1547: 	case 0:
        !          1548: 	  if (flags->log)
        !          1549: 	    logError(student,flags,LOG_STUDENTNOTEXIST);
        !          1550: 	  else
        !          1551: 	    {
        !          1552: 	      fprintf(stderr,"Student %s was not found.\n",student->answerPID);
        !          1553: 	      printf("Type start to continue");
        !          1554: 	      scanf("%s",buf);
        !          1555: 	    }
        !          1556: 	  return;
        !          1557: 	  break;
        !          1558: 	case -1:
        !          1559: 	  fprintf(stderr,"Unable to find the classl file while grading\n");
        !          1560: 	  exit(E_CAPA_GET_STUDENT); break;
        !          1561: 	default:
        !          1562: 	  fprintf(stderr,"Unknown error from capa_get_student while grading\n");
        !          1563: 	  exit(E_CAPA_GET_STUDENT); break;
        !          1564: 	}	
        !          1565:       strcpy(student->questionPID,PIDandPINlist[matches[i]].PID);
        !          1566:       result=capa_parse(flags->SetId,&headProblem,student->questionPID,
        !          1567: 			&capaQuestions);
        !          1568:       curProblem=headProblem;
        !          1569:       if (result==0 || result == -1)
        !          1570: 	{
        !          1571: 	  fprintf(stderr,"The Parse failed: %d\nDying\n",result);
        !          1572: 	  exit(E_PARSER);
        !          1573: 	}
        !          1574:       else if (result != flags->NumQuestions)
        !          1575: 	{
        !          1576: 	  fprintf(stderr,"The parser found %d questions, there were supposed to be %d questions.\nDying\n",result,flags->NumQuestions);
        !          1577: 	  exit(E_PARSER_DIFFERENT);
        !          1578: 	}
        !          1579:       for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1580: 	{
        !          1581: 	  numRight=gradeQuestion(questions,questionIndex,curProblem,
        !          1582: 				 student,flags);
        !          1583: 	  if (questionIndex==4) 
        !          1584: 	    if (numRight==1)
        !          1585: 	      correctID=i;
        !          1586: 
        !          1587: 	  total[i]+=numRight;
        !          1588: 	  grade[i][questionIndex]='0'+(char)numRight;
        !          1589: 	  curProblem=curProblem->next;
        !          1590: 	}
        !          1591:       if (total[i] > total[maxTotal]) maxTotal=i;
        !          1592:       grade[i][questionIndex]='\0';
        !          1593:       
        !          1594:       /*printf("Total right for PID %s is %d\n",PIDandPINlist[matches[i]].PID,
        !          1595: 	     total[i]);*/
        !          1596:       free_problems(headProblem);  
        !          1597:     }
        !          1598: 
        !          1599:   if (correctID!=-1)
        !          1600:     {
        !          1601:       answerstring[0]='\0';
        !          1602:       for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1603: 	strcat(answerstring,student->Answers[questionIndex]);
        !          1604:       
        !          1605:       offset=getScorerEntry(outputFile,student->answerPID);  
        !          1606: 
        !          1607:       printf("Total right for student %s is %d\n\n",capaStudent.s_nm,
        !          1608: 	     total[correctID]);
        !          1609:       setScorerEntry(outputFile,student->answerPID,capaStudent.s_nm,
        !          1610: 		     grade[correctID],total[correctID],capaStudent.s_sec,
        !          1611: 		     answerstring,student->questionPID,student->serialNumber,
        !          1612: 		     offset);
        !          1613:       return;
        !          1614:     }
        !          1615: 
        !          1616:   if (!flags->QueryAboutPID && flags->log) 
        !          1617:     {
        !          1618:       logMultipleAnon(PIDandPINlist,matches,student,flags,maxTotal,total);
        !          1619: 
        !          1620:       answerstring[0]='\0';
        !          1621:       for(questionIndex=0;questionIndex<flags->NumQuestions;questionIndex++)
        !          1622: 	strcat(answerstring,student->Answers[questionIndex]);
        !          1623:       
        !          1624:       offset=getScorerEntry(outputFile,student->answerPID);  
        !          1625: 
        !          1626:       printf("Total right for student %s is %d\n\n",capaStudent.s_nm,
        !          1627: 	     total[maxTotal]);
        !          1628:       setScorerEntry(outputFile,student->answerPID,capaStudent.s_nm,
        !          1629: 		     grade[maxTotal],total[maxTotal],capaStudent.s_sec,
        !          1630: 		     answerstring,student->questionPID,student->serialNumber,
        !          1631: 		     offset);
        !          1632:     }
        !          1633:   else
        !          1634:     {
        !          1635:       while(!done)
        !          1636: 	{
        !          1637: 	  printf("Please press\n");
        !          1638: 	  for(i=0;i<MAX_PID_MATCHES;i++)
        !          1639: 	    {
        !          1640: 	      if (matches[i]==-1)
        !          1641: 		break;
        !          1642: 	      
        !          1643: 	      printf("%d) for student number %s ",i+1,
        !          1644: 		     PIDandPINlist[matches[i]].PID);
        !          1645: 	      strcpy(student->questionPID,PIDandPINlist[matches[i]].PID);
        !          1646: 	      score=getScore(student,questions,flags,grade[i],
        !          1647: 			     LENIENT_METHOD);
        !          1648: 	      printf(" Lenient: %3d ",score);
        !          1649: 	      score=getScore(student,questions,flags,grade[i],
        !          1650: 			     CAPA_METHOD);
        !          1651: 	      printf(" CAPA: %3d ",score);
        !          1652: 	      score=getScore(student,questions,flags,grade[i],
        !          1653: 			     STRICT);
        !          1654: 	      printf(" Strict: %3d \n",score);
        !          1655: 	      
        !          1656: 	    }
        !          1657: 	  scanf("%s",buffer);
        !          1658: 	  if (isdigit(buffer[0]) && (atoi(buffer) < (j+1)) && 
        !          1659: 	      (atoi(buffer) > 0))
        !          1660: 	    {
        !          1661: 	      strcpy(student->questionPID,
        !          1662: 		     PIDandPINlist[matches[atoi(buffer)-1]].PID);
        !          1663: 	      saveForm(student,outputFile,questions,flags);
        !          1664: 	      done=TRUE;
        !          1665: 	    }
        !          1666: 	}
        !          1667:     }
        !          1668: }
        !          1669: 
        !          1670: int checkForm(Student * student,Flags *flags)
        !          1671: {
        !          1672:   int error,pin;
        !          1673:   T_student capaStudent;
        !          1674: 
        !          1675: #ifdef DEBUG
        !          1676:   int i,j;
        !          1677:   printf("PID:\t%s\nPIN:\t%s\nName:\t%s\n",
        !          1678: 	 student->answerPID,student->PIN,student->Name);
        !          1679: 
        !          1680:   for(i=0,j=0;i<flags->NumQuestions;i++)
        !          1681:     {
        !          1682:       printf("Answer %d: %s\n",i+1,student->Answers[i]);
        !          1683:     }
        !          1684: #endif /*DEBUG*/
        !          1685: 
        !          1686:   error=capa_get_student(student->answerPID, &capaStudent);
        !          1687:   switch(error)
        !          1688:     {
        !          1689:     case 1:
        !          1690:       if (!flags->log)
        !          1691: 	printf("The current student is %s from section %d\n",
        !          1692: 	       capaStudent.s_nm,capaStudent.s_sec);
        !          1693:       break;
        !          1694:     case 0:
        !          1695:       if (!flags->log)
        !          1696: 	{
        !          1697: 	  printf("Error Finding the student.\n");
        !          1698: 	  printf("The Scantron reported the PID:%s\n",student->answerPID);
        !          1699: 	  printf("But this was not found in the classl file.\n");
        !          1700: 	}
        !          1701:       return CF_STID;
        !          1702:       break;
        !          1703:     case -1:
        !          1704:       return CF_CLASSL;
        !          1705:       break;
        !          1706:     default:
        !          1707:       fprintf(stderr,"capa_get_student returned an invalid result");
        !          1708:       fprintf(stderr,"in CheckForm.\n Error=%d. Dying\n",error);
        !          1709:       exit(E_CAPA_GET_STUDENT);
        !          1710:       break;
        !          1711:     }
        !          1712:   
        !          1713:   if (flags->CheckPIN && !flags->AnonMode)
        !          1714:     {
        !          1715:       pin=capa_PIN(student->answerPID,flags->SetId,0);
        !          1716:       if (pin!=atoi(student->PIN))
        !          1717: 	{
        !          1718: 	  if (flags->log)
        !          1719: 	    {
        !          1720: 	      student->classlPIN=pin;
        !          1721: 	      logError(student,flags,LOG_PINNOTMATCH);
        !          1722: 	      sprintf(student->PIN,"%04d",pin);
        !          1723: 	    }
        !          1724: 	  else
        !          1725: 	    {
        !          1726: 	      printf("There is an error with the students PIN:\n");
        !          1727: 	      printf("The Scantron reported:%s, The Classl file has:%d\n",
        !          1728: 		     student->PIN,pin);
        !          1729: 	      fprintf(stderr,"If you wish to use what the Classl file reports\n");
        !          1730: 	      fprintf(stderr,"enter y, else enter n.\n");
        !          1731: 	      if (getYesOrNo()==YES)
        !          1732: 		sprintf(student->PIN,"%04d",pin);
        !          1733: 	      else
        !          1734: 		return CF_PIN;
        !          1735: 	    }
        !          1736: 	}
        !          1737:     }
        !          1738:   return CF_NOERROR;
        !          1739: }
        !          1740: 
        !          1741: int handleCheckForm(Student *student,FILE *outputFile,
        !          1742: 		   PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
        !          1743: 		   Question questions[MAX_QUEST],Flags *flags)
        !          1744: {
        !          1745:   int done=FALSE,error;
        !          1746:   char buf[MAX_LINE_LENGTH];
        !          1747: 
        !          1748:   switch(error=checkForm(student,flags))
        !          1749:     {
        !          1750:     case CF_STID:
        !          1751:       if (flags->log)
        !          1752: 	logError(student,flags,LOG_BADPID);
        !          1753:       else
        !          1754: 	{
        !          1755: 	  printf("The current form's Student Id is incorrect.\n");
        !          1756: 	  printf("Please type start to continue.\n");
        !          1757: 	  scanf("%s",buf);
        !          1758: 	}
        !          1759:       break;
        !          1760:     case CF_CLASSL:
        !          1761:       fprintf(stderr,"The classl file was not found in the");
        !          1762:       fprintf(stderr," current directory.\n");
        !          1763:       fprintf(stderr,"Please try again.\n");
        !          1764:       done=TRUE;
        !          1765:       break;
        !          1766:     case CF_PIN:
        !          1767:       if (flags->log)
        !          1768: 	logError(student,flags,LOG_BADPIN);
        !          1769:       else
        !          1770: 	{
        !          1771: 	  fprintf(stderr,"The current form's PIN is incorrect.\n");
        !          1772: 	  fprintf(stderr,"Please type start to continue.\n");
        !          1773: 	  scanf("%s",buf);
        !          1774: 	}
        !          1775:       break;
        !          1776:     case CF_NOERROR:
        !          1777:       printf("Grading and Saving Student %s Serial#: %s\n",
        !          1778: 	     student->answerPID,student->serialNumber);
        !          1779:       if (flags->AnonMode) 
        !          1780: 	saveAnonForm(student,outputFile,questions,PIDandPINlist,flags);
        !          1781:       else
        !          1782: 	{
        !          1783: 	  strcpy(student->questionPID,student->answerPID);
        !          1784: 	  saveForm(student,outputFile,questions,flags);
        !          1785: 	}
        !          1786:       break;
        !          1787:     default:
        !          1788:       fprintf(stderr,"Unimplemented error in checkForm %d\n",error);
        !          1789:       exit(E_CHECKFORM);
        !          1790:       break;
        !          1791:     }
        !          1792:   return done;
        !          1793: }
        !          1794: 
        !          1795: int handleGetFormStatus(int status,Student *student,FILE *outputFile,
        !          1796: 		   PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
        !          1797: 		   Question questions[MAX_QUEST],Flags *flags)
        !          1798: {
        !          1799:   int done=FALSE,save=TRUE;
        !          1800:   if (status & GF_SPACES)
        !          1801:     if (flags->CheckSpaces)
        !          1802:       {
        !          1803: 	if (flags->log)
        !          1804: 	  logError(student,flags,LOG_SPACES);
        !          1805: 	else
        !          1806: 	  {
        !          1807: 	    printf("The current form appears to have some questions left\n");
        !          1808: 	    printf("blank. Please enter yes if you wish to continue \n");
        !          1809: 	    printf("grading of this form.\n");
        !          1810: 	    if (getYesOrNo()==YES)
        !          1811: 	      ;
        !          1812: 	    else 
        !          1813: 	      save=FALSE;
        !          1814: 	  }
        !          1815:       }
        !          1816: 
        !          1817:   if(status & GF_MULTIPLEMARKS)
        !          1818:     if (flags->CheckMultipleMarks)
        !          1819:       {
        !          1820: 	if (flags->log)
        !          1821: 	  logError(student,flags,LOG_MULTIPLEMARKS);
        !          1822: 	else
        !          1823: 	  {
        !          1824: 	    printf("The current form appears to have some questions with\n");
        !          1825: 	    printf("multiple marks on lines that should have only one.\n");
        !          1826: 	    printf("Please enter yes if you wish to continue grading of this form.\n");
        !          1827: 	    if (getYesOrNo()==YES)
        !          1828: 	      ;
        !          1829: 	    else 
        !          1830: 	      save=FALSE;
        !          1831: 	  }
        !          1832:       }
        !          1833:   
        !          1834:   if (status == GF_EOF)
        !          1835:     done=TRUE;
        !          1836: 
        !          1837:   if ((status & GF_PINWRONG) && flags->AnonMode) return done;
        !          1838:    
        !          1839:   if (!done && save) 
        !          1840:     if (!flags->SurveyMode)
        !          1841:       {
        !          1842: #ifdef DEBUG
        !          1843: 	printf("Checking form.\n");
        !          1844: #endif
        !          1845: 	done=handleCheckForm(student,outputFile,PIDandPINlist,questions,
        !          1846: 			     flags);
        !          1847:       }
        !          1848:     else
        !          1849:       if (flags->AnonMode)
        !          1850: 	saveAnonForm(student,outputFile,questions,PIDandPINlist,flags);
        !          1851:       else
        !          1852: 	{
        !          1853: 	  strcpy(student->questionPID,student->answerPID);
        !          1854: 	  saveForm(student,outputFile,questions,flags);
        !          1855: 	}
        !          1856:   return done;
        !          1857: }
        !          1858: 
        !          1859: void processForms(FILE *outputFile, FILE *scantron,
        !          1860: 		  Question questions[MAX_QUEST], Flags *flags)
        !          1861: {
        !          1862: 
        !          1863:   int done=FALSE;
        !          1864:   int status;
        !          1865:   Student *student=NULL;
        !          1866:   PIDPINlist PIDandPINlist[MAX_SECTION_SIZE];
        !          1867: 
        !          1868:   if (flags->AnonMode)
        !          1869:     {
        !          1870:       flags->NumOfStudents=buildPIDandPINlist(flags->SetId,PIDandPINlist);
        !          1871:       if (flags->NumOfStudents==0)
        !          1872: 	{
        !          1873: 	  fprintf(stderr,"buildPIDandPINlists returned 0 students.");
        !          1874: 	  exit(E_BUILDPIDPIN);
        !          1875: 	}
        !          1876:     }
        !          1877:   
        !          1878:   while(!done)
        !          1879:     {
        !          1880: #ifdef DEBUG
        !          1881:       printf("Reading in a new form.\n");
        !          1882: #endif
        !          1883:       status=getForm(&student,scantron,questions,flags);
        !          1884:       done=handleGetFormStatus(status,student,outputFile,PIDandPINlist,
        !          1885: 			       questions,flags);
        !          1886:       if (student != NULL)
        !          1887: 	{
        !          1888: 	  if (student->error) 
        !          1889: 	    fprintf(flags->logFile,"%s",student->origString);
        !          1890: 	  free(student);
        !          1891: 	}
        !          1892:       student=NULL;
        !          1893:     }
        !          1894: }
        !          1895: 
        !          1896: void printResults(Flags* flags)
        !          1897: {
        !          1898:   printf("Number scanned %d, number errors logged %d\n.",
        !          1899: 	 flags->linesRead,flags->loggedErrors);
        !          1900: }
        !          1901: 
        !          1902: int main(int argc, char **argv)
        !          1903: {
        !          1904:   FILE *outputFile;
        !          1905:   Question questions[MAX_QUEST];
        !          1906:   Flags flags;
        !          1907:   FILE *scantron;
        !          1908:   
        !          1909:   Parsemode_f=ASCII_MODE;
        !          1910:   flags.linesRead=0;
        !          1911:   flags.loggedErrors=0;
        !          1912: 
        !          1913:   initScreen();
        !          1914:   getInfo(&outputFile,&scantron,questions,&flags);
        !          1915:   saveInfo(outputFile,questions,&flags);
        !          1916:   processForms(outputFile,scantron,questions,&flags);
        !          1917:   printResults(&flags);
        !          1918:   return 0;
        !          1919: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>