--- loncom/homework/hint.pm 2006/12/19 14:53:17 1.67 +++ loncom/homework/hint.pm 2024/09/29 01:58:43 1.79 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # implements the tags that control the hints # -# $Id: hint.pm,v 1.67 2006/12/19 14:53:17 www Exp $ +# $Id: hint.pm,v 1.79 2024/09/29 01:58:43 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,6 +26,8 @@ # http://www.lon-capa.org/ # + + package Apache::hinttags; use strict; @@ -33,12 +35,14 @@ use Apache::lonnet(); use capa; use Apache::caparesponse(); use Apache::lonmaxima(); +use Apache::lonr(); +use Apache::chemresponse(); use Apache::response(); use Apache::lonlocal; use Storable qw(dclone); BEGIN { - &Apache::lonxml::register('Apache::hinttags',('hintgroup','hintpart','numericalhint','stringhint','formulahint','optionhint','radiobuttonhint','mathhint','customhint')); + &Apache::lonxml::register('Apache::hinttags',('hintgroup','hintpart','numericalhint','stringhint','formulahint','optionhint','radiobuttonhint','mathhint','customhint','reactionhint','organichint')); } @@ -68,16 +72,19 @@ sub start_hintgroup { $result .= '\keephidden{'; } elsif ($target eq 'edit') { $result.=&Apache::edit::tag_start($target,$token); - $result.=&Apache::edit::select_arg('Show hint even if problem Correct:','showoncorrect',[['no',&mt('No')],['yes',&mt('Yes')]],$token); + $result.=&Apache::edit::select_arg('Show hint even if problem Correct:','showoncorrect',['no','yes'],$token); $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,'showoncorrect'); if ($constructtag) { $result =&Apache::edit::rebuild_tag($token); - $result.=&Apache::edit::handle_insert(); } } @Apache::hint::which=(); + if (($#Apache::functionplotresponse::failedrules>=0) && ($target eq 'web')) { + @Apache::hint::which=@Apache::functionplotresponse::failedrules; + undef @Apache::functionplotresponse::failedrules; + } return $result; } @@ -126,6 +133,8 @@ sub start_numericalhint { $token,40). &Apache::loncommon::help_open_topic('Formula_Response_Sampling'); } + $result.=&Apache::edit::text_arg('Pre-Processor Subroutine:','preprocess', + $token,10); $result.=&Apache::edit::end_row(); $result.=&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { @@ -133,15 +142,14 @@ sub start_numericalhint { if ($token->[1] eq 'numericalhint') { $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'name', - 'answer','unit','format'); + 'answer','unit','format','preprocess'); } elsif ($token->[1] eq 'formulahint') { $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'name','answer', - 'samples'); + 'samples','preprocess'); } if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } } elsif ($target eq 'web') { &Apache::response::reset_params(); @@ -162,7 +170,7 @@ sub end_numericalhint { my $partid=$Apache::inputtags::part; my $id=$Apache::inputtags::hint[-1]; - #id submissions occured under + #id submissions occurred under my $submitid=$Apache::inputtags::response[-1]; my $response = $Apache::lonhomework::history{ @@ -177,16 +185,19 @@ sub end_numericalhint { my $hideunit=&Apache::response::get_response_param($partid.'_'.$submitid,'turnoffunit'); if (lc($hideunit) eq "yes") { delete($$args_ref{'unit'}); } + my $stringify; if ($$tagstack[-1] eq 'formulahint') { if ($$args_ref{'samples'}) { $$args_ref{'type'}='fml'; + $stringify = 1; } else { $$args_ref{'type'}='math'; } } elsif ($$tagstack[-1] eq 'numericalhint') { $$args_ref{'type'}='float'; + $stringify = 1; } - &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval); + &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval,$stringify); my %answer = &Apache::caparesponse::get_answer(); my (@final_awards,@final_msgs,@ans_names); foreach my $ans_name (keys(%answer)) { @@ -244,7 +255,7 @@ sub start_mathhint { $result.=&Apache::edit::text_arg('Name:','name',$token); $result.=&Apache::edit::select_arg('Algebra System:', 'cas', - ['maxima'], + ['maxima','R'], $token); $result.=&Apache::edit::text_arg('Argument Array:', 'args',$token); @@ -256,7 +267,6 @@ sub start_mathhint { $safeeval,'name','cas', 'args'); $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } elsif ($target eq 'web') { &Apache::response::reset_params(); } @@ -283,6 +293,10 @@ sub end_mathhint { my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)]; $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args); } + if ($cas eq 'R') { + my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)]; + $award=&Apache::lonr::r_run($Apache::response::custom_answer[-1],$response,$args); + } if ($award eq 'EXACT_ANS' || $award eq 'APPROX_ANS') { push (@Apache::hint::which,$name); } @@ -314,7 +328,6 @@ sub start_customhint { $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'name'); $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } elsif ($target eq 'web') { &Apache::response::reset_params(); } @@ -373,15 +386,16 @@ sub start_stringhint { [['cs','Case Sensitive'],['ci','Case Insensitive'], ['mc','Case Insensitive, Any Order'], ['re','Regular Expression']],$token); + $result.=&Apache::edit::text_arg('Pre-Processor Subroutine:','preprocess', + $token,10); $result.=&Apache::edit::end_row(); $result.=&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { my $constructtag; $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'name','answer', - 'type'); + 'type','preprocess'); $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } elsif ($target eq 'web') { &Apache::response::reset_params(); } @@ -400,7 +414,7 @@ sub end_stringhint { &Apache::response::setup_params('stringhint',$safeeval); my $partid=$Apache::inputtags::part; my $id=$Apache::inputtags::hint[-1]; - #id submissions occured under + #id submissions occurred under my $submitid=$Apache::inputtags::response[-1]; my $response = $Apache::lonhomework::history{ "resource.$partid.$submitid.submission"}; @@ -427,7 +441,14 @@ sub end_stringhint { my $args_ref = &Apache::caparesponse::setup_capa_args($safeeval,$parstack, \@args,$response); - &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval); + if ($$args_ref{'type'} eq '') { + $$args_ref{'type'} = 'ci'; + } + my $stringify; + if ($$args_ref{'type'} ne 're') { + $stringify = 1; + } + &Apache::caparesponse::add_in_tag_answer($parstack,$safeeval,$stringify); my (@final_awards,@final_msgs,@ans_names); my %answer = &Apache::caparesponse::get_answer(); foreach my $ans_name (keys(%answer)) { @@ -462,6 +483,126 @@ sub end_stringhint { return $result; } +# reactionhint + +sub start_reactionhint { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + #do everything in end, so intervening work + &Apache::response::start_hintresponse($parstack,$safeeval); + my $result; + if ($target eq 'edit') { + $result.=&Apache::edit::tag_start($target,$token); + $result.=&Apache::edit::text_arg('Name:','name',$token); + $result.=&Apache::edit::text_arg('Answer:','answer',$token); + $result.=&Apache::edit::end_row(); + $result.=&Apache::edit::start_spanning_row(); + } elsif ($target eq 'modified') { + my $constructtag; + $constructtag=&Apache::edit::get_new_args($token,$parstack, + $safeeval,'name','answer', + ); + $result = &Apache::edit::rebuild_tag($token); + } elsif ($target eq 'web') { + &Apache::response::reset_params(); + } + return $result; +} + +sub end_reactionhint { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web') { + if (!$Apache::lonxml::default_homework_loaded) { + &Apache::lonxml::default_homework_load($safeeval); + } + my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval); + &Apache::response::setup_params('reactionhint',$safeeval); + my $partid=$Apache::inputtags::part; + my $id=$Apache::inputtags::hint[-1]; + #id submissions occurred under + my $submitid=$Apache::inputtags::response[-1]; + my $response = $Apache::lonhomework::history{ + "resource.$partid.$submitid.submission"}; + &Apache::lonxml::debug("hintgroup is using $response
\n"); + my $answer=&Apache::lonxml::get_param('answer',$parstack, + $safeeval); + &Apache::lonxml::debug("current $response"); + &Apache::lonxml::debug("current $answer"); + if (&Apache::chemresponse::chem_standard_order($response) eq + &Apache::chemresponse::chem_standard_order($answer)) { + push(@Apache::hint::which,$hint_name); + } + $result=''; + } elsif ($target eq 'meta') { + $result=&Apache::response::meta_package_write($token->[1]); + } elsif ($target eq 'edit') { + $result.=&Apache::edit::end_row().&Apache::edit::end_table(); + } + &Apache::response::end_hintresponse(); + return $result; +} + +# organichint + +sub start_organichint { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + #do everything in end, so intervening work + &Apache::response::start_hintresponse($parstack,$safeeval); + my $result; + if ($target eq 'edit') { + $result.=&Apache::edit::tag_start($target,$token); + $result.=&Apache::edit::text_arg('Name:','name',$token); + $result.=&Apache::edit::text_arg('Answer:','answer',$token); + $result.=&Apache::edit::end_row(); + $result.=&Apache::edit::start_spanning_row(); + } elsif ($target eq 'modified') { + my $constructtag; + $constructtag=&Apache::edit::get_new_args($token,$parstack, + $safeeval,'name','answer', + ); + $result = &Apache::edit::rebuild_tag($token); + } elsif ($target eq 'web') { + &Apache::response::reset_params(); + } + return $result; +} + +sub end_organichint { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web') { + if (!$Apache::lonxml::default_homework_loaded) { + &Apache::lonxml::default_homework_load($safeeval); + } + my $hint_name= &Apache::lonxml::get_param('name',$parstack,$safeeval); + &Apache::response::setup_params('organichint',$safeeval); + my $partid=$Apache::inputtags::part; + my $id=$Apache::inputtags::hint[-1]; + #id submissions occurred under + my $submitid=$Apache::inputtags::response[-1]; + my $response = $Apache::lonhomework::history{ + "resource.$partid.$submitid.submission"}; + &Apache::lonxml::debug("hintgroup is using $response
\n"); + my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval); + my %previous = &Apache::response::check_for_previous($response,$partid,$id); + foreach my $answer (@answers) { + &Apache::lonxml::debug("submitted a $response for $answer
\n"); + if ($response eq $answer) { + push(@Apache::hint::which,$hint_name); + last; + } + } + $result=''; + } elsif ($target eq 'meta') { + $result=&Apache::response::meta_package_write($token->[1]); + } elsif ($target eq 'edit') { + $result.=&Apache::edit::end_row().&Apache::edit::end_table(); + } + &Apache::response::end_hintresponse(); + return $result; +} + + # a part shows if it is on, if no specific parts are on, then default shows sub start_hintpart { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; @@ -492,7 +633,6 @@ sub start_hintpart { $safeeval,'on'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); - $result.=&Apache::edit::handle_insert(); } } return $result; @@ -522,7 +662,6 @@ sub start_optionhint { 'answer','concept'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } } elsif ($target eq 'meta') { $result=&Apache::response::meta_package_write('numericalhint'); @@ -537,7 +676,7 @@ sub end_optionhint { my ($foilmatch,$conceptmatch)=(-1,-1); my $name= &Apache::lonxml::get_param('name',$parstack,$safeeval); my $partid=$Apache::inputtags::part; - #id submissions occured under + #id submissions occurred under my $submitid=$Apache::inputtags::response[-1]; my $part_id="$partid.$submitid"; my %answer; @@ -601,7 +740,6 @@ sub start_radiobuttonhint { 'answer'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); - $result .= &Apache::edit::handle_insert(); } } elsif ($target eq 'meta') { $result=&Apache::response::meta_package_write('numericalhint'); @@ -618,7 +756,7 @@ sub end_radiobuttonhint { my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval); eval('@answer ='.$answer); my $partid=$Apache::inputtags::part; - #id submissions occured under + #id submissions occurred under my $submitid=$Apache::inputtags::response[-1]; my $part_id="$partid.$submitid"; my $response = $Apache::lonhomework::history{ @@ -654,3 +792,59 @@ sub end_radiobuttonhint { } 1; __END__ + + +=head1 NAME + +Apache::hinttags + +=head1 SYNOPSIS + +This handler coordinates the delivery of hints to students working on LON-CAPA problems and assignments. + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + +=head1 SUBROUTINES + +=over + +=item start_hintgroup() + +=item end_hintgroup() + +=item start_numericalhint() + +=item end_numericalhint() + +=item start_formulahint() + +=item end_formulahint() + +=item start_mathhint() + +=item end_mathhint() + +=item start_customhint() + +=item end_customhint() + +=item start_stringhint() + +=item end_stringhint() + +=item start_hintpart() + +=item end_hintpart() + +=item start_optionhint() + +=item end_optionhint() + +=item start_radiobuttonhint() + +=item end_radiobuttonhint() + +=back + +=cut