[system] / trunk / pg / lib / Multiple.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/Multiple.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1050 - (download) (as text) (annotate)
Fri Jun 6 21:39:42 2003 UTC (16 years, 8 months ago) by sh002i
File size: 7891 byte(s)
moved PG modules and macro files from webwork-modperl to pg
-sam

    1 #!/usr/bin/perl -w
    2 #Construct for Multiple Choice.
    3 #Inherits from List.pm
    4 #VS 6/16/2000
    5 
    6 
    7 =head1 NAME
    8 
    9 Multiple.pm -- sub-class of List that implements a multiple choice question.
   10 
   11 All items accessed by $out=$mc->item($in);
   12 
   13 =head1 SYNOPSIS
   14 
   15 Multiple.pm is intended to be used to create one of two types of multiple choice
   16 questions. The regular multiple choice question is one question followed by a
   17 list of answers, only one of which is correct, printed in a bulleted form with
   18 radio buttons to select the correct answer.  The second type of of multiple choice
   19 question consists of one question followed by several answers bulleted with check
   20 boxes so that more than one answer can be selected if more than one answer exists.
   21 Each student will receive the same set of answers in a mostly random order (some
   22 answers can be forced to be at the end of list of answers, see makeLast() below).
   23 
   24 =head1 DESCRIPTION
   25 
   26 =head2 Variables and methods available to Multiple
   27 
   28 =head3 Variables
   29 
   30   questions     # array of questions as entered using qa()
   31   answers       # array of answers as entered using qa()
   32 
   33   selected_q      # randomly selected subset of "questions"
   34   selected_a      # the answers for the selected questions
   35 
   36   slice       # index used to select specific questions
   37   shuffle       # permutation array which can be applied to slice
   38             # to shuffle the answers
   39 
   40   inverted_shuffle  # the inverse permutation array
   41 
   42   rf_print_q      # reference to any subroutine which should
   43             # take ($self, @questions) as parameters and
   44             # output the questions in a formatted string.
   45             # If you want to change the way questions are
   46             # printed, write your own print method and set
   47             # this equal to a reference to to that method
   48             # (i.e. $sl->rf_print_q = ~~&printing_routine_q)
   49 
   50   rf_print_a      # reference to any subroutine which should
   51             # take ($self, @answers) as parameters and
   52             # output the answers in a formatted string.
   53             # If you want to change the way answers are
   54             # printed, write your own print method and set
   55             # this equal to a reference to to that method
   56             # (i.e. $sl->rf_print_a = ~~&printing_routine_a)
   57 
   58 =head3 Methods
   59 
   60   qa( array )     # accepts an array of strings which can be used
   61             # for the question and answers
   62 
   63   extra( array )    # accepts an array of strings which can be used
   64             # as extra answers
   65 
   66   print_q       # yields a formatted string of question to be
   67             # matched with answer blanks
   68   print_a       # yields a formatted string of answers
   69 
   70   choose([3, 4], 1) # chooses questions indexed 3 and 4 and one other
   71             # randomly
   72   makeLast( array ) # accepts an array of strings (like qa) which will
   73             # be forced to the end of the list of answers.
   74 
   75   correct_ans     # outputs a reference to the array of correct answers
   76 
   77 
   78 =head2 Usage
   79 
   80 
   81 =head3 Regular Multiple Choice
   82 
   83 Create a multiple choice question using the new_multiple_choice call.
   84 
   85 =for html
   86   <PRE>
   87   <I>$mc = new_multiple_choice</I>
   88   </PRE>
   89 
   90 Use qa() to enter the question and the correct answer. Any duplicates will be eliminated.
   91 
   92 =for html
   93    <PRE>
   94    <I>$mc->qa('\( x^2 \) is:', 'quadratic');</I></PRE>
   95 
   96 After calling qa you can use extra() to add in extra incorrect answers that (along with the
   97 correct answer) will be made into a random list of answers shown to the student.
   98 
   99 =for html
  100   <PRE>
  101   <I>$mc->extra(
  102     'cubic',
  103     'logarithmic',
  104     'exponential'
  105   );</I></PRE>
  106 
  107 
  108 If you want certain answers to be at the end of the list instead of having them be randomized
  109 you can use makeLast to add specific answers to the end of the list of answers or to force
  110 already existing answers to be moved to the end of the list.  This is usually done for
  111 'None of the above', or 'All of the above' type answers.  Note that if 'None of the above'
  112 is the correct answer then you must put it in qa() and then also makeLast() but the duplicate
  113 will be eliminated.  If more than one extra answer is added via makeLast, they are added
  114 in the same order they are given in makeLast.
  115 
  116 =for html
  117   <PRE>
  118   <I>$mc->makeLast(
  119     'All of the above',
  120     'None of the above'
  121   );</I></PRE>
  122 
  123 Now you would start your problem with a C<BEGIN_TEXT> tag and print the questions
  124 and answers with the print_q() and print_a() commands. Within the C<BEGIN_TEXT/END_TEXT block>,
  125 all calls to objects must be enclosed in \( \).
  126 (The $PAR start a new paragraph by printing a blank line).
  127 
  128 =for html
  129   <PRE>
  130   <I>BEGIN_TEXT
  131     $PAR
  132     \{ $mc->print_q() \}
  133     $PAR
  134     \{ $mc->print_a() \}
  135   END_TEXT</I></PRE>
  136 
  137 Now all that''s left is sending the students answers to the answer evaluator
  138 along with the correct answers so that the students answers can be checked and
  139 a score can be given.  This is done using C<ANS>, an answer evaluator and the
  140 C<correct_ans> variable.
  141 
  142 =for html
  143   <PRE>
  144   <I>ANS(radio_cmp($mc->correct_ans))</I></PRE>
  145 
  146 
  147 =head3 Checkbox Multiple Choice
  148 
  149 
  150 A checkbox multiple choice problem is identical to a regular multiple choice problem with only
  151 a few exceptions.
  152 
  153 First, you create the checkbox multiple choice object using the command:
  154 
  155 =for html
  156   <PRE>
  157   <I>$cmc = new_checkbox_multiple_choice</I></PRE>
  158 
  159 Then you would call qa() just as in a regular multiple choice object except that this time
  160 you can provide more than one answer
  161 
  162 =for html
  163    <PRE>
  164    <I>$cmc->qa(
  165         'Indicate all the functions that are anti-derivatives of \( 3x^2 \)',
  166         '\( x^3 \)',
  167         '\( x^3 - 57 \)',
  168         '\( 27 + x^3 \)'
  169   );</I></PRE>
  170 
  171 Then you would use extra() and makeLast() and create the problem just as with a regular multiple
  172 choice.  The only other difference is that at then end of the problem you would use checkbox_cmp()
  173 instead of radio_cmp().
  174 
  175 =for html
  176   <PRE>
  177   <I>ANS(radio_cmp($cmc->correct_ans))</I></PRE>
  178 
  179 
  180 =cut
  181 
  182 BEGIN {
  183   be_strict();
  184 }
  185 
  186 #use strict;
  187 package Multiple;
  188 
  189 @Multiple::ISA = undef;
  190 #require "${Global::mainDirectory}courseScripts/List.pm";
  191 @Multiple::ISA = qw( Exporter List );
  192 
  193 # *** Subroutines which overload List.pm ***
  194 sub choose { warn "Multiple choice does not support choosing answers.\n(You can't use \$mc->choose().)"; }
  195 sub choose_extra { warn "Multiple choice does not support choosing answers.\n(You can't use \$mc->choose_extra().)"; }
  196 sub extras { warn "Extras() is not a method of Multiple.pm.\nUse the extra() method to add extra answers."; }
  197 
  198 sub qa {
  199   my $self = shift;
  200   my @input = @_;
  201 
  202   push( @{ $self->{questions} }, shift(@input) ); #one question
  203   push( @{ $self->{answers} }, @input );  #correct answer(s)
  204 
  205   $self->choose2(scalar(@{ $self->{answers} }));
  206 }
  207 
  208 sub extra {
  209   my $self = shift;
  210   my @input = @_;
  211 
  212   push( @{ $self->{extras} }, @input);
  213 
  214   #call as a method of $self
  215   &List::choose_extra($self, scalar(@{ $self->{extras} }));
  216 }
  217 
  218 #This means rf_print_q is not used but still exists for user customization
  219 sub print_q {
  220   my $self = shift;
  221 
  222   @{ $self->{questions} }[0];
  223 }
  224 
  225 
  226 #This is called choose2 because it needs to be called internally
  227 #but i didn't want it available to the user (hence choose being
  228 #overloaded to give a error message above).
  229 sub choose2 {
  230   my $self = shift;
  231   my @input = @_;
  232 
  233   $self->getRandoms(scalar(@{ $self->{answers} }), @input);
  234   $self->selectQA();
  235 }
  236 
  237 sub selectQA {
  238   my $self = shift;
  239 
  240   $self->{selected_q} = $self->{questions};
  241   $self->{selected_a} = [ @{ $self->{answers} }[@{ $self->{shuffle} }] ];
  242   $self->{inverted_shuffle} = [ &List::invert(@{ $self->{shuffle} }) ];
  243 }
  244 
  245 #Multiple
  246 sub ra_correct_ans {
  247   warn "Multiple does not use ra_correct_ans because radio_cmp and checkbox_cmp expect a string.\nYou should use correct_ans instead.";
  248 }
  249 
  250 #sends letters for comparison instead of actual answers
  251 #actual answers aren't used because they might contain LaTeX or HTML
  252 sub correct_ans {
  253   my $self = shift;
  254   my @ans = &List::ALPHABET( sort { $a <=> $b } @{$self->{inverted_shuffle}} );
  255 
  256   #radio_cmp and checkbox_cmp expect a string, not a reference to an array like str_cmp, etc
  257   join "", @ans;
  258 }
  259 
  260 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9