File:  [LON-CAPA] / capa / capa51 / GUITools / grader.funct.c
Revision 1.6: download - view: text, annotated - select for diffs
Mon Nov 6 22:52:51 2000 UTC (23 years, 7 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, version_0_5_1, version_0_5, version_0_4, stable_2002_spring, stable_2002_july, stable_2002_april, stable_2001_fall, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, STABLE, HEAD, GCI_3, GCI_2, GCI_1, CAPA_5-1-6, CAPA_5-1-5, CAPA_5-1-4_RC1, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- stupid bug, cleaned out all other responses when grading subjective

/* interfaces to the C portions of CAPA for grader
   Copyright (C) 1992-2000 Michigan State University

   The CAPA system is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CAPA system is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with the CAPA system; see the file COPYING.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   As a special exception, you have permission to link this program
   with the TtH/TtM library and distribute executables, as long as you
   follow the requirements of the GNU GPL in regard to all of the
   software in the executable aside from TtH/TtM.
*/

/*
 * grader.funct.c
 * Guy Albertelli II 1996
 */
#include <stdio.h>
#include <tk.h>
#include <pProj/capaCommon.h>
#include <grader.h>
#include <common.h>
#include <ctype.h>
#include <time.h>

/*
 * used to remeber the weights and partial credit from a parse for when 
 * setting a DBHeader
 */

/* Reads a header form the file and sets up the time and date variables
 */ 
int capaGetHeader(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  T_header header;
  char * setNumber,buf[BUFFER_SIZE],*sectionNumber,dateStr[BUFFER_SIZE];
  int set,section,result;


  setNumber=Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY);
  sectionNumber=Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY);

  if ( setNumber[0] == '\0' )  return TCL_OK;
  if ( sectionNumber[0] == '\0' )  return TCL_OK;

  set=atoi(setNumber);
  section=atoi(sectionNumber);

  result=capa_get_header(&header,set);

  if ( result == -1 )
    {
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,"0");
      return TCL_OK;
    }

  result=capa_get_date(CHECK_OPEN_DATE,NULL,section,set,dateStr);
  if (result<0) {
    Tcl_ResetResult(interp);
    Tcl_AppendElement(interp,"-1");
    return TCL_OK;
  }
  sscanf(dateStr,"%10c",buf);
  buf[10]='\0';
  Tcl_SetVar(interp,"gOpenDate",buf,TCL_GLOBAL_ONLY);
  sscanf((dateStr)+11,"%5c",buf);
  buf[5]='\0';
  Tcl_SetVar(interp,"gOpenTime",buf,TCL_GLOBAL_ONLY);

  result=capa_get_date(CHECK_DUE_DATE,NULL,section,set,dateStr);
  if (result<0) {
    Tcl_ResetResult(interp);
    Tcl_AppendElement(interp,"-1");
    return TCL_OK;
  }
  sscanf(dateStr,"%10c",buf);
  buf[10]='\0';
  Tcl_SetVar(interp,"gDueDate",buf,TCL_GLOBAL_ONLY);
  sscanf((dateStr)+11,"%5c",buf);
  buf[5]='\0';
  Tcl_SetVar(interp,"gDueTime",buf,TCL_GLOBAL_ONLY);

  result=capa_get_date(CHECK_ANS_DATE,NULL,section,set,dateStr);
  if (result<0) {
    Tcl_ResetResult(interp);
    Tcl_AppendElement(interp,"-1");
    return TCL_OK;
  }
  sscanf(dateStr,"%10c",buf);
  buf[10]='\0';
  Tcl_SetVar(interp,"gAnswerDate",buf,TCL_GLOBAL_ONLY);
  sscanf((dateStr)+11,"%5c",buf);
  buf[5]='\0';
  Tcl_SetVar(interp,"gAnswerTime",buf,TCL_GLOBAL_ONLY);
  
  Tcl_ResetResult(interp);
  Tcl_AppendElement(interp,"1");
  capa_mfree(header.weight);
  capa_mfree(header.partial_credit);
  return TCL_OK;
}

/* get the information for all of the students in the current section
 * and puts them into the listbox.
 * Arguments: the name of the variable the widget name of the listbox
 * is in.
 */
int capaGetStudents(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  T_student *headStudent,*currentStudent;
  int result,section,set,setScore,maxScore,num=0;
  char buf[BUFFER_SIZE],buf2[BUFFER_SIZE],*answers,*listWidget;
  
  section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
  set=atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY));
  
  if ( (listWidget = Tcl_GetVar(interp,argv[1],
				 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL)
    {
      fprintf(stderr,"Tcl_GetVar error\n");
      fprintf(stderr,"%s\n",interp->result);
      return TCL_ERROR;
    }

  result=capa_sorted_section(&headStudent,section);

  if (result == -1 || result == 0)
    {
      Tcl_Eval(interp,"displayError \"Invalid section\"");
      Tcl_ResetResult(interp);
      return TCL_OK;
    }

  currentStudent=headStudent;

  while(currentStudent!=NULL)
    {
      num++;
      setScore = capa_get_score(currentStudent->s_sn,set,&maxScore,&answers);
      if ( setScore == -1 ) setScore=0;
      sprintf(buf,"%s %s   %2d/%2d      %2d      ",currentStudent->s_nm,
	      currentStudent->s_sn,setScore,maxScore,
	      capa_PIN(currentStudent->s_sn,set,0));
      
      capaPrepareBuffer(buf,buf2,0);
      sprintf(buf,"%s insert end \"%s\" ",listWidget,buf2);
      
      if (Tcl_Eval(interp,buf) != TCL_OK)
	{
	  fprintf(stderr,"Tcl_Eval error\n");
	  fprintf(stderr,"%s\n",interp->result);
	  free_students(headStudent);
	  return TCL_ERROR;
	}
      
      if (!(num%10)) {
	if (Tcl_Eval(interp,"update") != TCL_OK)
	  {
	    fprintf(stderr,"Tcl_Eval error\n");
	    fprintf(stderr,"%s\n",interp->result);
	    free_students(headStudent);
	    return TCL_ERROR;
	  }
      }
      currentStudent=currentStudent->s_next;
      capa_mfree(answers);
    }

  free_students(headStudent);
  if (!(num%5)) {
    if (Tcl_Eval(interp,"update") != TCL_OK)
      {
	fprintf(stderr,"Tcl_Eval error\n");
	fprintf(stderr,"%s\n",interp->result);
	return TCL_ERROR;
      }
  }
  return TCL_OK;
}

/* searches for the section a student is in by either name or number
 * Arguments: one of (name or number) and then the name or number to
 * search for.
 */
int capaFindSection(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{ 
  int   errorNm;
  char  searchStr[MAX_NAME_CHAR+1],buf[MAX_NAME_CHAR+1];
  T_student student;
  
  switch(argv[1][1])
    {
      case 'a':
	strncpy(searchStr,argv[2],MAX_NAME_CHAR+1);
	if ( (errorNm = capa_student_byname(searchStr,&student ))==0 ) 
	  {
	    sprintf(buf,"%d",0);
	  }
	else
	  {
	    sprintf(buf,"%d",student.s_sec);
	  }
	break;
    case 'u':
	strncpy(searchStr,argv[2],MAX_NAME_CHAR+1);
	if ( (errorNm = capa_get_student(searchStr,&student ))==0 ) 
	  {
	    sprintf(buf,"%d",0);
	  }
	else
	  {
	    sprintf(buf,"%d",student.s_sec);
	  }      
      break;
    default:
      break;
    }
  Tcl_ResetResult(interp);
  Tcl_AppendElement(interp,buf);
  return TCL_OK;
}

/* makes a student report
 * Arguments: the student number
 */
int capaGetReportInfo(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  char          studentNumber[MAX_STUDENT_NUMBER+1], 
                lineOne[BUFFER_SIZE],*wgt,*partialCredit;
  T_header      header;
  T_entry       entry;
  int		ii, setIdx, setScores, setValids, 
                totalSet, totalProbs, neverLogin;
  int           termScores, termValids;

  strncpy(studentNumber,argv[1], MAX_STUDENT_NUMBER+1);
  totalSet  = howManySetDBFile();

  Tcl_ResetResult(interp);

  for(termScores=0,termValids=0,setIdx=1;setIdx <= totalSet ;setIdx++) 
    {
      capa_get_entry(&entry, studentNumber, setIdx);
      totalProbs = entry.e_probs;
      if( capa_get_header( &header, setIdx ) == -1 ) 
	{
	  Tcl_ResetResult(interp);
	  Tcl_AppendElement(interp,"File Error");
	  return TCL_OK;
	}
      wgt=header.weight;
      partialCredit=header.partial_credit;

      for(setScores=0, setValids=0,neverLogin=1,ii=0;ii<totalProbs;ii++) 
	{
	  switch(entry.answers[ii]) 
	    { 
	    case 'Y': case 'y':  
	      neverLogin = 0;
	      setScores    += (wgt[ii] - '0'); 
	      setValids    += (wgt[ii] - '0');  
	      break; 
	    case '-': case 'N': case 'n': 
	      setValids    += (wgt[ii] - '0');  
	      break; 
	    case 'E': case 'e':
	      break;
	    default : 
	      if( entry.answers[ii] >= '0' && entry.answers[ii] <= '9' ) 
		{
		  setScores    += (entry.answers[ii] - '0');
		  setValids    += (wgt[ii] - '0');
		  neverLogin = 0;
		} 
	      break;
	    } 
	}
      entry.answers[totalProbs]='\0'; /* get rid of last unknown chars */
      entry.tries[3*totalProbs]='\0';
      termScores += setScores;
      termValids += setValids;
    
      if(neverLogin) 
	{
	  sprintf(lineOne,"%3d   -/%3d %s\n",setIdx,setValids,entry.answers);
	} 
      else 
	{
	  sprintf(lineOne,"%3d %3d/%3d %s\n",setIdx,setScores,setValids,entry.answers);
	}
      Tcl_AppendResult(interp,lineOne,NULL);
      sprintf(lineOne,"           %s\n",entry.tries);
      Tcl_AppendResult(interp,lineOne,NULL);
      capa_mfree(entry.answers);
      capa_mfree(entry.tries);
    }
  sprintf(lineOne,"========================\n   Total = %3d/%3d",termScores,termValids);
  Tcl_AppendResult(interp,lineOne,NULL);
  capa_mfree(header.weight);
  capa_mfree(header.partial_credit);
  return TCL_OK;
}

int compare_string( a, b)
char *a, *b;
{
  return( strcasecmp(a, b) );
}

/* Builds a set summary
 * Argument: the filename to write to
 */
int capaGetSetSummary(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{   
  T_student *stuPtr, *currentStudentPtr;
  T_header   a_header;
  int        section, set;
  int        studentCount,currentStudent, setScores, validScores;
  char      fmt1[64], fmt2[64],buf[BUFFER_SIZE],*str1="Student Name",*str2=" ";
  char      *answersPtr;
  FILE      *outputFile;

  section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
  set=atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY));
  Tcl_ResetResult(interp);

  studentCount = capa_sorted_section(&stuPtr, section);
  if( studentCount > 0 ) 
    {
      if( capa_get_header( &a_header, set) == -1 ) 
	{
	  Tcl_Eval(interp,"displayerror \"Cannot open set.db file\"");
	  Tcl_ResetResult(interp);
	  free_students(stuPtr);
	  return TCL_OK;
	}
      capa_mfree(a_header.weight);
      capa_mfree(a_header.partial_credit);
      sprintf(fmt1,"%%-%ds\t%%%ss\t Score\n", MAX_NAME_CHAR,a_header.num_questions);

      outputFile=fopen(argv[1],"w");
      fprintf(outputFile, "Section %-3d, Set %-3d Score Report\n",section, set);

      fprintf(outputFile, fmt1,str1,str2);

      sprintf(fmt1,"%%-%ds\t%%s\t  -/%%3d\n", MAX_NAME_CHAR);
      sprintf(fmt2,"%%-%ds\t%%s\t%%3d/%%3d\n", MAX_NAME_CHAR);

      for(currentStudentPtr=stuPtr,currentStudent=0;currentStudentPtr;
	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
	{
	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	  Tcl_Eval(interp,buf);
	  if( (setScores = capa_get_score(currentStudentPtr->s_sn,
					  set,&validScores,&answersPtr) ) == -2 ) 
	    {
	      Tcl_Eval(interp,"displayerror \"Cannot open set.db file\"");
	      Tcl_ResetResult(interp);
	      free_students(stuPtr);
	      capa_mfree(answersPtr);
	      fclose(outputFile);
	      return TCL_OK;
	    }
	  if( setScores < 0 ) 
	    {
	      fprintf(outputFile,fmt1,currentStudentPtr->s_nm,answersPtr,validScores );
	    } 
          else 
	    {
	      fprintf(outputFile,fmt2,currentStudentPtr->s_nm,answersPtr,setScores,validScores );
	    }
	  capa_mfree(answersPtr);
	}
      free_students(stuPtr);
      fclose(outputFile);
    }
  return TCL_OK;
}

/* builds a term summary
 * Arguments: filename
 */
int capaGetTermSummary(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  T_student *studentPtr, *currentStudentPtr;
  int        section, totalSet;
  int        setIndex, setScores, termScores, validScores, termValids;
  int        studentCount,currentStudent=1;
  char       fmt[64];
  char      *answersPtr,buf[BUFFER_SIZE];
  FILE      *outputFile;

  outputFile=fopen(argv[1],"w");
  section=atoi(Tcl_GetVar(interp,"gSectionLoad",TCL_GLOBAL_ONLY));
  totalSet  = howManySetDBFile();
  Tcl_ResetResult(interp);

  studentCount = capa_sorted_section(&studentPtr, section);
  if( studentCount > 0 ) 
    {
      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
	{
	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	  Tcl_Eval(interp,buf);
	  sprintf(fmt,"%%-%ds\n", MAX_NAME_CHAR);
	  fprintf(outputFile,fmt,currentStudentPtr->s_nm);

	  for( termScores = 0, termValids = 0, setIndex = 1; setIndex <= totalSet; setIndex++) 
	    {
	      if( (setScores = capa_get_score(currentStudentPtr->s_sn,
					      setIndex,&validScores,&answersPtr) ) == -2 ) 
		{
		  sprintf(buf,"displayerror \"Cannot open set%d.db file\"",setIndex);
		  Tcl_Eval(interp,buf);
		  Tcl_ResetResult(interp);
		  capa_mfree(answersPtr);
		  free_students(studentPtr);
		  fclose(outputFile);
		  return TCL_OK;
		}
	      if( setScores < 0 ) 
		{
		  fprintf(outputFile,"Set %-3d\t%s\t  -/%3d\n", setIndex,answersPtr, validScores);
		} 
              else 
		{
		  fprintf(outputFile, "Set %-3d\t%s\t%3d/%3d\n",
			   setIndex,answersPtr,setScores,validScores );
		  termScores += setScores;
		}
	      capa_mfree(answersPtr);
	      termValids += validScores; 
	    }
	  fprintf(outputFile,"\t\t\tTerm Score = %3d/%3d\n", termScores,termValids);
	  fprintf(outputFile, "-----------------------------------------------------------------------\n");
	}
      free_students(studentPtr);
    }
  fclose(outputFile);
  return TCL_OK;
}

extern int Parsemode_f;

/* runs capaParse and puts the results into a text widget
 * Arguments: the name it is registered under (enscriptParse, texParse,
 *            webParse, bubblerParse); what results of the parse to show
 *            0 (Problem Only), 1 (Question and Answer), 2 (Answer Only);
 *            the set number; either (Random or Specific) student; section;
 *            student Number; student Name ; the name of the variable to
 *            find the widget name of the text widget to put the text into
 */
int capaTclParse (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  extern  char      *EndText_p;
  T_student student;
  Problem_t *headProblem,*currentProblem;
  int numOfQuestions,numAnswers,problemNumber=0;
  int result,i=1,j,length;
  char *buf, *buf2, *temp, *previewText=NULL;
  char lower[32],upper[32],ans[32], unit[32];
  double  targetAns;
  int  c_set;
#ifdef GRADER_UPDATE
  char *update=";update";
#else
  char *update=" ";
#endif

  switch(argv[0][0])
    {
    case 'e':Parsemode_f = ASCII_MODE;break;
    case 't':Parsemode_f = TeX_MODE;break;
    case 'w':Parsemode_f = HTML_MODE;break;
    case 'b':Parsemode_f = BUBBLE_MODE;break;
    default:
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,"Invalid call to capaTclParse\n");
      return TCL_ERROR;
      break;
    }

  if ( (previewText = Tcl_GetVar(interp,argv[7],
				 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL)
    {
      fprintf(stderr,"Tcl_GetVar error\n");
      fprintf(stderr,"%s\n",interp->result);
      return TCL_ERROR;
    }
  c_set = atoi(argv[2]);
  switch (argv[3][0])
    {
    case 'R':
      result = capa_pick_student(atoi(argv[4]),&student);
      if (result == -1)
	{
	  buf=capa_malloc(BUFFER_SIZE,1);
	  sprintf(buf,"displayError \"There are no students in section %d.\"",
		  atoi(argv[4]));
	  Tcl_Eval(interp,buf);
	  capa_mfree(buf);
	  Tcl_ResetResult(interp);
	  Tcl_AppendElement(interp,"-1");
	  return TCL_OK;
	}
      
      result = capa_parse(atoi(argv[2]),&headProblem,student.s_sn,&numOfQuestions,NULL);
      break;
    case 'S':
      result = capa_get_student(argv[5],&student);
      if ((result == -1) || (result == 0))
	{
	  buf=capa_malloc(BUFFER_SIZE,1);
	  sprintf(buf,"displayError \"The student %s does not exist.\"",
		  argv[5]);
	  Tcl_Eval(interp,buf);
	  capa_mfree(buf);
	  Tcl_ResetResult(interp);
	  Tcl_AppendElement(interp,"-1");
	  return TCL_OK;
	}
      result = capa_parse(atoi(argv[2]),&headProblem,argv[5],&numOfQuestions,NULL);
      break;
    default:
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,"Invalid 2nd argument to capaTclParse\n");
      return TCL_ERROR;
      break;
    }

  if (result==-1)
    {
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,"-1");
      return TCL_OK;
    }

  currentProblem=headProblem;
    
  if(argv[1][0] == Q_ANSWER)
    {
      /*
      switch(Parsemode_f)
	{
	case ASCII_MODE:
	  sprintf(buf,"Section %d                               Set %d\n Name: %s    PIN: %d\n\n",
		  student.s_sec, atoi(argv[2]), student.s_nm,
		  capa_PIN(student.s_sn, atoi(argv[2]),0));
	  break;
	case TeX_MODE:
	  sprintf(buf,"{\\bf Section %d\\qquad Set %d}\\\\\\medskip \n{\\bf Name: \
%s\\qquad PIN: %d}\\\\ \\bigskip\n\n", student.s_sec, atoi(argv[2]), student.s_nm,
		  capa_PIN(student.s_sn, atoi(argv[2]),0));
	  break;
	case HTML_MODE:
	  sprintf(buf,"Section %d                               Set %d\n Name: %s    PIN: %d\n\n",
		  student.s_sec, atoi(argv[2]), student.s_nm,
		  capa_PIN(student.s_sn, atoi(argv[2]),0));
	  break;
	case BUBBLE_MODE:
	  break;
	}
      j=capaPrepareBuffer(buf,buf2,0);

      sprintf(buf,"%s insert end \" %s \" header",previewText,buf2);

      if (Tcl_Eval(interp,buf) != TCL_OK)
	{
	  fprintf(stderr,"Tcl_Eval error\n");
	  fprintf(stderr,"%s\n",interp->result);
	  return TCL_ERROR;
	}
     */
    }

  while (currentProblem!=NULL)
    {
      switch (argv[1][0])
	{
	case Q_PROBLEM:
	  if (currentProblem->question) { 
	    length=strlen(currentProblem->question); 
	  } else { 
	    length=0;
	  }
	  buf=capa_malloc(BUFFER_SIZE+(2*length),1);
	  buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
	  if(currentProblem->question) {
	    j=capaPrepareBuffer(currentProblem->question,buf2,0);
	    buf2[j-1]='\n';
	    buf2[j]='\0';
	  } else {
	    buf2[0]='\n';buf2[1]='\0';
	  }
	  if(currentProblem->question) {
	    j=capaPrepareBuffer(currentProblem->question,buf2,0);
	    buf2[j-1]='\n';
	    buf2[j]='\0';
	  } else {
	    buf2[0]='\n';buf2[1]='\0';
	  }

	  switch(Parsemode_f)
	    {
	    case ASCII_MODE:
	      sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem",
		      previewText,buf2);
	      break;
	    case TeX_MODE:
	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
	      break;
	    case HTML_MODE:
	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
	      break;
	    case BUBBLE_MODE:
	      break;
	    }	      
	  if (Tcl_Eval(interp,buf) != TCL_OK)
	    {
	      fprintf(stderr,"Tcl_Eval error\n");
	      fprintf(stderr,"%s\n",interp->result);
	      return TCL_ERROR;
	    }
	  capa_mfree(buf);
	  capa_mfree(buf2);
	  break;
	case Q_PROBLEM_AND_ANSWER:
	  if (currentProblem->question) { 
	    length=strlen(currentProblem->question); 
	  } else { 
	    length=0;
	  }
	  buf=capa_malloc(BUFFER_SIZE+(2*length),1);
	  buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
	  temp=capa_malloc(BUFFER_SIZE+(2*length),1);
	  j=capaPrepareBuffer(currentProblem->question,buf2,0);

	  switch(Parsemode_f)
	    {
	    case ASCII_MODE:
	      sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem",
		      previewText,buf2);
	      break;
	    case TeX_MODE:
	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
	      break;
	    case HTML_MODE:
	      sprintf(buf,"%s insert end \"%s\" problem",previewText,buf2);
	      break;
	    case BUBBLE_MODE:
	      break;
	    }
	  if (Tcl_Eval(interp,buf) != TCL_OK)
	    {
	      fprintf(stderr,"Tcl_Eval error\n");
	      fprintf(stderr,"%s\n",interp->result);
	      return TCL_ERROR;
	    }

	  capa_mfree(buf);
	  capa_mfree(buf2);
	  capa_mfree(temp);
	  capaInsertAnswer(currentProblem,interp,previewText);
	  break;
	case Q_ANSWER:
	  print_begin_item(Parsemode_f,interp,previewText,problemNumber+1);
	  capaInsertAnswer(currentProblem,interp,previewText);
	  break;
	}

      currentProblem=currentProblem->next;
      problemNumber++;
    }
  if( ( EndText_p != NULL) ) 
    {
      buf=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
      buf2=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
      temp=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
      sprintf(temp,"%s", EndText_p);
      j=capaPrepareBuffer(temp,buf2,0);
      
      sprintf(buf,"%s insert end \"%s\" answer%s",previewText,buf2,update);
      
      if (Tcl_Eval(interp,buf) != TCL_OK)
        {
	  fprintf(stderr,"Tcl_Eval error 7\n");
	  fprintf(stderr,"%s\n",interp->result);
	  return TCL_ERROR;
	}
      capa_mfree(buf);
      capa_mfree(buf2);
      capa_mfree(temp);
    }
  free_problems(headProblem);
  
  if (result==0) 
    {
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,"0");
    }
  else
    {
      buf=capa_malloc(BUFFER_SIZE,1);
      sprintf(buf,"%d",result);
      Tcl_ResetResult(interp);
      Tcl_AppendElement(interp,buf);
      capa_mfree(buf);
    }
  
  return TCL_OK;
}

/* setup gQuestionType for all of the questions
 * Arguments: number of Questions
 */
int capaGetQuestionTypes(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  int numQuestions,result,i;
  T_header header;
  char buf[BUFFER_SIZE], buf2[BUFFER_SIZE],*weight;

  if (argc != 2) 
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"Wrong number of arguments to getQuestionTypes",
		       NULL);
      return TCL_ERROR;
    }
  
  numQuestions=atoi(argv[1]);
  
  result = capa_get_header(&header,atoi(Tcl_GetVar(interp,"gSetLoad",
						   TCL_GLOBAL_ONLY)));
  weight=header.weight;
			   
  if (result == -1)
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"capa_get_header returned error.",NULL);
      return TCL_ERROR;
    }
  
  for(i=1;i<=numQuestions;i++)
    {
      sprintf(buf,"%d",i);
      switch(header.partial_credit[i-1])
	{
	case '0':
	  Tcl_SetVar2(interp,"gQuestionType",buf,"autoGrade",TCL_GLOBAL_ONLY);
	  break;
	case '1':
	  Tcl_SetVar2(interp,"gQuestionType",buf,"handGrade",TCL_GLOBAL_ONLY);
	  sprintf(buf,"max%d",i);
	  sprintf(buf2,"%c",weight[i-1]);
	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
	  break;
	default:
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp,"Header for the set.db file is incorrect.",
			   NULL);
	  return TCL_ERROR;
	  break;
	}
    }
  capa_mfree(header.weight);
  capa_mfree(header.partial_credit);
  Tcl_ResetResult(interp);
  return TCL_OK;
}

/* setup gAnswer for all of the questions
 * Arguments: number of Questions
 */
T_entry graderEntry;
int capaSetupGAnswer (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  int numQuestions,i,result;
  char buf[BUFFER_SIZE],buf2[BUFFER_SIZE],*questionType;

  if (argc != 2) 
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"Incorrect number of arguments to setup gAnswer",
		       NULL);
      return TCL_ERROR;
    }

  numQuestions=atoi(argv[1]);

  result = capa_get_entry(&graderEntry,Tcl_GetVar2(interp,"gGrading","number",
					     TCL_GLOBAL_ONLY),
			  atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY)));

  if (result == 0)
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"capa_get_entry returned error.",NULL);
      return TCL_ERROR;
    }
  for(i=1;i<=numQuestions;i++)
    {
      sprintf(buf,"%d.tries",i);
      buf2[0]=graderEntry.tries[(i-1)*3];buf2[1]=graderEntry.tries[(i-1)*3+1];
      buf2[2]='\0';
      Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
      sprintf(buf,"%d",i);
      switch(graderEntry.answers[i-1])
	{
	case '-':
	  Tcl_SetVar2(interp,"gAnswer",buf,"-",TCL_GLOBAL_ONLY);
	  break;
	case 'y':
	case 'n':
	case 'E':
	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
	  break;
	case 'Y':
	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
	  questionType=Tcl_GetVar2(interp,"gQuestionType",buf,
				   TCL_GLOBAL_ONLY);
	  switch(questionType[0])
	    {
	    case 'a':
	      sprintf(buf,"$gGradeCanvas.dash%d configure -state disabled",i);
	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
		return TCL_ERROR;
	      sprintf(buf,"$gGradeCanvas.y%d configure -state disabled",i);
	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
		return TCL_ERROR;
	      sprintf(buf,"$gGradeCanvas.n%d configure -state disabled",i);
	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
		return TCL_ERROR;
	      sprintf(buf,"$gGradeCanvas.e%d configure -state disabled",i);
	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
		return TCL_ERROR;
	      break;
	    case 'h':
	      sprintf(buf,"$gGradeCanvas.hand%d configure -state disabled",i);
	      if (Tcl_Eval(interp,buf)!=TCL_OK) 
		return TCL_ERROR;
	      break;
	    default:
	      Tcl_ResetResult(interp);
	      Tcl_AppendElement(interp,"questionType contains invlaid data in capaSetupGAnswer.");
	      return TCL_ERROR;
	      break;
	    }
	  break;
	default:
	  sprintf(buf2,"%c",graderEntry.answers[i-1]);
	  Tcl_SetVar2(interp,"gAnswer",buf,buf2,TCL_GLOBAL_ONLY);
	  break;
	}
    }

  Tcl_ResetResult(interp);
  return TCL_OK;
}

/* save gAnswer to the set.db file
 * Arguments: number of Questions
 */
int capaSaveGAnswer (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  T_entry entry;
  int numQuestions,i,result;
  char buf[BUFFER_SIZE],*gAnswer;

  if (argc != 2) 
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"Incorrect number of arguments to save gAnswer",NULL);
      return TCL_ERROR;
    }

  numQuestions=atoi(argv[1]);

  entry.answers=capa_malloc(numQuestions+1,1);
  entry.tries=capa_malloc(3*numQuestions+1,1);

  for(i=0;i<numQuestions;i++) {
    sprintf(buf,"%d",i+1);
    gAnswer=Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY);
    if ( gAnswer[0] != graderEntry.answers[i] ) {
      entry.answers[i]=gAnswer[0];
    } else {
      entry.answers[i]='?';
    }
    sprintf(buf,"%d.tries",i+1);
    gAnswer=Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY);
    if (atoi(gAnswer) != atoi(&(graderEntry.tries[i*3]))) {
      sprintf(&(entry.tries[i*3]),"%2d",atoi(gAnswer));
      if (i<numQuestions-1) entry.tries[i*3+2]=',';
    } else {
      entry.tries[i*3]='-';entry.tries[i*3+1]='1';
      if (i<numQuestions-1) entry.tries[i*3+2]=',';
    }
  }
  entry.answers[numQuestions]='\0';
  entry.tries[numQuestions*3]='\0';
  sprintf(entry.student_number,Tcl_GetVar2(interp,"gGrading","number",TCL_GLOBAL_ONLY));
  entry.e_probs=numQuestions;
  result = capa_change_entry(&entry,Tcl_GetVar2(interp,"gGrading","number",
						TCL_GLOBAL_ONLY),
			     atoi(Tcl_GetVar(interp,"gSetLoad",TCL_GLOBAL_ONLY)));

  if (result == -1) {
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp,"capa_change_entry returned an error.",NULL);
    return TCL_ERROR;
  }

  Tcl_ResetResult(interp);
  return TCL_OK;
}

/* a wrapper for capa_excuse
 * Arguments: set; problem; section
 */
int capaExcuse (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  int result;

  result = capa_excuse(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]));

  if (result == -1)
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"capa_excuse returned error.",NULL);
      return TCL_ERROR;
    }

  return TCL_OK;
}

/* creates a summary report
 * Arguments: the filename
 */
int capaCreateSummary (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{    
  int          section = atoi(Tcl_GetVar2(interp,"gSummary","section",TCL_GLOBAL_ONLY)), 
    set = atoi(Tcl_GetVar2(interp,"gSummary","set",TCL_GLOBAL_ONLY)); 
  int          studentCount,currentStudent;
  int          setScores, termScores, validScores, termValids;
  int          setIndex, maxSet=0;
  int          whatSection;
  char         fmt[64];
  char         grades[4], sectionChar[4], *answersPtr, buf[BUFFER_SIZE], *who,*which,*sortOne,*sortTwo;
  T_student   *studentPtr, *currentStudentPtr;
  FILE        *outputFile;

  who=Tcl_GetVar2(interp,"gSummary","who",TCL_GLOBAL_ONLY);
  which=Tcl_GetVar2(interp,"gSummary","which",TCL_GLOBAL_ONLY);
  sortOne=Tcl_GetVar2(interp,"gSummary","first",TCL_GLOBAL_ONLY);
  sortTwo=Tcl_GetVar2(interp,"gSummary","second",TCL_GLOBAL_ONLY);
  maxSet=howManySetDBFile();
  if ( ( ( strcmp(which,"upto") == 0 ) 
       &&
       ( ( set <= 0 ) 
	|| 
	( set >= NUM_SET_LIMIT ) ) ) 
      ||
       ( set > maxSet ) )
    {
      sprintf(buf,"displayError \"The set number (%d) doesn't exist.\"",set);
      Tcl_Eval(interp,buf);
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"Error",NULL);
      return TCL_ERROR;
    }
  outputFile=fopen(argv[1],"w");
  if ( strcmp(who,"all") == 0 ) 
      whatSection = GET_ALL_SECTIONS;
  else 
      whatSection = section;
  studentCount = capa_get_section(&studentPtr, whatSection);

  if (Tcl_Eval(interp,"updateStatusMessage \"Creating primary sort key\"") != TCL_OK)
    {
      free_students(studentPtr);
      fclose(outputFile);
      return TCL_ERROR;
    }

  if( studentCount > 0 ) 
    {
      switch (sortOne[1]) 
	{
	case 'a': /*BY_NAME*/   
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      sprintf(currentStudentPtr->s_key,"%s",currentStudentPtr->s_nm);
	    }
	  break;
	case 'u': /*BY_NUMBER*/  
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      sprintf(currentStudentPtr->s_key,"%s",currentStudentPtr->s_sn);
	    }
	  break;
	case 'e': /*BY_SECTION*/ 
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      sprintf(currentStudentPtr->s_key,"%03d",currentStudentPtr->s_sec);
	    }
	  break;
	case 'r': /*BY_GRADE*/
	  if(strcmp(which,"specific") == 0 ) 
	    {
	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
		{
		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
		  Tcl_Eval(interp,buf);
		  if( (setScores = capa_get_score(currentStudentPtr->s_sn,set,
						  &validScores,&answersPtr)) == -2 ) 
		    break;
		  if( setScores < 0 ) 
		    sprintf(currentStudentPtr->s_key,"-");
                  else 
		    sprintf(currentStudentPtr->s_key,"%03d",setScores);
		  capa_mfree(answersPtr);
		} 
	    } 
          else 
	    {
	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
		{
		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
		  Tcl_Eval(interp,buf);
		  for( termScores = 0, termValids = 0, setIndex = 1; 
		       setIndex <= set; setIndex++) 
		    {
		      if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
						      &validScores,&answersPtr)) >= 0 ) 
			  termScores += setScores;
		      capa_mfree(answersPtr);
		      termValids += validScores; 
		    }
		  sprintf(currentStudentPtr->s_key,"%03d",termScores);
		}
	    }
	  break;
	}
      if (Tcl_Eval(interp,"updateStatusMessage \"Creating secondary sort key\"") != TCL_OK)
	{
	  free_students(studentPtr);
	  fclose(outputFile);
	  return TCL_ERROR;
	}
      switch (sortTwo[1]) 
	{
	case 'a':/*BY_NAME*/    
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      strcat(currentStudentPtr->s_key,currentStudentPtr->s_nm);
	    }
	  break;
	case 'u':/*BY_NUMBER*/  
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      strcat(currentStudentPtr->s_key,currentStudentPtr->s_sn);
	    }
	  break;
	case 'e':/*BY_SECTION*/ 
	  for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	      currentStudentPtr=currentStudentPtr->s_next,currentStudent++)  
	    {
	      sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	      Tcl_Eval(interp,buf);
	      sprintf(sectionChar,"%03d",currentStudentPtr->s_sec); 
	      strcat(currentStudentPtr->s_key,sectionChar);
	    }
	  break;
	case 'r':/*BY_GRADE*/
	  if(strcmp(which,"specific") == 0 ) 
	    {
	      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
		  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
		{
		  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
		  Tcl_Eval(interp,buf);
		  if( (setScores = capa_get_score(currentStudentPtr->s_sn,set,&validScores,
						  &answersPtr) ) == -2 ) 
		    break;
		  if( setScores < 0 ) 
		    strcat(currentStudentPtr->s_key,"-");
                  else 
		   {
		     sprintf(grades,"%03d",setScores);
		     strcat(currentStudentPtr->s_key,grades);
		   }
		   capa_mfree(answersPtr);
		} 
	    } 
         else 
	   {
	     for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
		 currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
	       {
		 sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
		 Tcl_Eval(interp,buf);
		 for( termScores = 0, termValids = 0, setIndex = 1; 
		      setIndex <= set; setIndex++) 
		   {
		     if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
						     &validScores,&answersPtr) ) >= 0 ) 
		       termScores += setScores;
		     capa_mfree(answersPtr);
		     termValids += validScores; 
		   }
		 sprintf(grades,"%03d",termScores);
		 strcat(currentStudentPtr->s_key,grades);
	       }
	   }
	   break;
	}
      if (Tcl_Eval(interp,"updateStatusMessage \"Sorting\"") != TCL_OK)
	{
	  free_students(studentPtr);
	  fclose(outputFile);
	  return TCL_ERROR;
	}
      msort_main(&studentPtr);
      Tcl_ResetResult(interp);

      sprintf(fmt,"%%-%ds\t%%-%ds %%2d\t", MAX_NAME_CHAR,MAX_STUDENT_NUMBER);
      if (Tcl_Eval(interp,"updateStatusMessage \"Creating Report\"") != TCL_OK)
	{
	  free_students(studentPtr);
	  fclose(outputFile);
	  return TCL_ERROR;
	}
      for(currentStudentPtr=studentPtr,currentStudent=1;currentStudentPtr;
	  currentStudentPtr=currentStudentPtr->s_next,currentStudent++) 
	{
	  sprintf(buf,"updateStatusBar %f",(float)currentStudent/(float)studentCount);
	  Tcl_Eval(interp,buf);
	  fprintf(outputFile,fmt,currentStudentPtr->s_nm,currentStudentPtr->s_sn,
		  currentStudentPtr->s_sec);
	  if( strcmp(which,"specific") == 0) 
	    {
	      setScores = 0; validScores = 0;
	      if( (setScores = 
		   capa_get_score(currentStudentPtr->s_sn,set,&validScores,&answersPtr) ) == -2 ) 
		  break;
	      if( setScores < 0 ) 
		{
		  fprintf(outputFile, "  -\t%3d\n", validScores);
		} 
              else 
		{
		  fprintf(outputFile, "%3d\t%3d\n",setScores, validScores);
		}
		capa_mfree(answersPtr);
	    } 
         else 
	   {
	     for( setScores=0, validScores=0, termScores = 0, termValids = 0, setIndex = 1; 
		  setIndex <= set; setIndex++) 
	       {
		 if( (setScores = capa_get_score(currentStudentPtr->s_sn,setIndex,
						 &validScores,&answersPtr) ) >= 0 ) 
		   termScores += setScores;
		 capa_mfree(answersPtr);
		 termValids += validScores;
		 if( setScores >= 0 ) 
		   {
		     fprintf(outputFile, "%3d ",setScores);
		   } 
                 else 
		   {
		     fprintf(outputFile, "  - ");
		   }
	       }
	     fprintf(outputFile, "\t %3d\t%3d\n",termScores,termValids);
	   }
	}
      free_students(studentPtr);
    }
  fclose(outputFile);
  return TCL_OK;
}

/* set the gAnswer score to what ever the user entered
 * Arguments: problemNumber
 */
int capaSetHandGrade (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  int problemNumber=atoi(argv[1]),handGrade,maxGrade;
  char *handGradeChar,buf[BUFFER_SIZE];

  handGradeChar=Tcl_GetVar(interp,"gNewHandGrade",TCL_GLOBAL_ONLY);
  sprintf(buf,"max%d",problemNumber);
  maxGrade=atoi(Tcl_GetVar2(interp,"gAnswer",buf,TCL_GLOBAL_ONLY));

  if (isdigit(handGradeChar[0])) {
    handGrade=atoi(handGradeChar);
    if (handGrade > maxGrade) {
      sprintf(buf,"displayError \"Invalid response, you must enter a number between 0 and %d, or an E to excuse the problem.\"",maxGrade);
      if (Tcl_Eval(interp,buf)!=TCL_OK) {
	return TCL_ERROR;
      }
    } else {
      sprintf(buf,"%d",handGrade);
      Tcl_SetVar2(interp,"gAnswer",argv[1],buf,TCL_GLOBAL_ONLY);
    }
  } else {
    if (handGradeChar[0]=='E') {
      Tcl_SetVar2(interp,"gAnswer",argv[1],"E",TCL_GLOBAL_ONLY);
    } else {
      sprintf(buf,"displayError \"Invalid response, you must enter a number between 0 and %d, or an E to excuse the problem.\"",maxGrade);
      if (Tcl_Eval(interp,buf)!=TCL_OK) return TCL_ERROR;
	    
    }
  }
  Tcl_ResetResult(interp);
  return TCL_OK;
}

/* save gAnswer to the set.db file
 * Arguments: setNum, questNum, stuId, score 
 */
int capaSetScore (ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
{
  T_entry entry;
  int score,i,result,question,numQuest,set;
  char buf[BUFFER_SIZE],*gAnswer,*stuId;
  T_header header;

  if (argc != 5) 
    {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp,"Incorrect number of arguments to save gAnswer",NULL);
      return TCL_ERROR;
    }

  set=atoi(argv[1]);
  question=atoi(argv[2]);
  stuId=argv[3];
  score=atoi(argv[4]);

  result=capa_get_header(&header,set);

  numQuest=atoi(header.num_questions);
  result = capa_get_entry(&entry,stuId,set);

  entry.answers=capa_malloc(numQuest+1,1);
  entry.tries=capa_malloc(3*numQuest+1,1);

  for(i=0;i<numQuest;i++) {
    if ( i==(question-1) ) {
      entry.answers[i]=score+'0';
    } else {
      entry.answers[i]='?';
    }
    entry.tries[i*3]='-';entry.tries[i*3+1]='1';
    if (i<numQuest-1) entry.tries[i*3+2]=',';
  }

  entry.answers[numQuest]='\0';
  entry.tries[(numQuest)*3]='\0';
  sprintf(entry.student_number,stuId);
  entry.e_probs=numQuest;
  result = capa_change_entry(&entry,stuId,set);

  if (result == -1) {
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp,"capa_change_entry returned an error.",NULL);
    return TCL_ERROR;
  }

  Tcl_ResetResult(interp);
  return TCL_OK;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.