From d5cf9dea1c7b0fabc1dbf7705002163a6aa6b0c0 Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Wed, 14 Aug 2019 18:54:39 -0400 Subject: [PATCH] Doc fixes (#62) and function pruning * comment out unused functions, move fxns to separate R files * small doc changes for pkgdown * doc fixes * rebase/fix conflicts/fix docs for R CMD check * barret review changes * reflow docstring, noRd get_* functions * condition pass_if fail_if all under one documentation * remove period from grade_learnr to keep consistent with other fxns --- NAMESPACE | 3 - R/check_code.R | 43 +++++++---- R/check_result.R | 12 ++-- R/condition.R | 21 ++++-- R/detect_mistakes.R | 1 - R/evaluate_condition.R | 28 +++++--- R/get_code.R | 18 +++-- R/glue.R | 2 +- R/grade_learnr.R | 36 +++++----- R/grading_demo.R | 2 +- R/pass_fail_if.R | 20 ++++-- R/praise.R | 5 +- archive/view_tutorial.R | 16 ++--- man-roxygen/check_result_examples.R | 22 ++++++ ...{pass_fail_x_condition.R => x_condition.R} | 2 +- man/check_code.Rd | 45 ++++++++---- man/check_result.Rd | 34 +++++++-- man/condition.Rd | 72 ++++++++++++++++--- man/evaluate_condition.Rd | 16 +++-- man/fail_if.Rd | 20 ------ man/get_code.Rd | 31 -------- man/grade_learnr.Rd | 38 +++++----- man/grading_demo.Rd | 2 +- man/pass_if.Rd | 20 ------ man/praise.Rd | 7 ++ 25 files changed, 314 insertions(+), 202 deletions(-) create mode 100644 man-roxygen/check_result_examples.R rename man-roxygen/{pass_fail_x_condition.R => x_condition.R} (76%) delete mode 100644 man/fail_if.Rd delete mode 100644 man/get_code.Rd delete mode 100644 man/pass_if.Rd diff --git a/NAMESPACE b/NAMESPACE index fde97cdc..0f8eaff5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,9 +5,6 @@ export(check_result) export(condition) export(evaluate_condition) export(fail_if) -export(get_code) -export(get_solution_code) -export(get_user_code) export(grade_learnr) export(graded) export(grading_demo) diff --git a/R/check_code.R b/R/check_code.R index 5946790d..c100cc59 100644 --- a/R/check_code.R +++ b/R/check_code.R @@ -1,12 +1,16 @@ -#' Check code structure +#' Check code against a solution #' -#' \code{check_code()} compares user code to a solution (i.e. model code) and -#' describes the first way that the user code differs. If the user code exactly -#' matches the solution, \code{check_code()} returns a customizable success -#' message. +#' Checks the code expression or the code result against a solution. #' -#' \code{check_code()} provides a *strict* check in that the user code must -#' exactly match the solution. It is not enough for the user code to be +#' \code{check_code()} compares student code to a solution (i.e. model code) and +#' describes the first way that the student code differs. If the student code +#' exactly matches the solution, \code{check_code()} returns a customizable +#' success message (\code{correct}). If the student code does not match the +#' solution, a customizable incorrect message (\code{incorrect}) can also be +#' provided. +#' +#' \code{check_code()} provides a *strict* check in that the student code must +#' exactly match the solution. It is not enough for the student code to be #' equivalent to the solution code (e.g. to return the same result as the #' solution). #' @@ -18,9 +22,10 @@ #' 2. Make a "-solution" code chunk for the exercise to be checked in a learnr #' document. There is no need to supply a solution argument for #' \code{check_code()} if you call it from the "-check" chunk of the same -#' exercise. Likewise, there is no need to supply a user argument when you call -#' \code{check_code()} from a learnr document (learnr will provide the code -#' that the student submits when it runs \code{check_code()}. +#' exercise. Likewise, there is no need to supply a student submitted code +#' argument when you call \code{check_code()} from a learnr document (learnr +#' will provide the code that the student submits when it runs +#' \code{check_code()}. #' #' For best results, name all arguments provided in the solution code. #' @@ -30,16 +35,24 @@ #' @template learnr_args #' @template glue_correct #' @template glue_incorrect -#' @param glue_pipe A glue string that returns the final message displayed when a user uses a pipe, -#' \code{$>$}. Defaults to \code{getOption("gradethis_glue_pipe")}. +#' @param glue_pipe A glue string that returns the final message displayed when +#' the student uses a pipe, \code{$>$}. Defaults to +#' \code{getOption("gradethis_glue_pipe")}. #' -#' @return a \code{\link{graded}} object. -#' An incorrect message will describe the first way that the answer differs, -#' the message will be the content of the \code{glue_pipe} argument. +#' @return a \code{\link{graded}} object. An incorrect message will describe the +#' first way that the answer differs, the message will be the content of the +#' \code{glue_pipe} argument. #' +#' @seealso \code{\link{check_code}}, \code{\link{check_result}}, and +#' \code{\link{test_result}} #' @export #' @examples #' \dontrun{grading_demo()} +#' +#' # This is a manual example, see grading demo for learnr tutorial usage +#' y <- quote(sqrt(log(2))) +#' z <- quote(sqrt(log(1))) +#' check_code(grader_args = list(user_quo = y, solution_quo = z)) check_code <- function( correct = NULL, incorrect = NULL, diff --git a/R/check_result.R b/R/check_result.R index 5cc17260..7fd2f533 100644 --- a/R/check_result.R +++ b/R/check_result.R @@ -1,11 +1,12 @@ #' Check result of exercise code #' -#' \code{check_result()} compares the final result of the user code to known \code{results}. -#' If the user result exactly matches a known \code{result}, \code{check_result} +#' \code{check_result()} compares the final result of the student code to known +#' \code{\link{pass_if}} and \code{\link{fail_if}} \code{\link{condition}}s. +#' If the student result exactly matches a known case, \code{check_result} #' returns the matching message value. #' -#' @param ... \code{\link{pass_if}} or \code{\link{fail_if}} conditions to check +#' @param ... \code{\link{pass_if}} or \code{\link{fail_if}} \code{\link{condition}}s to check #' @template correct #' @template incorrect #' @template grader_args @@ -13,13 +14,16 @@ #' @template glue_correct #' @template glue_incorrect #' -#' @return a \code{grader_graded} structure from either +#' @return a \code{\link{graded}} object from either #' \code{\link{pass_if}} or \code{\link{fail_if}} containing a formatted #' \code{correct} or \code{incorrect} message and whether or not a match was found. #' +#' @seealso \code{\link{check_code}}, \code{\link{check_result}}, and \code{\link{test_result}} #' @export #' @examples #' \dontrun{grading_demo()} +#' +#' @template check_result_examples check_result <- function( ..., correct = NULL, diff --git a/R/condition.R b/R/condition.R index a9b17572..28833296 100644 --- a/R/condition.R +++ b/R/condition.R @@ -1,10 +1,13 @@ #' Condition object -#' Captures what the user passes into \code{\link{pass_if}} or \code{\link{fail_if}}, +#' +#' Captures what the student passes into \code{\link{pass_if}} or \code{\link{fail_if}}, #' figures out what type of object was passed into \code{x}, -#' and returns a \code{grader_condition} object that will be passed into \code{evaluate_condi} +#' and returns a \code{grader_condition} object that will be passed into +#' \code{\link{evaluate_condition}}. #' -#' @param x expression to be evaluated -#' @param message character string for message returned +#' @template x_condition +#' @param message character string for message returned (usually passed in from +#' \code{\link{pass_if}} or \code{\link{fail_if}} #' @param correct logical whether the condition is the correct answer #' #' @return a \code{grader_condition} object that contains @@ -12,7 +15,17 @@ #' the message \code{message}, #' whether or not the expression is the correct answer or not, \code{correct}, #' the type of expression (formula, function, or value), \code{type} +#' +#' @describeIn condition +#' A condition object that contains the expression, message, +#' correct status, and condition type +#' @seealso \code{\link{pass_if}}, \code{\link{fail_if}}, and \code{\link{condition}} #' @export +#' +#' @examples +#' \dontrun{grading_demo()} +#' +#' condition(~ identical(x = .result, 5), message = "Correct", correct = TRUE) condition <- function(x, message, correct) { type <- if (rlang::is_formula(x)) { diff --git a/R/detect_mistakes.R b/R/detect_mistakes.R index 79e22d2d..62340f71 100644 --- a/R/detect_mistakes.R +++ b/R/detect_mistakes.R @@ -149,7 +149,6 @@ isolate_mismatch <- function(user, solution, i) { NULL } - real_name <- function(name) { !is.null(name) && name != "" } diff --git a/R/evaluate_condition.R b/R/evaluate_condition.R index 92feb9c1..f5a058e8 100644 --- a/R/evaluate_condition.R +++ b/R/evaluate_condition.R @@ -1,19 +1,29 @@ #' Evaluates a condition #' -#' @param condi a \code{grader} \code{\link{condition}} object +#' Evaluates the \code{\link{condition}} object to return a \code{\link{graded}} value. +#' +#' @param condition a \code{\link{condition}} object #' @param grader_args at minimum, a list that just contains the value for \code{solution_quo} #' @param learnr_args at minimum, a list that just contains the value for \code{envir_prep} #' -#' @return a \code{graded} value if \code{condi$x} is \code{TRUE} or +#' @return a \code{\link{graded}} value if \code{condi$x} is \code{TRUE} or #' \code{NULL} if \code{condi$x} is \code{FALSE} #' @export -evaluate_condition <- function(condi, grader_args, learnr_args) { - checkmate::assert_class(condi, "grader_condition") +#' +#' @examples +#' condi_formula_t <- condition(~ identical(.result, 5), +#' message = "my correct message", +#' correct = TRUE) +#' grader_args <- list() +#' learnr_args <- list(last_value = quote(5), envir_prep = new.env()) +#' evaluate_condition(condi_formula_t, grader_args, learnr_args) +evaluate_condition <- function(condition, grader_args, learnr_args) { + checkmate::assert_class(condition, "grader_condition") - res <- switch(condi$type, - "formula" = evaluate_condi_formula(condi$x, learnr_args$last_value, learnr_args$envir_prep), # nolint - "function" = evaluate_condi_function(condi$x, learnr_args$last_value), - "value" = evaluate_condi_value(condi$x, learnr_args$last_value) + res <- switch(condition$type, + "formula" = evaluate_condi_formula(condition$x, learnr_args$last_value, learnr_args$envir_prep), # nolint + "function" = evaluate_condi_function(condition$x, learnr_args$last_value), + "value" = evaluate_condi_value(condition$x, learnr_args$last_value) ) # if we compare something like a vector or dataframes to one another @@ -32,7 +42,7 @@ evaluate_condition <- function(condi, grader_args, learnr_args) { checkmate::assert_logical(res, len = 1, null.ok = FALSE) if (res) { - return(graded(correct = condi$correct, message = condi$message)) + return(graded(correct = condition$correct, message = condition$message)) } else { return(NULL) } diff --git a/R/get_code.R b/R/get_code.R index 749848bc..cd31609f 100644 --- a/R/get_code.R +++ b/R/get_code.R @@ -4,21 +4,27 @@ #' to extract user code and solution code. #' #' @seealso \code{\link{check_result}}, \code{\link{test_result}}, and \code{\link{check_code}} -#' @export -#' @rdname get_code #' @param user,solution,expr An expression or quosure to evaluate. #' @param name Name to print if a \code{NULL} expression is provided. +#' +#' @describeIn get_code Get student code #' @inheritParams rlang::eval_tidy +#' +#' @noRd get_user_code <- function(user = NULL, env = rlang::caller_env()) { get_code(user, "user", env = env) } -#' @export -#' @rdname get_code + +#' @describeIn get_code Get solution code provided by instructor +#"" +#' @noRd get_solution_code <- function(solution = NULL, env = rlang::caller_env()) { get_code(solution, "solution", env = env) } -#' @export -#' @rdname get_code + +#' @describeIn get_code Generic get code function +#' +#' @noRd get_code <- function(expr = NULL, name = "", env = rlang::caller_env()) { if (is.null(expr)) { stop("'", name, "' not provided") diff --git a/R/glue.R b/R/glue.R index 003d5e87..701d3f90 100644 --- a/R/glue.R +++ b/R/glue.R @@ -1,6 +1,6 @@ #' Generate Glue string from expression #' -#' Checks and validates arguments passed into \code{glue}. +#' Checks and validates arguments passed into \code{glue} to generate messages to the student. #' #' @param glue_expression A glue character expression string. #' @param ... Values to be inserted into glue expression. diff --git a/R/grade_learnr.R b/R/grade_learnr.R index 0931e1bd..092a3dc1 100644 --- a/R/grade_learnr.R +++ b/R/grade_learnr.R @@ -1,34 +1,36 @@ -#' grade_learnr +#' A checker function to use with \code{learnr} #' -#' A checker function to use with learnr -#' -#' For exercise checking, learnr tutorials require a function that learnr can -#' use in the background to run the code in each "-check" chunk and to format -#' the results into a format that learnr can display. The function must accept a -#' specific set of inputs and return a specific type of output (see \code{\link{graded}}). -#' Users are not intended to use the function themselves, but to pass it to the +#' For exercise checking, \code{learnr} tutorials require a function that +#' \code{learnr} can use in the background to run the code in each "-check" +#' chunk and to format the results into a format that \code{learnr} can display. +#' The function must accept a specific set of inputs and return a specific type +#' of output (see \code{\link{graded}}). Instructors are not intended to use the +#' \code{grade_learnr} function directly, but to pass it to the #' \code{exercise.checker} knitr chunk option within the setup chunk of the -#' tutorial. +#' \code{learnr} tutorial. #' -#' The grader package provides \code{grade_learnr} for this purpose. To enable -#' exercise checking in your learnr tutorial, set +#' To enable exercise checking in your learnr tutorial, set #' \code{tutorial_options(exercise.checker = grade_learnr)} in the setup chunk #' of your tutorial. #' -#' Run \code{grading_demo()} to see an example learnr document -#' that uses \code{grade_learnr()}. +#' Run \code{grading_demo()} to see an example learnr document that uses +#' \code{grade_learnr()}. #' #' @param label Label for exercise chunk -#' @param solution_code Code provided within the “-solution” chunk for the exercise. +#' @param solution_code Code provided within the “-solution” chunk for the +#' exercise. #' @param user_code R code submitted by the user #' @param check_code Code provided within the “-check” chunk for the exercise. #' @param envir_result The R environment after the execution of the chunk. -#' @param evaluate_result The return value from the \code{evaluate::evaluate} function. -#' @param envir_prep A copy of the R environment before the execution of the chunk. +#' @param evaluate_result The return value from the \code{evaluate::evaluate} +#' function. +#' @param envir_prep A copy of the R environment before the execution of the +#' chunk. #' @param last_value The last value from evaluating the exercise. #' @param ... Extra arguments supplied by learnr #' -#' @return An R list which contains several fields indicating the result of the check. +#' @return An R list which contains several fields indicating the result of the +#' check. #' @export #' #' @examples diff --git a/R/grading_demo.R b/R/grading_demo.R index 7abb1baa..1f770a91 100644 --- a/R/grading_demo.R +++ b/R/grading_demo.R @@ -3,7 +3,7 @@ #' If you are using the RStudio IDE, \code{grading_demo()} opens an example learnr #' file that demonstrates how to use the grader package to check student code. #' -#' The tutorial sets the learnr exercise. checker option to +#' The tutorial sets the learnr \code{exercise.checker} option to #' \code{grade_learnr()} in the document's setup chunk. #' It then uses three different exercise checking methods: #' \code{\link{check_result}}, \code{\link{test_result}}, and \code{\link{check_code}}. diff --git a/R/pass_fail_if.R b/R/pass_fail_if.R index 8a0943dd..17c92e7c 100644 --- a/R/pass_fail_if.R +++ b/R/pass_fail_if.R @@ -1,14 +1,22 @@ -#' Pass if condition matches -#' @template pass_fail_x_condition -#' @param message chracter string for message returned +#' Condition definition +#' +#' \code{pass_if} and \code{fail_if} are wrappers around \code{\link{condition}} +#' that sets the proper \code{correct} argument. +#' This allows the instructor to specify just the comparison code, \code{x}, +#' and \code{message}. +#' +#' @describeIn condition +#' a condition that if matched means the student provided result is correct +#' #' @export +#' @template check_result_examples pass_if <- function(x, message = NULL) { condition(x, message, correct = TRUE) } -#' Fail if condition matches -#' @template pass_fail_x_condition -#' @param message chracter string for message returned +#' @describeIn condition +#' a condition that if matched means the student provided result is incorrect +#' #' @export fail_if <- function(x, message = NULL) { condition(x, message, correct = FALSE) diff --git a/R/praise.R b/R/praise.R index 367cb2ae..9a21dbfb 100644 --- a/R/praise.R +++ b/R/praise.R @@ -64,12 +64,13 @@ #' replicate(5, glue::glue("Random praise: {random_praise()}")) #' replicate(5, glue::glue("Random encouragement: {random_encourage()}")) #' @export -#' @rdname praise +#' @describeIn praise Returns a random praise message random_praise <- function() { sample(.praise, 1) } + #' @export -#' @rdname praise +#' @describeIn praise Returns a random encouragement message random_encourage <- function() { sample(.encourage, 1) } diff --git a/archive/view_tutorial.R b/archive/view_tutorial.R index 59b9cbba..ed189d07 100644 --- a/archive/view_tutorial.R +++ b/archive/view_tutorial.R @@ -15,8 +15,6 @@ #' @keywords internal #' @importFrom utils browseURL view_tutorial <- function(name, package) { - - # launch in separate R session r2 <- callr::r_bg(function(name, package) { learnr_run_tutorial <- eval(call(":::", "learnr", "run_tutorial")) # removes learnr depedency @@ -32,7 +30,7 @@ view_tutorial <- function(name, package) { supervise = TRUE, args = list(name = name, package = package) ) - + # If you open the viewer before the app loads, it will # display a blank screen until you click refresh status <- r2$read_error() @@ -46,7 +44,7 @@ view_tutorial <- function(name, package) { break } } - + if (rstudioapi::isAvailable()) { rstudioapi::viewer( url = "http://localhost:8000", @@ -91,9 +89,9 @@ view_tutorial <- function(name, package) { #' @keywords internal add_tutorial <- function(name, package) { rprofile <- paste0(getwd(), "/.Rprofile") # nolint - + # load packages - + # Check that the .Rprofile does not already load a tutorial if (file.exists(rprofile)) { text <- readr::read_file(rprofile) @@ -117,21 +115,21 @@ add_tutorial <- function(name, package) { sep = "\n", append = TRUE ) - + # return message } remove_tutorial <- function(dir = NULL) { if (!is.null(dir)) dir <- getwd() rprofile <- paste0(dir, "/.Rprofile") # nolint - + if (file.exists(rprofile)) { text <- readr::read_lines(rprofile) } else { stop("Directory does not have a .Rprofile ", "file to remove tutorial from.") } - + tutorial_calls <- grepl("\\) ## Learnr tutorial added on ", text) if (!any(tutorial_calls)) { message("No tutorials detected to remove.") diff --git a/man-roxygen/check_result_examples.R b/man-roxygen/check_result_examples.R new file mode 100644 index 00000000..c7f58236 --- /dev/null +++ b/man-roxygen/check_result_examples.R @@ -0,0 +1,22 @@ +#' @examples +#' check_result( +#' pass_if(~ identical(.result, 5), "This is a correct message"), +#' grader_args = list(), +#' learnr_args = list(last_value = 5, envir_prep = new.env()) +#' ) +#' +#' check_result( +#' pass_if(function(x) identical(x, 5), "This is a correct message"), +#' learnr_args = list(last_value = 5) +#' ) +#' +#' check_result( +#' pass_if(5, "This is a correct message"), +#' learnr_args = list(last_value = 5) +#' ) +#' +#' check_result( +#' fail_if(5, "You were supposed to do this other thing!"), +#' pass_if(~ TRUE, "should never reach here"), +#' learnr_args = list(last_value = 5) +#' ) diff --git a/man-roxygen/pass_fail_x_condition.R b/man-roxygen/x_condition.R similarity index 76% rename from man-roxygen/pass_fail_x_condition.R rename to man-roxygen/x_condition.R index d7ae9cbc..52a7ce9c 100644 --- a/man-roxygen/pass_fail_x_condition.R +++ b/man-roxygen/x_condition.R @@ -1,5 +1,5 @@ #' @param x A formula, function, or value, that returns \code{TRUE} or \code{FALSE}. #' When comparing objects that are greater than length 1 (e.g., vectors, dataframes, matricies, etc) #' A boolean vector will be returned if the user uses \code{==}, not a single boolean value. -#' \code{grader} will run the vector through \code{all(..., na.rm = TRUE)} to check for the boolean value. +#' \code{gradethis} will run the vector through \code{all(..., na.rm = TRUE)} to check for the boolean value. #' It is advised that the user use \code{identical()} instead of \code{==} in this case. diff --git a/man/check_code.Rd b/man/check_code.Rd index c112b49f..82e767ac 100644 --- a/man/check_code.Rd +++ b/man/check_code.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/check_code.R \name{check_code} \alias{check_code} -\title{Check code structure} +\title{Check code against a solution} \usage{ check_code(correct = NULL, incorrect = NULL, grader_args = list(), learnr_args = list(), @@ -30,23 +30,28 @@ Defaults to \code{getOption("gradethis_glue_correct")}.} \item{glue_incorrect}{A glue string that returns the final incorrect message displayed. Defaults to \code{getOption("gradethis_glue_incorrect")}.} -\item{glue_pipe}{A glue string that returns the final message displayed when a user uses a pipe, -\code{$>$}. Defaults to \code{getOption("gradethis_glue_pipe")}.} +\item{glue_pipe}{A glue string that returns the final message displayed when +the student uses a pipe, \code{$>$}. Defaults to +\code{getOption("gradethis_glue_pipe")}.} } \value{ -a \code{\link{graded}} object. - An incorrect message will describe the first way that the answer differs, - the message will be the content of the \code{glue_pipe} argument. +a \code{\link{graded}} object. An incorrect message will describe the + first way that the answer differs, the message will be the content of the + \code{glue_pipe} argument. } \description{ -\code{check_code()} compares user code to a solution (i.e. model code) and -describes the first way that the user code differs. If the user code exactly -matches the solution, \code{check_code()} returns a customizable success -message. +Checks the code expression or the code result against a solution. } \details{ -\code{check_code()} provides a *strict* check in that the user code must -exactly match the solution. It is not enough for the user code to be +\code{check_code()} compares student code to a solution (i.e. model code) and +describes the first way that the student code differs. If the student code +exactly matches the solution, \code{check_code()} returns a customizable +success message (\code{correct}). If the student code does not match the +solution, a customizable incorrect message (\code{incorrect}) can also be +provided. + +\code{check_code()} provides a *strict* check in that the student code must +exactly match the solution. It is not enough for the student code to be equivalent to the solution code (e.g. to return the same result as the solution). @@ -58,12 +63,22 @@ argument of \code{check_code()} 2. Make a "-solution" code chunk for the exercise to be checked in a learnr document. There is no need to supply a solution argument for \code{check_code()} if you call it from the "-check" chunk of the same -exercise. Likewise, there is no need to supply a user argument when you call -\code{check_code()} from a learnr document (learnr will provide the code -that the student submits when it runs \code{check_code()}. +exercise. Likewise, there is no need to supply a student submitted code +argument when you call \code{check_code()} from a learnr document (learnr +will provide the code that the student submits when it runs +\code{check_code()}. For best results, name all arguments provided in the solution code. } \examples{ \dontrun{grading_demo()} + +# This is a manual example, see grading demo for learnr tutorial usage +y <- quote(sqrt(log(2))) +z <- quote(sqrt(log(1))) +check_code(grader_args = list(user_quo = y, solution_quo = z)) +} +\seealso{ +\code{\link{check_code}}, \code{\link{check_result}}, and + \code{\link{test_result}} } diff --git a/man/check_result.Rd b/man/check_result.Rd index 3274cff8..c93a4087 100644 --- a/man/check_result.Rd +++ b/man/check_result.Rd @@ -10,7 +10,7 @@ check_result(..., correct = NULL, incorrect = NULL, glue_incorrect = getOption("gradethis_glue_incorrect")) } \arguments{ -\item{...}{\code{\link{pass_if}} or \code{\link{fail_if}} conditions to check} +\item{...}{\code{\link{pass_if}} or \code{\link{fail_if}} \code{\link{condition}}s to check} \item{correct}{A character string to display if the student answer matches a known correct answer.} @@ -32,15 +32,41 @@ Defaults to \code{getOption("gradethis_glue_correct")}.} Defaults to \code{getOption("gradethis_glue_incorrect")}.} } \value{ -a \code{grader_graded} structure from either +a \code{\link{graded}} object from either \code{\link{pass_if}} or \code{\link{fail_if}} containing a formatted \code{correct} or \code{incorrect} message and whether or not a match was found. } \description{ -\code{check_result()} compares the final result of the user code to known \code{results}. -If the user result exactly matches a known \code{result}, \code{check_result} +\code{check_result()} compares the final result of the student code to known +\code{\link{pass_if}} and \code{\link{fail_if}} \code{\link{condition}}s. +If the student result exactly matches a known case, \code{check_result} returns the matching message value. } \examples{ \dontrun{grading_demo()} + +check_result( + pass_if(~ identical(.result, 5), "This is a correct message"), + grader_args = list(), + learnr_args = list(last_value = 5, envir_prep = new.env()) +) + +check_result( + pass_if(function(x) identical(x, 5), "This is a correct message"), + learnr_args = list(last_value = 5) +) + +check_result( + pass_if(5, "This is a correct message"), + learnr_args = list(last_value = 5) +) + +check_result( + fail_if(5, "You were supposed to do this other thing!"), + pass_if(~ TRUE, "should never reach here"), + learnr_args = list(last_value = 5) +) +} +\seealso{ +\code{\link{check_code}}, \code{\link{check_result}}, and \code{\link{test_result}} } diff --git a/man/condition.Rd b/man/condition.Rd index 68182f91..c74bbbd1 100644 --- a/man/condition.Rd +++ b/man/condition.Rd @@ -1,18 +1,26 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/condition.R +% Please edit documentation in R/condition.R, R/pass_fail_if.R \name{condition} \alias{condition} -\title{Condition object -Captures what the user passes into \code{\link{pass_if}} or \code{\link{fail_if}}, -figures out what type of object was passed into \code{x}, -and returns a \code{grader_condition} object that will be passed into \code{evaluate_condi}} +\alias{pass_if} +\alias{fail_if} +\title{Condition object} \usage{ condition(x, message, correct) + +pass_if(x, message = NULL) + +fail_if(x, message = NULL) } \arguments{ -\item{x}{expression to be evaluated} +\item{x}{A formula, function, or value, that returns \code{TRUE} or \code{FALSE}. +When comparing objects that are greater than length 1 (e.g., vectors, dataframes, matricies, etc) +A boolean vector will be returned if the user uses \code{==}, not a single boolean value. +\code{gradethis} will run the vector through \code{all(..., na.rm = TRUE)} to check for the boolean value. +It is advised that the user use \code{identical()} instead of \code{==} in this case.} -\item{message}{character string for message returned} +\item{message}{character string for message returned (usually passed in from +\code{\link{pass_if}} or \code{\link{fail_if}}} \item{correct}{logical whether the condition is the correct answer} } @@ -24,8 +32,52 @@ a \code{grader_condition} object that contains the type of expression (formula, function, or value), \code{type} } \description{ -Condition object -Captures what the user passes into \code{\link{pass_if}} or \code{\link{fail_if}}, +Captures what the student passes into \code{\link{pass_if}} or \code{\link{fail_if}}, figures out what type of object was passed into \code{x}, -and returns a \code{grader_condition} object that will be passed into \code{evaluate_condi} +and returns a \code{grader_condition} object that will be passed into +\code{\link{evaluate_condition}}. + +\code{pass_if} and \code{fail_if} are wrappers around \code{\link{condition}} +that sets the proper \code{correct} argument. +This allows the instructor to specify just the comparison code, \code{x}, +and \code{message}. +} +\section{Functions}{ +\itemize{ +\item \code{condition}: A condition object that contains the expression, message, +correct status, and condition type + +\item \code{pass_if}: a condition that if matched means the student provided result is correct + +\item \code{fail_if}: a condition that if matched means the student provided result is incorrect +}} + +\examples{ +\dontrun{grading_demo()} + +condition(~ identical(x = .result, 5), message = "Correct", correct = TRUE) +check_result( + pass_if(~ identical(.result, 5), "This is a correct message"), + grader_args = list(), + learnr_args = list(last_value = 5, envir_prep = new.env()) +) + +check_result( + pass_if(function(x) identical(x, 5), "This is a correct message"), + learnr_args = list(last_value = 5) +) + +check_result( + pass_if(5, "This is a correct message"), + learnr_args = list(last_value = 5) +) + +check_result( + fail_if(5, "You were supposed to do this other thing!"), + pass_if(~ TRUE, "should never reach here"), + learnr_args = list(last_value = 5) +) +} +\seealso{ +\code{\link{pass_if}}, \code{\link{fail_if}}, and \code{\link{condition}} } diff --git a/man/evaluate_condition.Rd b/man/evaluate_condition.Rd index 28b84ef9..6deb0180 100644 --- a/man/evaluate_condition.Rd +++ b/man/evaluate_condition.Rd @@ -4,19 +4,27 @@ \alias{evaluate_condition} \title{Evaluates a condition} \usage{ -evaluate_condition(condi, grader_args, learnr_args) +evaluate_condition(condition, grader_args, learnr_args) } \arguments{ -\item{condi}{a \code{grader} \code{\link{condition}} object} +\item{condition}{a \code{\link{condition}} object} \item{grader_args}{at minimum, a list that just contains the value for \code{solution_quo}} \item{learnr_args}{at minimum, a list that just contains the value for \code{envir_prep}} } \value{ -a \code{graded} value if \code{condi$x} is \code{TRUE} or +a \code{\link{graded}} value if \code{condi$x} is \code{TRUE} or \code{NULL} if \code{condi$x} is \code{FALSE} } \description{ -Evaluates a condition +Evaluates the \code{\link{condition}} object to return a \code{\link{graded}} value. +} +\examples{ + condi_formula_t <- condition(~ identical(.result, 5), + message = "my correct message", + correct = TRUE) + grader_args <- list() + learnr_args <- list(last_value = quote(5), envir_prep = new.env()) + evaluate_condition(condi_formula_t, grader_args, learnr_args) } diff --git a/man/fail_if.Rd b/man/fail_if.Rd deleted file mode 100644 index 198ce841..00000000 --- a/man/fail_if.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pass_fail_if.R -\name{fail_if} -\alias{fail_if} -\title{Fail if condition matches} -\usage{ -fail_if(x, message = NULL) -} -\arguments{ -\item{x}{A formula, function, or value, that returns \code{TRUE} or \code{FALSE}. -When comparing objects that are greater than length 1 (e.g., vectors, dataframes, matricies, etc) -A boolean vector will be returned if the user uses \code{==}, not a single boolean value. -\code{grader} will run the vector through \code{all(..., na.rm = TRUE)} to check for the boolean value. -It is advised that the user use \code{identical()} instead of \code{==} in this case.} - -\item{message}{chracter string for message returned} -} -\description{ -Fail if condition matches -} diff --git a/man/get_code.Rd b/man/get_code.Rd deleted file mode 100644 index f2d847bf..00000000 --- a/man/get_code.Rd +++ /dev/null @@ -1,31 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/get_code.R -\name{get_user_code} -\alias{get_user_code} -\alias{get_solution_code} -\alias{get_code} -\title{Get Code} -\usage{ -get_user_code(user = NULL, env = rlang::caller_env()) - -get_solution_code(solution = NULL, env = rlang::caller_env()) - -get_code(expr = NULL, name = "", - env = rlang::caller_env()) -} -\arguments{ -\item{user, solution, expr}{An expression or quosure to evaluate.} - -\item{env}{The environment in which to evaluate \code{expr}. This -environment is not applicable for quosures because they have -their own environments.} - -\item{name}{Name to print if a \code{NULL} expression is provided.} -} -\description{ -Helper methods around \code{rlang::\link[rlang]{eval_tidy}} -to extract user code and solution code. -} -\seealso{ -\code{\link{check_result}}, \code{\link{test_result}}, and \code{\link{check_code}} -} diff --git a/man/grade_learnr.Rd b/man/grade_learnr.Rd index 5e3c80c1..3db6e7a3 100644 --- a/man/grade_learnr.Rd +++ b/man/grade_learnr.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/grade_learnr.R \name{grade_learnr} \alias{grade_learnr} -\title{grade_learnr} +\title{A checker function to use with \code{learnr}} \usage{ grade_learnr(label = NULL, solution_code = NULL, user_code = NULL, check_code = NULL, envir_result = NULL, evaluate_result = NULL, @@ -11,7 +11,8 @@ grade_learnr(label = NULL, solution_code = NULL, user_code = NULL, \arguments{ \item{label}{Label for exercise chunk} -\item{solution_code}{Code provided within the “-solution” chunk for the exercise.} +\item{solution_code}{Code provided within the “-solution” chunk for the +exercise.} \item{user_code}{R code submitted by the user} @@ -19,36 +20,37 @@ grade_learnr(label = NULL, solution_code = NULL, user_code = NULL, \item{envir_result}{The R environment after the execution of the chunk.} -\item{evaluate_result}{The return value from the \code{evaluate::evaluate} function.} +\item{evaluate_result}{The return value from the \code{evaluate::evaluate} +function.} -\item{envir_prep}{A copy of the R environment before the execution of the chunk.} +\item{envir_prep}{A copy of the R environment before the execution of the +chunk.} \item{last_value}{The last value from evaluating the exercise.} \item{...}{Extra arguments supplied by learnr} } \value{ -An R list which contains several fields indicating the result of the check. +An R list which contains several fields indicating the result of the + check. } \description{ -A checker function to use with learnr +For exercise checking, \code{learnr} tutorials require a function that +\code{learnr} can use in the background to run the code in each "-check" +chunk and to format the results into a format that \code{learnr} can display. +The function must accept a specific set of inputs and return a specific type +of output (see \code{\link{graded}}). Instructors are not intended to use the +\code{grade_learnr} function directly, but to pass it to the +\code{exercise.checker} knitr chunk option within the setup chunk of the +\code{learnr} tutorial. } \details{ -For exercise checking, learnr tutorials require a function that learnr can -use in the background to run the code in each "-check" chunk and to format -the results into a format that learnr can display. The function must accept a -specific set of inputs and return a specific type of output (see \code{\link{graded}}). -Users are not intended to use the function themselves, but to pass it to the -\code{exercise.checker} knitr chunk option within the setup chunk of the -tutorial. - -The grader package provides \code{grade_learnr} for this purpose. To enable -exercise checking in your learnr tutorial, set +To enable exercise checking in your learnr tutorial, set \code{tutorial_options(exercise.checker = grade_learnr)} in the setup chunk of your tutorial. -Run \code{grading_demo()} to see an example learnr document -that uses \code{grade_learnr()}. +Run \code{grading_demo()} to see an example learnr document that uses +\code{grade_learnr()}. } \examples{ \dontrun{grading_demo()} diff --git a/man/grading_demo.Rd b/man/grading_demo.Rd index 2240ddf2..a7bcd1c0 100644 --- a/man/grading_demo.Rd +++ b/man/grading_demo.Rd @@ -11,7 +11,7 @@ If you are using the RStudio IDE, \code{grading_demo()} opens an example learnr file that demonstrates how to use the grader package to check student code. } \details{ -The tutorial sets the learnr exercise. checker option to +The tutorial sets the learnr \code{exercise.checker} option to \code{grade_learnr()} in the document's setup chunk. It then uses three different exercise checking methods: \code{\link{check_result}}, \code{\link{test_result}}, and \code{\link{check_code}}. diff --git a/man/pass_if.Rd b/man/pass_if.Rd deleted file mode 100644 index cf520a73..00000000 --- a/man/pass_if.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pass_fail_if.R -\name{pass_if} -\alias{pass_if} -\title{Pass if condition matches} -\usage{ -pass_if(x, message = NULL) -} -\arguments{ -\item{x}{A formula, function, or value, that returns \code{TRUE} or \code{FALSE}. -When comparing objects that are greater than length 1 (e.g., vectors, dataframes, matricies, etc) -A boolean vector will be returned if the user uses \code{==}, not a single boolean value. -\code{grader} will run the vector through \code{all(..., na.rm = TRUE)} to check for the boolean value. -It is advised that the user use \code{identical()} instead of \code{==} in this case.} - -\item{message}{chracter string for message returned} -} -\description{ -Pass if condition matches -} diff --git a/man/praise.Rd b/man/praise.Rd index b1e8309f..6f6a2fe1 100644 --- a/man/praise.Rd +++ b/man/praise.Rd @@ -14,6 +14,13 @@ Generate a random praise or encouragement phrase. This can be used in conjunction with \code{glue::\link[glue]{glue}} to generate praise or encouragement within feedback to users. } +\section{Functions}{ +\itemize{ +\item \code{random_praise}: Returns a random praise message + +\item \code{random_encourage}: Returns a random encouragement message +}} + \examples{ replicate(5, glue::glue("Random praise: {random_praise()}")) replicate(5, glue::glue("Random encouragement: {random_encourage()}"))