Exercises and Proofs#

There are two extensions for jupyterbook that enable us to add exercises and proofs in our lecture series.

These extensions provide a beautiful and clear separation from the text and offer a better reading experience.

Guiding Principles

  • Use gated syntax whenever your exercise uses:

    • executable code cells

    • any nested directives (such as math, note etc.)

  • Use :class: dropdown for solutions by default

  • [pdf] For compatibility with pdf builds, use the image directive (rather than figure directive) when inside another directive such as exercise and solution directives

Nested Directives#

When you need to include one directive inside another (such as including math, code-cell, figure, or note directives inside exercise, solution, or prf:proof directives), you have two main options:

Option 1: Tick Count Management#

Ensure the outer directive uses more ticks than any nested directive inside it. The MyST parser needs to clearly identify where each directive begins and ends.

Standard pattern:

  • Nested directive: 3 ticks (```)

  • Enclosing directive: 4 ticks (````)

````{prf:theorem}
:label: my-theorem

This theorem contains a nested math directive.

```{math}
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
```

The math directive uses 3 ticks, so the theorem uses 4 ticks.

````

Note

Multiple levels of nesting are discouraged. While technically possible with tick count management, we recommend using the gated syntax approach (Option 2) for better clarity and readability when you need complex nested structures.

Option 2: Gated Syntax (sphinx-exercise only)#

For exercise and solution directives, you can use gated syntax with start/end pairs:

```{exercise-start}
:label: my-exercise
```

Recall that $n!$ is read as "$n$ factorial" and defined as
$n! = n \times (n - 1) \times \cdots \times 2 \times 1$.

```{code-cell} python
def factorial(n):
    return 1 if n <= 1 else n * factorial(n-1)

factorial(5)
```

```{exercise-end}
```

Important

Directive Support Summary:

  • sphinx-exercise directives (exercise, solution): Support both tick count management AND gated syntax (using exercise-start/exercise-end and solution-start/solution-end)

  • sphinx-proof directives (prf:proof, prf:theorem, etc.): Only support tick count management (no gated syntax)

  • Standard MyST directives (note, warning, etc.): Only support tick count management

When to Use Each Option#

Use gated syntax when:

  • Working with exercise or solution directives

  • Including executable code cells (code-cell)

  • Including multiple nested directives

  • You want cleaner, more readable source code

Use tick count management when:

  • Working with prf: directives (proofs, theorems, etc.)

  • Working with any other standard directives

  • You have simple, single-level nesting

  • Gated syntax is not supported for your directive type

Exercises#

See also

To learn more about sphinx-exercise please read the documentation.

Here we provide a brief tutorial on using exercise admonitions in the quantecon lectures

To make an exercise you can use the exercise admonition

```{exercise}
:label: my-exercise

Recall that $n!$ is read as "$n$ factorial" and defined as
$n! = n \times (n - 1) \times \cdots \times 2 \times 1$.

There are functions to compute this in various modules, but let's
write our own version as an exercise.

In particular, write a function `factorial` such that `factorial(n)` returns $n!$
for any positive integer $n$.
```

where the label enables you to reference the exercise using ref or numref roles.

This will be rendered as

Exercise 1

Recall that \(n!\) is read as “\(n\) factorial” and defined as \(n! = n \times (n - 1) \times \cdots \times 2 \times 1\).

There are functions to compute this in various modules, but let’s write our own version as an exercise.

In particular, write a function factorial such that factorial(n) returns \(n!\) for any positive integer \(n\).

and then you can easily reference the exercise using the {ref} role (Exercise 1) or using the {numref} role (Exercise 1).

See also

There are additional configuration options available but are not frequently used in QuantEcon lectures

Each exercise admonition should be paired with a solution admonition.

The exercise extension also provides us with a useful property that enables us to convert our solutions into a dropdown paragraph.

This helps the reader to have more time to think about the questions without being tempted by the solution.

You can add this feature in class.

```{solution-start} my-exercise
:class: dropdown
:label: my-solution
```

Here's one solution.

```{code-cell} python
def factorial(n):
    k = 1
    for i in range(n):
        k = k * (i + 1)
    return k

factorial(4)
```

```{solution-end}
```

which is rendered as

The solution can be referenced using the label property using ref and numref.

The solution directive requires the label of the exercise.

Given many solutions across QuantEcon projects typically require code execution we frequently make use of the gated syntax.

Note: If a solution does not require code execution it is possible to use the primary solution admonition.

Warning

The code in this example is not executed but is syntax highlighted

````{solution} my-exercise
:label: my-solution

Here's one solution.

```{code-block} python
def factorial(n):
    k = 1
    for i in range(n):
        k = k * (i + 1)
    return k

factorial(4)
```
````

which is rendered as

Solution to Exercise 1

Here’s one solution.

def factorial(n):
    k = 1
    for i in range(n):
        k = k * (i + 1)
    return k

factorial(4)

Proofs#

There is a range of directives provided by sphinx-proof:

  1. prf:proof

  2. prf:theorem

  3. prf:axiom

  4. prf:lemma

  5. prf:definition

  6. prf:criteria

  7. prf:remark

  8. prf:conjecture

  9. prf:corollary

  10. prf:algorithm

  11. prf:example

  12. prf:property

  13. prf:observation

  14. prf:proposition

  15. prf:assumption

Note

The prf: included in each directive name is required in both the directive and when referencing the admonition such as {prf:ref}. These belong to the Sphinx prf domain that supports references and linking.

An example proof:

Tip

This package does not support the gated syntax provided by sphinx-exercise, therefore you must use the tick count management option for nested directives. See the Nested Directives section for detailed guidance and examples.

````{prf:proof}
We'll omit the full proof.

But we will prove sufficiency of the asserted conditions.

To this end, let $y \in \mathbb R^n$ and let $S$ be a linear subspace of $\mathbb R^n$.

Let $\hat y$ be a vector in $\mathbb R^n$ such that $\hat y \in S$ and $y - \hat y \perp S$.

Let $z$ be any other point in $S$ and use the fact that $S$ is a linear subspace to deduce

```{math}
\| y - z \|^2
= \| (y - \hat y) + (\hat y - z) \|^2
= \| y - \hat y \|^2  + \| \hat y - z  \|^2
```

Hence $\| y - z \| \geq \| y - \hat y \|$, which completes the proof.
```
````

will render as

Proof. We’ll omit the full proof.

But we will prove sufficiency of the asserted conditions.

To this end, let \(y \in \mathbb R^n\) and let \(S\) be a linear subspace of \(\mathbb R^n\).

Let \(\hat y\) be a vector in \(\mathbb R^n\) such that \(\hat y \in S\) and \(y - \hat y \perp S\).

Let \(z\) be any other point in \(S\) and use the fact that \(S\) is a linear subspace to deduce

\[\| y - z \|^2 = \| (y - \hat y) + (\hat y - z) \|^2 = \| y - \hat y \|^2 + \| \hat y - z \|^2\]

Hence \(\| y - z \| \geq \| y - \hat y \|\), which completes the proof.