Annotation of loncom/homework/hint.pm, revision 1.76
1.21 albertel 1: # The LearningOnline Network with CAPA
2: # implements the tags that control the hints
3: #
1.76 ! www 4: # $Id: hint.pm,v 1.75 2009/04/17 01:00:15 www Exp $
1.21 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
1.33 albertel 10: # LON-CAPA me&aree software; you can redistribute it and/or modify
1.21 albertel 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:
1.73 jms 29:
30:
1.1 albertel 31: package Apache::hinttags;
32:
33: use strict;
1.65 albertel 34: use Apache::lonnet();
1.6 albertel 35: use capa;
1.65 albertel 36: use Apache::caparesponse();
1.63 www 37: use Apache::lonmaxima();
1.75 www 38: use Apache::lonr();
1.76 ! www 39: use Apache::chemresponse();
1.63 www 40: use Apache::response();
1.53 albertel 41: use Apache::lonlocal;
1.65 albertel 42: use Storable qw(dclone);
1.1 albertel 43:
1.25 harris41 44: BEGIN {
1.76 ! www 45: &Apache::lonxml::register('Apache::hinttags',('hintgroup','hintpart','numericalhint','stringhint','formulahint','optionhint','radiobuttonhint','mathhint','customhint','reactionhint','organichint'));
1.1 albertel 46: }
47:
1.2 albertel 48:
1.15 albertel 49: @Apache::hint::which=();
1.1 albertel 50: sub start_hintgroup {
1.39 albertel 51: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
52: my $skiptoend='0';
53: my $result;
54:
55: if ($target eq 'web') {
56: my $id=$Apache::inputtags::part;
57: my $numtries=$Apache::lonhomework::history{"resource.$id.tries"};
58: if ( $numtries eq '') { $numtries = 0; }
1.52 albertel 59: my $hinttries=&Apache::response::get_response_param($id,"hinttries",1);
1.39 albertel 60: &Apache::lonxml::debug("found :$id:$numtries:$hinttries:");
1.53 albertel 61: my $gradestatus=
62: $Apache::lonhomework::history{"resource.$id.solved"};
63: my $showoncorrect=lc(&Apache::lonxml::get_param('showoncorrect',$parstack,$safeeval));
64: &Apache::lonxml::debug("onc orrect $showoncorrect, $gradestatus");
1.58 albertel 65: if ( ($showoncorrect ne 'yes' && &Apache::response::show_answer()) ||
1.53 albertel 66: ( $numtries < $hinttries) ) {
67: &Apache::lonxml::debug("Grabbin all");
1.61 albertel 68: &Apache::lonxml::get_all_text("/hintgroup",$parser,$style);
1.39 albertel 69: }
1.40 albertel 70: &Apache::lonxml::startredirection;
1.39 albertel 71: } elsif ($target eq 'tex') {
72: $result .= '\keephidden{';
1.53 albertel 73: } elsif ($target eq 'edit') {
74: $result.=&Apache::edit::tag_start($target,$token);
1.72 bisitz 75: $result.=&Apache::edit::select_arg('Show hint even if problem Correct:','showoncorrect',['no','yes'],$token);
1.53 albertel 76: $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
77: } elsif ($target eq 'modified') {
78: my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,'showoncorrect');
79: if ($constructtag) {
80: $result =&Apache::edit::rebuild_tag($token);
81: }
1.20 albertel 82: }
1.39 albertel 83: @Apache::hint::which=();
84: return $result;
1.1 albertel 85: }
86:
87: sub end_hintgroup {
1.39 albertel 88: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
89: my $result;
1.20 albertel 90:
1.39 albertel 91: if ($target eq 'web') {
92: my $id=$Apache::inputtags::part;
93: my $numtries=$Apache::lonhomework::history{"resource.$id.tries"};
94: if ( $numtries eq '') { $numtries = 0; }
1.52 albertel 95: my $hinttries=&Apache::response::get_response_param($id,"hinttries",1);
1.39 albertel 96: &Apache::lonxml::debug("found :$id:$numtries:$hinttries:");
1.40 albertel 97: my $hinttext=&Apache::lonxml::endredirection;
98: if ($Apache::lonhomework::type ne 'exam' &&
1.41 albertel 99: $numtries >= $hinttries && $hinttext =~/\S/) {
1.40 albertel 100: $result='<table bgcolor="#dddddd"><tr><td>'.
101: $hinttext.'</td></tr></table>';
1.38 albertel 102: }
1.39 albertel 103: } elsif ($target eq 'edit') {
1.62 albertel 104: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
1.39 albertel 105: } elsif ($target eq 'tex') {
106: $result .= '}';
1.19 albertel 107: }
1.39 albertel 108: @Apache::hint::which=();
109: return $result;
1.3 albertel 110: }
111:
112: sub start_numericalhint {
1.39 albertel 113: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
114: #do everything in end, so intervening <responseparams> work
115: &Apache::response::start_hintresponse($parstack,$safeeval);
1.66 albertel 116: &Apache::caparesponse::push_answer();
1.39 albertel 117: my $result;
118: if ($target eq 'edit') {
119: $result.=&Apache::edit::tag_start($target,$token);
120: $result.=&Apache::edit::text_arg('Name:','name',$token);
121: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
122: if ($token->[1] eq 'numericalhint') {
123: $result.=&Apache::edit::text_arg('Unit:','unit',$token,5).
124: &Apache::loncommon::help_open_topic('Physical_Units');
125: $result.=&Apache::edit::text_arg('Format:','format',$token,4).
126: &Apache::loncommon::help_open_topic('Numerical_Response_Format');
127: } elsif ($token->[1] eq 'formulahint') {
1.65 albertel 128: $result.=&Apache::edit::text_arg('Sample Points:','samples',
129: $token,40).
130: &Apache::loncommon::help_open_topic('Formula_Response_Sampling');
1.39 albertel 131: }
132: $result.=&Apache::edit::end_row();
133: $result.=&Apache::edit::start_spanning_row();
134: } elsif ($target eq 'modified') {
135: my $constructtag;
136: if ($token->[1] eq 'numericalhint') {
137: $constructtag=&Apache::edit::get_new_args($token,$parstack,
138: $safeeval,'name',
139: 'answer','unit','format');
140: } elsif ($token->[1] eq 'formulahint') {
141: $constructtag=&Apache::edit::get_new_args($token,$parstack,
142: $safeeval,'name','answer',
143: 'samples');
144: }
145: if ($constructtag) {
146: $result = &Apache::edit::rebuild_tag($token);
147: }
148: } elsif ($target eq 'web') {
149: &Apache::response::reset_params();
1.28 albertel 150: }
1.39 albertel 151: return $result;
1.3 albertel 152: }
153:
154: sub end_numericalhint {
1.39 albertel 155: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
156: my $result;
157: if ($target eq 'web') {
158: if (!$Apache::lonxml::default_homework_loaded) {
159: &Apache::lonxml::default_homework_load($safeeval);
160: }
161: $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
1.65 albertel 162: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
1.48 albertel 163: &Apache::response::setup_params('numericalhint',$safeeval);
1.65 albertel 164:
1.39 albertel 165: my $partid=$Apache::inputtags::part;
1.60 albertel 166: my $id=$Apache::inputtags::hint[-1];
1.69 bisitz 167: #id submissions occurred under
1.60 albertel 168: my $submitid=$Apache::inputtags::response[-1];
1.65 albertel 169:
1.39 albertel 170: my $response = $Apache::lonhomework::history{
1.18 albertel 171: "resource.$partid.$submitid.submission"};
1.39 albertel 172: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
1.65 albertel 173:
174: my @args = ('type','tol','sig','ans_fmt','unit','calc','samples');
175: my $args_ref =
176: &Apache::caparesponse::setup_capa_args($safeeval,$parstack,
177: \@args,$response);
178:
1.54 albertel 179: my $hideunit=&Apache::response::get_response_param($partid.'_'.$submitid,'turnoffunit');
1.51 albertel 180: if (lc($hideunit) eq "yes") { delete($$args_ref{'unit'}); }
1.65 albertel 181:
1.43 albertel 182: if ($$tagstack[-1] eq 'formulahint') {
1.67 www 183: if ($$args_ref{'samples'}) {
184: $$args_ref{'type'}='fml';
185: } else {
186: $$args_ref{'type'}='math';
187: }
1.43 albertel 188: } elsif ($$tagstack[-1] eq 'numericalhint') {
1.51 albertel 189: $$args_ref{'type'}='float';
1.39 albertel 190: }
1.65 albertel 191: &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval);
192: my %answer = &Apache::caparesponse::get_answer();
193: my (@final_awards,@final_msgs,@ans_names);
194: foreach my $ans_name (keys(%answer)) {
195: &Apache::lonxml::debug(" doing $ans_name with ".join(':',@{ $answer{$ans_name}{'answers'} }));
196:
197: ${$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=
198: dclone($answer{$ans_name});
199: &Apache::caparesponse::setup_capa_response($args_ref,$response);
200: my ($result,@msgs) =
1.71 raeburn 201: &Apache::run::run("&caparesponse_check_list()",$safeeval);
1.65 albertel 202: &Apache::lonxml::debug("checking $ans_name $result with $response");
203: &Apache::lonxml::debug('msgs are '.join(':',@msgs));
204: my ($awards)=split(/:/,$result);
205: my @awards= split(/,/,$awards);
206: my ($ad, $msg) =
207: &Apache::inputtags::finalizeawards(\@awards,\@msgs);
208: push(@final_awards,$ad);
209: push(@final_msgs,$msg);
210: push(@ans_names,$ans_name);
211: }
212: my ($ad, $msg, $ans_name) =
213: &Apache::inputtags::finalizeawards(\@final_awards,
214: \@final_msgs,
215: \@ans_names,1);
216: if ($ad eq 'EXACT_ANS' || $ad eq 'APPROX_ANS') {
217: push(@Apache::hint::which,$hint_name);
218: }
1.39 albertel 219: $result='';
220: } elsif ($target eq 'meta') {
221: $result=&Apache::response::meta_package_write($token->[1]);
222: } elsif ($target eq 'edit') {
1.62 albertel 223: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
1.18 albertel 224: }
1.66 albertel 225: &Apache::caparesponse::pop_answer();
1.39 albertel 226: &Apache::response::end_hintresponse();
227: return $result;
1.28 albertel 228: }
229:
1.51 albertel 230: sub start_formulahint {
1.35 albertel 231: return &start_numericalhint(@_);
1.28 albertel 232: }
233:
1.51 albertel 234: sub end_formulahint {
1.35 albertel 235: return &end_numericalhint(@_);
1.28 albertel 236: }
237:
1.63 www 238: sub start_mathhint {
239: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
240: #do everything in end, so intervening <responseparams> and <answer> work
241: &Apache::response::start_hintresponse($parstack,$safeeval);
242: &Apache::lonxml::register('Apache::response',('answer'));
243: my $result;
244: if ($target eq 'edit') {
245: $result.=&Apache::edit::tag_start($target,$token);
246: $result.=&Apache::edit::text_arg('Name:','name',$token);
247: $result.=&Apache::edit::select_arg('Algebra System:',
248: 'cas',
1.75 www 249: ['maxima','R'],
1.63 www 250: $token);
251: $result.=&Apache::edit::text_arg('Argument Array:',
252: 'args',$token);
253: $result.=&Apache::edit::end_row();
254: $result.=&Apache::edit::start_spanning_row();
255: } elsif ($target eq 'modified') {
256: my $constructtag;
257: $constructtag=&Apache::edit::get_new_args($token,$parstack,
258: $safeeval,'name','cas',
259: 'args');
260: $result = &Apache::edit::rebuild_tag($token);
261: } elsif ($target eq 'web') {
262: &Apache::response::reset_params();
263: }
264: return $result;
265: }
266:
267: sub end_mathhint {
268: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
269: my $result;
270: if ($target eq 'web') {
271: if (!$Apache::lonxml::default_homework_loaded) {
272: &Apache::lonxml::default_homework_load($safeeval);
273: }
274: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
275: &Apache::response::setup_params('mathhint',$safeeval);
276: my $partid=$Apache::inputtags::part;
277: my $submitid=$Apache::inputtags::response[-1];
278: my $response = $Apache::lonhomework::history{
279: "resource.$partid.$submitid.submission"};
280:
281: my $cas = &Apache::lonxml::get_param('cas',$parstack,$safeeval);
282: my $award;
283: if ($cas eq 'maxima') {
284: my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)];
285: $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args);
286: }
1.75 www 287: if ($cas eq 'R') {
288: my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)];
289: $award=&Apache::lonr::r_run($Apache::response::custom_answer[-1],$response,$args);
290: }
1.63 www 291: if ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS') {
292: push (@Apache::hint::which,$name);
293: }
294: $result='';
295: } elsif ($target eq 'meta') {
296: $result=&Apache::response::meta_package_write($token->[1]);
297: } elsif ($target eq 'edit') {
298: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
299: }
300: pop(@Apache::response::custom_answer);
301: pop(@Apache::response::custom_answer_type);
302: &Apache::response::end_hintresponse();
303: return $result;
304: }
305:
1.64 www 306: sub start_customhint {
307: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
308: #do everything in end, so intervening <responseparams> and <answer> work
309: &Apache::response::start_hintresponse($parstack,$safeeval);
310: &Apache::lonxml::register('Apache::response',('answer'));
311: my $result;
312: if ($target eq 'edit') {
313: $result.=&Apache::edit::tag_start($target,$token);
314: $result.=&Apache::edit::text_arg('Name:','name',$token);
315: $result.=&Apache::edit::end_row();
316: $result.=&Apache::edit::start_spanning_row();
317: } elsif ($target eq 'modified') {
318: my $constructtag;
319: $constructtag=&Apache::edit::get_new_args($token,$parstack,
320: $safeeval,'name');
321: $result = &Apache::edit::rebuild_tag($token);
322: } elsif ($target eq 'web') {
323: &Apache::response::reset_params();
324: }
325: return $result;
326: }
327:
328: sub end_customhint {
329: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
330: my $result;
331: if ($target eq 'web') {
332: if (!$Apache::lonxml::default_homework_loaded) {
333: &Apache::lonxml::default_homework_load($safeeval);
334: }
335: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
336: &Apache::response::setup_params('customhint',$safeeval);
337: my $partid=$Apache::inputtags::part;
338: my $submitid=$Apache::inputtags::response[-1];
339: my $response = $Apache::lonhomework::history{
340: "resource.$partid.$submitid.submission"};
341: my $award;
342: if ( $response =~ /[^\s]/ &&
343: $Apache::response::custom_answer_type[-1] eq 'loncapa/perl') {
344: if (!$Apache::lonxml::default_homework_loaded) {
345: &Apache::lonxml::default_homework_load($safeeval);
346: }
347: ${$safeeval->varglob('LONCAPA::customresponse_submission')}=
348: $response;
349:
350: $award = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer[-1].'}',$safeeval);
351: }
352: if ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS') {
353: push (@Apache::hint::which,$name);
354: }
355: $result='';
356: } elsif ($target eq 'meta') {
357: $result=&Apache::response::meta_package_write($token->[1]);
358: } elsif ($target eq 'edit') {
359: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
360: }
361: pop(@Apache::response::custom_answer);
362: pop(@Apache::response::custom_answer_type);
363: &Apache::response::end_hintresponse();
364: return $result;
365: }
366:
1.51 albertel 367: sub start_stringhint {
368: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
369: #do everything in end, so intervening <responseparams> work
370: &Apache::response::start_hintresponse($parstack,$safeeval);
371: my $result;
372: if ($target eq 'edit') {
373: $result.=&Apache::edit::tag_start($target,$token);
374: $result.=&Apache::edit::text_arg('Name:','name',$token);
375: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
376: $result.=&Apache::edit::select_arg('Type:','type',
377: [['cs','Case Sensitive'],['ci','Case Insensitive'],
378: ['mc','Case Insensitive, Any Order'],
379: ['re','Regular Expression']],$token);
380: $result.=&Apache::edit::end_row();
381: $result.=&Apache::edit::start_spanning_row();
382: } elsif ($target eq 'modified') {
383: my $constructtag;
384: $constructtag=&Apache::edit::get_new_args($token,$parstack,
385: $safeeval,'name','answer',
386: 'type');
387: $result = &Apache::edit::rebuild_tag($token);
388: } elsif ($target eq 'web') {
389: &Apache::response::reset_params();
390: }
391: return $result;
1.28 albertel 392: }
393:
1.51 albertel 394: sub end_stringhint {
395: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
396: my $result;
397: if ($target eq 'web') {
398: if (!$Apache::lonxml::default_homework_loaded) {
399: &Apache::lonxml::default_homework_load($safeeval);
400: }
401: $safeeval->share_from('capa',['&caparesponse_capa_check_answer']);
1.65 albertel 402: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
1.51 albertel 403: &Apache::response::setup_params('stringhint',$safeeval);
404: my $partid=$Apache::inputtags::part;
1.60 albertel 405: my $id=$Apache::inputtags::hint[-1];
1.69 bisitz 406: #id submissions occurred under
1.60 albertel 407: my $submitid=$Apache::inputtags::response[-1];
1.51 albertel 408: my $response = $Apache::lonhomework::history{
409: "resource.$partid.$submitid.submission"};
410: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
1.65 albertel 411: my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
1.51 albertel 412: my ($ad,$msg);
413: if ($type eq 're' ) {
1.65 albertel 414: my $answer=&Apache::lonxml::get_param('answer',$parstack,
415: $safeeval);
1.51 albertel 416: ${$safeeval->varglob('LONCAPA::response')}=$response;
1.57 albertel 417: my $compare='=';
418: if ($answer=~/^\s*NOT\s*/) {
419: $answer=~s/^\s*NOT\s*//;
420: $compare='!';
421: }
422: my $test='$LONCAPA::response'.$compare.'~m'.$answer;
423: &Apache::lonxml::debug("test $test");
424: $result = &Apache::run::run("return $test",$safeeval);
1.51 albertel 425: &Apache::lonxml::debug("current $response");
426: &Apache::lonxml::debug("current $answer");
427: $ad = ($result) ? 'APPROX_ANS' : 'INCORRECT';
428: } else {
1.65 albertel 429: my @args = ('type');
430: my $args_ref =
431: &Apache::caparesponse::setup_capa_args($safeeval,$parstack,
432: \@args,$response);
1.71 raeburn 433: if ($$args_ref{'type'} eq '') {
434: $$args_ref{'type'} = 'ci';
435: }
1.65 albertel 436: &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval);
437: my (@final_awards,@final_msgs,@ans_names);
438: my %answer = &Apache::caparesponse::get_answer();
439: foreach my $ans_name (keys(%answer)) {
440: &Apache::lonxml::debug(" doing $ans_name with ".join(':',@{ $answer{$ans_name}{'answers'} }));
441: ${$safeeval->varglob('LONCAPA::CAPAresponse_answer')}=dclone($answer{$ans_name});
1.71 raeburn 442: my ($result, @msgs)=&Apache::run::run("&caparesponse_check_list()",$safeeval);
1.65 albertel 443: &Apache::lonxml::debug('msgs are'.join(':',@msgs));
444: my ($awards) = split(/:/,$result);
445: my (@awards) = split(/,/,$awards);
446: ($ad,$msg) =
447: &Apache::inputtags::finalizeawards(\@awards,\@msgs);
448: push(@final_awards,$ad);
449: push(@final_msgs,$msg);
450: push(@ans_names,$ans_name);
451: &Apache::lonxml::debug("\n<br>result:$result:$Apache::lonxml::curdepth<br>\n");
1.51 albertel 452: }
1.65 albertel 453: my ($ad, $msg, $ans_name) =
454: &Apache::inputtags::finalizeawards(\@final_awards,
455: \@final_msgs,
456: \@ans_names,1);
1.51 albertel 457: }
458: if ($ad eq 'EXACT_ANS' || $ad eq 'APPROX_ANS') {
1.65 albertel 459: push(@Apache::hint::which,$hint_name);
1.51 albertel 460: }
461: $result='';
462: } elsif ($target eq 'meta') {
463: $result=&Apache::response::meta_package_write($token->[1]);
464: } elsif ($target eq 'edit') {
1.62 albertel 465: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
1.51 albertel 466: }
467: &Apache::response::end_hintresponse();
468: return $result;
1.1 albertel 469: }
470:
1.76 ! www 471: # reactionhint
! 472:
! 473: sub start_reactionhint {
! 474: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
! 475: #do everything in end, so intervening <responseparams> work
! 476: &Apache::response::start_hintresponse($parstack,$safeeval);
! 477: my $result;
! 478: if ($target eq 'edit') {
! 479: $result.=&Apache::edit::tag_start($target,$token);
! 480: $result.=&Apache::edit::text_arg('Name:','name',$token);
! 481: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
! 482: $result.=&Apache::edit::end_row();
! 483: $result.=&Apache::edit::start_spanning_row();
! 484: } elsif ($target eq 'modified') {
! 485: my $constructtag;
! 486: $constructtag=&Apache::edit::get_new_args($token,$parstack,
! 487: $safeeval,'name','answer',
! 488: );
! 489: $result = &Apache::edit::rebuild_tag($token);
! 490: } elsif ($target eq 'web') {
! 491: &Apache::response::reset_params();
! 492: }
! 493: return $result;
! 494: }
! 495:
! 496: sub end_reactionhint {
! 497: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
! 498: my $result;
! 499: if ($target eq 'web') {
! 500: if (!$Apache::lonxml::default_homework_loaded) {
! 501: &Apache::lonxml::default_homework_load($safeeval);
! 502: }
! 503: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
! 504: &Apache::response::setup_params('reactionhint',$safeeval);
! 505: my $partid=$Apache::inputtags::part;
! 506: my $id=$Apache::inputtags::hint[-1];
! 507: #id submissions occurred under
! 508: my $submitid=$Apache::inputtags::response[-1];
! 509: my $response = $Apache::lonhomework::history{
! 510: "resource.$partid.$submitid.submission"};
! 511: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
! 512: my $answer=&Apache::lonxml::get_param('answer',$parstack,
! 513: $safeeval);
! 514: &Apache::lonxml::debug("current $response");
! 515: &Apache::lonxml::debug("current $answer");
! 516: if (&Apache::chemresponse::chem_standard_order($response) eq
! 517: &Apache::chemresponse::chem_standard_order($answer)) {
! 518: push(@Apache::hint::which,$hint_name);
! 519: }
! 520: $result='';
! 521: } elsif ($target eq 'meta') {
! 522: $result=&Apache::response::meta_package_write($token->[1]);
! 523: } elsif ($target eq 'edit') {
! 524: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
! 525: }
! 526: &Apache::response::end_hintresponse();
! 527: return $result;
! 528: }
! 529:
! 530: # organichint
! 531:
! 532: sub start_organichint {
! 533: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
! 534: #do everything in end, so intervening <responseparams> work
! 535: &Apache::response::start_hintresponse($parstack,$safeeval);
! 536: my $result;
! 537: if ($target eq 'edit') {
! 538: $result.=&Apache::edit::tag_start($target,$token);
! 539: $result.=&Apache::edit::text_arg('Name:','name',$token);
! 540: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
! 541: $result.=&Apache::edit::end_row();
! 542: $result.=&Apache::edit::start_spanning_row();
! 543: } elsif ($target eq 'modified') {
! 544: my $constructtag;
! 545: $constructtag=&Apache::edit::get_new_args($token,$parstack,
! 546: $safeeval,'name','answer',
! 547: );
! 548: $result = &Apache::edit::rebuild_tag($token);
! 549: } elsif ($target eq 'web') {
! 550: &Apache::response::reset_params();
! 551: }
! 552: return $result;
! 553: }
! 554:
! 555: sub end_organichint {
! 556: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
! 557: my $result;
! 558: if ($target eq 'web') {
! 559: if (!$Apache::lonxml::default_homework_loaded) {
! 560: &Apache::lonxml::default_homework_load($safeeval);
! 561: }
! 562: my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
! 563: &Apache::response::setup_params('organichint',$safeeval);
! 564: my $partid=$Apache::inputtags::part;
! 565: my $id=$Apache::inputtags::hint[-1];
! 566: #id submissions occurred under
! 567: my $submitid=$Apache::inputtags::response[-1];
! 568: my $response = $Apache::lonhomework::history{
! 569: "resource.$partid.$submitid.submission"};
! 570: &Apache::lonxml::debug("hintgroup is using $response<br />\n");
! 571: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
! 572: my %previous = &Apache::response::check_for_previous($response,$partid,$id);
! 573: foreach my $answer (@answers) {
! 574: &Apache::lonxml::debug("submitted a $response for $answer<br \>\n");
! 575: if ($response eq $answer) {
! 576: push(@Apache::hint::which,$hint_name);
! 577: last;
! 578: }
! 579: }
! 580: $result='';
! 581: } elsif ($target eq 'meta') {
! 582: $result=&Apache::response::meta_package_write($token->[1]);
! 583: } elsif ($target eq 'edit') {
! 584: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
! 585: }
! 586: &Apache::response::end_hintresponse();
! 587: return $result;
! 588: }
! 589:
! 590:
1.2 albertel 591: # a part shows if it is on, if no specific parts are on, then default shows
1.1 albertel 592: sub start_hintpart {
1.39 albertel 593: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.15 albertel 594:
1.39 albertel 595: my $show ='0';
596: my $result = '';
597: if ($target eq 'web') {
598: my $on= &Apache::lonxml::get_param('on',$parstack,$safeeval);
599: &Apache::lonxml::debug("hintpart sees $on and ,$#Apache::hint::which");
600: if ( $on eq 'default' && $#Apache::hint::which == '-1') {
601: $show=1;
602: } else {
603: my $which;
604: foreach $which (@Apache::hint::which) { if ($which eq $on) { $show = 1; last } }
605: }
606: if (!$show) {
1.61 albertel 607: &Apache::lonxml::get_all_text("/hintpart",$parser,$style);
1.39 albertel 608: }
609: } elsif ($target eq 'grade') {
1.61 albertel 610: &Apache::lonxml::get_all_text("/hintpart",$parser,$style);
1.39 albertel 611: } elsif ($target eq 'edit') {
612: $result.= &Apache::edit::tag_start($target,$token);
613: $result.= &Apache::edit::text_arg('On:','on',$token);
614: $result.= &Apache::edit::end_row();
615: $result.= &Apache::edit::start_spanning_row();
616: } elsif ($target eq 'modified') {
617: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
618: $safeeval,'on');
619: if ($constructtag) {
620: $result = &Apache::edit::rebuild_tag($token);
621: }
1.20 albertel 622: }
1.39 albertel 623: return $result;
1.1 albertel 624: }
625:
626: sub end_hintpart {
1.29 albertel 627: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
628: my $result;
1.62 albertel 629: if ($target eq 'edit') {
630: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
631: }
1.29 albertel 632: return $result;
633: }
634:
635: sub start_optionhint {
636: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
637: my $result;
1.30 albertel 638: &Apache::response::start_hintresponse($parstack,$safeeval);
639: if ($target eq 'edit') {
640: $result.=&Apache::edit::tag_start($target,$token);
641: $result.=&Apache::edit::text_arg('Name:','name',$token);
642: $result.=&Apache::edit::text_arg('Answer:','answer',$token,40);
643: $result.=&Apache::edit::text_arg('Concept:','concept',$token,50);
644: } elsif ($target eq 'modified') {
645: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
646: $safeeval,'name',
647: 'answer','concept');
648: if ($constructtag) {
649: $result = &Apache::edit::rebuild_tag($token);
650: }
651: } elsif ($target eq 'meta') {
652: $result=&Apache::response::meta_package_write('numericalhint');
653: }
1.29 albertel 654: return $result;
655: }
656:
657: sub end_optionhint {
658: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
659: my $result;
1.30 albertel 660: if ($target eq 'web') {
661: my ($foilmatch,$conceptmatch)=(-1,-1);
662: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
663: my $partid=$Apache::inputtags::part;
1.69 bisitz 664: #id submissions occurred under
1.60 albertel 665: my $submitid=$Apache::inputtags::response[-1];
1.30 albertel 666: my $part_id="$partid.$submitid";
667: my %answer;
668: my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
669: if ($answer) {
670: eval('%answer ='.$answer);
1.62 albertel 671: &Apache::lonxml::debug("answwer hash");
1.30 albertel 672: &Apache::lonhomework::showhash(%answer);
673: my $response = $Apache::lonhomework::history{
674: "resource.$part_id.submission"};
675: my %response=&Apache::lonnet::str2hash($response);
676: &Apache::lonhomework::showhash(%response);
677: foreach my $foil (keys(%answer)) {
678: $foilmatch=1;
679: if ($answer{$foil} ne $response{$foil}) {$foilmatch=0;last;}
680: }
681: }
682: my %concept;
683: my $constr=&Apache::lonxml::get_param('concept',$parstack,$safeeval);
684: if ( $constr ) { eval('%concept ='.$constr); }
685: my $response = $Apache::lonhomework::history{
686: "resource.$part_id.submissiongrading"};
687: my %response=&Apache::lonnet::str2hash($response);
688: foreach my $concept (keys(%concept)) {
689: my $compare;
690: if ($concept{$concept} eq 'correct') {$compare=1}else{$compare=0}
691: $conceptmatch=1;
692: if (ref($Apache::hint::option{"$part_id.concepts"})) {
693: foreach my $foil (@{ $Apache::hint::option{"$part_id.concept.$concept"} }) {
694: &Apache::lonxml::debug("compare -$foil- -$response{$foil}-$compare-");
695: if ( exists($response{$foil}) &&
696: $response{$foil} ne $compare) {$conceptmatch=0;last;}
697: }
698: } else {
699: $conceptmatch=0;
700: }
701: if ($conceptmatch eq '0') { last; }
702: }
703: if ( ($conceptmatch eq '-1' || $conceptmatch eq '1') &&
704: ($foilmatch eq '-1' || $foilmatch eq '1') ) {
705: push(@Apache::hint::which,$name);
706: }
1.62 albertel 707: } elsif ($target eq 'edit') {
708: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
709: }
1.30 albertel 710: &Apache::response::end_hintresponse();
1.29 albertel 711: return $result;
712: }
713:
714: sub start_radiobuttonhint {
715: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
716: my $result;
717: &Apache::response::start_hintresponse($parstack,$safeeval);
718: if ($target eq 'edit') {
719: $result.=&Apache::edit::tag_start($target,$token);
720: $result.=&Apache::edit::text_arg('Name:','name',$token);
721: $result.=&Apache::edit::text_arg('Answer:','answer',$token);
722: } elsif ($target eq 'modified') {
723: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
724: $safeeval,'name',
725: 'answer');
726: if ($constructtag) {
727: $result = &Apache::edit::rebuild_tag($token);
728: }
729: } elsif ($target eq 'meta') {
730: $result=&Apache::response::meta_package_write('numericalhint');
731: }
732: return $result;
1.1 albertel 733: }
734:
1.31 albertel 735: sub end_radiobuttonhint {
1.29 albertel 736: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
737: my $result;
738: if ($target eq 'web') {
739: my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval);
740: my @answer;
741: my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
742: eval('@answer ='.$answer);
743: my $partid=$Apache::inputtags::part;
1.69 bisitz 744: #id submissions occurred under
1.60 albertel 745: my $submitid=$Apache::inputtags::response[-1];
1.29 albertel 746: my $part_id="$partid.$submitid";
747: my $response = $Apache::lonhomework::history{
748: "resource.$part_id.submission"};
749: ($response)=&Apache::lonnet::str2hash($response);
1.42 albertel 750: &Apache::lonxml::debug("response is $response");
751:
752: if ($answer[0] eq 'foil') {
753: shift(@answer);
754: foreach my $answer (@answer) {
755: if ($response eq $answer) {
756: push (@Apache::hint::which,$name);
757: last;
758: }
759: }
1.29 albertel 760: } elsif ($answer[0] eq 'concept') {
1.42 albertel 761: shift(@answer);
762: foreach my $answer (@answer) {
763: if (ref($Apache::hint::radiobutton{"$part_id.concept.".$answer})) {
764: my @names=@{ $Apache::hint::radiobutton{"$part_id.concept.".$answer} };
765: if (grep(/^\Q$response\E$/,@names)) {
766: push(@Apache::hint::which,$name);
767: last;
768: }
1.29 albertel 769: }
770: }
771: }
1.62 albertel 772: } elsif ($target eq 'edit') {
773: $result.=&Apache::edit::end_row().&Apache::edit::end_table();
774: }
1.29 albertel 775: &Apache::response::end_hintresponse();
776: return $result;
777: }
1.1 albertel 778: 1;
779: __END__
1.74 jms 780:
781:
782: =head1 NAME
783:
784: Apache::hinttags
785:
786: =head1 SYNOPSIS
787:
788: This handler coordinates the delivery of hints to students working on LON-CAPA problems and assignments.
789:
790: This is part of the LearningOnline Network with CAPA project
791: described at http://www.lon-capa.org.
792:
793: =head1 SUBROUTINES
794:
795: =over
796:
797: =item start_hintgroup()
798:
799: =item end_hintgroup()
800:
801: =item start_numericalhint()
802:
803: =item end_numericalhint()
804:
805: =item start_formulahint()
806:
807: =item end_formulahint()
808:
809: =item start_mathhint()
810:
811: =item end_mathhint()
812:
813: =item start_customhint()
814:
815: =item end_customhint()
816:
817: =item start_stringhint()
818:
819: =item end_stringhint()
820:
821: =item start_hintpart()
822:
823: =item end_hintpart()
824:
825: =item start_optionhint()
826:
827: =item end_optionhint()
828:
829: =item start_radiobuttonhint()
830:
831: =item end_radiobuttonhint()
832:
833: =back
834:
1.75 www 835: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>