This section gives a short overview about the order in which students have to solve problem sets and methods for customization. We also give some background information about the environments in which solutions are tested.

Default Rule: Exercises Matter

The default evaluation order is that within an exercise chunks must be solved in the given order. In contrast, it is not neccessary to have solved all previous exercises to start a new exercise.

Recall that the start of a new exercise is determined in your solution file with a line like:

## Exercise 1 -- My First Exercise`

Environments in which chunks are tested

Testing a chunk takes place in an own environment that is not equal to the global workspace.

By default all chunks inside an exercise are evaluated in an environment in which all created variables of earlier chunks in the same exercise are available. Since by default you can only proceed if previous chunks in the exercise are solved correctly, this guarantees that in the testing environment you have the correct solutions of earlier chunks available.

Environments in which hints are evaluated

Adaptive hints also evaluate expression in an environment. If hint() is called, it is evaluated in the test environment. It contains all variables from earlier chunks of the same exercise and the variables the student created in the current chunk the last time the current chunk was checked. Note that hint() itself does not by default newly evaluate the current chunk code of the student. This means one always should first check a modified solution before asking for a new hint.

Using variables from earlier exercises (Only RStudio)

By default variables that have been generated by the student in earlier exercises are not known when testing chunks in the current exercise.

It is possible to use variables from earlier exercises, but there is a severe drawback:

If an exercise imports variables, students can only start with the exercise if all previous exercises from which variables have been imported are completly solved.

In a shiny app you should always make each exercise self contained. In an RStudio based problem set you may link exercises, in some instances. E.g. you have a very simple initial exercise (that every student should pass) that just loads a data set and all later exercises use the data set from that initial exercise.

Here is an example:

## Exercise 2 -- Proceed with the data analysis

#< settings
import.var = list("1"="dat")
a) Add a column `ones` to dat that only contains 1. Show dat.
dat$ones = 1

As you see, in order to use variables from earlier exercises, you must add at the beginning of an exercise a settings block that defines a variable import.var, like

#< settings
import.var = list("1"="dat")

The variable import.var is a list whose element names correspond to the short exercise names (part of the name before –) from which you want to import variables. The list elements are character vectors of the variable names you want to import from the corresponding exercise.

Memoization for importing same data set in several exercises in a shiny based problem set

In a shiny based problem set, I suggest to never make exercises import variables from previous exercises. Not even for data loading. Instead add a chunk at the beginning of each exercise that loads the relevant data again in a task block.

You can use memoization to avoid behind the scenes that the same data is loaded twice. Assume you call import("mydat.csv") from the library rio in several exercises of your problem set.

You can then call with the arguments use.memoise=TRUE and memoise.funs=c("rio::import") to avoid that the data set is indeed loaded multiple times.

Optional chunks

If you set the chunk option optional=TRUE, a chunk needs not be solved in order to continue the exercise. Example:

```{r "1_b", optional = TRUE}
# Code here


Variables generated in an optional chunk will not be available in later chunks of the exercise. That is because we cannot be sure whether these variables exist or not.

The environment in which an optional chunk is tested will contain all variables created in non-optional chunks earlier in the exercise.


The function has an argument extra.code.file. This can be set to a the name of an R file. This R file will be sourced when the problem set is generated and all created variables and functions will be available in ALL chunks when chunks are tested. This usually only makes sense for shiny based problem sets.

Note that you don’t have to give the extra code R file to the students. The information will be included in the problem set rps file.

preknit blocks

preknit blocks are declared outside of code chunks and start with #< preknit and end with #>.

Any rmd code inside a preknit block will be knitted at compile-time and shown as usual RMarkdown output in the shiny based version of the problem set. This is very similar to the output of an info block, except that it is not put into a collapsible.

Note that code that was evaluated in an earlier preknit block or earlier info block will be available at compile time at later info or preknit blocks, no matter which exercise the blocks are in. If you want just to do some preliminary computations for later info or preknit blocks without showing any output, add a chunk with the chunk option include=FALSE in a preknit block.