Annotation of loncom/homework/inputtags.pm, revision 1.42
1.41 harris41 1: # The LON-CAPA input tags
2: #
3: # Input definitions.
4: #
5: # YEAR=2000
6: # 7/25,9/11,9/19,10/2,10/11,11/21,11/28,12/1,12/4,12/8,12/11 Guy Albertelli
7: # 12/12 Guy Albertelli
8: # 12/12 Gerd Kortemeyer
9: # 12/12,12/15,12/21 Guy Albertelli
10: # YEAR=2001
11: # 1/4,1/5,1/6,1/10,1/15,1/24,2/19 Guy Albertelli
1.42 ! harris41 12: # 8/6 Scott Harrison
1.1 albertel 13:
14: package Apache::inputtags;
15: use strict;
16:
1.41 harris41 17: # ======================================================================= BEGIN
1.1 albertel 18: sub BEGIN {
1.41 harris41 19: &Apache::lonxml::register('Apache::inputtags',
20: ('textarea','textline','datasubmission'));
1.1 albertel 21: }
22:
1.41 harris41 23: # ======================================================= Initialize input tags
1.1 albertel 24: sub initialize_inputtags {
1.41 harris41 25: # list of current input ids
26: @Apache::inputtags::input = ();
27: # list of all input ids seen in this problem
28: @Apache::inputtags::inputlist = ();
29: # list of all current response ids
30: @Apache::inputtags::response = ();
31: # list of all response ids seen in this problem
32: @Apache::inputtags::responselist = ();
33: # list of whether or not a specific response was previously used
34: @Apache::inputtags::previous = ();
35: # id of current part, 0 means no part is current (inside <problem> only
36: $Apache::inputtags::part = '';
37: # list of problem date statuses, the first element is for <problem>
38: #if there is a second element it is for the current <part>
39: @Apache::inputtags::status = ();
40: #hash of defined params for the current response
41: %Apache::inputtags::params = ();
1.1 albertel 42: }
43:
1.41 harris41 44: # ========================================== Start input (return scalar string)
1.14 albertel 45: sub start_input {
1.41 harris41 46: my ($parstack,$safeeval) = @_;
47: my $id = &Apache::lonxml::get_param('id',$parstack,$safeeval);
48: if ($id eq '') { $id = $Apache::lonxml::curdepth; }
49: push (@Apache::inputtags::input,$id);
50: push (@Apache::inputtags::inputlist,$id);
51: return $id;
1.14 albertel 52: }
53:
1.41 harris41 54: # =================================================================== End input
1.14 albertel 55: sub end_input {
1.41 harris41 56: pop @Apache::inputtags::input;
57: return '';
1.14 albertel 58: }
59:
1.41 harris41 60: # ====================================== Start text area (return scalar string)
1.6 albertel 61: sub start_textarea {
1.41 harris41 62: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
63: my $result = "";
64: my $id = &start_input($parstack,$safeeval);
65: if ($target eq 'web') {
66: my $oldresponse = $Apache::lonhomework::history{'resource.'.
67: $Apache::inputtags::part.'.'.
68: $Apache::inputtags::response['-1'].'.submission'};
69: my $cols = &Apache::lonxml::get_param('cols',$parstack,$safeeval);
70: if ( $cols eq '') { $cols = 80; }
71: my $rows = &Apache::lonxml::get_param('rows',$parstack,$safeeval);
72: if ( $rows eq '') { $rows = 10; }
73: $result= '<textarea name="HWVAL'.$Apache::inputtags::response['-1'].
74: '" '."rows=\"$rows\" cols=\"$cols\">".$oldresponse;
75: if ($oldresponse ne '') {
76: #get rid of any startup text if the user has already responded
77: &Apache::lonxml::get_all_text("/textarea",$$parser[$#$parser]);
78: }
1.30 albertel 79: }
1.41 harris41 80: return $result;
1.6 albertel 81: }
82:
1.41 harris41 83: # ======================================== End text area (return scalar string)
1.6 albertel 84: sub end_textarea {
1.41 harris41 85: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
86: if ($target eq 'web') {
87: return "</textarea>";
88: }
89: &end_input;
90: return '';
1.6 albertel 91: }
92:
1.41 harris41 93: # ====================================== Start text line (return scalar string)
1.1 albertel 94: sub start_textline {
1.41 harris41 95: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
96: my $result = "";
97: if ($target eq 'web') {
98: my $size = &Apache::lonxml::get_param('size',$parstack,$safeeval);
99: if ($size eq '') { $size=20; }
100: my $oldresponse = $Apache::lonhomework::history{'resource.'.
101: $Apache::inputtags::part.'.'.
102: $Apache::inputtags::response['-1'].'.submission'};
103: $result = '<input type="text" name="HWVAL'.
104: $Apache::inputtags::response['-1'].
105: '" value="'.$oldresponse.'" size="'.$size.'" />';
106: }
107: if ($target eq 'edit') {
108: $result .= &Apache::edit::tag_start($target,$token,
109: &Apache::lonxml::description($token));
110: $result .= &Apache::edit::text_arg('Size:','size',$token,'5').
111: '</td></tr>';
112: $result .= &Apache::edit::end_table;
113: }
114: if ($target eq 'modified') {
115: my $constructtag = &Apache::edit::get_new_args($token,$parstack,
116: $safeeval,'size');
117: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
118: }
119: return $result;
1.1 albertel 120: }
121:
1.41 harris41 122: # =============================================================== End text line
1.1 albertel 123: sub end_textline {
1.41 harris41 124: my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
125: if ($target eq 'edit') { return ('','no'); }
126: return "";
1.1 albertel 127: }
128:
1.41 harris41 129: # ======================================================= Start data submission
1.6 albertel 130: sub start_datasubmission {
1.41 harris41 131: return '';
1.6 albertel 132: }
133:
1.41 harris41 134: # ========================================================= End data submission
1.6 albertel 135: sub end_datasubmission {
1.41 harris41 136: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
137: if ( $target == 'web' ) {
138: return '<input type="submit" name="submit" value="Submit All Data" />';
139: }
140: return '';
1.9 albertel 141: }
142:
1.41 harris41 143: # ============================================================= Finalize awards
1.9 albertel 144: sub finalizeawards {
1.41 harris41 145: my $result='';
146: my $award;
147: if ($#_ == '-1') { $result = "NO_RESPONSE"; }
148: if ($result eq '' ) {
149: foreach $award (@_) { if ($award eq '') {$result='MISSING_ANSWER';
150: last;}}
151: }
152: if ($result eq '' ) {
153: foreach $award (@_) { if ($award eq 'ERROR') {$result='ERROR'; last;}}
154: }
155: if ($result eq '' ) {
156: foreach $award (@_) { if ($award eq 'NO_RESPONSE') {
157: $result='NO_RESPONSE'; last;} }
158: }
159: if ($result eq '' ) {
160: foreach $award (@_) {
161: if ($award eq 'UNIT_FAIL' ||
162: $award eq 'NO_UNIT' ||
163: $award eq 'UNIT_NOTNEEDED') {
164: $result=$award; last;
165: }
166: }
167: }
168: if ($result eq '' ) {
169: foreach $award (@_) {
170: if ($award eq 'WANTED_NUMERIC' ||
171: $award eq 'BAD_FORMULA') {$result=$award; last;}
172: }
173: }
174: if ($result eq '' ) {
175: foreach $award (@_) { if ($award eq 'SIG_FAIL') {
176: $result=$award; last;} }
177: }
178: if ($result eq '' ) {
179: foreach $award (@_) { if ($award eq 'INCORRECT') {$result=$award;
180: last;} }
181: }
182: if ($result eq '' ) {
183: foreach $award (@_) { if ($award eq 'SUBMITTED') {$result=$award;
184: last;} }
185: }
186: if ($result eq '' ) {
187: foreach $award (@_) { if ($award eq 'APPROX_ANS') {$result=$award;
188: last;} }
189: }
190: if ($result eq '' ) { $result='EXACT_ANS'; }
191: return $result;
1.9 albertel 192: }
193:
1.41 harris41 194: # ====================================== Decide output (return 3 element array)
1.10 albertel 195: sub decideoutput {
1.41 harris41 196: my ($award,$solved,$previous)=@_;
197: my $message='';
198: my $button=0;
199: my $previousmsg;
200:
201: if ($previous) { $previousmsg='You have entered that answer before'; }
202:
203: if ($solved =~ /^correct/) {
204: $message = "<b>You are correct.</b> Your receipt is ".
205: &Apache::lonnet::receipt;
206: $button=0;
207: $previousmsg='';
208: } elsif ($solved =~ /^excused/) {
209: $message = "<b>You are excused from the problem.</b>";
210: $button=0;
211: $previousmsg='';
212: } elsif ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS' ) {
213: if ($solved =~ /^incorrect/ || $solved eq '') {
214: $message = "Incorrect";
215: $button=1;
216: } else {
217: $message = "<b>You are correct.</b> Your receipt is ".
218: &Apache::lonnet::receipt;
219: $button=0;
220: $previousmsg='';
221: }
222: } elsif ($award eq 'NO_RESPONSE') {
223: $message = '';
224: $button=1;
225: } elsif ($award eq 'MISSING_ANSWER') {
226: $message = 'Some parts were not submitted';
227: $button = 1;
228: } elsif ($award eq 'WANTED_NUMERIC') {
229: $message = "This question expects a numeric answer";
230: $button=1;
231: } elsif ($award eq 'SIG_FAIL') {
232: $message = "Please adjust significant figures.";# you provided %s significant figures";
233: $button=1;
234: } elsif ($award eq 'UNIT_FAIL') {
235: $message = "Units incorrect."; #Computer reads units as %s";
236: $button=1;
237: } elsif ($award eq 'UNIT_NOTNEEDED') {
238: $message = "Only a number required.";# Computer reads units of %s";
239: $button=1;
240: } elsif ($award eq 'NO_UNIT') {
241: $message = "Units required";
242: $button=1;
243: } elsif ($award eq 'BAD_FORMULA') {
244: $message = "Unable to understand formula";
245: $button=1;
246: } elsif ($award eq 'INCORRECT') {
247: $message = "Incorrect";
248: $button=1;
249: } elsif ($award eq 'SUBMITTED') {
250: $message = "Your submission has been recorded.";
251: $button=1;
1.37 albertel 252: } else {
1.41 harris41 253: $message = "Unknown message: $award";
254: $button=1;
255: }
256: return ($button,$message,$previousmsg);
1.12 albertel 257: }
258:
1.41 harris41 259: # ============================================================== Set grade data
1.12 albertel 260: sub setgradedata {
1.41 harris41 261: my ($award,$id,$previously_used) = @_;
262: # if the student already has it correct, don't modify the status
263: if ( $Apache::lonhomework::history{"resource.$id.solved"} !~ /^correct/ ) {
264: #handle assignment of tries and solved status
265: if ( $award eq 'APPROX_ANS' || $award eq 'EXACT_ANS' ) {
266: $Apache::lonhomework::results{"resource.$id.tries"} =
267: $Apache::lonhomework::history{"resource.$id.tries"} + 1;
268: $Apache::lonhomework::results{"resource.$id.solved"} =
269: 'correct_by_student';
270: $Apache::lonhomework::results{"resource.$id.awarded"} = '1';
271: } elsif ( $award eq 'INCORRECT' ) {
272: $Apache::lonhomework::results{"resource.$id.tries"} =
273: $Apache::lonhomework::history{"resource.$id.tries"} + 1;
274: $Apache::lonhomework::results{"resource.$id.solved"} =
275: 'incorrect_attempted';
276: } elsif ( $award eq 'SUBMITTED' ) {
277: $Apache::lonhomework::results{"resource.$id.tries"} =
278: $Apache::lonhomework::history{"resource.$id.tries"} + 1;
279: $Apache::lonhomework::results{"resource.$id.solved"} =
280: 'ungraded_attempted';
281: } elsif ( $award eq 'NO_RESPONSE' ) {
282: return '';
283: } else {
284: $Apache::lonhomework::results{"resource.$id.solved"} =
285: 'incorrect_attempted';
286: }
287:
288: # check if this was a previous submission if it was delete the
289: # unneeded data and update the previously_used attribute
290: if ( $previously_used eq 'PREVIOUSLY_USED') {
291: delete($Apache::lonhomework::results{"resource.$id.tries"});
292: $Apache::lonhomework::results{"resource.$id.previous"} = '1';
293: } elsif ( $previously_used eq 'PREVIOUSLY_LAST') {
294: #delete all data as they student didn't do anything
295: foreach my $key (keys(%Apache::lonhomework::results)) {
296: if ($key =~ /^resource\.$id\./) {
297: &Apache::lonxml::debug("Removing $key");
298: delete($Apache::lonhomework::results{$key});
299: }
300: }
301: #and since they didn't do anything we were never here
302: return '';
303: } else {
304: $Apache::lonhomework::results{"resource.$id.previous"} = '0';
305: }
1.40 albertel 306: }
1.41 harris41 307: $Apache::lonhomework::results{"resource.$id.award"} = $award;
1.10 albertel 308: }
309:
1.41 harris41 310: # ======================================================================= Grade
1.9 albertel 311: sub grade {
1.41 harris41 312: my ($target) = @_;
313: my $id = $Apache::inputtags::part;
314: my $response = '';
315: if ( defined $ENV{'form.submitted'}) {
316: my @awards = ();
317: foreach $response (@Apache::inputtags::responselist) {
318: &Apache::lonxml::debug("looking for response.$id.$response.".
319: "awarddetail");
320: my $value=$Apache::lonhomework::results{"resource.$id.$response.".
321: "awarddetail"};
322: if ( $value ne '' ) {
323: &Apache::lonxml::debug("keeping $value from $response for".
324: " $id");
325: push (@awards,$value);
326: } else {
327: &Apache::lonxml::debug("skipping $value from $response for".
328: " $id");
329: }
330: }
331: my $finalaward = &finalizeawards(@awards);
332: my $previously_used;
333: if ( $#Apache::inputtags::previous eq $#awards ) {
334: $previously_used = 'PREVIOUSLY_LAST';
335: foreach my $value (@Apache::inputtags::previous) {
336: if ($value eq 'PREVIOUSLY_USED' ) {
337: $previously_used = $value;
338: last;
339: }
340: }
341: }
342: &Apache::lonxml::debug("final award $finalaward, $previously_used");
343: &setgradedata($finalaward,$id,$previously_used);
344: }
345: return '';
1.1 albertel 346: }
347:
1.41 harris41 348: # ========================================= Grade status (return scalar string)
1.11 albertel 349: sub gradestatus {
1.41 harris41 350: my ($id) = @_;
351: my $showbutton = 1;
352: my $message = '';
353: my $trystr = '';
354: my $button = '';
355: my $previousmsg = '';
356:
357: my $status = $Apache::inputtags::status['-1'];
358: &Apache::lonxml::debug("gradestatus has :$status:");
359: if ( $status ne 'CLOSED' ) {
360: my $award = $Apache::lonhomework::history{"resource.$id.award"};
361: my $solved = $Apache::lonhomework::history{"resource.$id.solved"};
362: my $previous = $Apache::lonhomework::history{"resource.$id.previous"};
363: &Apache::lonxml::debug("Found Award |$award|$solved|");
364: if ( $award ne '' ) {
365: &Apache::lonxml::debug('Getting message');
366: ($showbutton,$message,$previousmsg) =
367: &decideoutput($award,$solved,$previous);
368: $message = "<td bgcolor=\"#aaffaa\">$message</td>";
369: if ($previousmsg) {
370: $previousmsg = "<td bgcolor=\"#ffaaaa\">$previousmsg</td>";
371: }
372: }
373: my $tries = $Apache::lonhomework::history{"resource.$id.tries"};
374: my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
375: &Apache::lonxml::debug("got maxtries of :$maxtries:");
376: if ( $tries eq '' ) { $tries = '0'; }
377: if ( $maxtries eq '' ) { $maxtries = '2'; }
378: if ( $maxtries eq 'con_lost' ) { $maxtries = '0'; }
379: if ( $showbutton ) {
380: $trystr = "<td>Tries $tries/$maxtries</td>";
381: }
382: if ( $status eq 'SHOW_ANSWER' || $status eq 'CANNOT_ANSWER') {
383: $showbutton = 0;}
384: if ( $showbutton ) {
385: $button = '<br /><input type="submit" name="submit" value='.
386: '"Submit All Answers" />';
387: }
388: }
389: my $output= $previousmsg.$message.$trystr;
390: if ($output =~ /^\s*$/) {
391: return $button;
392: } else {
393: return $button.'<table><tr>'.$previousmsg.$message.$trystr.
394: '</tr></table>';
395: }
1.11 albertel 396: }
1.41 harris41 397:
1.1 albertel 398: 1;
1.41 harris41 399:
1.1 albertel 400: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>