--- loncom/homework/radiobuttonresponse.pm 2007/05/17 10:01:44 1.115
+++ loncom/homework/radiobuttonresponse.pm 2012/01/24 12:05:12 1.153.6.5
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# mutliple choice style responses
#
-# $Id: radiobuttonresponse.pm,v 1.115 2007/05/17 10:01:44 foxr Exp $
+# $Id: radiobuttonresponse.pm,v 1.153.6.5 2012/01/24 12:05:12 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -18,8 +18,7 @@
# 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
#
@@ -32,672 +31,1384 @@ use HTML::Entities();
use Apache::lonlocal;
use Apache::lonnet;
use Apache::response;
+use Apache::caparesponse;
+
+my $default_bubbles_per_line = 10;
+my @alphabet = ( 'A' .. 'Z' ); # Foil labels.
+
+
BEGIN {
- &Apache::lonxml::register('Apache::radiobuttonresponse',('radiobuttonresponse'));
+ &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 ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
+ @_;
my $result;
- #----- test/debugging to figure out some crap
-
- my $partid = $Apache::inputtags::part;
- &Apache::lonnet::logthis("Part id = $partid");
- my $bubble_max = &Apache::response::get_response_param($partid, 'numbubbles', 10);
- &Apache::lonnet::logthis("numbubbles [10] = $bubble_max");
- #----- End test/debugging
#when in a radiobutton response use these
- &Apache::lonxml::register('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
- push (@Apache::lonxml::namespace,'radiobuttonresponse');
- my $id = &Apache::response::start_response($parstack,$safeeval);
- %Apache::hint::radiobutton=();
+ &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').
- " | 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',
- ['vertical','horizontal'],$token).
- &Apache::edit::end_row().
- &Apache::edit::start_spanning_row()."\n";
- } elsif ($target eq 'modified') {
- my $constructtag=&Apache::edit::get_new_args($token,$parstack,
- $safeeval,'max',
- 'randomize','direction');
- if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
- } elsif ($target eq 'tex') {
- my $type=&Apache::lonxml::get_param('TeXtype',$parstack,$safeeval,
- undef,0);
- if ($type eq '1') {
- $result .= ' \renewcommand{\labelenumi}{\arabic{enumi}.}';
- } elsif ($type eq 'A') {
- $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
- } elsif ($type eq 'a') {
- $result .= ' \renewcommand{\labelenumi}{\alph{enumi}.}';
- } elsif ($type eq 'i') {
- $result .= ' \renewcommand{\labelenumi}{\roman{enumi}.}';
- } else {
- $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
- }
- $result .= '\begin{enumerate}';
- } elsif ($target eq 'analyze') {
- my $part_id="$Apache::inputtags::part.$id";
- push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
+ 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' )
+ . ' ' 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";
+ }
+ elsif ( $target eq 'modified' ) {
+ my $constructtag =
+ &Apache::edit::get_new_args( $token, $parstack, $safeeval, 'max',
+ 'randomize', 'direction' );
+ if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
+ }
+ elsif ( $target eq 'tex' ) {
+ my $type =
+ &Apache::lonxml::get_param( 'TeXtype', $parstack, $safeeval, undef,
+ 0 );
+ if ( $type eq '1' ) {
+ $result .= ' \renewcommand{\labelenumi}{\arabic{enumi}.}';
+ }
+ elsif ( $type eq 'A' ) {
+ $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
+ }
+ elsif ( $type eq 'a' ) {
+ $result .= ' \renewcommand{\labelenumi}{\alph{enumi}.}';
+ }
+ elsif ( $type eq 'i' ) {
+ $result .= ' \renewcommand{\labelenumi}{\roman{enumi}.}';
+ }
+ else {
+ $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
+ }
+
+ }
+ 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;
}
sub end_radiobuttonresponse {
- my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+ 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 'edit' ) { $result = &Apache::edit::end_table(); }
+
&Apache::response::end_response;
pop @Apache::lonxml::namespace;
- &Apache::lonxml::deregister('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
+ &Apache::lonxml::deregister( 'Apache::radiobuttonresponse',
+ ( 'foilgroup', 'foil', 'conceptgroup' ) );
undef(%Apache::response::foilnames);
return $result;
}
-%Apache::response::foilgroup=();
+%Apache::response::foilgroup = ();
+
sub start_foilgroup {
- my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
- my $result;
- %Apache::response::foilgroup=();
- $Apache::radiobuttonresponse::conceptgroup=0;
- &Apache::response::pushrandomnumber();
- if ($target eq 'tex' && $Apache::lonhomework::type eq 'exam') {
- $result.='\item[\textbf{'.$Apache::lonxml::counter.'}.]';
- }
- return $result;
+ my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
+ @_;
+ %Apache::response::foilgroup = ();
+ $Apache::radiobuttonresponse::conceptgroup = 0;
+ &Apache::response::pushrandomnumber( undef, $target );
+ return;
}
sub storesurvey {
+ my ($style) = @_;
if ( !&Apache::response::submitted() ) { return ''; }
- my $response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
+ my $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
&Apache::lonxml::debug("Here I am!:$response:");
- if ( $response !~ /[0-9]+/) { return ''; }
- my $part = $Apache::inputtags::part;
- my $id = $Apache::inputtags::response['-1'];
- my @whichfoils=@{ $Apache::response::foilgroup{'names'} };
+ if ( $response !~ /[0-9]+/ ) { return ''; }
+ my $part = $Apache::inputtags::part;
+ my $id = $Apache::inputtags::response['-1'];
+ my @whichfoils = @{ $Apache::response::foilgroup{'names'} };
my %responsehash;
- $responsehash{$whichfoils[$response]}=$response;
- my $responsestr=&Apache::lonnet::hash2str(%responsehash);
- $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';
- &Apache::response::handle_previous(\%previous,$ad);
+ $responsehash{ $whichfoils[$response] } = $response;
+ my $responsestr = &Apache::lonnet::hash2str(%responsehash);
+ $Apache::lonhomework::results{"resource.$part.$id.submission"} =
+ $responsestr;
+ my %previous =
+ &Apache::response::check_for_previous( $responsestr, $part, $id );
+ 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_CREDIT';
+ }
+ 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;
- if ($env{'form.submitted'} eq 'scantron') {
- $response=&Apache::response::getresponse();
- } else {
- $response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
+
+ if ( $env{'form.submitted'} eq 'scantron' ) {
+ $response =
+ &Apache::response::getresponse( 1, undef,
+ &bubble_line_count( scalar( @{$whichfoils} ), $bubbles_per_line ),
+ $bubbles_per_line );
+
}
- if ( $response !~ /[0-9]+/) { return; }
- my $part=$Apache::inputtags::part;
- my $id = $Apache::inputtags::response['-1'];
+ else {
+ $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
+ }
+
+ if ( $response !~ /[0-9]+/ ) { return; }
+ my $part = $Apache::inputtags::part;
+ my $id = $Apache::inputtags::response['-1'];
my %responsehash;
- $responsehash{$whichfoils[$response]}=$response;
- my $responsestr=&Apache::lonnet::hash2str(%responsehash);
- my %previous=&Apache::response::check_for_previous($responsestr,
- $part,$id);
- $Apache::lonhomework::results{"resource.$part.$id.submission"}=
- $responsestr;
+ $responsehash{ $whichfoils->[$response] } = $response;
+ my $responsestr = &Apache::lonnet::hash2str(%responsehash);
+ my %previous =
+ &Apache::response::check_for_previous( $responsestr, $part, $id );
+ $Apache::lonhomework::results{"resource.$part.$id.submission"} =
+ $responsestr;
&Apache::lonxml::debug("submitted a $response \n");
my $ad;
- if ($response == $answer) {
- $ad='EXACT_ANS';
- } else {
- $ad='INCORRECT';
+
+ if ( $response == $answer ) {
+ $ad = 'EXACT_ANS';
+ }
+ else {
+ $ad = 'INCORRECT';
}
- $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=$ad;
- &Apache::response::handle_previous(\%previous,$ad);
+ $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} = $ad;
+ &Apache::response::handle_previous( \%previous, $ad );
}
sub end_foilgroup {
- my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+ my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
+ @_;
my $result;
- 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 ($target eq 'web' || $target eq 'tex') {
- $result=&displayallfoils($direction, $target);
- } elsif ( $target eq 'answer' ) {
- $result=&displayallanswers();
- } elsif ( $target eq 'grade' ) {
- $result=&storesurvey();
- }
- } else {
- my $name;
- my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,
- '-2');
- my $randomize = &Apache::lonxml::get_param('randomize',$parstack,
- $safeeval,'-2');
- if ($target eq 'web' || $target eq 'tex') {
- $result=&displayfoils($target,$max,$randomize,$direction);
- } elsif ($target eq 'answer' ) {
- $result=&displayanswers($max,$randomize);
- } elsif ( $target eq 'grade') {
- &grade_response($max,$randomize);
- } elsif ( $target eq 'analyze') {
- my @shown = &whichfoils($max,$randomize);
- &Apache::response::analyze_store_foilgroup(\@shown,
- ['text','value','location']);
- my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]";
- push (@{ $Apache::lonhomework::analyze{"$part_id.options"} },
- ('true','false'));
- }
- }
- $Apache::lonxml::post_evaluate=0;
- }
- if ($target eq 'web') {
- &Apache::response::setup_prior_tries_hash(\&format_prior_answer,
- [\%Apache::response::foilgroup]);
+ my $bubble_lines;
+ my $answer_count;
+ my $id = $Apache::inputtags::response['-1'];
+ my $part = $Apache::inputtags::part;
+ my $bubbles_per_line = &getbubblesnum( $part, $id );
+
+ 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' )
+ || ( $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($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, $answer, \@shown, $direction,
+ $bubbles_per_line );
+ }
+ elsif ( $target eq 'answer' ) {
+ $result =
+ &displayanswers( $answer, \@shown, $bubbles_per_line );
+ }
+ elsif ( $target eq 'grade' ) {
+ &grade_response( $answer, \@shown, $bubbles_per_line );
+ }
+ elsif ( $target eq 'analyze' ) {
+ my $bubble_lines =
+ &bubble_line_count( $answer_count, $bubbles_per_line );
+ &Apache::response::analyze_store_foilgroup( \@shown,
+ [ 'text', 'value', 'location' ] );
+ my $part_id = "$part.$id";
+ push(
+ @{ $Apache::lonhomework::analyze{"$part_id.options"} },
+ ( 'true', 'false' )
+ );
+
+ }
+ }
+ $Apache::lonxml::post_evaluate = 0;
+ }
+ if ( $target eq 'web' ) {
+ &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;
}
+sub getbubblesnum {
+ my ( $part, $id ) = @_;
+ my $bubbles_per_line;
+ my $default_numbubbles = $default_bubbles_per_line;
+ if ( ( $env{'form.bubbles_per_row'} =~ /^\d+$/ )
+ && ( $env{'form.bubbles_per_row'} > 0 ) )
+ {
+ $default_numbubbles = $env{'form.bubbles_per_row'};
+ }
+ $bubbles_per_line = &Apache::response::get_response_param( $part . "_$id",
+ 'numbubbles', $default_numbubbles );
+ return $bubbles_per_line;
+}
+
sub getfoilcounts {
my @names;
- my $truecnt=0;
- my $falsecnt=0;
+ my $truecnt = 0;
+ my $falsecnt = 0;
my $name;
if ( $Apache::response::foilgroup{'names'} ) {
- @names= @{ $Apache::response::foilgroup{'names'} };
+ @names = @{ $Apache::response::foilgroup{'names'} };
}
foreach $name (@names) {
- if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
- $truecnt++;
- } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
- $falsecnt++;
- }
+ if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
+ $truecnt++;
+ }
+ elsif ( $Apache::response::foilgroup{ $name . '.value' } eq 'false' ) {
+ $falsecnt++;
+ }
}
- return ($truecnt,$falsecnt);
+ return ( $truecnt, $falsecnt );
}
sub format_prior_answer {
- my ($mode,$answer,$other_data) = @_;
+ my ( $mode, $answer, $other_data ) = @_;
my $foil_data = $other_data->[0];
- my %response = &Apache::lonnet::str2hash($answer);
- my ($name) = keys(%response);
- return ''.
- $foil_data->{$name.'.text'}.'';
+ my %response = &Apache::lonnet::str2hash($answer);
+ my ($name) = keys(%response);
+ return
+ ''
+ . $foil_data->{ $name . '.text' }
+ . '';
}
-sub displayallfoils {
- my ($direction, $target)=@_;
+##
+sub displayallfoils{
+ my ( $direction, $target ) = @_;
my $result;
&Apache::lonxml::debug("survey style display");
my @names;
if ( $Apache::response::foilgroup{'names'} ) {
- @names= @{ $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"};
- if ($direction eq 'horizontal') { $result.='';
+ }
+
+ # Close tex bracketing:
+
+ if ($target eq 'tex') {
+ $result .= $end_environment;
}
- if (($direction eq 'horizontal') && ($target ne 'tex')) { $result.=' |
'; }
return $result;
}
sub whichfoils {
- my ($max,$randomize)=@_;
+ my ( $max, $randomize ) = @_;
my @truelist;
my @falselist;
- my @whichfalse =();
- my ($truecnt,$falsecnt) = &getfoilcounts();
- my $count=0;
+ my @whichfalse = ();
+ my ( $truecnt, $falsecnt ) = &getfoilcounts();
+ my $count = 0;
+
# we will add in 1 of the true statements
- if ( $max>0 && ($falsecnt+1)>$max) { $count=$max } else { $count=$falsecnt+1; $max=$count; }
- my $answer=int(&Math::Random::random_uniform() * ($count));
+ if ( $max > 0 && ( $falsecnt + 1 ) > $max ) { $count = $max }
+ else { $count = $falsecnt + 1; $max = $count; }
+ my $answer = int( &Math::Random::random_uniform() * ($count) );
&Apache::lonxml::debug("Count is $count, $answer is $answer");
my @names;
if ( $Apache::response::foilgroup{'names'} ) {
- @names= @{ $Apache::response::foilgroup{'names'} };
+ @names = @{ $Apache::response::foilgroup{'names'} };
}
- if (&Apache::response::showallfoils()) {
- @whichfalse=@names;
- } elsif ($randomize eq 'no') {
- &Apache::lonxml::debug("No randomization");
- my $havetrue=0;
- foreach my $name (@names) {
- if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
- if (!$havetrue ) {
- push(@whichfalse,$name); $havetrue++; $answer=$#whichfalse;
- }
- } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
- push (@whichfalse,$name);
- } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'unused') {
- } else {
- &Apache::lonxml::error(&HTML::Entities::encode("No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in