-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_learnr_gradethis_interactive_tuto.Rmd
277 lines (199 loc) · 8.31 KB
/
_learnr_gradethis_interactive_tuto.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
---
title: "Tutoriels avec R avec learnr et gradethis"
output:
learnr::tutorial:
code_download: true
runtime: shiny_prerendered
---
## Démarrer: en tête `yaml` et `setup` chunk
Tout tutoriel doit débuter avec l'en tête yaml (voir `help(learnr::tutorial)` dans `R` pour les différentes options):
````markdown
---
title: "Tutoriels avec R avec learnr et gradethis"
output:
learnr::tutorial:
code_download: true
runtime: shiny_prerendered
---
````
De plus, on peut régler des options du tutoriel dans le chunk `setup`.
```{r setup, message = FALSE, warning = FALSE}
# Setup chunk
## Packages
# L'utilisation de require semble à privilégier pour le déploiment sur shiny apps
library(tidyverse)
library(learnr)
# devtools::install_github("https://github.com/rstudio-education/gradethis")
library(gradethis)
# Options du tutoriel (voir l'aide)
tutorial_options(
exercise.checker = gradethis::grade_learnr, # Pour checker
)
# Objets pour exercices
my_data <- tibble(x = 1:10, y = runif(10))
```
**Remarque importante:** Tout objet `R` qui est créé pour plusieurs exercices doit être créé dans ce chunk. En effet, les chunks exercices que nous verrons dans la section suivantes ne créé que des objets dans l'environnement du chunk, qui ne seront connus par aucun autre.
## Exercice simple (avec indice)
On peut faire des exercices simples, en ajoutant potentiellement indices et solutions.
*Faire une fonction `add` qui additionne deux nombres. Puis utiliser cette fonction pour calculer 4 + 6*
Le point clé est de spécifier dans le chunk `r` classique l'option `exercise = TRUE`.
Il est essentiel de **nommer** le chunk associé (ici, on a nommé le chunk `add`).
````markdown
`r ''````{r add, exercise=TRUE}
add <- function() {
}
```
````
Ce nommage permet d'ajouter ensuite des attributs à cet exercice, qui seront spécifiés dans de nouveaux chunks.
Par exemple, on peut donner des indices via l'attribut `hint`.
On créera un nouveau chunk lié au chunk `nom_chunk` sous la forme:
`nom_chunk-hint`.
````markdown
`r ''````{r add-hint}
# La fonction prendra deux arguments, séparés par une virgule.
# La dernière ligne de la fonction renverra le résultat.
exemple_function <- function(argument1, argument2){
# Code de la fonction
# resultat <- ....
resultat # On peut aussi mettre return(resultat)
}
```
````
Cet indice sera visible par le lecteur dans un onglet *Hint* sur lequel il pourra cliquer.
De même, on peut ajouter une solution, dans un chunk nommé `nom_chunk-solution`:
````markdown
`r ''````{r add-solution}
# SOLUTION
add <- function(argument1, argument2){
resultat <- argument1 + argument2
resultat # On peut aussi mettre return(resultat)
}
add(4, 6)
```
````
Ceci crée un onglet *Solution* dans la fenêtre de code.
**Remarque:** Dans la version actuelle de `learnr`, il semblerait qu'ajouter une solution à un *hint* ne crée pas deux onglets, mais un seul onglet *Hints*, qui permet de défiler plusieurs fenêtres, dont la dernière sera la solution. On peut espérer que cela évolue dans l'avenir.
L'écriture de tous ces codes renvoie le chunk suivant, dans
```{r add, exercise=TRUE}
add <- function() {
}
```
```{r add-hint}
# La fonction prendra deux arguments, séparés par une virgule.
# La dernière ligne de la fonction renverra le résultat.
exemple_function <- function(argument1, argument2){
# Code de la fonction
# resultat <- ....
resultat # On peut aussi mettre return(resultat)
}
```
```{r add-solution}
# SOLUTION
add <- function(argument1, argument2){
resultat <- argument1 + argument2
resultat # On peut aussi mettre return(resultat)
}
add(4, 6)
```
### Exercices faisant appel à des objets extérieurs.
Supposons qu'on ait deux exercices. Le premier est:
1. *Créer un vecteur `exemple` contenant les valeurs de 1 à 5:*
```{r exo_chunk_ex_data, exercise = TRUE}
# Afficher le vecteur ex_data
exemple <-
```
Le second fait appel au résultat du premier:
2. *Calculer la somme des éléments du vecteur `exemple`:*
```{r exo_chunk_exemple_sum, exercise = TRUE}
# Afficher le vecteur ex_data
sum(exemple)
```
Malheureusement, l'objet n'est pas reconnu. Ceci est dû au fait que l'objet créé dans le premier exercice n'est créé que dans un environnement local.
Pour que cet objet soit reconnu, il faudra le créer dans le chunk setup initial (voir la première section de ce document), ou le crééer dans un chunk associé à cet exercice (ici, l'exercice 2), dont le nom fera référence à l'exercice,, auquel on ajoutera le suffixe `setup`: i.e. `exercice2-setup`
Par exemple, on peut imprimer l'objet `my_data` créé dans la première section
```{r print_my_data, exercise = TRUE}
# Imprimer my_data
print(my_data)
```
On peut ensuite passer à la section suivante avec le `## Quiz (QCM)`.
## Quiz (QCM)
*On peut faire des quiz à l'aide des fonctions `quiz` et `question`*.
La fonction `quiz` regroupe différentes fonctions `question`, dans lesquelles des QCM
peuvent être très facilement intégrés (voir Help).
```{r quiz, echo = TRUE}
library(learnr)
quiz(
question(text = "La méthode des k-means est une méthode de classification:",
answer("Supervisée"),
answer("Non-supervisée", correct = TRUE),
answer("C'est des stats, ça?",
message = "Donne n'importe quel nom à une rose, elle sentira toujours bon"),
submit_button = "Valider la réponse"
),
question(text = "R est:",
answer("Une lettre de l'alphabet", correct = TRUE),
answer("Un des quatre éléments"),
answer("Un logiciel de statistiques", correct = TRUE)
)
)
```
## Exercice avec "vérification"
Dans cette section, on utilise le package `gradethis` qui permet de vérifier la validité d'un code donné dans un exercice:
### Vérification du résultat
Dans un exercice sur du code, si on veut vérifier le résultat, on peut ajouter à un exercice un chunk de vérification, qui sera sous la forme `nom_chunk-check`.
En incluant dans ce chunk la fonction `gradethis::grade_result`, on pourra passer une liste de tests pour voir si le résultat donné est correct.
Par exemple, pour l'exercice suivant, on commence par créer un chunk d'exercice, comme précedemment:
````markdown
`r ''```{r puissance, exercise=TRUE, exercise.lines = 5}
function(x, y) {
# Rentrer le code de la fonction ici
}
```
````
On passera alors les tests dans le chunk:
````markdown
`r ''```{r puissance-check}
grade_result(
fail_if(~ !is.function(.result), "I expected a function."),
pass_if(~ identical(.result(1.4, 2.3), 1.4^2.3),
message = "Bravo!"),
glue_incorrect = glue::glue("Pour x = 1.4 et y = 2.3, votre fonction devrait renvoyer {1.4^2.3}. En R, la puissance se fait avec ^"))
```
````
Ici, on passe deux tests, un sur la nature de l'objet rendu, un sur le résultat pour deux arguments donnés.
En pratique, cela donne l'exempl;e suivant (essayez différentes valeurs dans le chunk!).
*Faites une fonction qui prend un nombre `x` et un nombre `y` et renvoie
$x^y$. Vous n'assignerez pas cette fonction à un objet*
```{r puissance, exercise=TRUE, exercise.lines = 5}
function(x, y) {
# Rentrer le code de la fonction ici
}
```
```{r puissance-check}
grade_result(
pass_if(~ identical(.result(1.4, 2.3), 1.4^2.3),
message = "Bravo!"),
glue_incorrect = glue::glue("Pour x = 1.4 et y = 2.3, votre fonction devrait renvoyer {1.4^2.3}. En R, la puissance se fait avec ^"))
```
### Vérification du code
Mais aussi du code!
Pour cela, on procède comme précedemment, sauf que l'on utilise désormais la fonction `grade_code` dans le chunk `-check`
````markdown
`r ''```{r code_verif-check}
grade_code("Bah ça alors") # Message d'ajout.
```
````
En une seule ligne, tirez un échantillon de taille 1 dans une uniforme, en prend le logarithme,
puis la valeur absolue.
*Dans le code suivant, essayez d'écrire `abs(log(runif(1)))`, puis `abs(exp(runif(1)))`, et constatez le résultat.*
```{r code_verif, exercise=TRUE, exercise.lines = 10}
# Rentrer la solution
```
```{r code_verif-solution}
abs(log(runif(1)))
```
```{r code_verif-check}
grade_code(correct = "Très bon", incorrect = "Essaye encore!") # Message circonstancié
```
## Publication sur `shinyapps`
Un tutorial `learnr` peut être déployé sur `shinyapps`. Il faut pour cela avoir un compte sur shinyapps.io. Ensuite, on peut publier directement depuis Rstudio (ongle `Publish` en haut à droite de `Run`.)