File:  [LON-CAPA] / capa / capa51 / Historic / Scorer / scorertoset.c
Revision 1.1: download - view: text, annotated - select for diffs
Wed Aug 30 15:02:30 2000 UTC (23 years, 10 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, version_0_5_1, version_0_5, version_0_4, stable_2002_spring, stable_2002_july, stable_2002_april, stable_2001_fall, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, STABLE, HEAD, GCI_3, GCI_2, GCI_1, CAPA_5-1-6, CAPA_5-1-5, CAPA_5-1-4_RC1, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- documentation updates

    1: /*
    2:  * scorertoset.c
    3:  * Copyright Guy Albertelli II 1997
    4:  */
    5: #include <stdio.h>
    6: #include <ctype.h>
    7: #include "Capa/capaCommon.h"
    8: #include "scorer.h"
    9: 
   10: #ifdef __sun
   11: #include <unistd.h>  /* lockf() */
   12: #endif
   13: 
   14: #ifdef   F_DBUG
   15: extern FILE *dfp; 
   16: #endif
   17: 
   18: /********************************************************** file locking */
   19: int flockstream_sh(FILE *sp)
   20: {
   21:   int fd = fileno(sp);
   22: #ifdef __sun
   23:   return ( lockf(fd,F_LOCK, 0L) );
   24: #else
   25:   return (flock(fd,LOCK_SH));
   26: #endif
   27: }
   28: 
   29: int flockstream(FILE *sp)
   30: {
   31:   int fd = fileno(sp);
   32: #ifdef __sun
   33:   return ( lockf(fd,F_LOCK, 0L) );
   34: #else
   35:   return (flock(fd,LOCK_EX));
   36: #endif
   37: }
   38: 
   39: int funlockstream(FILE *sp)
   40: {
   41:   int fd = fileno(sp);
   42: #ifdef __sun
   43:   return ( lockf(fd,F_ULOCK, 0L) );
   44: #else
   45:   return (flock(fd,LOCK_UN));
   46: #endif
   47: }
   48: 
   49: char* capa_malloc(unsigned int num,unsigned int sz)
   50: {
   51:   char *p;
   52:   p = calloc(num, sz);
   53:   return (p);
   54: }
   55: 
   56: 
   57: /****************************************************** Database Entry */
   58: int /* RETURNS: error code */
   59: scorer_set_entry(entry, student_number, set, offset) 
   60: T_entry   *entry;          /* pointer to entry structure to fill in */
   61: char      *student_number;
   62: int        set;
   63: long       offset;
   64: {
   65:    FILE    *fp;
   66:    int      errcode=0;
   67:    int      len;
   68:    char     filename[FILE_NAME_LENGTH];
   69:    char     a_line[MAX_LINE_LENGTH];
   70: 
   71:    sprintf(filename,"records/set%d.sb",set);
   72:    if ((fp=fopen(filename,"r+"))==NULL)
   73:      {
   74:       printf("Error: can't open %s\n",filename);  return (-1);
   75:      }
   76:    sprintf(a_line,"%s %s,%s\n",entry->student_number,entry->answers,
   77: 	   entry->tries);
   78:    len = strlen(a_line);
   79:    flockstream(fp);
   80:    fseek(fp,offset,0);
   81:    if (!fwrite(a_line,len,1,fp) ) 
   82:      {
   83:        printf("Error writing data to file\n");
   84:        errcode= (-1);
   85:      }
   86:    funlockstream(fp);
   87:    fclose(fp);
   88:    return (errcode);
   89: }
   90: 
   91: /**************************************************** Get db entry*/
   92: 
   93: long /* RETURNS: byte offset to start of record, 0 if error,
   94:                     -offset if not found & newly created  */
   95: scorer_get_entry(entry, student_number, set) 
   96: T_entry   *entry;           
   97: char      *student_number;  
   98: int        set;            
   99: {
  100:    char      filename[FILE_NAME_LENGTH];
  101:    FILE     *fp;
  102:    int       len, nq;          
  103:    char     *ans_p, *tries_p,oneline[MAX_LINE_LENGTH],fmtbuf[MAX_LINE_LENGTH];
  104:    long      offset=0, next_r;             
  105:    int       ii, done, found=0;
  106:    char      a_sn[MAX_STUDENT_NUMBER+1];
  107:    
  108:    sprintf(filename,"records/set%d.sb",set); 
  109:    if ((fp=fopen(filename,"r"))==NULL) 
  110:      {
  111:       printf("Error: can't open %s\n",filename);
  112:       return (0); 
  113:      }
  114:    sprintf(entry->student_number,"%s",student_number);
  115:    sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
  116:    flockstream(fp);
  117:    fgets(oneline,MAX_LINE_LENGTH-1,fp); 
  118:    len = strlen(oneline); sscanf(oneline,"%d",&nq);
  119:    ans_p = capa_malloc(nq+1,1); tries_p = capa_malloc(3*nq,1);
  120:    fgets(oneline,MAX_LINE_LENGTH-1,fp); /* skip weight line */
  121:    fgets(oneline,MAX_LINE_LENGTH-1,fp); /* hand grading */
  122:    done = 0;
  123:    while(!done) 
  124:      {
  125:        done = !fgets(oneline,MAX_LINE_LENGTH-1,fp); len = strlen(oneline);
  126:        if( !done ) 
  127: 	 {
  128: 	   sscanf(oneline,fmtbuf,a_sn);
  129: 	   if( !strncasecmp(a_sn,student_number,MAX_STUDENT_NUMBER) ) 
  130: 	     { /* Found */
  131: 	       next_r = ftell(fp); offset = next_r - len; done = 1; found = 1;
  132: 	     }
  133: 	 } 
  134:        else 
  135: 	 {
  136: 	   fseek(fp,0L,SEEK_END);
  137: 	   offset = ftell(fp);  /* last byte, if last bye is cr, back up one */
  138: 	   fseek(fp,-1L,SEEK_END);
  139: 	   while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
  140: 	   offset = offset +2; /* last char and cr */
  141: 	   found = 0; done=1;
  142: 	 }
  143:      }
  144:    funlockstream(fp); fclose(fp);
  145:    if(!found) 
  146:      {
  147:        for(ii=0;ii<nq;ii++) 
  148: 	 { /* Initialize answer string and tries string */
  149: 	   ans_p[ii] = '-'; tries_p[3*ii] = ' '; tries_p[3*ii + 1] = '0';
  150: 	   if(ii < nq-1) tries_p[3*ii + 2] = ',';
  151: 	 }
  152:        entry->answers = ans_p;
  153:        entry->tries   = tries_p;
  154:        entry->e_probs = nq;
  155:        if (scorer_set_entry(entry,student_number,set,offset)==-1)
  156: 	 offset=0;
  157:        offset = -offset;
  158:      } 
  159:    else 
  160:      {
  161:        sprintf(fmtbuf, "%%%dc",nq);
  162:        sscanf(oneline + MAX_STUDENT_NUMBER+1,fmtbuf,ans_p);
  163:        sprintf(fmtbuf, "%%%dc",(3*nq-1));
  164:        sscanf(oneline + MAX_STUDENT_NUMBER+1+nq+1,fmtbuf,tries_p);
  165:        entry->answers = ans_p;
  166:        entry->tries   = tries_p;
  167:        entry->e_probs = nq;
  168:      }
  169:    return (offset);
  170: }
  171: 
  172: void initScreen(void)
  173: {
  174:   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");
  175:   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");
  176:   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");
  177:   printf("Covert form Scorer output to CAPA set file and score. ");
  178:   printf("Arch %s, Version %s.%s\n",ARCHSTR,MAJORVER,MINORVER);
  179: }
  180: 
  181: int getSetId()
  182: {
  183:   int setId;
  184:   printf("Please enter the Set Id number:");
  185:   scanf("%d",&setId);
  186:   return setId;
  187: }
  188: 
  189: FILE *openInputFile(int setId)
  190: {
  191:   char filename[MAX_LINE_LENGTH];
  192:   FILE *inputFile;
  193: 
  194:   sprintf(filename,"records/scorer.output.%d",setId);
  195:   inputFile=fopen(filename,"r");
  196:   if (inputFile==NULL)
  197:     {
  198:       fprintf(stderr,"%s not found\n",filename);
  199:       exit(-1);
  200:     }
  201:   return inputFile;
  202: }
  203: 
  204: int getHeader(FILE *inputFile, int setId, Question questions[MAX_QUEST])
  205: {
  206:   char class[MAX_LINE_LENGTH],set[MAX_LINE_LENGTH],flags[MAX_LINE_LENGTH],buf,
  207:     numQuestions[MAX_LINE_LENGTH];
  208:   int i=0,done=FALSE;
  209:   float pauseTime;
  210: 
  211:   fscanf(inputFile,"%s %s %s %s %f",class,set,numQuestions,flags,&pauseTime);
  212:   printf("%s %s %s %s %f\n",class,set,numQuestions,flags,pauseTime);
  213: 
  214:   fscanf(inputFile,"%c",&buf);
  215:   while(!done)
  216:     {
  217:       buf=fgetc(inputFile);
  218:       switch (buf)
  219: 	{
  220: 	case '\n':
  221: 	  done=TRUE;
  222: 	  break;
  223: 	case ' ':
  224: 	  break;
  225: 	default:
  226: 	  questions[i].type=buf;
  227: 	  buf=fgetc(inputFile);
  228: 	  questions[i].points=(int)(buf-'0');
  229: 	  buf=fgetc(inputFile);
  230: 	  questions[i].leafs=(int)(buf-'0');
  231: 	  i++;
  232: 	  break;
  233: 	}
  234:     }
  235:   return i;
  236: }
  237: 
  238: int getGradingMethod(void)
  239: {
  240:   int done=FALSE,i;
  241:   while(!done)
  242:     {
  243:       printf("\t\t%d for Capa Standard Method\n",CAPA_METHOD);
  244:       printf("\t\t%d for Lenient Method\n",LENIENT_METHOD);
  245:       printf("\t\t%d for Strict Method\n",STRICT);
  246:       printf("Which grading method?");
  247:       
  248:       scanf("%d",&i);
  249:       switch(i)
  250: 	{
  251: 	case CAPA_METHOD:
  252: 	case LENIENT_METHOD:
  253: 	case STRICT:
  254: 	  done=TRUE;
  255: 	  break;
  256: 	default:
  257: 	  fprintf(stderr,"Please choose one of\n");
  258: 	  break;
  259: 	}
  260:     }
  261:   return i;
  262: }
  263: 
  264: void processFile(FILE *inputFile,Question questions[MAX_QUEST],int setId,
  265: 		 int gradingMethod,int numQuestions)
  266: {
  267:   T_entry grade;
  268:   char studentNumber[MAX_STUDENT_NUMBER+1],name[MAX_NAME_CHAR+1];
  269:   int offset,score,section,buf,i,numRight,points=0,leafs,processed=0,unit;
  270: 
  271:   printf("Processing");
  272:   while(fscanf(inputFile,"%s",studentNumber)!=EOF)
  273:     {
  274:       processed++;
  275:       if (processed%100==1) { printf("%d",processed-1); }
  276:       printf(".");
  277:       fflush(stdout);
  278:       if ((offset = scorer_get_entry(&grade,studentNumber,setId))==0)
  279: 	{
  280: 	  fprintf(stderr,"Please create the set%d.sb file\n",setId);
  281: 	  exit(-1);
  282: 	}
  283:       fscanf(inputFile,"%30c",name);
  284:       fscanf(inputFile,"%s",grade.answers); 
  285:       fscanf(inputFile,"%d",&score);
  286:       fscanf(inputFile,"%d",&section);
  287:       if ( (grade.e_probs != strlen(grade.answers)) 
  288: 	   || 
  289: 	   (strlen(grade.answers) != numQuestions))
  290: 	{
  291: 	  fprintf(stderr,"There is a disagreement in the number of problems");
  292: 	  fprintf(stderr,"\nNumQuestions:%d\n",numQuestions);
  293: 	  fprintf(stderr,"strlen(grade.answers):%d\n",strlen(grade.answers));
  294: 	  fprintf(stderr,"grade.answers:%s\n",grade.answers);
  295: 	  fprintf(stderr,"grade.e_probs:%d\n",grade.e_probs);
  296: 	  fprintf(stderr,"The set.sb file may have bad entries, please\n");
  297: 	  fprintf(stderr,"check the file and fix the error.\n");
  298: 	  exit(-1);
  299: 	}
  300:       buf='\0';
  301:       while(buf!='\n')
  302: 	{
  303: 	  buf=fgetc(inputFile);
  304: 	}
  305: #ifdef DEBUG
  306:       printf("%d %d\n",numQuestions,strlen(grade.answers));
  307: #endif /*DEBUG*/
  308:       for(i=0;i<numQuestions;i++)
  309: 	{
  310: 	  switch(questions[i].type)
  311: 	    {
  312: 	    case ONE_OUT_OF_8:
  313: 	    case SINGLE_DIGIT:
  314: 	      numRight= (int) (grade.answers[i]-'0');
  315: 	      score=numRight*questions[i].points;
  316: 	      grade.answers[i]='0'+(char)score;
  317: 	      break;
  318: 	    case STRING_MATCH:
  319: 	      /*for STRING_MATCH the score is stroed as the NumRight*/
  320: 	      numRight= (int) (grade.answers[i]-'0');
  321: 	      score=numRight;
  322: 	      grade.answers[i]='0'+(char)score;
  323: 	      break;
  324: 	    case GLE:
  325: 	    case TF:
  326: 	    case N_OUT_OF_M:
  327: 	      numRight=(int) (grade.answers[i]-'0');
  328: 	      leafs=questions[i].leafs;
  329: 	      points=questions[i].points;
  330: 	      unit=(int)ceil((double)points/(double)leafs);
  331: 	      if (unit==0) unit=points;
  332: 	      switch (gradingMethod)
  333: 		{
  334: 		case CAPA_METHOD:
  335: 		  score=points-(2*unit*(leafs-numRight));
  336: 		  break;
  337: 		case LENIENT_METHOD:
  338: 		  score=points-(unit*(leafs-numRight));
  339: 		  break;
  340: 		case STRICT:
  341: 		  if (numRight==leafs) score=points;
  342: 		  else score=0;
  343: 		  break;
  344: 		default:
  345: 		  fprintf(stderr,"Unknown grading Method. %d\n",gradingMethod);
  346: 		  break;
  347: 		}
  348: 	      if (score<0)
  349: 		score=0;
  350: 	      grade.answers[i]='0'+(char)score;
  351: 	      break;
  352: 	    case ASSIGNED:
  353: 	      /*
  354: 	       *grade.answers already has the correct number of points. 
  355: 	       *i.e whatever the scorer.output file had in it and was put in
  356: 	       *grade.
  357: 	       */
  358: 	      break;
  359: 	    default:
  360: 	      fprintf(stderr,"Unknown question type %c\n",questions[i].type);
  361: 	      break;
  362: 	    }
  363: 	}
  364:       for(i=0;i<strlen(grade.answers);i++)
  365: 	{
  366: 	  grade.tries[3*i]=' ';
  367: 	  grade.tries[3*i+1]='1';
  368: 	  grade.tries[3*i+2]=',';
  369: 	}
  370:       grade.tries[3*i-1]='\0';
  371:       grade.answers[i]='\0';
  372: #ifdef DEBUG
  373:       printf("%s\n",studentNumber);
  374: #endif /*DEBUG*/
  375:       if (scorer_set_entry(&grade,studentNumber,setId,abs(offset))==-1)
  376: 	{
  377: 	  fprintf(stderr,"Please create the set%d.sb file\n",setId);
  378: 	  exit(-1);
  379: 	}
  380:     }
  381:   printf("\nProcessed %d results\n",processed);
  382: }
  383: 
  384: int main(void)
  385: {
  386:   FILE * inputFile;
  387:   int setId,gradingMethod,numQuestions;
  388:   Question questions[MAX_QUEST];
  389: 
  390:   initScreen();
  391:   setId=getSetId();
  392:   inputFile=openInputFile(setId);
  393:   numQuestions=getHeader(inputFile,setId,questions);
  394:   gradingMethod=getGradingMethod();
  395: 
  396:   processFile(inputFile,questions,setId,gradingMethod,numQuestions);
  397: 
  398:   printf("\nProcessing completed. Look in records/set%d.sb for results.\n",
  399: 	 setId);
  400:   return 0;
  401: }

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