@jutge.org/toolkit 4.4.17 → 4.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/problems/quizzes/demo-quiz.pbm/README.md +1 -0
- package/assets/problems/quizzes/demo-quiz.pbm/ca/award.png +0 -0
- package/assets/problems/quizzes/demo-quiz.pbm/ca/quiz.yml +1 -1
- package/assets/problems/quizzes/demo-quiz.pbm/ca/single-choice.yml +9 -1
- package/assets/problems/quizzes/demo-quiz.pbm/ca/some-drawing.svg +150 -0
- package/assets/problems/quizzes/demo-quiz.pbm/ca/some-image.png +0 -0
- package/assets/problems/quizzes/demo-quiz.pbm/en/quiz.yml +1 -1
- package/assets/problems/quizzes/demo-quiz.pbm/en/single-choice.yml +9 -1
- package/assets/problems/quizzes/demo-quiz.pbm/en/some-drawing.svg +150 -0
- package/assets/problems/quizzes/demo-quiz.pbm/en/some-image.png +0 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/README.md +11 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/handler.yml +1 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q01.yml +14 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q02.yml +14 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q03.yml +14 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q04.yml +15 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q05.yml +32 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q06.yml +12 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q07.yml +23 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q08.yml +14 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q09.yml +14 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/q10.yml +23 -0
- package/assets/problems/quizzes/heroes-of-computation.pbm/en/quiz.yml +48 -0
- package/assets/problems/quizzes/the-answer-is-42.pbm/en/quiz.yml +2 -0
- package/dist/index.js +469 -465
- package/docs/quiz-anatomy.md +93 -61
- package/package.json +2 -1
- package/toolkit/quiz.ts +30 -3
package/docs/quiz-anatomy.md
CHANGED
|
@@ -4,17 +4,13 @@ This document describes the anatomy of a **quiz problem** in [Jutge.org](https:/
|
|
|
4
4
|
|
|
5
5
|
## Terminology
|
|
6
6
|
|
|
7
|
-
A **quiz** is a problem whose handler is set to `quiz`. It is made of a **quiz root** and a list of **questions**. The quiz root is defined in `quiz.yml` and holds the quiz title, statement, whether questions are shuffled, and the list of questions with their scores. Each **question** is defined in a separate YAML file (e.g. `single-choice.yml`) and has a
|
|
7
|
+
A **quiz** is a problem whose handler is set to `quiz`. It is made of a **quiz root** and a list of **questions**. The quiz root is defined in `quiz.yml` and holds the quiz title, author, statement, whether questions are shuffled, and the list of questions with their scores. Each **question** is defined in a separate YAML file (e.g. `single-choice.yml`) and has a `type`: SingleChoice, MultipleChoice, FillIn, Ordering, Matching, or OpenQuestion.
|
|
8
8
|
|
|
9
9
|
Quiz content can be **localized**: the same quiz can have different `quiz.yml` and question files per language (e.g. under `en/` and `ca/`). The toolkit runs or lints the quiz for a given directory, so you typically run it from a language-specific subdirectory. Each language should live inside its own folder.
|
|
10
10
|
|
|
11
|
-
**Variable substitution** allows question text and options to depend on values generated at run time. If a question file is named `example.yml`, the toolkit looks for `example.py` in the same directory. When present, it runs the Python script with a random
|
|
11
|
+
**Variable substitution** allows question text and options to depend on values generated at run time. If a question file is named `example.yml`, the toolkit looks for `example.py` in the same directory. When present, it runs the Python script with a random `seed` and collects the script’s global variables. Those variables can be referenced in the question YAML with `$name` or `${name}`. This makes it possible to have different numbers, strings, or options for each run while keeping the same correct answer logic (e.g. “What is $a + $b?” with `a` and `b` random).
|
|
12
12
|
|
|
13
|
-
**Scoring**: Each question has a
|
|
14
|
-
|
|
15
|
-
- If `partial_answer` is set to `false` (default), users get full points for that question only when their answer is completely correct; any mistake gives zero points for that question.
|
|
16
|
-
|
|
17
|
-
- If `partial_answer` is set to `true`, users can receive partial points for that question when the answer is partially correct (e.g. proportional to how many parts are right), and the response may still be marked as "correct" if at least one part is right.
|
|
13
|
+
**Scoring**: Each question has a `score` between 0–100, and the total of all question scores listed in `quiz.yml` must add up to 100. Users earn points for each question.
|
|
18
14
|
|
|
19
15
|
## Quiz structure
|
|
20
16
|
|
|
@@ -43,25 +39,26 @@ You run or lint the quiz from the directory that contains `quiz.yml` (e.g. `jtk
|
|
|
43
39
|
|
|
44
40
|
`yml` files are YAML (YAML Ain't Markup Language) files. YAML is a human-readable data-serialization language; see [YAML documentation](https://yaml.org/) for more details. Also, see [YAML multiline info](https://yaml-multiline.info/) for more details on how to write multiline strings in YAML.
|
|
45
41
|
|
|
46
|
-
Many items are written in Markdown. See [Markdown documentation](https://www.markdownguide.org/) for more details. In addition, you can use a small subset of LaTeX for mathematical expressions but these have to be enclosed between `·` signs, not standard `$` signs.
|
|
47
|
-
|
|
48
42
|
## The `quiz.yml` file
|
|
49
43
|
|
|
50
44
|
The file `quiz.yml` defines the quiz root.
|
|
51
45
|
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
46
|
+
- `title`: Title of the quiz.
|
|
47
|
+
- `author`: Author of the quiz.
|
|
48
|
+
- `statement`: Short description or instructions shown for the quiz (Markdown).
|
|
49
|
+
- `questions`: List of question entries. Each entry has:
|
|
50
|
+
- `title`: Title of the question (e.g. for display in a table of contents).
|
|
51
|
+
- `file`: Base name of the question file, without the `.yml` extension (e.g. `question` for `question.yml`).
|
|
52
|
+
- `score`: Integer from 0 to 100. The sum of all `score` values in the list must be 100.
|
|
53
|
+
- `shuffle` (optional): Whether to shuffle the order of questions when running the quiz. Defaults to `false`.
|
|
59
54
|
|
|
60
55
|
### Example
|
|
61
56
|
|
|
62
57
|
```yaml
|
|
63
58
|
title: Demo quiz
|
|
64
59
|
|
|
60
|
+
author: Jordi Petit
|
|
61
|
+
|
|
65
62
|
statement: This quiz showcases the possibilities of the quiz problems at Jutge.org.
|
|
66
63
|
|
|
67
64
|
shuffle: true
|
|
@@ -90,16 +87,24 @@ questions:
|
|
|
90
87
|
|
|
91
88
|
## Question types
|
|
92
89
|
|
|
93
|
-
Each question is stored in a YAML file whose name matches the `file` field in `quiz.yml` (e.g. `question.yml`). The file must contain a
|
|
90
|
+
Each question is stored in a YAML file whose name matches the `file` field in `quiz.yml` (e.g. `question.yml`). The file must contain a `type` field that identifies the kind of question. Variable substitution applies to text fields and options when a corresponding `.py` file exists. All question types support an optional `hide_score` (default `false`) and an optional `partial_answer` (default `false`).
|
|
91
|
+
|
|
92
|
+
The `partial_answer` option is set per question in the question YAML:
|
|
93
|
+
|
|
94
|
+
- If `partial_answer` is set to `false` (default), users get full points for that question only when their answer is completely correct; any mistake gives zero points for that question.
|
|
95
|
+
|
|
96
|
+
- If `partial_answer` is set to `true`, users can receive partial points for that question when the answer is partially correct (e.g. proportional to how many parts are right), and the response may still be marked as "correct" if at least one part is right.
|
|
97
|
+
|
|
98
|
+
The `hide_score` option is set per question in the question YAML. If set to `true`, the question score is not shown to the user.
|
|
94
99
|
|
|
95
100
|
### SingleChoice
|
|
96
101
|
|
|
97
|
-
One correct option among several. Exactly one choice must have `correct: true`. Choices can be shuffled (optional
|
|
102
|
+
One correct option among several. Exactly one choice must have `correct: true`. Choices can be shuffled (optional `shuffle`, default `true`). Each choice can have an optional `hint`. Duplicate choice text is not allowed.
|
|
98
103
|
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
104
|
+
- `text`: Question text (supports `$var` and `${var}`).
|
|
105
|
+
- `choices`: List of `{ text, correct?, hint? }`. One and only one choice must have `correct: true`.
|
|
106
|
+
- `shuffle` (optional): Whether to shuffle choices. Defaults to `true`.
|
|
107
|
+
- `partial_answer` (optional): Whether to award partial credit for this question. Defaults to `false`.
|
|
103
108
|
|
|
104
109
|
Example:
|
|
105
110
|
|
|
@@ -121,12 +126,12 @@ Variables `a`, `b`, `s1`, `s2`, `s3` would be produced by a `single-choice.py` s
|
|
|
121
126
|
|
|
122
127
|
### MultipleChoice
|
|
123
128
|
|
|
124
|
-
Zero or more correct options. Multiple choices can have `correct: true`. Choices can be shuffled (optional
|
|
129
|
+
Zero or more correct options. Multiple choices can have `correct: true`. Choices can be shuffled (optional `shuffle`, default `true`).
|
|
125
130
|
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
131
|
+
- `text`: Question text (supports variables).
|
|
132
|
+
- `choices`: List of `{ text, correct?, hint? }`.
|
|
133
|
+
- `shuffle` (optional): Whether to shuffle choices. Defaults to `true`.
|
|
134
|
+
- `partial_answer` (optional): Whether to award partial credit for this question. Defaults to `false`.
|
|
130
135
|
|
|
131
136
|
Example:
|
|
132
137
|
|
|
@@ -146,19 +151,19 @@ choices:
|
|
|
146
151
|
|
|
147
152
|
### FillIn
|
|
148
153
|
|
|
149
|
-
One or more blanks in a text or code block. Each blank is identified by a placeholder (e.g. `S1`, `XXXX`) and has a correct answer and optional options (dropdown). If
|
|
154
|
+
One or more blanks in a text or code block. Each blank is identified by a placeholder (e.g. `S1`, `XXXX`) and has a correct answer and optional options (dropdown). If `options` are given, the correct answer must be one of them.
|
|
150
155
|
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
-
|
|
156
|
+
- `text`: Question or instructions (supports variables).
|
|
157
|
+
- `context`: Text containing placeholders (e.g. `S1`, `S2`, `XXXX`). Placeholders are the keys in `items`.
|
|
158
|
+
- `items`: Map from placeholder name to an item object:
|
|
159
|
+
- `correct`: Correct answer (string).
|
|
160
|
+
- `options` (optional): List of strings; if present, the blank is shown as a dropdown and `correct` must be in this list.
|
|
161
|
+
- `maxlength` (optional): Max length for the answer. Defaults to 100.
|
|
162
|
+
- `placeholder` (optional): Placeholder text in the input (e.g. `"?"`).
|
|
163
|
+
- `ignorecase` (optional): Whether to ignore case when checking. Defaults to `true`.
|
|
164
|
+
- `trim` (optional): Whether to trim spaces. Defaults to `true`.
|
|
165
|
+
- `partial_answer` (optional): Whether this blank contributes to partial credit for the question. Defaults to `false`.
|
|
166
|
+
- `partial_answer` (optional, at question level): Whether to award partial credit for this question. Defaults to `false`.
|
|
162
167
|
|
|
163
168
|
Example with dropdowns:
|
|
164
169
|
|
|
@@ -217,13 +222,13 @@ items:
|
|
|
217
222
|
|
|
218
223
|
### Ordering
|
|
219
224
|
|
|
220
|
-
User must order a list of items (e.g. chronological order). Items can be shown in shuffled order (optional
|
|
225
|
+
User must order a list of items (e.g. chronological order). Items can be shown in shuffled order (optional `shuffle`, default `true`).
|
|
221
226
|
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
225
|
-
-
|
|
226
|
-
-
|
|
227
|
+
- `text`: Question text (supports variables).
|
|
228
|
+
- `label`: Label for the list (e.g. “Programming language”).
|
|
229
|
+
- `items`: List of strings in the correct order.
|
|
230
|
+
- `shuffle` (optional): Whether to show items in random order. Defaults to `true`.
|
|
231
|
+
- `partial_answer` (optional): Whether to award partial credit for this question. Defaults to `false`.
|
|
227
232
|
|
|
228
233
|
Example:
|
|
229
234
|
|
|
@@ -245,14 +250,14 @@ items:
|
|
|
245
250
|
|
|
246
251
|
### Matching
|
|
247
252
|
|
|
248
|
-
Two columns: user matches each left item with one right item. Left and right lists can be shuffled (optional
|
|
253
|
+
Two columns: user matches each left item with one right item. Left and right lists can be shuffled (optional `shuffle`, default `true`).
|
|
249
254
|
|
|
250
|
-
-
|
|
251
|
-
-
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
255
|
+
- `text`: Question text (supports variables).
|
|
256
|
+
- `labels`: Two strings, e.g. `["Countries", "Capitals"]`.
|
|
257
|
+
- `left`: List of strings (e.g. countries).
|
|
258
|
+
- `right`: List of strings (e.g. capitals), in the same order as `left` (left[i] matches right[i]).
|
|
259
|
+
- `shuffle` (optional): Whether to shuffle left and right columns. Defaults to `true`.
|
|
260
|
+
- `partial_answer` (optional): Whether to award partial credit for this question. Defaults to `false`.
|
|
256
261
|
|
|
257
262
|
Example:
|
|
258
263
|
|
|
@@ -284,9 +289,9 @@ right:
|
|
|
284
289
|
|
|
285
290
|
Free-text answer with no automatic correction. Useful for open-ended or reflective answers.
|
|
286
291
|
|
|
287
|
-
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
292
|
+
- `text`: Question text (supports variables).
|
|
293
|
+
- `placeholder` (optional): Placeholder for the text area. Defaults to `""`. Supports variables.
|
|
294
|
+
- `partial_answer` (optional): Whether to award partial credit for this question. Defaults to `false`.
|
|
290
295
|
|
|
291
296
|
Example:
|
|
292
297
|
|
|
@@ -300,11 +305,30 @@ placeholder: 'My name is **$name** and I want to pass this course.'
|
|
|
300
305
|
|
|
301
306
|
The variable `name` can be set by an optional `open-ended.py` (or the same base name as the question file) in the same directory.
|
|
302
307
|
|
|
308
|
+
## Markdown usage
|
|
309
|
+
|
|
310
|
+
Markdown is supported in most fields. See [Markdown documentation](https://www.markdownguide.org/) for more details.
|
|
311
|
+
|
|
312
|
+
For quizzes, you may use:
|
|
313
|
+
|
|
314
|
+
- Lists (e.g. `- Item 1`, `- Item 2`, `- Item 3`)
|
|
315
|
+
- Italic text (e.g. `*italic text*`)
|
|
316
|
+
- Bold text (e.g. `**bold text**`)
|
|
317
|
+
- Underline text (e.g. `__underline text__`)
|
|
318
|
+
- Code (with backticks, e.g. `` `code` ``)
|
|
319
|
+
- Code blocks (with triple backticks and a programming language specifier)
|
|
320
|
+
|
|
321
|
+
Avoid sections, links, and tables. HTML is not supported.
|
|
322
|
+
|
|
323
|
+
In order to include images, you can use the `` syntax. The `FIG_DIR` variable will be replaced by the URL where the images are stored. PNG and SVG images are supported.
|
|
324
|
+
|
|
325
|
+
In addition, you can use a small subset of LaTeX for mathematical expressions but these have to be enclosed between `·` signs, not standard `$` signs. Take into account that math in quizzes is fragile, as it conflicts with Markdown and other features.
|
|
326
|
+
|
|
303
327
|
## Variable substitution (`.py` files)
|
|
304
328
|
|
|
305
329
|
If a question file is named `example.yml`, the toolkit looks for `example.py` in the same directory. When present:
|
|
306
330
|
|
|
307
|
-
1. The Python script is run with a given
|
|
331
|
+
1. The Python script is run with a given `seed` (passed as an argument by the toolkit) so that the run is reproducible.
|
|
308
332
|
2. The script’s global variables (that are JSON-serializable and whose names do not start with `__`) are collected.
|
|
309
333
|
3. In the question YAML, any string field that supports substitution can use `$name` or `${name}` to be replaced by the value of `name`.
|
|
310
334
|
|
|
@@ -337,11 +361,11 @@ handler: quiz
|
|
|
337
361
|
|
|
338
362
|
Other handler options (e.g. `std`, `graphic`) are for non-quiz problems. See [Problem anatomy — handler.yml](problem-anatomy.md#the-handleryml-file) for the full list of handler and option descriptions.
|
|
339
363
|
|
|
340
|
-
##
|
|
364
|
+
## Linting, running and playing quizzes
|
|
341
365
|
|
|
342
366
|
From the toolkit CLI:
|
|
343
367
|
|
|
344
|
-
-
|
|
368
|
+
- `jtk quiz lint` — lint a quiz (validate `quiz.yml` and all referenced question YAML files):
|
|
345
369
|
|
|
346
370
|
```bash
|
|
347
371
|
jtk quiz lint -d <directory>
|
|
@@ -349,12 +373,20 @@ From the toolkit CLI:
|
|
|
349
373
|
|
|
350
374
|
Use the directory that contains `quiz.yml` (e.g. the `en` subdirectory).
|
|
351
375
|
|
|
352
|
-
-
|
|
376
|
+
- `jtk quiz run` — run a quiz (build questions, apply variables, output JSON or YAML):
|
|
377
|
+
|
|
353
378
|
```bash
|
|
354
379
|
jtk quiz run -d <directory> [-s <seed>] [-f json|yaml]
|
|
355
380
|
```
|
|
381
|
+
|
|
356
382
|
If no seed is provided, a random one is used. Running the quiz applies variable substitution and, if `shuffle` is true, shuffles question order (and, per question, choices or ordering/matching items when their `shuffle` is true).
|
|
357
383
|
|
|
384
|
+
- `jtk quiz play` — play a quiz in the terminal:
|
|
385
|
+
```bash
|
|
386
|
+
jtk quiz play -d <directory> [-i <input>] [-o <output>] [-s <seed>]
|
|
387
|
+
```
|
|
388
|
+
If no seed is provided, a random one is used. Playing the quiz applies variable substitution and, if `shuffle` is true, shuffles question order (and, per question, choices or ordering/matching items when their `shuffle` is true).
|
|
389
|
+
|
|
358
390
|
## Quick checklist
|
|
359
391
|
|
|
360
392
|
- Use a problem folder with `handler: quiz` in `handler.yml`.
|
|
@@ -362,6 +394,6 @@ From the toolkit CLI:
|
|
|
362
394
|
- Ensure every `file` in `quiz.yml` has a corresponding `file.yml` in the same directory.
|
|
363
395
|
- Ensure question scores in `quiz.yml` sum to 100.
|
|
364
396
|
- For SingleChoice, set exactly one choice with `correct: true`.
|
|
365
|
-
- For FillIn with
|
|
366
|
-
- For Matching, ensure
|
|
397
|
+
- For FillIn with `options`, ensure `correct` is in the `options` list.
|
|
398
|
+
- For Matching, ensure `left` and `right` have the same length and are in matching order.
|
|
367
399
|
- Use variable names in `$name` / `${name}` that are produced by the optional `file.py` script; the script is run with the toolkit’s seed for reproducibility.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jutge.org/toolkit",
|
|
3
3
|
"description": "Toolkit to prepare problems for Jutge.org",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.20",
|
|
5
5
|
"homepage": "https://jutge.org",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Jutge.org",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"chalk": "^5.6.2",
|
|
73
73
|
"chokidar": "^5.0.0",
|
|
74
74
|
"cli-highlight": "^2.1.11",
|
|
75
|
+
"cli-table3": "^0.6.5",
|
|
75
76
|
"commander": "^14.0.3",
|
|
76
77
|
"dayjs": "^1.11.19",
|
|
77
78
|
"env-paths": "^4.0.0",
|
package/toolkit/quiz.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Command } from '@commander-js/extra-typings'
|
|
2
2
|
import { runQuiz, lintQuiz } from '../lib/quiz'
|
|
3
|
+
import {
|
|
4
|
+
loadQuizTestInput,
|
|
5
|
+
playQuiz,
|
|
6
|
+
writeQuizTestOutput,
|
|
7
|
+
} from '../lib/play-quiz'
|
|
3
8
|
import tui from '../lib/tui'
|
|
4
9
|
import { findRealDirectories } from '../lib/helpers'
|
|
5
10
|
import { random } from 'radash'
|
|
@@ -30,12 +35,11 @@ quizCmd
|
|
|
30
35
|
.command('run')
|
|
31
36
|
.summary('Run a quiz problem')
|
|
32
37
|
.description(
|
|
33
|
-
`Run a quiz problem.
|
|
38
|
+
`Run a quiz problem.
|
|
34
39
|
|
|
35
40
|
This command will run the quiz problem and print the resulting object to stdout.
|
|
36
41
|
A random seed will be generated if not provided.
|
|
37
|
-
|
|
38
|
-
)
|
|
42
|
+
`)
|
|
39
43
|
|
|
40
44
|
.option('-d, --directory <directory>', 'problem directory', '.')
|
|
41
45
|
.option('-s, --seed <seed>', 'random seed')
|
|
@@ -50,3 +54,26 @@ A random seed will be generated if not provided.
|
|
|
50
54
|
tui.yaml(object)
|
|
51
55
|
}
|
|
52
56
|
})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
quizCmd
|
|
60
|
+
.command('play')
|
|
61
|
+
.summary('Play a quiz problem')
|
|
62
|
+
.description(
|
|
63
|
+
`Play an interactive quiz test. Questions are shown in sequence; you can review and change answers before submitting.
|
|
64
|
+
Input is a JSON file from \`quiz run\`; if --input is omitted, a run is generated with a random seed from the given directory.
|
|
65
|
+
If --output is given, the results (your answers, correct answers, and score per question) are written to that file.`)
|
|
66
|
+
|
|
67
|
+
.option('-i, --input <input>', 'input JSON file from quiz run')
|
|
68
|
+
.option('-o, --output <output>', 'output file for results')
|
|
69
|
+
.option('-d, --directory <directory>', 'problem directory (used when --input is not provided)', '.')
|
|
70
|
+
.option('-s, --seed <seed>', 'random seed (used when --input is not provided)')
|
|
71
|
+
|
|
72
|
+
.action(async ({ input, output, directory, seed }) => {
|
|
73
|
+
const seedValue = seed !== undefined ? parseInt(seed, 10) : undefined
|
|
74
|
+
const quizInput = await loadQuizTestInput(input, directory, seedValue)
|
|
75
|
+
const results = await playQuiz(quizInput)
|
|
76
|
+
if (output !== undefined) {
|
|
77
|
+
await writeQuizTestOutput(output, results)
|
|
78
|
+
}
|
|
79
|
+
})
|