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 |
---|---|
... | 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()
.
# 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]))#> <gradethis_graded: [Incorrect] #> I expected a single value instead of 2 values. #> ># This student submission returns a missing value... grader(mock_this_exercise(mean(Loblolly$Seed)))#> Warning: argument is not numeric or logical: returning NA#> <gradethis_graded: [Incorrect] #> I expected a number, but your code returned a missing value. #> ># 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)))#> <gradethis_graded: [Incorrect] #> Incorrect. But no need to fret, try it again. #> ># 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) ) )#> <gradethis_graded: [Incorrect] #> Incorrect. In `Loblolly$age`, I expected `height` where you wrote #> `age`. Try it again. I have a good feeling about this. #> >#> <gradethis_graded: [Correct] Great work! The average height is 32.36.>