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

    1: /*
    2:  * scorer.c
    3:  * Copyright Guy Albertelli II 1997
    4:  */
    5: #include <stdio.h>
    6: #include <stdlib.h>
    7: #include <ctype.h>
    8: #include <string.h>
    9: #ifdef NeXT
   10: #endif
   11: #ifdef linux
   12: #include <sys/types.h>
   13: #include <sys/stat.h>
   14: #include <fcntl.h>
   15: #include <termios.h>
   16: #include <unistd.h>
   17: #endif
   18: #include <tcl.h>
   19: #include <tk.h>
   20: #include "Capa/capaCommon.h"
   21: #include "scorer.h"
   22: #include "manager.h"
   23: #ifdef DMALLOC
   24: #include <dmalloc.h>
   25: #endif
   26: 
   27: extern int Parsemode_f;
   28: char NUMBER[10]={'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
   29: char LETTER[10]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
   30: PIDPINlist *studentList;
   31: 
   32: /* 2 arguments, string 1 and string 2 result is an integer of # charactes the same*/
   33: int compareCapaID(ClientData notused, Tcl_Interp *interp, int argc,
   34: 		     char* argv[])
   35: {
   36:   int same=0,length,i;
   37:   char buf[MAX_BUFFER_SIZE];
   38:   length=strlen(argv[1]);
   39:   for(i=0;i<length;i++) if(argv[1][i] == argv[2][i]) same++;
   40:   sprintf(buf,"%d",same);
   41:   Tcl_SetResult(interp,buf,TCL_VOLATILE);
   42:   return TCL_OK;
   43: }
   44: 
   45: /* 3 arguments, the PID of the student, the setID, the number of expected questions */
   46: int getAnswersFromSet(ClientData notused, Tcl_Interp *interp, int argc,
   47: 		     char* argv[])
   48: {
   49:   int result,capaQuestions,questionIndex,numRight,total=0,numQuestions;
   50:   Problem_t *curProblem,*headProblem;
   51:   char answerstring[MAX_LINE_LENGTH],grade[MAX_LINE_LENGTH];
   52:   char *buf;
   53:   T_student capaStudent;
   54:   char* questionPID;
   55:   int setID;
   56:   Tcl_Obj* tclResult;
   57: 
   58: 
   59:   if (argc!=4) {
   60:     Tcl_SetResult(interp,"usage is: PID setID numQuestions",TCL_VOLATILE);
   61:     return TCL_ERROR;
   62:   }
   63:   questionPID=argv[1];
   64:   setID=atoi(argv[2]);
   65:   numQuestions=atoi(argv[3]);
   66: 
   67:   result=capa_parse(setID,&headProblem,questionPID,&capaQuestions,NULL);
   68:   curProblem=headProblem;
   69: 
   70:   if (result==0 || result == -1) {
   71:     buf=capa_malloc(MAX_LINE_LENGTH,sizeof(char));
   72:     sprintf(buf,"The Parse failed: %d\n",result);
   73:     Tcl_SetResult(interp,buf,TCL_VOLATILE);
   74:     capa_mfree(buf);
   75:     return TCL_ERROR;
   76:   } else if (result != numQuestions)  {
   77:     buf=capa_malloc(MAX_LINE_LENGTH,sizeof(char));
   78:     sprintf(buf,"The parser found %d questions, there were supposed to be %d questions.\nDying\n",result,numQuestions);
   79:     Tcl_SetResult(interp,buf,TCL_VOLATILE);
   80:     capa_mfree(buf);
   81:     return TCL_ERROR;
   82:   }
   83: 
   84:   tclResult=Tcl_NewStringObj("",0);
   85:   Tcl_IncrRefCount(tclResult);
   86:   for(questionIndex=0;questionIndex<numQuestions;questionIndex++) {
   87:     buf=(char*)capa_malloc(strlen(curProblem->answer)+MAX_LINE_LENGTH,sizeof(char));
   88:     sprintf(buf,"%s ",curProblem->answer);
   89:     Tcl_AppendStringsToObj(tclResult,buf,NULL);
   90:     capa_mfree(buf);
   91:     curProblem=curProblem->next;
   92:   }
   93:   free_problems(headProblem);
   94:   Tcl_SetObjResult(interp,tclResult);
   95:   Tcl_DecrRefCount(tclResult);
   96:   return TCL_OK;
   97: }
   98: 
   99: /*needs num (the unique ident)*/
  100: int freeStudentList(ClientData notused, Tcl_Interp *interp, int agrc,
  101: 		     char* argv[])
  102: {
  103:   int i,num = atoi(argv[1]);
  104:   PIDPINlist *cur,*prev;
  105: 
  106:   if (!studentList) { return TCL_OK; }
  107: 
  108:   cur=studentList;
  109:   prev=NULL;
  110:   while((cur->num!=num) && cur->next) { prev=cur; cur=cur->next; }
  111:   if (cur->num!=num) { return TCL_OK; }
  112:   
  113:   capa_mfree(cur->classname);
  114:   for(i=0;i<cur->numStudents;i++) capa_mfree(cur->classList[i].capaid_plus);
  115:   capa_mfree((char*)cur->classList);
  116:   if ( prev != NULL ) {
  117:     prev->next=cur->next;
  118:   } else {
  119:     if (cur->next) studentList=cur->next;
  120:   }
  121:   capa_mfree((char*)cur);
  122:   return TCL_OK;
  123: }
  124: 
  125: /*needs num (unique ident), classname, setId, capaid_plus size*/
  126: int buildStudentList(ClientData notused, Tcl_Interp *interp, int argc,
  127: 		     char* argv[])
  128: {
  129:   long i,j,numStudents,num,capaidplusSize,setId,part1,part2;
  130:   T_student *curStudent,*headStudent;
  131:   PIDPINlist *cur;
  132:   char *buf,*buf2;
  133:   Tcl_Obj* tclResult;
  134: 
  135:   if (argc!=5) {
  136:     Tcl_SetResult(interp,"usage is: number classname setId capa_id_plus_size",
  137: 		  TCL_VOLATILE);
  138:     return TCL_ERROR;
  139:   }
  140: 
  141:   if (studentList) {
  142:     cur=studentList;
  143:     while(cur->next) { cur=cur->next; }
  144:     cur->next=(PIDPINlist*)capa_malloc(1,sizeof(PIDPINlist));
  145:     cur=cur->next;
  146:   } else {
  147:     studentList=(PIDPINlist*)capa_malloc(1,sizeof(PIDPINlist));
  148:     cur=studentList;
  149:   }
  150:   cur->classname=(char*)capa_malloc(strlen(argv[2]),sizeof(char));
  151:   strcpy(argv[2],cur->classname);
  152:   cur->num=num=atoi(argv[1]);
  153:   setId=atoi(argv[3]);
  154:   capaidplusSize=atoi(argv[4]);
  155: 
  156:   numStudents=capa_get_section(&headStudent, 0);
  157:   if ( numStudents == 0 ) {
  158:     Tcl_SetResult(interp,"No students in class.",TCL_VOLATILE);
  159:     return TCL_ERROR;
  160:   } else if ( numStudents < 0 ) {
  161:     Tcl_SetResult(interp,"Unable to read the classl file",TCL_VOLATILE);
  162:     return TCL_ERROR;
  163:   }
  164:   cur->classList=(PIDPIN*)capa_malloc(numStudents,sizeof(PIDPIN));
  165:   curStudent=headStudent;
  166:   tclResult=Tcl_NewStringObj("",0);
  167:   Tcl_IncrRefCount(tclResult);
  168:   for(i=0;curStudent;curStudent=curStudent->s_next,i++) {
  169:     capa_seed(&part1, &part2, curStudent->s_sn);setall(part1, part2);
  170:     strcpy(cur->classList[i].PID,curStudent->s_sn);
  171:     cur->classList[i].PIN=capa_PIN(curStudent->s_sn,setId,0);
  172:     cur->classList[i].capaid_plus=capa_id_plus(curStudent->s_sn,setId,capaidplusSize);
  173:     j=strlen(cur->classList[i].capaid_plus)+MAX_PIN_CHAR+
  174:       strlen(cur->classList[i].PID)+strlen(curStudent->s_nm)+MAX_LINE_LENGTH;
  175:     buf=(char*)capa_malloc(j,sizeof(char));
  176:     sprintf(buf,"{{%s} %s %d %s} ",curStudent->s_nm,curStudent->s_sn,
  177: 	    cur->classList[i].PIN,cur->classList[i].capaid_plus);
  178:     Tcl_AppendStringsToObj(tclResult,buf,NULL);
  179:     capa_mfree(buf);
  180:   }
  181:   Tcl_SetObjResult(interp,tclResult);
  182:   Tcl_IncrRefCount(tclResult);
  183:   free_students(headStudent);
  184:   cur->numStudents=numStudents;
  185:   return TCL_OK;
  186: }
  187: 
  188: int gradeQuestion(Question questions[MAX_QUEST],int questionIndex,
  189: 		  Problem_t *problem,Student *student,Flags* flags)
  190: {
  191:   int numRight=0,leafs;
  192:   char one=1,zero=0;
  193:   char *ansOn[20],*stuOn[20];
  194:   int i,j;
  195:   int sortArray[256]; 
  196:   char newAnswer[MAX_LINE_LENGTH],*oldAnswer;
  197: 
  198:   switch(questions[questionIndex].type)
  199:     {
  200:     case ONE_OUT_OF_8:
  201:     case GLE:
  202:     case TF:
  203:     case SINGLE_DIGIT:
  204:       if (!flags->log)
  205: 	printf("The correct answer:%10s  The student's answer:%10s, \t",
  206: 	       problem->answer,student->Answers[questionIndex]);
  207:       for(leafs=0;problem->answer[leafs]!='\0';leafs++)
  208: 	if (problem->answer[leafs]==student->Answers[questionIndex][leafs])
  209: 	  numRight++;
  210:       if (!flags->log)
  211: 	printf("%d right\n",numRight);
  212:       break;
  213:     case ASSIGNED:
  214:       if (!flags->log)
  215: 	printf("The student got a %s out of %d\n",
  216: 	       student->Answers[questionIndex],
  217: 	       questions[questionIndex].points);
  218:       if (isspace(student->Answers[questionIndex][0]))
  219: 	numRight=0;
  220:       else
  221: 	numRight=(int)(student->Answers[questionIndex][0]-'0');
  222:       break;
  223:     case N_OUT_OF_M:
  224:       if (!flags->log)
  225: 	printf("The correct answer:%10s  The student's answer:%10s, \t",
  226: 	       problem->answer,student->Answers[questionIndex]);
  227:       if (problem->ans_type == ANSWER_IS_CHOICE) {
  228: 	for(i=0;i<255;i++) sortArray[i]=0;
  229: 	for(i=0;i< strlen(problem->answer);i++)
  230: 	  sortArray[(int)problem->answer[i]]=1;
  231: 	for(i=0,j=0;i<255;i++) {
  232: 	  if (sortArray[i]) {
  233: 	    newAnswer[j]=i;
  234: 	    j++;
  235: 	  }
  236: 	}
  237: 	newAnswer[j]='\0';
  238: 	if (!flags->log) 
  239: 	  printf("\nThe sorted correct answer:%10s\t\t\t",newAnswer);
  240: 	oldAnswer=problem->answer;
  241: 	problem->answer=newAnswer;
  242:       }
  243:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
  244: 	{
  245: 	  ansOn[leafs]=strchr(problem->answer,('A'+(char)leafs));
  246: 	}
  247:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
  248: 	{
  249: 	  if (ansOn[leafs] != NULL ) 
  250: 	    ansOn[leafs]=&one; 
  251: 	  else
  252: 	    ansOn[leafs]=&zero;
  253: 	}
  254:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
  255: 	{
  256: 	  stuOn[leafs]=strchr(student->Answers[questionIndex],
  257: 			      ('A'+(char)leafs));
  258: 	}
  259:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
  260: 	{
  261: 	  if (stuOn[leafs] != NULL)
  262: 	    stuOn[leafs]=&one; 
  263: 	  else 
  264: 	    stuOn[leafs]=&zero;
  265: 	}
  266:       for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
  267: 	if (ansOn[leafs] == stuOn[leafs]) 
  268: 	  numRight++;
  269:       if (!flags->log)
  270: 	printf("%d right\n",numRight);
  271:       if (problem->ans_type == ANSWER_IS_CHOICE) problem->answer=oldAnswer;
  272:       break;
  273:     case STRING_MATCH:
  274:       if (!flags->log)
  275: 	printf("The correct answer:%10s  The student's answer:%10s, ",
  276: 	       problem->answer,student->Answers[questionIndex]);
  277:       if (problem->ans_type == ANSWER_IS_CHOICE) {
  278: 	for(i=0;i<255;i++) sortArray[i]=0;
  279: 	for(i=0;i< strlen(problem->answer);i++)
  280: 	  sortArray[(int)problem->answer[i]]=1;
  281: 	for(i=0,j=0;i<255;i++) {
  282: 	  if (sortArray[i]) {
  283: 	    newAnswer[j]=i;
  284: 	    j++;
  285: 	  }
  286: 	}
  287: 	newAnswer[j]='\0';
  288: 	if (!flags->log) 
  289: 	  printf("\nThe sorted correct answer:%10s\t\t\t",newAnswer);
  290: 	oldAnswer=problem->answer;
  291: 	problem->answer=newAnswer;
  292:       }
  293:       if (!(strcasecmp(problem->answer,student->Answers[questionIndex]))) {
  294: 	if (!flags->log) printf("Answer is correct\n");
  295: 	numRight=questions[questionIndex].points;
  296:       } else {
  297: 	if (!flags->log) printf("Answer is wrong\n");
  298: 	numRight=0;
  299:       }
  300:       if (problem->ans_type == ANSWER_IS_CHOICE) problem->answer=oldAnswer;
  301:       break;
  302:     default:
  303:       fprintf(stderr,"Unknown question type while grading, %c.\nDying.\n",
  304: 	      questions[questionIndex].type);
  305:       exit(E_UNKNOWN_QTYPE);
  306:       break;
  307:     }
  308:   return numRight;
  309: }
  310: 
  311: 

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