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,noteetc.)
Use
:class: dropdownfor solutions by default[pdf] For compatibility with
pdfbuilds, use theimagedirective (rather thanfiguredirective) when inside another directive such asexerciseandsolutiondirectives
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 (usingexercise-start/exercise-endandsolution-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
exerciseorsolutiondirectivesIncluding 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
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)
24
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:
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
Hence \(\| y - z \| \geq \| y - \hat y \|\), which completes the proof.