Skip to content

Commit 8016d2d

Browse files
TomNaessensclaude
andcommitted
Correct and expand the Trinket guide
Trinket open sourced their platform as trinketapp/trinket-oss, so the parts of the guide that described the export can now be checked against the code that wrote it instead of against one sample. What that changed: - page and assignment are the only material types that ever existed. A video or a slide deck was a page with something embedded, never a type of its own. - The folder under trinkets/ is the trinket kind, and python3 is one of eleven. R is the only capitalised one, and python accepts both Python 2 and 3, so it cannot be read as Python 2. - Uploaded images are in the export, under assets/. Only what a page linked to is missing, which is why an export can reference slide decks and carry no assets directory at all. - Unpublished pages are exported next to published ones, distinguishable only by an isDraft flag that older exports do not have. - Trinket had no autograding. There is no grade or score anywhere in its models, so a teacher moving here writes test suites from scratch. Also documents code playgrounds as the counterpart to a trinket embedded in a page, with a warning that they are an early preview whose authoring format will change and that they run Python only. Expands the section on writing activities to argue for the test suite and the model solution rather than just listing them, links the boilerplate reference, and adds a section on letting an AI assistant do the first pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHmqGYt9PunEAwMdsafyTY
1 parent f494546 commit 8016d2d

2 files changed

Lines changed: 124 additions & 28 deletions

File tree

  • en/guides/teachers/moving-from-trinket
  • nl/guides/teachers/moving-from-trinket

en/guides/teachers/moving-from-trinket/index.md

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ It assumes you have never used Dodona and have never used git.
1414

1515
Start by working out what you actually have.
1616

17-
**An export contains what Trinket stored, not what your pages linked to.** Your lesson pages are in the zip, and so is the code of every trinket. Anything a page merely pointed at is not: files shown through a viewer, documents on Google Drive, images loaded from another site, embedded video.
17+
**An export contains what Trinket stored, not what your pages linked to.** Your lesson pages are in the zip, along with the code of every trinket and the images you uploaded. What is missing is anything a page only pointed at: documents you added through Trinket's viewer, such as PDFs and slide decks, files on Google Drive, images loaded from another site, embedded video.
1818

19-
Open a few lesson pages in a text editor and look for links, so you know what is missing before you start rebuilding.
19+
Open a few lesson pages in a text editor and look for links, so you know what is missing before you start rebuilding. Everything on that list has to be gathered separately and carried across by hand, from wherever you still have it. Later on it goes into your own repository, next to the pages that use it.
2020

2121
::: warning Links to Trinket itself no longer work
2222

@@ -28,7 +28,7 @@ This is also a good moment to decide what you want to keep. A course that grew o
2828

2929
## What is in the export
3030

31-
The zip has three parts. This example comes from a Python course:
31+
The zip is laid out like this. The example comes from a Python course:
3232

3333
```
3434
course.json
@@ -44,6 +44,9 @@ trinkets/
4444
python3/
4545
12-Loops-Predict_a1b2c3d4e5/
4646
main.py
47+
assets/
48+
60f1a2b3c4d5e6f7/
49+
diagram.png
4750
```
4851

4952
`course.json` is the table of contents. It lists your lessons in order, and for each lesson the materials it contains:
@@ -69,7 +72,15 @@ The `type` of each material is the useful part:
6972
* `page` is a lesson page: text only, and all of it is in the matching `.md` file.
7073
* `assignment` is a page with a trinket attached. The text is in the `.md` file, and the code students started from is in `trinkets/`.
7174

72-
One directory per lesson holds the `.md` files, numbered in the order they appeared. Under `trinkets/`, each assignment has its own directory with the starter code inside, usually as `main.py`.
75+
Those two are the only material types Trinket had. A video, a slide deck or a quiz was never a type of its own: it was a `page` with that thing embedded in its text, which is why they do not show up separately here.
76+
77+
One directory per lesson holds the `.md` files, numbered in the order they appeared. Under `trinkets/`, each assignment has its own directory with the starter code inside. The folder in between is named after the kind of trinket: `python3` in this example, but `python`, `html`, `java`, `blocks`, `console`, `pygame`, `glowscript`, `glowscript-blocks`, `music` and `R` are all possible. `assets/` holds the images you uploaded, and is absent when a course used none.
78+
79+
::: warning Unpublished pages are in there too
80+
81+
Depending on when you took the export, `course.json` carries an `isDraft` flag on each lesson and material. Pages you never published sit next to the published ones and look identical, so check that flag before you convert a lesson you thought was finished. Older exports do not have it at all.
82+
83+
:::
7384

7485
Read through the `.md` files before you plan anything. How much of the teaching sits in the pages themselves differs a lot between courses, and that decides how much you have to rewrite.
7586

@@ -81,11 +92,33 @@ Read through the `.md` files before you plan anything. How much of the teaching
8192
| A lesson | A [series](../exercise-series-management/) inside that course |
8293
| A material of type `page` | A [reading activity](/en/guides/exercises/examples/content/) |
8394
| A material of type `assignment` | An [exercise](/en/guides/exercises/creating-exercises/introduction/), or a reading activity when there is nothing to grade |
84-
| The starter code of a trinket | The boilerplate of the exercise |
95+
| The starter code of a trinket | The [boilerplate](/en/references/exercise-directory-structure/#exercise-only-configuration) of the exercise |
96+
| A trinket embedded in a page | A code playground in a reading activity, described below |
97+
98+
### Runnable code inside a page
99+
100+
A trinket embedded in the middle of a page, which students could run and edit where it stood, has a counterpart on Dodona: a code playground. It is a runnable, editable block inside a reading activity, and students can run it without submitting anything.
101+
102+
You write one by wrapping the code in a `<pre>`:
103+
104+
```html
105+
<dw-code-playground>
106+
<pre>
107+
name = input("What is your name? ")
108+
print("Hello, " + name + "!")
109+
</pre>
110+
</dw-code-playground>
111+
```
85112

86-
There is one thing that does not carry across: a trinket embedded in the middle of a page, which students could run and edit where it stood. On Dodona, students write and run code inside an exercise, which they then submit and get feedback on.
113+
The block runs in the student's browser and can read input, so a program that asks a question works as expected.
87114

88-
In practice that means two things. If the point is for students to run code and change it, make it an exercise. If the point is to show code while you explain something, put it in a code block in a reading activity and follow that with an exercise where they use it.
115+
::: warning Code playgrounds are an early preview
116+
117+
This is a proof of concept. Both the way playgrounds look and the way you write them are likely to change, so expect to revisit pages that use them. They currently run Python only.
118+
119+
:::
120+
121+
A playground is for exploring, not for assessment: nothing is submitted, and nothing is graded. Where students should get feedback on what they wrote, use an exercise.
89122

90123
## Deciding what becomes an exercise
91124

@@ -101,7 +134,7 @@ If one task in Trinket ran across several pages, decide page by page. A page tha
101134

102135
Your activities live in a git repository that Dodona reads. Set that up once, before you write anything.
103136

104-
This is a real difference from Trinket, and worth understanding before you start. Your content is not stored inside Dodona: it lives in a repository you own, and Dodona reads from it. You can copy it, move it elsewhere, or hand it to a colleague, and it does not disappear if the platform does. That is exactly the situation you are in now with Trinket.
137+
Dodona works differently from Trinket here. Your material is not stored inside the platform: it lives in a repository you own, and Dodona only reads from it. You can copy it, move it elsewhere, or hand it to a colleague, and it stays yours whatever happens to the platform. There is also no export step to think about later, because the repository already is your copy.
105138

106139
[Creating exercises: installation](/en/guides/exercises/creating-exercises/setup/) walks through the setup: creating a GitHub account, starting from our template repository, giving the user `dodona-server` access to your repository, adding the repository to Dodona, and setting up a webhook so Dodona picks up your changes automatically.
107140

@@ -123,6 +156,8 @@ my-course/
123156
config.json
124157
description/
125158
description.en.md
159+
boilerplate/
160+
boilerplate
126161
evaluation/
127162
suite.yaml
128163
solution/
@@ -137,15 +172,20 @@ The folder structure is only there to keep you organised. Which activities end u
137172

138173
To convert a **page**, move its text into `description/description.en.md`. The [description reference](/en/references/exercise-description/) covers images, code blocks, tables and callouts.
139174

140-
To convert an **assignment**, do the same for the text, then use the trinket's starter code as the boilerplate, write a test suite that describes what a correct solution does, and add a solution of your own.
175+
To convert an **assignment**, start with the text, then add the three things that turn it into a graded exercise:
176+
177+
* **The starter code** goes in `description/boilerplate/boilerplate`, so students open the exercise with the same code the trinket gave them.
178+
* **A test suite** in `evaluation/` describes what a correct solution does. Trinket had no equivalent: assignments were handed in and then read by you, so there is no grading logic in the export to carry over and you write these from scratch. It is also what the rest of Dodona is built on: students find out whether they are right the moment they submit, they can correct themselves without waiting for you, and you can see who is stuck and where. An exercise without a test suite is just a page with an editor attached.
179+
* **A model solution** in `solution/` proves the test suite is right. Submit it yourself once. If your own solution does not pass, the test suite is wrong, and you want to know that before thirty students do.
180+
181+
Writing test suites is the new part of the move, so give the first one time and reuse its shape afterwards. [Test suites](/en/guides/exercises/testsuites/) explains the format, and [an exercise with input and output](/en/guides/exercises/examples/input-output/) is the closest match to a typical Trinket assignment: a program that reads input and prints a result.
141182

142183
These pages cover the rest:
143184

144-
* [Creating exercises: the exercise](/en/guides/exercises/creating-exercises/exercise/) for a first complete exercise.
145-
* [An exercise with input and output](/en/guides/exercises/examples/input-output/), which is the shape most converted Trinket assignments take.
185+
* [Creating exercises: the exercise](/en/guides/exercises/creating-exercises/exercise/) for a first complete exercise, end to end.
146186
* [A reading activity](/en/guides/exercises/examples/content/) for pages without a task.
147-
* [Test suites](/en/guides/exercises/testsuites/) for describing what a correct answer does.
148187
* [The `config.json` reference](/en/references/exercise-config/) for the settings of a single activity.
188+
* [The exercise directory structure](/en/references/exercise-directory-structure/) for where each file belongs.
149189

150190
## Building the course
151191

@@ -159,7 +199,7 @@ Material you wrote for yourself rather than for students, like lesson plans or a
159199

160200
## What works differently than in Trinket
161201

162-
Two things are worth knowing before you write your test suites.
202+
Two things to know before you write your test suites.
163203

164204
**Tests run your students' programs, they do not read them.** Dodona can check what a program prints, what a function returns, which exception it raises, what exit code it ends with, and the files it writes. What it cannot check is how the code was written. A rule such as "solve this with a single print statement" will not be enforced by the tests, because a solution that ignores the rule still behaves correctly. Put the rule in the description, and check it yourself when you read submissions.
165205

@@ -171,9 +211,17 @@ When a program asks a question with `input("What is your name? ")`, that prompt
171211

172212
:::
173213

214+
## Letting an AI assistant do the first pass
215+
216+
Converting a course is a lot of manual work: a description and a test suite for every single activity.
217+
218+
We have had good results letting a coding assistant do the first pass. Point it at your export, at this guide and the reference pages it links to, and at [universal-judge](https://github.com/dodona-edu/universal-judge), the repository behind TESTed, which documents the test suite format in full. Then ask it to produce the directory structure, the descriptions and a first test suite per exercise.
219+
220+
What comes back is a first draft, not a finished course. Read every description, and submit your own solution to every exercise. A test suite can look reasonable and still expect slightly the wrong thing, which you will not see by reading it.
221+
174222
## Before you share it with students
175223

176-
New activities start as [draft](/en/faq/activities/#what-is-a-draft-activity), so students cannot see them yet. That gives you room for a final authoring pass before anything is published.
224+
New activities start as [draft](/en/faq/activities/#what-is-a-draft-activity), so students cannot see them yet. That gives you room for a final authoring pass, and lets you try your activities out on the platform yourself, before anything is published.
177225

178226
Solve every exercise yourself and submit your own solution. This is the fastest way to catch a test suite that expects the wrong thing, and it takes about a minute per exercise.
179227

0 commit comments

Comments
 (0)