Code Treadmill is an open source project. Pull requests are always welcome! Here is a helpful guide to help you contribute new exercises.
Exercises live in exercises/, one file per topic (e.g. js-loops.js). Each file exports a default object keyed by exercise ID.
// exercises/js-loops.js
export default {
'js-loops-001': {
content: `
let num = 0;
while (num < #-#) {
num = num + 1;
}
console.log(num);`,
},
};The content field contains the code to display. Placeholders (see below) are substituted with random values each time the exercise is shown.
'js-boolean-write-001': {
type: 'write',
description: 'Write a function `allPositive(a, b, c)` that returns `true` if all three arguments are positive.',
starterCode: `function allPositive(a, b, c) {
return false;
}
// > allPositive(1, 2, 3)
// true
// > allPositive(1, -1, 3)
// false`,
hiddenTests: [
['allPositive(0, 1, 2)', 'false'],
['allPositive(10, 20, 30)', 'true'],
],
},The doctest-style examples in starterCode are visible to the student. The hiddenTests array runs on submission but is not shown.
Add an isError flag and a cleanContent field (the corrected version of the code). The error type buttons appear automatically when any exercise in the workout has isError set.
'js-errors-001': {
isError: true,
content: `
let x = foo;
console.log(x);`,
cleanContent: `
let foo = 1;
let x = foo;
console.log(x);`,
},Place these tokens anywhere inside a content string. They are replaced with random values each time the exercise loads.
| Placeholder | Description |
|---|---|
## | Random integer between 1 and 7. |
#-# | Random integer between 8 and 16. |
#.# | Random float with two decimal places. |
#d8# | Random decimal integer between 1 and 255. |
@@ | Random animal name. |
^^ | Random human name. |
** | Random boolean — true or false (JS style). |
%% | Random boolean — True or False (Python style). |
$$ | Random adjective. |
~~ | Random single character. |
!! | Random sentence. |
#x# | Random hex byte in Intel notation (e.g. 1AH, 0FFH) — for Intel 8080 assembly exercises. |
#b# | Random binary string for a value 1–255 (e.g. 10110101) — for Intel 8080 assembly exercises. |
#h# | Random 2-digit lowercase hex for a value 16–255 (e.g. b5) — for Intel 8080 assembly exercises. |
#o# | Random octal string for a value 1–255 (e.g. 265) — for Intel 8080 assembly exercises. |
Wrapping any of the following in [(...)] produces a random array of 3–8 elements of that type: [(##)], [(#-#)], [(#.#)], [(@@)], [(~~)], [(^^)].
Workouts live in workouts/. Each file exports an object:
// workouts/js-loops.js
export default {
lang: 'js',
exercises: [
'js-loops-001',
'js-loops-002',
{ id: 'js-loops-003', repeat: 3 }, // show this exercise 3 times
],
pairedWith: 'js-loops-write', // optional companion workout
};The exercises array can contain plain string IDs or objects with a repeat count to show the same exercise multiple times with fresh random values each time.
Register new workouts in workouts/workoutsOptions.js so they appear in the picker:
{ lang: 'js', workout: 'loops', type: 'read', label: '7. Loops' }Thanks! See the note on the overview page.