File:  [LON-CAPA] / capa / capa51 / GUITools / scorer.funct.c
Revision 1.4: download - view: text, annotated - select for diffs
Mon Aug 7 20:47:29 2000 UTC (23 years, 9 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, release_5-1-3, 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
- fixed license notices the reference the GNU GPL rather than the GNU LGPL

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

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