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

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

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