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> '
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: . ' ' x 3
89: . &Apache::edit::select_arg( 'Randomize Foil Order:',
90: 'randomize', [ 'yes', 'no' ], $token )
91: . ' ' 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>