Annotation of capa/capa51/GUITools/scorertoset.c, revision 1.1.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>