Open dlglin opened 1 year ago
For your item 1, $correct
is the PopUp object, while $student
is a string object whose value is B1
or whatever, and so that is what it shows when it is stringified. The stringified value for the PopUp is the label value. You can convert $student
to its label via $RB->answerLabel($student)
if you want that. It would be possible to make the student answer strings be the same as the labels, but there is no current method to do that when there is randomization involved. One could be added.
For your item 2, the shuffled answers are in $RB->{orderedChoices}
, and the indices into the original (flattened) array of choices for the ordered choices are in $RB->{order}
. These can be used to unshuffle the choices, but they aren't quite in a form that makes that easy. For example, if you want the label in the ordered choices of the answer in the original (flattened) choice array with index $i
, then you could do something like:
$label = $RB->{labels}[(grep { $RB->{order}[$_] == $i } 0 .. $RB->{n} - 1)[0]];
If you want the label for the answer string $s
, then
$label = $RB->{labels}[(grep { $RB->{orderedChoices}[$_] eq $s } 0 .. $RB->{n} - 1)[0]];
should do the trick. If you need to look up the labels of a lot of answers, then you might want to make the reverse mapping from $RB->{order}
, say
my @reverse;
map {$reverse[$RB->{order}[$_]] = $_] 0 .. $RB->{n} - 1;
so that $reverse[$i]
will be the index into shuffled choices of the choice at index $i
of the original choice array. Then
$label = $RB->{labels}[$reverse[$i]];
will be the label for the choice at position $i
in the original choice array.
One thing that you can do is use the new values
option. The values
are reordered together with everything else. So you could do
DOCUMENT();
loadMacros('PGstandard.pl', 'PGML.pl', 'parserRadioButtons.pl', 'PGcourse.pl');
$checker = sub {
my ($correct, $student) = @_;
return $correct == $student || $student eq 'second correct';
};
$RB = RadioButtons(
[ [ 'First correct', 'Second correct', 'First incorrect' ] ], 0,
labels => 'ABC',
values => ['first correct', 'second correct', 'first incorrect']
);
BEGIN_PGML
[_]{$RB->cmp(checker=>$checker)}
END_PGML
ENDDOCUMENT();
This will work with PG 2.18, but not before of course.
Another thing you could do that I believe would work prior to PG 2.18 is
DOCUMENT();
loadMacros('PGstandard.pl', 'PGML.pl', 'parserRadioButtons.pl', 'PGcourse.pl');
$checker = sub {
my ($correct, $student) = @_;
return $correct == $student || $RB->answerChoice($student) eq 'Second correct';
};
$RB = RadioButtons([ [ 'First correct', 'Second correct', 'First incorrect' ] ], 0, labels => 'ABC');
BEGIN_PGML
[_]{$RB->cmp(checker=>$checker)}
END_PGML
ENDDOCUMENT();
Of course these suggestions don't address your concern about warn
showing something different for the correct and student answers.
This was motivated by https://webwork.maa.org/moodle/mod/forum/discuss.php?d=8369 which asks about custom answer checkers for multiple choice problems.
Consider the following MWE:
There are a couple of concerns:
warn
statements produce inconsistent output. For the student answer what is displayed is the underlying MathObject value (i.e.B0
,B1
, orB2
), whereas for the correct answer the label is displayed by default (i.e.A
,B
orC
in this example). The underlying checking compares the MathObject values, so$correct==$student
returns the proper value, but the values that are displayed in the warn statement are confusing.$correct->Value
returns the proper choice after randomization, but'B1'
will refer to answer B in the scrambled choices, which doesn't consistently correspond to any specific answer. I don't see a way to get the index of "Second correct" after the entries have been scrambled.I don't know that there is going to be an easy way to fix the second issue. I wonder if it's possible to make the labels of the scrambled answers available to the problem author. This could also be useful in solutions. For example for a "which of the following statements is true" type question, the solution could discuss why each incorrect option is false, and refer to them by their labels.