| 1 | #!/usr/local/bin/webwork-perl |
1 | |
| 2 | BEGIN{ |
2 | BEGIN{ |
| 3 | be_strict; |
3 | be_strict; |
| 4 | } |
4 | } |
| 5 | |
5 | |
| 6 | package main; |
6 | package main; |
| … | |
… | |
| 13 | |
13 | |
| 14 | =head1 SYNPOSIS |
14 | =head1 SYNPOSIS |
| 15 | |
15 | |
| 16 | =pod |
16 | =pod |
| 17 | |
17 | |
| 18 | There are two types of choice macros. The older versions are simply scripts. |
18 | There are two types of choice macros. The older versions are simply scripts. |
| 19 | The newer versions involve the "List.pm" class and its sub-classes |
19 | The newer versions involve the "List.pm" class and its sub-classes |
| 20 | and the use of objects based on these classes. The list sub-classes are: |
20 | and the use of objects based on these classes. The list sub-classes are: |
| 21 | "Match.pm" which aids in setting up matching question |
21 | "Match.pm" which aids in setting up matching question |
| 22 | and answer lists, "Select.pm" which aids in selecting |
22 | and answer lists, "Select.pm" which aids in selecting |
| 23 | and presenting a subset of questions with short answers |
23 | and presenting a subset of questions with short answers |
| 24 | (e.g. true/false questions) from a larger question set, and |
24 | (e.g. true/false questions) from a larger question set, and |
| 25 | "Multiple.pm" which aids in setting up a |
25 | "Multiple.pm" which aids in setting up a |
| 26 | standard style, one question, many answers type multiple |
26 | standard style, one question, many answers type multiple |
| 27 | choice question. |
27 | choice question. |
| 28 | |
28 | |
| 29 | |
29 | |
| 30 | =head1 DESCRIPTION |
30 | =head1 DESCRIPTION |
| 31 | |
31 | |
| 32 | Sample usage: |
32 | Sample usage: |
| 33 | |
33 | |
| 34 | |
34 | |
| 35 | $ml = new_match_list(); |
35 | $ml = new_match_list(); |
| 36 | # enter three questions and their answers |
36 | # enter three questions and their answers |
| 37 | $ml->qa( "What color is a rose?", |
37 | $ml->qa( "What color is a rose?", |
| 38 | "Red", |
38 | "Red", |
| 39 | "What color is the sky?", |
39 | "What color is the sky?", |
| 40 | "Blue", |
40 | "Blue", |
| 41 | "What color is the sea?", |
41 | "What color is the sea?", |
| 42 | "Green" |
42 | "Green" |
| 43 | ); |
43 | ); |
| 44 | # choose two of these questions, ordered at random, |
44 | # choose two of these questions, ordered at random, |
| 45 | # which will be printed in the problem. |
45 | # which will be printed in the problem. |
| 46 | $ml->choose(2); |
46 | $ml->choose(2); |
| 47 | BEGIN_TEXT |
47 | BEGIN_TEXT |
| 48 | Match the answers below with these questions:$BR |
48 | Match the answers below with these questions:$BR |
| 49 | \\{$ml->print_q\\} $BR |
49 | \\{$ml->print_q\\} $BR |
| 50 | Answers: |
50 | Answers: |
| 51 | \\{$ml->print_a\\} |
51 | \\{$ml->print_a\\} |
| 52 | END_TEXT |
52 | END_TEXT |
| 53 | |
53 | |
| 54 | ANS( $ml->ra_correct_ans() ); |
54 | ANS( $ml->ra_correct_ans() ); |
| 55 | |
55 | |
| 56 | =cut |
56 | =cut |
| 57 | |
57 | |
| 58 | |
58 | |
| 59 | =head2 Matching List macros |
59 | =head2 Matching List macros |
| 60 | |
60 | |
| … | |
… | |
| 71 | Which is short hand for the following direct call to Match |
71 | Which is short hand for the following direct call to Match |
| 72 | |
72 | |
| 73 | $ml = new Match(random(1,2000,1), ~~&std_print_q, ~~&std_print_a); |
73 | $ml = new Match(random(1,2000,1), ~~&std_print_q, ~~&std_print_a); |
| 74 | |
74 | |
| 75 | |
75 | |
| 76 | Either call will create a matching list object in the variable $ml. |
76 | Either call will create a matching list object in the variable $ml. |
| 77 | (I< Note: $ml cannot be a my variable if it is to be used within a BEGIN_TEXT/END_TEXT block.>) |
77 | (I< Note: $ml cannot be a my variable if it is to be used within a BEGIN_TEXT/END_TEXT block.>) |
| 78 | |
78 | |
| 79 | The first argument is the seed for the match list (choosen at random between 1 and 2000 in |
79 | The first argument is the seed for the match list (choosen at random between 1 and 2000 in |
| 80 | the example above.). The next two arguments are references to the print subroutines |
80 | the example above.). The next two arguments are references to the print subroutines |
| 81 | used to print the questions and the answers. |
81 | used to print the questions and the answers. |
| 82 | Other printing methods can be used instead of the standard ones. An |
82 | Other printing methods can be used instead of the standard ones. An |
| 83 | example of how to do this is demonstrated with |
83 | example of how to do this is demonstrated with |
| 84 | "pop_up_list_print_q" below. |
84 | "pop_up_list_print_q" below. |
| 85 | |
85 | |
| 86 | =head4 std_print_q |
86 | =head4 std_print_q |
| 87 | |
87 | |
| 88 | Standard method for formatting a list of questions with answer blanks. |
88 | Standard method for formatting a list of questions with answer blanks. |
| 89 | |
89 | |
| 90 | This formatting routine is the default method for formatting the |
90 | This formatting routine is the default method for formatting the |
| 91 | way questions are printed |
91 | way questions are printed |
| 92 | for each of the three sub-classes of "List.pm". It lists the questions vertically, numbering |
92 | for each of the three sub-classes of "List.pm". It lists the questions vertically, numbering |
| 93 | them sequentially and providing an answer blank before each question. |
93 | them sequentially and providing an answer blank before each question. |
| 94 | C<std_print_q> checks which mode the user is trying to print the |
94 | C<std_print_q> checks which mode the user is trying to print the |
| 95 | questions from and returns the appropriately formatted string. |
95 | questions from and returns the appropriately formatted string. |
| 96 | |
96 | |
| 97 | The length of the answer blank can be set with C<$ml-> |
97 | The length of the answer blank can be set with C<$ml-> |
| 98 | |
98 | |
| 99 | To replace the standard question formatting method with your own, use: |
99 | To replace the standard question formatting method with your own, use: |
| 100 | |
100 | |
| 101 | $ml->rf_print_q(~~&my_question_format_method) |
101 | $ml->rf_print_q(~~&my_question_format_method) |
| 102 | |
102 | |
| 103 | Your method should be a subroutine of the form C<my_question_format_method($self, @questions)> |
103 | Your method should be a subroutine of the form C<my_question_format_method($self, @questions)> |
| 104 | and should return a string to be printed. The @questions array contains the |
104 | and should return a string to be printed. The @questions array contains the |
| 105 | questions to be listed, while $self can be used to obtain extra information from |
105 | questions to be listed, while $self can be used to obtain extra information from |
| 106 | the object for formatting purposes. The variable C<$main::displayMode> contains the |
106 | the object for formatting purposes. The variable C<$main::displayMode> contains the |
| 107 | current display mode. (See "MODES" for more details on display modes and |
107 | current display mode. (See "MODES" for more details on display modes and |
| 108 | see "writing print methods for lists" for details on constructing formatting subroutines.) |
108 | see "writing print methods for lists" for details on constructing formatting subroutines.) |
| 109 | |
109 | |
| 110 | |
110 | |
| … | |
… | |
| 118 | |
118 | |
| 119 | To replace the standard answer formatting method with your own subroutine use: |
119 | To replace the standard answer formatting method with your own subroutine use: |
| 120 | |
120 | |
| 121 | $ml->rf_print_q(~~&my_answer_format_method) |
121 | $ml->rf_print_q(~~&my_answer_format_method) |
| 122 | |
122 | |
| 123 | The answer formatting method has the same interface as the question formatting |
123 | The answer formatting method has the same interface as the question formatting |
| 124 | method. |
124 | method. |
| 125 | |
125 | |
| 126 | |
126 | |
| 127 | =head2 Select List macros |
127 | =head2 Select List macros |
| 128 | |
128 | |
| 129 | |
129 | |
| 130 | =head3 new_select_list |
130 | =head3 new_select_list |
| … | |
… | |
| 408 | } else { |
408 | } else { |
| 409 | $out = "Error: PGchoicemacros: pop_up_list_print_q: Unknown displayMode: $main::displayMode.\n"; |
409 | $out = "Error: PGchoicemacros: pop_up_list_print_q: Unknown displayMode: $main::displayMode.\n"; |
| 410 | } |
410 | } |
| 411 | $out; |
411 | $out; |
| 412 | |
412 | |
|
|
413 | } |
|
|
414 | |
|
|
415 | |
|
|
416 | # For graphs in a matching question. |
|
|
417 | |
|
|
418 | #sub format_graphs { |
|
|
419 | # my $self = shift; |
|
|
420 | # my @in = @_; |
|
|
421 | # my $out = ""; |
|
|
422 | # while (@in) { |
|
|
423 | # $out .= shift(@in). "#" ; |
|
|
424 | # } |
|
|
425 | # $out; |
|
|
426 | #} |
|
|
427 | |
|
|
428 | |
|
|
429 | # To put pop-up-list at the end of a question. |
|
|
430 | # contributed by Mark Schmitt 3-6-03 |
|
|
431 | |
|
|
432 | sub quest_first_pop_up_list_print_q { |
|
|
433 | my $self = shift; |
|
|
434 | my (@questions) = @_; |
|
|
435 | my $length = $self->{ans_rule_len}; |
|
|
436 | my @list = @{$self->{ra_pop_up_list} }; |
|
|
437 | my $out = ""; |
|
|
438 | |
|
|
439 | if ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth' |
|
|
440 | || $main::displayMode eq 'HTML_jsMath' || $main::displayMode eq 'HTML_asciimath' |
|
|
441 | || $main::displayMode eq 'HTML_dpng'|| $main::displayMode eq 'HTML_img') { |
|
|
442 | my $i=1; my $quest; |
|
|
443 | foreach $quest (@questions) { |
|
|
444 | $out.= "\n<p>" . " $quest" . pop_up_list(@list); |
|
|
445 | $i++; |
|
|
446 | } |
|
|
447 | $out .= "<br>\n"; |
|
|
448 | } elsif ($main::displayMode eq 'Latex2HTML') { |
|
|
449 | my $i=1; my $quest; |
|
|
450 | foreach $quest (@questions) { |
|
|
451 | $out.= " \\begin{rawhtml}<p><B>\\end{rawhtml}" . pop_up_list(@list) . " $i. \\begin{rawhtml}</B>\\end{rawhtml} $quest"; |
|
|
452 | $i++; |
|
|
453 | } |
|
|
454 | $out .= " \\begin{rawhtml}<BR>\\end{rawhtml} "; |
|
|
455 | } elsif ($main::displayMode eq 'TeX') { |
|
|
456 | $out = "\n\\par\\begin{enumerate}\n"; |
|
|
457 | my $i=1; my $quest; |
|
|
458 | foreach $quest (@questions) { |
|
|
459 | $out .= "\\item[" . pop_up_list(@list) . "$i.] $quest\n"; |
|
|
460 | $i++; |
|
|
461 | } |
|
|
462 | $out .= "\\end{enumerate}\n"; |
|
|
463 | } else { |
|
|
464 | $out = "Error: PGchoicemacros: pop_up_list_print_q: Unknown displayMode: $main::displayMode.\n"; |
|
|
465 | } |
|
|
466 | $out; |
|
|
467 | |
|
|
468 | } |
|
|
469 | # To put pop-up-list in the middle of a question. |
|
|
470 | # contributed by Mark Schmitt 3-6-03 |
|
|
471 | |
|
|
472 | sub ans_in_middle_pop_up_list_print_q { |
|
|
473 | my $self = shift; |
|
|
474 | my (@questions) = @_; |
|
|
475 | my $length = $self->{ans_rule_len}; |
|
|
476 | my @list = @{$self->{ra_pop_up_list} }; |
|
|
477 | my $out = ""; |
|
|
478 | |
|
|
479 | if ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth' |
|
|
480 | || $main::displayMode eq 'HTML_jsMath' || $main::displayMode eq 'HTML_asciimath' |
|
|
481 | || $main::displayMode eq 'HTML_dpng'|| $main::displayMode eq 'HTML_img') { |
|
|
482 | my $i=1; my $quest; |
|
|
483 | foreach $quest (@questions) { |
|
|
484 | $out.= "" . " $quest" . pop_up_list(@list); |
|
|
485 | $i++; |
|
|
486 | } |
|
|
487 | $out .= ""; |
|
|
488 | } elsif ($main::displayMode eq 'Latex2HTML') { |
|
|
489 | my $i=1; my $quest; |
|
|
490 | foreach $quest (@questions) { |
|
|
491 | $out.= " \\begin{rawhtml}<p><B>\\end{rawhtml}" . pop_up_list(@list) . " $i. \\begin{rawhtml}</B>\\end{rawhtml} $quest"; |
|
|
492 | $i++; |
|
|
493 | } |
|
|
494 | $out .= " \\begin{rawhtml}<BR>\\end{rawhtml} "; |
|
|
495 | } elsif ($main::displayMode eq 'TeX') { |
|
|
496 | $out = "\n\\par\\begin{enumerate}\n"; |
|
|
497 | my $i=1; my $quest; |
|
|
498 | foreach $quest (@questions) { |
|
|
499 | $out .= "\\item[" . pop_up_list(@list) . "$i.] $quest\n"; |
|
|
500 | $i++; |
|
|
501 | } |
|
|
502 | $out .= "\\end{enumerate}\n"; |
|
|
503 | } else { |
|
|
504 | $out = "Error: PGchoicemacros: pop_up_list_print_q: Unknown displayMode: $main::displayMode.\n"; |
|
|
505 | } |
|
|
506 | $out; |
|
|
507 | |
|
|
508 | } |
|
|
509 | |
|
|
510 | |
|
|
511 | # Units for physics class |
|
|
512 | # contributed by Mark Schmitt 3-6-03 |
|
|
513 | |
|
|
514 | sub units_list_print_q { |
|
|
515 | my $self = shift; |
|
|
516 | my (@questions) = @_; |
|
|
517 | my $length = $self->{ans_rule_len}; |
|
|
518 | my @list = @{$self->{ra_pop_up_list} }; |
|
|
519 | my $out = ''; |
|
|
520 | |
|
|
521 | $out.= pop_up_list(@list); |
|
|
522 | |
|
|
523 | $out; |
| 413 | } |
524 | } |
| 414 | |
525 | |
| 415 | #Standard method of printing answers in a matching list |
526 | #Standard method of printing answers in a matching list |
| 416 | sub std_print_a { |
527 | sub std_print_a { |
| 417 | my $self = shift; |
528 | my $self = shift; |
| … | |
… | |
| 531 | my (@questions) = @_; |
642 | my (@questions) = @_; |
| 532 | my $length = $self->{ans_rule_len}; |
643 | my $length = $self->{ans_rule_len}; |
| 533 | my $out = ""; |
644 | my $out = ""; |
| 534 | #if ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth') { |
645 | #if ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth') { |
| 535 | if ($main::displayMode =~ /^HTML/) { |
646 | if ($main::displayMode =~ /^HTML/) { |
| 536 | my $i=1; my $quest; |
647 | my $i=1; my $quest; $out = "\n<P>\n"; |
| 537 | foreach $quest (@questions) { |
648 | foreach $quest (@questions) { |
| 538 | $out.= "\n<BR>" . ans_rule($length) . "<B>$i.</B> $quest"; |
649 | $out.= ans_rule($length) . " <B>$i.</B> $quest<BR>"; |
| 539 | $i++; |
650 | $i++; |
| 540 | } |
651 | } |
| 541 | $out .= "<br>\n"; |
|
|
| 542 | } elsif ($main::displayMode eq 'Latex2HTML') { |
652 | } elsif ($main::displayMode eq 'Latex2HTML') { |
| 543 | my $i=1; my $quest; |
653 | my $i=1; my $quest; $out = "\\par\n"; |
| 544 | foreach $quest (@questions) { |
654 | foreach $quest (@questions) { |
| 545 | $out.= " \\begin{rawhtml}<BR>\\end{rawhtml} " . ans_rule($length) . "\\begin{rawhtml}<B>\\end{rawhtml} $i. \\begin{rawhtml}</B>\\end{rawhtml} $quest"; #"$i. $quest"; |
655 | $out.= ans_rule($length) . "\\begin{rawhtml}<B>$i. </B>\\end{rawhtml} $quest\\begin{rawhtml}<BR>\\end{rawhtml}\n"; |
| 546 | $i++; |
656 | $i++; |
| 547 | } |
657 | } |
| 548 | $out .= " \\begin{rawhtml}<BR>\\end{rawhtml} "; |
|
|
| 549 | } elsif ($main::displayMode eq 'TeX') { |
658 | } elsif ($main::displayMode eq 'TeX') { |
| 550 | $out = "\n\\par\\begin{enumerate}\n"; |
659 | $out = "\n\\par\\begin{enumerate}\n"; |
| 551 | my $i=1; my $quest; |
660 | my $i=1; my $quest; |
| 552 | foreach $quest (@questions) { |
661 | foreach $quest (@questions) { |
| 553 | $out .= "\\item[" . ans_rule($length) . "$i.] $quest\n"; |
662 | $out .= "\\item[" . ans_rule($length) . "$i.] $quest\n"; |