File:  [LON-CAPA] / capa / capa51 / GUITools / grader.funct.c
Revision 1.2: download - view: text, annotated - select for diffs
Tue Nov 2 19:10:44 1999 UTC (24 years, 7 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- Copied the Class Report File generation in Manager. Probably should
  eventually make the two versions into one.
- Started working on gradesubjective email responses

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

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