Difference between revisions of "AdaptiveParameters"
m |
(modify based on a forum post to avoid certain issues with the 'produce_equivalence_message' filter.) |
||
Line 45: | Line 45: | ||
<tr valign="top"> |
<tr valign="top"> |
||
<td style="background-color:#eeddff;border:black 1px dashed;"> |
<td style="background-color:#eeddff;border:black 1px dashed;"> |
||
+ | <pre> |
||
+ | ANS( $aSoln->cmp( checker => sub { |
||
+ | my ( $correct, $student, $self ) = @_; |
||
+ | # return 0 if ( $student == Formula(0) ); # see comments |
||
+ | if ($self->{_filter_name} ne 'produce_equivalence_message') { |
||
+ | my $context = Context()->copy; |
||
+ | $context->flags->set(no_parameters=>0); |
||
+ | $context->variables->add('C0'=>'Parameter'); |
||
+ | $student = Formula($context,$student); |
||
+ | $correct = Formula($context,"C0 * e^x - 1"); |
||
+ | } |
||
+ | return $correct == $student; |
||
+ | })); |
||
+ | </pre> |
||
+ | <td style="background-color:#eeccff;padding:7px;"> |
||
+ | <p> |
||
+ | Then in the answer, we define a [[CustomAnswerCheckers|custom answer checker]] that creates a copy of the Context in which an adaptive parameter is allowed, redefines the student and correct answers in that context, and checks that the answers match with the adaptive parameter. |
||
+ | </p> |
||
+ | <p> |
||
+ | Again, note that if we just want to allow a solution to differ by an <em>additive constant</em> from the answer in the problem, we can use the existing MathObjects infrastructure, as discussed on the [[FormulasToConstants|formulas up to constants]] techniques page. |
||
+ | </p> |
||
+ | <p> |
||
+ | Some history to help users who have run into trouble with older versions of this page. This page has been updated based on [https://webwork.maa.org/moodle/mod/forum/discuss.php?d=497 a forum post] to fix some issues with modified versions of the |
||
+ | original recipe for a similar needs. The '''old''' code on this page was: |
||
<pre> |
<pre> |
||
ANS( $aSoln->cmp( checker => sub { |
ANS( $aSoln->cmp( checker => sub { |
||
Line 57: | Line 81: | ||
})); |
})); |
||
</pre> |
</pre> |
||
− | <td style="background-color:#eeccff;padding:7px;"> |
||
+ | </p> |
||
<p> |
<p> |
||
− | Then in the answer, we define a [[CustomAnswerCheckers|custom answer checker]] that creates a copy of the Context in which an adaptive parameter is allowed, redefines the student and correct answers in that context, and checks that the answers match with the adaptive parameter. |
||
+ | However, in the setting where the correct answer is just a multiple of a standard answer without an additive constant we '''would expect''' code like the following to work: |
||
+ | <pre> |
||
+ | # HAS BUGS |
||
+ | $aSoln = Compute("e^x"); |
||
+ | ANS( $aSoln->cmp( checker => sub { |
||
+ | my ( $correct, $student, $self ) = @_; |
||
+ | my $context = Context()->copy; |
||
+ | $context->flags->set(no_parameters=>0); |
||
+ | $context->variables->add('C0'=>'Parameter'); |
||
+ | $student = Formula($context,$student); |
||
+ | $correct = Formula($context,"C0 ($correct)"); |
||
+ | return $correct == $student; |
||
+ | })); |
||
+ | </pre> |
||
+ | but that code has 2 issues: |
||
+ | <ul> |
||
+ | <li>If "0" was entered as the answer then the following submission would report "Please inform your instructor that an error occurred while checking your answer at [PG]/lib/Value/AnswerChecker.pm line 252"</li> |
||
+ | <li>Entering a scalar multiple of the prior answer (whether correct or now) would trigger the message "This answer is equivalent to the one you just submitted."</li> |
||
+ | </ul> |
||
+ | The solution to these issues (provided by Davide Cervone in the forum thread) is to use code like: |
||
+ | <pre> |
||
+ | $aSoln = Compute("e^x"); |
||
+ | ANS( $aSoln->cmp( checker => sub { |
||
+ | my ( $correct, $student, $self ) = @_; |
||
+ | return 0 if ( $student == Formula(0) ); |
||
+ | if ($self->{_filter_name} ne 'produce_equivalence_message') { |
||
+ | my $context = Context()->copy; |
||
+ | $context->flags->set(no_parameters=>0); |
||
+ | $context->variables->add('C0'=>'Parameter'); |
||
+ | $student = Formula($context,$student); |
||
+ | $correct = Formula($context,"C0 ($correct)"); |
||
+ | } |
||
+ | return $correct == $student; |
||
+ | })); |
||
+ | </pre> |
||
+ | which bypasses the adaptive parameter code for the 'produce_equivalence_message' filter, and also includes a test to avoid allowing 0 times the standard answer to be accepted. (See [https://webwork.maa.org/moodle/mod/forum/discuss.php?d=324 this forum post] for a mention of the test against 0.) |
||
</p> |
</p> |
||
<p> |
<p> |
||
− | Again, note that if we just want to allow a solution to differ by an <em>additive constant</em> from the answer in the problem, we can use the existing MathObjects infrastructure, as discussed on the [[FormulasToConstants|formulas up to constants]] techniques page. |
||
+ | Similar changes were made to the code on the left. |
||
</p> |
</p> |
||
+ | |||
</td> |
</td> |
||
</tr> |
</tr> |
Revision as of 04:38, 16 August 2020
Adaptive Parameters: PG Code Snippet
This code snippet shows the essential PG code to include adaptive parameters in a problem solution. Note that these are insertions, not a complete PG file. This code will have to be incorporated into the problem file on which you are working. This page is largely drawn from this discussion thread, which looks at one application.
Note that if we want to have a formula that is only unique up to a specified additive constant, we have the upToConstant
option in the answer checker, as discussed in the formulas up to constants page.
PG problem file | Explanation |
---|---|
$aSoln = Compute("e^x - 1"); |
In this case we work with the adaptive parameters only in the custom answer checker that we use for the problem, so no special set-up needs to be done in the problem set-up section of the PG file. Here we've defined |
BEGIN_TEXT Find one solution to the differential equation \[ \frac{dy}{dx} = y + 1. \] \( y = \) \{ ans_rule(35) \} END_TEXT |
And the text section of the file is similarly "normal." The general solution to this differential equation is y = c ex - 1, but a student could also write it as something like y = ec ex - 1. We use the adaptive parameter to find the value of the constant. |
ANS( $aSoln->cmp( checker => sub { my ( $correct, $student, $self ) = @_; # return 0 if ( $student == Formula(0) ); # see comments if ($self->{_filter_name} ne 'produce_equivalence_message') { my $context = Context()->copy; $context->flags->set(no_parameters=>0); $context->variables->add('C0'=>'Parameter'); $student = Formula($context,$student); $correct = Formula($context,"C0 * e^x - 1"); } return $correct == $student; })); |
Then in the answer, we define a custom answer checker that creates a copy of the Context in which an adaptive parameter is allowed, redefines the student and correct answers in that context, and checks that the answers match with the adaptive parameter. Again, note that if we just want to allow a solution to differ by an additive constant from the answer in the problem, we can use the existing MathObjects infrastructure, as discussed on the formulas up to constants techniques page. Some history to help users who have run into trouble with older versions of this page. This page has been updated based on a forum post to fix some issues with modified versions of the original recipe for a similar needs. The old code on this page was: ANS( $aSoln->cmp( checker => sub { my ( $correct, $student, $self ) = @_; my $context = Context()->copy; $context->flags->set(no_parameters=>0); $context->variables->add('C0'=>'Parameter'); my $c0 = Formula($context,'C0'); $student = Formula($context,$student); $correct = Formula($context,"$c0 e^x - 1"); return $correct == $student; })); However, in the setting where the correct answer is just a multiple of a standard answer without an additive constant we would expect code like the following to work: # HAS BUGS $aSoln = Compute("e^x"); ANS( $aSoln->cmp( checker => sub { my ( $correct, $student, $self ) = @_; my $context = Context()->copy; $context->flags->set(no_parameters=>0); $context->variables->add('C0'=>'Parameter'); $student = Formula($context,$student); $correct = Formula($context,"C0 ($correct)"); return $correct == $student; })); but that code has 2 issues:
The solution to these issues (provided by Davide Cervone in the forum thread) is to use code like: $aSoln = Compute("e^x"); ANS( $aSoln->cmp( checker => sub { my ( $correct, $student, $self ) = @_; return 0 if ( $student == Formula(0) ); if ($self->{_filter_name} ne 'produce_equivalence_message') { my $context = Context()->copy; $context->flags->set(no_parameters=>0); $context->variables->add('C0'=>'Parameter'); $student = Formula($context,$student); $correct = Formula($context,"C0 ($correct)"); } return $correct == $student; })); which bypasses the adaptive parameter code for the 'produce_equivalence_message' filter, and also includes a test to avoid allowing 0 times the standard answer to be accepted. (See this forum post for a mention of the test against 0.) Similar changes were made to the code on the left. |