File:  [LON-CAPA] / capa / capa51 / pProj / checkunits.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Sep 28 21:26:22 1999 UTC (24 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
Initial revision

    1: 
    2: /* 
    3:    Units is checked against real or integer answers, 
    4:    for string and choice answers, units is not checked 
    5:    
    6:           UNIT_NOTNEEDED  ==> user entered some units and answer did not need one
    7:           NO_UNIT         ==> 
    8:           UNIT_FAIL
    9:    
   10:    ans_type must be either ANSWER_IS_INTEGER or ANSWER_IS_FLOAT
   11:    or else, skip or return UNIT_NOTNEEDED
   12:    if unit_p is NULL, then UNIT_NOTNEEDED
   13:    
   14:    answer must contains at least one digit 
   15:    
   16:    
   17: */
   18: 
   19: /*   
   20: 
   21: 
   22: #define    EXACT_ANS           1
   23: #define    APPROX_ANS          2 
   24: #define    SIG_FAIL            3
   25: #define    UNIT_FAIL           4
   26: #define    NO_UNIT             5
   27: #define    UNIT_OK             6
   28: #define    INCORRECT           7
   29: #define    UNIT_NOTNEEDED      8
   30: #define    ANS_CNT_NOT_MATCH   9
   31:   /*  called from capaCommon.c */
   32: /*                      */
   33: /*  UNIT_FAIL           */
   34: /*  NO_UNIT             */
   35: /*  result: UNIT_OK correct   */
   36: /*                            */
   37:  */
   38: 
   39: /* capa_check_units() only works under ANSWER_IS_INTEGER or ANSWER_IS_FLOAT */
   40: int
   41: capa_check_units( ans, u_p ) char *ans;Unit_t *u_p;
   42: {
   43:   input_len = strlen(ans);
   44:   all_alphabet = 1;
   45:   for(idx=0;idx<input_len;idx++) {
   46:     if( isdigit(ans[idx]) ) {
   47:       all_alphabet = 0;
   48:     }
   49:   }
   50:   
   51:   if( !all_alphabet ) { /* contains at least a digit char */
   52:     outcome = split_num_unit(ans,&n_part,num_str,unit_str);
   53:     /* num_str is used in calc_sig() for sig fig */
   54:     /* n_part is used together with scale from check_correct_answer() */
   55:     /* unit_str is used later as input to check_correct_unit() */
   56:     if( outcome > 1 ) {  /* with both num and unit parts or only unit part */
   57:     
   58:       if( u_p != NULL ) {
   59:           result = check_correct_unit(unit_str,u_p,&scale);
   60:           /* result could be UNIT_OK, UNIT_FAIL */
   61:           
   62:           
   63:       } else { /* no unit is specified but student entered an units? */
   64:           
   65:           result = UNIT_NOTNEEDED;
   66:           
   67:       }
   68: 
   69:     } else { /* outcome = 0 empty string, 1 a number without units */
   70:       if( u_p != NULL ) {
   71:           
   72:           result = NO_UNIT; /* units required */
   73:           
   74:       } else { 
   75:           result = INCORRECT, /* proceed to check numerical value */
   76:       }
   77:     }
   78:     /* at this point, result could be one of UNIT_OK, UNIT_FAIL, UNIT_NOTNEEDED, and NO_UNIT */
   79:     
   80:     sig = calc_sig( num_str );
   81:     
   82:   } else {   /* contains all non-digit  char */
   83:       result = INCORRECT;  /* the students may enter an units but not containing any number */
   84:       
   85:   }
   86:   return (result);
   87: }
   88: 
   89: 
   90: 
   91: 
   92: 
   93: 
   94: 
   95: 
   96: 
   97: 
   98: 
   99: 
  100: 
  101: 
  102: int
  103: capa_check_allunits(p,answers,cnt) Problem_t *p; char **answers; int cnt;
  104: {
  105:   int     type; 
  106:   char   *correct;
  107:   char    input[ANSWER_STRING_LENG], unit_str[UNIT_STRING_LENG];
  108:   int     tol_type, calc_type;
  109:   double  tol, n_part; 
  110:   int     sig_l; 
  111:   int     sig_u;
  112:   char   *fmt;
  113:   int     choice[SIXTY_FOUR], ii, idx, corr_len, input_len;
  114:   int     result = INCORRECT, sig, outcome, all_alphabet;
  115:   char    fmted[FORMAT_STRING_LENG];
  116:   double  given, target, ratio, fmted_target, target_u, target_l, scale=1.0;
  117:   double  delta;
  118:   
  119:   type       = p->ans_type;
  120:   correct    = p->answer;
  121:   tol_type   = p->tol_type;
  122:   tol        = p->tolerance;
  123:   sig_l      = p->sig_lbound;
  124:   sig_u      = p->sig_ubound;
  125:   fmt        = p->ans_fmt;
  126:   calc_type  = p->calc;
  127:   unit_str[0]= 0;
  128:   
  129:   if( (cnt != p->ans_cnt) ) { return (ANS_CNT_NOT_MATCH); }
  130:   switch(type) {
  131:     case ANSWER_IS_INTEGER:
  132:     case ANSWER_IS_FLOAT:
  133:           {
  134:             input_len = strlen(ans);
  135:             all_alphabet = 1;
  136:             for(idx=0;idx<input_len;idx++) {
  137:               if( isdigit(ans[idx]) ) {
  138:                 all_alphabet = 0;
  139:               }
  140:             }
  141:             if( !all_alphabet ) {  /* answer string is not all alphabets */
  142:               outcome = split_num_unit(ans,&n_part,num_str,unit_str);
  143:               if( outcome > 1 ) {  /* with both num and unit parts or only unit part */
  144:                 if( u_p != NULL ) {
  145:                   result = check_correct_unit(unit_str,u_p,&scale);
  146:                 } else { /* what to do when no unit is specified but student entered a
  147:                 unit? */
  148:                   result = UNIT_NOTNEEDED;
  149:                 }
  150:               } else {
  151:                 if( u_p != NULL ) {
  152:                   result = NO_UNIT;
  153:                 }
  154:               }
  155:   
  156:   idx = 1;  ai = p->ans_list;
  157:        while( (idx<cnt) && ( (result == EXACT_ANS) || (result == APPROX_ANS) ) ) {
  158:          result =  capa_check_ans(ai,answers[idx]);
  159:          ai = ai->ans_next; idx++;
  160:        }
  161:   if(num_answer==2)  printf("Answer:->%s [%s,%s] %s, ",p->answer,lower,upper,
  162: 			    p->unit_str); 
  163:       else  printf("Answer:->%s, ",lower);
  164:   switch(p->ans_type) {
  165:        case ANSWER_IS_INTEGER:   printf(" INTEGER,");
  166:         break;
  167:        case ANSWER_IS_FLOAT: 
  168:         printf(" FLOAT format=%s, SIG=[%d,%d],",
  169:           p->ans_fmt,p->sig_lbound,p->sig_ubound );
  170:         break;
  171:        case ANSWER_IS_STRING_CI: printf(" STRING C.I.,"); break;
  172:        case ANSWER_IS_STRING_CS: printf(" STRING C.S.,"); break;
  173:        case ANSWER_IS_CHOICE:    printf(" CHOICE,");      break;
  174:    }
  175:    printf(" WEIGHT=%d, TRIES=%d\n", p->weight,p->tries); fflush(stdout);
  176:    if(p->ans_unit != NULL) {
  177:         print_unit_t(p->ans_unit);  fflush(stdout);
  178:    }

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