[LON-CAPA-cvs] cvs: loncom /homework radiobuttonresponse.pm

albertel lon-capa-cvs@mail.lon-capa.org
Mon, 23 Sep 2002 22:32:41 -0000


This is a MIME encoded message

--albertel1032820361
Content-Type: text/plain

albertel		Mon Sep 23 18:32:41 2002 EDT

  Modified files:              
    /loncom/homework	radiobuttonresponse.pm 
  Log:
  - all the possible ways one might derandomize are in here now, and athe answer is correct.
  - BUG#542
  
  
--albertel1032820361
Content-Type: text/plain
Content-Disposition: attachment; filename="albertel-20020923183241.txt"

Index: loncom/homework/radiobuttonresponse.pm
diff -u loncom/homework/radiobuttonresponse.pm:1.48 loncom/homework/radiobuttonresponse.pm:1.49
--- loncom/homework/radiobuttonresponse.pm:1.48	Mon Sep 23 15:09:52 2002
+++ loncom/homework/radiobuttonresponse.pm	Mon Sep 23 18:32:41 2002
@@ -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.49 2002/09/23 22:32:41 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -101,13 +101,13 @@
 }
 
 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 @@
       }
     } 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,7 @@
 }
 
 sub getfoilcounts {
-  my ($parstack,$safeeval)=@_;
-  my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2');
+  my ($max)=@_;
   my @names;
   my $truecnt=0;
   my $falsecnt=0;
@@ -216,24 +210,31 @@
 }
 
 sub whichfoils {
-  my ($max,$answer,$randomize)=@_;
+  my ($max,$randomize)=@_;
 
   my @truelist;
   my @falselist;
   my @whichfalse =();
-
+  my ($truecnt,$falsecnt,$max) = &getfoilcounts($max);
+  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 +243,98 @@
 	  }
       }
   } 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.="<br /><b>$name</b> is <i> $Apache::response::foilgroup{$name.'.value'} </i>";
-      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 <foilgroup>"));
-      }
+	$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 <foilgroup>"));
+	}
     }
+    #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 +378,8 @@
 }
 
 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 +418,7 @@
       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 +444,7 @@
     $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') {

--albertel1032820361--