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

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

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