1: # The LearningOnline Network with CAPA
2: # implements the tags that control the hints
3: #
4: # $Id: hint.pm,v 1.73 2008/11/19 18:34:56 jms Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA me&aree software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
29: =head1 NAME
30:
31: Apache::hinttags
32:
33: =head1 SYNOPSIS
34:
35: This handler coordinates the delivery of hints to students working on LON-CAPA problems and assignments.
36:
37: This is part of the LearningOnline Network with CAPA project
38: described at http://www.lon-capa.org.
39:
40: =head1 SUBROUTINES
41:
42: =over
43:
44: =item start_hintgroup()
45:
46: =item end_hintgroup()
47:
48: =item start_numericalhint()
49:
50: =item end_numericalhint()
51:
52: =item start_formulahint()
53:
54: =item end_formulahint()
55:
56: =item start_mathhint()
57:
58: =item end_mathhint()
59:
60: =item start_customhint()
61:
62: =item end_customhint()
63:
64: =item start_stringhint()
65:
66: =item end_stringhint()
67:
68: =item start_hintpart()
69:
70: =item end_hintpart()
71:
72: =item start_optionhint()
73:
74: =item end_optionhint()
75:
76: =item start_radiobuttonhint()
77:
78: =item end_radiobuttonhint()
79:
80: =back
81:
82: =cut
83:
84: package Apache::hinttags;
85:
86: use strict;
87: use Apache::lonnet();
88: use capa;
89: use Apache::caparesponse();
90: use Apache::lonmaxima();
91: use Apache::response();
92: use Apache::lonlocal;
93: use Storable qw(dclone);
94:
95: BEGIN {
96: &Apache::lonxml::register('Apache::hinttags',('hintgroup','hintpart','numericalhint','stringhint','formulahint','optionhint','radiobuttonhint','mathhint','customhint'));
97: }
98:
99:
100: @Apache::hint::which=();
101: sub start_hintgroup {
102: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
103: my $skiptoend='0';
104: my $result;
105:
106: if ($target eq 'web') {
107: my $id=$Apache::inputtags::part;
108: my $numtries=$Apache::lonhomework::history{"resource.$id.tries"};
109: if ( $numtries eq '') { $numtries = 0; }
110: my $hinttries=&Apache::response::get_response_param($id,"hinttries",1);
111: &Apache::lonxml::debug("found :$id:$numtries:$hinttries:");
112: my $gradestatus=
113: $Apache::lonhomework::history{"resource.$id.solved"};
114: my $showoncorrect=lc(&Apache::lonxml::get_param('showoncorrect',$parstack,$safeeval));
115: &Apache::lonxml::debug("onc orrect $showoncorrect, $gradestatus");
116: if ( ($showoncorrect ne 'yes' && &Apache::response::show_answer()) ||
117: ( $numtries < $hinttries) ) {
118: &Apache::lonxml::debug("Grabbin all");
119: &Apache::lonxml::get_all_text("/hintgroup",$parser,$style);
120: }
121: &Apache::lonxml::startredirection;
122: } elsif ($target eq 'tex') {
123: $result .= '\keephidden{';
124: } elsif ($target eq 'edit') {
125: $result.=&Apache::edit::tag_start($target,$token);
126: $result.=&Apache::edit::select_arg('Show hint even if problem Correct:','showoncorrect',['no','yes'],$token);
127: $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
128: } elsif ($target eq 'modified') {
129: my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,'showoncorrect');
130: if ($constructtag) {
131: $result =&Apache::edit::rebuild_tag($token);
132: }
133: }
134: @Apache::hint::which=();
135: return $result;
136: }
137:
138: sub end_hintgroup {
139: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
140: my $result;
141:
142: if ($target eq 'web') {
143: my $id=$Apache::inputtags::part;
144: my $numtries=$Apache::lonhomework::history{"resource.$id.tries"};
145: if ( $numtries eq '') { $numtries = 0; }
146: my $hinttries=&Apache::response::get_response_param($id,"hinttries",1);
147: &Apache::lonxml::debug("found :$id:$numtries:$hinttries:");
148: my $hinttext=&Apache::lonxml::endredirection;
149: if ($Apache::lonhomework::type ne 'exam' &&
150: $numtries >= $hinttries && $hinttext =~/\S/) {
151: $result='<table bgcolor="#dddddd"><tr><td>'.
152: $hinttext.'</td></tr></table>';
153: }
154: } elsif ($target eq 'edit') {
155: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
156: } elsif ($target eq 'tex') {
157: $result .= '}';
158: }
159: @Apache::hint::which=();
160: return $result;
161: }
162:
163: sub start_numericalhint {
164: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
165: #do everything in end, so intervening <responseparams> work
166: &Apache::response::start_hintresponse($parstack,$safeeval);
167: &Apache::caparesponse::push_answer();
168: my $result;
169: if ($target eq 'edit') {
170: $result.=&Apache::edit::tag_start($target,$token);
171: $result.=&Apache::edit::text_arg('Name:','name',$token);
172: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
173: if ($token->[1] eq 'numericalhint') {
174: $result.=&Apache::edit::text_arg('Unit:','unit',$token,5).
175: &Apache::loncommon::help_open_topic('Physical_Units');
176: $result.=&Apache::edit::text_arg('Format:','format',$token,4).
177: &Apache::loncommon::help_open_topic('Numerical_Response_Format');
178: } elsif ($token->[1] eq 'formulahint') {
179: $result.=&Apache::edit::text_arg('Sample Points:','samples',
180: $token,40).
181: &Apache::loncommon::help_open_topic('Formula_Response_Sampling');
182: }
183: $result.=&Apache::edit::end_row();
184: $result.=&Apache::edit::start_spanning_row();
185: } elsif ($target eq 'modified') {
186: my $constructtag;
187: if ($token->[1] eq 'numericalhint') {
188: $constructtag=&Apache::edit::get_new_args($token,$parstack,
189: $safeeval,'name',
190: 'answer','unit','format');
191: } elsif ($token->[1] eq 'formulahint') {
192: $constructtag=&Apache::edit::get_new_args($token,$parstack,
193: $safeeval,'name','answer',
194: 'samples');
195: }
196: if ($constructtag) {
197: $result = &Apache::edit::rebuild_tag($token);
198: }
199: } elsif ($target eq 'web') {
200: &Apache::response::reset_params();
201: }
202: return $result;
203: }
204:
205: sub end_numericalhint {
206: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
207: my $result;
208: if ($target eq 'web') {
209: if (!$Apache::lonxml::default_homework_loaded) {
210: &Apache::lonxml::default_homework_load($safeeval);
211: }
212: $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
213: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
214: &Apache::response::setup_params('numericalhint',$safeeval);
215:
216: my $partid=$Apache::inputtags::part;
217: my $id=$Apache::inputtags::hint[-1];
218: #id submissions occurred under
219: my $submitid=$Apache::inputtags::response[-1];
220:
221: my $response = $Apache::lonhomework::history{
222: "resource.$partid.$submitid.submission"};
223: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
224:
225: my @args = ('type','tol','sig','ans_fmt','unit','calc','samples');
226: my $args_ref =
227: &Apache::caparesponse::setup_capa_args($safeeval,$parstack,
228: \@args,$response);
229:
230: my $hideunit=&Apache::response::get_response_param($partid.'_'.$submitid,'turnoffunit');
231: if (lc($hideunit) eq "yes") { delete($$args_ref{'unit'}); }
232:
233: if ($$tagstack[-1] eq 'formulahint') {
234: if ($$args_ref{'samples'}) {
235: $$args_ref{'type'}='fml';
236: } else {
237: $$args_ref{'type'}='math';
238: }
239: } elsif ($$tagstack[-1] eq 'numericalhint') {
240: $$args_ref{'type'}='float';
241: }
242: &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval);
243: my %answer = &Apache::caparesponse::get_answer();
244: my (@final_awards,@final_msgs,@ans_names);
245: foreach my $ans_name (keys(%answer)) {
246: &Apache::lonxml::debug(" doing $ans_name with ".join(':',@{ $answer{$ans_name}{'answers'} }));
247:
248: ${$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=
249: dclone($answer{$ans_name});
250: &Apache::caparesponse::setup_capa_response($args_ref,$response);
251: my ($result,@msgs) =
252: &Apache::run::run("&caparesponse_check_list()",$safeeval);
253: &Apache::lonxml::debug("checking $ans_name $result with $response");
254: &Apache::lonxml::debug('msgs are '.join(':',@msgs));
255: my ($awards)=split(/:/,$result);
256: my @awards= split(/,/,$awards);
257: my ($ad, $msg) =
258: &Apache::inputtags::finalizeawards(\@awards,\@msgs);
259: push(@final_awards,$ad);
260: push(@final_msgs,$msg);
261: push(@ans_names,$ans_name);
262: }
263: my ($ad, $msg, $ans_name) =
264: &Apache::inputtags::finalizeawards(\@final_awards,
265: \@final_msgs,
266: \@ans_names,1);
267: if ($ad eq 'EXACT_ANS' || $ad eq 'APPROX_ANS') {
268: push(@Apache::hint::which,$hint_name);
269: }
270: $result='';
271: } elsif ($target eq 'meta') {
272: $result=&Apache::response::meta_package_write($token->[1]);
273: } elsif ($target eq 'edit') {
274: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
275: }
276: &Apache::caparesponse::pop_answer();
277: &Apache::response::end_hintresponse();
278: return $result;
279: }
280:
281: sub start_formulahint {
282: return &start_numericalhint(@_);
283: }
284:
285: sub end_formulahint {
286: return &end_numericalhint(@_);
287: }
288:
289: sub start_mathhint {
290: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
291: #do everything in end, so intervening <responseparams> and <answer> work
292: &Apache::response::start_hintresponse($parstack,$safeeval);
293: &Apache::lonxml::register('Apache::response',('answer'));
294: my $result;
295: if ($target eq 'edit') {
296: $result.=&Apache::edit::tag_start($target,$token);
297: $result.=&Apache::edit::text_arg('Name:','name',$token);
298: $result.=&Apache::edit::select_arg('Algebra System:',
299: 'cas',
300: ['maxima'],
301: $token);
302: $result.=&Apache::edit::text_arg('Argument Array:',
303: 'args',$token);
304: $result.=&Apache::edit::end_row();
305: $result.=&Apache::edit::start_spanning_row();
306: } elsif ($target eq 'modified') {
307: my $constructtag;
308: $constructtag=&Apache::edit::get_new_args($token,$parstack,
309: $safeeval,'name','cas',
310: 'args');
311: $result = &Apache::edit::rebuild_tag($token);
312: } elsif ($target eq 'web') {
313: &Apache::response::reset_params();
314: }
315: return $result;
316: }
317:
318: sub end_mathhint {
319: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
320: my $result;
321: if ($target eq 'web') {
322: if (!$Apache::lonxml::default_homework_loaded) {
323: &Apache::lonxml::default_homework_load($safeeval);
324: }
325: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
326: &Apache::response::setup_params('mathhint',$safeeval);
327: my $partid=$Apache::inputtags::part;
328: my $submitid=$Apache::inputtags::response[-1];
329: my $response = $Apache::lonhomework::history{
330: "resource.$partid.$submitid.submission"};
331:
332: my $cas = &Apache::lonxml::get_param('cas',$parstack,$safeeval);
333: my $award;
334: if ($cas eq 'maxima') {
335: my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)];
336: $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args);
337: }
338: if ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS') {
339: push (@Apache::hint::which,$name);
340: }
341: $result='';
342: } elsif ($target eq 'meta') {
343: $result=&Apache::response::meta_package_write($token->[1]);
344: } elsif ($target eq 'edit') {
345: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
346: }
347: pop(@Apache::response::custom_answer);
348: pop(@Apache::response::custom_answer_type);
349: &Apache::response::end_hintresponse();
350: return $result;
351: }
352:
353: sub start_customhint {
354: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
355: #do everything in end, so intervening <responseparams> and <answer> work
356: &Apache::response::start_hintresponse($parstack,$safeeval);
357: &Apache::lonxml::register('Apache::response',('answer'));
358: my $result;
359: if ($target eq 'edit') {
360: $result.=&Apache::edit::tag_start($target,$token);
361: $result.=&Apache::edit::text_arg('Name:','name',$token);
362: $result.=&Apache::edit::end_row();
363: $result.=&Apache::edit::start_spanning_row();
364: } elsif ($target eq 'modified') {
365: my $constructtag;
366: $constructtag=&Apache::edit::get_new_args($token,$parstack,
367: $safeeval,'name');
368: $result = &Apache::edit::rebuild_tag($token);
369: } elsif ($target eq 'web') {
370: &Apache::response::reset_params();
371: }
372: return $result;
373: }
374:
375: sub end_customhint {
376: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
377: my $result;
378: if ($target eq 'web') {
379: if (!$Apache::lonxml::default_homework_loaded) {
380: &Apache::lonxml::default_homework_load($safeeval);
381: }
382: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
383: &Apache::response::setup_params('customhint',$safeeval);
384: my $partid=$Apache::inputtags::part;
385: my $submitid=$Apache::inputtags::response[-1];
386: my $response = $Apache::lonhomework::history{
387: "resource.$partid.$submitid.submission"};
388: my $award;
389: if ( $response =~ /[^\s]/ &&
390: $Apache::response::custom_answer_type[-1] eq 'loncapa/perl') {
391: if (!$Apache::lonxml::default_homework_loaded) {
392: &Apache::lonxml::default_homework_load($safeeval);
393: }
394: ${$safeeval->varglob('LONCAPA::customresponse_submission')}=
395: $response;
396:
397: $award = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer[-1].'}',$safeeval);
398: }
399: if ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS') {
400: push (@Apache::hint::which,$name);
401: }
402: $result='';
403: } elsif ($target eq 'meta') {
404: $result=&Apache::response::meta_package_write($token->[1]);
405: } elsif ($target eq 'edit') {
406: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
407: }
408: pop(@Apache::response::custom_answer);
409: pop(@Apache::response::custom_answer_type);
410: &Apache::response::end_hintresponse();
411: return $result;
412: }
413:
414: sub start_stringhint {
415: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
416: #do everything in end, so intervening <responseparams> work
417: &Apache::response::start_hintresponse($parstack,$safeeval);
418: my $result;
419: if ($target eq 'edit') {
420: $result.=&Apache::edit::tag_start($target,$token);
421: $result.=&Apache::edit::text_arg('Name:','name',$token);
422: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
423: $result.=&Apache::edit::select_arg('Type:','type',
424: [['cs','Case Sensitive'],['ci','Case Insensitive'],
425: ['mc','Case Insensitive, Any Order'],
426: ['re','Regular Expression']],$token);
427: $result.=&Apache::edit::end_row();
428: $result.=&Apache::edit::start_spanning_row();
429: } elsif ($target eq 'modified') {
430: my $constructtag;
431: $constructtag=&Apache::edit::get_new_args($token,$parstack,
432: $safeeval,'name','answer',
433: 'type');
434: $result = &Apache::edit::rebuild_tag($token);
435: } elsif ($target eq 'web') {
436: &Apache::response::reset_params();
437: }
438: return $result;
439: }
440:
441: sub end_stringhint {
442: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
443: my $result;
444: if ($target eq 'web') {
445: if (!$Apache::lonxml::default_homework_loaded) {
446: &Apache::lonxml::default_homework_load($safeeval);
447: }
448: $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
449: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
450: &Apache::response::setup_params('stringhint',$safeeval);
451: my $partid=$Apache::inputtags::part;
452: my $id=$Apache::inputtags::hint[-1];
453: #id submissions occurred under
454: my $submitid=$Apache::inputtags::response[-1];
455: my $response = $Apache::lonhomework::history{
456: "resource.$partid.$submitid.submission"};
457: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
458: my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
459: my ($ad,$msg);
460: if ($type eq 're' ) {
461: my $answer=&Apache::lonxml::get_param('answer',$parstack,
462: $safeeval);
463: ${$safeeval->varglob('LONCAPA::response')}=$response;
464: my $compare='=';
465: if ($answer=~/^\s*NOT\s*/) {
466: $answer=~s/^\s*NOT\s*//;
467: $compare='!';
468: }
469: my $test='$LONCAPA::response'.$compare.'~m'.$answer;
470: &Apache::lonxml::debug("test $test");
471: $result = &Apache::run::run("return $test",$safeeval);
472: &Apache::lonxml::debug("current $response");
473: &Apache::lonxml::debug("current $answer");
474: $ad = ($result) ? 'APPROX_ANS' : 'INCORRECT';
475: } else {
476: my @args = ('type');
477: my $args_ref =
478: &Apache::caparesponse::setup_capa_args($safeeval,$parstack,
479: \@args,$response);
480: if ($$args_ref{'type'} eq '') {
481: $$args_ref{'type'} = 'ci';
482: }
483: &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval);
484: my (@final_awards,@final_msgs,@ans_names);
485: my %answer = &Apache::caparesponse::get_answer();
486: foreach my $ans_name (keys(%answer)) {
487: &Apache::lonxml::debug(" doing $ans_name with ".join(':',@{ $answer{$ans_name}{'answers'} }));
488: ${$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=dclone($answer{$ans_name});
489: my ($result, @msgs)=&Apache::run::run("&caparesponse_check_list()",$safeeval);
490: &Apache::lonxml::debug('msgs are'.join(':',@msgs));
491: my ($awards) = split(/:/,$result);
492: my (@awards) = split(/,/,$awards);
493: ($ad,$msg) =
494: &Apache::inputtags::finalizeawards(\@awards,\@msgs);
495: push(@final_awards,$ad);
496: push(@final_msgs,$msg);
497: push(@ans_names,$ans_name);
498: &Apache::lonxml::debug("\n<br>result:$result:$Apache::lonxml::curdepth<br>\n");
499: }
500: my ($ad, $msg, $ans_name) =
501: &Apache::inputtags::finalizeawards(\@final_awards,
502: \@final_msgs,
503: \@ans_names,1);
504: }
505: if ($ad eq 'EXACT_ANS' || $ad eq 'APPROX_ANS') {
506: push(@Apache::hint::which,$hint_name);
507: }
508: $result='';
509: } elsif ($target eq 'meta') {
510: $result=&Apache::response::meta_package_write($token->[1]);
511: } elsif ($target eq 'edit') {
512: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
513: }
514: &Apache::response::end_hintresponse();
515: return $result;
516: }
517:
518: # a part shows if it is on, if no specific parts are on, then default shows
519: sub start_hintpart {
520: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
521:
522: my $show ='0';
523: my $result = '';
524: if ($target eq 'web') {
525: my $on= &Apache::lonxml::get_param('on',$parstack,$safeeval);
526: &Apache::lonxml::debug("hintpart sees $on and ,$#Apache::hint::which");
527: if ( $on eq 'default' && $#Apache::hint::which == '-1') {
528: $show=1;
529: } else {
530: my $which;
531: foreach $which (@Apache::hint::which) { if ($which eq $on) { $show = 1; last } }
532: }
533: if (!$show) {
534: &Apache::lonxml::get_all_text("/hintpart",$parser,$style);
535: }
536: } elsif ($target eq 'grade') {
537: &Apache::lonxml::get_all_text("/hintpart",$parser,$style);
538: } elsif ($target eq 'edit') {
539: $result.= &Apache::edit::tag_start($target,$token);
540: $result.= &Apache::edit::text_arg('On:','on',$token);
541: $result.= &Apache::edit::end_row();
542: $result.= &Apache::edit::start_spanning_row();
543: } elsif ($target eq 'modified') {
544: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
545: $safeeval,'on');
546: if ($constructtag) {
547: $result = &Apache::edit::rebuild_tag($token);
548: }
549: }
550: return $result;
551: }
552:
553: sub end_hintpart {
554: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
555: my $result;
556: if ($target eq 'edit') {
557: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
558: }
559: return $result;
560: }
561:
562: sub start_optionhint {
563: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
564: my $result;
565: &Apache::response::start_hintresponse($parstack,$safeeval);
566: if ($target eq 'edit') {
567: $result.=&Apache::edit::tag_start($target,$token);
568: $result.=&Apache::edit::text_arg('Name:','name',$token);
569: $result.=&Apache::edit::text_arg('Answer:','answer',$token,40);
570: $result.=&Apache::edit::text_arg('Concept:','concept',$token,50);
571: } elsif ($target eq 'modified') {
572: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
573: $safeeval,'name',
574: 'answer','concept');
575: if ($constructtag) {
576: $result = &Apache::edit::rebuild_tag($token);
577: }
578: } elsif ($target eq 'meta') {
579: $result=&Apache::response::meta_package_write('numericalhint');
580: }
581: return $result;
582: }
583:
584: sub end_optionhint {
585: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
586: my $result;
587: if ($target eq 'web') {
588: my ($foilmatch,$conceptmatch)=(-1,-1);
589: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
590: my $partid=$Apache::inputtags::part;
591: #id submissions occurred under
592: my $submitid=$Apache::inputtags::response[-1];
593: my $part_id="$partid.$submitid";
594: my %answer;
595: my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
596: if ($answer) {
597: eval('%answer ='.$answer);
598: &Apache::lonxml::debug("answwer hash");
599: &Apache::lonhomework::showhash(%answer);
600: my $response = $Apache::lonhomework::history{
601: "resource.$part_id.submission"};
602: my %response=&Apache::lonnet::str2hash($response);
603: &Apache::lonhomework::showhash(%response);
604: foreach my $foil (keys(%answer)) {
605: $foilmatch=1;
606: if ($answer{$foil} ne $response{$foil}) {$foilmatch=0;last;}
607: }
608: }
609: my %concept;
610: my $constr=&Apache::lonxml::get_param('concept',$parstack,$safeeval);
611: if ( $constr ) { eval('%concept ='.$constr); }
612: my $response = $Apache::lonhomework::history{
613: "resource.$part_id.submissiongrading"};
614: my %response=&Apache::lonnet::str2hash($response);
615: foreach my $concept (keys(%concept)) {
616: my $compare;
617: if ($concept{$concept} eq 'correct') {$compare=1}else{$compare=0}
618: $conceptmatch=1;
619: if (ref($Apache::hint::option{"$part_id.concepts"})) {
620: foreach my $foil (@{ $Apache::hint::option{"$part_id.concept.$concept"} }) {
621: &Apache::lonxml::debug("compare -$foil- -$response{$foil}-$compare-");
622: if ( exists($response{$foil}) &&
623: $response{$foil} ne $compare) {$conceptmatch=0;last;}
624: }
625: } else {
626: $conceptmatch=0;
627: }
628: if ($conceptmatch eq '0') { last; }
629: }
630: if ( ($conceptmatch eq '-1' || $conceptmatch eq '1') &&
631: ($foilmatch eq '-1' || $foilmatch eq '1') ) {
632: push(@Apache::hint::which,$name);
633: }
634: } elsif ($target eq 'edit') {
635: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
636: }
637: &Apache::response::end_hintresponse();
638: return $result;
639: }
640:
641: sub start_radiobuttonhint {
642: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
643: my $result;
644: &Apache::response::start_hintresponse($parstack,$safeeval);
645: if ($target eq 'edit') {
646: $result.=&Apache::edit::tag_start($target,$token);
647: $result.=&Apache::edit::text_arg('Name:','name',$token);
648: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
649: } elsif ($target eq 'modified') {
650: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
651: $safeeval,'name',
652: 'answer');
653: if ($constructtag) {
654: $result = &Apache::edit::rebuild_tag($token);
655: }
656: } elsif ($target eq 'meta') {
657: $result=&Apache::response::meta_package_write('numericalhint');
658: }
659: return $result;
660: }
661:
662: sub end_radiobuttonhint {
663: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
664: my $result;
665: if ($target eq 'web') {
666: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
667: my @answer;
668: my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
669: eval('@answer ='.$answer);
670: my $partid=$Apache::inputtags::part;
671: #id submissions occurred under
672: my $submitid=$Apache::inputtags::response[-1];
673: my $part_id="$partid.$submitid";
674: my $response = $Apache::lonhomework::history{
675: "resource.$part_id.submission"};
676: ($response)=&Apache::lonnet::str2hash($response);
677: &Apache::lonxml::debug("response is $response");
678:
679: if ($answer[0] eq 'foil') {
680: shift(@answer);
681: foreach my $answer (@answer) {
682: if ($response eq $answer) {
683: push (@Apache::hint::which,$name);
684: last;
685: }
686: }
687: } elsif ($answer[0] eq 'concept') {
688: shift(@answer);
689: foreach my $answer (@answer) {
690: if (ref($Apache::hint::radiobutton{"$part_id.concept.".$answer})) {
691: my @names=@{ $Apache::hint::radiobutton{"$part_id.concept.".$answer} };
692: if (grep(/^\Q$response\E$/,@names)) {
693: push(@Apache::hint::which,$name);
694: last;
695: }
696: }
697: }
698: }
699: } elsif ($target eq 'edit') {
700: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
701: }
702: &Apache::response::end_hintresponse();
703: return $result;
704: }
705: 1;
706: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>