Annotation of capa/capa51/pProj/checkunits.c, revision 1.2
1.2 ! albertel 1: /* harness to test the unit engine out
! 2: Copyright (C) 1992-2000 Michigan State University
! 3:
! 4: The CAPA system is free software; you can redistribute it and/or
! 5: modify it under the terms of the GNU Library General Public License as
! 6: published by the Free Software Foundation; either version 2 of the
! 7: License, or (at your option) any later version.
! 8:
! 9: The CAPA system is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 12: Library General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU Library General Public
! 15: License along with the CAPA system; see the file COPYING. If not,
! 16: write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
! 17: Boston, MA 02111-1307, USA. */
1.1 albertel 18:
19: /*
20: Units is checked against real or integer answers,
21: for string and choice answers, units is not checked
22:
23: UNIT_NOTNEEDED ==> user entered some units and answer did not need one
24: NO_UNIT ==>
25: UNIT_FAIL
26:
27: ans_type must be either ANSWER_IS_INTEGER or ANSWER_IS_FLOAT
28: or else, skip or return UNIT_NOTNEEDED
29: if unit_p is NULL, then UNIT_NOTNEEDED
30:
31: answer must contains at least one digit
32:
33:
34: */
35:
36: /*
37:
38:
39: #define EXACT_ANS 1
40: #define APPROX_ANS 2
41: #define SIG_FAIL 3
42: #define UNIT_FAIL 4
43: #define NO_UNIT 5
44: #define UNIT_OK 6
45: #define INCORRECT 7
46: #define UNIT_NOTNEEDED 8
47: #define ANS_CNT_NOT_MATCH 9
48: /* called from capaCommon.c */
49: /* */
50: /* UNIT_FAIL */
51: /* NO_UNIT */
52: /* result: UNIT_OK correct */
53: /* */
54: */
55:
56: /* capa_check_units() only works under ANSWER_IS_INTEGER or ANSWER_IS_FLOAT */
57: int
58: capa_check_units( ans, u_p ) char *ans;Unit_t *u_p;
59: {
60: input_len = strlen(ans);
61: all_alphabet = 1;
62: for(idx=0;idx<input_len;idx++) {
63: if( isdigit(ans[idx]) ) {
64: all_alphabet = 0;
65: }
66: }
67:
68: if( !all_alphabet ) { /* contains at least a digit char */
69: outcome = split_num_unit(ans,&n_part,num_str,unit_str);
70: /* num_str is used in calc_sig() for sig fig */
71: /* n_part is used together with scale from check_correct_answer() */
72: /* unit_str is used later as input to check_correct_unit() */
73: if( outcome > 1 ) { /* with both num and unit parts or only unit part */
74:
75: if( u_p != NULL ) {
76: result = check_correct_unit(unit_str,u_p,&scale);
77: /* result could be UNIT_OK, UNIT_FAIL */
78:
79:
80: } else { /* no unit is specified but student entered an units? */
81:
82: result = UNIT_NOTNEEDED;
83:
84: }
85:
86: } else { /* outcome = 0 empty string, 1 a number without units */
87: if( u_p != NULL ) {
88:
89: result = NO_UNIT; /* units required */
90:
91: } else {
92: result = INCORRECT, /* proceed to check numerical value */
93: }
94: }
95: /* at this point, result could be one of UNIT_OK, UNIT_FAIL, UNIT_NOTNEEDED, and NO_UNIT */
96:
97: sig = calc_sig( num_str );
98:
99: } else { /* contains all non-digit char */
100: result = INCORRECT; /* the students may enter an units but not containing any number */
101:
102: }
103: return (result);
104: }
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119: int
120: capa_check_allunits(p,answers,cnt) Problem_t *p; char **answers; int cnt;
121: {
122: int type;
123: char *correct;
124: char input[ANSWER_STRING_LENG], unit_str[UNIT_STRING_LENG];
125: int tol_type, calc_type;
126: double tol, n_part;
127: int sig_l;
128: int sig_u;
129: char *fmt;
130: int choice[SIXTY_FOUR], ii, idx, corr_len, input_len;
131: int result = INCORRECT, sig, outcome, all_alphabet;
132: char fmted[FORMAT_STRING_LENG];
133: double given, target, ratio, fmted_target, target_u, target_l, scale=1.0;
134: double delta;
135:
136: type = p->ans_type;
137: correct = p->answer;
138: tol_type = p->tol_type;
139: tol = p->tolerance;
140: sig_l = p->sig_lbound;
141: sig_u = p->sig_ubound;
142: fmt = p->ans_fmt;
143: calc_type = p->calc;
144: unit_str[0]= 0;
145:
146: if( (cnt != p->ans_cnt) ) { return (ANS_CNT_NOT_MATCH); }
147: switch(type) {
148: case ANSWER_IS_INTEGER:
149: case ANSWER_IS_FLOAT:
150: {
151: input_len = strlen(ans);
152: all_alphabet = 1;
153: for(idx=0;idx<input_len;idx++) {
154: if( isdigit(ans[idx]) ) {
155: all_alphabet = 0;
156: }
157: }
158: if( !all_alphabet ) { /* answer string is not all alphabets */
159: outcome = split_num_unit(ans,&n_part,num_str,unit_str);
160: if( outcome > 1 ) { /* with both num and unit parts or only unit part */
161: if( u_p != NULL ) {
162: result = check_correct_unit(unit_str,u_p,&scale);
163: } else { /* what to do when no unit is specified but student entered a
164: unit? */
165: result = UNIT_NOTNEEDED;
166: }
167: } else {
168: if( u_p != NULL ) {
169: result = NO_UNIT;
170: }
171: }
172:
173: idx = 1; ai = p->ans_list;
174: while( (idx<cnt) && ( (result == EXACT_ANS) || (result == APPROX_ANS) ) ) {
175: result = capa_check_ans(ai,answers[idx]);
176: ai = ai->ans_next; idx++;
177: }
178: if(num_answer==2) printf("Answer:->%s [%s,%s] %s, ",p->answer,lower,upper,
179: p->unit_str);
180: else printf("Answer:->%s, ",lower);
181: switch(p->ans_type) {
182: case ANSWER_IS_INTEGER: printf(" INTEGER,");
183: break;
184: case ANSWER_IS_FLOAT:
185: printf(" FLOAT format=%s, SIG=[%d,%d],",
186: p->ans_fmt,p->sig_lbound,p->sig_ubound );
187: break;
188: case ANSWER_IS_STRING_CI: printf(" STRING C.I.,"); break;
189: case ANSWER_IS_STRING_CS: printf(" STRING C.S.,"); break;
190: case ANSWER_IS_CHOICE: printf(" CHOICE,"); break;
191: }
192: printf(" WEIGHT=%d, TRIES=%d\n", p->weight,p->tries); fflush(stdout);
193: if(p->ans_unit != NULL) {
194: print_unit_t(p->ans_unit); fflush(stdout);
195: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>