File:  [LON-CAPA] / capa / capa51 / Historic / bubblersurveyexam.c
Revision 1.2: download - view: text, annotated - select for diffs
Fri Jul 7 18:33:51 2000 UTC (23 years, 11 months ago) by albertel
Branches: MAIN
CVS tags: version5-1-2-first_release, HEAD
- added GPL notices

    1: /* scantron control program for named surveys
    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: 
   25: #include <stdio.h>
   26: #include "Capa/capaCommon.h"
   27: #include "bubbler.h"
   28: 
   29: 
   30: #include <ctype.h>
   31: 
   32: #ifdef __sun
   33: #include <unistd.h>  /* lockf() */
   34: #endif
   35: 
   36: #include "capaParser.h"
   37: #include "capaToken.h"
   38: #include "ranlib.h"
   39: /*********************************************/
   40: /*  flock() in SUN is in BSD compatibility lib */
   41: /*  #include <sys/file.h> */
   42: 
   43: #ifdef   F_DBUG
   44: extern FILE *dfp; 
   45: #endif
   46: 
   47: 
   48: /********************************************************** file locking */
   49: int
   50: flockstream_sh(sp) FILE *sp;
   51: {
   52:   int fd;
   53:   
   54:   fd = fileno(sp);
   55:   
   56: #ifdef __sun
   57:   return ( lockf(fd,F_LOCK, 0L) );
   58: #else
   59:   return (flock(fd,LOCK_SH));
   60: #endif
   61: }
   62: 
   63: int
   64: flockstream(sp) FILE *sp;
   65: {
   66:   int fd;
   67:   
   68:   fd = fileno(sp);
   69:   
   70: #ifdef __sun
   71:   return ( lockf(fd,F_LOCK, 0L) );
   72: #else
   73:   return (flock(fd,LOCK_EX));
   74: #endif
   75: }
   76: int
   77: funlockstream(sp) FILE *sp;
   78: {
   79:   int fd;
   80:   
   81:   fd = fileno(sp);
   82:   
   83: #ifdef __sun
   84:   return ( lockf(fd,F_ULOCK, 0L) );
   85: #else
   86:   return (flock(fd,LOCK_UN));
   87: #endif
   88: }
   89: 
   90: char *
   91: capa_malloc(num,sz) unsigned num,sz;
   92: {
   93:   char *p;
   94:   p = calloc(num, sz);
   95:   return (p);
   96: }
   97: 
   98: 
   99: /****************************************************** Database Entry */
  100: int /* RETURNS: error code */
  101: capa_set_entry(entry, student_number, set, offset) 
  102: T_entry   *entry;          /* pointer to entry structure to fill in */
  103: char      *student_number;
  104: int        set;
  105: long       offset;
  106: {
  107:    FILE    *fp;
  108:    int      errcode=0;
  109:    int      len;
  110:    char     filename[FILE_NAME_LENGTH];
  111:    char     a_line[512];
  112: 
  113:    sprintf(filename,"records/set%d.db",set);
  114:    if ((fp=fopen(filename,"r+"))==NULL) {
  115:       printf("Error: can't open %s\n",filename);  return (-1);
  116:    }
  117:    sprintf(a_line,"%s %s,%s\n",entry->student_number,entry->answers,entry->tries);
  118:    len = strlen(a_line);
  119:    flockstream(fp);
  120:    fseek(fp,offset,0);
  121:      if (!fwrite(a_line,len,1,fp) ) {
  122:        printf("Error writing data to file\n");
  123:        errcode= (-1);
  124:      }
  125:    funlockstream(fp);
  126:    fclose(fp);
  127:    return (errcode);
  128: }
  129: 
  130: /**************************************************** Get db entry*/
  131: 
  132: long /* RETURNS: byte offset to start of record, 0 if error,
  133:                     -offset if not found & newly created  */
  134: capa_get_entry(entry, student_number, set) 
  135: T_entry   *entry;           
  136: char      *student_number;  
  137: int        set;            
  138: {
  139:    char      filename[FILE_NAME_LENGTH];
  140:    FILE     *fp;
  141:    int       len, nq;          
  142:    char     *ans_p, *tries_p, oneline[512],fmtbuf[128];          
  143:    long      offset, next_r;             
  144:    int       ii, done=0, found=0;
  145:    char      a_sn[MAX_STUDENT_NUMBER+1];
  146:    
  147:    sprintf(filename,"records/set%d.db",set); 
  148:    if ((fp=fopen(filename,"r"))==NULL) {
  149:       printf("Error: can't open %s\n",filename);
  150:       return (-1); 
  151:    }
  152:    sprintf(entry->student_number,"%s",student_number);
  153:    sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
  154:    flockstream(fp);
  155:    fgets(oneline,511,fp); len = strlen(oneline); sscanf(oneline,"%d",&nq);
  156:    ans_p = capa_malloc(nq+1,1); tries_p = capa_malloc(3*nq,1);
  157:    fgets(oneline,511,fp); /* skip weight line */
  158:    fgets(oneline,511,fp); /* hand grading */
  159:    done = 0;
  160:    while(!done) {
  161:      done = !fgets(oneline,511,fp); len = strlen(oneline);
  162:      if( !done ) {
  163:        sscanf(oneline,fmtbuf,a_sn);
  164:        if( !strncasecmp(a_sn,student_number,MAX_STUDENT_NUMBER) ) { /* Found */
  165:          next_r = ftell(fp); offset = next_r - len; done = 1; found = 1;
  166:        }
  167:      } else {
  168:        fseek(fp,0L,SEEK_END);
  169:        offset = ftell(fp);  /* last byte, if last bye is cr, back up one */
  170:        fseek(fp,-1L,SEEK_END);
  171:        while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
  172:        offset = offset +2; /* last char and cr */
  173:        found = 0; done=1;
  174:      }
  175:    }
  176:    funlockstream(fp); fclose(fp);
  177:    if(!found) {
  178:      for(ii=0;ii<nq;ii++) { /* Initialize answer string and tries string */
  179:        ans_p[ii] = '-'; tries_p[3*ii] = ' '; tries_p[3*ii + 1] = '0';
  180:        if(ii < nq-1) tries_p[3*ii + 2] = ',';
  181:      }
  182:      entry->answers = ans_p;
  183:      entry->tries   = tries_p;
  184:      capa_set_entry(entry,student_number,set,offset);
  185:      offset = -offset;
  186:    } else {
  187:      sprintf(fmtbuf, "%%%dc",nq);
  188:      sscanf(oneline + MAX_STUDENT_NUMBER+1,fmtbuf,ans_p);
  189:      sprintf(fmtbuf, "%%%dc",(3*nq-1));
  190:      sscanf(oneline + MAX_STUDENT_NUMBER+1+nq+1,fmtbuf,tries_p);
  191:      entry->answers = ans_p;
  192:      entry->tries   = tries_p;
  193:    }
  194:    return (offset);
  195: }
  196: 
  197: int main()
  198: {
  199:   T_entry grade,examgrade;
  200:   FILE * inputFile, * outputFile;
  201:   int i=0,setnumber,score,section,setId,done=0,numQuestions,examSetId;
  202:   char class[10],set[3],name[MAX_NAME_CHAR+1],buf,buffmt[128],
  203:       studentnumber[MAX_STUDENT_NUMBER+1],filename[128];
  204:   int q=0,r=0,answerTop[MAXQUEST][11],answerMid[MAXQUEST][11],
  205:       answerBot[MAXQUEST][11],examtotal=0,firstDiv,secondDiv;
  206:   Question questions[MAXQUEST];
  207:   
  208:   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  209:   printf("Covert form Bubbler output to survey results ");
  210:   printf("Version 0.1.00\n");
  211:   printf("Please enter the Set Id number. of survey");
  212:   scanf("%d",&setId);
  213:   printf("Please enter the SetId of the Final exam.");
  214:   scanf("%d",&examSetId);
  215:   printf("Please enter score of first divison.");
  216:   scanf("%d",&firstDiv);
  217:   printf("Please enter score of second divison.");
  218:   scanf("%d",&secondDiv);
  219:   sprintf(filename,"bubbler.output.%d",setId);
  220:   inputFile=fopen(filename,"r");
  221: 
  222:   if (inputFile==NULL)
  223:     {
  224:       fprintf(stderr,"%s not found\n",filename);
  225:       exit(-1);
  226:     }
  227: 
  228:   fscanf(inputFile,"%s %s",class,set);
  229:   printf("%s %s\n",class,set);
  230:   setnumber=atoi(set);
  231: 
  232:   i=0;
  233:   fscanf(inputFile,"%c",&buf);
  234:   while(!done)
  235:     {
  236:       buf=fgetc(inputFile);
  237:       if (buf!='\n')
  238: 	{
  239: 	  questions[i].type=buf;
  240: 	  buf=fgetc(inputFile);
  241: 	  questions[i].points=questions[i].leafs=(int)(buf-'0');
  242: 	  i++;
  243: 	}
  244:       else
  245: 	{
  246: 	  done=1;
  247: 	}
  248:     }
  249:   
  250:   numQuestions=i;
  251: 
  252:   for(q=0;q<MAXQUEST;q++)
  253:     for(r=0;r<11;r++)
  254:       {
  255: 	answerTop[q][r]=0;
  256: 	answerMid[q][r]=0;
  257: 	answerBot[q][r]=0;
  258:       }
  259: 
  260:   printf("Processing");
  261:   while(fscanf(inputFile,"%s",studentnumber)!=EOF)
  262:     {
  263:       examtotal=0;
  264:       printf(".");
  265:       fflush(stdout);
  266:       fscanf(inputFile,"%32c",name);
  267:       sprintf(buffmt,"%%%dc",numQuestions);
  268:       fscanf(inputFile,buffmt,grade.answers);
  269:       fscanf(inputFile,"%d",&score);
  270:       fscanf(inputFile,"%d",&section);
  271:       buf='\0';
  272:       while(buf!='\n')
  273: 	{
  274: 	  buf=fgetc(inputFile);
  275: 	}
  276:       capa_get_entry(&examgrade,studentnumber,examSetId);
  277:       
  278: #ifdef DEBUG
  279:       printf("%d %d\n",numQuestions,strlen(grade.answers));
  280: #endif /*DEBUG*/
  281: 
  282:       for(i=0;i<numQuestions;i++)
  283: 	{
  284: 	  switch(examgrade.answers[i])
  285: 	    {
  286: 	    case 'Y':
  287: 	    case 'y':
  288: 	      i=0;
  289: 	      fprintf(stderr,"Skipping %s b/c of Ys\n",studentnumber);
  290: 	      goto skip_student;
  291: 	      break;
  292: 	    case 'N':
  293: 	    case 'n':
  294: 	      i=0;
  295: 	      fprintf(stderr,"Skipping %s b/c of Ns\n",studentnumber);
  296: 	      goto skip_student;	      
  297: 	      break;
  298: 	    case ' ':
  299: 	    case '-':
  300: 	      i=0;
  301: 	      fprintf(stderr,"Skipping %s b/c not complete\n",studentnumber);
  302: 	      goto skip_student;
  303: 	      break;
  304: 	    default:
  305: 	      if (isdigit(examgrade.answers[i]))
  306: 		{
  307: 		  examtotal+=(int)(examgrade.answers[i]-'0');
  308: 		}
  309: 	      else
  310: 		{
  311: 		  i=0;
  312: 		  fprintf(stderr,"Skipping %s b/c weird\n",studentnumber);
  313: 		  goto skip_student;
  314: 		}
  315: 	      break;
  316: 	    }
  317: 	}
  318:       for(i=0;i<numQuestions;i++)
  319: 	{
  320: 	  switch(questions[i].type)
  321: 	    {
  322: 	    case 'a':
  323: 	    case 'f':
  324: 	    case 'g':
  325: 	    case 'b':
  326: 	    case 'c':
  327: 	    case 'e':
  328: 	    case 'd':
  329: 	      if (isdigit(grade.answers[i]))
  330: 		{
  331: 		  if (examtotal < firstDiv)
  332: 		    answerBot[i][grade.answers[i]-'0']++;
  333: 		  else if (examtotal < secondDiv)
  334: 		    answerMid[i][grade.answers[i]-'0']++;
  335: 		  else
  336: 		    answerTop[i][grade.answers[i]-'0']++;
  337: 		}
  338: 	      else if(isspace(grade.answers[i]))
  339: 		{
  340: 		  if (examtotal < firstDiv)
  341: 		    answerBot[i][10]++;
  342: 		  else if (examtotal < secondDiv)
  343: 		    answerMid[i][10]++;
  344: 		  else
  345: 		    answerTop[i][10]++;
  346: 		}
  347: 	      break;
  348: 	    default:
  349: 	      printf("Unknown question type\n");
  350: 	      break;
  351: 	    }
  352: 	}
  353:       skip_student:
  354:       grade.answers[i]='\0';
  355: #ifdef DEBUG
  356:       printf("%s\n",studentnumber);
  357: #endif /*DEBUG*/
  358:     }
  359: 
  360:   sprintf(filename,"surveyexam.%d",setId);
  361:   outputFile=fopen(filename,"w");
  362:   if (outputFile==NULL)
  363:     {
  364:       fprintf(stderr,"%s not found\n",filename);
  365:       exit(-1);
  366:     }
  367: 
  368:   fprintf(outputFile,"Bottom Third:\n");
  369:   for(q=0;q<numQuestions;q++)
  370:     {
  371:       fprintf(outputFile,"Question: %d\n",q+1);
  372:       fprintf(outputFile,"  0   1   2   3   4   5   6   7   8   9   S\n");
  373:       for(r=0;r<11;r++)
  374: 	{
  375: 	  fprintf(outputFile,"%3d ",answerBot[q][r]);
  376: 	}
  377:       fprintf(outputFile,"\n");
  378:     }
  379:   fprintf(outputFile,"\014Middle Third:\n");
  380:   for(q=0;q<numQuestions;q++)
  381:     {
  382:       fprintf(outputFile,"Question: %d\n",q+1);
  383:       fprintf(outputFile,"  0   1   2   3   4   5   6   7   8   9   S\n");
  384:       for(r=0;r<11;r++)
  385: 	{
  386: 	  fprintf(outputFile,"%3d ",answerMid[q][r]);
  387: 	}
  388:       fprintf(outputFile,"\n");
  389:     }
  390:   fprintf(outputFile,"\014Top Third:\n");
  391:   for(q=0;q<numQuestions;q++)
  392:     {
  393:       fprintf(outputFile,"Question: %d\n",q+1);
  394:       fprintf(outputFile,"  0   1   2   3   4   5   6   7   8   9   S\n");
  395:       for(r=0;r<11;r++)
  396: 	{
  397: 	  fprintf(outputFile,"%3d ",answerTop[q][r]);
  398: 	}
  399:       fprintf(outputFile,"\n");
  400:     }
  401:   printf("\nProcessing completed. Look in survey.%d for results.\n",
  402: 	 setId);
  403:   return 0;
  404: }

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