Annotation of capa/capa51/GUITools/scorertoset.c, revision 1.1

1.1     ! albertel    1: /*
        !             2:  * scorertoset.c
        !             3:  * Copyright Guy Albertelli II 1997
        !             4:  */
        !             5: #include <stdio.h>
        !             6: #include <ctype.h>
        !             7: #include <tcl.h>
        !             8: #include <tk.h>
        !             9: #include "Capa/capaCommon.h"
        !            10: #include "scorer.h"
        !            11: 
        !            12: /**************************************************Set Database Entry */
        !            13: int scorer_set_entry(ClientData notused, Tcl_Interp *interp, int argc, char** argv)
        !            14: {
        !            15:    FILE    *fp;
        !            16:    int      fd;
        !            17:    int      errcode=TCL_OK;
        !            18:    int      done,len,new_len,item_cnt;
        !            19:    long     next_r, orig_size, new_size, big_buf_size;
        !            20:    char     filename[FILE_NAME_LENGTH];
        !            21:    char     *a_line, tmpline[MAX_LINE_LENGTH], errorline[MAX_LINE_LENGTH], 
        !            22:      tmp_sn[MAX_STUDENT_NUMBER+1], fmtbuf[SMALL_LINE_BUFFER];
        !            23:    char    *big_buf;
        !            24:    char    *student_number,*answers,*tries;
        !            25:    int      set;
        !            26:    long     offset;
        !            27:    
        !            28:    if (argc != 6) {
        !            29:      Tcl_SetResult(interp,"usage is: studentNumber set fileOffset answers tries",
        !            30: 		   TCL_VOLATILE);
        !            31:      return TCL_ERROR;
        !            32:    }
        !            33:    student_number=argv[1];
        !            34:    set=atoi(argv[2]);
        !            35:    offset=atoi(argv[3]);
        !            36:    answers=argv[4];
        !            37:    tries=argv[5];
        !            38: 
        !            39:    offset=(offset<0)?-offset:offset;
        !            40: 
        !            41:    sprintf(filename,"records/set%d.sb",set);
        !            42:    if ((fp=fopen(filename,"r+"))==NULL) {
        !            43:      sprintf(errorline,"Error: can't open %s\n",filename);
        !            44:      Tcl_SetResult(interp,errorline,TCL_VOLATILE);
        !            45:      return TCL_ERROR;
        !            46:    }
        !            47:    a_line=capa_malloc(strlen(tries)*5,1);
        !            48:    sprintf(a_line,"%s %s,%s\n",student_number,answers,tries);
        !            49:    new_len = strlen(a_line);
        !            50:    sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
        !            51:    flockstream(fp);
        !            52:    fseek(fp,0L,SEEK_END);
        !            53:    orig_size = ftell(fp);
        !            54:    big_buf_size = orig_size + new_len;
        !            55:    big_buf = capa_malloc(big_buf_size,1);
        !            56:    fseek(fp,0L,SEEK_SET); /* rewind to beginning of file */
        !            57:    fgets(tmpline,TMP_LINE_LENGTH-1,fp); /* skip weight line, including \n */
        !            58:    fgets(tmpline,TMP_LINE_LENGTH-1,fp); /* hand grading */
        !            59:    done = 0;
        !            60:    while(!done) {
        !            61:      done = !fgets(tmpline,TMP_LINE_LENGTH-1,fp); len = strlen(tmpline);
        !            62:      if( !done ) {
        !            63:        sscanf(tmpline,fmtbuf,tmp_sn);
        !            64:        if( !strncasecmp(tmp_sn,student_number,MAX_STUDENT_NUMBER) ) { /* Found */
        !            65:          next_r = ftell(fp); offset = next_r - len; done = 1;
        !            66:          item_cnt=fread(big_buf,1,big_buf_size, fp); /* read remaining lines into buffer */
        !            67:          if(item_cnt >= 0 ) { /* no error reading remaining lines */
        !            68:            big_buf[item_cnt]=0;   /* terminate the buffer, for sure */
        !            69:            fseek(fp,offset,SEEK_SET);  /* reposition file pointer to the record */
        !            70:            if (!fwrite(a_line,new_len,1,fp) ) {       /* write out the records */
        !            71: 	     sprintf(errorline,"Error writing data to file: %s\n",filename);
        !            72: 	     Tcl_SetResult(interp,errorline,TCL_VOLATILE);
        !            73:              errcode= TCL_ERROR;
        !            74:            }
        !            75: 	   if (item_cnt != 0) {
        !            76: 	     if (!fwrite(big_buf,item_cnt,1,fp) ){/*write out the remainings*/
        !            77: 	       sprintf(errorline,"Error writing data to file: %s\n",filename);
        !            78: 	       Tcl_SetResult(interp,errorline,TCL_VOLATILE);
        !            79: 	       errcode= TCL_ERROR;
        !            80: 	     }
        !            81: 	   }
        !            82: 	   new_size = ftell(fp);
        !            83: 	   if(new_size < orig_size ) {
        !            84: 	     fd = fileno(fp);
        !            85: 	     ftruncate(fd,new_size);
        !            86: 	   }
        !            87:          }
        !            88:        }
        !            89:      } else { /* end of file */
        !            90:        fseek(fp,0L,SEEK_END);
        !            91:        offset = ftell(fp);  /* last byte, if last byte is cr, back up one */
        !            92:        fseek(fp,-1L,SEEK_END);
        !            93:        while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
        !            94:        offset = offset +2; /* last char and cr */
        !            95:        done=1;
        !            96:        fseek(fp,offset,SEEK_SET);
        !            97:        if (!fwrite(a_line,new_len,1,fp) ) {       /* write out the records */
        !            98: 	 sprintf(errorline,"Error writing data to file: %s\n",filename);
        !            99: 	 Tcl_SetResult(interp,errorline,TCL_VOLATILE);
        !           100: 	 errcode= TCL_ERROR;
        !           101:        }
        !           102:      }
        !           103:    }
        !           104:    fflush(fp);
        !           105:    funlockstream(fp);   /* <======= unlock the file */
        !           106:    fclose(fp);
        !           107:    capa_mfree(big_buf);  /* free up the buffer */
        !           108:    return (errcode);
        !           109: }
        !           110: 
        !           111: /**************************************************** Get db entry*/
        !           112: /* RETURNS: byte offset to start of record, 0 if error,
        !           113:                     -offset if not found & newly created  
        !           114: 		    
        !           115: */
        !           116: int scorer_get_entry(ClientData notused, Tcl_Interp *interp, int argc, char** argv)
        !           117: {
        !           118:    char      filename[FILE_NAME_LENGTH];
        !           119:    FILE     *fp;
        !           120:    int       len, nq;          
        !           121:    char     *ans_p, *tries_p,oneline[MAX_LINE_LENGTH],fmtbuf[MAX_LINE_LENGTH],
        !           122:      buf[MAX_LINE_LENGTH];
        !           123:    long      offset=0, next_r;             
        !           124:    int       ii, done, found=0,set;
        !           125:    char      a_sn[MAX_STUDENT_NUMBER+1];
        !           126:    char     *student_number;
        !           127:    T_entry  *entry;
        !           128: 
        !           129:    if (argc!=3) {
        !           130:      Tcl_SetResult(interp,"usage is: studentNumber set",TCL_VOLATILE);
        !           131:      return TCL_ERROR;
        !           132:    }
        !           133:    set=atoi(argv[2]);
        !           134:    student_number=argv[1];
        !           135:    entry=(T_entry*)capa_malloc(1,sizeof(T_entry));
        !           136: 
        !           137:    sprintf(filename,"records/set%d.sb",set); 
        !           138:    if ((fp=fopen(filename,"r"))==NULL)  {
        !           139:      sprintf(buf,"Error: can't open %s\n",filename);
        !           140:      Tcl_SetResult(interp,buf,TCL_VOLATILE);
        !           141:      return TCL_ERROR; 
        !           142:    }
        !           143:    sprintf(entry->student_number,"%s",student_number);
        !           144:    sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
        !           145:    flockstream(fp);
        !           146:    fgets(oneline,MAX_LINE_LENGTH-1,fp); 
        !           147:    len = strlen(oneline); sscanf(oneline,"%d",&nq);
        !           148:    ans_p = capa_malloc(nq+1,1); tries_p = capa_malloc(3*nq,1);
        !           149:    fgets(oneline,MAX_LINE_LENGTH-1,fp); /* skip weight line */
        !           150:    fgets(oneline,MAX_LINE_LENGTH-1,fp); /* hand grading */
        !           151:    done = 0;
        !           152:    while(!done)  {
        !           153:      done = !fgets(oneline,MAX_LINE_LENGTH-1,fp); len = strlen(oneline);
        !           154:      if( !done )  {
        !           155:        sscanf(oneline,fmtbuf,a_sn);
        !           156:        if( !strncasecmp(a_sn,student_number,MAX_STUDENT_NUMBER) )  { /* Found */
        !           157: 	 next_r = ftell(fp); offset = next_r - len; done = 1; found = 1;
        !           158:        }
        !           159:      } else  {
        !           160:        fseek(fp,0L,SEEK_END);
        !           161:        offset = ftell(fp);  /* last byte, if last bye is cr, back up one */
        !           162:        fseek(fp,-1L,SEEK_END);
        !           163:        while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
        !           164:        offset = offset +2; /* last char and cr */
        !           165:        found = 0; done=1;
        !           166:      }
        !           167:    }
        !           168:    funlockstream(fp); fclose(fp);
        !           169:    if(!found) {
        !           170:      for(ii=0;ii<nq;ii++) { /* Initialize answer string and tries string */
        !           171:        ans_p[ii] = '-'; tries_p[3*ii] = ' '; tries_p[3*ii + 1] = '0';
        !           172:        if(ii < nq-1) tries_p[3*ii + 2] = ',';
        !           173:      }
        !           174:      entry->answers = ans_p;
        !           175:      entry->tries   = tries_p;
        !           176:      entry->e_probs = nq;
        !           177:      /*if (scorer_set_entry(entry,student_number,set,offset)==-1)
        !           178:        offset=0;*/
        !           179:      offset = -offset;
        !           180:    } else {
        !           181:      sprintf(fmtbuf, "%%%dc",nq);
        !           182:      sscanf(oneline + MAX_STUDENT_NUMBER+1,fmtbuf,ans_p);
        !           183:      sprintf(fmtbuf, "%%%dc",(3*nq-1));
        !           184:      sscanf(oneline + MAX_STUDENT_NUMBER+1+nq+1,fmtbuf,tries_p);
        !           185:      entry->answers = ans_p;
        !           186:      entry->tries   = tries_p;
        !           187:      entry->e_probs = nq;
        !           188:    }
        !           189:    sprintf(buf,"%d;%d;%s;%s",offset,entry->e_probs,entry->answers,entry->tries);
        !           190:    Tcl_SetResult(interp,buf,TCL_VOLATILE);
        !           191:    return TCL_OK;
        !           192: }
        !           193: 
        !           194: void processFile(FILE *inputFile,Question questions[MAX_QUEST],int setId,
        !           195: 		 int gradingMethod,int numQuestions)
        !           196: {
        !           197:   T_entry grade;
        !           198:   char studentNumber[MAX_STUDENT_NUMBER+1],name[MAX_NAME_CHAR+1];
        !           199:   int offset,score,section,buf,i,numRight,points=0,leafs,processed=0,unit;
        !           200: 
        !           201:   printf("Processing");
        !           202:   while(fscanf(inputFile,"%s",studentNumber)!=EOF)
        !           203:     {
        !           204:       processed++;
        !           205:       if (processed%100==1) { printf("%d",processed-1); }
        !           206:       printf(".");
        !           207:       fflush(stdout);
        !           208:       /*      if ((offset = scorer_get_entry(&grade,studentNumber,setId))==0)
        !           209: 	{
        !           210: 	  fprintf(stderr,"Please create the set%d.sb file\n",setId);
        !           211: 	  exit(-1);
        !           212: 	}
        !           213:       */
        !           214:       fscanf(inputFile,"%30c",name);
        !           215:       fscanf(inputFile,"%s",grade.answers); 
        !           216:       fscanf(inputFile,"%d",&score);
        !           217:       fscanf(inputFile,"%d",&section);
        !           218:       if ( (grade.e_probs != strlen(grade.answers)) 
        !           219: 	   || 
        !           220: 	   (strlen(grade.answers) != numQuestions))
        !           221: 	{
        !           222: 	  fprintf(stderr,"There is a disagreement in the number of problems");
        !           223: 	  fprintf(stderr,"\nNumQuestions:%d\n",numQuestions);
        !           224: 	  fprintf(stderr,"strlen(grade.answers):%d\n",strlen(grade.answers));
        !           225: 	  fprintf(stderr,"grade.answers:%s\n",grade.answers);
        !           226: 	  fprintf(stderr,"grade.e_probs:%d\n",grade.e_probs);
        !           227: 	  fprintf(stderr,"The set.sb file may have bad entries, please\n");
        !           228: 	  fprintf(stderr,"check the file and fix the error.\n");
        !           229: 	  exit(-1);
        !           230: 	}
        !           231:       buf='\0';
        !           232:       while(buf!='\n')
        !           233: 	{
        !           234: 	  buf=fgetc(inputFile);
        !           235: 	}
        !           236: #ifdef DEBUG
        !           237:       printf("%d %d\n",numQuestions,strlen(grade.answers));
        !           238: #endif /*DEBUG*/
        !           239:       for(i=0;i<numQuestions;i++)
        !           240: 	{
        !           241: 	  switch(questions[i].type)
        !           242: 	    {
        !           243: 	    case ONE_OUT_OF_8:
        !           244: 	    case SINGLE_DIGIT:
        !           245: 	      numRight= (int) (grade.answers[i]-'0');
        !           246: 	      score=numRight*questions[i].points;
        !           247: 	      grade.answers[i]='0'+(char)score;
        !           248: 	      break;
        !           249: 	    case STRING_MATCH:
        !           250: 	      /*for STRING_MATCH the score is stroed as the NumRight*/
        !           251: 	      numRight= (int) (grade.answers[i]-'0');
        !           252: 	      score=numRight;
        !           253: 	      grade.answers[i]='0'+(char)score;
        !           254: 	      break;
        !           255: 	    case GLE:
        !           256: 	    case TF:
        !           257: 	    case N_OUT_OF_M:
        !           258: 	      numRight=(int) (grade.answers[i]-'0');
        !           259: 	      leafs=questions[i].leafs;
        !           260: 	      points=questions[i].points;
        !           261: 	      unit=(int)ceil((double)points/(double)leafs);
        !           262: 	      if (unit==0) unit=points;
        !           263: 	      switch (gradingMethod)
        !           264: 		{
        !           265: 		case CAPA_METHOD:
        !           266: 		  score=points-(2*unit*(leafs-numRight));
        !           267: 		  break;
        !           268: 		case LENIENT_METHOD:
        !           269: 		  score=points-(unit*(leafs-numRight));
        !           270: 		  break;
        !           271: 		case STRICT:
        !           272: 		  if (numRight==leafs) score=points;
        !           273: 		  else score=0;
        !           274: 		  break;
        !           275: 		default:
        !           276: 		  fprintf(stderr,"Unknown grading Method. %d\n",gradingMethod);
        !           277: 		  break;
        !           278: 		}
        !           279: 	      if (score<0)
        !           280: 		score=0;
        !           281: 	      grade.answers[i]='0'+(char)score;
        !           282: 	      break;
        !           283: 	    case ASSIGNED:
        !           284: 	      /*
        !           285: 	       *grade.answers already has the correct number of points. 
        !           286: 	       *i.e whatever the scorer.output file had in it and was put in
        !           287: 	       *grade.
        !           288: 	       */
        !           289: 	      break;
        !           290: 	    default:
        !           291: 	      fprintf(stderr,"Unknown question type %c\n",questions[i].type);
        !           292: 	      break;
        !           293: 	    }
        !           294: 	}
        !           295:       for(i=0;i<strlen(grade.answers);i++)
        !           296: 	{
        !           297: 	  grade.tries[3*i]=' ';
        !           298: 	  grade.tries[3*i+1]='1';
        !           299: 	  grade.tries[3*i+2]=',';
        !           300: 	}
        !           301:       grade.tries[3*i-1]='\0';
        !           302:       grade.answers[i]='\0';
        !           303: #ifdef DEBUG
        !           304:       printf("%s\n",studentNumber);
        !           305: #endif /*DEBUG*/
        !           306:       /*if (scorer_set_entry(&grade,studentNumber,setId,abs(offset))==-1)
        !           307: 	{
        !           308: 	  fprintf(stderr,"Please create the set%d.sb file\n",setId);
        !           309: 	  exit(-1);
        !           310: 	}
        !           311:       */
        !           312:     }
        !           313:   printf("\nProcessed %d results\n",processed);
        !           314: }

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