Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support answer-functions #657

Merged
merged 32 commits into from
Feb 15, 2022
Merged

Support answer-functions #657

merged 32 commits into from
Feb 15, 2022

Conversation

gadenbuie
Copy link
Member

Adds answer_fn(), as a complimentary function to answer(). Where answer() provides an option and a single value against which the student's response is compared, answer_fn() provides a function that is evaluated on the submission and is not visible to the user. If the function returns a marked answer via mark_as() or correct() or incorrect(), that mark determines the overall question correctness.

The most obvious use cases are for text and numeric answers where answer_fn() could be used to evaluate the submission to use regular expressions or check that it falls within a range. Both of those actions are difficult to do currently. Since text and numeric questions don't present answer options to the user, the question answers are evaluated in the order they were written. (Note we now disable random_answer_order in text questions.)

For checkbox questions, the submission is checked against function-type answers before checking against regular answers. Additionally, function-type answers are not shown to the user. This enables scenarios like "pick 2 of 3 correct answers" or "any answer is correct". If random_answer_order = TRUE and the question uses answer_fn() answers, the function-type answers will be checked first, but their internal order will be randomized.

Function-type answers are not allowed in radio questions since the user is forced to select only one answer option. Trying to use answer_fn() inside question_radio() will throw an error at render.

Here's a really basic toy example showing how answer_fn() could be used to apply regular expressions in a text question.

good_value <- function(value) {
  if (!grepl("na", value, ignore.case = TRUE)) {
    correct("Nice!")
  } else {
    incorrect("nanananana hey hey good bye")
  }
}

question_text(
  "Write something that doesn't say 'na'.",
  answer("na", correct = FALSE, message = "I said *don't* write `na`."),
  answer("banana", FALSE, "You must be a joker."),
  answer_fn(good_value),
  allow_retry = TRUE,
  random_answer_order = FALSE
)

@gadenbuie
Copy link
Member Author

gadenbuie commented Feb 8, 2022

  • Use rlang::as_function()
  • Suppress answer function shuffle in checkbox questions

@gadenbuie gadenbuie marked this pull request as ready for review February 9, 2022 22:29
Copy link
Contributor

@rossellhayes rossellhayes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks good to me! My only suggestion would be to add more documentation with examples of answer_fns in actions. I think it's particularly hard to understand how answer_fn works in checkbox questions right now.

@gadenbuie gadenbuie merged commit 756e95b into main Feb 15, 2022
@gadenbuie gadenbuie deleted the answer-functions branch February 15, 2022 21:53
@tvedebrink
Copy link

👏

@hgreatrex
Copy link

hgreatrex commented Jan 6, 2023

Hello!
This is EXACTLY what I need - thank you :)
Is there any way to pass a second variable into the answer function? For example

`DataIn <- data.frame(x = c(65,34,48,72,58,63,26,80), y = c(74,49,45,80,63,72,12,75))

question_numeric(
"How many cases are there in this study?",
answer_fn(function(value,DataIn) {
if (round(value) == nrow(DataIn)) {
correct(paste(c("Yes! n =",nrow(DataIn),",AKA there are",nrow(DataIn),"Objects/Cases")))
} else if (round(value) == ncol(DataIn)) {
incorrect("That's the number of variables...")
}
`

if not, could I request that as a feature? Or I guess I could find a way to get the variable recognised in the global environment?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants