Annotation of capa/capa51/pProj/checkunits.c, revision 1.1.1.1
1.1 albertel 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>