File:  [LON-CAPA] / capa / capa51 / GUITools / scorertoset.c
Revision 1.5: download - view: text, annotated - select for diffs
Mon Sep 11 14:51:25 2000 UTC (23 years, 8 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_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
- stupid bug, short records would corrupt memory.

    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 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:    General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU 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: 
   25: /*
   26:  * scorertoset.c
   27:  * Guy Albertelli II 1997
   28:  */
   29: #include <stdio.h>
   30: #include <ctype.h>
   31: #include <tcl.h>
   32: #include <tk.h>
   33: #include "pProj/capaCommon.h"
   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+MAX_STUDENT_NUMBER,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,"%ld;%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 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>