Skip to content

Commit bff06ac

Browse files
mmckyshlff
andauthored
ENH: Use sphinx-exercise for Styled Exercises and Solutions (#176)
* [functions]Migrating exercise to use sphinx-exercise * add sphinx-exercise * pull out code-cell until supported * TST: new gated directives * Enable dropdown via sphinx-togglebutton * TST: see if sphinx-togglebutton works in sphinx_book_theme * Restore quantecon-book-theme * Empty commit to trigger rebuild * Update all solutions to be hidden by default * Update for sphinx-exercise * Migrate to sphinx-exercise * migrate to sphinx-exercise * fix numpy syntax issue * fix broken label * Enable dropdown toggle for solutions * Enable dropdown toggle for solutions * move to use pypi sphinx-exercise==0.4.1 * upgrade sphinx-tojupyter==0.2.1 Co-authored-by: Shu <[email protected]>
1 parent 2d3b6a8 commit bff06ac

15 files changed

+363
-88
lines changed

environment.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ dependencies:
88
- pip:
99
- jupyter-book==0.12.1
1010
- quantecon-book-theme==0.3.0
11-
- sphinx-tojupyter==0.2.0
11+
- sphinx-tojupyter==0.2.1
1212
- sphinxext-rediraffe==0.2.7
13-
- sphinx-exercise==0.2.1
13+
- sphinx-exercise==0.4.0
14+
- sphinx-togglebutton
1415
- ghp-import==1.1.0
1516
# Temporary Fixes
1617
- networkx==2.6.3

lectures/_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ latex:
1616
targetname: quantecon-python-programming.tex
1717

1818
sphinx:
19-
extra_extensions: [sphinx_multitoc_numbering, sphinxext.rediraffe, sphinx_tojupyter]
19+
extra_extensions: [sphinx_multitoc_numbering, sphinxext.rediraffe, sphinx_tojupyter, sphinx_exercise, sphinx_togglebutton]
2020
config:
2121
html_favicon: _static/lectures-favicon.ico
2222
html_theme: quantecon_book_theme

lectures/functions.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ function*---as we did above.
313313

314314
## Exercises
315315

316-
### Exercise 1
316+
```{exercise}
317+
:label: exercise_1
317318
318319
Recall that $n!$ is read as "$n$ factorial" and defined as
319320
$n! = n \times (n - 1) \times \cdots \times 2 \times 1$.
@@ -323,17 +324,21 @@ write our own version as an exercise.
323324
324325
In particular, write a function `factorial` such that `factorial(n)` returns $n!$
325326
for any positive integer $n$.
327+
```
326328

327-
### Exercise 2
329+
```{exercise}
330+
:label: exercise_2
328331
329332
The [binomial random variable](https://en.wikipedia.org/wiki/Binomial_distribution) $Y \sim Bin(n, p)$ represents the number of successes in $n$ binary trials, where each trial succeeds with probability $p$.
330333
331334
Without any import besides `from numpy.random import uniform`, write a function
332335
`binomial_rv` such that `binomial_rv(n, p)` generates one draw of $Y$.
333336
334337
Hint: If $U$ is uniform on $(0, 1)$ and $p \in (0,1)$, then the expression `U < p` evaluates to `True` with probability $p$.
338+
```
335339

336-
### Exercise 3
340+
```{exercise}
341+
:label: exercise_3
337342
338343
First, write a function that returns one realization of the following random device
339344
@@ -346,12 +351,16 @@ Second, write another function that does the same task except that the second ru
346351
- If a head occurs `k` or more times within this sequence, pay one dollar.
347352
348353
Use no import besides `from numpy.random import uniform`.
354+
```
349355

350356
## Solutions
351357

352-
### Exercise 1
358+
```{solution-start} exercise_1
359+
:label: solution_1
360+
:class: dropdown
353361
354362
Here's one solution.
363+
```
355364

356365
```{code-cell} python3
357366
def factorial(n):
@@ -363,7 +372,13 @@ def factorial(n):
363372
factorial(4)
364373
```
365374

366-
### Exercise 2
375+
```{solution-end}
376+
```
377+
378+
```{solution-start} exercise_2
379+
:label: solution_2
380+
:class: dropdown
381+
````
367382
368383
```{code-cell} python3
369384
from numpy.random import uniform
@@ -379,9 +394,16 @@ def binomial_rv(n, p):
379394
binomial_rv(10, 0.5)
380395
```
381396

382-
### Exercise 3
397+
```{solution-end}
398+
```
399+
400+
401+
```{solution-start} exercise_3
402+
:label: solution_3
403+
:class: dropdown
383404
384405
Here's a function for the first random device.
406+
```
385407

386408
```{code-cell} python3
387409
from numpy.random import uniform
@@ -423,3 +445,5 @@ def draw_new(k): # pays if k successes in a sequence
423445
draw_new(3)
424446
```
425447

448+
```{solution-end}
449+
```

lectures/getting_started.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,9 @@ Alternatively, if you want an outstanding free text editor and don't mind a seem
468468

469469
## Exercises
470470

471-
### Exercise 1
471+
```{exercise}
472+
:label: gs_ex1
473+
```
472474

473475
If Jupyter is still running, quit by using `Ctrl-C` at the terminal where
474476
you started it.
@@ -488,8 +490,10 @@ You should now be able to run a standard Jupyter notebook session.
488490

489491
This is an alternative way to start the notebook that can also be handy.
490492

491-
(gs_ex2)=
492-
### Exercise 2
493+
494+
```{exercise-start}
495+
:label: gs_ex2
496+
```
493497

494498
```{index} single: Git
495499
```
@@ -547,3 +551,5 @@ For reading on these and other topics, try
547551
* [Pro Git Book](http://git-scm.com/book) by Scott Chacon and Ben Straub.
548552
* One of the thousands of Git tutorials on the Net.
549553

554+
```{exercise-end}
555+
```

lectures/matplotlib.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ The custom `subplots` function
278278

279279
## Exercises
280280

281-
### Exercise 1
281+
```{exercise-start}
282+
:label: mpl_ex1
283+
```
282284

283285
Plot the function
284286

@@ -296,9 +298,14 @@ The output should look like this
296298
:scale: 130
297299
```
298300

301+
```{exercise-end}
302+
```
303+
299304
## Solutions
300305

301-
### Exercise 1
306+
```{solution-start} mpl_ex1
307+
:class: dropdown
308+
```
302309

303310
Here's one solution
304311

@@ -316,3 +323,5 @@ for θ in θ_vals:
316323
plt.show()
317324
```
318325

326+
```{solution-end}
327+
```

lectures/numba.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -475,18 +475,21 @@ When Numba compiles machine code for functions, it treats global variables as co
475475

476476
## Exercises
477477

478-
(speed_ex1)=
479-
### Exercise 1
478+
```{exercise}
479+
:label: speed_ex1
480480
481481
{ref}`Previously <pbe_ex3>` we considered how to approximate $\pi$ by
482482
Monte Carlo.
483483
484484
Use the same idea here, but make the code efficient using Numba.
485485
486486
Compare speed with and without Numba when the sample size is large.
487+
```
488+
487489

488-
(speed_ex2)=
489-
### Exercise 2
490+
```{exercise-start}
491+
:label: speed_ex2
492+
```
490493

491494
In the [Introduction to Quantitative Economics with Python](https://python-intro.quantecon.org) lecture series you can
492495
learn all about finite-state Markov chains.
@@ -498,7 +501,6 @@ Suppose that the volatility of returns on an asset can be in one of two regimes
498501
The transition probabilities across states are as follows
499502

500503
```{figure} /_static/lecture_specific/sci_libs/nfs_ex1.png
501-
502504
```
503505

504506
For example, let the period length be one day, and suppose the current state is high.
@@ -523,9 +525,14 @@ Hints:
523525
* Represent the low state as 0 and the high state as 1.
524526
* If you want to store integers in a NumPy array and then apply JIT compilation, use `x = np.empty(n, dtype=np.int_)`.
525527

528+
```{exercise-end}
529+
```
530+
526531
## Solutions
527532

528-
### Exercise 1
533+
```{solution-start} speed_ex1
534+
:class: dropdown
535+
```
529536

530537
Here is one solution:
531538

@@ -561,7 +568,13 @@ If we switch off JIT compilation by removing `@njit`, the code takes around
561568
So we get a speed gain of 2 orders of magnitude--which is huge--by adding four
562569
characters.
563570

564-
### Exercise 2
571+
```{solution-end}
572+
```
573+
574+
575+
```{solution-start} speed_ex2
576+
:class: dropdown
577+
```
565578

566579
We let
567580

@@ -632,3 +645,5 @@ qe.toc()
632645

633646
This is a nice speed improvement for one line of code!
634647

648+
```{solution-end}
649+
```

lectures/numpy.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,9 @@ For a comprehensive list of what's available in NumPy see [this documentation](h
710710

711711
## Exercises
712712

713-
(np_ex1)=
714-
### Exercise 1
713+
```{exercise-start}
714+
:label: np_ex1
715+
```
715716

716717
Consider the polynomial expression
717718

@@ -729,8 +730,13 @@ Now write a new function that does the same job, but uses NumPy arrays and array
729730

730731
* Hint: Use `np.cumprod()`
731732

732-
(np_ex2)=
733-
### Exercise 2
733+
```{exercise-end}
734+
```
735+
736+
737+
```{exercise-start}
738+
:label: np_ex2
739+
```
734740

735741
Let `q` be a NumPy array of length `n` with `q.sum() == 1`.
736742

@@ -775,15 +781,20 @@ If you can, implement the functionality as a class called `DiscreteRV`, where
775781

776782
If you can, write the method so that `draw(k)` returns `k` draws from `q`.
777783

778-
(np_ex3)=
779-
### Exercise 3
784+
```{exercise-end}
785+
```
786+
787+
788+
```{exercise}
789+
:label: np_ex3
780790
781791
Recall our {ref}`earlier discussion <oop_ex1>` of the empirical cumulative distribution function.
782792
783793
Your task is to
784794
785795
1. Make the `__call__` method more efficient using NumPy.
786796
1. Add a method that plots the ECDF over $[a, b]$, where $a$ and $b$ are method parameters.
797+
```
787798

788799
## Solutions
789800

@@ -793,7 +804,9 @@ import matplotlib.pyplot as plt
793804
plt.rcParams['figure.figsize'] = (10,6)
794805
```
795806

796-
### Exercise 1
807+
```{solution-start} np_ex1
808+
:class: dropdown
809+
```
797810

798811
This code does the job
799812

@@ -817,7 +830,13 @@ q = np.poly1d(np.flip(coef))
817830
print(q(x))
818831
```
819832

820-
### Exercise 2
833+
```{solution-end}
834+
```
835+
836+
837+
```{solution-start} np_ex2
838+
:class: dropdown
839+
```
821840

822841
Here's our first pass at a solution:
823842

@@ -876,7 +895,13 @@ library](https://github.com/QuantEcon/QuantEcon.py/tree/master/quantecon)
876895
using descriptors that behaves as we desire can be found
877896
[here](https://github.com/QuantEcon/QuantEcon.py/blob/master/quantecon/discrete_rv.py).
878897

879-
### Exercise 3
898+
```{solution-end}
899+
```
900+
901+
902+
```{solution-start} np_ex3
903+
:class: dropdown
904+
```
880905

881906
An example solution is given below.
882907

@@ -962,3 +987,5 @@ F = ECDF(X)
962987
F.plot(ax)
963988
```
964989

990+
```{solution-end}
991+
```

0 commit comments

Comments
 (0)