version 1.14, 2000/08/07 20:47:29
|
version 1.24, 2004/06/01 19:57:18
|
Line 48 int yyparse();
|
Line 48 int yyparse();
|
extern FILE *yyin; |
extern FILE *yyin; |
extern void yyrestart(); |
extern void yyrestart(); |
|
|
|
extern FILE *dfp; |
|
|
/*----------------------------------------------------------*/ |
/*----------------------------------------------------------*/ |
/* RETURN: -1 file error */ |
/* RETURN: -1 file error */ |
/* 0 success */ |
/* 0 success */ |
Line 1447 void capa_get_due_date(char *date_str,T_
|
Line 1449 void capa_get_due_date(char *date_str,T_
|
if ((duration > 0) && (student_number!=NULL)) { |
if ((duration > 0) && (student_number!=NULL)) { |
if (capa_get_login_time(student_number,set,&logintime)==1) { |
if (capa_get_login_time(student_number,set,&logintime)==1) { |
duetime=logintime+duration; |
duetime=logintime+duration; |
due_time_tm=localtime(&duetime); |
if (compare_datetime(duetime,current->due_date)==-1) { |
sprintf(date_str,"%04d/%02d/%02d %02d:%02d",((due_time_tm->tm_year)+1900), |
due_time_tm=localtime(&duetime); |
due_time_tm->tm_mon+1,due_time_tm->tm_mday,due_time_tm->tm_hour, |
sprintf(date_str,"%04d/%02d/%02d %02d:%02d",((due_time_tm->tm_year)+1900), |
due_time_tm->tm_min); |
due_time_tm->tm_mon+1,due_time_tm->tm_mday,due_time_tm->tm_hour, |
|
due_time_tm->tm_min); |
|
} else { |
|
strncpy(date_str,current->due_date,DATE_BUFFER); |
|
} |
return; |
return; |
} |
} |
} |
} |
Line 2493 char *buf;double *num; char *num_p; char
|
Line 2499 char *buf;double *num; char *num_p; char
|
while( isspace(buf[idx]) ) { idx++; } |
while( isspace(buf[idx]) ) { idx++; } |
sscanf(num_str, "%lg", &result); /* put the numerical value into a double variable */ |
sscanf(num_str, "%lg", &result); /* put the numerical value into a double variable */ |
errcode = errcode | 1; |
errcode = errcode | 1; |
} else if( buf[idx] == 'x' || buf[idx] == 'X') { /* optional x or X part */ |
} else if( buf[idx] == 'x' || buf[idx] == 'X' || buf[idx] == '*') { /* optional x or X part */ |
idx++; /* skip x or X */ |
idx++; /* skip x or X */ |
while( isspace(buf[idx]) ) { idx++; } |
while( isspace(buf[idx]) ) { idx++; } |
|
|
Line 2632 answers_string(mode, p)int mode;Problem_
|
Line 2638 answers_string(mode, p)int mode;Problem_
|
if(len_dd == 0 ) { /* no unit_str */ |
if(len_dd == 0 ) { /* no unit_str */ |
sprintf(ans_str," %s [%s,%s]\n\n", str_aa,str_bb,str_cc); |
sprintf(ans_str," %s [%s,%s]\n\n", str_aa,str_bb,str_cc); |
} else { |
} else { |
sprintf(ans_str," %s [%s,%s] $%s$\n\n", str_aa,str_bb,str_cc,p->unit_str); |
sprintf(ans_str," %s [%s,%s] $\\mathrm{%s}$\n\n", str_aa,str_bb,str_cc,p->unit_str); |
} |
} |
capa_mfree((char *)str_aa); |
capa_mfree((char *)str_aa); |
capa_mfree((char *)str_bb); |
capa_mfree((char *)str_bb); |
Line 2654 answers_string(mode, p)int mode;Problem_
|
Line 2660 answers_string(mode, p)int mode;Problem_
|
if(len_dd == 0 ) { /* no unit_str */ |
if(len_dd == 0 ) { /* no unit_str */ |
sprintf(ans_str," %s\n", str_bb); |
sprintf(ans_str," %s\n", str_bb); |
} else { |
} else { |
sprintf(ans_str," %s $%s$\n", str_bb,p->unit_str); |
sprintf(ans_str," %s $\\mathrm{%s}$\n", str_bb,p->unit_str); |
} |
} |
capa_mfree((char *)str_bb); |
capa_mfree((char *)str_bb); |
} |
} |
Line 2891 answers_string(mode, p)int mode;Problem_
|
Line 2897 answers_string(mode, p)int mode;Problem_
|
} |
} |
|
|
|
|
|
int check_for_unit_fail(int result) |
|
{ |
|
int ret; |
|
ret = (result == UNIT_FAIL || |
|
result == UNIT_IRRECONCIBLE || |
|
result == UNIT_INVALID_STUDENT3 || |
|
result == UNIT_INVALID_STUDENT2 || |
|
result == UNIT_INVALID_STUDENT1); |
|
return ret; |
|
} |
|
|
/* ------------------------------ called from capalogin */ |
/* ------------------------------ called from capalogin */ |
/* impose stronger checking on the user input string *answer */ |
/* impose stronger checking on the user input string *answer */ |
Line 2915 capa_check_ans(ai,ans, error) AnswerInfo
|
Line 2931 capa_check_ans(ai,ans, error) AnswerInfo
|
int sig, corr_len; |
int sig, corr_len; |
int choice[ANSWER_STRING_LENG]; |
int choice[ANSWER_STRING_LENG]; |
char num_str[ANSWER_STRING_LENG], unit_str[ANSWER_STRING_LENG]; |
char num_str[ANSWER_STRING_LENG], unit_str[ANSWER_STRING_LENG]; |
char fmted[ANSWER_STRING_LENG], correct[ANSWER_STRING_LENG], answer[ANSWER_STRING_LENG]; |
char fmted[ANSWER_STRING_LENG], correctans[ANSWER_STRING_LENG], answer[ANSWER_STRING_LENG]; |
double n_part; |
double n_part; |
double given, target, ratio, fmted_target, target_u, target_l, scale=1.0; |
double given, target, ratio, fmted_target, target_u, target_l, scale=1.0; |
double delta; |
double delta; |
Line 2941 capa_check_ans(ai,ans, error) AnswerInfo
|
Line 2957 capa_check_ans(ai,ans, error) AnswerInfo
|
outcome = split_num_unit(ans,&n_part,num_str,unit_str); |
outcome = split_num_unit(ans,&n_part,num_str,unit_str); |
if( outcome > 1 ) { /* with both num and unit parts or only unit part */ |
if( outcome > 1 ) { /* with both num and unit parts or only unit part */ |
if( u_p != NULL ) { |
if( u_p != NULL ) { |
if (UNIT_FAIL == (result = check_correct_unit(unit_str,u_p,&scale))) { |
result = check_correct_unit(unit_str,u_p,&scale); |
|
if (check_for_unit_fail(result)) { |
*error=strsave(unit_str); |
*error=strsave(unit_str); |
} |
} |
} else { /* what to do when no unit is specified but student entered a unit? */ |
} else { /* what to do when no unit is specified but student entered a unit? */ |
Line 2953 capa_check_ans(ai,ans, error) AnswerInfo
|
Line 2970 capa_check_ans(ai,ans, error) AnswerInfo
|
result = NO_UNIT; |
result = NO_UNIT; |
} |
} |
} |
} |
if( (result != NO_UNIT) && (result != UNIT_FAIL) && ( result != UNIT_NOTNEEDED) ) { |
if( (result != NO_UNIT) && (!check_for_unit_fail(result)) && ( result != UNIT_NOTNEEDED) ) { |
if( t == ANSWER_IS_FLOAT ) { |
if( t == ANSWER_IS_FLOAT ) { |
target = (double)atof(s); /* real number */ |
target = (double)atof(s); /* real number */ |
} else { |
} else { |
Line 3014 capa_check_ans(ai,ans, error) AnswerInfo
|
Line 3031 capa_check_ans(ai,ans, error) AnswerInfo
|
{ |
{ |
corr_len = strlen(s); input_len = strlen(ans); |
corr_len = strlen(s); input_len = strlen(ans); |
if( corr_len == input_len ) { |
if( corr_len == input_len ) { |
for(idx=0;idx<ANSWER_STRING_LENG;idx++) choice[idx] = 0; |
for(idx=0;idx<ANSWER_STRING_LENG;idx++) { |
|
choice[idx] = 0;correctans[idx] = 0; |
|
} |
result = EXACT_ANS; |
result = EXACT_ANS; |
for(ii=0;ii<corr_len; ii++) { |
for(ii=0;ii<corr_len; ii++) { |
idx = toupper(correct[ii]) - 'A'; choice[idx] = 1; |
idx = toupper(s[ii]) - 'A'; choice[idx] = 1; |
} |
} |
for(ii=0;ii<input_len;ii++) { |
for(ii=0;ii<input_len;ii++) { |
idx = toupper(answer[ii]) - 'A'; |
idx = toupper(ans[ii]) - 'A'; correctans[idx] = 1; |
if(choice[idx] != 1 ) result = INCORRECT; |
} |
|
for(ii=0;ii<ANSWER_STRING_LENG;ii++) { |
|
if(choice[ii] != correctans[ii] ) result = INCORRECT; |
} |
} |
} else { result = INCORRECT; } |
} else { result = INCORRECT; } |
break; |
break; |
Line 3071 capa_check_answer(p, answer, error) Prob
|
Line 3092 capa_check_answer(p, answer, error) Prob
|
int sig_l; |
int sig_l; |
int sig_u; |
int sig_u; |
char *fmt; |
char *fmt; |
int choice[ANSWER_STRING_LENG], ii, idx, corr_len, input_len; |
int choice[ANSWER_STRING_LENG], correctans[ANSWER_STRING_LENG]; |
|
int ii, idx, corr_len, input_len; |
int result = INCORRECT, sig, outcome, all_alphabet; |
int result = INCORRECT, sig, outcome, all_alphabet; |
char fmted[FORMAT_STRING_LENG]; |
char fmted[FORMAT_STRING_LENG]; |
double given, target, ratio, fmted_target, target_u, target_l, scale=1.0; |
double given, target, ratio, fmted_target, target_u, target_l, scale=1.0; |
Line 3086 capa_check_answer(p, answer, error) Prob
|
Line 3108 capa_check_answer(p, answer, error) Prob
|
fmt = p->ans_fmt; |
fmt = p->ans_fmt; |
calc_type = p->calc; |
calc_type = p->calc; |
unit_str[0]=0; |
unit_str[0]=0; |
|
|
switch(type) { |
switch(type) { |
case ANSWER_IS_INTEGER: |
case ANSWER_IS_INTEGER: |
case ANSWER_IS_FLOAT: |
case ANSWER_IS_FLOAT: |
Line 3102 capa_check_answer(p, answer, error) Prob
|
Line 3124 capa_check_answer(p, answer, error) Prob
|
outcome = split_num_unit(answer,&n_part,input,unit_str); |
outcome = split_num_unit(answer,&n_part,input,unit_str); |
if( outcome > 1 ) { /* with both num and unit parts or only unit part */ |
if( outcome > 1 ) { /* with both num and unit parts or only unit part */ |
if( p->ans_unit != NULL ) { |
if( p->ans_unit != NULL ) { |
if ( UNIT_FAIL == ( result = check_correct_unit(unit_str,p->ans_unit,&scale) ) ) { |
result = check_correct_unit(unit_str,p->ans_unit,&scale); |
|
if (check_for_unit_fail(result)) { |
*error=strsave(unit_str); |
*error=strsave(unit_str); |
} |
} |
} else { /* what to do when no unit is specified but student entered a unit? */ |
} else { /* what to do when no unit is specified but student entered a unit? */ |
Line 3114 capa_check_answer(p, answer, error) Prob
|
Line 3137 capa_check_answer(p, answer, error) Prob
|
result = NO_UNIT; |
result = NO_UNIT; |
} |
} |
} |
} |
if( (result != NO_UNIT) && (result != UNIT_FAIL) && ( result != UNIT_NOTNEEDED) ) { |
if( (result != NO_UNIT) && (!check_for_unit_fail(result)) && ( result != UNIT_NOTNEEDED) ) { |
if( type == ANSWER_IS_FLOAT ) { |
if( type == ANSWER_IS_FLOAT ) { |
target = (double)atof(correct); /* real number */ |
target = (double)atof(correct); /* real number */ |
} else { |
} else { |
Line 3175 capa_check_answer(p, answer, error) Prob
|
Line 3198 capa_check_answer(p, answer, error) Prob
|
{ |
{ |
corr_len = strlen(correct); input_len = strlen(answer); |
corr_len = strlen(correct); input_len = strlen(answer); |
if( corr_len == input_len ) { |
if( corr_len == input_len ) { |
for(ii=0;ii<ANSWER_STRING_LENG;ii++) choice[ii] = 0; result = EXACT_ANS; |
for(idx=0;idx<ANSWER_STRING_LENG;idx++) { |
|
choice[idx] = 0;correctans[idx] = 0; |
|
} |
|
result = EXACT_ANS; |
for(ii=0;ii<corr_len; ii++) { |
for(ii=0;ii<corr_len; ii++) { |
idx = toupper(correct[ii]) - 'A'; choice[idx] = 1; |
idx = toupper(correct[ii]) - 'A'; choice[idx] = 1; |
} |
} |
for(ii=0;ii<input_len;ii++) { |
for(ii=0;ii<input_len;ii++) { |
idx = toupper(answer[ii]) - 'A'; |
idx = toupper(answer[ii]) - 'A'; correctans[idx] = 1; |
if(choice[idx] != 1 ) result = INCORRECT; |
} |
|
for(ii=0;ii<ANSWER_STRING_LENG;ii++) { |
|
if(choice[ii] != correctans[ii] ) result = INCORRECT; |
} |
} |
} else { result = INCORRECT; } |
} else { result = INCORRECT; } |
break; |
break; |
Line 3200 capa_check_answer(p, answer, error) Prob
|
Line 3228 capa_check_answer(p, answer, error) Prob
|
/* and the result will be given back as 0 or 1 to indicate the */ |
/* and the result will be given back as 0 or 1 to indicate the */ |
/* given answer is correct or not */ |
/* given answer is correct or not */ |
/* arguments are given to the program as */ |
/* arguments are given to the program as */ |
|
/* before running the program, check its existance first */ |
|
/* should we specify a time out period in capa.config file? */ |
|
/* set up a timer for this purpose */ |
|
/* FILE *popen (const char *command,const char *type ); */ |
|
|
break; |
break; |
|
|
Line 3207 capa_check_answer(p, answer, error) Prob
|
Line 3239 capa_check_answer(p, answer, error) Prob
|
return (result); |
return (result); |
} |
} |
|
|
/* ----------------------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------------- */ |
/* assumming the formula is *fml_str and the student input is *input_str */ |
/* assumming the formula is *fml_str and the student input is *input_str */ |
/* according to the type of tolerance, we form the final formula as */ |
/* according to the type of tolerance, we form the final formula as */ |
/* absolute tolerance: (*fml_str) - (*input_str) */ |
/* absolute tolerance: (*fml_str) - (*input_str) */ |
Line 3242 char *fml_str;char *input_str;char *var_
|
Line 3274 char *fml_str;char *input_str;char *var_
|
} |
} |
} else { |
} else { |
diff = abs(1.0 - formula_val) * 100.0 ; |
diff = abs(1.0 - formula_val) * 100.0 ; |
if( diff < tol ) { |
if( diff > tol ) { |
outcome = INCORRECT; |
outcome = INCORRECT; |
} |
} |
} |
} |
Line 3367 Problem_t *p; char **answers; int cnt; c
|
Line 3399 Problem_t *p; char **answers; int cnt; c
|
outcomes = (int *)capa_malloc(sizeof(int),cnt); |
outcomes = (int *)capa_malloc(sizeof(int),cnt); |
for(ii=0;ii<cnt;ii++) outcomes[ii]=0; /* initialize the outcomes array */ |
for(ii=0;ii<cnt;ii++) outcomes[ii]=0; /* initialize the outcomes array */ |
outcomes[0] = capa_check_answer(p, answers[0], &errormsg[0]); |
outcomes[0] = capa_check_answer(p, answers[0], &errormsg[0]); |
|
#ifdef COMMON_DBUG |
|
printf("CAPA_CHECK_ANSWER(%s,%s):: outcome[0]=%d\n", |
|
p->answer,answers[0],outcomes[0]); |
|
#endif |
for(ii=1, ai = p->ans_list; ai; ii++,ai = ai->ans_next ) { |
for(ii=1, ai = p->ans_list; ai; ii++,ai = ai->ans_next ) { |
outcomes[ii] = capa_check_ans(ai,answers[ii],&(errormsg[ii])); |
outcomes[ii] = capa_check_ans(ai,answers[ii],&(errormsg[ii])); |
|
#ifdef COMMON_DBUG |
|
printf("CAPA_CHECK_ANS(%s,%s): outcome[%d]=%d\n", ai->ans_str,answers[ii],ii,outcomes[ii]); |
|
#endif |
} |
} |
done = ii = 0; |
done = ii = 0; |
result = 0; |
result = 0; |
while( !done ) { /* check if any of the outcome has failed on units */ |
while( !done ) { /* check if any of the outcome has failed on units */ |
if( (outcomes[ii] == UNIT_FAIL) || |
if( (check_for_unit_fail(outcomes[ii])) || |
(outcomes[ii] == NO_UNIT) || |
(outcomes[ii] == NO_UNIT) || |
(outcomes[ii] == UNIT_NOTNEEDED) ) { |
(outcomes[ii] == UNIT_NOTNEEDED) ) { |
result = outcomes[ii]; |
result = outcomes[ii]; |
Line 3383 Problem_t *p; char **answers; int cnt; c
|
Line 3422 Problem_t *p; char **answers; int cnt; c
|
ii++; |
ii++; |
if(ii==cnt) done = 1; |
if(ii==cnt) done = 1; |
} |
} |
if( result == 0 ) { /* check if any of the outcome has failed to be a numeric */ |
if( result == 0 ) { |
|
/* check if any of the outcome has failed to be a numeric |
|
or was a malformed equation */ |
done = ii = 0; |
done = ii = 0; |
while( !done ) { |
while( !done ) { |
if( outcomes[ii] == WANTED_NUMERIC ) { |
if( outcomes[ii] == WANTED_NUMERIC || outcomes[ii] == BAD_FORMULA ) { |
result = outcomes[ii]; |
result = outcomes[ii]; |
done = 1; |
done = 1; |
} |
} |
Line 3394 Problem_t *p; char **answers; int cnt; c
|
Line 3435 Problem_t *p; char **answers; int cnt; c
|
if(ii==cnt) done = 1; |
if(ii==cnt) done = 1; |
} |
} |
} |
} |
if( result == 0 ) { /* check if any of the outcome has failed on sig figs */ |
if( result == 0 ) {/*check if any of the outcome has failed on sig figs*/ |
done = ii = 0; |
done = ii = 0; |
while( !done ) { |
while( !done ) { |
if( outcomes[ii] == SIG_FAIL ) { |
if( outcomes[ii] == SIG_FAIL ) { |
Line 3418 Problem_t *p; char **answers; int cnt; c
|
Line 3459 Problem_t *p; char **answers; int cnt; c
|
} |
} |
} |
} |
for (ii=0;ii<cnt;ii++) { |
for (ii=0;ii<cnt;ii++) { |
if( (outcomes[ii] == UNIT_FAIL) || |
if( (check_for_unit_fail(outcomes[ii])) || |
(outcomes[ii] == SIG_FAIL) || |
(outcomes[ii] == SIG_FAIL) || |
(outcomes[ii] == UNIT_NOTNEEDED) ) { |
(outcomes[ii] == UNIT_NOTNEEDED) ) { |
capa_mfree(errormsg[ii]); |
capa_mfree(errormsg[ii]); |
Line 3436 Problem_t *p; char **answers; int cnt; c
|
Line 3477 Problem_t *p; char **answers; int cnt; c
|
result = capa_check_answer(p, answers[0], error); |
result = capa_check_answer(p, answers[0], error); |
ii = 1; ai = p->ans_list; |
ii = 1; ai = p->ans_list; |
while( (ii<p->ans_cnt) && ( (result != EXACT_ANS) && (result != APPROX_ANS) ) ) { |
while( (ii<p->ans_cnt) && ( (result != EXACT_ANS) && (result != APPROX_ANS) ) ) { |
if((ii!=1)&&((result==UNIT_FAIL)||(result==SIG_FAIL)||(result==UNIT_NOTNEEDED))) { |
if((ii!=1)&&((check_for_unit_fail(result))||(result==SIG_FAIL)||(result==UNIT_NOTNEEDED))) { |
capa_mfree((char*)error); |
capa_mfree((char*)error); |
} |
} |
result = capa_check_ans(ai,answers[0],error); |
result = capa_check_ans(ai,answers[0],error); |
Line 3537 char *key_word;char *value;
|
Line 3578 char *key_word;char *value;
|
} |
} |
} |
} |
if (c=='\n') found=1; |
if (c=='\n') found=1; |
if (((char)c)==((char)EOF)) break; |
if (((char)c)==((char)EOF)) {failed=1;break;} |
} |
} |
} |
} |
} while (!done && !failed); |
} while (!done && !failed); |