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

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

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