--- loncom/homework/radiobuttonresponse.pm 2007/06/20 22:50:27 1.119
+++ loncom/homework/radiobuttonresponse.pm 2010/05/03 14:43:50 1.145
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# mutliple choice style responses
#
-# $Id: radiobuttonresponse.pm,v 1.119 2007/06/20 22:50:27 foxr Exp $
+# $Id: radiobuttonresponse.pm,v 1.145 2010/05/03 14:43:50 onken Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -18,14 +18,15 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with LON-CAPA; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# along with LON-CAPA; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
+
+
package Apache::radiobuttonresponse;
use strict;
use HTML::Entities();
@@ -33,12 +34,25 @@ use Apache::lonlocal;
use Apache::lonnet;
use Apache::response;
-my $bubbles_per_line = 10;
+my $default_bubbles_per_line = 10;
+
BEGIN {
&Apache::lonxml::register('Apache::radiobuttonresponse',('radiobuttonresponse'));
}
+sub bubble_line_count {
+ my ($numfoils, $bubbles_per_line) = @_;
+ my $bubble_lines;
+ $bubble_lines = int($numfoils / $bubbles_per_line);
+ if (($numfoils % $bubbles_per_line) != 0) {
+ $bubble_lines++;
+ }
+ return $bubble_lines;
+
+}
+
+
sub start_radiobuttonresponse {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
my $result;
@@ -47,24 +61,27 @@ sub start_radiobuttonresponse {
&Apache::lonxml::register('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
push (@Apache::lonxml::namespace,'radiobuttonresponse');
my $id = &Apache::response::start_response($parstack,$safeeval);
+
%Apache::hint::radiobutton=();
undef(%Apache::response::foilnames);
if ($target eq 'meta') {
$result=&Apache::response::meta_package_write('radiobuttonresponse');
} elsif ($target eq 'edit' ) {
- $result.=&Apache::edit::start_table($token).
- '
'.&Apache::lonxml::description($token)
+ .&Apache::loncommon::help_open_topic('Radio_Response_Problems')
+ .' '
+ .''.&mt('Delete?').' '
+ .&Apache::edit::deletelist($target,$token)
+ .' '
+ .' '.&Apache::edit::end_row()
+ .&Apache::edit::start_spanning_row();
$result.=
&Apache::edit::text_arg('Max Number Of Shown Foils:','max',
- $token,'4').
- &Apache::edit::select_arg('Randomize Foil Order','randomize',
- ['yes','no'],$token).
- &Apache::edit::select_arg('Display Direction','direction',
+ $token,'4').' 'x 3 .
+ &Apache::edit::select_arg('Randomize Foil Order:','randomize',
+ ['yes','no'],$token).' 'x 3 .
+ &Apache::edit::select_arg('Display Direction:','direction',
['vertical','horizontal'],$token).
&Apache::edit::end_row().
&Apache::edit::start_spanning_row()."\n";
@@ -87,9 +104,14 @@ sub start_radiobuttonresponse {
} else {
$result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
}
- $result .= '\begin{enumerate}';
+ if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+ $result .= '\begin{itemize}';
+ } else {
+ $result .= '\begin{enumerate}';
+ }
} elsif ($target eq 'analyze') {
my $part_id="$Apache::inputtags::part.$id";
+ $Apache::lonhomework::analyze{"$part_id.type"} = 'radiobuttonresponse';
push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
}
return $result;
@@ -99,7 +121,13 @@ sub end_radiobuttonresponse {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
my $result;
if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
- if ($target eq 'tex') { $result .= '\end{enumerate}'; }
+ if ($target eq 'tex' ) {
+ if($env{'form.pdfFormFields'} eq 'yes' and $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+ $result .= '\end{itemize}';
+ } else {
+ $result .= '\end{enumerate}';
+ }
+ }
&Apache::response::end_response;
pop @Apache::lonxml::namespace;
&Apache::lonxml::deregister('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
@@ -121,6 +149,7 @@ sub start_foilgroup {
}
sub storesurvey {
+ my ($style) = @_;
if ( !&Apache::response::submitted() ) { return ''; }
my $response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
&Apache::lonxml::debug("Here I am!:$response:");
@@ -134,43 +163,44 @@ sub storesurvey {
$Apache::lonhomework::results{"resource.$part.$id.submission"}=
$responsestr;
my %previous=&Apache::response::check_for_previous($responsestr,$part,$id);
- my $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='SUBMITTED';
+ my $ad;
+ if ($style eq 'anonsurvey') {
+ $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='ANONYMOUS';
+ } elsif ($style eq 'anonsurveycred') {
+ $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='ANONYMOUS_CRED';
+ } elsif ($style eq 'surveycred') {
+ $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='SUBMITTED_CREDIT';
+ } else {
+ $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='SUBMITTED';
+ }
&Apache::response::handle_previous(\%previous,$ad);
&Apache::lonxml::debug("submitted a $response \n");
return '';
}
+
sub grade_response {
- my ($max,$randomize)=@_;
- #keep the random numbers the same must always call this
- my ($answer,@whichfoils)=&whichfoils($max,$randomize);
+ my ($answer, $whichfoils, $bubbles_per_line)=@_;
+
if ( !&Apache::response::submitted() ) { return; }
my $response;
- # Need to know how many foils we have so that I know how many
- # bubble lines to consume:
-
- my $numfoils = scalar(@whichfoils);
- my $bubble_lines = int($numfoils / $bubbles_per_line);
- if (($numfoils % $bubbles_per_line) != 0) {
- $bubble_lines++; # Partial line of bubbles too.
- }
-
-
if ($env{'form.submitted'} eq 'scantron') {
- $response = &Apache::response::getresponse(1,undef,$bubble_lines,
- $bubbles_per_line);
+ $response = &Apache::response::getresponse(1,undef,
+ &bubble_line_count(scalar(@{ $whichfoils}),
+ $bubbles_per_line),
+ $bubbles_per_line);
} else {
$response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
}
- &Apache::lonxml::increment_counter($bubble_lines-1);
+
if ( $response !~ /[0-9]+/) { return; }
my $part=$Apache::inputtags::part;
my $id = $Apache::inputtags::response['-1'];
my %responsehash;
- $responsehash{$whichfoils[$response]}=$response;
+ $responsehash{$whichfoils->[$response]}=$response;
my $responsestr=&Apache::lonnet::hash2str(%responsehash);
my %previous=&Apache::response::check_for_previous($responsestr,
$part,$id);
@@ -191,38 +221,62 @@ sub end_foilgroup {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
my $result;
+ my $bubble_lines;
+ my $bubbles_per_line;
+ my $answer_count;
+ my $id = $Apache::inputtags::response['-1'];
+ my $part = $Apache::inputtags::part;
+ $bubbles_per_line =
+ &Apache::response::get_response_param($Apache::inputtags::part."_$id",
+ 'numbubbles',
+ $default_bubbles_per_line);
+
+
if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
$target eq 'tex' || $target eq 'analyze') {
my $style = $Apache::lonhomework::type;
my $direction = &Apache::lonxml::get_param('direction',$parstack,
$safeeval,'-2');
- if ( $style eq 'survey' && $target ne 'analyze') {
+ if ( (($style eq 'survey') || ($style eq 'surveycred') ||
+ ($style eq 'anonsurvey') || ($style eq 'anonsurveycred'))
+ && ($target ne 'analyze')) {
if ($target eq 'web' || $target eq 'tex') {
$result=&displayallfoils($direction, $target);
} elsif ( $target eq 'answer' ) {
$result=&displayallanswers();
} elsif ( $target eq 'grade' ) {
- $result=&storesurvey();
+ $result=&storesurvey($style);
}
+ $answer_count = scalar(@{$Apache::response::foilgroup{'names'}});
+
} else {
+
my $name;
my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,
'-2');
my $randomize = &Apache::lonxml::get_param('randomize',$parstack,
$safeeval,'-2');
+ my ($answer, @shown) = &whichfoils($max, $randomize);
+ $answer_count = scalar(@shown);
+
if ($target eq 'web' || $target eq 'tex') {
- $result=&displayfoils($target,$max,$randomize,$direction);
+ $result=&displayfoils($target,
+ $answer, \@shown,
+ $direction,
+ $bubbles_per_line);
} elsif ($target eq 'answer' ) {
- $result=&displayanswers($max,$randomize);
+ $result=&displayanswers($answer, \@shown, $bubbles_per_line);
} elsif ( $target eq 'grade') {
- &grade_response($max,$randomize);
+ &grade_response($answer, \@shown, $bubbles_per_line);
} elsif ( $target eq 'analyze') {
- my @shown = &whichfoils($max,$randomize);
+ my $bubble_lines = &bubble_line_count($answer_count,
+ $bubbles_per_line);
&Apache::response::analyze_store_foilgroup(\@shown,
['text','value','location']);
- my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]";
+ my $part_id="$part.$id";
push (@{ $Apache::lonhomework::analyze{"$part_id.options"} },
('true','false'));
+
}
}
$Apache::lonxml::post_evaluate=0;
@@ -231,9 +285,13 @@ sub end_foilgroup {
&Apache::response::setup_prior_tries_hash(\&format_prior_answer,
[\%Apache::response::foilgroup]);
}
-
&Apache::response::poprandomnumber();
- &Apache::lonxml::increment_counter();
+ $bubble_lines = &bubble_line_count($answer_count, $bubbles_per_line);
+ &Apache::lonxml::increment_counter($bubble_lines,
+ "$part.$id");
+ if ($target eq 'analyze') {
+ &Apache::lonhomework::set_bubble_lines();
+ }
return $result;
}
@@ -273,12 +331,16 @@ sub displayallfoils {
if ( $Apache::response::foilgroup{'names'} ) {
@names= @{ $Apache::response::foilgroup{'names'} };
}
+
my $temp=0;
my $i =0;
my $id=$Apache::inputtags::response['-1'];
my $part=$Apache::inputtags::part;
- my $lastresponse=
- $Apache::lonhomework::history{"resource.$part.$id.submission"};
+ my $lastresponse;
+ unless ((($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurvey') || ($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurveycred')) && (defined($env{'form.grade_symb'}))) {
+ $lastresponse =
+ $Apache::lonhomework::history{"resource.$part.$id.submission"};
+ }
if ($direction eq 'horizontal') { $result.=''; }
my %lastresponse=&Apache::lonnet::str2hash($lastresponse);
if (&Apache::response::show_answer() ) {
@@ -314,13 +376,22 @@ sub displayallfoils {
$result.="";
} else {
if ($target eq 'tex') {
- $result .= '\item \vskip -2mm ';
- } else {
+ if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+ my $fieldname = $env{'request.symb'}.'&part_'. $Apache::inputtags::part
+ .'&radiobuttonresponse'.'&HWVAL_'.$Apache::inputtags::response['-1'];
+ $result .= '\item[{'.&Apache::lonxml::print_pdf_radiobutton($fieldname,$temp).'}]'
+ .$Apache::response::foilgroup{$name.'.text'}."\n";
+ } else {
+ $result .= '\item \vskip -2mm ';
+ }
+ } else {
$result.=" ";
}
}
if ($target eq 'tex') {
- $result .= '$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\'; #' stupid emacs
+ if($env{'form.pdfFormFields'} ne 'yes' or $Apache::inputtags::status[-1] ne 'CAN_ANSWER') {
+ $result .= '$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\'; #' stupid emacs
+ }
$i++;
} else {
$result .= '';
@@ -328,8 +399,8 @@ sub displayallfoils {
onchange=\"javascript:setSubmittedPart('$part');\"
type=\"radio\"
name=\"HWVAL_$Apache::inputtags::response['-1']\"
- value=\"$temp\" ";
- if (defined($lastresponse{$name})) { $result .= 'checked="on"'; }
+ value=\"$temp\"";
+ if (defined($lastresponse{$name})) { $result .= ' checked="checked"'; }
$result .= ' />'.$Apache::response::foilgroup{$name.'.text'}.
' ';
}
@@ -342,10 +413,12 @@ sub displayallfoils {
}
}
}
+
if (($direction eq 'horizontal') && ($target ne 'tex')) { $result.='
'; }
return $result;
}
+
sub whichfoils {
my ($max,$randomize)=@_;
@@ -379,8 +452,12 @@ sub whichfoils {
&Apache::lonxml::error(&HTML::Entities::encode("No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in ",'<>&"'));
}
}
- if (!$havetrue && $Apache::lonhomework::type ne 'survey') {
- &Apache::lonxml::error("There are no true statements available. ");
+ if ((!$havetrue) &&
+ ($Apache::lonhomework::type ne 'survey') &&
+ ($Apache::lonhomework::type ne 'surveycred') &&
+ ($Apache::lonhomework::type ne 'anonsurvey') &&
+ ($Apache::lonhomework::type ne 'anonsurveycred')) {
+ &Apache::lonxml::error(&mt('There are no true statements available.').' ');
}
} else {
my $current=0;
@@ -439,9 +516,13 @@ sub whichfoils {
&Apache::lonxml::debug("Answer wants $answer");
my $truename=$truelist[$whichtrue];
my $dosplice=1;
- if ($notrue && $Apache::lonhomework::type ne 'survey') {
+ if (($notrue) &&
+ ($Apache::lonhomework::type ne 'survey') &&
+ ($Apache::lonhomework::type ne 'surveycred') &&
+ ($Apache::lonhomework::type ne 'anonsurvey') &&
+ ($Apache::lonhomework::type ne 'anonsurveycred')) {
$dosplice=0;
- &Apache::lonxml::error("There are no true statements available. ");
+ &Apache::lonxml::error(&mt('There are no true statements available.').' ');
}
#insert the true statement, keeping track of where it wants to be
if ($Apache::response::foilgroup{$truename.'.location'} eq 'top' && $dosplice) {
@@ -483,10 +564,9 @@ sub whichfoils {
}
sub displayfoils {
- my ($target,$max,$randomize,$direction)=@_;
+ my ($target,$answer,$whichfoils,$direction, $bubbles_per_line)=@_;
my $result;
- my ($answer,@whichfoils)=&whichfoils($max,$randomize);
my $part=$Apache::inputtags::part;
my $solved=$Apache::lonhomework::history{"resource.$part.solved"};
if ( ($target ne 'tex') &&
@@ -496,7 +576,7 @@ sub displayfoils {
$result.='';
}
}
- foreach my $name (@whichfoils) {
+ foreach my $name (@{ $whichfoils }) {
if ($direction eq 'horizontal') {
if ($target ne 'tex') { $result.=''; }
}
@@ -506,9 +586,13 @@ sub displayfoils {
$result.='\item \vskip -2 mm ';
}
if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
- if ($target ne 'tex') { $result.='Correct:'; } else { $result.='Correct: \textbf{';}
+ if ($target ne 'tex') {
+ $result.=&mt('Correct:').'';
+ } else {
+ $result.=&mt('Correct:').' \textbf{';
+ }
} else {
- $result.='Incorrect:';
+ $result.=&mt('Incorrect:');
}
if ($target eq 'web') { $result.=""; }
$result.=$Apache::response::foilgroup{$name.'.text'};
@@ -529,6 +613,7 @@ sub displayfoils {
my @alphabet = ('A'..'Z');
my $i = 0;
my $bubble_number = 0;
+ my $line = 0;
my $temp=0;
my $id=$Apache::inputtags::response['-1'];
my $part=$Apache::inputtags::part;
@@ -537,7 +622,7 @@ sub displayfoils {
if ($target ne 'tex' && $direction eq 'horizontal') {
$result.="";
}
- foreach my $name (@whichfoils) {
+ foreach my $name (@{ $whichfoils }) {
if ($target ne 'tex') {
if ($direction eq 'horizontal') {
$result.="";
@@ -551,23 +636,30 @@ sub displayfoils {
" ";
} else {
if ($Apache::lonhomework::type eq 'exam') {
- $result .= '{\small \textbf{'.$alphabet[$i].'}}$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\'; #' stupid emacs
- $i++;
- $bubble_number++;
if($bubble_number >= $bubbles_per_line) {
+ $line++;
$i = 0;
$bubble_number = 0;
- &Apache::lonxml::increment_counter(1);
- $result.='\item[\textbf{'.$Apache::lonxml::counter.'}.]';
+ $result.='\item[\textbf{'.($Apache::lonxml::counter+$line).'}.]';
}
+ $result .= '{\small \textbf{'.$alphabet[$i].'}}$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\'; #' stupid emacs
+ $i++;
+ $bubble_number++;
} else {
- $result .= '\vspace*{-2 mm}\item '.$Apache::response::foilgroup{$name.'.text'};
- }
+ if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+ my $fieldname = $env{'request.symb'}.'&part_'. $Apache::inputtags::part
+ .'&radiobuttonresponse'.'&HWVAL_'.$Apache::inputtags::response['-1'];
+ $result .= '\item[{'.&Apache::lonxml::print_pdf_radiobutton($fieldname,$temp).'}]'
+ .$Apache::response::foilgroup{$name.'.text'}."\n";
+ } else {
+ $result .= '\vspace*{-2 mm}\item '.$Apache::response::foilgroup{$name.'.text'};
+ }
+ }
}
if ($target ne 'tex' && $direction eq 'horizontal') {
$result.=" ";
@@ -587,7 +679,6 @@ sub displayallanswers {
if ( $Apache::response::foilgroup{'names'} ) {
@names= @{ $Apache::response::foilgroup{'names'} };
}
-
my $result=&Apache::response::answer_header('radiobuttonresponse');
foreach my $name (@names) {
$result.=&Apache::response::answer_part('radiobuttonresponse',
@@ -598,15 +689,20 @@ sub displayallanswers {
}
sub displayanswers {
- my ($max,$randomize)=@_;
- my ($answer,@whichopt) = &whichfoils($max,$randomize);
- my $result=&Apache::response::answer_header('radiobuttonresponse');
+ my ($answer, $whichopt, $bubbles_per_line)=@_;
+ my $result;
+
if ($Apache::lonhomework::type eq 'exam') {
- my $correct = ('A'..'Z')[$answer];
- $result.=&Apache::response::answer_part('radiobuttonresponse',
- $correct);
+ my $line = int($answer/$bubbles_per_line);
+ my $correct = ('A'..'Z')[$answer%$bubbles_per_line];
+ $result .= &Apache::response::answer_header('radiobuttonresponse',
+ $line);
+ $result .= &Apache::response::answer_part('radiobuttonresponse',
+ $correct);
+ } else {
+ $result .= &Apache::response::answer_header('radiobuttonresponse');
}
- foreach my $name (@whichopt) {
+ foreach my $name (@{ $whichopt }) {
$result.=&Apache::response::answer_part('radiobuttonresponse',
$Apache::response::foilgroup{$name.'.value'});
}
@@ -694,11 +790,11 @@ sub end_foil {
if ($value ne 'unused') {
my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
if ($name eq "") {
- &Apache::lonxml::warning("Foils without names exist. This can cause problems to malfunction.");
+ &Apache::lonxml::warning(&mt('Foils without names exist. This can cause problems to malfunction.'));
$name=$Apache::lonxml::curdepth;
}
if (defined($Apache::response::foilnames{$name})) {
- &Apache::lonxml::error(&mt("Foil name [_1] appears more than once. Foil names need to be unique.",$name));
+ &Apache::lonxml::error(&mt('Foil name [_1] appears more than once. Foil names need to be unique.',''.$name.' '));
}
$Apache::response::foilnames{$name}++;
my $location =&Apache::lonxml::get_param('location',$parstack,
@@ -729,4 +825,87 @@ sub insert_foil {
}
1;
__END__
+
+
+
+=head1 NAME
+
+Apache::radiobuttonresponse
+
+=head1 SYNOPSIS
+
+Handles multiple-choice style responses.
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+=head1 SUBROUTINES
+
+=over
+
+=item start_radiobuttonresponse()
+
+=item bubble_line_count()
+
+=item end_radiobuttonresponse()
+
+=item start_foilgroup()
+
+=item storesurvey()
+
+=item grade_response()
+
+=item end_foilgroup()
+
+=item getfoilcounts()
+
+=item format_prior_answer()
+
+=item displayallfoils()
+
+=item &whichfoils($max,$randomize)
+
+Randomizes the list of foils.
+Respects
+ - each foils desire to be randomized
+ - the existance of Concept groups of foils (select 1 foil from each)
+ - and selects a single correct statement from all possilble true statments
+ - and limits it to a toal of $max foils
+
+WARNING: this routine uses the random number generator, it should only
+be called once per target, otherwise it can cause randomness changes in
+homework problems.
+
+Arguments
+ $max - maximum number of foils to select (including the true one)
+ (so a max of 5 is: 1 true, 4 false)
+
+ $randomize - whether to randomize the listing of foils, by default
+ will randomize, only if randomize is 'no' will it not
+
+Returns
+ $answer - location in the array of the correct answer
+ @foils - array of foil names in to display order
+
+=item displayfoils()
+
+=item displayallanswers()
+
+=item displayanswers()
+
+=item start_conceptgroup()
+
+=item end_conceptgroup()
+
+=item insert_conceptgroup()
+
+=item start_foil()
+
+=item end_foil()
+
+=item insert_foil()
+
+=back
+
+=cut