--- loncom/homework/response.pm 2011/03/07 19:42:21 1.222 +++ loncom/homework/response.pm 2013/04/29 21:09:40 1.233 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # various response type definitons response definition # -# $Id: response.pm,v 1.222 2011/03/07 19:42:21 www Exp $ +# $Id: response.pm,v 1.233 2013/04/29 21:09:40 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -53,6 +53,7 @@ package Apache::response; use strict; use Apache::lonlocal; use Apache::lonnet; +use Apache::inputtags(); use Apache::lonmaxima(); use Apache::lonr(); @@ -179,7 +180,7 @@ sub setrandomnumber { } else { ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2"); } - + $Apache::lonhomework::results{'resource.'.$id1.'.rawrndseed'}=$rndseed; if ($rndseed =~/([,:])/) { my $char=$1; use integer; @@ -196,6 +197,7 @@ sub setrandomnumber { } } &Apache::lonxml::debug("randseed $rndmod $rndseed"); + $Apache::lonhomework::results{'resource.'.$id1.'.rndseed'}=$rndseed; &Apache::lonnet::setup_random_from_rndseed($rndseed); return ''; } @@ -321,7 +323,7 @@ sub check_for_previous { next if (($questiontype eq 'randomizetry') && ($curr_rndseed ne $Apache::lonhomework::history{"$history:resource.$partid.rndseed"})); push (@{$previous{'versionci'}},$history); - $previous{'awardci'} = $Apache::lonhomework::history{"resource.$partid.$id.awarddetail"}; + $previous{'awardci'} = $Apache::lonhomework::history{"$history:resource.$partid.$id.awarddetail"}; $previous{'usedci'} = 1; } } @@ -467,6 +469,18 @@ sub end_customresponse { $error = $award; $award = 'ERROR'; } + if (($award eq 'INCORRECT' || $award eq 'APPROX_ANS' || + $award eq 'EXACT_ANS')) { + if ($Apache::lonhomework::type eq 'survey') { + $award='SUBMITTED'; + } elsif ($Apache::lonhomework::type eq 'surveycred') { + $award='SUBMITTED_CREDIT'; + } elsif ($Apache::lonhomework::type eq 'anonsurvey') { + $award='ANONYMOUS'; + } elsif ($Apache::lonhomework::type eq 'anonsurveycred') { + $award='ANONYMOUS_CREDIT'; + } + } &Apache::response::handle_previous(\%previous,$award); $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}= $award; @@ -489,12 +503,12 @@ sub end_customresponse { $result .= &Apache::response::answer_footer('customresponse'); } if ($target eq 'web') { - &setup_prior_tries_hash(\&format_prior_response_math); + &setup_prior_tries_hash(\&format_prior_response_custom); } if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || $target eq 'tex' || $target eq 'analyze') { - &Apache::lonxml::increment_counter(&Apache::response::repetition(), - "$part.$id"); + my $repetition = &repetition(); + &Apache::lonxml::increment_counter($repetition,"$part.$id"); if ($target eq 'analyze') { $Apache::lonhomework::analyze{"$part.$id.type"} = 'customresponse'; &Apache::lonhomework::set_bubble_lines(); @@ -510,6 +524,9 @@ sub end_customresponse { sub format_prior_response_custom { my ($mode,$answer) =@_; + if (ref($answer) eq 'ARRAY') { + $answer = '('.join(', ', @{ $answer }).')'; + } return ''. &HTML::Entities::encode($answer,'"<>&').''; } @@ -609,6 +626,18 @@ sub end_mathresponse { $error = $award; $award = 'ERROR'; } + if (($award eq 'INCORRECT' || $award eq 'APPROX_ANS' || + $award eq 'EXACT_ANS')) { + if ($Apache::lonhomework::type eq 'survey') { + $award='SUBMITTED'; + } elsif ($Apache::lonhomework::type eq 'surveycred') { + $award='SUBMITTED_CREDIT'; + } elsif ($Apache::lonhomework::type eq 'anonsurvey') { + $award='ANONYMOUS'; + } elsif ($Apache::lonhomework::type eq 'anonsurveycred') { + $award='ANONYMOUS_CREDIT'; + } + } &Apache::response::handle_previous(\%previous,$award); $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}= $award; @@ -1002,16 +1031,18 @@ sub getresponse { $Apache::lonhomework::results{"resource.$part.$id.scantron"}.= $response; if ($resulttype ne 'letter') { - if ($resulttype eq 'A is 1') { - $response = $let_to_num{$response}+1; - } else { - $response = $let_to_num{$response}; + $response = $let_to_num{$response}; + if ($resulttype eq 'A is 1') { + if ($response ne "") { + $response = $response+1; + } } if ($response ne "") { $response += $line * $bubbles_per_line; } } else { if ($response ne "") { + my $raw = $response; $response = chr(ord($response) + $line * $bubbles_per_line); } } @@ -1031,8 +1062,17 @@ sub getresponse { =item &repetition(); -Returns the number of lines that are required to encode the weight. -(Currently expects that there are 10 bubbles per line) +In scalar context: + +returns: the number of lines that are required to encode the weight. +(Default is for 10 bubbles per bubblesheet item; other (integer) +values can be specified by using a custom Bubblesheet format file +with an eighteenth entry (BubblesPerRow) set to the integer +appropriate for the bubblesheets which will be used to assign weights. + +In array context: + +returns: number of lines required to encode weight, and bubbles/line. =cut @@ -1040,9 +1080,25 @@ sub repetition { my $id = $Apache::inputtags::part; my $weight = &Apache::lonnet::EXT("resource.$id.weight"); if (!defined($weight) || ($weight eq '')) { $weight=1; } - my $repetition = int($weight/10); - if ($weight % 10 != 0) { $repetition++; } + my $bubbles_per_row; + if (($env{'form.bubbles_per_row'} =~ /^\d+$/) && + ($env{'form.bubbles_per_row'} > 0)) { + $bubbles_per_row = $env{'form.bubbles_per_row'}; + } else { + $bubbles_per_row = 10; + } + my $denominator = $bubbles_per_row; + if (($env{'form.scantron_lastbubblepoints'} == 0) && + ($bubbles_per_row > 1)) { + $denominator = $bubbles_per_row - 1; + } + my $repetition = int($weight/$denominator); + if ($weight % $denominator != 0) { $repetition++; } + if (wantarray) { + return ($repetition,$bubbles_per_row); + } return $repetition; + } =pod @@ -1072,11 +1128,24 @@ Arguments sub scored_response { my ($part,$id)=@_; my $repetition=&repetition(); + my $bubbles_per_row; + if (($env{'form.bubbles_per_row'} =~ /^\d+$/) && + ($env{'form.bubbles_per_row'} > 0)) { + $bubbles_per_row = $env{'form.bubbles_per_row'}; + } else { + $bubbles_per_row = 10; + } my $score=0; for (my $i=0;$i<$repetition;$i++) { - # A is 1, B is 2, etc. (get response return 0-9 and then we add 1) + # A is 1, B is 2, etc. my $increase=&Apache::response::getresponse($i+1); - if ($increase ne '') { $score+=$increase+1; } + unless (($increase == $bubbles_per_row-1) && + ($env{'form.scantron_lastbubblepoints'} == 0)) { + # (get response return 0-9 and then we add 1) + if ($increase ne '') { + $score+=$increase+1; + } + } } my $weight = &Apache::lonnet::EXT("resource.$part.weight"); if (!defined($weight) || $weight eq '' || $weight eq 0) { $weight = 1; } @@ -1090,8 +1159,11 @@ sub scored_response { sub whichorder { my ($max,$randomize,$showall,$hash,$rndseed)=@_; #&Apache::lonxml::debug("man $max randomize $randomize"); - if (!defined(@{ $$hash{'names'} })) { return; } - my @names = @{ $$hash{'names'} }; + my @names; + if (ref($hash->{'names'}) eq 'ARRAY') { + @names = @{$hash->{'names'}}; + } + return if (!@names); my @whichopt =(); my (%top,@toplist,%bottom,@bottomlist); if (!($showall || ($randomize eq 'no'))) { @@ -1140,11 +1212,17 @@ sub whichorder { sub show_answer { my $part = $Apache::inputtags::part; - my $award = $Apache::lonhomework::history{"resource.$part.awarded"}; + my $award = $Apache::lonhomework::history{"resource.$part.solved"}; my $status = $Apache::inputtags::status[-1]; - return ( ($award ==1 - && &Apache::lonhomework::show_problem_status()) - || $status eq "SHOW_ANSWER"); + my $canshow = 0; + if ($award =~ /^correct/) { + if (($Apache::lonhomework::history{"resource.$part.awarded"} >= 1) || + (&Apache::lonnet::EXT("resource.$part.retrypartial") !~/^1|on|yes$/)) { + $canshow = 1; + } + } + return (($canshow && &Apache::lonhomework::show_problem_status()) + || $status eq "SHOW_ANSWER"); } sub analyze_store_foilgroup { @@ -1172,8 +1250,11 @@ sub check_if_computed { sub pick_foil_for_concept { my ($target,$attrs,$hinthash,$parstack,$safeeval)=@_; - if (not defined(@{ $Apache::response::conceptgroup{'names'} })) { return; } - my @names = @{ $Apache::response::conceptgroup{'names'} }; + my @names; + if (ref($Apache::response::conceptgroup{'names'}) eq 'ARRAY') { + @names = @{ $Apache::response::conceptgroup{'names'} }; + } + return if (!@names); my $pick=int(&Math::Random::random_uniform() * ($#names+1)); my $name=$names[$pick]; push @{ $Apache::response::foilgroup{'names'} }, $name;