Annotation of capa/capa51/GUITools/grader.funct.c, revision 1.2

1.1       albertel    1: /*
                      2:  * grader.funct.c
                      3:  * Copyright Guy Albertelli II 1996
                      4:  * Portions Copyright Issac Tsai
                      5:  */
                      6: #include <stdio.h>
                      7: #include <tk.h>
                      8: #include <Capa/capaCommon.h>
                      9: #include <grader.h>
                     10: #include <common.h>
                     11: #include <ctype.h>
                     12: #include <time.h>
                     13: 
                     14: /*
                     15:  * used to remeber the weights and partial credit from a parse for when 
                     16:  * setting a DBHeader
                     17:  */
                     18: 
                     19: /* Reads a header form the file and sets up the time and date variables
                     20:  */ 
                     21: int capaGetHeader(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                     22: {
                     23:   T_header header;
                     24:   char * setNumber,buf[BUFFER_SIZE],*sectionNumber,dateStr[BUFFER_SIZE];
                     25:   int set,section,result;
                     26: 
                     27: 
                     28:   setNumber=Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY);
                     29:   sectionNumber=Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY);
                     30: 
                     31:   if ( setNumber[0] == '\0' )  return TCL_OK;
                     32:   if ( sectionNumber[0] == '\0' )  return TCL_OK;
                     33: 
                     34:   set=atoi(setNumber);
                     35:   section=atoi(sectionNumber);
                     36: 
                     37:   result=capa_get_header(&header,set);
                     38: 
                     39:   if ( result == -1 )
                     40:     {
                     41:       Tcl_ResetResult(interp);
                     42:       Tcl_AppendElement(interp,"0");
                     43:       return TCL_OK;
                     44:     }
                     45: 
                     46:   result=capa_get_date(CHECK_OPEN_DATE,NULL,section,set,dateStr);
                     47:   if (result<0) {
                     48:     Tcl_ResetResult(interp);
                     49:     Tcl_AppendElement(interp,"-1");
                     50:     return TCL_OK;
                     51:   }
                     52:   sscanf(dateStr,"%10c",buf);
                     53:   buf[10]='\0';
                     54:   Tcl_SetVar(interp,"gOpenDate",buf,TCL_GLOBAL_ONLY);
                     55:   sscanf((dateStr)+11,"%5c",buf);
                     56:   buf[5]='\0';
                     57:   Tcl_SetVar(interp,"gOpenTime",buf,TCL_GLOBAL_ONLY);
                     58: 
                     59:   result=capa_get_date(CHECK_DUE_DATE,NULL,section,set,dateStr);
                     60:   if (result<0) {
                     61:     Tcl_ResetResult(interp);
                     62:     Tcl_AppendElement(interp,"-1");
                     63:     return TCL_OK;
                     64:   }
                     65:   sscanf(dateStr,"%10c",buf);
                     66:   buf[10]='\0';
                     67:   Tcl_SetVar(interp,"gDueDate",buf,TCL_GLOBAL_ONLY);
                     68:   sscanf((dateStr)+11,"%5c",buf);
                     69:   buf[5]='\0';
                     70:   Tcl_SetVar(interp,"gDueTime",buf,TCL_GLOBAL_ONLY);
                     71: 
                     72:   result=capa_get_date(CHECK_ANS_DATE,NULL,section,set,dateStr);
                     73:   if (result<0) {
                     74:     Tcl_ResetResult(interp);
                     75:     Tcl_AppendElement(interp,"-1");
                     76:     return TCL_OK;
                     77:   }
                     78:   sscanf(dateStr,"%10c",buf);
                     79:   buf[10]='\0';
                     80:   Tcl_SetVar(interp,"gAnswerDate",buf,TCL_GLOBAL_ONLY);
                     81:   sscanf((dateStr)+11,"%5c",buf);
                     82:   buf[5]='\0';
                     83:   Tcl_SetVar(interp,"gAnswerTime",buf,TCL_GLOBAL_ONLY);
                     84:   
                     85:   Tcl_ResetResult(interp);
                     86:   Tcl_AppendElement(interp,"1");
                     87:   capa_mfree(header.weight);
                     88:   capa_mfree(header.partial_credit);
                     89:   return TCL_OK;
                     90: }
                     91: 
                     92: /* get the information for all of the students in the current section
                     93:  * and puts them into the listbox.
                     94:  * Arguments: the name of the variable the widget name of the listbox
                     95:  * is in.
                     96:  */
                     97: int capaGetStudents(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                     98: {
                     99:   T_student *headStudent,*currentStudent;
                    100:   int result,section,set,setScore,maxScore,num=0;
                    101:   char buf[BUFFER_SIZE],buf2[BUFFER_SIZE],*answers,*listWidget;
                    102:   
                    103:   section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
                    104:   set=atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY));
                    105:   
                    106:   if ( (listWidget = Tcl_GetVar(interp,argv[1],
                    107: 				 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL)
                    108:     {
                    109:       fprintf(stderr,"Tcl_GetVar error\n");
                    110:       fprintf(stderr,"%s\n",interp->result);
                    111:       return TCL_ERROR;
                    112:     }
                    113: 
                    114:   result=capa_sorted_section(&headStudent,section);
                    115: 
                    116:   if (result == -1 || result == 0)
                    117:     {
                    118:       Tcl_Eval(interp,"displayError \"Invalid section\"");
                    119:       Tcl_ResetResult(interp);
                    120:       return TCL_OK;
                    121:     }
                    122: 
                    123:   currentStudent=headStudent;
                    124: 
                    125:   while(currentStudent!=NULL)
                    126:     {
                    127:       num++;
                    128:       setScore = capa_get_score(currentStudent->s_sn,set,&maxScore,&answers);
                    129:       if ( setScore == -1 ) setScore=0;
                    130:       sprintf(buf,"%s %s   %2d/%2d      %2d      ",currentStudent->s_nm,
                    131: 	      currentStudent->s_sn,setScore,maxScore,
                    132: 	      capa_PIN(currentStudent->s_sn,set,0));
                    133:       
                    134:       capaPrepareBuffer(buf,buf2,0);
                    135:       sprintf(buf,"%s insert end \"%s\" ",listWidget,buf2);
                    136:       
                    137:       if (Tcl_Eval(interp,buf) != TCL_OK)
                    138: 	{
                    139: 	  fprintf(stderr,"Tcl_Eval error\n");
                    140: 	  fprintf(stderr,"%s\n",interp->result);
                    141: 	  free_students(headStudent);
                    142: 	  return TCL_ERROR;
                    143: 	}
                    144:       
                    145:       if (!(num%10)) {
                    146: 	if (Tcl_Eval(interp,"update") != TCL_OK)
                    147: 	  {
                    148: 	    fprintf(stderr,"Tcl_Eval error\n");
                    149: 	    fprintf(stderr,"%s\n",interp->result);
                    150: 	    free_students(headStudent);
                    151: 	    return TCL_ERROR;
                    152: 	  }
                    153:       }
                    154:       currentStudent=currentStudent->s_next;
                    155:       capa_mfree(answers);
                    156:     }
                    157: 
                    158:   free_students(headStudent);
                    159:   if (!(num%5)) {
                    160:     if (Tcl_Eval(interp,"update") != TCL_OK)
                    161:       {
                    162: 	fprintf(stderr,"Tcl_Eval error\n");
                    163: 	fprintf(stderr,"%s\n",interp->result);
                    164: 	return TCL_ERROR;
                    165:       }
                    166:   }
                    167:   return TCL_OK;
                    168: }
                    169: 
                    170: /* searches for the section a student is in by either name or number
                    171:  * Arguments: one of (name or number) and then the name or number to
                    172:  * search for.
                    173:  */
                    174: int capaFindSection(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    175: { 
                    176:   int   errorNm;
                    177:   char  searchStr[MAX_NAME_CHAR+1],buf[MAX_NAME_CHAR+1];
                    178:   T_student student;
                    179:   
                    180:   switch(argv[1][1])
                    181:     {
                    182:       case 'a':
                    183: 	strncpy(searchStr,argv[2],MAX_NAME_CHAR+1);
                    184: 	if ( (errorNm = capa_student_byname(searchStr,&student ))==0 ) 
                    185: 	  {
                    186: 	    sprintf(buf,"%d",0);
                    187: 	  }
                    188: 	else
                    189: 	  {
                    190: 	    sprintf(buf,"%d",student.s_sec);
                    191: 	  }
                    192: 	break;
                    193:     case 'u':
                    194: 	strncpy(searchStr,argv[2],MAX_NAME_CHAR+1);
                    195: 	if ( (errorNm = capa_get_student(searchStr,&student ))==0 ) 
                    196: 	  {
                    197: 	    sprintf(buf,"%d",0);
                    198: 	  }
                    199: 	else
                    200: 	  {
                    201: 	    sprintf(buf,"%d",student.s_sec);
                    202: 	  }      
                    203:       break;
                    204:     default:
                    205:       break;
                    206:     }
                    207:   Tcl_ResetResult(interp);
                    208:   Tcl_AppendElement(interp,buf);
                    209:   return TCL_OK;
                    210: }
                    211: 
                    212: /* makes a student report
                    213:  * Arguments: the student number
                    214:  */
                    215: int capaGetReportInfo(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    216: {
                    217:   char          studentNumber[MAX_STUDENT_NUMBER+1], 
                    218:                 lineOne[BUFFER_SIZE],*wgt,*partialCredit;
                    219:   T_header      header;
                    220:   T_entry       entry;
                    221:   int		ii, setIdx, setScores, setValids, 
                    222:                 totalSet, totalProbs, neverLogin;
                    223:   int           termScores, termValids;
                    224: 
                    225:   strncpy(studentNumber,argv[1], MAX_STUDENT_NUMBER+1);
                    226:   totalSet  = howManySetDBFile();
                    227: 
                    228:   Tcl_ResetResult(interp);
                    229: 
                    230:   for(termScores=0,termValids=0,setIdx=1;setIdx <= totalSet ;setIdx++) 
                    231:     {
                    232:       capa_get_entry(&entry, studentNumber, setIdx);
                    233:       totalProbs = entry.e_probs;
                    234:       if( capa_get_header( &header, setIdx ) == -1 ) 
                    235: 	{
                    236: 	  Tcl_ResetResult(interp);
                    237: 	  Tcl_AppendElement(interp,"File Error");
                    238: 	  return TCL_OK;
                    239: 	}
                    240:       wgt=header.weight;
                    241:       partialCredit=header.partial_credit;
                    242: 
                    243:       for(setScores=0, setValids=0,neverLogin=1,ii=0;ii<totalProbs;ii++) 
                    244: 	{
                    245: 	  switch(entry.answers[ii]) 
                    246: 	    { 
                    247: 	    case 'Y': case 'y':  
                    248: 	      neverLogin = 0;
                    249: 	      setScores    += (wgt[ii] - '0'); 
                    250: 	      setValids    += (wgt[ii] - '0');  
                    251: 	      break; 
                    252: 	    case '-': case 'N': case 'n': 
                    253: 	      setValids    += (wgt[ii] - '0');  
                    254: 	      break; 
                    255: 	    case 'E': case 'e':
                    256: 	      break;
                    257: 	    default : 
                    258: 	      if( entry.answers[ii] >= '0' && entry.answers[ii] <= '9' ) 
                    259: 		{
                    260: 		  setScores    += (entry.answers[ii] - '0');
                    261: 		  setValids    += (wgt[ii] - '0');
                    262: 		  neverLogin = 0;
                    263: 		} 
                    264: 	      break;
                    265: 	    } 
                    266: 	}
                    267:       entry.answers[totalProbs]='\0'; /* get rid of last unknown chars */
                    268:       entry.tries[3*totalProbs]='\0';
                    269:       termScores += setScores;
                    270:       termValids += setValids;
                    271:     
                    272:       if(neverLogin) 
                    273: 	{
                    274: 	  sprintf(lineOne,"%3d   -/%3d %s\n",setIdx,setValids,entry.answers);
                    275: 	} 
                    276:       else 
                    277: 	{
                    278: 	  sprintf(lineOne,"%3d %3d/%3d %s\n",setIdx,setScores,setValids,entry.answers);
                    279: 	}
                    280:       Tcl_AppendResult(interp,lineOne,NULL);
                    281:       sprintf(lineOne,"           %s\n",entry.tries);
                    282:       Tcl_AppendResult(interp,lineOne,NULL);
                    283:       capa_mfree(entry.answers);
                    284:       capa_mfree(entry.tries);
                    285:     }
                    286:   sprintf(lineOne,"========================\n   Total = %3d/%3d",termScores,termValids);
                    287:   Tcl_AppendResult(interp,lineOne,NULL);
                    288:   capa_mfree(header.weight);
                    289:   capa_mfree(header.partial_credit);
                    290:   return TCL_OK;
                    291: }
                    292: 
                    293: int compare_string( a, b)
                    294: char *a, *b;
                    295: {
                    296:   return( strcasecmp(a, b) );
                    297: }
                    298: 
                    299: /* Builds a set summary
                    300:  * Argument: the filename to write to
                    301:  */
                    302: int capaGetSetSummary(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    303: {   
                    304:   T_student *stuPtr, *currentStudentPtr;
                    305:   T_header   a_header;
                    306:   int        section, set;
                    307:   int        studentCount,currentStudent, setScores, validScores;
                    308:   char      fmt1[64], fmt2[64],buf[BUFFER_SIZE],*str1="Student Name",*str2=" ";
                    309:   char      *answersPtr;
                    310:   FILE      *outputFile;
                    311: 
                    312:   section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
                    313:   set=atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY));
                    314:   Tcl_ResetResult(interp);
                    315: 
                    316:   studentCount = capa_sorted_section(&stuPtr, section);
                    317:   if( studentCount > 0 ) 
                    318:     {
                    319:       if( capa_get_header( &a_header, set) == -1 ) 
                    320: 	{
                    321: 	  Tcl_Eval(interp,"displayerror \"Cannot open set.db file\"");
                    322: 	  Tcl_ResetResult(interp);
                    323: 	  free_students(stuPtr);
                    324: 	  return TCL_OK;
                    325: 	}
                    326:       capa_mfree(a_header.weight);
                    327:       capa_mfree(a_header.partial_credit);
                    328:       sprintf(fmt1,"%%-%ds\t%%%ss\t Score\n", MAX_NAME_CHAR,a_header.num_questions);
                    329: 
                    330:       outputFile=fopen(argv[1],"w");
                    331:       fprintf(outputFile, "Section %-3d, Set %-3d Score Report\n",section, set);
                    332: 
                    333:       fprintf(outputFile, fmt1,str1,str2);
                    334: 
                    335:       sprintf(fmt1,"%%-%ds\t%%s\t  -/%%3d\n", MAX_NAME_CHAR);
                    336:       sprintf(fmt2,"%%-%ds\t%%s\t%%3d/%%3d\n", MAX_NAME_CHAR);
                    337: 
                    338:       for(currentStudentPtr=stuPtr,currentStudent=0;currentStudentPtr;
                    339: 	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                    340: 	{
                    341: 	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                    342: 	  Tcl_Eval(interp,buf);
                    343: 	  if( (setScores = capa_get_score(currentStudentPtr->s_sn,
                    344: 					  set,&validScores,&answersPtr) ) == -2 ) 
                    345: 	    {
                    346: 	      Tcl_Eval(interp,"displayerror \"Cannot open set.db file\"");
                    347: 	      Tcl_ResetResult(interp);
                    348: 	      free_students(stuPtr);
                    349: 	      capa_mfree(answersPtr);
                    350: 	      fclose(outputFile);
                    351: 	      return TCL_OK;
                    352: 	    }
                    353: 	  if( setScores < 0 ) 
                    354: 	    {
                    355: 	      fprintf(outputFile,fmt1,currentStudentPtr->s_nm,answersPtr,validScores );
                    356: 	    } 
                    357:           else 
                    358: 	    {
                    359: 	      fprintf(outputFile,fmt2,currentStudentPtr->s_nm,answersPtr,setScores,validScores );
                    360: 	    }
                    361: 	  capa_mfree(answersPtr);
                    362: 	}
                    363:       free_students(stuPtr);
                    364:       fclose(outputFile);
                    365:     }
                    366:   return TCL_OK;
                    367: }
                    368: 
                    369: /* builds a term summary
                    370:  * Arguments: filename
                    371:  */
                    372: int capaGetTermSummary(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    373: {
                    374:   T_student *studentPtr, *currentStudentPtr;
                    375:   int        section, totalSet;
                    376:   int        setIndex, setScores, termScores, validScores, termValids;
                    377:   int        studentCount,currentStudent=1;
                    378:   char       fmt[64];
                    379:   char      *answersPtr,buf[BUFFER_SIZE];
                    380:   FILE      *outputFile;
                    381: 
                    382:   outputFile=fopen(argv[1],"w");
                    383:   section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
                    384:   totalSet  = howManySetDBFile();
                    385:   Tcl_ResetResult(interp);
                    386: 
                    387:   studentCount = capa_sorted_section(&studentPtr, section);
                    388:   if( studentCount > 0 ) 
                    389:     {
                    390:       for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                    391: 	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                    392: 	{
                    393: 	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                    394: 	  Tcl_Eval(interp,buf);
                    395: 	  sprintf(fmt,"%%-%ds\n", MAX_NAME_CHAR);
                    396: 	  fprintf(outputFile,fmt,currentStudentPtr->s_nm);
                    397: 
                    398: 	  for( termScores = 0, termValids = 0, setIndex = 1; setIndex <= totalSet; setIndex++) 
                    399: 	    {
                    400: 	      if( (setScores = capa_get_score(currentStudentPtr->s_sn,
                    401: 					      setIndex,&validScores,&answersPtr) ) == -2 ) 
                    402: 		{
                    403: 		  sprintf(buf,"displayerror \"Cannot open set%d.db file\"",setIndex);
                    404: 		  Tcl_Eval(interp,buf);
                    405: 		  Tcl_ResetResult(interp);
                    406: 		  capa_mfree(answersPtr);
                    407: 		  free_students(studentPtr);
                    408: 		  fclose(outputFile);
                    409: 		  return TCL_OK;
                    410: 		}
                    411: 	      if( setScores < 0 ) 
                    412: 		{
                    413: 		  fprintf(outputFile,"Set %-3d\t%s\t  -/%3d\n", setIndex,answersPtr, validScores);
                    414: 		} 
                    415:               else 
                    416: 		{
                    417: 		  fprintf(outputFile, "Set %-3d\t%s\t%3d/%3d\n",
                    418: 			   setIndex,answersPtr,setScores,validScores );
                    419: 		  termScores += setScores;
                    420: 		}
                    421: 	      capa_mfree(answersPtr);
                    422: 	      termValids += validScores; 
                    423: 	    }
                    424: 	  fprintf(outputFile,"\t\t\tTerm Score = %3d/%3d\n", termScores,termValids);
                    425: 	  fprintf(outputFile, "-----------------------------------------------------------------------\n");
                    426: 	}
                    427:       free_students(studentPtr);
                    428:     }
                    429:   fclose(outputFile);
                    430:   return TCL_OK;
                    431: }
                    432: 
                    433: extern int Parsemode_f;
                    434: 
                    435: /* runs capaParse and puts the results into a text widget
                    436:  * Arguments: the name it is registered under (enscriptParse, texParse,
                    437:  *            webParse, bubblerParse); what results of the parse to show
                    438:  *            0 (Problem Only), 1 (Question and Answer), 2 (Answer Only);
                    439:  *            the set number; either (Random or Specific) student; section;
                    440:  *            student Number; student Name ; the name of the variable to
                    441:  *            find the widget name of the text widget to put the text into
                    442:  */
                    443: int capaTclParse (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    444: {
                    445:   extern  char      *EndText_p;
                    446:   T_student student;
                    447:   Problem_t *headProblem,*currentProblem;
                    448:   int numOfQuestions,numAnswers,problemNumber=0;
                    449:   int result,i=1,j,length;
                    450:   char *buf, *buf2, *temp, *previewText=NULL;
                    451:   char lower[32],upper[32],ans[32], unit[32];
                    452:   double  targetAns;
                    453:   int  c_set;
                    454: #ifdef GRADER_UPDATE
                    455:   char *update=";update";
                    456: #else
                    457:   char *update=" ";
                    458: #endif
                    459: 
                    460:   switch(argv[0][0])
                    461:     {
                    462:     case 'e':Parsemode_f = ASCII_MODE;break;
                    463:     case 't':Parsemode_f = TeX_MODE;break;
                    464:     case 'w':Parsemode_f = HTML_MODE;break;
                    465:     case 'b':Parsemode_f = BUBBLE_MODE;break;
                    466:     default:
                    467:       Tcl_ResetResult(interp);
                    468:       Tcl_AppendElement(interp,"Invalid call to capaTclParse\n");
                    469:       return TCL_ERROR;
                    470:       break;
                    471:     }
                    472: 
                    473:   if ( (previewText = Tcl_GetVar(interp,argv[7],
                    474: 				 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL)
                    475:     {
                    476:       fprintf(stderr,"Tcl_GetVar error\n");
                    477:       fprintf(stderr,"%s\n",interp->result);
                    478:       return TCL_ERROR;
                    479:     }
                    480:   c_set = atoi(argv[2]);
                    481:   switch (argv[3][0])
                    482:     {
                    483:     case 'R':
                    484:       result = capa_pick_student(atoi(argv[4]),&student);
                    485:       if (result == -1)
                    486: 	{
                    487: 	  buf=capa_malloc(BUFFER_SIZE,1);
                    488: 	  sprintf(buf,"displayError \"There are no students in section %d.\"",
                    489: 		  atoi(argv[4]));
                    490: 	  Tcl_Eval(interp,buf);
                    491: 	  capa_mfree(buf);
                    492: 	  Tcl_ResetResult(interp);
                    493: 	  Tcl_AppendElement(interp,"-1");
                    494: 	  return TCL_OK;
                    495: 	}
                    496:       
                    497:       result = capa_parse(atoi(argv[2]),&headProblem,student.s_sn,&numOfQuestions,NULL);
                    498:       break;
                    499:     case 'S':
                    500:       result = capa_get_student(argv[5],&student);
                    501:       if ((result == -1) || (result == 0))
                    502: 	{
                    503: 	  buf=capa_malloc(BUFFER_SIZE,1);
                    504: 	  sprintf(buf,"displayError \"The student %s does not exist.\"",
                    505: 		  argv[5]);
                    506: 	  Tcl_Eval(interp,buf);
                    507: 	  capa_mfree(buf);
                    508: 	  Tcl_ResetResult(interp);
                    509: 	  Tcl_AppendElement(interp,"-1");
                    510: 	  return TCL_OK;
                    511: 	}
                    512:       result = capa_parse(atoi(argv[2]),&headProblem,argv[5],&numOfQuestions,NULL);
                    513:       break;
                    514:     default:
                    515:       Tcl_ResetResult(interp);
                    516:       Tcl_AppendElement(interp,"Invalid 2nd argument to capaTclParse\n");
                    517:       return TCL_ERROR;
                    518:       break;
                    519:     }
                    520: 
                    521:   if (result==-1)
                    522:     {
                    523:       Tcl_ResetResult(interp);
                    524:       Tcl_AppendElement(interp,"-1");
                    525:       return TCL_OK;
                    526:     }
                    527: 
                    528:   currentProblem=headProblem;
                    529:     
                    530:   if(argv[1][0] == Q_ANSWER)
                    531:     {
                    532:       /*
                    533:       switch(Parsemode_f)
                    534: 	{
                    535: 	case ASCII_MODE:
                    536: 	  sprintf(buf,"Section %d                               Set %d\n Name: %s    PIN: %d\n\n",
                    537: 		  student.s_sec, atoi(argv[2]), student.s_nm,
                    538: 		  capa_PIN(student.s_sn, atoi(argv[2]),0));
                    539: 	  break;
                    540: 	case TeX_MODE:
                    541: 	  sprintf(buf,"{\\bf Section %d\\qquad Set %d}\\\\\\medskip \n{\\bf Name: \
                    542: %s\\qquad PIN: %d}\\\\ \\bigskip\n\n", student.s_sec, atoi(argv[2]), student.s_nm,
                    543: 		  capa_PIN(student.s_sn, atoi(argv[2]),0));
                    544: 	  break;
                    545: 	case HTML_MODE:
                    546: 	  sprintf(buf,"Section %d                               Set %d\n Name: %s    PIN: %d\n\n",
                    547: 		  student.s_sec, atoi(argv[2]), student.s_nm,
                    548: 		  capa_PIN(student.s_sn, atoi(argv[2]),0));
                    549: 	  break;
                    550: 	case BUBBLE_MODE:
                    551: 	  break;
                    552: 	}
                    553:       j=capaPrepareBuffer(buf,buf2,0);
                    554: 
                    555:       sprintf(buf,"%s insert end \" %s \" header",previewText,buf2);
                    556: 
                    557:       if (Tcl_Eval(interp,buf) != TCL_OK)
                    558: 	{
                    559: 	  fprintf(stderr,"Tcl_Eval error\n");
                    560: 	  fprintf(stderr,"%s\n",interp->result);
                    561: 	  return TCL_ERROR;
                    562: 	}
                    563:      */
                    564:     }
                    565: 
                    566:   while (currentProblem!=NULL)
                    567:     {
                    568:       switch (argv[1][0])
                    569: 	{
                    570: 	case Q_PROBLEM:
                    571: 	  if (currentProblem->question) { 
                    572: 	    length=strlen(currentProblem->question); 
                    573: 	  } else { 
                    574: 	    length=0;
                    575: 	  }
                    576: 	  buf=capa_malloc(BUFFER_SIZE+(2*length),1);
                    577: 	  buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
                    578: 	  if(currentProblem->question) {
                    579: 	    j=capaPrepareBuffer(currentProblem->question,buf2,0);
                    580: 	    buf2[j-1]='\n';
                    581: 	    buf2[j]='\0';
                    582: 	  } else {
                    583: 	    buf2[0]='\n';buf2[1]='\0';
                    584: 	  }
                    585: 	  if(currentProblem->question) {
                    586: 	    j=capaPrepareBuffer(currentProblem->question,buf2,0);
                    587: 	    buf2[j-1]='\n';
                    588: 	    buf2[j]='\0';
                    589: 	  } else {
                    590: 	    buf2[0]='\n';buf2[1]='\0';
                    591: 	  }
                    592: 
                    593: 	  switch(Parsemode_f)
                    594: 	    {
                    595: 	    case ASCII_MODE:
                    596: 	      sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem",
                    597: 		      previewText,buf2);
                    598: 	      break;
                    599: 	    case TeX_MODE:
                    600: 	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
                    601: 	      break;
                    602: 	    case HTML_MODE:
                    603: 	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
                    604: 	      break;
                    605: 	    case BUBBLE_MODE:
                    606: 	      break;
                    607: 	    }	      
                    608: 	  if (Tcl_Eval(interp,buf) != TCL_OK)
                    609: 	    {
                    610: 	      fprintf(stderr,"Tcl_Eval error\n");
                    611: 	      fprintf(stderr,"%s\n",interp->result);
                    612: 	      return TCL_ERROR;
                    613: 	    }
                    614: 	  capa_mfree(buf);
                    615: 	  capa_mfree(buf2);
                    616: 	  break;
                    617: 	case Q_PROBLEM_AND_ANSWER:
                    618: 	  if (currentProblem->question) { 
                    619: 	    length=strlen(currentProblem->question); 
                    620: 	  } else { 
                    621: 	    length=0;
                    622: 	  }
                    623: 	  buf=capa_malloc(BUFFER_SIZE+(2*length),1);
                    624: 	  buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
                    625: 	  temp=capa_malloc(BUFFER_SIZE+(2*length),1);
                    626: 	  j=capaPrepareBuffer(currentProblem->question,buf2,0);
                    627: 
                    628: 	  switch(Parsemode_f)
                    629: 	    {
                    630: 	    case ASCII_MODE:
                    631: 	      sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem",
                    632: 		      previewText,buf2);
                    633: 	      break;
                    634: 	    case TeX_MODE:
                    635: 	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
                    636: 	      break;
                    637: 	    case HTML_MODE:
                    638: 	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
                    639: 	      break;
                    640: 	    case BUBBLE_MODE:
                    641: 	      break;
                    642: 	    }
                    643: 	  if (Tcl_Eval(interp,buf) != TCL_OK)
                    644: 	    {
                    645: 	      fprintf(stderr,"Tcl_Eval error\n");
                    646: 	      fprintf(stderr,"%s\n",interp->result);
                    647: 	      return TCL_ERROR;
                    648: 	    }
                    649: 
                    650: 	  capa_mfree(buf);
                    651: 	  capa_mfree(buf2);
                    652: 	  capa_mfree(temp);
                    653: 	  capaInsertAnswer(currentProblem,interp,previewText);
                    654: 	  break;
                    655: 	case Q_ANSWER:
                    656: 	  print_begin_item(Parsemode_f,interp,previewText,problemNumber+1);
                    657: 	  capaInsertAnswer(currentProblem,interp,previewText);
                    658: 	  break;
                    659: 	}
                    660: 
                    661:       currentProblem=currentProblem->next;
                    662:       problemNumber++;
                    663:     }
                    664:   if( ( EndText_p != NULL) ) 
                    665:     {
                    666:       buf=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
                    667:       buf2=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
                    668:       temp=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
                    669:       sprintf(temp,"%s", EndText_p);
                    670:       j=capaPrepareBuffer(temp,buf2,0);
                    671:       
                    672:       sprintf(buf,"%s insert end \"%s\" answer%s",previewText,buf2,update);
                    673:       
                    674:       if (Tcl_Eval(interp,buf) != TCL_OK)
                    675:         {
                    676: 	  fprintf(stderr,"Tcl_Eval error 7\n");
                    677: 	  fprintf(stderr,"%s\n",interp->result);
                    678: 	  return TCL_ERROR;
                    679: 	}
                    680:       capa_mfree(buf);
                    681:       capa_mfree(buf2);
                    682:       capa_mfree(temp);
                    683:     }
                    684:   free_problems(headProblem);
                    685:   
                    686:   if (result==0) 
                    687:     {
                    688:       Tcl_ResetResult(interp);
                    689:       Tcl_AppendElement(interp,"0");
                    690:     }
                    691:   else
                    692:     {
                    693:       buf=capa_malloc(BUFFER_SIZE,1);
                    694:       sprintf(buf,"%d",result);
                    695:       Tcl_ResetResult(interp);
                    696:       Tcl_AppendElement(interp,buf);
                    697:       capa_mfree(buf);
                    698:     }
                    699:   
                    700:   return TCL_OK;
                    701: }
                    702: 
                    703: /* setup gQuestionType for all of the questions
                    704:  * Arguments: number of Questions
                    705:  */
                    706: int capaGetQuestionTypes(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    707: {
                    708:   int numQuestions,result,i;
                    709:   T_header header;
                    710:   char buf[BUFFER_SIZE], buf2[BUFFER_SIZE],*weight;
                    711: 
                    712:   if (argc != 2) 
                    713:     {
                    714:       Tcl_ResetResult(interp);
                    715:       Tcl_AppendResult(interp,"Wrong number of arguments to getQuestionTypes",
                    716: 		       NULL);
                    717:       return TCL_ERROR;
                    718:     }
                    719:   
                    720:   numQuestions=atoi(argv[1]);
                    721:   
                    722:   result = capa_get_header(&header,atoi(Tcl_GetVar(interp,"gSetLoad",
                    723: 						   TCL_GLOBAL_ONLY)));
                    724:   weight=header.weight;
                    725: 			   
                    726:   if (result == -1)
                    727:     {
                    728:       Tcl_ResetResult(interp);
                    729:       Tcl_AppendResult(interp,"capa_get_header returned error.",NULL);
                    730:       return TCL_ERROR;
                    731:     }
                    732:   
                    733:   for(i=1;i<=numQuestions;i++)
                    734:     {
                    735:       sprintf(buf,"%d",i);
                    736:       switch(header.partial_credit[i-1])
                    737: 	{
                    738: 	case '0':
                    739: 	  Tcl_SetVar2(interp,"gQuestionType",buf,"autoGrade",TCL_GLOBAL_ONLY);
                    740: 	  break;
                    741: 	case '1':
                    742: 	  Tcl_SetVar2(interp,"gQuestionType",buf,"handGrade",TCL_GLOBAL_ONLY);
                    743: 	  sprintf(buf,"max%d",i);
                    744: 	  sprintf(buf2,"%c",weight[i-1]);
                    745: 	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
                    746: 	  break;
                    747: 	default:
                    748: 	  Tcl_ResetResult(interp);
                    749: 	  Tcl_AppendResult(interp,"Header for the set.db file is incorrect.",
                    750: 			   NULL);
                    751: 	  return TCL_ERROR;
                    752: 	  break;
                    753: 	}
                    754:     }
                    755:   capa_mfree(header.weight);
                    756:   capa_mfree(header.partial_credit);
                    757:   Tcl_ResetResult(interp);
                    758:   return TCL_OK;
                    759: }
                    760: 
                    761: /* setup gAnswer for all of the questions
                    762:  * Arguments: number of Questions
                    763:  */
                    764: T_entry graderEntry;
                    765: int capaSetupGAnswer (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    766: {
                    767:   int numQuestions,i,result;
                    768:   char buf[BUFFER_SIZE],buf2[BUFFER_SIZE],*questionType;
                    769: 
                    770:   if (argc != 2) 
                    771:     {
                    772:       Tcl_ResetResult(interp);
                    773:       Tcl_AppendResult(interp,"Incorrect number of arguments to setup gAnswer",
                    774: 		       NULL);
                    775:       return TCL_ERROR;
                    776:     }
                    777: 
                    778:   numQuestions=atoi(argv[1]);
                    779: 
                    780:   result = capa_get_entry(&graderEntry,Tcl_GetVar2(interp,"gGrading","number",
                    781: 					     TCL_GLOBAL_ONLY),
                    782: 			  atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY)));
                    783: 
                    784:   if (result == 0)
                    785:     {
                    786:       Tcl_ResetResult(interp);
                    787:       Tcl_AppendResult(interp,"capa_get_entry returned error.",NULL);
                    788:       return TCL_ERROR;
                    789:     }
                    790:   for(i=1;i<=numQuestions;i++)
                    791:     {
                    792:       sprintf(buf,"%d.tries",i);
                    793:       buf2[0]=graderEntry.tries[(i-1)*3];buf2[1]=graderEntry.tries[(i-1)*3+1];
                    794:       buf2[2]='\0';
                    795:       Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
                    796:       sprintf(buf,"%d",i);
                    797:       switch(graderEntry.answers[i-1])
                    798: 	{
                    799: 	case '-':
                    800: 	  Tcl_SetVar2(interp,"gAnswer",buf,"-",TCL_GLOBAL_ONLY);
                    801: 	  break;
                    802: 	case 'y':
                    803: 	case 'n':
                    804: 	case 'E':
                    805: 	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
                    806: 	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
                    807: 	  break;
                    808: 	case 'Y':
                    809: 	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
                    810: 	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
                    811: 	  questionType=Tcl_GetVar2(interp,"gQuestionType",buf,
                    812: 				   TCL_GLOBAL_ONLY);
                    813: 	  switch(questionType[0])
                    814: 	    {
                    815: 	    case 'a':
                    816: 	      sprintf(buf,"$gGradeCanvas.dash%d configure -state disabled",i);
                    817: 	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
                    818: 		return TCL_ERROR;
                    819: 	      sprintf(buf,"$gGradeCanvas.y%d configure -state disabled",i);
                    820: 	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
                    821: 		return TCL_ERROR;
                    822: 	      sprintf(buf,"$gGradeCanvas.n%d configure -state disabled",i);
                    823: 	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
                    824: 		return TCL_ERROR;
                    825: 	      sprintf(buf,"$gGradeCanvas.e%d configure -state disabled",i);
                    826: 	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
                    827: 		return TCL_ERROR;
                    828: 	      break;
                    829: 	    case 'h':
                    830: 	      sprintf(buf,"$gGradeCanvas.hand%d configure -state disabled",i);
                    831: 	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
                    832: 		return TCL_ERROR;
                    833: 	      break;
                    834: 	    default:
                    835: 	      Tcl_ResetResult(interp);
                    836: 	      Tcl_AppendElement(interp,"questionType contains invlaid data in capaSetupGAnswer.");
                    837: 	      return TCL_ERROR;
                    838: 	      break;
                    839: 	    }
                    840: 	  break;
                    841: 	default:
                    842: 	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
                    843: 	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
                    844: 	  break;
                    845: 	}
                    846:     }
                    847: 
                    848:   Tcl_ResetResult(interp);
                    849:   return TCL_OK;
                    850: }
                    851: 
                    852: /* save gAnswer to the set.db file
                    853:  * Arguments: number of Questions
                    854:  */
                    855: int capaSaveGAnswer (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    856: {
                    857:   T_entry entry;
                    858:   int numQuestions,i,result;
                    859:   char buf[BUFFER_SIZE],*gAnswer;
                    860: 
                    861:   if (argc != 2) 
                    862:     {
                    863:       Tcl_ResetResult(interp);
                    864:       Tcl_AppendResult(interp,"Incorrect number of arguments to save gAnswer",NULL);
                    865:       return TCL_ERROR;
                    866:     }
                    867: 
                    868:   numQuestions=atoi(argv[1]);
                    869: 
                    870:   entry.answers=capa_malloc(numQuestions+1,1);
                    871:   entry.tries=capa_malloc(3*numQuestions+1,1);
                    872: 
                    873:   for(i=0;i<numQuestions;i++) {
                    874:     sprintf(buf,"%d",i+1);
                    875:     gAnswer=Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY);
                    876:     if ( gAnswer[0] != graderEntry.answers[i] ) {
                    877:       entry.answers[i]=gAnswer[0];
                    878:     } else {
                    879:       entry.answers[i]='?';
                    880:     }
                    881:     sprintf(buf,"%d.tries",i+1);
                    882:     gAnswer=Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY);
                    883:     if (atoi(gAnswer) != atoi(&(graderEntry.tries[i*3]))) {
                    884:       sprintf(&(entry.tries[i*3]),"%2d",atoi(gAnswer));
                    885:       if (i<numQuestions-1) entry.tries[i*3+2]=',';
                    886:     } else {
                    887:       entry.tries[i*3]='-';entry.tries[i*3+1]='1';
                    888:       if (i<numQuestions-1) entry.tries[i*3+2]=',';
                    889:     }
                    890:   }
                    891:   entry.answers[numQuestions]='\0';
                    892:   entry.tries[numQuestions*3]='\0';
                    893:   sprintf(entry.student_number,Tcl_GetVar2(interp,"gGrading","number",TCL_GLOBAL_ONLY));
                    894:   entry.e_probs=numQuestions;
                    895:   result = capa_change_entry(&entry,Tcl_GetVar2(interp,"gGrading","number",
                    896: 						TCL_GLOBAL_ONLY),
                    897: 			     atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY)));
                    898: 
                    899:   if (result == -1) {
                    900:     Tcl_ResetResult(interp);
                    901:     Tcl_AppendResult(interp,"capa_change_entry returned an error.",NULL);
                    902:     return TCL_ERROR;
                    903:   }
                    904: 
                    905:   Tcl_ResetResult(interp);
                    906:   return TCL_OK;
                    907: }
                    908: 
                    909: /* a wrapper for capa_excuse
                    910:  * Arguments: set; problem; section
                    911:  */
                    912: int capaExcuse (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    913: {
                    914:   int result;
                    915: 
                    916:   result = capa_excuse(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]));
                    917: 
                    918:   if (result == -1)
                    919:     {
                    920:       Tcl_ResetResult(interp);
                    921:       Tcl_AppendResult(interp,"capa_excuse returned error.",NULL);
                    922:       return TCL_ERROR;
                    923:     }
                    924: 
                    925:   return TCL_OK;
                    926: }
                    927: 
                    928: /* creates a summary report
                    929:  * Arguments: the filename
                    930:  */
                    931: int capaCreateSummary (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                    932: {    
                    933:   int          section = atoi(Tcl_GetVar2(interp,"gSummary","section",TCL_GLOBAL_ONLY)), 
                    934:     set = atoi(Tcl_GetVar2(interp,"gSummary","set",TCL_GLOBAL_ONLY)); 
                    935:   int          studentCount,currentStudent;
                    936:   int          setScores, termScores, validScores, termValids;
                    937:   int          setIndex, maxSet=0;
                    938:   int          whatSection;
                    939:   char         fmt[64];
                    940:   char         grades[4], sectionChar[4], *answersPtr, buf[BUFFER_SIZE], *who,*which,*sortOne,*sortTwo;
                    941:   T_student   *studentPtr, *currentStudentPtr;
                    942:   FILE        *outputFile;
                    943: 
                    944:   who=Tcl_GetVar2(interp,"gSummary","who",TCL_GLOBAL_ONLY);
                    945:   which=Tcl_GetVar2(interp,"gSummary","which",TCL_GLOBAL_ONLY);
                    946:   sortOne=Tcl_GetVar2(interp,"gSummary","first",TCL_GLOBAL_ONLY);
                    947:   sortTwo=Tcl_GetVar2(interp,"gSummary","second",TCL_GLOBAL_ONLY);
                    948:   maxSet=howManySetDBFile();
                    949:   if ( ( ( strcmp(which,"upto") == 0 ) 
                    950:        &&
                    951:        ( ( set <= 0 ) 
                    952: 	|| 
                    953: 	( set >= NUM_SET_LIMIT ) ) ) 
                    954:       ||
                    955:        ( set > maxSet ) )
                    956:     {
                    957:       sprintf(buf,"displayError \"The set number (%d) doesn't exist.\"",set);
                    958:       Tcl_Eval(interp,buf);
                    959:       Tcl_ResetResult(interp);
                    960:       Tcl_AppendResult(interp,"Error",NULL);
                    961:       return TCL_ERROR;
                    962:     }
                    963:   outputFile=fopen(argv[1],"w");
                    964:   if ( strcmp(who,"all") == 0 ) 
                    965:       whatSection = GET_ALL_SECTIONS;
                    966:   else 
                    967:       whatSection = section;
                    968:   studentCount = capa_get_section(&studentPtr, whatSection);
                    969: 
                    970:   if (Tcl_Eval(interp,"updateStatusMessage \"Creating primary sort key\"") != TCL_OK)
                    971:     {
                    972:       free_students(studentPtr);
                    973:       fclose(outputFile);
                    974:       return TCL_ERROR;
                    975:     }
                    976: 
                    977:   if( studentCount > 0 ) 
                    978:     {
                    979:       switch (sortOne[1]) 
                    980: 	{
                    981: 	case 'a': /*BY_NAME*/   
                    982: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                    983: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)
                    984: 	    {
                    985: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                    986: 	      Tcl_Eval(interp,buf);
                    987: 	      sprintf(currentStudentPtr->s_key,"%s",currentStudentPtr->s_nm);
                    988: 	    }
                    989: 	  break;
                    990: 	case 'u': /*BY_NUMBER*/  
                    991: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                    992: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
                    993: 	    {
                    994: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                    995: 	      Tcl_Eval(interp,buf);
                    996: 	      sprintf(currentStudentPtr->s_key,"%s",currentStudentPtr->s_sn);
                    997: 	    }
                    998: 	  break;
                    999: 	case 'e': /*BY_SECTION*/ 
                   1000: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1001: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
                   1002: 	    {
                   1003: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1004: 	      Tcl_Eval(interp,buf);
                   1005: 	      sprintf(currentStudentPtr->s_key,"%03d",currentStudentPtr->s_sec);
                   1006: 	    }
                   1007: 	  break;
                   1008: 	case 'r': /*BY_GRADE*/
                   1009: 	  if(strcmp(which,"specific") == 0 ) 
                   1010: 	    {
                   1011: 	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1012: 		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                   1013: 		{
                   1014: 		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1015: 		  Tcl_Eval(interp,buf);
                   1016: 		  if( (setScores = capa_get_score(currentStudentPtr->s_sn,set,
                   1017: 						  &validScores,&answersPtr)) == -2 ) 
                   1018: 		    break;
                   1019: 		  if( setScores < 0 ) 
                   1020: 		    sprintf(currentStudentPtr->s_key,"-");
                   1021:                   else 
                   1022: 		    sprintf(currentStudentPtr->s_key,"%03d",setScores);
                   1023: 		  capa_mfree(answersPtr);
                   1024: 		} 
                   1025: 	    } 
                   1026:           else 
                   1027: 	    {
                   1028: 	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1029: 		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                   1030: 		{
                   1031: 		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1032: 		  Tcl_Eval(interp,buf);
                   1033: 		  for( termScores = 0, termValids = 0, setIndex = 1; 
                   1034: 		       setIndex <= set; setIndex++) 
                   1035: 		    {
                   1036: 		      if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
                   1037: 						      &validScores,&answersPtr)) >= 0 ) 
                   1038: 			  termScores += setScores;
                   1039: 		      capa_mfree(answersPtr);
                   1040: 		      termValids += validScores; 
                   1041: 		    }
                   1042: 		  sprintf(currentStudentPtr->s_key,"%03d",termScores);
                   1043: 		}
                   1044: 	    }
                   1045: 	  break;
                   1046: 	}
                   1047:       if (Tcl_Eval(interp,"updateStatusMessage \"Creating secondary sort key\"") != TCL_OK)
                   1048: 	{
                   1049: 	  free_students(studentPtr);
                   1050: 	  fclose(outputFile);
                   1051: 	  return TCL_ERROR;
                   1052: 	}
                   1053:       switch (sortTwo[1]) 
                   1054: 	{
                   1055: 	case 'a':/*BY_NAME*/    
                   1056: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1057: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
                   1058: 	    {
                   1059: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1060: 	      Tcl_Eval(interp,buf);
                   1061: 	      strcat(currentStudentPtr->s_key,currentStudentPtr->s_nm);
                   1062: 	    }
                   1063: 	  break;
                   1064: 	case 'u':/*BY_NUMBER*/  
                   1065: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1066: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
                   1067: 	    {
                   1068: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1069: 	      Tcl_Eval(interp,buf);
                   1070: 	      strcat(currentStudentPtr->s_key,currentStudentPtr->s_sn);
                   1071: 	    }
                   1072: 	  break;
                   1073: 	case 'e':/*BY_SECTION*/ 
                   1074: 	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1075: 	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
                   1076: 	    {
                   1077: 	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1078: 	      Tcl_Eval(interp,buf);
                   1079: 	      sprintf(sectionChar,"%03d",currentStudentPtr->s_sec); 
                   1080: 	      strcat(currentStudentPtr->s_key,sectionChar);
                   1081: 	    }
                   1082: 	  break;
                   1083: 	case 'r':/*BY_GRADE*/
                   1084: 	  if(strcmp(which,"specific") == 0 ) 
                   1085: 	    {
                   1086: 	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1087: 		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                   1088: 		{
                   1089: 		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1090: 		  Tcl_Eval(interp,buf);
                   1091: 		  if( (setScores = capa_get_score(currentStudentPtr->s_sn,set,&validScores,
                   1092: 						  &answersPtr) ) == -2 ) 
                   1093: 		    break;
                   1094: 		  if( setScores < 0 ) 
                   1095: 		    strcat(currentStudentPtr->s_key,"-");
                   1096:                   else 
                   1097: 		   {
                   1098: 		     sprintf(grades,"%03d",setScores);
                   1099: 		     strcat(currentStudentPtr->s_key,grades);
                   1100: 		   }
                   1101: 		   capa_mfree(answersPtr);
                   1102: 		} 
                   1103: 	    } 
                   1104:          else 
                   1105: 	   {
                   1106: 	     for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1107: 		 currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                   1108: 	       {
                   1109: 		 sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1110: 		 Tcl_Eval(interp,buf);
                   1111: 		 for( termScores = 0, termValids = 0, setIndex = 1; 
                   1112: 		      setIndex <= set; setIndex++) 
                   1113: 		   {
                   1114: 		     if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
                   1115: 						     &validScores,&answersPtr) ) >= 0 ) 
                   1116: 		       termScores += setScores;
                   1117: 		     capa_mfree(answersPtr);
                   1118: 		     termValids += validScores; 
                   1119: 		   }
                   1120: 		 sprintf(grades,"%03d",termScores);
                   1121: 		 strcat(currentStudentPtr->s_key,grades);
                   1122: 	       }
                   1123: 	   }
                   1124: 	   break;
                   1125: 	}
                   1126:       if (Tcl_Eval(interp,"updateStatusMessage \"Sorting\"") != TCL_OK)
                   1127: 	{
                   1128: 	  free_students(studentPtr);
                   1129: 	  fclose(outputFile);
                   1130: 	  return TCL_ERROR;
                   1131: 	}
                   1132:       msort_main(&studentPtr);
                   1133:       Tcl_ResetResult(interp);
                   1134: 
                   1135:       sprintf(fmt,"%%-%ds\t%%-%ds %%2d\t", MAX_NAME_CHAR,MAX_STUDENT_NUMBER);
                   1136:       if (Tcl_Eval(interp,"updateStatusMessage \"Creating Report\"") != TCL_OK)
                   1137: 	{
                   1138: 	  free_students(studentPtr);
                   1139: 	  fclose(outputFile);
                   1140: 	  return TCL_ERROR;
                   1141: 	}
                   1142:       for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
                   1143: 	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
                   1144: 	{
                   1145: 	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
                   1146: 	  Tcl_Eval(interp,buf);
                   1147: 	  fprintf(outputFile,fmt,currentStudentPtr->s_nm,currentStudentPtr->s_sn,
                   1148: 		  currentStudentPtr->s_sec);
                   1149: 	  if( strcmp(which,"specific") == 0) 
                   1150: 	    {
                   1151: 	      setScores = 0; validScores = 0;
                   1152: 	      if( (setScores = 
                   1153: 		   capa_get_score(currentStudentPtr->s_sn,set,&validScores,&answersPtr) ) == -2 ) 
                   1154: 		  break;
                   1155: 	      if( setScores < 0 ) 
                   1156: 		{
                   1157: 		  fprintf(outputFile, "  -\t%3d\n", validScores);
                   1158: 		} 
                   1159:               else 
                   1160: 		{
                   1161: 		  fprintf(outputFile, "%3d\t%3d\n",setScores, validScores);
                   1162: 		}
                   1163: 		capa_mfree(answersPtr);
                   1164: 	    } 
                   1165:          else 
                   1166: 	   {
                   1167: 	     for( setScores=0, validScores=0, termScores = 0, termValids = 0, setIndex = 1; 
                   1168: 		  setIndex <= set; setIndex++) 
                   1169: 	       {
                   1170: 		 if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
                   1171: 						 &validScores,&answersPtr) ) >= 0 ) 
                   1172: 		   termScores += setScores;
                   1173: 		 capa_mfree(answersPtr);
                   1174: 		 termValids += validScores;
                   1175: 		 if( setScores >= 0 ) 
                   1176: 		   {
                   1177: 		     fprintf(outputFile, "%3d ",setScores);
                   1178: 		   } 
                   1179:                  else 
                   1180: 		   {
                   1181: 		     fprintf(outputFile, "  - ");
                   1182: 		   }
                   1183: 	       }
                   1184: 	     fprintf(outputFile, "\t %3d\t%3d\n",termScores,termValids);
                   1185: 	   }
                   1186: 	}
                   1187:       free_students(studentPtr);
                   1188:     }
                   1189:   fclose(outputFile);
                   1190:   return TCL_OK;
                   1191: }
                   1192: 
                   1193: /* set the gAnswer score to what ever the user entered
                   1194:  * Arguments: problemNumber
                   1195:  */
                   1196: int capaSetHandGrade (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                   1197: {
                   1198:   int problemNumber=atoi(argv[1]),handGrade,maxGrade;
                   1199:   char *handGradeChar,buf[BUFFER_SIZE];
                   1200: 
                   1201:   handGradeChar=Tcl_GetVar(interp,"gNewHandGrade",TCL_GLOBAL_ONLY);
                   1202:   sprintf(buf,"max%d",problemNumber);
                   1203:   maxGrade=atoi(Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY));
                   1204: 
                   1205:   if (isdigit(handGradeChar[0])) {
                   1206:     handGrade=atoi(handGradeChar);
                   1207:     if (handGrade > maxGrade) {
                   1208:       sprintf(buf,"displayError \"Invalid response, you must enter a number between 0 and %d, or an E to excuse the problem.\"",maxGrade);
                   1209:       if (Tcl_Eval(interp,buf)!=TCL_OK) {
                   1210: 	return TCL_ERROR;
                   1211:       }
                   1212:     } else {
                   1213:       sprintf(buf,"%d",handGrade);
                   1214:       Tcl_SetVar2(interp,"gAnswer",argv[1],buf,TCL_GLOBAL_ONLY);
                   1215:     }
                   1216:   } else {
                   1217:     if (handGradeChar[0]=='E') {
                   1218:       Tcl_SetVar2(interp,"gAnswer",argv[1],"E",TCL_GLOBAL_ONLY);
                   1219:     } else {
                   1220:       sprintf(buf,"displayError \"Invalid response, you must enter a number between 0 and %d, or an E to excuse the problem.\"",maxGrade);
                   1221:       if (Tcl_Eval(interp,buf)!=TCL_OK) return TCL_ERROR;
                   1222: 	    
                   1223:     }
                   1224:   }
                   1225:   Tcl_ResetResult(interp);
                   1226:   return TCL_OK;
                   1227: }
                   1228: 
                   1229: /* save gAnswer to the set.db file
                   1230:  * Arguments: setNum, questNum, stuId, score 
                   1231:  */
                   1232: int capaSetScore (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
                   1233: {
                   1234:   T_entry entry;
                   1235:   int score,i,result,question,numQuest,set;
                   1236:   char buf[BUFFER_SIZE],*gAnswer,*stuId;
                   1237:   T_header header;
                   1238: 
                   1239:   if (argc != 5) 
                   1240:     {
                   1241:       Tcl_ResetResult(interp);
                   1242:       Tcl_AppendResult(interp,"Incorrect number of arguments to save gAnswer",NULL);
                   1243:       return TCL_ERROR;
                   1244:     }
                   1245: 
                   1246:   set=atoi(argv[1]);
                   1247:   question=atoi(argv[2]);
                   1248:   stuId=argv[3];
                   1249:   score=atoi(argv[4]);
                   1250: 
                   1251:   result=capa_get_header(&header,set);
                   1252: 
                   1253:   numQuest=atoi(header.num_questions);
                   1254:   result = capa_get_entry(&entry,stuId,set);
                   1255: 
                   1256:   entry.answers=capa_malloc(numQuest+1,1);
                   1257:   entry.tries=capa_malloc(3*numQuest+1,1);
                   1258: 
                   1259:   for(i=0;i<numQuest;i++) {
                   1260:     if ( i==(question-1) ) {
                   1261:       entry.answers[i]=score+'0';
                   1262:     } else {
                   1263:       entry.answers[i]='-';
                   1264:     }
                   1265:     entry.tries[i*3]='-';entry.tries[i*3+1]='1';
                   1266:     if (i<numQuest-1) entry.tries[i*3+2]=',';
                   1267:   }
                   1268: 
                   1269:   entry.answers[numQuest]='\0';
                   1270:   entry.tries[(numQuest)*3]='\0';
                   1271:   sprintf(entry.student_number,stuId);
                   1272:   entry.e_probs=numQuest;
                   1273:   result = capa_change_entry(&entry,stuId,set);
                   1274: 
                   1275:   if (result == -1) {
                   1276:     Tcl_ResetResult(interp);
                   1277:     Tcl_AppendResult(interp,"capa_change_entry returned an error.",NULL);
                   1278:     return TCL_ERROR;
                   1279:   }
                   1280: 
                   1281:   Tcl_ResetResult(interp);
                   1282:   return TCL_OK;
                   1283: }

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