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