Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions source/npm/qsharp/ux/qdk-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ body[data-vscode-theme-kind="vscode-high-contrast-light"] {
--qdk-atom-fill: #0078d4;
--qdk-atom-trail: #fa0;

/* Use to mark a self-check question. The chemistry tutorial styles its
collapsible questions with this burnt orange, so anything that asks the
reader something should share it. Paired with a foreground because the
accent is a filled band: the two must be picked together to stay legible,
and which one is the dark half flips between light and dark themes. */
--qdk-quiz-accent: #8c4a00;
--qdk-quiz-accent-foreground: #ffffff;

/* Circuit diagram: unitary gate box colors */
--qdk-circuit-unitary-fill: #ffffff;
--qdk-circuit-unitary-text: #3b3b3b;
Expand Down Expand Up @@ -193,6 +201,11 @@ body[data-vscode-theme-kind="vscode-high-contrast"] {
--qdk-atom-fill: #9df;
--qdk-atom-trail: #fa0;

/* Same hue as the light theme's quiz accent, lightened until it separates
from a dark editor background; the band's text goes dark to match. */
--qdk-quiz-accent: #e0a15e;
--qdk-quiz-accent-foreground: #2b1a05;

/* Chord diagram: 3-stop colormaps (low → mid → high) */
--qdk-chord-node-lo: #3a3a3a;
--qdk-chord-node-mid: #e04040;
Expand Down
76 changes: 76 additions & 0 deletions source/vscode/authoring-courses.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,82 @@ Use `register_exercise(name, validate, ...)` when a unit needs its own checking;
When validation fails, `_course_lib` shows the message and raises, so the cell errors out.
Once the cell runs successfully, the exercise will be considered to be complete.

## Quizzes

A quiz is a multiple-choice question the learner answers in the cell output.
Unlike an exercise, it is a self-check: answering doesn't record progress, so a quiz is a place to think rather than something to complete.

Register the question in the unit's `_unit.py`, next to the exercise registrations:

```python
from _learning_output import quiz, register_quiz # noqa: E402, F401

register_quiz(
"grid-spacing",
"Which control changes the energy-grid spacing?",
[
("bits", "The number of phase bits", True, "It sets how finely the interval is discretized."),
("shots", "The number of shots per bit", False, "More shots stabilize each bit; spacing is untouched."),
("space", "The size of the active space", False, "That changes the Hamiltonian itself."),
],
)
```

Each option is `(id, text, correct, explanation)`.
The explanation is shown after the learner commits to a choice, so write it as the reason that option is right or wrong rather than as a hint.
A single-select question needs exactly one correct option, and ids must be unique; anything else raises when the cell runs, so mistakes surface while you're authoring.

For a question with several right answers, pass `multi_select=True`:

```python
register_quiz(
"ancilla-traits",
"Which of these are true of the readout ancilla?",
[
("h-gates", "It receives the H gates and the feedback rotation", True, "That is what puts it in superposition."),
("controls", "It controls the Hamiltonian evolution", True, "The controlled-unitary hangs off this wire."),
("state", "It holds the prepared molecular state", False, "The compute register does that."),
],
multi_select=True,
)
```

The learner then gets checkboxes and an explicit "Select all that apply", and has to find every correct option to pass.
A multi-select question needs at least two correct options and at least one incorrect one — a "select all that apply" with a single answer teaches learners to distrust the instruction, and one where everything applies can't be answered wrongly.

Options are shuffled, seeded from the quiz id.
It's natural to write the correct answer first, which would otherwise make "always pick A" a winning strategy across a unit.
The order is stable, so re-running the notebook doesn't reshuffle or produce a spurious diff.

The notebook cell then just names the quiz, and is tagged `quiz` the same way exercise cells are tagged:

```python
quiz("grid-spacing")
```

The tag keeps the cell out of the progress tree, and lets the cell below it still find the section heading above.
One call can name several quizzes (`quiz("a", "b")`) when a section asks two questions in a row - the progress tree names a code cell after the heading above it, so two adjacent quiz cells would appear under the same name.

Quiz ids and option ids are lowercase letters, digits and hyphens, up to 64 characters.
Registering one that isn't fails when you run the cell: those ids are the only thing the renderer's Copilot action sends to the extension, so a shape it can't accept would leave that button doing less than it should.

A question needs text, and so does every option.
The renderer refuses to draw a payload missing either, so registering one fails when you run the cell rather than baking cleanly and showing a learner an error.

Run the cell once and save, so the question ships with the notebook and a learner sees it on opening rather than after running.

For the chemistry course, `utils/chemistry-qpe/details_to_quiz.py` does that baking for a whole chapter, and re-bakes it when a question's wording or options change:

```
python details_to_quiz.py 06-iterative-phase-estimation --check # report drift, write nothing
python details_to_quiz.py 06-iterative-phase-estimation # re-bake what changed
```

`--check` is what catches a `_unit.py` edit that never reached the notebook, including a question deleted from a cell that still shows it.

The answers are in the saved cell output, because grading happens in the renderer without a kernel.
This keeps them out of the cell source the learner reads, which is the same protection the collapsible-answer style gave; it isn't a guarantee against a determined learner opening the `.ipynb`.

## Editing a published course

Progress is tracked per cell, using the notebook's nbformat cell IDs.
Expand Down
Loading