Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I record exercise submission in a learnr R tutorial?

Tags:

r

I wrote a series of learnr tutorials to help students learn R, and I need to record when students have submitted an answer to a question or an exercise. A section of the learnr documentation touches on this topic (https://rstudio.github.io/learnr/publishing.html#recording_events), but not at the level of detail I need, apparently. I have two main question areas, and below those I've pasted code for a sample tutorial.

  1. Setting the tutorial.event_recorder option: The learnr documentation states

    "You can capture events by using a custom event recorder function. This function is specified via the tutorial.event_recorder global option."

    I found one example online where this is defined in the setup chunk as

    options(tutorial.event_recorder = learnr:::debug_event_recorder)
    

    So that's what I've put in my code, but are there other possible options? Am I even using it correctly?

  2. Actually recording events: the learnr documentation creates an example event recorder function printing to stdout as

    tutorial_event_recorder <- function(tutorial_id, tutorial_version,
                                        user_id, event, data) {
    cat(tutorial_id, " (", tutorial_version, "): ", user_id , "\n", sep = "")
    cat("event: ", event, "\n", sep = "")
    }
    

Let's say I was happy with that level of event recording: I'm assuming I define it in some R code chunk, but where do I call it? Are tutorial_id, tutorial_version, and user_id global arguments that are defined by the program once I set the tutorial.event_recorder option? Then do I define the event as exercise_submission, for example? Is there an argument that specifies which exercise or question was submitted? I typically have several exercises and questions per tutorial.

I have pasted an example of my tutorial code if this helps. Eventually I would like to incorporate the checkr package and its event recording, but I don't have time to do that well at the moment. The tutorials are hosted on a server but I am first trying just to get event recording to work locally. Thank you very much!

---
title: "Tutorial:  Categorical Variables"
output: learnr::tutorial
runtime: shiny_prerendered
tutorial:
  id: "toytorial"
---


```{r setup, include=FALSE}
library(learnr)
knitr::opts_chunk$set(echo = TRUE)
tutorial_options(exercise.eval = FALSE)
options(tutorial.event_recorder = learnr:::debug_event_recorder)
```

### Test yourself

Use the `dim()` command to get the number of columns and rows in the data frame 'iris'.
```{r, ex1, exercise=TRUE, echo = FALSE}

```

```{r, q1, echo=FALSE}
question("How many rows are in the 'iris' data frame?",
  answer("5"),
  answer("150", correct=TRUE)
)
```

EDIT: After Andrie's answer on 8/24 and the helpful sample tutorial Andrie posted at github.com/rstudio/learnr/issues/182 I have updated my setup chunk in my sample tutorial to:

```{r setup, include=FALSE}
library(learnr)
knitr::opts_chunk$set(echo = TRUE)

tutorial_options(exercise.eval = FALSE)
new_recorder <- function(tutorial_id, tutorial_version, user_id, event, data) {
    cat(tutorial_id, " (", tutorial_version, "): ", user_id, ", ", event, ", ", data$label, ", ", data$answers, ", ", data$correct, "\n", sep = "")
}

options(tutorial.event_recorder = new_recorder)

```

Now that I know to look at the R Markdown window in RStudio I see the recording as questions are answered or exercises attempted. I still cannot figure out how to write the event recording to a file or database: sink() doesn't seem to work for me.

like image 679
bigorangesplot Avatar asked Aug 10 '18 02:08

bigorangesplot


2 Answers

I ran your code, and observed the following output from stdout (in the RMarkdown pane if you're using RStudio).

This output answers your first question, about how to define the event. From the output it is clear that the learnr recording function automatically records the event. In this case the event is exercise_submission and question_submission respectively.

C:/Users/apdev/Documents/temp (1.0): apdev
event: exercise_submission
List of 6
 $ label        : chr "ex1"
 $ code         : chr "\ndim(iris)\n"
 $ output       : 'html' chr "\n\n\n<pre><code>[1] 150   5</code></pre>\n"
  ..- attr(*, "html")= logi TRUE
  ..- attr(*, "html_dependencies")= list()
 $ error_message: NULL
 $ checked      : logi FALSE
 $ feedback     : NULL

C:/Users/apdev/Documents/temp (1.0): apdev
event: question_submission
List of 4
 $ label   : chr "q1"
 $ question: chr "How many rows are in the &#39;iris&#39; data frame?"
 $ answers : chr "5"
 $ correct : logi FALSE

Your other questions are answered in the documentation under the heading Tutorial identifiers. In short, learnr will use the following defaults for the identifiers:

  • tutorial_id : Network origin and path of tutorial.
  • tutorial_version : 1.0
  • user_id : Account name of server user executing the tutorial

I have tried this and it works out of the box with RStudio Connect.


However, I suspect there might be a bug in the learnr package, since it seems that changing the defaults in the YAML header doesn't have any effect. I'm still trying to get to the bottom of this.

like image 87
Andrie Avatar answered Nov 03 '22 11:11

Andrie


Regarding writing the event recording to a file, a basic way to do this is by passing file = "/my_path/my_filename.txt" and append = TRUE as additional arguments to the cat function in your new_recorder function.

like image 22
SPP Avatar answered Nov 03 '22 12:11

SPP