--- capa/capa51/pProj/capaCommon.c 2000/07/07 18:33:03 1.13 +++ capa/capa51/pProj/capaCommon.c 2005/12/01 22:32:10 1.26 @@ -2,16 +2,16 @@ 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 Library General Public License as + 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 - Library General Public License for more details. + General Public License for more details. - You should have received a copy of the GNU Library General Public + 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. @@ -48,6 +48,8 @@ int yyparse(); extern FILE *yyin; extern void yyrestart(); +extern FILE *dfp; + /*----------------------------------------------------------*/ /* RETURN: -1 file error */ /* 0 success */ @@ -1447,10 +1449,14 @@ void capa_get_due_date(char *date_str,T_ if ((duration > 0) && (student_number!=NULL)) { if (capa_get_login_time(student_number,set,&logintime)==1) { duetime=logintime+duration; - due_time_tm=localtime(&duetime); - sprintf(date_str,"%04d/%02d/%02d %02d:%02d",((due_time_tm->tm_year)+1900), - due_time_tm->tm_mon+1,due_time_tm->tm_mday,due_time_tm->tm_hour, - due_time_tm->tm_min); + if (compare_datetime(duetime,current->due_date)==-1) { + due_time_tm=localtime(&duetime); + sprintf(date_str,"%04d/%02d/%02d %02d:%02d",((due_time_tm->tm_year)+1900), + 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; } } @@ -2448,7 +2454,8 @@ check_input_usymb(u_symb)char *u_symb; /* num_p : the numerical part in string */ /* unit_p : the unit string */ /* num_p is used to calculate sig figs */ -/* return : 0 empty string */ +/* return : -1 invalid string */ +/* 0 empty string */ /* 1 number without units */ /* 2 empty number with units */ /* 3 number with units */ @@ -2493,14 +2500,17 @@ char *buf;double *num; char *num_p; char while( isspace(buf[idx]) ) { idx++; } sscanf(num_str, "%lg", &result); /* put the numerical value into a double variable */ 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 */ while( isspace(buf[idx]) ) { idx++; } e_part = 1.0; /* default power */ base_str[b_idx] = 0; /* initialize base_str[] */ - while( isdigit(buf[idx]) || buf[idx] == '.' ) { /* should start with a digit or . */ + if( buf[idx] == '1' && buf[idx+1] == '0') { base_str[b_idx++] = buf[idx++]; + base_str[b_idx++] = buf[idx++]; + } else { + return (-1); } base_str[b_idx] = 0; /* terminate base_str[] */ while( isspace(buf[idx]) ) { idx++; } /* skip over white spaces */ @@ -2514,7 +2524,7 @@ char *buf;double *num; char *num_p; char while( isspace(buf[idx]) ) { idx++; } if( isdigit(buf[idx]) || buf[idx] == '+' || buf[idx] == '-' ) { exp_str[e_idx] = 0; /* initialize exp_str[], again */ - while( isdigit(buf[idx]) || buf[idx] == '.' || buf[idx] == '+' || buf[idx] == '-' ) { + while( isdigit(buf[idx]) /*|| buf[idx] == '.'*/ || buf[idx] == '+' || buf[idx] == '-' ) { exp_str[e_idx++] = buf[idx++]; } exp_str[e_idx] = 0; /* terminate exp_str[] */ @@ -2548,7 +2558,7 @@ char *buf;double *num; char *num_p; char while( isspace(buf[idx]) ) { idx++; } if( isdigit(buf[idx]) || buf[idx] == '+' || buf[idx] == '-' ) { exp_str[e_idx] = 0; - while( isdigit(buf[idx]) || buf[idx] == '.' || buf[idx] == '+' || buf[idx] == '-' ) { + while( isdigit(buf[idx]) /*|| buf[idx] == '.'*/ || buf[idx] == '+' || buf[idx] == '-' ) { exp_str[e_idx++] = buf[idx++]; } exp_str[e_idx] = 0; @@ -2559,6 +2569,9 @@ char *buf;double *num; char *num_p; char } sscanf(exp_str, "%lg", &e_part); sscanf(num_str, "%lg", &n_part); + if( n_part != 10 ) { + return (-1); + } result = pow(n_part,e_part); errcode = errcode | 1; } else { /* number unit */ @@ -2632,7 +2645,7 @@ answers_string(mode, p)int mode;Problem_ if(len_dd == 0 ) { /* no unit_str */ sprintf(ans_str," %s [%s,%s]\n\n", str_aa,str_bb,str_cc); } 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_bb); @@ -2654,7 +2667,7 @@ answers_string(mode, p)int mode;Problem_ if(len_dd == 0 ) { /* no unit_str */ sprintf(ans_str," %s\n", str_bb); } 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); } @@ -2891,6 +2904,16 @@ 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 */ /* impose stronger checking on the user input string *answer */ @@ -2915,7 +2938,7 @@ capa_check_ans(ai,ans, error) AnswerInfo int sig, corr_len; int choice[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 given, target, ratio, fmted_target, target_u, target_l, scale=1.0; double delta; @@ -2937,11 +2960,14 @@ capa_check_ans(ai,ans, error) AnswerInfo all_alphabet = 0; } } - if( !all_alphabet ) { /* answer string is not all alphabets */ + if( !all_alphabet ) { outcome = split_num_unit(ans,&n_part,num_str,unit_str); + } + if( outcome > 0 ) { if( outcome > 1 ) { /* with both num and unit parts or only unit part */ 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); } } else { /* what to do when no unit is specified but student entered a unit? */ @@ -2953,7 +2979,7 @@ capa_check_ans(ai,ans, error) AnswerInfo 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 ) { target = (double)atof(s); /* real number */ } else { @@ -3014,14 +3040,18 @@ capa_check_ans(ai,ans, error) AnswerInfo { corr_len = strlen(s); input_len = strlen(ans); if( corr_len == input_len ) { - for(idx=0;idxans_fmt; calc_type = p->calc; unit_str[0]=0; - + switch(type) { case ANSWER_IS_INTEGER: case ANSWER_IS_FLOAT: @@ -3100,9 +3131,12 @@ capa_check_answer(p, answer, error) Prob } if( !all_alphabet ) { outcome = split_num_unit(answer,&n_part,input,unit_str); + } + if( outcome > 0 ) { if( outcome > 1 ) { /* with both num and unit parts or only unit part */ 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); } } else { /* what to do when no unit is specified but student entered a unit? */ @@ -3114,7 +3148,7 @@ capa_check_answer(p, answer, error) Prob 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 ) { target = (double)atof(correct); /* real number */ } else { @@ -3175,13 +3209,18 @@ capa_check_answer(p, answer, error) Prob { corr_len = strlen(correct); input_len = strlen(answer); if( corr_len == input_len ) { - for(ii=0;ii tol ) { + outcome = INCORRECT; + } + } + return outcome; +} + +/* -------------------------------------------------------------------------- */ /* 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 */ /* absolute tolerance: (*fml_str) - (*input_str) */ @@ -3219,7 +3281,7 @@ char *fml_str;char *input_str;char *var_ char *check_fml_str; int f_len, i_len, outcome, error_code; PointsList_t *pt, *next; - double formula_val, diff; + double formula_val; f_len = strlen(fml_str); i_len = strlen(input_str); @@ -3231,21 +3293,20 @@ char *fml_str;char *input_str;char *var_ sprintf(check_fml_str,"(%s) / (%s)",input_str,fml_str); } outcome = APPROX_ANS; + if( pts_list==NULL ) { + error_code = f_eval_formula(&formula_val,check_fml_str, var_list, NULL); + if( ! error_code ) { + outcome = check_tol(formula_val,tol_type,tol); + } else { + outcome = BAD_FORMULA; + } + } + for(pt= pts_list; pt!=NULL ; pt=next) { next=pt->pts_next; error_code = f_eval_formula(&formula_val,check_fml_str, var_list, pt->pts_str); if( ! error_code ) { - if( tol_type == TOL_ABSOLUTE ) { - diff = tol - formula_val; - if( diff < 0.0 ) { - outcome = INCORRECT; - } - } else { - diff = abs(1.0 - formula_val) * 100.0 ; - if( diff < tol ) { - outcome = INCORRECT; - } - } + outcome = check_tol(formula_val,tol_type,tol); } else { outcome = BAD_FORMULA; break; @@ -3367,13 +3428,20 @@ Problem_t *p; char **answers; int cnt; c outcomes = (int *)capa_malloc(sizeof(int),cnt); for(ii=0;iianswer,answers[0],outcomes[0]); +#endif for(ii=1, ai = p->ans_list; ai; ii++,ai = ai->ans_next ) { 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; result = 0; 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] == UNIT_NOTNEEDED) ) { result = outcomes[ii]; @@ -3383,10 +3451,12 @@ Problem_t *p; char **answers; int cnt; c ii++; 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; while( !done ) { - if( outcomes[ii] == WANTED_NUMERIC ) { + if( outcomes[ii] == WANTED_NUMERIC || outcomes[ii] == BAD_FORMULA ) { result = outcomes[ii]; done = 1; } @@ -3394,7 +3464,7 @@ Problem_t *p; char **answers; int cnt; c 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; while( !done ) { if( outcomes[ii] == SIG_FAIL ) { @@ -3418,7 +3488,7 @@ Problem_t *p; char **answers; int cnt; c } } for (ii=0;iians_list; while( (iians_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); } result = capa_check_ans(ai,answers[0],error); @@ -3537,7 +3607,7 @@ char *key_word;char *value; } } if (c=='\n') found=1; - if (((char)c)==((char)EOF)) break; + if (((char)c)==((char)EOF)) {failed=1;break;} } } } while (!done && !failed);