grade_code()
no longer fails if.envir_result
or.envir_solution
is missing (#355).detect_mistakes()
now keeps a version of standardized user and solution code with and without default arguments added. Missing arguments are detected by comparing the user code with defaults to the solution code without defaults. Surplus arguments are detected by comparing the user code without defaults to the solution code with defaults (#356).- This helps avoid spurious feedback when comparing code that involves S3 methods. If the user's code differs from the solution code in a way that means a different S3 method is used, the standardized code may gain different default arguments. This could result in feedback about missing or surplus arguments that were added by code standardization rather than by the student, which is not actionable feedback. By no longer looking for default arguments that are missing or surplus in the user code, we ensure that students receive more actionable feedback, likely about the incorrect argument that resulted in the use of a different S3 method.
- The
gradethis_equal.list()
method is now only used if bothx
andy
are bare lists (as defined byrlang::is_bare_list()
) (#357).- This fixes a bug where a list could be marked as equal to another object with the same contents but a different class, e.g.
list(a = 1, b = 2)
andc(a = 1, b = 2)
ordata.frame(a = 1, b = 2)
.
- This fixes a bug where a list could be marked as equal to another object with the same contents but a different class, e.g.
- Fix bug where
call_standardise_formals()
would fail when given apurrr::map()
function where.f
is an index rather than a function (#359).
code_feedback()
now standardizes arguments to functions defined within student and solution code before comparing code. It also now successfully standardizes arguments passed through...
by mapping functions into functions defined by setup code (#349).gradethis_equal()
now has a method for objects of classlist
. If two lists are notidentical()
and their lengths are the same,gradethis_equal()
is applied to each element pairwise. This allows special logic for specific classes to be used for list elements of that class (#351).call_standardise_formals()
now appliesggplot2::standardise_aes_names()
to all arguments ofggplot2
functions. This means it no longer detects inconsequential differences between, e.g.,color =
andcolour =
(#353).- When an exercise without an
-error-check
chunk returns an error, the default feedback now includes both the error message and code feedback iffail.hint = TRUE
. Previously the error message was only shown whenfail.hint = FALSE
and code feedback was only shown whenfail.hint = TRUE
(#352).
gradethis_equal()
now has default arguments ofx = .result
andy = .solution
(#347).gradethis_equal.default()
now has a default argument oftolerance = sqrt(.Machine$double.eps)
.
- Add
fail_if_not_equal()
(#346). pass_if_equal()
,fail_if_equal()
, andfail_if_not_equal()
now callgradethis_equal()
, an S3 generic which callswaldo::compare()
by default. This allows other methods forgradethis_equal()
to handle special cases (#346).
call_standardise_formals()
now attempts to standardize arguments passed through...
in mapping functions likelapply()
orpurrr::map()
(#344).
call_standardise_formals()
now attempts to standardize the arguments of calls to S3 generics (#339).
pass_if()
andfail_if()
now produce more informative error messages if theircond
argument is invalid (#341).
- New functions:
user_object_get()
,user_object_exists()
anduser_object_list()
can be used to interact with objects created by the student's code.solution_object_get()
,solution_object_exists()
andsolution_object_list()
do the same for objects created by the solution code (#333). - New function:
with_exercise()
allows you to evaluate an expression as if it were run insidegrade_this()
with an associated exercise. It can be used alongsidemock_this_exercise()
for testing grading code outside the context of a learnr tutorial (#333). .envir_solution
is now included in thegrade_this()
check environment alongside.envir_prep
and.envir_result
..envir_solution
contains the state of the environment used to execute solution code, just as.envir_result
does for student code (#333).
- Code feedback is now disabled for non-R exercise engines (#321).
- More operators were added to our list of infixes (#327).
- Feedback for error messages are now slightly more generic and refer to your code instead of your R code (@Laura-Puckett #318).
code_feedback()
now supports multiple solutions. By default,code_feedback()
now looks for.solution_code_all
. If multiple solutions are present, string distance is used to determine the closest solution to.user_code
and give feedback based on that solution. Functions that callcode_feedback()
internally (grade_this_code()
,fail_if_code_feedback()
andmaybe_code_feedback()
) inherit the same functionality (#289).- The
solution_code
argument ofcode_feedback()
is now the single entry-point for solution code incode_feedback()
,fail_if_code_feedback()
and other functions that work with both.solution_code
and.solution_code_all
. In these cases, the default argument values will use multiple solutions if they exist (#305). pass_if_equal()
supports multiple solutions when authors sety = .solution_all
to compare the student's result with all solutions. For additional details, please see the new section, Comparing with Multiple Solutions, in?pass_if_equal
(#306).- A new
vignette("multiple_solutions")
describes how gradethis can be used to provide feedback for exercises with more than one solution (#312). gradethis_error_checker()
gains thehint
argument fromfail()
which follows the globalgradethis.fail.hint
option. WhenFALSE
, the error feedback won't include code feedback hints (thanks @cswclui, #315).gradethis_exercise_checker()
can now be configure to evaluate solution code for non-R exercise engines by providing a function ofcode
andenvir
to thesolution_eval_fn
argument. In addition to evaluation R exercise solutions, gradethis will now also evaluate SQL exercise solutions (#316).
- gradethis now includes support for multiple solutions with different results. The solutions are made available in the
.solution_all
object ingrade_this()
grading code.pass_if_equal()
gains support for multiple solutions as itsy
argument. If.solution_all
is used as they
argument ofpass_if_equal()
, it will return a passing grade ifx
matches any of the multiple solutions (#296).
- You may now call
return()
ingrade_this()
grading code to exit grading early. This is allowed in code and error checking code, but will result in an "internal error" when used in the-check
chunk grading code (#284). - gradethis now includes low-level support for multiple solutions. Authors can add multiple solutions in the
-solution
chunk, separated by code section headers, e.g.# ----
. (note only trailing dashes,----
, are supported). These additional solutions are made available in the.solution_code_all
object ingrade_this()
grading code and are named with the code section name if one is provided, e.g.# first ----
. When multiple solutions are provided using the code section comments,.solution
and.solution_code
will default to the last solution. (#286) grade_this_code()
andfail_if_code_feedback()
now return informative feedback with a neutral grade when no code is submitted and when not previously caught by learnr (#288).- gradethis can now be used to grade non-R code. If learnr can evaluate the non-R code and return the result of the submitted code as an R object, then gradethis can be used to grade the submission result. Grading code is still written in R and code feedback tool designed for R will not work as expected (#290).
pass_if_equal()
andfail_if_equal()
gain a tolerance argument which is passed towaldo::compare()
. This defaults to the same default value asall.equal()
to avoid floating point errors when comparing numeric values (#295).
grade_this_code()
gains anaction
argument, allowing authors to choose ifgrade_this_code()
should only"pass"
or"fail"
the user's submission. By default,grade_this_code()
usesaction = "both"
to maintain current behavior. (#276)- When combined with learnr version 0.10.1.9017 or later, gradethis' exercise checking function will not require that grading code absolutely return feedback unless exercise checking is at the
"check"
stage. (#276)
- Errors in the grading code are now returned as neutral grades rather than failing grades. The feedback message and type can be changed with two new arguments to
gradethis_setup()
:grading_problem.message
andgrading_problem.type
(#256).
- Added
gradethis_error_checker()
, a more robust checking function for general use when the student's submission should not throw an error. (#234)
grade_this()
no longer automatically converts errors tofail()
grades, instead authors need to wrap unit-test-style code infail_if_error()
to convert them to grades. This helps to better differentiate between unexpected errors resulting from the author's grading code and portions of the grading code where errors are expected and indicative of a problem with the user's code. (#254)
- All failing
graded()
helper functions, likefail()
etc, now take ahint
argument that whenTRUE
adds a code feedback hint to the custom feedback message. The default value of this argument can be set viagradethis_setup()
. (#216) - Passing and failing
graded()
helper functions gain apraise
orencourage
argument (respectively) to prepend a random praising phrase when passing or append a random encouraging phrase when failing. The default values of these arguments can be set viagradethis_setup()
. (#227) - New functions:
give_praise()
andgive_encouragement()
. Follow the same pattern asgive_code_feedback()
to automatically add praise or encouragement topass()
orfail()
grades, respectively. (#227) - New function:
fail_if_code_feedback()
. Returns an incorrect grade when there are differences between the user code and solution code (if it exists). (#228) - We now use placeholder sentinel objects as function argument defaults to signal that a function will find the object in the
grade_this()
check environment. The help page?grade_this-objects
describes these objects and documents their purpose, which you can also find by calling one of the placeholders, e.g..result
. (#232)
- The
x
argument ofpass_if()
andfail_if()
has been renamedcond
and both functions now work insidegrade_this()
, although the function and formula versions are not supported there. (#216)
- New function:
give_code_feedback()
. When applied to agrade_this()
orgrade_result()
grading function, code feedback is added to the messages of anyfail()
grades. (#219)
gradethis_setup()
now uses a new argument order that favors the gradethis-specific options (#212).gradethis.code.feedback
is nowgradethis.maybe_code_feedback
. (#219)- The
space_before
andspace_after
arguments ofmaybe_code_feedback()
have been deprecated in favor of more flexible argumentsbefore
andafter
that accept arbitrary strings to add before or after the message. (#219)
- Calling
gradethis_setup()
is no longer required if you want to use the default gradethis setup. Simply calllibrary(gradethis)
. You can usegradethis_setup()
to adjust the default values of any options. (#210)
- The "Insert Exercise ..." RStudio Addins were removed from gradethis (#196).
- The names of several global options were changed in #210. This will only affect users who were setting the options directly rather than using
gradethis_setup()
. The name changes are:gradethis.code.partial_matching
is nowgradethis.allow_partial_matching
gradethis.code.feedback
is nowgradethis.fail_code_feedback
gradethis.code.correct
is nowgradethis.code_correct
gradethis.code.incorrect
is nowgradethis.code_incorrect
gradethis_glue_correct
is nowgradethis.glue_correct
gradethis_glue_incorrect
is nowgradethis.glue_incorrect
gradethis_glue_correct_test
is nowgradethis.glue_correct_test
gradethis_glue_incorrect_test
is nowgradethis.glue_incorrect_test
grade_learnr()
is now calledgradethis_exercise_checker()
.grade_learnr()
will continue to work but will issue a deprecation warning (#204).
pass_if_equal()
now compares the submitted.result
to the exercise.solution
by default (#203).- New function:
debug_this()
returns information about the various objects available for use by grading code. It is designed for tutorial authors to use during development and can be used in*-check
chunks or insidegrade_this()
grading code and the feedback is shown in the tutorial when clicking on Submit Answer. See?debug_this
for more information. (#203) graded()
and its pass/fail helper functions now accepttype
andlocation
parameters that specify how the feedback is displayed (see learnr Custom Checking for more details about these options).
- The
gradethis.glue_pipe
option is now calledgradethis.pipe_warning
as it sets the default value of thepipe_warning()
function.pipe_warning()
can be included in the glue strings of other messages, such as those set bygradethis.code.incorrect
(#193). - The
glue_pipe
argument ofglue_code()
is now deprecated (#193).
- Checking exercise code with blanks, e.g.
____
, now returns clear feedback that students should replace the____
with code. (#153) - The
exercise.parse.error
global option now accepts a function with one argument. The function is given the gradethis check environment with an additional.error
object containing the parse error condition. (#153) - Improved code feedback for function definitions will detect mistakes in function arguments (#178)
- gradethis now accepts markdown or an htmltools
tags
or atagList()
object for feedback messages. Markdown processing is handled via commonmark. Internally, all code feedback messages now use markdown. (#189)
- Improved code feedback for function definitions will detect mistakes in function arguments (#178)
- gradethis now uses learnr for
random_praise()
andrandom_encouragement()
.random_encourage()
has been soft-deprecated (#183).
- New function:
grade_this(expr)
. Evaluates the expression and returns the first grade that is called or error that is thrown. - New function:
grade_this_code(correct, incorrect)
. Makes a grade from comparing the user code against the solution code. This is a simplified version ofgrade_code()
. - New function:
code_feedback()
. Compares the user code against the solution code.
- Deprecated
grade_feedback()
graded()
now returns and signals a condition with class"gradethis_graded"
instead of returning an object with class"grader_graded"
grade_code()
,grade_result()
, andgrade_result_strict()
now return a function that accepts checking arguments to be supplied bygrade_learnr()
grade_code()
will now throw an error (rather than returningNULL
) if no solution code is providedevaluate_condition()
now acceptslast_value
andenv
rather thangrader_args
andlearnr_args
condition()
s now have a class of"gradethis_condition"
- Added a
NEWS.md
file to track changes to the package.