Set the global exam configuration. Must be called from the server context
(i.e., in an R code chunk with context="server"
).
exam_config_server_start(
auth_provider,
storage_provider,
exercise_data_provider,
exercise_evaluator,
seed_attempt,
cache_data = FALSE
)
exam_config(...)
data_provider(fun, cache_data = FALSE)
exam_document_setup(points_format, data_provider, cache_data = FALSE)
exam_setup(...)
an authentication provider function to identify a user.
See authentication providers for details.
If NULL
, the authentication provider will be reset to a dummy provider which generates a random user id for
every request.
a storage provider list of functions for saving/retrieving section data.
See storage providers for details.
If NULL
, the authentication provider will be reset to a dummy provider which does not safe any section
data.
a data provider function which generates the user-specific (e.g., randomized) data
for all exercise chunks. Similar to data_provider
, but gets an argument chunk_label
instead of section
.
See the section on Exercise Data Providers below.
Note that exercise chunks have access only to the data returned by this data provider.
The enclosing environment of the returned environment (or list) will be set to the empty environment, emptyenv()
.
a function which creates an exercise evaluator. See exercise evaluators for details.
a function to generate the seed for the random number generator used in a single attempt. By default every user gets their unique seed which does not change between attempts. See Seeding function for more details.
cache the data generated by the exercise data provider (for exam_config()
) or the data provider
for (data_provider()
) in the Shiny session.
This makes sense if generating the data takes a while, but is only small in size.
a data provider function which generates the user-specific (e.g., randomized) data for the sections. See section Data provider for details.
formats for showing the number of points per question. The first format
is for plural, the second for singular. If only a single format is given, it is used for both plural and
singular. Can also be a function which receives the number of points and should return the label to display.
The default is points_format = c('%d point', '%d points')
.
a data provider function which generates the user-specific (e.g., randomized) data for the sections. See section Data provider for details.
Only non-missing options are set, the others are kept at their previous values.
exam_config()
is deprecated in favor of the function exam_config_server_start()
.
exam_setup()
is deprecated in favor of the function exam_document_setup()
.
Each section and question is rendered in a sterile environment, containing only the data returned by the data provider. This data provider is called every time a section is rendered and should return a list or environment with all the objects required to render the section. This includes the user-specific randomized values. The function should not set the seed itself, as it is set before the data provider is invoked.
The data provider is a function taking arguments
section
the identifier of the current section or TRUE
when data for all sections is requested.
attempt
the attempt object containing information about the current attempt, or NULL
if called
when pre-rendering the exam.
session
the Shiny session object or NULL
if called when pre-rendering the exam.
...
further arguments for future additions
The data provider function returns a list or an environment containing all objects required to render the sections.
Internally, the markdown code for each section is rendered with rmarkdown::render()
in the environment returned
by the data provider.
Warning:
To ensure the answers can be reproduced, the exercise data provider must always return the same values for
a given attempt.
The data provider must not use the attempt$user$user_id
information for randomization and should in general
not change the seed. When grading the user_id
field may not be the same as for the exam itself!
The setup and user code of an exercise is run in a separate environment, possibly in a different R process. This environment consists only of the objects in the list (or environment) returned by the exercise data provider. The function should not set the seed itself, as it is set before the data provider is invoked. The exercise data provider is run in the server R process and is called with the following arguments:
label
the exercise chunk label
attempt
the attempt object as described in the attempt object section containing information about
the current attempt (or NULL
, see below).
session
the Shiny session object or NULL
for building the auto-completion (see below).
...
further arguments for future additions
If the exercise data provider returns an environment, the enclosing environment will be set to the
empty environment, emptyenv()
.
The exercise data provider is called once when the Shiny server starts with attempt=NULL
and session=NULL
to
ensure auto-completion knows about all available objects.
Warning:
To ensure the answers can be reproduced, the exercise data provider must always return the same values for
a given attempt & exercise!
The data provider must not use the attempt$user$user_id
field for randomization, but rely on the seed which
is already set. When grading the user_id
field may not be the same as for the exam itself!
For more fine-grained control over the random seed used for an attempt, a seeding function may optionally be provided
as seed_attempt
.
This function is called with the following arguments
user
a user object as returned by the authentication provider.
previous_attempts
a list of all previous attempts (see the section on the attempt object). The list does not follow any particular order.
...
further arguments for future additions
The seeding function is useful, for example, if a group of users should get the same seed, or if a user should get the same seed for multiple attempts.
The following seeding function, for example, gives the same seed for all users whose id starts with the same letter. The seed changes with the attempt, but all users in a group will get the same seed for their 2nd, 3rd, etc, attempt.
seeding_function <- function (user, previous_attempts, ...) {
group <- substr(user$user_id, 1, 1)
# take the number of attempts into account
digest::digest2int(paste(group, length(previous_attempts)))
}
The next seeding function gives a different seed for every user, but gives the same seed for every 5 attempts.
Some functions receive one or more attempt objects. An attempt object is a list with the following elements:
id
a character string (UUID) uniquely identifying the attempt.
user
a user object as returned by the authentication provider.
seed
an integer associated with the attempt for initializing the random number generator.
started_at
the UTC time the attempt was first started (as POSIXct).
Other exam configuration:
section_config()
# Use the RStudio Connect user and assign a fixed seed for all attempts
function (shiny_session) {
user_id <- shiny_session$user
return(list(user_id = user_id, seed = digest::digest2int(shiny_session$user)))
}
#> function (shiny_session)
#> {
#> user_id <- shiny_session$user
#> return(list(user_id = user_id, seed = digest::digest2int(shiny_session$user)))
#> }
#> <environment: 0x55ce520a56f8>
# Use the RStudio Connect user and assign the same seed for all users with the same first letter.
function (shiny_session) {
user_id <- shiny_session$user
return(list(user_id = user_id,
seed = function (user, prev_attempts, ...) {
}))
}
#> function (shiny_session)
#> {
#> user_id <- shiny_session$user
#> return(list(user_id = user_id, seed = function(user, prev_attempts,
#> ...) {
#> }))
#> }
#> <environment: 0x55ce520a56f8>