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

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

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