Annotation of loncom/homework/radiobuttonresponse.pm, revision 1.153.6.1

1.22      albertel    1: # The LearningOnline Network with CAPA
                      2: # mutliple choice style responses
1.31      albertel    3: #
1.153.6.1! foxr        4: # $Id: radiobuttonresponse.pm,v 1.153 2012/01/05 11:56:34 foxr Exp $
1.31      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
1.130     foxr       21: # along with LON-CAPA; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1.31      albertel   22: #
                     23: # /home/httpd/html/adm/gpl.txt
                     24: #
                     25: # http://www.lon-capa.org/
                     26: #
1.1       albertel   27: 
                     28: package Apache::radiobuttonresponse;
                     29: use strict;
1.42      albertel   30: use HTML::Entities();
1.85      albertel   31: use Apache::lonlocal;
1.100     albertel   32: use Apache::lonnet;
1.115     foxr       33: use Apache::response;
1.1       albertel   34: 
1.120     foxr       35: my $default_bubbles_per_line = 10;
1.121     foxr       36: 
1.36      harris41   37: BEGIN {
1.153     foxr       38:     &Apache::lonxml::register( 'Apache::radiobuttonresponse',
                     39:         ('radiobuttonresponse') );
1.1       albertel   40: }
                     41: 
1.121     foxr       42: sub bubble_line_count {
1.153     foxr       43:     my ( $numfoils, $bubbles_per_line ) = @_;
1.121     foxr       44:     my $bubble_lines;
1.153     foxr       45:     $bubble_lines = int( $numfoils / $bubbles_per_line );
                     46:     if ( ( $numfoils % $bubbles_per_line ) != 0 ) {
                     47:         $bubble_lines++;
1.121     foxr       48:     }
                     49:     return $bubble_lines;
1.153     foxr       50: 
1.121     foxr       51: }
                     52: 
1.1       albertel   53: sub start_radiobuttonresponse {
1.153     foxr       54:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                     55:       @_;
1.83      albertel   56:     my $result;
1.115     foxr       57: 
1.83      albertel   58:     #when in a radiobutton response use these
1.153     foxr       59:     &Apache::lonxml::register( 'Apache::radiobuttonresponse',
                     60:         ( 'foilgroup', 'foil', 'conceptgroup' ) );
                     61:     push( @Apache::lonxml::namespace, 'radiobuttonresponse' );
                     62:     my $id = &Apache::response::start_response( $parstack, $safeeval );
1.120     foxr       63: 
1.153     foxr       64:     %Apache::hint::radiobutton = ();
1.85      albertel   65:     undef(%Apache::response::foilnames);
1.153     foxr       66:     if ( $target eq 'meta' ) {
                     67:         $result = &Apache::response::meta_package_write('radiobuttonresponse');
                     68:     }
                     69:     elsif ( $target eq 'edit' ) {
                     70:         $result .=
                     71:             &Apache::edit::start_table($token)
                     72:           . '<tr><td>'
                     73:           . &Apache::lonxml::description($token)
                     74:           . &Apache::loncommon::help_open_topic('Radio_Response_Problems')
                     75:           . '</td>'
                     76:           . '<td><span class="LC_nobreak">'
                     77:           . &mt('Delete?') . ' '
                     78:           . &Apache::edit::deletelist( $target, $token )
                     79:           . '</span></td>'
                     80:           . '<td>&nbsp;'
                     81:           . &Apache::edit::end_row()
                     82:           . &Apache::edit::start_spanning_row();
                     83:         $result .= &Apache::edit::text_arg( 'Max Number Of Shown Foils:',
                     84:             'max', $token, '4' )
                     85:           . '&nbsp;' x 3
                     86:           . &Apache::edit::select_arg( 'Randomize Foil Order:',
                     87:             'randomize', [ 'yes', 'no' ], $token )
                     88:           . '&nbsp;' x 3
                     89:           . &Apache::edit::select_arg(
                     90:             'Display Direction:', 'direction',
                     91:             [ 'vertical', 'horizontal' ], $token
                     92:           )
                     93:           . &Apache::edit::end_row()
                     94:           . &Apache::edit::start_spanning_row() . "\n";
                     95:     }
                     96:     elsif ( $target eq 'modified' ) {
                     97:         my $constructtag =
                     98:           &Apache::edit::get_new_args( $token, $parstack, $safeeval, 'max',
                     99:             'randomize', 'direction' );
                    100:         if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                    101:     }
                    102:     elsif ( $target eq 'tex' ) {
                    103:         my $type =
                    104:           &Apache::lonxml::get_param( 'TeXtype', $parstack, $safeeval, undef,
                    105:             0 );
                    106:         if ( $type eq '1' ) {
                    107:             $result .= ' \renewcommand{\labelenumi}{\arabic{enumi}.}';
                    108:         }
                    109:         elsif ( $type eq 'A' ) {
                    110:             $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
                    111:         }
                    112:         elsif ( $type eq 'a' ) {
                    113:             $result .= ' \renewcommand{\labelenumi}{\alph{enumi}.}';
                    114:         }
                    115:         elsif ( $type eq 'i' ) {
                    116:             $result .= ' \renewcommand{\labelenumi}{\roman{enumi}.}';
                    117:         }
                    118:         else {
                    119:             $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
                    120:         }
                    121:         if (   $env{'form.pdfFormFields'} eq 'yes'
                    122:             && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                    123:         {
1.145     onken     124:             $result .= '\begin{itemize}';
1.153     foxr      125:         }
                    126:         else {
1.135     onken     127:             $result .= '\begin{enumerate}';
                    128:         }
1.153     foxr      129:     }
                    130:     elsif ( $target eq 'analyze' ) {
                    131:         my $part_id = "$Apache::inputtags::part.$id";
1.131     raeburn   132:         $Apache::lonhomework::analyze{"$part_id.type"} = 'radiobuttonresponse';
1.153     foxr      133:         push( @{ $Apache::lonhomework::analyze{"parts"} }, $part_id );
1.83      albertel  134:     }
                    135:     return $result;
1.1       albertel  136: }
                    137: 
                    138: sub end_radiobuttonresponse {
1.153     foxr      139:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                    140:       @_;
1.83      albertel  141:     my $result;
1.153     foxr      142:     if ( $target eq 'edit' ) { $result = &Apache::edit::end_table(); }
                    143:     if ( $target eq 'tex' ) {
                    144:         if (    $env{'form.pdfFormFields'} eq 'yes'
                    145:             and $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                    146:         {
1.145     onken     147:             $result .= '\end{itemize}';
1.153     foxr      148:         }
                    149:         else {
1.145     onken     150:             $result .= '\end{enumerate}';
                    151:         }
1.135     onken     152:     }
1.83      albertel  153:     &Apache::response::end_response;
                    154:     pop @Apache::lonxml::namespace;
1.153     foxr      155:     &Apache::lonxml::deregister( 'Apache::radiobuttonresponse',
                    156:         ( 'foilgroup', 'foil', 'conceptgroup' ) );
1.85      albertel  157:     undef(%Apache::response::foilnames);
1.83      albertel  158:     return $result;
1.1       albertel  159: }
                    160: 
1.153     foxr      161: %Apache::response::foilgroup = ();
                    162: 
1.1       albertel  163: sub start_foilgroup {
1.153     foxr      164:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                    165:       @_;
                    166:     %Apache::response::foilgroup               = ();
                    167:     $Apache::radiobuttonresponse::conceptgroup = 0;
                    168:     &Apache::response::pushrandomnumber( undef, $target );
1.151     raeburn   169:     return;
1.5       albertel  170: }
                    171: 
1.15      albertel  172: sub storesurvey {
1.144     raeburn   173:     my ($style) = @_;
1.99      albertel  174:     if ( !&Apache::response::submitted() ) { return ''; }
1.153     foxr      175:     my $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
1.83      albertel  176:     &Apache::lonxml::debug("Here I am!:$response:");
1.153     foxr      177:     if ( $response !~ /[0-9]+/ ) { return ''; }
                    178:     my $part       = $Apache::inputtags::part;
                    179:     my $id         = $Apache::inputtags::response['-1'];
                    180:     my @whichfoils = @{ $Apache::response::foilgroup{'names'} };
1.83      albertel  181:     my %responsehash;
1.153     foxr      182:     $responsehash{ $whichfoils[$response] } = $response;
                    183:     my $responsestr = &Apache::lonnet::hash2str(%responsehash);
                    184:     $Apache::lonhomework::results{"resource.$part.$id.submission"} =
                    185:       $responsestr;
                    186:     my %previous =
                    187:       &Apache::response::check_for_previous( $responsestr, $part, $id );
1.144     raeburn   188:     my $ad;
1.153     foxr      189: 
                    190:     if ( $style eq 'anonsurvey' ) {
                    191:         $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
                    192:           'ANONYMOUS';
                    193:     }
                    194:     elsif ( $style eq 'anonsurveycred' ) {
                    195:         $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
                    196:           'ANONYMOUS_CREDIT';
                    197:     }
                    198:     elsif ( $style eq 'surveycred' ) {
                    199:         $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
                    200:           'SUBMITTED_CREDIT';
                    201:     }
                    202:     else {
                    203:         $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
                    204:           'SUBMITTED';
1.144     raeburn   205:     }
1.153     foxr      206:     &Apache::response::handle_previous( \%previous, $ad );
1.83      albertel  207:     &Apache::lonxml::debug("submitted a $response<br />\n");
                    208:     return '';
1.15      albertel  209: }
                    210: 
1.32      albertel  211: sub grade_response {
1.153     foxr      212:     my ( $answer, $whichfoils, $bubbles_per_line ) = @_;
1.123     albertel  213: 
1.99      albertel  214:     if ( !&Apache::response::submitted() ) { return; }
1.83      albertel  215:     my $response;
1.116     foxr      216: 
1.153     foxr      217:     if ( $env{'form.submitted'} eq 'scantron' ) {
                    218:         $response =
                    219:           &Apache::response::getresponse( 1, undef,
                    220:             &bubble_line_count( scalar( @{$whichfoils} ), $bubbles_per_line ),
                    221:             $bubbles_per_line );
                    222: 
                    223:     }
                    224:     else {
                    225:         $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
1.83      albertel  226:     }
1.120     foxr      227: 
1.153     foxr      228:     if ( $response !~ /[0-9]+/ ) { return; }
                    229:     my $part = $Apache::inputtags::part;
                    230:     my $id   = $Apache::inputtags::response['-1'];
1.83      albertel  231:     my %responsehash;
1.153     foxr      232:     $responsehash{ $whichfoils->[$response] } = $response;
                    233:     my $responsestr = &Apache::lonnet::hash2str(%responsehash);
                    234:     my %previous =
                    235:       &Apache::response::check_for_previous( $responsestr, $part, $id );
                    236:     $Apache::lonhomework::results{"resource.$part.$id.submission"} =
                    237:       $responsestr;
1.83      albertel  238:     &Apache::lonxml::debug("submitted a $response<br />\n");
                    239:     my $ad;
1.153     foxr      240: 
                    241:     if ( $response == $answer ) {
                    242:         $ad = 'EXACT_ANS';
                    243:     }
                    244:     else {
                    245:         $ad = 'INCORRECT';
1.83      albertel  246:     }
1.153     foxr      247:     $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} = $ad;
                    248:     &Apache::response::handle_previous( \%previous, $ad );
1.32      albertel  249: }
                    250: 
1.1       albertel  251: sub end_foilgroup {
1.153     foxr      252:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                    253:       @_;
1.29      albertel  254: 
1.83      albertel  255:     my $result;
1.121     foxr      256:     my $bubble_lines;
                    257:     my $answer_count;
1.153     foxr      258:     my $id               = $Apache::inputtags::response['-1'];
                    259:     my $part             = $Apache::inputtags::part;
                    260:     my $bubbles_per_line = &getbubblesnum( $part, $id );
                    261: 
                    262:     if (   $target eq 'grade'
                    263:         || $target eq 'web'
                    264:         || $target eq 'answer'
                    265:         || $target eq 'tex'
                    266:         || $target eq 'analyze' )
                    267:     {
                    268:         my $style = $Apache::lonhomework::type;
                    269:         my $direction =
                    270:           &Apache::lonxml::get_param( 'direction', $parstack, $safeeval, '-2' );
                    271:         if (
                    272:             (
                    273:                    ( $style eq 'survey' )
                    274:                 || ( $style eq 'surveycred' )
                    275:                 || ( $style eq 'anonsurvey' )
                    276:                 || ( $style eq 'anonsurveycred' )
                    277:             )
                    278:             && ( $target ne 'analyze' )
                    279:           )
                    280:         {
                    281:             if ( $target eq 'web' || $target eq 'tex' ) {
                    282:                 $result = &displayallfoils( $direction, $target );
                    283:             }
                    284:             elsif ( $target eq 'answer' ) {
                    285:                 $result = &displayallanswers();
                    286:             }
                    287:             elsif ( $target eq 'grade' ) {
                    288:                 $result = &storesurvey($style);
                    289:             }
                    290:             $answer_count =
                    291:               scalar( @{ $Apache::response::foilgroup{'names'} } );
                    292: 
                    293:         }
                    294:         else {
                    295: 
                    296:             my $name;
                    297:             my $max =
                    298:               &Apache::lonxml::get_param( 'max', $parstack, $safeeval, '-2' );
                    299:             my $randomize =
                    300:               &Apache::lonxml::get_param( 'randomize', $parstack, $safeeval,
                    301:                 '-2' );
                    302:             my ( $answer, @shown ) = &whichfoils( $max, $randomize );
                    303:             $answer_count = scalar(@shown);
                    304: 
                    305:             if ( $target eq 'web' || $target eq 'tex' ) {
                    306:                 $result =
                    307:                   &displayfoils( $target, $answer, \@shown, $direction,
                    308:                     $bubbles_per_line );
                    309:             }
                    310:             elsif ( $target eq 'answer' ) {
                    311:                 $result =
                    312:                   &displayanswers( $answer, \@shown, $bubbles_per_line );
                    313:             }
                    314:             elsif ( $target eq 'grade' ) {
                    315:                 &grade_response( $answer, \@shown, $bubbles_per_line );
                    316:             }
                    317:             elsif ( $target eq 'analyze' ) {
                    318:                 my $bubble_lines =
                    319:                   &bubble_line_count( $answer_count, $bubbles_per_line );
                    320:                 &Apache::response::analyze_store_foilgroup( \@shown,
                    321:                     [ 'text', 'value', 'location' ] );
                    322:                 my $part_id = "$part.$id";
                    323:                 push(
                    324:                     @{ $Apache::lonhomework::analyze{"$part_id.options"} },
                    325:                     ( 'true', 'false' )
                    326:                 );
1.121     foxr      327: 
1.153     foxr      328:             }
                    329:         }
                    330:         $Apache::lonxml::post_evaluate = 0;
                    331:     }
                    332:     if ( $target eq 'web' ) {
                    333:         &Apache::response::setup_prior_tries_hash( \&format_prior_answer,
                    334:             [ \%Apache::response::foilgroup ] );
1.114     albertel  335:     }
1.128     foxr      336:     &Apache::response::poprandomnumber();
1.153     foxr      337:     $bubble_lines = &bubble_line_count( $answer_count, $bubbles_per_line );
                    338:     &Apache::lonxml::increment_counter( $bubble_lines, "$part.$id" );
                    339:     if ( $target eq 'analyze' ) {
                    340:         &Apache::lonhomework::set_bubble_lines();
1.128     foxr      341:     }
1.83      albertel  342:     return $result;
1.6       albertel  343: }
                    344: 
1.151     raeburn   345: sub getbubblesnum {
1.153     foxr      346:     my ( $part, $id ) = @_;
1.151     raeburn   347:     my $bubbles_per_line;
                    348:     my $default_numbubbles = $default_bubbles_per_line;
1.153     foxr      349:     if (   ( $env{'form.bubbles_per_row'} =~ /^\d+$/ )
                    350:         && ( $env{'form.bubbles_per_row'} > 0 ) )
                    351:     {
1.151     raeburn   352:         $default_numbubbles = $env{'form.bubbles_per_row'};
                    353:     }
1.153     foxr      354:     $bubbles_per_line = &Apache::response::get_response_param( $part . "_$id",
                    355:         'numbubbles', $default_numbubbles );
1.151     raeburn   356:     return $bubbles_per_line;
                    357: }
                    358: 
1.6       albertel  359: sub getfoilcounts {
1.83      albertel  360:     my @names;
1.153     foxr      361:     my $truecnt  = 0;
                    362:     my $falsecnt = 0;
1.83      albertel  363:     my $name;
                    364:     if ( $Apache::response::foilgroup{'names'} ) {
1.153     foxr      365:         @names = @{ $Apache::response::foilgroup{'names'} };
1.6       albertel  366:     }
1.83      albertel  367:     foreach $name (@names) {
1.153     foxr      368:         if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
                    369:             $truecnt++;
                    370:         }
                    371:         elsif ( $Apache::response::foilgroup{ $name . '.value' } eq 'false' ) {
                    372:             $falsecnt++;
                    373:         }
1.83      albertel  374:     }
1.153     foxr      375:     return ( $truecnt, $falsecnt );
1.5       albertel  376: }
                    377: 
1.114     albertel  378: sub format_prior_answer {
1.153     foxr      379:     my ( $mode, $answer, $other_data ) = @_;
1.114     albertel  380:     my $foil_data = $other_data->[0];
1.153     foxr      381:     my %response  = &Apache::lonnet::str2hash($answer);
                    382:     my ($name)    = keys(%response);
                    383:     return
                    384:         '<span class="LC_prior_radiobutton">'
                    385:       . $foil_data->{ $name . '.text' }
                    386:       . '</span>';
1.114     albertel  387: 
1.112     albertel  388: }
                    389: 
1.153.6.1! foxr      390: ##
1.15      albertel  391: sub displayallfoils {
1.153     foxr      392:     my ( $direction, $target ) = @_;
1.83      albertel  393:     my $result;
                    394:     &Apache::lonxml::debug("survey style display");
1.106     albertel  395:     my @names;
                    396:     if ( $Apache::response::foilgroup{'names'} ) {
1.153     foxr      397:         @names = @{ $Apache::response::foilgroup{'names'} };
1.106     albertel  398:     }
1.120     foxr      399: 
1.153     foxr      400:     my $temp = 0;
                    401:     my $i    = 0;
                    402:     my $id   = $Apache::inputtags::response['-1'];
                    403:     my $part = $Apache::inputtags::part;
                    404:     my ( $lastresponse, $newvariation, $showanswer );
                    405:     if (
                    406:         (
                    407:             (
                    408:                 $Apache::lonhomework::history{"resource.$part.type"} eq
                    409:                 'randomizetry'
                    410:             )
                    411:             || ( $Apache::lonhomework::type eq 'randomizetry' )
                    412:         )
                    413:         && ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                    414:       )
                    415:     {
                    416:         if ( $env{ 'form.' . $part . '.rndseed' } ne
                    417:             $Apache::lonhomework::history{"resource.$part.rndseed"} )
                    418:         {
1.147     raeburn   419:             $newvariation = 1;
                    420:         }
                    421:     }
                    422:     $showanswer = &Apache::response::show_answer();
1.153     foxr      423:     unless (
                    424:         (
                    425:             (
                    426:                 $Apache::lonhomework::history{"resource.$part.type"} eq
                    427:                 'anonsurvey'
                    428:             )
                    429:             || ( $Apache::lonhomework::history{"resource.$part.type"} eq
                    430:                 'anonsurveycred' )
                    431:         )
                    432:         && ( defined( $env{'form.grade_symb'} ) )
                    433:         || ( $newvariation && !$showanswer )
                    434:       )
                    435:     {
                    436:         $lastresponse =
                    437:           $Apache::lonhomework::history{"resource.$part.$id.submission"};
1.144     raeburn   438:     }
1.153     foxr      439:     if ( $direction eq 'horizontal' ) { $result .= '<table><tr>'; }
                    440:     my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
1.147     raeburn   441:     if ($showanswer) {
1.153     foxr      442:         foreach my $name (@names) {
                    443:             if ( $Apache::response::foilgroup{ $name . '.value' } ne 'unused' )
                    444:             {
                    445:                 if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
                    446:                     $result .= "<td>";
                    447:                 }
                    448:                 else {
                    449:                     if ( $target eq 'tex' ) {
                    450:                         $result .= '\item \vskip -2mm ';
                    451:                     }
                    452:                     else {
                    453:                         $result .= "<br />";
                    454:                     }
                    455:                 }
                    456:                 if ( defined( $lastresponse{$name} ) ) {
                    457:                     if ( $target eq 'tex' ) {
                    458:                         $result .= '}';
                    459:                     }
                    460:                     else {
                    461:                         $result .= '<b>';
                    462:                     }
                    463:                 }
                    464:                 $result .= $Apache::response::foilgroup{ $name . '.text' };
                    465:                 if ( defined( $lastresponse{$name} ) && ( $target ne 'tex' ) ) {
                    466:                     $result .= '</b>';
                    467:                 }
                    468:                 if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
                    469:                     $result .= "</td>";
                    470:                 }
                    471:             }
                    472:         }
                    473:     }
                    474:     else {
                    475:         foreach my $name (@names) {
                    476:             if ( $Apache::response::foilgroup{ $name . '.value' } ne 'unused' )
                    477:             {
                    478:                 if ( $direction eq 'horizontal' ) {
                    479:                     $result .= "<td>";
                    480:                 }
                    481:                 else {
                    482:                     if ( $target eq 'tex' ) {
                    483:                         if (   $env{'form.pdfFormFields'} eq 'yes'
                    484:                             && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                    485:                         {
                    486:                             my $fieldname =
                    487:                                 $env{'request.symb'} 
                    488:                               . '&part_'
                    489:                               . $Apache::inputtags::part
                    490:                               . '&radiobuttonresponse'
                    491:                               . '&HWVAL_'
                    492:                               . $Apache::inputtags::response['-1'];
                    493:                             $result .= '\item[{'
                    494:                               . &Apache::lonxml::print_pdf_radiobutton(
                    495:                                 $fieldname, $temp )
                    496:                               . '}]'
                    497:                               . $Apache::response::foilgroup{ $name . '.text' }
                    498:                               . "\n";
                    499:                         }
                    500:                         else {
1.135     onken     501:                             $result .= '\item \vskip -2mm ';
                    502:                         }
1.153     foxr      503:                     }
                    504:                     else {
                    505:                         $result .= "<br />";
                    506:                     }
                    507:                 }
                    508:                 if ( $target eq 'tex' ) {
                    509:                     if (   $env{'form.pdfFormFields'} ne 'yes'
                    510:                         or $Apache::inputtags::status[-1] ne 'CAN_ANSWER' )
                    511:                     {
                    512:                         $result .=
                    513:                             '$\bigcirc$'
                    514:                           . $Apache::response::foilgroup{ $name . '.text' }
                    515:                           . '\\\\';    #' stupid emacs
                    516:                     }
                    517:                     $i++;
                    518:                 }
                    519:                 else {
                    520:                     $result .= '<label>';
                    521:                     $result .= "<input
1.113     albertel  522:                        onchange=\"javascript:setSubmittedPart('$part');\"
                    523:                        type=\"radio\"
                    524:                        name=\"HWVAL_$Apache::inputtags::response['-1']\"
1.142     bisitz    525:                        value=\"$temp\"";
1.147     raeburn   526: 
1.153     foxr      527:                     if ( defined( $lastresponse{$name} ) ) {
                    528:                         $result .= ' checked="checked"';
                    529:                     }
                    530:                     $result .= ' />'
                    531:                       . $Apache::response::foilgroup{ $name . '.text' }
                    532:                       . '</label>';
                    533:                 }
                    534:                 $temp++;
                    535:                 if ( $target ne 'tex' ) {
                    536:                     if (   ( $direction eq 'horizontal' )
                    537:                         && ( $target ne 'tex' ) )
                    538:                     {
                    539:                         $result .= "</td>";
                    540:                     }
                    541:                 }
                    542:                 else {
                    543:                     $result .= '\vskip 0 mm ';
                    544:                 }
                    545:             }
                    546:         }
                    547:     }
                    548: 
                    549:     if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
                    550:         $result .= '</tr></table>';
1.45      albertel  551:     }
1.83      albertel  552:     return $result;
1.15      albertel  553: }
                    554: 
1.28      albertel  555: sub whichfoils {
1.153     foxr      556:     my ( $max, $randomize ) = @_;
1.28      albertel  557: 
1.83      albertel  558:     my @truelist;
                    559:     my @falselist;
1.153     foxr      560:     my @whichfalse = ();
                    561:     my ( $truecnt, $falsecnt ) = &getfoilcounts();
                    562:     my $count = 0;
                    563: 
1.83      albertel  564:     # we will add in 1 of the true statements
1.153     foxr      565:     if ( $max > 0 && ( $falsecnt + 1 ) > $max ) { $count = $max }
                    566:     else { $count = $falsecnt + 1; $max = $count; }
                    567:     my $answer = int( &Math::Random::random_uniform() * ($count) );
1.83      albertel  568:     &Apache::lonxml::debug("Count is $count, $answer is $answer");
                    569:     my @names;
                    570:     if ( $Apache::response::foilgroup{'names'} ) {
1.153     foxr      571:         @names = @{ $Apache::response::foilgroup{'names'} };
                    572:     }
                    573:     if ( &Apache::response::showallfoils() ) {
                    574:         @whichfalse = @names;
                    575:     }
                    576:     elsif ( $randomize eq 'no' ) {
                    577:         &Apache::lonxml::debug("No randomization");
                    578:         my $havetrue = 0;
                    579:         foreach my $name (@names) {
                    580:             if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
                    581:                 if ( !$havetrue ) {
                    582:                     push( @whichfalse, $name );
                    583:                     $havetrue++;
                    584:                     $answer = $#whichfalse;
                    585:                 }
                    586:             }
                    587:             elsif (
                    588:                 $Apache::response::foilgroup{ $name . '.value' } eq 'false' )
                    589:             {
                    590:                 push( @whichfalse, $name );
                    591:             }
                    592:             elsif (
                    593:                 $Apache::response::foilgroup{ $name . '.value' } eq 'unused' )
                    594:             {
                    595:             }
                    596:             else {
                    597:                 &Apache::lonxml::error(
                    598:                     &HTML::Entities::encode(
                    599: "No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",
                    600:                         '<>&"'
                    601:                     )
                    602:                 );
                    603:             }
                    604:         }
                    605:         if (   ( !$havetrue )
                    606:             && ( $Apache::lonhomework::type ne 'survey' )
                    607:             && ( $Apache::lonhomework::type ne 'surveycred' )
                    608:             && ( $Apache::lonhomework::type ne 'anonsurvey' )
                    609:             && ( $Apache::lonhomework::type ne 'anonsurveycred' ) )
                    610:         {
                    611:             &Apache::lonxml::error(
                    612:                 &mt('There are no true statements available.') . '<br />' );
                    613:         }
1.83      albertel  614:     }
1.153     foxr      615:     else {
                    616:         my $current = 0;
                    617:         &Apache::lonhomework::showhash(%Apache::response::foilgroup);
                    618:         my ( %top, %bottom );
                    619: 
                    620:         #first find out where everyone wants to be
                    621:         foreach my $name (@names) {
                    622:             $current++;
                    623:             if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
                    624:                 push( @truelist, $name );
                    625:                 if ( $Apache::response::foilgroup{ $name . '.location' } eq
                    626:                     'top' )
                    627:                 {
                    628:                     $top{$name} = $current;
                    629:                 }
                    630:                 elsif ( $Apache::response::foilgroup{ $name . '.location' } eq
                    631:                     'bottom' )
                    632:                 {
                    633:                     $bottom{$name} = $current;
                    634:                 }
                    635:             }
                    636:             elsif (
                    637:                 $Apache::response::foilgroup{ $name . '.value' } eq 'false' )
                    638:             {
                    639:                 push( @falselist, $name );
                    640:                 if ( $Apache::response::foilgroup{ $name . '.location' } eq
                    641:                     'top' )
                    642:                 {
                    643:                     $top{$name} = $current;
                    644:                 }
                    645:                 elsif ( $Apache::response::foilgroup{ $name . '.location' } eq
                    646:                     'bottom' )
                    647:                 {
                    648:                     $bottom{$name} = $current;
                    649:                 }
                    650:             }
                    651:             elsif (
                    652:                 $Apache::response::foilgroup{ $name . '.value' } eq 'unused' )
                    653:             {
                    654:             }
                    655:             else {
                    656:                 &Apache::lonxml::error(
                    657:                     &HTML::Entities::encode(
                    658: "No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",
                    659:                         '<>&"'
                    660:                     )
                    661:                 );
                    662:             }
                    663:         }
                    664: 
                    665:         #pick a true statement
                    666:         my $notrue = 0;
                    667:         if ( scalar(@truelist) == 0 ) { $notrue = 1; }
                    668:         my $whichtrue =
                    669:           int( &Math::Random::random_uniform() * ( $#truelist + 1 ) );
                    670:         &Apache::lonxml::debug(
                    671:             "Max is $max, From $#truelist elms, picking $whichtrue");
                    672:         my ( @toplist, @bottomlist );
                    673:         my $topcount    = 0;
                    674:         my $bottomcount = 0;
                    675: 
                    676:         # assign everyone to either toplist/bottomlist or whichfalse
                    677:         # which false is randomized, toplist bottomlist are in order
                    678:         while (( ( $#whichfalse + $topcount + $bottomcount ) < $max - 2 )
                    679:             && ( $#falselist > -1 ) )
                    680:         {
                    681:             &Apache::lonxml::debug("Have $#whichfalse max is $max");
                    682:             my $afalse =
                    683:               int( &Math::Random::random_uniform() * ( $#falselist + 1 ) );
                    684:             &Apache::lonxml::debug("From $#falselist elms, picking $afalse");
                    685:             $afalse = splice( @falselist, $afalse, 1 );
                    686:             &Apache::lonxml::debug("Picked $afalse");
                    687:             &Apache::lonhomework::showhash( ( 'names' => \@names ) );
                    688:             &Apache::lonhomework::showhash(%top);
                    689:             if ( $top{$afalse} ) {
                    690:                 $toplist[ $top{$afalse} ] = $afalse;
                    691:                 $topcount++;
                    692:             }
                    693:             elsif ( $bottom{$afalse} ) {
                    694:                 $bottomlist[ $bottom{$afalse} ] = $afalse;
                    695:                 $bottomcount++;
                    696:             }
                    697:             else {
                    698:                 push( @whichfalse, $afalse );
                    699:             }
                    700:         }
                    701:         &Apache::lonxml::debug("Answer wants $answer");
                    702:         my $truename = $truelist[$whichtrue];
                    703:         my $dosplice = 1;
                    704:         if (   ($notrue)
                    705:             && ( $Apache::lonhomework::type ne 'survey' )
                    706:             && ( $Apache::lonhomework::type ne 'surveycred' )
                    707:             && ( $Apache::lonhomework::type ne 'anonsurvey' )
                    708:             && ( $Apache::lonhomework::type ne 'anonsurveycred' ) )
                    709:         {
                    710:             $dosplice = 0;
                    711:             &Apache::lonxml::error(
                    712:                 &mt('There are no true statements available.') . '<br />' );
                    713:         }
                    714: 
                    715:         #insert the true statement, keeping track of where it wants to be
                    716:         if (   $Apache::response::foilgroup{ $truename . '.location' } eq 'top'
                    717:             && $dosplice )
                    718:         {
                    719:             $toplist[ $top{$truename} ] = $truename;
                    720:             $answer = -1;
                    721:             foreach my $top ( reverse(@toplist) ) {
                    722:                 if ($top) { $answer++; }
                    723:                 if ( $top eq $truename ) { last; }
                    724:             }
                    725:             $dosplice = 0;
                    726:         }
                    727:         elsif (
                    728:             $Apache::response::foilgroup{ $truename . '.location' } eq 'bottom'
                    729:             && $dosplice )
                    730:         {
                    731:             $bottomlist[ $bottom{$truename} ] = $truename;
                    732:             $answer = -1;
                    733:             foreach my $bot (@bottomlist) {
                    734:                 if ($bot) { $answer++; }
                    735:                 if ( $bot eq $truename ) { last; }
                    736:             }
                    737:             $answer += $topcount + $#whichfalse + 1;
                    738:             $dosplice = 0;
                    739:         }
                    740:         else {
                    741:             if ( $topcount > 0 || $bottomcount > 0 ) {
1.150     raeburn   742:                 my $inc = 1;
1.153     foxr      743:                 if (   ( $bottomcount > 0 )
                    744:                     && ( $Apache::lonhomework::type ne 'exam' ) )
                    745:                 {
1.150     raeburn   746:                     $inc = 2;
                    747:                 }
1.153     foxr      748:                 $answer = int(
                    749:                     &Math::Random::random_uniform() * ( $#whichfalse + $inc ) )
                    750:                   + $topcount;
                    751:             }
                    752:         }
                    753:         &Apache::lonxml::debug("Answer now wants $answer");
                    754: 
                    755:         #add the top items to the top, bottom items to the bottom
                    756:         for ( my $i = 0 ; $i <= $#toplist ; $i++ ) {
                    757:             if ( $toplist[$i] ) { unshift( @whichfalse, $toplist[$i] ) }
                    758:         }
                    759:         for ( my $i = 0 ; $i <= $#bottomlist ; $i++ ) {
                    760:             if ( $bottomlist[$i] ) { push( @whichfalse, $bottomlist[$i] ) }
                    761:         }
                    762: 
                    763:         #if the true statement is randomized insert it into the list
                    764:         if ($dosplice) {
                    765:             splice( @whichfalse, $answer, 0, $truelist[$whichtrue] );
                    766:         }
1.49      albertel  767:     }
1.83      albertel  768:     &Apache::lonxml::debug("Answer is $answer");
1.153     foxr      769:     return ( $answer, @whichfalse );
1.28      albertel  770: }
1.153.6.1! foxr      771: ##
        !           772: # Display foils in html rendition:
        !           773: #
        !           774: # @param $whichfoils - Set of foils to display.
        !           775: # @param $target     - Rendition target...there are several html targets.
        !           776: # @param $direction  - 'horizontal' if layout is horizontal.
        !           777: # @param $part       - Part of the problem that's being displayed.
        !           778: # @param $solved     - Solution state of the problem.
        !           779: # @param $show_answer- True if answers should be shown.
        !           780: #
        !           781: # @return string
        !           782: # @retval generated html.
        !           783: #
        !           784: sub display_foils_html {
        !           785:     my ($whichfoils, $target, $direction, $part, $solved, $show_answer) = @_;
        !           786:     my $result;
        !           787: 
        !           788:     # if the answers get shown, we need to label each item as correct or
        !           789:     # incorrect.
        !           790: 
        !           791:     if ($show_answer) {
        !           792: 	my $item_pretext     = '<br />'; # html prior to each item
        !           793: 	my $item_posttext    = '';	 # html after each item.
        !           794: 	my $finalclose       = '';	 # html to close off the whole shebang
        !           795: 
        !           796: 
        !           797: 	# Horizontal layout is a table with each foil in a cell
        !           798: 
        !           799: 	if ($direction eq 'horizontal') {
        !           800: 	    $result        = '<table><tr>';
        !           801: 	    $item_pretext  = '<td>' . $item_pretext;
        !           802: 	    $item_posttext = '</td>';
        !           803: 	    $finalclose    = '</tr></table>';
        !           804: 	} 
        !           805: 
        !           806: 	foreach my $name (@{$whichfoils}) {
        !           807: 
        !           808: 	    # If the item gets further surrounded by tags, this 
        !           809: 	    # holds the closures for those tages.
        !           810: 
        !           811: 	    my $item_closetag = '';
        !           812: 
        !           813: 	    $result .= $item_pretext;
        !           814: 
        !           815: 	    # Label each foil as correct or incorrect:
        !           816: 
        !           817: 	    if ($Apache::response::foilgroup{$name . '.value'} eq 'true') {
        !           818: 		$result .= &mt('Correct:') . '<b>';
        !           819: 		$item_closetag .= '</b>';
        !           820: 		
        !           821: 	    } else {
        !           822: 		$result .= &mt('Incorrect');
        !           823: 	    }
        !           824: 
        !           825: 	    # Web rendition encloses the 
        !           826: 	    # item text in a label tag as well:
        !           827: 
        !           828: 	    if ($target eq 'web') {
        !           829: 		$result .= '<label>';
        !           830: 		$item_closetag = '</label>' . $item_closetag;
        !           831: 	    }
        !           832: 	    $result .= $Apache::response::foilgroup{$name . '.text'};
        !           833: 	    $result .= $item_closetag;
        !           834: 	    $result .= $item_posttext;
        !           835: 	    $result .= "\n";	# make the html a bit more readable.
        !           836: 	}
        !           837: 
        !           838: 	$result .= $finalclose;
        !           839: 
        !           840:     } else {
        !           841: 	#  Not showing the answers, we need to generate the HTML appropriate
        !           842: 	#  to allowing the student to respond.
        !           843: 	
        !           844: 
        !           845:     }
        !           846: 
        !           847:     return $result;
        !           848: }
        !           849: 
        !           850: 
        !           851: ##
1.28      albertel  852: 
                    853: sub displayfoils {
1.153     foxr      854:     my ( $target, $answer, $whichfoils, $direction, $bubbles_per_line ) = @_;
1.83      albertel  855:     my $result;
1.28      albertel  856: 
1.153     foxr      857:     my $part   = $Apache::inputtags::part;
                    858:     my $solved = $Apache::lonhomework::history{"resource.$part.solved"};
                    859:     if ( ( $target ne 'tex' )
                    860:         && &Apache::response::show_answer() )
                    861:     {
1.153.6.1! foxr      862: 
        !           863: 	$result = &display_foils_html(
        !           864: 	    $whichfoils, $target, $direction, $part, $solved, 1);
        !           865: 
        !           866: #        if ( $direction eq 'horizontal' ) {
        !           867: #            if ( $target ne 'tex' ) {
        !           868: #                $result .= '<table><tr>';
        !           869: #            }
        !           870: #        }
        !           871: #        foreach my $name ( @{$whichfoils} ) {
        !           872: #            if ( $direction eq 'horizontal' ) {
        !           873: #                if ( $target ne 'tex' ) { $result .= '<td>'; }
        !           874: #            }
        !           875: #            if ( $target ne 'tex' ) {
        !           876: #                $result .= "<br />";
        !           877: #            }
        !           878: #            else {
        !           879: #                $result .= '\item \vskip -2 mm  ';
        !           880: #            }
        !           881: #            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
        !           882: #                if ( $target ne 'tex' ) {
        !           883: #                    $result .= &mt('Correct:') . '<b>';
        !           884: #                }
        !           885: #                else {
        !           886: #                    $result .= &mt('Correct:') . ' \textbf{';
        !           887: #                }
        !           888: #            }
        !           889: #            else {
        !           890: #                $result .= &mt('Incorrect:');
        !           891: #            }
        !           892: #            if ( $target eq 'web' ) { $result .= "<label>"; }
        !           893: #            $result .= $Apache::response::foilgroup{ $name . '.text' };
        !           894: #            if ( $target eq 'web' ) { $result .= "</label>"; }
        !           895: #            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
        !           896: #                if   ( $target ne 'tex' ) { $result .= '</b>'; }
        !           897: #                else                      { $result .= '}'; }
        !           898: #            }
        !           899: #            if ( $direction eq 'horizontal' ) {
        !           900: #                if ( $target ne 'tex' ) { $result .= '</td>'; }
        !           901: #            }
        !           902: #        }
        !           903: #        if ( $direction eq 'horizontal' ) {
        !           904: #            if ( $target ne 'tex' ) {
        !           905: #                $result .= '</tr></table>';
        !           906: #            }
        !           907: #        }
1.153     foxr      908:     }
                    909:     else {
                    910:         my @alphabet      = ( 'A' .. 'Z' );
                    911:         my $i             = 0;
                    912:         my $bubble_number = 0;
                    913:         my $line          = 0;
                    914:         my $temp          = 0;
                    915:         my $id            = $Apache::inputtags::response['-1'];
                    916:         my $part          = $Apache::inputtags::part;
                    917:         my ( $lastresponse, $newvariation );
                    918: 
                    919:         if (
                    920:             (
                    921:                 (
                    922:                     $Apache::lonhomework::history{"resource.$part.type"} eq
                    923:                     'randomizetry'
                    924:                 )
                    925:                 || ( $Apache::lonhomework::type eq 'randomizetry' )
                    926:             )
                    927:             && ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                    928:           )
                    929:         {
                    930: 
                    931:             if ( $env{ 'form.' . $part . '.rndseed' } ne
                    932:                 $Apache::lonhomework::history{"resource.$part.rndseed"} )
                    933:             {
1.147     raeburn   934:                 $newvariation = 1;
                    935:             }
                    936:         }
                    937:         unless ($newvariation) {
1.153     foxr      938:             $lastresponse =
                    939:               $Apache::lonhomework::history{"resource.$part.$id.submission"};
                    940:         }
                    941:         my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
                    942:         if ( $target ne 'tex' && $direction eq 'horizontal' ) {
                    943:             $result .= "<table><tr>";
1.147     raeburn   944:         }
1.151     raeburn   945:         my $numlines;
1.153     foxr      946:         if ( ( $target eq 'tex' ) && ( $Apache::lonhomework::type eq 'exam' ) )
                    947:         {
                    948:             my $numitems = scalar( @{$whichfoils} );
                    949:             $numlines = int( $numitems / $bubbles_per_line );
                    950:             if ( ( $numitems % $bubbles_per_line ) != 0 ) {
                    951:                 $numlines++;
1.151     raeburn   952:             }
1.153     foxr      953:             if ( $numlines < 1 ) {
1.151     raeburn   954:                 $numlines = 1;
                    955:             }
1.153     foxr      956:             if ( $numlines > 1 ) {
1.151     raeburn   957:                 my $linetext;
1.153     foxr      958:                 for ( my $i = 0 ; $i < $numlines ; $i++ ) {
                    959:                     $linetext .= $Apache::lonxml::counter + $i . ', ';
1.151     raeburn   960:                 }
                    961:                 $linetext =~ s/,\s$//;
1.153     foxr      962:                 $result .=
                    963:                     '\item[\small {\textbf{'
                    964:                   . $linetext . '}}]'
                    965:                   . ' {\footnotesize '
                    966:                   . &mt( '(Bubble once in [_1] lines)', $numlines )
                    967:                   . '} \hspace*{\fill} \\\\';
                    968:             }
                    969:             else {
                    970:                 $result .= '\item[\textbf{' . $Apache::lonxml::counter . '}.]';
                    971:             }
                    972:         }
                    973:         foreach my $name ( @{$whichfoils} ) {
                    974:             if ( $target ne 'tex' ) {
                    975:                 if ( $direction eq 'horizontal' ) {
                    976:                     $result .= "<td>";
                    977:                 }
                    978:                 else {
                    979:                     $result .= "<br />";
                    980:                 }
                    981:             }
                    982:             if ( $target ne 'tex' ) {
                    983:                 $result .= '<label>';
                    984:                 $result .= "<input type=\"radio\"
1.113     albertel  985:                             onchange=\"javascript:setSubmittedPart('$part');\"
                    986:                             name=\"HWVAL_$Apache::inputtags::response['-1']\"
1.142     bisitz    987:                             value=\"$temp\"";
1.153     foxr      988:                 if ( defined( $lastresponse{$name} ) ) {
                    989:                     $result .= ' checked="checked"';
                    990:                 }
                    991:                 $result .= ' />'
                    992:                   . $Apache::response::foilgroup{ $name . '.text' }
                    993:                   . "</label>";
                    994:             }
                    995:             else {
                    996:                 if ( $Apache::lonhomework::type eq 'exam' ) {
                    997:                     if ( $bubble_number >= $bubbles_per_line ) {
                    998:                         $line++;
                    999:                         $i             = 0;
                   1000:                         $bubble_number = 0;
                   1001:                     }
1.151     raeburn  1002:                     my $identifier;
1.153     foxr     1003:                     if ( $numlines > 1 ) {
                   1004:                         $identifier = $Apache::lonxml::counter + $line;
                   1005:                     }
                   1006:                     $result .=
                   1007:                         '{\small \textbf{'
                   1008:                       . $identifier
                   1009:                       . $alphabet[$i]
                   1010:                       . '}}$\bigcirc$'
                   1011:                       . $Apache::response::foilgroup{ $name . '.text' }
                   1012:                       . '\\\\';    #' stupid emacs
                   1013:                     $i++;
                   1014:                     $bubble_number++;
                   1015:                 }
                   1016:                 else {
                   1017:                     if (   $env{'form.pdfFormFields'} eq 'yes'
                   1018:                         && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
                   1019:                     {
                   1020:                         my $fieldname =
                   1021:                             $env{'request.symb'} 
                   1022:                           . '&part_'
                   1023:                           . $Apache::inputtags::part
                   1024:                           . '&radiobuttonresponse'
                   1025:                           . '&HWVAL_'
                   1026:                           . $Apache::inputtags::response['-1'];
                   1027:                         $result .= '\item[{'
                   1028:                           . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
                   1029:                             $temp )
                   1030:                           . '}]'
                   1031:                           . $Apache::response::foilgroup{ $name . '.text' }
                   1032:                           . "\n";
                   1033:                     }
                   1034:                     else {
                   1035:                         $result .= '\vspace*{-2 mm}\item '
                   1036:                           . $Apache::response::foilgroup{ $name . '.text' };
1.151     raeburn  1037:                     }
1.153     foxr     1038:                 }
                   1039:             }
                   1040:             if ( $target ne 'tex' && $direction eq 'horizontal' ) {
                   1041:                 $result .= "</td>";
                   1042:             }
                   1043:             $temp++;
                   1044:         }
                   1045:         if ( $target ne 'tex' && $direction eq 'horizontal' ) {
                   1046:             $result .= "</tr></table>";
                   1047:         }
                   1048:     }
                   1049:     if ( $target ne 'tex' ) {
                   1050:         if ( $direction ne 'horizontal' ) { $result .= "<br />"; }
1.83      albertel 1051:     }
1.153     foxr     1052:     else { $result .= '\vskip 0 mm '; }
1.83      albertel 1053:     return $result;
1.81      albertel 1054: }
                   1055: 
                   1056: sub displayallanswers {
1.106     albertel 1057:     my @names;
                   1058:     if ( $Apache::response::foilgroup{'names'} ) {
1.153     foxr     1059:         @names = @{ $Apache::response::foilgroup{'names'} };
1.106     albertel 1060:     }
1.153     foxr     1061:     my $result = &Apache::response::answer_header('radiobuttonresponse');
1.81      albertel 1062:     foreach my $name (@names) {
1.153     foxr     1063:         $result .=
                   1064:           &Apache::response::answer_part( 'radiobuttonresponse',
                   1065:             $Apache::response::foilgroup{ $name . '.value' } );
1.81      albertel 1066:     }
1.153     foxr     1067:     $result .= &Apache::response::answer_footer('radiobuttonresponse');
1.81      albertel 1068:     return $result;
1.14      albertel 1069: }
                   1070: 
1.28      albertel 1071: sub displayanswers {
1.153     foxr     1072:     my ( $answer, $whichopt, $bubbles_per_line ) = @_;
1.124     albertel 1073:     my $result;
                   1074: 
1.153     foxr     1075:     if ( $Apache::lonhomework::type eq 'exam' ) {
                   1076:         my $line    = int( $answer / $bubbles_per_line );
                   1077:         my $correct = ( 'A' .. 'Z' )[ $answer % $bubbles_per_line ];
                   1078:         $result .=
                   1079:           &Apache::response::answer_header( 'radiobuttonresponse', $line );
                   1080:         $result .=
                   1081:           &Apache::response::answer_part( 'radiobuttonresponse', $correct );
                   1082:     }
                   1083:     else {
                   1084:         $result .= &Apache::response::answer_header('radiobuttonresponse');
                   1085:     }
                   1086:     foreach my $name ( @{$whichopt} ) {
                   1087:         $result .=
                   1088:           &Apache::response::answer_part( 'radiobuttonresponse',
                   1089:             $Apache::response::foilgroup{ $name . '.value' } );
1.105     albertel 1090:     }
1.153     foxr     1091:     $result .= &Apache::response::answer_footer('radiobuttonresponse');
1.83      albertel 1092:     return $result;
1.28      albertel 1093: }
                   1094: 
1.14      albertel 1095: sub start_conceptgroup {
1.153     foxr     1096:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                   1097:       @_;
                   1098:     $Apache::radiobuttonresponse::conceptgroup = 1;
                   1099:     %Apache::response::conceptgroup            = ();
1.83      albertel 1100:     my $result;
1.153     foxr     1101:     if ( $target eq 'edit' ) {
                   1102:         $result .= &Apache::edit::tag_start( $target, $token );
                   1103:         $result .=
                   1104:             &Apache::edit::text_arg( 'Concept:', 'concept', $token, '50' )
                   1105:           . &Apache::edit::end_row()
                   1106:           . &Apache::edit::start_spanning_row();
                   1107:     }
                   1108:     elsif ( $target eq 'modified' ) {
                   1109:         my $constructtag =
                   1110:           &Apache::edit::get_new_args( $token, $parstack, $safeeval,
                   1111:             'concept' );
                   1112:         if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.83      albertel 1113:     }
                   1114:     return $result;
1.14      albertel 1115: }
                   1116: 
                   1117: sub end_conceptgroup {
1.153     foxr     1118:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                   1119:       @_;
                   1120:     $Apache::radiobuttonresponse::conceptgroup = 0;
1.83      albertel 1121:     my $result;
1.153     foxr     1122:     if (   $target eq 'web'
                   1123:         || $target eq 'grade'
                   1124:         || $target eq 'answer'
                   1125:         || $target eq 'tex'
                   1126:         || $target eq 'analyze' )
                   1127:     {
                   1128:         &Apache::response::pick_foil_for_concept( $target,
                   1129:             [ 'value', 'text', 'location' ],
                   1130:             \%Apache::hint::radiobutton, $parstack, $safeeval );
                   1131:     }
                   1132:     elsif ( $target eq 'edit' ) {
                   1133:         $result = &Apache::edit::end_table();
1.83      albertel 1134:     }
                   1135:     return $result;
1.26      albertel 1136: }
                   1137: 
                   1138: sub insert_conceptgroup {
1.153     foxr     1139:     my $result =
                   1140:         "\n\t\t<conceptgroup concept=\"\">"
                   1141:       . &insert_foil()
                   1142:       . "\n\t\t</conceptgroup>\n";
1.83      albertel 1143:     return $result;
1.1       albertel 1144: }
                   1145: 
                   1146: sub start_foil {
1.153     foxr     1147:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                   1148:       @_;
                   1149:     my $result = '';
                   1150:     if ( $target eq 'web' || $target eq 'tex' || $target eq 'analyze' ) {
                   1151:         &Apache::lonxml::startredirection;
                   1152:         if ( $target eq 'analyze' ) {
                   1153:             &Apache::response::check_if_computed( $token, $parstack, $safeeval,
                   1154:                 'value' );
                   1155:         }
                   1156:     }
                   1157:     elsif ( $target eq 'edit' ) {
                   1158:         $result = &Apache::edit::tag_start( $target, $token );
                   1159:         $result .= &Apache::edit::text_arg( 'Name:', 'name', $token );
                   1160:         $result .= &Apache::edit::select_or_text_arg(
                   1161:             'Correct Option:', 'value',
                   1162:             [ 'unused', 'true', 'false' ], $token
                   1163:         );
                   1164:         my $randomize =
                   1165:           &Apache::lonxml::get_param( 'randomize', $parstack, $safeeval, '-3' );
                   1166:         if ( $randomize ne 'no' ) {
                   1167:             $result .=
                   1168:               &Apache::edit::select_arg( 'Location:', 'location',
                   1169:                 [ 'random', 'top', 'bottom' ], $token );
                   1170:         }
                   1171:         $result .=
                   1172:           &Apache::edit::end_row() . &Apache::edit::start_spanning_row();
                   1173:     }
                   1174:     elsif ( $target eq 'modified' ) {
                   1175:         my $constructtag =
                   1176:           &Apache::edit::get_new_args( $token, $parstack, $safeeval, 'value',
                   1177:             'name', 'location' );
                   1178:         if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                   1179:     }
1.83      albertel 1180:     return $result;
1.1       albertel 1181: }
                   1182: 
                   1183: sub end_foil {
1.153     foxr     1184:     my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
                   1185:       @_;
                   1186:     my $text = '';
                   1187:     if ( $target eq 'web' || $target eq 'tex' || $target eq 'analyze' ) {
                   1188:         $text = &Apache::lonxml::endredirection;
                   1189:     }
                   1190:     if (   $target eq 'web'
                   1191:         || $target eq 'grade'
                   1192:         || $target eq 'answer'
                   1193:         || $target eq 'tex'
                   1194:         || $target eq 'analyze' )
                   1195:     {
                   1196:         my $value = &Apache::lonxml::get_param( 'value', $parstack, $safeeval );
                   1197:         if ( $value ne 'unused' ) {
                   1198:             my $name =
                   1199:               &Apache::lonxml::get_param( 'name', $parstack, $safeeval );
                   1200:             if ( $name eq "" ) {
                   1201:                 &Apache::lonxml::warning(
                   1202:                     &mt(
                   1203: 'Foils without names exist. This can cause problems to malfunction.'
                   1204:                     )
                   1205:                 );
                   1206:                 $name = $Apache::lonxml::curdepth;
                   1207:             }
                   1208:             if ( defined( $Apache::response::foilnames{$name} ) ) {
                   1209:                 &Apache::lonxml::error(
                   1210:                     &mt(
                   1211: 'Foil name [_1] appears more than once. Foil names need to be unique.',
                   1212:                         '<b><tt>' . $name . '</tt></b>'
                   1213:                     )
                   1214:                 );
                   1215:             }
                   1216:             $Apache::response::foilnames{$name}++;
                   1217:             my $location =
                   1218:               &Apache::lonxml::get_param( 'location', $parstack, $safeeval );
                   1219:             if ( $Apache::radiobuttonresponse::conceptgroup
                   1220:                 && !&Apache::response::showallfoils() )
                   1221:             {
                   1222:                 push @{ $Apache::response::conceptgroup{'names'} }, $name;
                   1223:                 $Apache::response::conceptgroup{"$name.value"}    = $value;
                   1224:                 $Apache::response::conceptgroup{"$name.text"}     = $text;
                   1225:                 $Apache::response::conceptgroup{"$name.location"} = $location;
                   1226:             }
                   1227:             else {
                   1228:                 push @{ $Apache::response::foilgroup{'names'} }, $name;
                   1229:                 $Apache::response::foilgroup{"$name.value"}    = $value;
                   1230:                 $Apache::response::foilgroup{"$name.text"}     = $text;
                   1231:                 $Apache::response::foilgroup{"$name.location"} = $location;
                   1232:             }
                   1233:         }
1.18      albertel 1234:     }
1.83      albertel 1235:     return '';
1.1       albertel 1236: }
                   1237: 
1.27      albertel 1238: sub insert_foil {
1.83      albertel 1239:     return '
1.27      albertel 1240: <foil name="" value="unused">
                   1241: <startouttext />
                   1242: <endouttext />
                   1243: </foil>';
                   1244: }
1.151     raeburn  1245: 
1.1       albertel 1246: 1;
                   1247: __END__
1.139     jms      1248: 
                   1249: 
                   1250: 
                   1251: =head1 NAME
                   1252: 
                   1253: Apache::radiobuttonresponse
                   1254: 
                   1255: =head1 SYNOPSIS
                   1256: 
                   1257: Handles multiple-choice style responses.
                   1258: 
                   1259: This is part of the LearningOnline Network with CAPA project
                   1260: described at http://www.lon-capa.org.
                   1261: 
                   1262: =head1 SUBROUTINES
                   1263: 
                   1264: =over
                   1265: 
                   1266: =item start_radiobuttonresponse()
                   1267: 
                   1268: =item bubble_line_count()
                   1269: 
                   1270: =item end_radiobuttonresponse()
                   1271: 
                   1272: =item start_foilgroup()
                   1273: 
                   1274: =item storesurvey()
                   1275: 
                   1276: =item grade_response()
                   1277: 
                   1278: =item end_foilgroup()
                   1279: 
                   1280: =item getfoilcounts()
                   1281: 
                   1282: =item format_prior_answer()
                   1283: 
                   1284: =item displayallfoils()
                   1285: 
                   1286: =item &whichfoils($max,$randomize)
                   1287: 
                   1288: Randomizes the list of foils.
                   1289: Respects
                   1290:   - each foils desire to be randomized
                   1291:   - the existance of Concept groups of foils (select 1 foil from each)
                   1292:   - and selects a single correct statement from all possilble true statments
                   1293:   - and limits it to a toal of $max foils
                   1294: 
                   1295: WARNING: this routine uses the random number generator, it should only
                   1296: be called once per target, otherwise it can cause randomness changes in
                   1297: homework problems.
                   1298: 
                   1299: Arguments
                   1300:   $max - maximum number of foils to select (including the true one)
                   1301:          (so a max of 5 is: 1 true, 4 false)
                   1302: 
                   1303:   $randomize - whether to randomize the listing of foils, by default
                   1304:                will randomize, only if randomize is 'no' will it not
                   1305: 
                   1306: Returns
                   1307:   $answer - location in the array of the correct answer
                   1308:   @foils  - array of foil names in to display order
                   1309: 
                   1310: =item displayfoils()
                   1311: 
                   1312: =item displayallanswers()
                   1313: 
                   1314: =item displayanswers()
                   1315: 
                   1316: =item start_conceptgroup()
                   1317: 
                   1318: =item end_conceptgroup()
                   1319: 
                   1320: =item insert_conceptgroup()
                   1321: 
                   1322: =item start_foil()
                   1323: 
                   1324: =item end_foil()
                   1325: 
                   1326: =item insert_foil()
                   1327: 
                   1328: =back
                   1329: 
                   1330: =cut
1.1       albertel 1331:  

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>