---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
kernelspec:
  display_name: Python 3
  language: python
  name: python3
---

# Exercises and Proofs

There are two extensions for jupyterbook that enable us to add 
[exercises](https://ebp-sphinx-exercise.readthedocs.io/en/latest/) 
and [proofs](https://sphinx-proof.readthedocs.io/en/latest/) in our lecture series.

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

```{admonition} Guiding Principles
* Use [gated syntax](https://ebp-sphinx-exercise.readthedocs.io/en/latest/syntax.html#alternative-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] A LaTeX **float** nested inside a directive breaks the PDF build with `! LaTeX Error: Not in outer par mode.` So inside `exercise`, `solution`, or `prf:` directives: use the `image` directive (not `figure`) for static images, and do **not** add `mystnb: figure:` caption metadata to `{code-cell}`s (an uncaptioned cell renders fine)
```

(nested-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 (````)

`````md
````{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:

````md
```{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

```{seealso}
To learn more about [sphinx-exercise](https://ebp-sphinx-exercise.readthedocs.io/en/latest/)
please read the [documentation](https://ebp-sphinx-exercise.readthedocs.io/en/latest/). 
```

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

To make an exercise you can use the `exercise` admonition 

````md
```{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}
: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$.
```

and then you can easily reference the exercise using the `{ref}` role ({ref}`my-exercise`) or using the `{numref}` role ({numref}`my-exercise`).

```{seealso}
There are [additional configuration options available](https://ebp-sphinx-exercise.readthedocs.io/en/latest/syntax.html#exercise-directive)
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`.

````md
```{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-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}
```

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
```

`````md
````{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} my-exercise
:label: my-solution2

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)
```
````


## Proofs

There is a range of directives provided by [sphinx-proof](https://sphinx-proof.readthedocs.io/en/latest/):

1. [prf:proof](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#proofs)
2. [prf:theorem](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#theorems)
3. [prf:axiom](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#axioms)
4. [prf:lemma](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#lemmas)
5. [prf:definition](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#definitions)
6. [prf:criteria](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#criteria)
7. [prf:remark](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#remarks)
8. [prf:conjecture](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#conjectures)
9. [prf:corollary](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#corollaries)
10. [prf:algorithm](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#algorithms)
11. [prf:example](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#examples)
12. [prf:property](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#properties)
13. [prf:observation](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#observations)
14. [prf:proposition](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#propositions)
15. [prf:assumption](https://sphinx-proof.readthedocs.io/en/latest/syntax.html#assumptions)

```{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 
{ref}`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

````{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.
````

