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