Skip to content

Commit 93c7d68

Browse files
committed
Add Jupyter notebook download functionality
Enables users to download individual chapters and all content as .ipynb files. This allows users to run the notebooks locally in their own Jupyter environment. Changes: - Add ipynb export configuration to myst.yml - Create generate_notebooks.py script to convert all markdown files to ipynb format - Add downloads.md page with links to individual notebooks and bundled zip archive - Update CI/CD workflows to generate notebooks during build process - Add jupytext to requirements.txt for notebook conversion The script generates 30 notebooks (21 chapters, 5 appendices, 2 labs, 2 exercises) and creates a single zip file containing all notebooks for easy download.
1 parent 30bd993 commit 93c7d68

6 files changed

Lines changed: 225 additions & 0 deletions

File tree

.github/workflows/auto-merge.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ jobs:
3838
- name: Build HTML Assets (execute)
3939
run: myst build --execute --html
4040

41+
- name: Generate Jupyter Notebooks
42+
run: python generate_notebooks.py
43+
4144
- name: Merge to main
4245
if: success()
4346
run: |

.github/workflows/deploy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ jobs:
7070
retry_on: timeout
7171
command: myst build --execute --html
7272

73+
- name: Generate Jupyter Notebooks
74+
run: python generate_notebooks.py
75+
7376
- name: Generate Sitemap
7477
run: |
7578
python generate_sitemap.py

downloads.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: Download Notebooks
3+
---
4+
5+
# Download Jupyter Notebooks
6+
7+
All chapters and materials are available as Jupyter notebooks (.ipynb) that you can download and run locally on your computer.
8+
9+
## Download All Notebooks
10+
11+
Get all notebooks in a single zip file:
12+
13+
📦 [**Download All Notebooks (ZIP)**](learn_probability_notebooks.zip)
14+
15+
## Individual Notebooks
16+
17+
### Part 1 - Foundations of Probability
18+
19+
- [Chapter 1: Introduction to Probability and Python Setup](notebooks/chapter_01.ipynb)
20+
- [Chapter 2: Sample Spaces and Events](notebooks/chapter_02.ipynb)
21+
- [Chapter 3: Probability Axioms and Basic Rules](notebooks/chapter_03.ipynb)
22+
23+
### Part 2 - Conditional Probability and Independence
24+
25+
- [Chapter 4: Conditional Probability](notebooks/chapter_04.ipynb)
26+
- [Chapter 5: Independence](notebooks/chapter_05.ipynb)
27+
28+
### Part 3 - Random Variables and Distributions
29+
30+
- [Chapter 6: Discrete Random Variables](notebooks/chapter_06.ipynb)
31+
- [Chapter 7: Continuous Random Variables](notebooks/chapter_07.ipynb)
32+
- [Chapter 8: Expectation and Variance](notebooks/chapter_08.ipynb)
33+
- [Chapter 9: Important Discrete Distributions](notebooks/chapter_09.ipynb)
34+
- [Chapter 10: Important Continuous Distributions](notebooks/chapter_10.ipynb)
35+
36+
### Part 4 - Multiple Random Variables
37+
38+
- [Chapter 11: Joint Distributions](notebooks/chapter_11.ipynb)
39+
- [Chapter 12: Covariance and Correlation](notebooks/chapter_12.ipynb)
40+
- [Chapter 13: Conditional Expectation](notebooks/chapter_13.ipynb)
41+
42+
### Part 5 - Limit Theorems and Their Significance
43+
44+
- [Chapter 14: Moment Generating Functions](notebooks/chapter_14.ipynb)
45+
- [Chapter 15: The Central Limit Theorem](notebooks/chapter_15.ipynb)
46+
47+
### Part 6 - Advanced Topics and Applications
48+
49+
- [Chapter 16: Markov Chains](notebooks/chapter_16.ipynb)
50+
- [Chapter 17: Poisson Processes](notebooks/chapter_17.ipynb)
51+
- [Chapter 18: Introduction to Bayesian Statistics](notebooks/chapter_18.ipynb)
52+
- [Chapter 19: Basic Statistical Inference](notebooks/chapter_19.ipynb)
53+
- [Chapter 20: Monte Carlo Methods](notebooks/chapter_20.ipynb)
54+
- [Chapter 21: Applications and Case Studies](notebooks/chapter_21.ipynb)
55+
56+
### Exercises and Labs
57+
58+
- [Chapter 4 Exercises](notebooks/chapter_04_exercises_a.ipynb)
59+
- [Chapter 4 Lab](notebooks/chapter_04_lab.ipynb)
60+
- [Chapter 5 Lab](notebooks/chapter_05_lab.ipynb)
61+
62+
### Appendices
63+
64+
- [Appendix A: Python Programming Primer](notebooks/appendix_a.ipynb)
65+
- [Appendix B: Key Mathematical Concepts](notebooks/appendix_b.ipynb)
66+
- [Appendix C: Common Probability Distributions Reference](notebooks/appendix_c.ipynb)
67+
- [Appendix D: Solutions to Selected Exercises](notebooks/appendix_d.ipynb)
68+
- [Appendix E: Further Resources](notebooks/appendix_e.ipynb)
69+
70+
## How to Use Downloaded Notebooks
71+
72+
1. **Extract the ZIP file** (if you downloaded the complete archive)
73+
2. **Install Jupyter**: `pip install jupyter notebook`
74+
3. **Install required packages**: `pip install -r requirements.txt`
75+
4. **Launch Jupyter**: `jupyter notebook`
76+
5. **Open and run** any notebook file
77+
78+
## Requirements
79+
80+
To run these notebooks, you'll need Python 3.11+ and the following packages:
81+
82+
- jupyter-book
83+
- matplotlib
84+
- matplotlib-venn
85+
- numpy
86+
- pandas
87+
- scipy
88+
- seaborn
89+
- sympy
90+
91+
Install all requirements with:
92+
93+
```bash
94+
pip install -r requirements.txt
95+
```
96+
97+
## Alternative: Run in the Cloud
98+
99+
Don't want to install anything locally? You can also:
100+
101+
- 🚀 **Run in browser**: Most pages have an interactive JupyterLite option
102+
- ☁️ **Launch on Binder**: Click the Binder badge on any chapter to run in the cloud

generate_notebooks.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate .ipynb files from MyST Markdown notebook files.
4+
This script converts all chapter, lab, exercise, and appendix markdown files
5+
to Jupyter notebook format and creates a downloadable zip archive.
6+
"""
7+
8+
import os
9+
import shutil
10+
import zipfile
11+
from pathlib import Path
12+
import jupytext
13+
14+
def get_notebook_files():
15+
"""Get list of all markdown files that should be converted to notebooks."""
16+
notebook_files = []
17+
18+
# Chapter files
19+
for i in range(1, 22):
20+
file = f"chapter_{i:02d}.md"
21+
if os.path.exists(file):
22+
notebook_files.append(file)
23+
24+
# Lab files
25+
for lab_file in ["chapter_04_lab.md", "chapter_05_lab.md"]:
26+
if os.path.exists(lab_file):
27+
notebook_files.append(lab_file)
28+
29+
# Exercise files
30+
for exercise_file in ["chapter_04_exercises_a.md", "chapter_04_exercises_b.md"]:
31+
if os.path.exists(exercise_file):
32+
notebook_files.append(exercise_file)
33+
34+
# Appendix files
35+
for letter in ['a', 'b', 'c', 'd', 'e']:
36+
file = f"appendix_{letter}.md"
37+
if os.path.exists(file):
38+
notebook_files.append(file)
39+
40+
return notebook_files
41+
42+
def convert_md_to_ipynb(md_file, output_dir):
43+
"""Convert a single markdown file to ipynb format."""
44+
try:
45+
# Read the markdown file
46+
notebook = jupytext.read(md_file)
47+
48+
# Generate output filename
49+
output_file = output_dir / f"{Path(md_file).stem}.ipynb"
50+
51+
# Write the ipynb file
52+
jupytext.write(notebook, output_file, fmt='ipynb')
53+
54+
print(f"✓ Converted {md_file} -> {output_file}")
55+
return output_file
56+
except Exception as e:
57+
print(f"✗ Error converting {md_file}: {e}")
58+
return None
59+
60+
def create_zip_archive(notebook_dir, zip_path):
61+
"""Create a zip archive of all notebook files."""
62+
try:
63+
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
64+
for file in sorted(notebook_dir.glob("*.ipynb")):
65+
zipf.write(file, file.name)
66+
print(f" Added {file.name} to archive")
67+
print(f"✓ Created archive: {zip_path}")
68+
return True
69+
except Exception as e:
70+
print(f"✗ Error creating archive: {e}")
71+
return False
72+
73+
def main():
74+
"""Main function to generate all notebooks and archive."""
75+
print("=" * 60)
76+
print("Generating Jupyter Notebooks from MyST Markdown")
77+
print("=" * 60)
78+
79+
# Create output directory
80+
output_dir = Path("_build/html/notebooks")
81+
output_dir.mkdir(parents=True, exist_ok=True)
82+
83+
# Get all notebook files
84+
notebook_files = get_notebook_files()
85+
print(f"\nFound {len(notebook_files)} notebook files to convert\n")
86+
87+
# Convert each file
88+
converted_files = []
89+
for md_file in notebook_files:
90+
result = convert_md_to_ipynb(md_file, output_dir)
91+
if result:
92+
converted_files.append(result)
93+
94+
print(f"\n✓ Successfully converted {len(converted_files)} notebooks")
95+
96+
# Create zip archive
97+
if converted_files:
98+
print("\nCreating zip archive...")
99+
zip_path = Path("_build/html/learn_probability_notebooks.zip")
100+
create_zip_archive(output_dir, zip_path)
101+
102+
# Calculate total size
103+
total_size = sum(f.stat().st_size for f in converted_files)
104+
zip_size = zip_path.stat().st_size
105+
print(f"\nTotal notebooks size: {total_size / 1024:.1f} KB")
106+
print(f"Archive size: {zip_size / 1024:.1f} KB")
107+
108+
print("\n" + "=" * 60)
109+
print("Done!")
110+
print("=" * 60)
111+
112+
if __name__ == "__main__":
113+
main()

myst.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ project:
1616
- format: pdf
1717
template: plain_latex_book
1818
output: exports/book.pdf
19+
- format: ipynb
20+
output: exports/notebooks
1921
toc:
2022
- file: index.md
23+
- file: downloads.md
2124
- title: Part 1 - Foundations of Probability
2225
children:
2326
- file: chapter_01.md

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
jupyter-book
2+
jupytext
23
matplotlib
34
matplotlib-venn
45
numpy

0 commit comments

Comments
 (0)