## Features & Development

by Dick Lane -
Number of replies: 8
A method to match explanations with a shuffled list of matching problems is presented in
http://webwork.maa.org/wiki/MatchingProblems
The method involves creating a list of explanations whose order matches the object->qa list, then looping through the shuffled list of asked questions to arrange the explanations in matching order, followed by explicit lines to present those explanations in the problem's Solution block.

That method also works with a shuffled list of True/False items as presented in
http://webwork.maa.org/wiki/ManyMultipleChoice1

I request some additions to PGchoicemacros.pl for handling a list of triples: Question, Answer, Explanation.  The new functionality would remove the need for looping to match explanations with asked questions and would provide a single command for display of all explanations in Solutions.  Maintenance and revision of a single QAE list is apt to be easier than managing a pair of QA and E lists.

Some of my WeBWorK assignments are Reading Question assignments, close an hour before a class with answers & solutions available after class, which I use for Just-in-Time info to help me adjust my agenda for a class (encouraging students to read the text before class is also important).  I plan to adapt some ConcepTest and Check-Your-Understanding items to use in my RQ assignments.  I am a strong believer in providing explanations or solutions in all problems I write, so my request is for tools to simplify writing a batch of problems with each problem presenting several (e.g., 5 chosen from 8) True/False items.

by Davide Cervone -
The looping is already completely unnecessary, as the indices of the selected questions are already available in a field of the match object, in this case $ml->{slice}. See the POD documentation for ChoiceList (the root class for the match list) for a list of the data available. Using an array @explanations of explanations and this slice data, you can get the explanation corresponding to the i-th question as $explanations[$ml->{slice}[$i]].

by Dick Lane -
Thanks, Davide --- that is great information.

After a standard setup, it seems sufficient to create an @explain array followed by concatenating appropriate pieces for display in the Solution block.  Here's my first draft of such code.

$n = 0 ;$why = '' ;
foreach $i ( @{$tf->slice} ) {
$n++ ;$why .= "$BR$n. "
.  "$tf->{answers}[$i], " . $SPACE . "$explain[$i]" . "$BR"
} ;

Context() -> texStrings;
BEGIN_SOLUTION
$SOLUTION$why
END_SOLUTION
Context() -> normalStrings;

by Davide Cervone -
Your code looks good, except I think you need $tf->{slice} not $tf->slice (though I guess there may be a method as well; I didn't check).

One simplification is that you don't need Context()->texStrings or Context()->normalStrings, as these only affect the substitution of MathObjects into the text. You aren't doing that, so they have no effect, here.

by Dick Lane -
The attached example incorporates Davide's remark that MathObjects stuff is apt to be superfluous for forced-choice  (multiple-choice, match, select) tasks.

The POD Documentation for ChoiceList concludes by saying "cmp
Usage    ANS($ml -> cmp); provides a MathObject like comparison method returns a string of comparison methods for checking the list object" If I replace ANS( str_cmp($tf -> ra_correct_ans ) ) ;
with
ANS( $tf -> cmp() ) ; the error message is Variable 'F' is not defined in this context; see position 1 of formula at line 358 of [PG]/lib/ChoiceList.pm Died within ChoiceList::cmp called at line 37 of (eval 91702) I'm content to stay with an old-style checker that works, but don't want to overlook possible improvements. In reply to Dick Lane ### Re: request Question-Answer-Explanation by Dick Lane - Although this works with a select list, it fails with a match list. My bugzilla report includes an attachment showing slice gets its indices from choose_extra rather than choose. In reply to Dick Lane ### Re: request Question-Answer-Explanation by Davide Cervone - The solution here might be to capture the slice after your $ml->choose and before the $ml->choose_extra. For example $ml->choose(2) ;
@slice = @{$ml->slice}; ... foreach$i ( @slice ) {
$n++ ;$why .= "$BR$n. "
.  "$explain[$i]" . "$BR" } ;  (it turns out the $ml->slice is OK for this).

Alternatively,

    $ml->choose(2) ;$ml->{original_slice} = [@{$ml->slice}]; ... foreach$i ( @{$ml->{original_slice}} ) {$n++ ;
$why .= "$BR $n. " . "$explain[$i]" . "$BR"
} ;

See if either of those does what you want.

Davide

by Dick Lane -
I opted for a mild variant of the first.
$ml->choose(2); is immediately followed by #### assemble the explanation while slice has indices from choose() #### [choose_extra() will subsequently put its indices into slice]$n = 0 ;
$why = '' ; foreach my$i ( @{$ml->{slice}} ) {$n++ ;
$why .= "$BR $n.$explain[$i]$BR"
} ;

Once again --- thanks, Davide, for your help.