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

    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>