--- loncom/homework/optionresponse.pm 2003/04/24 15:49:46 1.76 +++ loncom/homework/optionresponse.pm 2004/02/12 15:50:01 1.99 @@ -1,7 +1,7 @@ # LearningOnline Network with CAPA # option list style responses # -# $Id: optionresponse.pm,v 1.76 2003/04/24 15:49:46 albertel Exp $ +# $Id: optionresponse.pm,v 1.99 2004/02/12 15:50:01 sakharuk Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,8 +25,6 @@ # # http://www.lon-capa.org/ # -# 2/21 Guy -# 01/18 Alex package Apache::optionresponse; use strict; use Apache::response; @@ -45,7 +43,8 @@ sub start_optionresponse { %Apache::hint::option=(); if ($target eq 'edit') { $result.=&Apache::edit::start_table($token). - "<tr><td>Multiple Option Response Question</td><td>Delete:". + "<tr><td>Multiple Option Response Question ". + &Apache::loncommon::help_open_topic('Option_Response_Problems')."</td><td>Delete:". &Apache::edit::deletelist($target,$token) ."</td><td> ". &Apache::edit::end_row(). @@ -63,7 +62,7 @@ sub start_optionresponse { } elsif ($target eq 'meta') { $result=&Apache::response::meta_package_write('optionresponse'); } elsif ($target eq 'analyze') { - my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]"; + my $part_id="$Apache::inputtags::part.$id"; push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id); } return $result; @@ -151,10 +150,13 @@ sub end_foilgroup { 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') { + if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || + $target eq 'tex' || $target eq 'analyze') { + my $tex_option_switch=&Apache::lonxml::get_param('texoptions',$parstack,$safeeval); my $name; my @opt; eval '@opt ='.&Apache::lonxml::get_param('options',$parstack,$safeeval); + if ($target eq 'tex' && $tex_option_switch eq 'nochoice') {@opt=();} &Apache::lonxml::debug("Options are $#opt"); my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2'); my $randomize = &Apache::lonxml::get_param('randomize',$parstack, @@ -164,17 +166,11 @@ sub end_foilgroup { } elsif ( $target eq 'answer') { $result.=&displayanswers($max,$randomize,@opt); } elsif ( $target eq 'analyze') { - my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]"; - foreach my $name (@{ $Apache::response::foilgroup{'names'} }) { - if (defined($Apache::lonhomework::analyze{"$part_id.foil.value.$name"})) { next; } - push (@{ $Apache::lonhomework::analyze{"$part_id.foils"} },$name); - $Apache::lonhomework::analyze{"$part_id.foil.value.$name"} = - $Apache::response::foilgroup{"$name.value"}; - $Apache::lonhomework::analyze{"$part_id.foil.text.$name"} = - $Apache::response::foilgroup{"$name.text"}; - } - push (@{ $Apache::lonhomework::analyze{"$part_id.options"} },@opt); - push (@{ $Apache::lonhomework::analyze{"$part_id.shown"} },&whichfoils($max,$randomize)); + 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"} },@opt); } elsif ( $target eq 'grade') { if ( defined $ENV{'form.submitted'}) { my @whichopt = &whichfoils($max,$randomize); @@ -189,8 +185,8 @@ sub end_foilgroup { if ($ENV{'form.submitted'} eq 'scantron') { $response = $opt[$response]; } - $responsehash{$name}=$response; if ( $response =~ /[^\s]/) { + $responsehash{$name}=$response; my $value=$Apache::response::foilgroup{$name.'.value'}; &Apache::lonxml::debug("submitted a $response for $value<br />\n"); if ($value eq $response) { @@ -265,52 +261,10 @@ sub getfoilcounts { } sub whichfoils { - my ($max,$randomize)=@_; - $max = &getfoilcounts($max); - &Apache::lonxml::debug("randomize $randomize"); - if (!defined(@{ $Apache::response::foilgroup{'names'} })) {return;} - my @names = @{ $Apache::response::foilgroup{'names'} }; - my @whichopt =(); - my (%top,@toplist,%bottom,@bottomlist); - if (!(&Apache::response::showallfoils() || ($randomize eq 'no'))) { - my $current=0; - foreach my $name (@names) { - $current++; - if ($Apache::response::foilgroup{$name.'.location'} eq 'top') { - $top{$name}=$current; - } elsif ($Apache::response::foilgroup{$name.'.location'} eq - 'bottom') { - $bottom{$name}=$current; - } - } - } - while ((($#whichopt+1) < $max) && ($#names > -1)) { - &Apache::lonxml::debug("Have $#whichopt max is $max"); - my $aopt; - if (&Apache::response::showallfoils() || ($randomize eq 'no')) { - $aopt=0; - } else { - $aopt=int(&Math::Random::random_uniform() * ($#names+1)); - } - &Apache::lonxml::debug("From $#whichopt $max $#names elms, picking $aopt"); - $aopt=splice(@names,$aopt,1); - &Apache::lonxml::debug("Picked $aopt"); - if ($top{$aopt}) { - $toplist[$top{$aopt}]=$aopt; - } elsif ($bottom{$aopt}) { - $bottomlist[$bottom{$aopt}]=$aopt; - } else { - push (@whichopt,$aopt); - } - } - for (my $i=0;$i<=$#toplist;$i++) { - if ($toplist[$i]) { unshift(@whichopt,$toplist[$i]) } - } - for (my $i=0;$i<=$#bottomlist;$i++) { - if ($bottomlist[$i]) { push(@whichopt,$bottomlist[$i]) } - } - - return @whichopt; + my ($max,$randomize)=@_; + return &Apache::response::whichorder($max,$randomize, + &Apache::response::showallfoils(), + \%Apache::response::foilgroup); } sub displayanswers { @@ -333,7 +287,7 @@ sub displayfoils { my @names = @{ $Apache::response::foilgroup{'names'} }; my @truelist; my @falselist; - my $result; + my $result; my $name; my $displayoptionintex=0; my @alphabet = ('A'..'Z'); @@ -342,12 +296,13 @@ sub displayfoils { my $id=$Apache::inputtags::response[-1]; my $break; my $solved=$Apache::lonhomework::history{"resource.$part.solved"}; - my $status=$Apache::inputtags::status[-1]; - if ( - ($target ne 'tex') && - (($solved =~ /^correct/) || ($status eq 'SHOW_ANSWER')) ) { + if ( ($target ne 'tex') && + &Apache::response::show_answer() ) { + my $temp=1; foreach $name (@whichopt) { my $text=$Apache::response::foilgroup{$name.'.text'}; + my %lastresponse=&Apache::lonnet::str2hash($Apache::lonhomework::history{"resource.$part.$id.submission"}); + my $lastopt=$lastresponse{$name}; if ($text!~/^\s*$/) { if ($target eq 'tex') { $break='\vskip 0 mm '; @@ -364,24 +319,29 @@ sub displayfoils { } else { $text=$value.': '.$text; } + } else { + $text='•'.$text; } $result.=$text."\n"; } elsif ($target eq 'tex') { $Apache::response::foilgroup{$name.'.text'}=~s/\\item//; - $result .='\item \textit{'.$Apache::response::foilgroup{$name.'.value'}.'}'. + if ($max>1) {$result .='\item ';} + $result .=' \textit{'.$Apache::response::foilgroup{$name.'.value'}.'}'. ":".$Apache::response::foilgroup{$name.'.text'}."\n"; } if ($Apache::lonhomework::type eq 'exam') { if ($target ne 'tex') { - $result.=&webbubbles(\@opt,\@alphabet); + $result.=&webbubbles(\@opt,\@alphabet,$temp,$lastopt); } else { $result.=&bubbles(\@alphabet,\@opt); } } + $temp++; } } else { my $temp=1; my %lastresponse=&Apache::lonnet::str2hash($Apache::lonhomework::history{"resource.$part.$id.submission"}); + my $internal_counter=$Apache::lonxml::counter; foreach $name (@whichopt) { my $text=$Apache::response::foilgroup{$name.'.text'}; if ($text!~/^\s*$/) { @@ -410,10 +370,12 @@ sub displayfoils { my $text=$Apache::response::foilgroup{$name.'.text'}; if (!($text=~s|<drawoptionlist\s*/>|$optionlist|) && $Apache::lonhomework::type ne 'exam') { $text=$optionlist.$text; + } else { + $text='•'.$text; } $result.=$break.$text."\n"; if ($Apache::lonhomework::type eq 'exam') { - $result.=&webbubbles(\@opt,\@alphabet,$temp); + $result.=&webbubbles(\@opt,\@alphabet,$temp,$lastopt); } $temp++; } else { @@ -436,7 +398,8 @@ sub displayfoils { } } if ($Apache::lonhomework::type eq 'exam') { - $result.='\vskip -2 mm\parbox{\textwidth}{\begin{enumerate}\item[\textbf{'.$Apache::lonxml::counter.'}.]\parbox{\textwidth - 5 mm}{'.&bubbles(\@alphabet,\@opt).'}\end{enumerate}} \vskip -9 mm \strut '; + $result.='\vskip -1 mm\noindent\begin{enumerate}\item[\textbf{'.$internal_counter.'}.]'.&bubbles(\@alphabet,\@opt).'\end{enumerate} \vskip -9 mm \strut '; + $internal_counter++; } $displayoptionintex=1; } else { @@ -456,7 +419,8 @@ sub displayfoils { } } if ($Apache::lonhomework::type eq 'exam') { - $result.='\vskip -2 mm \parbox{\textwidth}{\begin{enumerate}\item[\textbf{'.$Apache::lonxml::counter.'}.]\parbox{\textwidth - 5 mm}{'.&bubbles(\@alphabet,\@opt).'}\end{enumerate}} \vskip -9 mm \strut '; + $result.='\vskip -1 mm \noindent\begin{enumerate}\item[\textbf{'.$internal_counter.'}.]'.&bubbles(\@alphabet,\@opt).'\end{enumerate} \vskip -9 mm \strut '; + $internal_counter++; } } } @@ -473,33 +437,43 @@ sub displayfoils { sub optionlist_correction { my $texoptionlist = shift; - $texoptionlist =~ s/<option><\/option>/\\item \[\] Possible answers are:/; - $texoptionlist =~ s/<option>/\{\\bf /g; - $texoptionlist =~ s/<option selected="on">/\{\\bf /g; - $texoptionlist =~ s/<\/option>/\},/g; - $texoptionlist =~ s/,$/\./g; - $texoptionlist =~ s/>/\$>\$/g; - $texoptionlist =~ s/</\$<\$/g; - $texoptionlist =~ s/=/\$=\$/g; - $texoptionlist =~ s/\^(\d+)/<m>\$$1\$<\/m>/g; + if ($texoptionlist=~/<option selected/ or $texoptionlist=~/<option>[^<]+<\/option>/) { + $texoptionlist =~ s/<option><\/option>/\\item \[\] Choices: /; + $texoptionlist =~ s/<option>/\{\\bf /g; + $texoptionlist =~ s/<option selected="on">/\{\\bf /g; + $texoptionlist =~ s/<\/option>/\},/g; + $texoptionlist =~ s/,$/\./g; + $texoptionlist =~ s/>/\$>\$/g; + $texoptionlist =~ s/</\$<\$/g; + $texoptionlist =~ s/=/\$=\$/g; + $texoptionlist =~ s/\^(\d+)/\$^{$1}\$/g; + } else { + $texoptionlist =~ s/<option><\/option>/\\item \[\] \\vskip -5 mm/; + } return $texoptionlist; } sub webbubbles { - my ($ropt,$ralphabet,$temp)=@_; + my ($ropt,$ralphabet,$temp,$lastopt)=@_; my @opt=@$ropt; my @alphabet=@$ralphabet; my $result=''; - my $number_of_bubbles = $#opt + 1; - $result.= '<table border="1"><tr>'; - for (my $ind=0;$ind<$number_of_bubbles;$ind++) { - $result.='<td><input type="radio" name="HWVAL_'.$Apache::inputtags::response['-1'].':'.$temp. - '" value='.$opt[$ind].'>'.$alphabet[$ind].': '.$opt[$ind].'</td>'; + my $number_of_bubbles = $#opt + 1; + $result.= '<table border="1"><tr>'; + for (my $ind=0;$ind<$number_of_bubbles;$ind++) { + my $checked=''; + if ($lastopt eq $opt[$ind]) { + $checked=' checked="on" '; } - $result.='</tr></table>'; - return $result; + $result.='<td><input type="radio" name="HWVAL_'. + $Apache::inputtags::response['-1'].':'.$temp. + '" value="'.$opt[$ind].'" '.$checked.' />'.$alphabet[$ind].': '. + $opt[$ind].'</td>'; + } + $result.='</tr></table>'; + return $result; } @@ -511,14 +485,18 @@ sub bubbles { my ($result,$head,$line) =('','',''); my $number_of_bubbles = $#opt + 1; my $current_length = 0; + $ENV{'form.textwidth'}=~/(\d+)/; + my $textwidth=$1; for (my $ind=0;$ind<=$number_of_bubbles;$ind++) { - $current_length += (length($opt[$ind])+length($alphabet[$ind])+2)*2; - if ($current_length<0.9*$ENV{'form.textwidth'} and $ind!=$number_of_bubbles) { + my $leftmargin; + if ($ind==0) {$leftmargin=6;} else {$leftmargin=10;} + $current_length += (length($opt[$ind])+length($alphabet[$ind])+3)*2; + if ($current_length<($textwidth-$leftmargin) and $ind!=$number_of_bubbles) { $line.='\hskip -1 mm {\small \textbf{'.$alphabet[$ind].'}}$\bigcirc$\hskip -1 mm & \hskip -3 mm {\small '.$opt[$ind].'} & '; $head.='lr'; } else { $line=~s/\&\s*$//; - $result.='\vskip -5 mm\begin{tabular}{'.$head.'}\\\\'.$line.'\\\\\end{tabular}'; + $result.='\vskip -2 mm\noindent\begin{tabular}{'.$head.'}'.$line.'\\\\\end{tabular}'; $line = '\hskip -1 mm {\small \textbf{'.$alphabet[$ind].'}}$\bigcirc$\hskip -1 mm & \hskip -3 mm {\small '.$opt[$ind].'} & ';; $head ='lr'; $current_length = (length($opt[$ind])+length($alphabet[$ind]))*2; @@ -550,47 +528,13 @@ sub end_conceptgroup { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; $Apache::optionresponse::conceptgroup=0; my $result=''; - if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' - || $target eq 'tex' || $target eq 'analyze') { + if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || + $target eq 'tex' || $target eq 'analyze') { #if not there aren't any foils to display and thus no question - if (defined(@{ $Apache::response::conceptgroup{'names'} })) { - my @names = @{ $Apache::response::conceptgroup{'names'} }; - my $pick=int(&Math::Random::random_uniform() * ($#names+1)); - my $name=$names[$pick]; - push @{ $Apache::response::foilgroup{'names'} }, $name; - $Apache::response::foilgroup{"$name.value"} = - $Apache::response::conceptgroup{"$name.value"}; - $Apache::response::foilgroup{"$name.text"} = - $Apache::response::conceptgroup{"$name.text"}; - $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"); - if ($target eq 'analyze') { - my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]"; - push (@{ $Apache::lonhomework::analyze{"$part_id.concepts"} }, - $concept); - $Apache::lonhomework::analyze{"$part_id.concept.$concept"}= - $Apache::response::conceptgroup{'names'}; - foreach my $name (@{ $Apache::response::conceptgroup{'names'} }) { - push (@{ $Apache::lonhomework::analyze{"$part_id.foils"} }, - $name); - $Apache::lonhomework::analyze{"$part_id.foil.value.$name"} = - $Apache::response::conceptgroup{"$name.value"}; - $Apache::lonhomework::analyze{"$part_id.foil.text.$name"} = - $Apache::response::conceptgroup{"$name.text"}; - $Apache::lonhomework::analyze{"$part_id.foil.location.$name"} = - $Apache::response::conceptgroup{"$name.location"}; - } - } elsif ($target eq 'web') { - my $part_id="$Apache::inputtags::part.$Apache::inputtags::response[-1]"; - push(@{ $Apache::hint::option{"$part_id.concepts"} }, - $concept); - $Apache::hint::option{"$part_id.concept.$concept"}= - $Apache::response::conceptgroup{'names'}; - } - } + &Apache::response::pick_foil_for_concept($target, + ['value','text','location'], + \%Apache::hint::option, + $parstack,$safeeval); } elsif ($target eq 'edit') { $result=&Apache::edit::end_table(); } @@ -635,7 +579,7 @@ sub end_foil { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $text =''; my $result = ''; - if ($target eq 'web' || $target eq 'tex') { + if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') { $text=&Apache::lonxml::endredirection; if ($target eq 'tex' and $Apache::lonhomework::type ne 'exam') { $text = '\vspace*{-2 mm}\item '.$text; } } @@ -655,24 +599,16 @@ sub end_foil { if ($target eq 'tex' and $Apache::lonhomework::type eq 'exam') { $Apache::response::conceptgroup{"$name.text"} = '\vskip 4 mm $\triangleright$ '.$text; } else { - if ($target eq 'tex' and $Apache::lonhomework::type eq 'exam') { - $Apache::response::conceptgroup{"$name.text"} = ' $\triangleright$ '.$text; - } else { - $Apache::response::conceptgroup{"$name.text"} = $text; - } + $Apache::response::conceptgroup{"$name.text"} = $text; } $Apache::response::conceptgroup{"$name.location"} = $location; } else { push @{ $Apache::response::foilgroup{'names'} }, $name; $Apache::response::foilgroup{"$name.value"} = $value; - if ($Apache::lonhomework::type eq 'exam') { + if ($target eq 'tex' and $Apache::lonhomework::type eq 'exam') { $Apache::response::foilgroup{"$name.text"} = '\vskip 5 mm $\triangleright$ '.$text; } else { - if ($target eq 'tex' and $Apache::lonhomework::type eq 'exam') { - $Apache::response::foilgroup{"$name.text"} = ' $\triangleright$ '.$text; - } else { - $Apache::response::foilgroup{"$name.text"} = $text; - } + $Apache::response::foilgroup{"$name.text"} = $text; } $Apache::response::foilgroup{"$name.location"} = $location; }