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