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

    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>