--- loncom/homework/radiobuttonresponse.pm 2002/09/23 19:09:52 1.48
+++ loncom/homework/radiobuttonresponse.pm 2002/09/25 19:39:49 1.50
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# mutliple choice style responses
#
-# $Id: radiobuttonresponse.pm,v 1.48 2002/09/23 19:09:52 albertel Exp $
+# $Id: radiobuttonresponse.pm,v 1.50 2002/09/25 19:39:49 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -101,13 +101,13 @@ sub storesurvey {
}
sub grade_response {
- my ($max,$answer,$randomize)=@_;
+ my ($max,$randomize)=@_;
if (!defined($ENV{'form.submitted'})) { return; }
my $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 @whichfoils=&whichfoils($max,$answer,$randomize);
+ my ($answer,@whichfoils)=&whichfoils($max,$randomize);
my %responsehash;
$responsehash{$whichfoils[$response]}=$response;
my $responsestr=&Apache::lonnet::hash2str(%responsehash);
@@ -140,20 +140,15 @@ sub end_foilgroup {
}
} else {
my $name;
- my ($truecnt,$falsecnt,$max) = &getfoilcounts($parstack,$safeeval);
- my $count=0;
- # we will add in 1 of the true statements
- if (($falsecnt+1)>$max) { $count=$max } else { $count=$falsecnt+1; }
- my $answer = int(rand ($count));
- &Apache::lonxml::debug("Answer is $answer, $count from $max, $falsecnt");
+ 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,$answer,$randomize);
+ $result=&displayfoils($target,$max,$randomize);
} elsif ($target eq 'answer' ) {
- $result=&displayanswers($max,$answer,$randomize);
+ $result=&displayanswers($max,$randomize);
} elsif ( $target eq 'grade') {
- &grade_response($max,$answer,$randomize);
+ &grade_response($max,$randomize);
}
}
}
@@ -161,8 +156,6 @@ sub end_foilgroup {
}
sub getfoilcounts {
- my ($parstack,$safeeval)=@_;
- my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2');
my @names;
my $truecnt=0;
my $falsecnt=0;
@@ -177,7 +170,7 @@ sub getfoilcounts {
$falsecnt++;
}
}
- return ($truecnt,$falsecnt,$max);
+ return ($truecnt,$falsecnt);
}
sub displayallfoils {
@@ -216,24 +209,31 @@ sub displayallfoils {
}
sub whichfoils {
- my ($max,$answer,$randomize)=@_;
+ my ($max,$randomize)=@_;
my @truelist;
my @falselist;
my @whichfalse =();
-
+ my ($truecnt,$falsecnt) = &getfoilcounts();
+ my $count=0;
+ # we will add in 1 of the true statements
+ if (($falsecnt+1)>$max) { $count=$max } else { $count=$falsecnt+1; }
+ my $answer=int(rand($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;
+ @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++; }
+ 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') {
@@ -242,38 +242,98 @@ sub whichfoils {
}
}
} else {
+ my $current=0;
+ &Apache::lonhomework::showhash(%Apache::response::foilgroup);
+ my (%top,%bottom);
+ #first find out where everyone wants to be
foreach my $name (@names) {
- #result.="
$name is $Apache::response::foilgroup{$name.'.value'} ";
- if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
- push (@truelist,$name);
- } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
- push (@falselist,$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 "));
- }
+ $current++;
+ if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
+ push (@truelist,$name);
+ if ($Apache::response::foilgroup{$name.'.location'} eq 'top') {
+ $top{$name}=$current;
+ } elsif ($Apache::response::foilgroup{$name.'.location'} eq 'bottom') {
+ $bottom{$name}=$current;
+ }
+ } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
+ push (@falselist,$name);
+ if ($Apache::response::foilgroup{$name.'.location'} eq 'top') {
+ $top{$name}=$current;
+ } elsif ($Apache::response::foilgroup{$name.'.location'} eq 'bottom') {
+ $bottom{$name}=$current;
+ }
+ } 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 "));
+ }
}
+ #pick a true statement
my $whichtrue = int(rand($#truelist+1));
&Apache::lonxml::debug("Max is $max, From $#truelist elms, picking $whichtrue");
- while ((($#whichfalse+1) < $max-1) && ($#falselist > -1)) {
- &Apache::lonxml::debug("Have $#whichfalse max is $max");
- my $afalse=int(rand($#falselist+1));
- &Apache::lonxml::debug("From $#falselist elms, picking $afalse");
- $afalse=splice(@falselist,$afalse,1);
- &Apache::lonxml::debug("Picked $afalse");
- push (@whichfalse,$afalse);
+ my $numinserted;
+ my (@toplist, @bottomlist);
+ my $topcount=0;
+ # assign everyone to either toplist/bottomlist or whichfalse
+ # which false is randomized, toplist bottomlist are in order
+ while ((($numinserted) < $max-1) && ($#falselist > -1)) {
+ &Apache::lonxml::debug("Have $#whichfalse max is $max");
+ my $afalse=int(rand($#falselist+1));
+ &Apache::lonxml::debug("From $#falselist elms, picking $afalse");
+ $afalse=splice(@falselist,$afalse,1);
+ &Apache::lonxml::debug("Picked $afalse");
+ &Apache::lonhomework::showhash(('names'=>\@names));
+ &Apache::lonhomework::showhash(%top);
+ if ($top{$afalse}) {
+ $toplist[$top{$afalse}]=$afalse;
+ $topcount++;
+ } elsif ($bottom{$afalse}) {
+ $bottomlist[$bottom{$afalse}]=$afalse;
+ } else {
+ push (@whichfalse,$afalse);
+ }
+ }
+ my $truename=$truelist[$whichtrue];
+ my $dosplice=1;
+ #insert the true statement, keeping track of where it wants to be
+ if ($Apache::response::foilgroup{$truename.'.location'} eq 'top' ) {
+ $toplist[$top{$truename}]=$truename;
+ $answer=-1;
+ foreach my $top (reverse(@toplist)) {
+ if ($top) { $answer++;}
+ if ($top eq $truename) { last; }
+ }
+ $dosplice=0;
+ } elsif ($Apache::response::foilgroup{$truename.'.location'} eq 'bottom') {
+ $bottomlist[$bottom{$truename}]=$truename;
+ $answer=-1;
+ foreach my $bot (@bottomlist) {
+ if ($bot) { $answer++;}
+ if ($bot eq $truename) { last; }
+ }
+ $answer+=$topcount+$#whichfalse+1;
+ $dosplice=0;
+ } else {
+ if ($topcount>0) { $answer = int(rand($#whichfalse+1))+$topcount; }
+ }
+ #add the top items to the top, bottom items to the bottom
+ for (my $i=0;$i<=$#toplist;$i++) {
+ if ($toplist[$i]) { unshift(@whichfalse,$toplist[$i]) }
+ }
+ for (my $i=0;$i<=$#bottomlist;$i++) {
+ if ($bottomlist[$i]) { push(@whichfalse,$bottomlist[$i]) }
}
- splice(@whichfalse,$answer,0,$truelist[$whichtrue]);
- &Apache::lonxml::debug("the true statement is $answer");
+ #if the true statement is randomized insert it into the list
+ if ($dosplice) { splice(@whichfalse,$answer,0,$truelist[$whichtrue]); }
}
- return @whichfalse;
+ &Apache::lonxml::debug("Answer is $answer");
+ return ($answer,@whichfalse);
}
sub displayfoils {
- my ($target,$max,$answer,$randomize)=@_;
+ my ($target,$max,$randomize)=@_;
my $result;
- my @whichfoils=&whichfoils($max,$answer,$randomize);
+ my ($answer,@whichfoils)=&whichfoils($max,$randomize);
if ($Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"} =~ /^correct/ || ($Apache::inputtags::status[-1] eq 'SHOW_ANSWER')) {
foreach my $name (@whichfoils) {
if ($target ne 'tex') {
@@ -317,8 +377,8 @@ sub displayfoils {
}
sub displayanswers {
- my ($max,$answer,$randomize)=@_;
- my @whichopt = &whichfoils($max,$answer,$randomize);
+ my ($max,$randomize)=@_;
+ my ($answer,@whichopt) = &whichfoils($max,$randomize);
my $result=&Apache::response::answer_header('radiobuttonresponse');
foreach my $name (@whichopt) {
$result.=&Apache::response::answer_part('radiobuttonresponse',
@@ -357,6 +417,7 @@ sub end_conceptgroup {
push @{ $Apache::response::foilgroup{'names'} }, $name;
$Apache::response::foilgroup{"$name.text"} = $Apache::response::conceptgroup{"$name.text"};
$Apache::response::foilgroup{"$name.value"} = $Apache::response::conceptgroup{"$name.value"};
+ $Apache::response::foilgroup{"$name.location"} = $Apache::response::conceptgroup{"$name.location"};
my $concept = &Apache::lonxml::get_param('concept',$parstack,$safeeval);
$Apache::response::foilgroup{"$name.concept"} = $concept;
&Apache::lonxml::debug("Selecting $name in $concept");
@@ -382,7 +443,7 @@ sub start_foil {
$result.=&Apache::edit::text_arg('Name:','name',$token);
$result.=&Apache::edit::select_or_text_arg('Correct Option:','value',
['unused','true','false'],$token);
- $result.=&Apache::edit::select_or_text_arg('Location:','location',
+ $result.=&Apache::edit::select_arg('Location:','location',
['random','bottom','top'],$token);
$result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
} elsif ($target eq 'modified') {