Title: | Create Interactive Quizzes in 'shiny' |
---|---|
Description: | Simple and flexible quizzes in 'shiny'. Easily create quizzes from various pre-built question and choice types or create your own using 'htmltools' and 'shiny' packages as building blocks. Integrates with larger 'shiny' applications. Ideal for non-web-developers such as educators, data scientists, and anyone who wants to assess responses interactively in a small form factor. |
Authors: | Joseph Marlo [aut, cre], George Perrett [aut] |
Maintainer: | Joseph Marlo <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.0.1.9000 |
Built: | 2025-02-09 05:00:25 UTC |
Source: | https://github.com/priism-center/shinyquiz |
Add a choice to a quiz question. Used in conjunction with create_question()
to generate a question.
add_choice(text, correct = FALSE) add_numeric(correct) add_slider(min = 0, max = 1, default_position = 0.5, correct) add_text(correct, exact = FALSE)
add_choice(text, correct = FALSE) add_numeric(correct) add_slider(min = 0, max = 1, default_position = 0.5, correct) add_text(correct, exact = FALSE)
text |
Text of the choice answer |
correct |
Boolean denoting if this |
min |
the minimum value of the slider range |
max |
the maximum value of the slider range |
default_position |
the default value the slider should take |
exact |
Boolean denoting if the grader should use exact matching. If FALSE, the user's answer will be compared to the correct answer after trimming whitespace, converting to lower case, and normalizing diacritics. If you wish to use your own normalizing function, please see |
an object of class 'quizChoice'
an object of class 'quizChoiceNumeric'
an object of class 'quizChoiceSlider'
an object of class 'quizChoiceText'
add_choice()
: Create a discrete choice
add_numeric()
: Create a numeric choice
add_slider()
: Create a slider choice
add_text()
: Create a free text choice
Joseph Marlo
George Perrett
add_choice('39') add_choice('39', TRUE) add_slider(0, 1, 0.5, 0.8) add_text('Correct answer') q <- create_question( 'My question prompt', add_choice('39'), add_choice('41', TRUE) ) q1_fuzzy <- create_question('My Label', add_text(correct = ' hEllo')) q1_fuzzy@grader('Héllo ') q1_exact <- create_question('My Label', add_text(correct = 'hEllo', exact = TRUE)) q1_exact@grader('Héllo ')
add_choice('39') add_choice('39', TRUE) add_slider(0, 1, 0.5, 0.8) add_text('Correct answer') q <- create_question( 'My question prompt', add_choice('39'), add_choice('41', TRUE) ) q1_fuzzy <- create_question('My Label', add_text(correct = ' hEllo')) q1_fuzzy@grader('Héllo ') q1_exact <- create_question('My Label', add_text(correct = 'hEllo', exact = TRUE)) q1_exact@grader('Héllo ')
Create a single quiz question. Used in conjunction with create_quiz()
to generate a quiz.
create_question( prompt, ..., type = c("auto", "single", "multiple"), input = c("auto", "select", "checkbox", "radio"), shuffle = FALSE, ns = shiny::NS("quiz") ) create_question_raw( prompt, grader, correct_answer_pretty, user_answer_prettifier = function(user_input) paste0(user_input, collapse = ", ") )
create_question( prompt, ..., type = c("auto", "single", "multiple"), input = c("auto", "select", "checkbox", "radio"), shuffle = FALSE, ns = shiny::NS("quiz") ) create_question_raw( prompt, grader, correct_answer_pretty, user_answer_prettifier = function(user_input) paste0(user_input, collapse = ", ") )
prompt |
Text of the question prompt. Can also be an HTML element such as |
... |
Objects of class 'quizChoice' generated from |
type |
One of c('auto', 'single', 'multiple'). Can the user select only one answer or multiple? |
input |
One of c('auto', 'select', 'checkbox'). Should the UI for a select input ( |
shuffle |
TRUE or FALSE. If TRUE order of choices will be randomly shuffled. |
ns |
Namespace function generated from |
grader |
A function that takes the user answer and determines if it is correct. Must take one argument and return TRUE or FALSE. Note that this is wrapped with |
correct_answer_pretty |
A string representing the correct answer that is printed 'pretty' |
user_answer_prettifier |
A function with one argument that takes the user's answers and prints it 'pretty' |
create_question
is the default method of creating quiz questions.
create_question_raw()
allows any HTML in the prompt
. This must contain a shiny input that is accessible via input$answers
. The namespace also needs care. The default inputId
is shiny::NS('quiz')('answers')
.
an object of class quizQuestion
an object of class quizQuestion
create_question()
: Create a quiz question
create_question_raw()
: Create a quiz question using custom inputs. This is a more flexible function that allows any html.
Joseph Marlo, George Perrett
Joseph Marlo
add_choice()
, add_slider()
, add_numeric()
, add_text()
, create_question_raw()
q <- create_question( prompt = 'My prompt explaining what the ATE of this thing should be', add_choice("34"), add_choice("59", TRUE), add_choice("98", TRUE) ) q2 <- create_question( prompt = 'My prompt explaining what the ATC of this thing should be', add_slider(0, 30, 15, correct = 10) ) quiz <- create_quiz(q, q2) q3 <- create_question_raw( prompt = htmltools::div( htmltools::p("my question"), shiny::selectInput( inputId = shiny::NS('quiz')('answers'), label = 'Select 5', choices = c(4, 5, 6) ) ), grader = \(user_input) user_input == '5', correct_answer_pretty = '5' ) quiz2 <- create_quiz(q3, q2)
q <- create_question( prompt = 'My prompt explaining what the ATE of this thing should be', add_choice("34"), add_choice("59", TRUE), add_choice("98", TRUE) ) q2 <- create_question( prompt = 'My prompt explaining what the ATC of this thing should be', add_slider(0, 30, 15, correct = 10) ) quiz <- create_quiz(q, q2) q3 <- create_question_raw( prompt = htmltools::div( htmltools::p("my question"), shiny::selectInput( inputId = shiny::NS('quiz')('answers'), label = 'Select 5', choices = c(4, 5, 6) ) ), grader = \(user_input) user_input == '5', correct_answer_pretty = '5' ) quiz2 <- create_quiz(q3, q2)
Create questions with inherit randomness. Allows one function to generate many different questions.
create_question_random(.f, n = 50, verify_randomness = TRUE)
create_question_random(.f, n = 50, verify_randomness = TRUE)
.f |
a function that outputs an object of class |
n |
a numeric value indicating how many draws of function .f to include in the random question bank. |
verify_randomness |
a boolean to denote if |
create_question_random()
takes any user generated function .f
. The function passed to the .f
argument creates a random prompt along with an updated answer, the function passed to the .f
argument must return an object of class quizQuestion
. create_question_random()
will automatically check to ensure the function passed to .f
is in the appropriate format. The n
argument controls how many random draws from the function passed to .f
are included in the question bank for the quiz. Higher values of n
allow more unique questions but extreme values of n
may also lead to slower performance. To create a quiz with n
randomly generated questions, create_question_random()
can be passed as an argument to create_quiz()
.
a list of length n that includes objects of class quizQuestionRandom
George Perrett, Joseph Marlo
# a function that generates a random question random_question <- function() { number <- round(rnorm(1, 30, 10), 0) rand_prompt <- paste('Is', number, 'an even number?') # using create_question inside the function helps to ensure correct class q <- create_question( prompt = rand_prompt, add_choice('Yes, it is even', correct = number %% 2 == 0), add_choice('No, it is odd', correct = number %% 2 != 0) ) return(q) } # create a quiz with a question bank of 20 randomly generated questions quiz <- create_quiz( create_question_random(.f = random_question, n = 20) )
# a function that generates a random question random_question <- function() { number <- round(rnorm(1, 30, 10), 0) rand_prompt <- paste('Is', number, 'an even number?') # using create_question inside the function helps to ensure correct class q <- create_question( prompt = rand_prompt, add_choice('Yes, it is even', correct = number %% 2 == 0), add_choice('No, it is odd', correct = number %% 2 != 0) ) return(q) } # create a quiz with a question bank of 20 randomly generated questions quiz <- create_quiz( create_question_random(.f = random_question, n = 20) )
Create a single quiz comprising of questions generated from create_question()
and/or create_question_raw()
.
create_quiz(..., options = set_quiz_options())
create_quiz(..., options = set_quiz_options())
... |
objects of class 'quizQuestions'. See |
options |
a list of options generated from |
an object of class quiz
Joseph Marlo
set_quiz_options()
, create_question()
, create_question_raw()
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) )
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) )
Launch a viewer to preview the structure of the questions in a quiz.
preview_app(quiz, launch_browser = TRUE)
preview_app(quiz, launch_browser = TRUE)
quiz |
an object of class 'quiz' to preview |
launch_browser |
launch in a web browser? |
Called for side effect
preview_app()
: Preview a quiz with full operability
Joseph Marlo
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) ) preview_app(quiz)
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) ) preview_app(quiz)
A 'shiny' module to implement a quiz. These are the core functions to implement the quiz with a 'shiny' application.
quiz_ui(quiz) quiz_server(quiz)
quiz_ui(quiz) quiz_server(quiz)
quiz |
an object of class |
a reactive object showing the current results of the quiz
quiz_ui()
: UI side function
quiz_server()
: Server side function
Joseph Marlo
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) ) ui <- shiny::fluidPage( htmltools::div( style = "max-width: 700px", quiz_ui(quiz) ) ) server <- function(input, output, session) { quiz_server(quiz) } shinyApp(ui, server)
quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ) ) ui <- shiny::fluidPage( htmltools::div( style = "max-width: 700px", quiz_ui(quiz) ) ) server <- function(input, output, session) { quiz_server(quiz) } shinyApp(ui, server)
These are options to be passed to a quiz
.
set_quiz_options( ns = shiny::NS("quiz"), messages, sandbox = FALSE, end_on_first_wrong = !sandbox, class = NULL, progress_bar = !sandbox, progress_bar_color = "#609963", question_heading = "Practice what you've learned", include_question_title = TRUE, ... ) create_messages(message_correct, message_wrong, message_skipped)
set_quiz_options( ns = shiny::NS("quiz"), messages, sandbox = FALSE, end_on_first_wrong = !sandbox, class = NULL, progress_bar = !sandbox, progress_bar_color = "#609963", question_heading = "Practice what you've learned", include_question_title = TRUE, ... ) create_messages(message_correct, message_wrong, message_skipped)
ns |
namespace generated from |
messages |
an object of class |
sandbox |
boolean. Quiz no longer ends of the first wrong, removes the progress bar, and grading does not include unattempted questions. Note that the presence of a random question automatically triggers sandbox mode. It can be overridden with |
end_on_first_wrong |
Should the quiz immediately end once the user gets one question wrong? |
class |
string. A custom CSS class to add to the quiz div |
progress_bar |
boolean. Show the progress bar UI at the top of the quiz |
progress_bar_color |
Color code for the progress bar background |
question_heading |
Default text to show above the question prompt. |
include_question_title |
boolean. Should the text "Question #" be included above the prompt? If not included, the green check / red X will not be shown either. |
... |
other named options to pass to |
message_correct |
a string to be shown at the end of the quiz when the user gets all questions correct |
message_wrong |
a string to be shown at the end of the quiz when the user gets at least one question wrong |
message_skipped |
a string to be shown at the end of the quiz when the user skips the quiz or ends it early |
a list
an object of class quizMessages
set_quiz_options()
: Sets the options for a quiz
create_messages()
: Create a messages object
# set the options when creating the quiz quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ), options = set_quiz_options(sandbox = TRUE) ) # or modify the options on a quiz object quiz@options <- set_quiz_options(sandbox = FALSE) # adjust the messages shown at the end of the quiz messages <- create_messages( 'Congrats!', 'Ahh, bummer! Got at least one wrong', 'Looks like you skipped to the end!' ) quiz@options <- set_quiz_options(messages = messages)
# set the options when creating the quiz quiz <- create_quiz( create_question( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Select nulla.', add_choice('auctor'), add_choice('nulla', correct = TRUE) ), create_question( 'Mauris congue aliquet dui, ut dapibus lorem porttitor sed. Select 600.', add_choice('600', correct = TRUE), add_choice('800') ), options = set_quiz_options(sandbox = TRUE) ) # or modify the options on a quiz object quiz@options <- set_quiz_options(sandbox = FALSE) # adjust the messages shown at the end of the quiz messages <- create_messages( 'Congrats!', 'Ahh, bummer! Got at least one wrong', 'Looks like you skipped to the end!' ) quiz@options <- set_quiz_options(messages = messages)