File:
[LON-CAPA] /
capa /
capa51 /
GUITools /
scorertoset.c
Revision
1.5:
download - view:
text,
annotated -
select for diffs
Mon Sep 11 14:51:25 2000 UTC (24 years, 2 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_5_msu,
version_2_11_5,
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, short records would corrupt memory.
/* convert scorer.output files to set.db files
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.
*/
/*
* scorertoset.c
* Guy Albertelli II 1997
*/
#include <stdio.h>
#include <ctype.h>
#include <tcl.h>
#include <tk.h>
#include "pProj/capaCommon.h"
#include "scorer.h"
/**************************************************Set Database Entry */
int scorer_set_entry(ClientData notused, Tcl_Interp *interp, int argc, char** argv)
{
FILE *fp;
int fd;
int errcode=TCL_OK;
int done,len,new_len,item_cnt;
long next_r, orig_size, new_size, big_buf_size;
char filename[FILE_NAME_LENGTH];
char *a_line, tmpline[MAX_LINE_LENGTH], errorline[MAX_LINE_LENGTH],
tmp_sn[MAX_STUDENT_NUMBER+1], fmtbuf[SMALL_LINE_BUFFER];
char *big_buf;
char *student_number,*answers,*tries;
int set;
long offset;
if (argc != 6) {
Tcl_SetResult(interp,"usage is: studentNumber set fileOffset answers tries",
TCL_VOLATILE);
return TCL_ERROR;
}
student_number=argv[1];
set=atoi(argv[2]);
offset=atoi(argv[3]);
answers=argv[4];
tries=argv[5];
offset=(offset<0)?-offset:offset;
sprintf(filename,"records/set%d.sb",set);
if ((fp=fopen(filename,"r+"))==NULL) {
sprintf(errorline,"Error: can't open %s\n",filename);
Tcl_SetResult(interp,errorline,TCL_VOLATILE);
return TCL_ERROR;
}
a_line=capa_malloc(strlen(tries)*5+MAX_STUDENT_NUMBER,1);
sprintf(a_line,"%s %s,%s\n",student_number,answers,tries);
new_len = strlen(a_line);
sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
flockstream(fp);
fseek(fp,0L,SEEK_END);
orig_size = ftell(fp);
big_buf_size = orig_size + new_len;
big_buf = capa_malloc(big_buf_size,1);
fseek(fp,0L,SEEK_SET); /* rewind to beginning of file */
fgets(tmpline,TMP_LINE_LENGTH-1,fp); /* skip weight line, including \n */
fgets(tmpline,TMP_LINE_LENGTH-1,fp); /* hand grading */
done = 0;
while(!done) {
done = !fgets(tmpline,TMP_LINE_LENGTH-1,fp); len = strlen(tmpline);
if( !done ) {
sscanf(tmpline,fmtbuf,tmp_sn);
if( !strncasecmp(tmp_sn,student_number,MAX_STUDENT_NUMBER) ) { /* Found */
next_r = ftell(fp); offset = next_r - len; done = 1;
item_cnt=fread(big_buf,1,big_buf_size, fp); /* read remaining lines into buffer */
if(item_cnt >= 0 ) { /* no error reading remaining lines */
big_buf[item_cnt]=0; /* terminate the buffer, for sure */
fseek(fp,offset,SEEK_SET); /* reposition file pointer to the record */
if (!fwrite(a_line,new_len,1,fp) ) { /* write out the records */
sprintf(errorline,"Error writing data to file: %s\n",filename);
Tcl_SetResult(interp,errorline,TCL_VOLATILE);
errcode= TCL_ERROR;
}
if (item_cnt != 0) {
if (!fwrite(big_buf,item_cnt,1,fp) ){/*write out the remainings*/
sprintf(errorline,"Error writing data to file: %s\n",filename);
Tcl_SetResult(interp,errorline,TCL_VOLATILE);
errcode= TCL_ERROR;
}
}
new_size = ftell(fp);
if(new_size < orig_size ) {
fd = fileno(fp);
ftruncate(fd,new_size);
}
}
}
} else { /* end of file */
fseek(fp,0L,SEEK_END);
offset = ftell(fp); /* last byte, if last byte is cr, back up one */
fseek(fp,-1L,SEEK_END);
while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
offset = offset +2; /* last char and cr */
done=1;
fseek(fp,offset,SEEK_SET);
if (!fwrite(a_line,new_len,1,fp) ) { /* write out the records */
sprintf(errorline,"Error writing data to file: %s\n",filename);
Tcl_SetResult(interp,errorline,TCL_VOLATILE);
errcode= TCL_ERROR;
}
}
}
fflush(fp);
funlockstream(fp); /* <======= unlock the file */
fclose(fp);
capa_mfree(big_buf); /* free up the buffer */
return (errcode);
}
/**************************************************** Get db entry*/
/* RETURNS: byte offset to start of record, 0 if error,
-offset if not found & newly created
*/
int scorer_get_entry(ClientData notused, Tcl_Interp *interp, int argc, char** argv)
{
char filename[FILE_NAME_LENGTH];
FILE *fp;
int len, nq;
char *ans_p, *tries_p,oneline[MAX_LINE_LENGTH],fmtbuf[MAX_LINE_LENGTH],
buf[MAX_LINE_LENGTH];
long offset=0, next_r;
int ii, done, found=0,set;
char a_sn[MAX_STUDENT_NUMBER+1];
char *student_number;
T_entry *entry;
if (argc!=3) {
Tcl_SetResult(interp,"usage is: studentNumber set",TCL_VOLATILE);
return TCL_ERROR;
}
set=atoi(argv[2]);
student_number=argv[1];
entry=(T_entry*)capa_malloc(1,sizeof(T_entry));
sprintf(filename,"records/set%d.sb",set);
if ((fp=fopen(filename,"r"))==NULL) {
sprintf(buf,"Error: can't open %s\n",filename);
Tcl_SetResult(interp,buf,TCL_VOLATILE);
return TCL_ERROR;
}
sprintf(entry->student_number,"%s",student_number);
sprintf(fmtbuf, "%%%dc",MAX_STUDENT_NUMBER);
flockstream(fp);
fgets(oneline,MAX_LINE_LENGTH-1,fp);
len = strlen(oneline); sscanf(oneline,"%d",&nq);
ans_p = capa_malloc(nq+1,1); tries_p = capa_malloc(3*nq,1);
fgets(oneline,MAX_LINE_LENGTH-1,fp); /* skip weight line */
fgets(oneline,MAX_LINE_LENGTH-1,fp); /* hand grading */
done = 0;
while(!done) {
done = !fgets(oneline,MAX_LINE_LENGTH-1,fp); len = strlen(oneline);
if( !done ) {
sscanf(oneline,fmtbuf,a_sn);
if( !strncasecmp(a_sn,student_number,MAX_STUDENT_NUMBER) ) { /* Found */
next_r = ftell(fp); offset = next_r - len; done = 1; found = 1;
}
} else {
fseek(fp,0L,SEEK_END);
offset = ftell(fp); /* last byte, if last bye is cr, back up one */
fseek(fp,-1L,SEEK_END);
while(fgetc(fp) == '\n' ) { offset--; fseek(fp,offset,SEEK_SET); }
offset = offset +2; /* last char and cr */
found = 0; done=1;
}
}
funlockstream(fp); fclose(fp);
if(!found) {
for(ii=0;ii<nq;ii++) { /* Initialize answer string and tries string */
ans_p[ii] = '-'; tries_p[3*ii] = ' '; tries_p[3*ii + 1] = '0';
if(ii < nq-1) tries_p[3*ii + 2] = ',';
}
entry->answers = ans_p;
entry->tries = tries_p;
entry->e_probs = nq;
/*if (scorer_set_entry(entry,student_number,set,offset)==-1)
offset=0;*/
offset = -offset;
} else {
sprintf(fmtbuf, "%%%dc",nq);
sscanf(oneline + MAX_STUDENT_NUMBER+1,fmtbuf,ans_p);
sprintf(fmtbuf, "%%%dc",(3*nq-1));
sscanf(oneline + MAX_STUDENT_NUMBER+1+nq+1,fmtbuf,tries_p);
entry->answers = ans_p;
entry->tries = tries_p;
entry->e_probs = nq;
}
sprintf(buf,"%ld;%d;%s;%s",offset,entry->e_probs,entry->answers,entry->tries);
Tcl_SetResult(interp,buf,TCL_VOLATILE);
return TCL_OK;
}
void processFile(FILE *inputFile,Question questions[MAX_QUEST],int setId,
int gradingMethod,int numQuestions)
{
T_entry grade;
char studentNumber[MAX_STUDENT_NUMBER+1],name[MAX_NAME_CHAR+1];
int score,section,buf,i,numRight,points=0,leafs,processed=0,unit;
printf("Processing");
while(fscanf(inputFile,"%s",studentNumber)!=EOF)
{
processed++;
if (processed%100==1) { printf("%d",processed-1); }
printf(".");
fflush(stdout);
/* if ((offset = scorer_get_entry(&grade,studentNumber,setId))==0)
{
fprintf(stderr,"Please create the set%d.sb file\n",setId);
exit(-1);
}
*/
fscanf(inputFile,"%30c",name);
fscanf(inputFile,"%s",grade.answers);
fscanf(inputFile,"%d",&score);
fscanf(inputFile,"%d",§ion);
if ( (grade.e_probs != strlen(grade.answers))
||
(strlen(grade.answers) != numQuestions))
{
fprintf(stderr,"There is a disagreement in the number of problems");
fprintf(stderr,"\nNumQuestions:%d\n",numQuestions);
fprintf(stderr,"strlen(grade.answers):%d\n",strlen(grade.answers));
fprintf(stderr,"grade.answers:%s\n",grade.answers);
fprintf(stderr,"grade.e_probs:%d\n",grade.e_probs);
fprintf(stderr,"The set.sb file may have bad entries, please\n");
fprintf(stderr,"check the file and fix the error.\n");
exit(-1);
}
buf='\0';
while(buf!='\n')
{
buf=fgetc(inputFile);
}
#ifdef DEBUG
printf("%d %d\n",numQuestions,strlen(grade.answers));
#endif /*DEBUG*/
for(i=0;i<numQuestions;i++)
{
switch(questions[i].type)
{
case ONE_OUT_OF_8:
case SINGLE_DIGIT:
numRight= (int) (grade.answers[i]-'0');
score=numRight*questions[i].points;
grade.answers[i]='0'+(char)score;
break;
case STRING_MATCH:
/*for STRING_MATCH the score is stroed as the NumRight*/
numRight= (int) (grade.answers[i]-'0');
score=numRight;
grade.answers[i]='0'+(char)score;
break;
case GLE:
case TF:
case N_OUT_OF_M:
numRight=(int) (grade.answers[i]-'0');
leafs=questions[i].leafs;
points=questions[i].points;
unit=(int)ceil((double)points/(double)leafs);
if (unit==0) unit=points;
switch (gradingMethod)
{
case CAPA_METHOD:
score=points-(2*unit*(leafs-numRight));
break;
case LENIENT_METHOD:
score=points-(unit*(leafs-numRight));
break;
case STRICT:
if (numRight==leafs) score=points;
else score=0;
break;
default:
fprintf(stderr,"Unknown grading Method. %d\n",gradingMethod);
break;
}
if (score<0)
score=0;
grade.answers[i]='0'+(char)score;
break;
case ASSIGNED:
/*
*grade.answers already has the correct number of points.
*i.e whatever the scorer.output file had in it and was put in
*grade.
*/
break;
default:
fprintf(stderr,"Unknown question type %c\n",questions[i].type);
break;
}
}
for(i=0;i<strlen(grade.answers);i++)
{
grade.tries[3*i]=' ';
grade.tries[3*i+1]='1';
grade.tries[3*i+2]=',';
}
grade.tries[3*i-1]='\0';
grade.answers[i]='\0';
#ifdef DEBUG
printf("%s\n",studentNumber);
#endif /*DEBUG*/
/*if (scorer_set_entry(&grade,studentNumber,setId,abs(offset))==-1)
{
fprintf(stderr,"Please create the set%d.sb file\n",setId);
exit(-1);
}
*/
}
printf("\nProcessed %d results\n",processed);
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>