WeBWorK Problems

Answer checker for DropDown

Answer checker for DropDown

by Steven Fiedler -
Number of replies: 10

The bottom paragraph of the parserPopUp.pl POD indicates that custom answer checkers can be used with drop down menus. This is an embarrassingly simple question, but the below MWE shows that the dropdown works properly for the typical drop down use case, but it doesn't appear to display the menu when used with the ANS($dropdown->cmp); syntax. I'd appreciate if someone could point me in the correct direction. 

DOCUMENT();

loadMacros('PGstandard.pl', 'PGML.pl','parserPopUp.pl');

$dropdown = DropDown(
    [
        "First Item",
        [ "Random 1", "Random 2", "Random 3" ],
        "Last Item"
    ],
    "Random 3"
);

BEGIN_PGML
Select an item:  [_]{$dropdown}

END_PGML 

BEGIN_PGML
Select an item:  [_]
END_PGML 
ANS($dropdown->cmp);

ENDDOCUMENT();

Attachment Screenshot_2025-10-02_11-00-29.png
In reply to Steven Fiedler

Answer checker for DropDown

by Danny Glin -

In the last couple of versions of WeBWorK you can put the cmp() method directly into the answer in PGML.

For your example you could do:

Select an item:  [_]{$dropdown->cmp(checker => sub { ... } )}

This can make your code hard to read, so you may prefer:

$dropdown = DropDown(
    [ "First Item", [ "Random 1", "Random 2", "Random 3" ], "Last Item" ],
    "Random 3")->cmp(
    checker => sub {
    ...
    }
    );

Then you can use

Select an item:  [_]{$dropdown}

in your PGML block.

In reply to Steven Fiedler

Answer checker for DropDown

by Alex Jordan -

When PGML is being processed, it is not yet aware that this answer blank will be something different than a regular input field, and that is learned too late to make that input be a select.

Danny's answer is good. An alternative is that you can go ahead and redefine $dropdown with its cmp method, and pass that in the PGML.

DOCUMENT();

loadMacros('PGstandard.pl', 'PGML.pl','parserPopUp.pl');

$dropdown = DropDown(
    [
        "First Item",
        [ "Random 1", "Random 2", "Random 3" ],
        "Last Item"
    ],
    "Random 3"
);

$dropdown = $dropdown->cmp();

BEGIN_PGML
Select an item:  [_]{$dropdown}
END_PGML


ENDDOCUMENT();

In reply to Alex Jordan

Answer checker for DropDown

by Steven Fiedler -
Thank you - this helps. I debated on opening another discussion but the below issue may be related. 

It would be helpful to learn more about the {label => value} option discussed in the parserPopUp.pl POD. Below is a MWE where I unsuccessfully attempted to display the value "foo" in the Answer Preview box. My impression from the POD was that the value "foo" would serve as a (more succinct) representation of the label, but that is obviously not correct.

DOCUMENT();
loadMacros('PGstandard.pl', 'PGML.pl','parserPopUp.pl');

$dropdown = DropDown(
    [   {"First Item"=>foo},
        "Last Item"    ],
    "First Item"
);

$dropdown = $dropdown->cmp(
 checker => sub {
             my ($correct,$student,$ansHash) = @_;
             $ansHash->{preview_latex_string}=$correct; #Answer Preview
             return 1;
            }
);

BEGIN_PGML
Select an item:  [_]{$dropdown}
END_PGML

ENDDOCUMENT();






Attachment Screenshot_2025-10-03_11-03-04.png
In reply to Steven Fiedler

Answer checker for DropDown

by Glenn Rice -

Yes, your impression is completely incorrect.  The values are never shown to the students.  The values are are the internal value for the options in the HTML select element.  These values are what is displayed for the student answer when you view the past answers.  The point of this option is to make is easier for a instructor to determine what the student answer means when they are looking at the past answer table.  Before this was added all you would see in the past answer table were things like B0, B1, ...., and that is still the case if you don't use the value option.

In reply to Glenn Rice

Answer checker for DropDown

by Steven Fiedler -

I apologize for the extended discussion, but my main goal for this type of problem was to share answers between custom answer checkers in multiple drop down menus. The last paragraph of the parserPopUp.pl appears to indicate in spirit that this is possible. However, I've made little headway despite attempting to use Glenn's previous instruction with MultiAnswer and $inputs_ref in this post and its follow-up responses.

Below is a MWE where sharing such answers could come in handy. I'd greatly appreciate any direction on this.

DOCUMENT();
loadMacros('PGstandard.pl', 'PGML.pl','parserPopUp.pl');

$first="First Item";
$second="Second Item";
$dropdown = DropDown( [$first,$second],$first );

$dropdownA = $dropdown->cmp(
 checker => sub {
    my ($correct,$student,$ansHash) = @_;
    return 1;
  }
);

$dropdownB = $dropdown->cmp(
 checker => sub {
    my ($correct,$student,$ansHash) = @_;
    return 1;
  }
);

BEGIN_PGML
Select one of each item:

 [_]{$dropdownA}

 [_]{$dropdownB}
END_PGML
ENDDOCUMENT();

In reply to Steven Fiedler

Answer checker for DropDown

by Steven Fiedler -

Below is a more targeted MWE on asking how to extract student answers from drop down menus. Note: No values are returned to the bold lines.

DOCUMENT();
loadMacros('PGstandard.pl', 'PGML.pl','parserPopUp.pl');

$first="First Item";
$second="Second Item";
$dropdown = DropDown( [$first,$second],$second,values=>['foo','bar'] );

$ans1 = $dropdown->cmp(
 checker => sub {  
  my ($correct,$student,$ansHash) = @_;
     return 1;  }
);


BEGIN_PGML
Select one of each item:

 [_]{$ans1}

[`\phantom{vspace}`]

From AnswerHash.pm
-------------------
The correct_ans is:
[$ans1->rh_ans->{correct_ans}]

The problem type is:
[$ans1->rh_ans->{type}]

*The student answer is:*
[$ans1->rh_ans->{student_ans}]

*The original student answer is:*
[$ans1->rh_ans->{original_student_ans}]


[`\phantom{vspace}`]

From the dropdown parser
----------------------------
The first label is:
[$dropdown->{labels}[0]]

The second label is:
[$dropdown->{labels}[1]]

The answer label is:
[$dropdown->answerLabel]

The answer value is:
[$dropdown->value]

END_PGML

ENDDOCUMENT();

Attachment Screenshot_2025-10-04_09-42-13.png
In reply to Steven Fiedler

Answer checker for DropDown

by Glenn Rice -

I still don't really know what you want.  Your second example seems to indicate that you want to show the students answers in the problem.  Although, that can be done, I really don't see the point of that.  There are various techniques for using earlier answers in the grading of later answers in the problem, and you linked to the forum discussion where some techniques for doing so were pointed out.

So if you can give some real indication of what you really want to do with the answers in the problem, that would help.

In reply to Glenn Rice

Answer checker for DropDown

by Steven Fiedler -

Thank you Glenn for seeking clarification on my objective. Below is pseudocode in quotes for the specific problem that I'm attempting to write.

"Boyle's law demonstrates that DropDownA (Temperature, Pressure, Volume, Number of Molecules) is DropdownB (directly proportional, inversely proportional) to DropDownC (Temperature, Pressure, Volume, Number of Molecules)".

The custom graders for DropDownA and DropdownC will require knowledge students answers in the both to correctly grade the overall problem. My previous post was a demonstration that I could not harvest student answers from any DropDown menu.

In reply to Steven Fiedler

Answer checker for DropDown

by Glenn Rice -

That sort of problem is easily accomplished with a MultiAnswer problem.  For example,

DOCUMENT();

loadMacros(
    'PGstandard.pl',  'PGML.pl',
    'parserPopUp.pl', 'parserMultiAnswer.pl',
    'PGcourse.pl'
);

$ma = MultiAnswer(
    DropDown([ 'temperature', 'pressure', 'volume', 'number of molecules' ], 1),
    DropDown([ 'directly proportional', 'inversely proportional' ],          1),
    DropDown([ 'temperature', 'pressure', 'volume', 'number of molecules' ], 2)
)->with(
    singleResult => 1,
    checker         => sub {
        my ($correct, $student, $self, $ansHash) = @_;
        return ($student->[0] == $correct->[0]
                && $student->[1] == $correct->[1]
                && $student->[2] == $correct->[2])
            || ($student->[0] == $correct->[2]
                && $student->[1] == $correct->[1]
                && $student->[2] == $correct->[0]) ? 1 : 0;
    }
);

BEGIN_PGML
Complete the statement below by selecting the appropriate answers.

[<
    Boyle's law states that the [_]{$ma} of a fixed mass of gass is [_]{$ma} to the [_]{$ma}.
>]{ [ class => 'ww-feedback-container' ] }
END_PGML

ENDDOCUMENT();
In reply to Glenn Rice

Answer checker for DropDown

by Steven Fiedler -
Glenn - I appreciate you staying with the thread and for providing this elegant solution.

I'm finding that converting some of the simplest pen & paper questions to comparable questions on WeBWorK to be an interesting but sometimes difficult task. Particularly when permitting students to make use of multiple attempts. The help of all the responders on the forum(s) and the github site helps makes this transition possible. Thank you.