An undergraduate lecture series on the foundations of computational economics, designed and written by Thomas J. Sargent and John Stachurski.
- Original live site: https://intro.quantecon.org/
- Customized live site https://cmg777.github.io/lecture-python-intro/
The lectures cover topics from economic data analysis and supply-demand models through linear and nonlinear dynamics, probability, optimization, and estimation — all using Python. Each lecture is a MyST Markdown file that contains executable Python code, mathematical notation, and narrative text, built into a website using Jupyter Book.
- A First Course in Quantitative Economics with Python
lecture-python-intro/
├── environment.yml # Conda environment specification
├── README.md # This file
├── .github/workflows/ # CI/CD pipelines (build, publish, link check)
├── lectures/
│ ├── _config.yml # Jupyter Book configuration
│ ├── _toc.yml # Table of contents (defines lecture order)
│ ├── _static/
│ │ ├── quant-econ.bib # BibTeX bibliography
│ │ ├── lecture_specific/ # Images and data used by specific lectures
│ │ └── *.png, *.ico # Logos and favicons
│ ├── datasets/ # Data files used across lectures
│ ├── intro.md # Landing page
│ └── *.md # 50 lecture files (MyST Markdown)
└── _notebook_repo/ # Supporting notebook repository config
Key files:
lectures/_config.yml— Jupyter Book settings: theme, execution mode (cache), Sphinx extensions, intersphinx mappings, MathJax macros, and deployment metadata.lectures/_toc.yml— Defines the 13 parts of the lecture series and the order of lectures within each part.environment.yml— Conda environment specification with Python version and all pip-installed build tools.lectures/_static/quant-econ.bib— Bibliography entries referenced by lectures via{cite}directives.
| Requirement | Notes |
|---|---|
| Conda | Anaconda or Miniforge |
| Python 3.13 | Installed automatically by the conda environment |
| Git | For cloning the repository and version control |
| xelatex (optional) | Only required for PDF builds; install via texlive-xetex |
If you use the full Anaconda distribution, the environment file will resolve directly:
conda env create -f environment.yml
conda activate quanteconThis installs Python 3.13, the Anaconda metapackage (which bundles NumPy, SciPy, Matplotlib, Pandas, and other scientific packages), and all pip-based build tools (Jupyter Book, Sphinx extensions, etc.).
The anaconda=2025.12 metapackage in environment.yml is not available on conda-forge. If you use Miniforge or Miniconda, create the environment manually:
conda create -n quantecon python=3.13 pip -y
conda activate quanteconInstall the build tools:
pip install jupyter-book==1.0.4post1 quantecon-book-theme==0.15.1 \
sphinx-tojupyter==0.6.0 sphinxext-rediraffe==0.3.0 \
sphinx-exercise==1.2.1 sphinx-proof==0.3.0 \
sphinxcontrib-youtube==1.4.1 sphinx-togglebutton==0.3.2 \
sphinx-reredirects==1.1.0Install the scientific computing packages needed to execute lecture notebooks. Install numba via conda first (pip builds from source can fail on some platforms), then the rest via pip:
conda install -n quantecon -c conda-forge numba -y
pip install numpy matplotlib scipy pandas quantecon networkx sympy \
statsmodels openpyxl xlrdpython --version # Should show Python 3.13.x
jb --version # Should show jupyter-book 1.0.4.post1
python -c "import numpy" # Should succeed without errorsAll build commands should be run from the repository root with the quantecon environment activated.
Build HTML:
jb build lecturesThe output is written to lectures/_build/html/. Open lectures/_build/html/index.html in a browser to preview.
Build PDF (requires xelatex):
jb build lectures --builder=pdflatexClean the build cache (useful when notebooks need to be re-executed from scratch):
jb clean lectures --allThe first build takes longer because every notebook is executed and cached. Subsequent builds reuse the cache and only re-execute changed notebooks.
Lectures are written in MyST Markdown — an extended markdown syntax that supports executable code cells, LaTeX math, cross-references, and Sphinx directives. Each .md file begins with a YAML frontmatter block:
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.17.1
kernelspec:
name: python3
display_name: Python 3 (ipykernel)
language: python
---After the frontmatter, a typical lecture includes:
- Reference label —
(lecture-name)=enables cross-referencing from other lectures - Title —
# Lecture Title - Narrative text — standard markdown with LaTeX math (
$...$and$$...$$) - Code cells — fenced with
```{code-cell} ipython3and``` - Directives —
{exercise},{solution},{prf:theorem},{note}, etc. - Citations —
{cite}`bibtex-key`referencingquant-econ.bib
Example code cell:
```{code-cell} ipython3
import matplotlib.pyplot as plt
import numpy as np
```
Code cells can include tags for display control:
```{code-cell} ipython3
:tags: [hide-output]
# This cell's output is hidden by default
```
-
Create the lecture file. Add a new
.mdfile in thelectures/directory with the standard frontmatter (copy from an existing lecture likesolow.md). -
Add a reference label. Place
(your-lecture-name)=on the line before the title so other lectures can link to it. -
Register it in the table of contents. Edit
lectures/_toc.ymland add- file: your-lecture-nameunder the appropriate part:- caption: Section Name numbered: true chapters: - file: existing_lecture - file: your_new_lecture # Add here
-
Add bibliography entries. If your lecture cites references, add BibTeX entries to
lectures/_static/quant-econ.bib. -
Add static assets. If your lecture uses images or data files, place them in
lectures/_static/lecture_specific/your_lecture_name/orlectures/datasets/. -
Build and verify. Run
jb build lecturesand check that your lecture renders correctly, all code cells execute, and cross-references resolve.
-
Edit content directly in the
.mdfile — change text, code, or math as needed. -
Re-execute a single lecture by clearing its cache and rebuilding:
jb clean lectures --all jb build lectures
Alternatively, delete the specific cached notebook from
lectures/_build/.jupyter_cache/and rebuild. -
Test code changes by running the lecture as a Jupyter notebook. You can convert it with Jupytext:
jupytext --to notebook lectures/your_lecture.md jupyter notebook lectures/your_lecture.ipynb
Please read the QuantEcon Operations Manual for the full style reference. Below is a summary of the most important conventions.
- Keep content clear and concise; when choosing between options, prefer the simplest approach
- Use bold for definitions and technical terms, italics for emphasis
- Lecture titles: capitalize all major words (e.g., "How it Works: Data, Variables and Names")
- Section headings: capitalize only the first word and proper nouns
- Follow PEP8; capital letters are acceptable for matrices to match mathematical notation
- Use Unicode Greek letters in code (
α,β,γ,σ,θ) instead of spelled-out names - Surround operators with spaces (
a * b), but not powers (a**b) - Use
qe.Timer()context manager for performance timing andqe.timeit()for benchmarking - Install non-Anaconda packages at the top of the lecture
- Use UTF-8 unicode characters (α, β, γ) in narrative text; use LaTeX commands (
\alpha,\beta) inside math environments ($,$$) - Transpose notation:
\top(e.g.,$A^\top$) - Matrices: always use
\begin{bmatrix}...\end{bmatrix}with square brackets; never bold matrices or vectors - Sequences:
\{ x_t \}_{t=0}^{\infty} - Multi-line equations: use
\begin{aligned}...\end{aligned}within$$blocks
- No embedded titles in figures (avoid
ax.set_title) - Captions: lowercase (~5-6 words); axis labels: lowercase
- Use
lw=2for all line charts - Keep the default matplotlib box around figures; do not hide spines
- Prefer code-generated figures over static image files
- Use gated syntax (
exercise-start/exercise-end) for exercises containing executable code - Solutions should use the dropdown class by default
- Proof directives require the
prf:prefix (e.g.,prf:theorem,prf:definition)
- Standard citation:
{cite}`bibtex-label`; in-text citation:{cite:t}`bibtex-label` - Add new BibTeX entries to
lectures/_static/quant-econ.bib - Internal links:
[link text](filename)or[](filename)for auto-title - Cross-series links:
{doc}`series:page_name`(requires intersphinx config in_config.yml)
The repository uses five GitHub Actions workflows in .github/workflows/:
| Workflow | Trigger | Purpose |
|---|---|---|
| ci.yml | Pull requests | Builds HTML, PDF, and notebooks; deploys a Netlify preview |
| publish.yml | publish* tags |
Builds and deploys to GitHub Pages at intro.quantecon.org |
| collab.yml | Pull requests | Tests execution in a Google Colab environment |
| cache.yml | Weekly (Monday 3am UTC) | Pre-builds and caches notebooks for faster CI runs |
| linkcheck.yml | Weekly (Sunday 11pm UTC) | Checks for broken links and opens issues if found |
All CI builds run on Ubuntu with Python 3.13, the full texlive suite, and a 10-minute per-notebook execution timeout.
- Fork the repository and create a feature branch
- Make your changes following the style guide
- Build locally to verify (
jb build lectures) - Open a pull request with a detailed description
- Use checkboxes for multi-task PRs
- Link related issues; use
fixes #numberto auto-close on merge
- Mark the PR as Draft until it is ready for review
- Once reviewed and approved, apply the
readytag for merging
CI will automatically build a preview of your changes on Netlify.
This is one of several lecture series in the QuantEcon ecosystem:
| Series | URL |
|---|---|
| Quantitative Economics with Python (Intermediate) | https://python.quantecon.org/ |
| Python Programming for Economics and Finance | https://python-programming.quantecon.org/ |
| Dynamic Linear Economies | https://dle.quantecon.org/ |
| Dynamic Programming Squared | https://dps.quantecon.org/ |
| Equilibrium Models | https://eqm.quantecon.org/ |
| Quantitative Economics with Data | https://stats.quantecon.org/ |
| Tools and Techniques | https://tools-techniques.quantecon.org/ |
| Economic Dynamics | https://dynamics.quantecon.org/ |
Cross-references between series are supported via intersphinx. See the intersphinx_mapping section in lectures/_config.yml for the configuration.