grade_this | R Documentation |
grade_this()
allows instructors to write custom logic to evaluate, grade
and give feedback to students. To use grade_this()
, call it directly in
your *-check
chunk:
```{r example-check} grade_this({ # custom checking code appears here if (identical(.result, .solution)) { pass("Great work!") } fail("Try again!") }) ```
grade_this()
makes available a number of objects based on the exercise and
the student's submission that can be used to evaluate the student's submitted
code. See ?"grade_this-objects"
for more information about these objects.
As the instructor, you are free to use any logic to determine a student's
grade as long as a graded()
object is signaled. The check code can also
contain testthat expectation code. Failed testthat expectations
will be turned into fail()
ed grades with the corresponding message.
A final grade is signaled from grade_this()
using the graded()
helper
functions, which include pass()
, fail()
, among others. grade_this()
uses condition handling to short-circuit further evaluation when a grade is
reached. This means that you may also signal a failing grade using any of the
expect_*()
functions from testthat, other functions designed to work
with testthat, such as checkmate, or standard R errors via
stop()
. Learn more about this behavior in graded()
in the section
Return a grade immediately.
grade_this(
expr,
...,
maybe_code_feedback = getOption("gradethis.maybe_code_feedback", TRUE)
)
expr |
The grade-checking expression to be evaluated. This expression
must either signal a grade via By default, errors in this expression are converted to "internal problem"
grades that mask the error for the user. If your grading logic relies on
unit-test-styled functions, such as those from testthat, you can use
|
... |
Ignored |
maybe_code_feedback |
Should Typically, |
Returns a function whose first parameter will be an environment
containing objects specific to the exercise and submission (see Available
variables). For local testing, you can create a version of the expected
environment for a mock exercise submission with mock_this_exercise()
.
Calling the returned function on the exercise-checking environment will
evaluate the grade-checking expr
and return a final grade via graded()
.
grade_this_code()
, mock_this_exercise()
, gradethis_demo()
# For an interactive example run: gradethis_demo()
# Suppose we have an exercise that prompts students to calculate the
# average height of Loblolly pine trees using the `Loblolly` data set.
# We might write an exercise `-check` chunk like the one below.
#
# Since grade_this() returns a function, we'll save the result of this
# "chunk" as `grader()`, which can be called on an exercise submission
# to evaluate the student's code, which we'll simulate with
# `mock_this_exercise()`.
grader <-
# ```{r example-check}
grade_this({
if (length(.result) != 1) {
fail("I expected a single value instead of {length(.result)} values.")
}
if (is.na(.result)) {
fail("I expected a number, but your code returned a missing value.")
}
avg_height <- mean(Loblolly$height)
if (identical(.result, avg_height)) {
pass("Great work! The average height is {round(avg_height, 2)}.")
}
# Always end grade_this() with a default grade.
# By default fail() will also give code feedback,
# if a solution is available.
fail()
})
# ```
# Simulate an incorrect answer: too many values...
grader(mock_this_exercise(.user_code = Loblolly$height[1:2]))
# This student submission returns a missing value...
grader(mock_this_exercise(mean(Loblolly$Seed)))
# This student submission isn't caught by any specific tests,
# the final grade is determined by the default (last) value in grade_this()
grader(mock_this_exercise(mean(Loblolly$age)))
# If you have a *-solution chunk,
# fail() without arguments gives code feedback...
grader(
mock_this_exercise(
.user_code = mean(Loblolly$age),
.solution_code = mean(Loblolly$height)
)
)
# Finally, the "student" gets the correct answer!
grader(mock_this_exercise(mean(Loblolly$height)))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.