By default, each answer is weighted 0 or 1 based on correctness. If your WeBWorK problem uses a custom answer checker, to award partial weights for specific answers in Edfinity:
- Go to the problem and select the Problem details tab.
- Enable Partial WeBWorK answer scoring.
- Be sure to publish your assignment in order for students to see the change.
Example usage
To give partial credit for different answers, the problem type must be algorithmic (WeBWorK) and use a custom answer checker to return weights other than 0 or 1. It is important to note that these are weights and will scale depending on the number of points an answer blank is worth. For example, if an answer blank is worth 3 points and an alternative answer is set to 0.75 partial credit, then 0.75 * 3 = 2.25 points will be awarded for this alternative answer.
WeBWorK's MathObjects must also be used. We recommend viewing Answer Checkers (MathObjects) for an introduction to the default MathObject answer checkers, and Custom Answer Checkers and Custom Answer Checkers for Lists to learn more about custom answer checkers.
There are three different types of custom answer checkers, depending on the type of answer.
Simple custom answer checker
Unless the answer is a List or RadioButtons, a simple custom checker that returns weights other than 0 or 1 for alternative answers can be used. See Custom Answer Checkers for more information on how to work with custom answer checkers.
DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGML.pl",
);
TEXT(beginproblem());
##############################################################################
# Problem Setup
##############################################################################
Context("Numeric");
# Suppose the question is find f'(x) where f(x) = x^p + b.
$p = random(3, 9, 1);
$b = random(2, 5, 1);
$p_minus_1 = $p - 1;
# You may want to 0.5 credit if they either forget to drop the power
# or leave the constant.
$wrong_answer_1 = Formula("x^($p_minus_1)");
$wrong_answer_2 = Formula("$p x^($p_minus_1) + $b");
# You may want to only give 0.25 if they make both errors.
$wrong_answer_3 = Formula("x^($p_minus_1) + $b");
# We can now set up the custom answer checker to handle assigning partial
# credit. IMPORTANT: Remember to toggle Partial WeBWorK answer scoring
# under the Problem details tab.
$correct_answer = Formula("$p x^($p_minus_1)")->reduce->cmp(
checker => sub {
my ($correct, $student, $ansHash) = @_;
return 0.5 if $student == $wrong_answer_1;
return 0.5 if $student == $wrong_answer_2;
return 0.25 if $student == $wrong_answer_3;
return $student == $correct;
},
);
##############################################################################
# Problem Statement
##############################################################################
BEGIN_PGML
Find the derivative of [``f(x) = x^{[$p]} + [$b]``].
[``f'(x) = ``] [__]{$correct_answer}
END_PGML
ENDDOCUMENT();
Note how forgetting to drop the power, 5, down in front gives 0.5 / 1 (half weight of 1). The other alternative answers work similarly.
List custom answer checker
Custom answer checking for List objects is a bit more complicated because you can act on single elements or the list as a whole. See Custom Answer Checkers for Lists. However, the idea is the same as above in that you can assign weights to single answers or the entire list. An important difference is that the weight is a fraction of the total number of answers in the list. For example, if the correct answer is a List with three expected answers, then return a number between 0 and 3 instead of between 0 and 1. Furthermore, $showPartialCorrectAnswers = 1; must be included in the code; otherwise, partial credit is ignored.
DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGML.pl",
);
TEXT(beginproblem());
$showPartialCorrectAnswers = 1;
################################################################################
# Problem Setup
################################################################################
Context("Numeric");
# Set up (x - a)(x^2 - (b + c) x + (b * c)) = 0.
$a = random(-4, -1);
$b = random(1, 4);
$c = random($b + 1, 5);
$x1 = Real($a);
$x2 = Real($b);
$x3 = Real($c);
# showHints => 0 and showLengthHints => 0 can be removed:
# You don't have to disable hints and length hints if you don't want to.
# IMPORTANT: Remember to toggle Partial WeBWorK answer scoring
# under the Problem details tab.
$ans = List($x1, $x2, $x3)->cmp(showHints => 0, showLengthHints => 0,
list_checker => sub{
my ($correct, $student, $ansHash, $value) = @_;
# When comparing $student to other answers, ensure that at least one has
# List around it for proper comparison.
# 0.5/3 = 1/6 credit is awarded.
if ($student == List($x1) ||
$student == List($x2) ||
$student == List($x3))
{
return (0.5);
}
# The second argument is included for illustration purposes.
# You can remove it if you don't want to show the student a message.
# 2/3 credit is awarded.
if ($student == List($x1, $x2) ||
$student == List($x1, $x3) ||
$student == List($x2, $x3))
{
return (2, "You have two solutions correct. One more to go!");
}
return (3) if $student == List($correct);
}
);
##############################################################################
# Problem Statement
##############################################################################
BEGIN_PGML
Find the zeros of [``(x - [$a])(x^2 - [$b + $c] x + [$b * $c])``].
[``x = ``] [__]{$ans}
END_PGML
ENDDOCUMENT();
RadioButtons custom answer checker
RadioButtons behave differently from other MathObjects, so Edfinity has created a custom macro to handle this situation. To use this functionality, include the partialRadioButtons.pl macro in the loadMacros call.
Note that partialRadioButtons behaves very similarly to RadioButtons, but requires weights to be assigned, and the correct answer is automatically the first choice with its weight set to 1. You can also use the following optional parameters.
- letterLabels => 1 will add letters in front of each choice (up to 26 choices). The default is 0.
- randomOrder => 1 will randomize the order of all the choices, except for the choices passed in makeLast. The default is 0.
- Pass choice and weight pairs with makeLast to force certain answers to appear last. These choices will always be displayed in the order they are passed.
- separator => "..." can be used to change how the choices are displayed. The default is $BR.
- labels => [...] can be used to set custom labels. The default is no labels. Note that letterLabels=>1 supercedes this option (labels is ignored).
- labelFormat => "..." to specify how to display the labels using sprintf strings with %s to specify where the label should go. The default is "${BBOLD}%s${EBOLD}. ".
DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGML.pl",
"partialRadioButtons.pl",
);
TEXT(beginproblem());
##############################################################################
# Problem Setup
##############################################################################
Context("Numeric");
# Suppose the question is find f'(x) where f(x) = x^p + b.
$p = random(3, 9, 1);
$b = random(2, 5, 1);
$p_minus_1 = $p - 1;
# We set up the radio buttons, assigning weights. Two approaches are given:
# 1. The first, uncommented approach fixes the order of all but two choices
# by placing brackets around the two choices to randomize their order.
# 2. The second randomizes the order of all non-makeLast options, uses the
# letterLabels optional parameter, and includes two options in makeLast.
# You can uncomment this out to see it in action. Pro-tip: select the
# text and use Ctrl + /.
# A RadioButtons object and a custom answer checker to handle the partial scoring
# is returned from the partialRadioButtons call.
# IMPORTANT: Remember to toggle Partial WeBWorK answer scoring
# under the Problem details tab.
($radio_buttons, $partial_checker) = partialRadioButtons(
[
# Places these two first with weight 0, and the third with weight 0.25.
["\(0\)", "\(x^{$p}\)", 0],
["\(x^{$p_minus_1} + $b\)", 0.25],
# The order of these two is randomized with weight 0.5.
[["\(x^{$p_minus_1}\)", "\($p x^{$p_minus_1} + $b\)"], 0.5],
# Make sure at least one answer has weight 1. This can also be used
# accept multiple correct answers.
["\($p x^{$p_minus_1}\)", 1],
]
);
# ($radio_buttons, $partial_checker) = partialRadioButtons(
# [
# ["\(0\)", "\(x^{$p}\)", 0],
# ["\(x^{$p_minus_1} + $b\)", 0.25],
# ["\($p x^{$p_minus_1} + $b\)", 0.5],
# ["\($p x^{$p_minus_1}\)", 1],
# ],
# letterLabels => 1,
# randomOrder => 1,
# makeLast => [
# ["\(x^{$p_minus_1}\)", 0.5],
# ["None of the above.", 0],
# ],
# separator => "$BR $HR",
# labelFormat => "${BITALIC}%s.${EITALIC} ",
# );
##############################################################################
# Problem Statement
##############################################################################
BEGIN_PGML
Find the derivative of [``f(x) = x^{[$p]} + [$b]``].
[@
ANS($radio_buttons->cmp(checker=>$partial_checker));
$radio_buttons->buttons();
@]*
END_PGML
ENDDOCUMENT();