Skip to content

Commit 2f06e88

Browse files
committed
further simplification
1 parent cc11104 commit 2f06e88

File tree

2 files changed

+79
-87
lines changed

2 files changed

+79
-87
lines changed

docs/source/notebooks/index.md

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Example Gallery
2-
## ANCOVA
2+
## Regression Kink Design
33
::::{grid} 1 2 3 3
44
:gutter: 3
55

6-
:::{grid-item-card} ANCOVA for pre/post treatment nonequivalent group designs
6+
:::{grid-item-card} Regression kink design with `pymc` models
77
:class-card: sd-card-h-100
8-
:img-top: ../_static/thumbnails/ancova_pymc.png
9-
:link: ancova_pymc
8+
:img-top: ../_static/thumbnails/rkink_pymc.png
9+
:link: rkink_pymc
1010
:link-type: doc
1111
:::
1212
::::
@@ -35,44 +35,50 @@
3535
:::
3636
::::
3737

38-
## Geographical lift testing
38+
## Inverse Propensity Score Weighting
3939
::::{grid} 1 2 3 3
4040
:gutter: 3
4141

42-
:::{grid-item-card} Bayesian geolift with CausalPy
42+
:::{grid-item-card} The Paradox of Propensity Scores in Bayesian Inference
4343
:class-card: sd-card-h-100
44-
:img-top: ../_static/thumbnails/geolift1.png
45-
:link: geolift1
44+
:img-top: ../_static/thumbnails/inv_prop_latent.png
45+
:link: inv_prop_latent
4646
:link-type: doc
4747
:::
48-
:::{grid-item-card} Multi-cell geolift analysis
48+
:::{grid-item-card} Inverse Propensity Score Weighting with `pymc`
4949
:class-card: sd-card-h-100
50-
:img-top: ../_static/thumbnails/multi_cell_geolift.png
51-
:link: multi_cell_geolift
50+
:img-top: ../_static/thumbnails/inv_prop_pymc.png
51+
:link: inv_prop_pymc
5252
:link-type: doc
5353
:::
5454
::::
5555

56-
## Difference in Differences
56+
## ANCOVA
5757
::::{grid} 1 2 3 3
5858
:gutter: 3
5959

60-
:::{grid-item-card} Difference in Differences with `pymc` models
60+
:::{grid-item-card} ANCOVA for pre/post treatment nonequivalent group designs
6161
:class-card: sd-card-h-100
62-
:img-top: ../_static/thumbnails/did_pymc.png
63-
:link: did_pymc
62+
:img-top: ../_static/thumbnails/ancova_pymc.png
63+
:link: ancova_pymc
6464
:link-type: doc
6565
:::
66-
:::{grid-item-card} Banking dataset with a `pymc` model
66+
::::
67+
68+
## Instrumental Variables Regression
69+
::::{grid} 1 2 3 3
70+
:gutter: 3
71+
72+
:::{grid-item-card} Instrumental Variable Modelling (IV) with `pymc` models
6773
:class-card: sd-card-h-100
68-
:img-top: ../_static/thumbnails/did_pymc_banks.png
69-
:link: did_pymc_banks
74+
:img-top: ../_static/thumbnails/iv_pymc.png
75+
:link: iv_pymc
7076
:link-type: doc
7177
:::
72-
:::{grid-item-card} Difference in Differences with scikit-learn models
78+
:::{grid-item-card} Instrumental Regression and Justifying Instruments with `pymc`
7379
:class-card: sd-card-h-100
74-
:img-top: ../_static/thumbnails/did_skl.png
75-
:link: did_skl
80+
:img-top: ../_static/thumbnails/iv_weak_instruments.png
81+
:link: iv_weak_instruments
7682
:link-type: doc
7783
:::
7884
::::
@@ -101,6 +107,30 @@
101107
:::
102108
::::
103109

110+
## Difference in Differences
111+
::::{grid} 1 2 3 3
112+
:gutter: 3
113+
114+
:::{grid-item-card} Difference in Differences with `pymc` models
115+
:class-card: sd-card-h-100
116+
:img-top: ../_static/thumbnails/did_pymc.png
117+
:link: did_pymc
118+
:link-type: doc
119+
:::
120+
:::{grid-item-card} Banking dataset with a `pymc` model
121+
:class-card: sd-card-h-100
122+
:img-top: ../_static/thumbnails/did_pymc_banks.png
123+
:link: did_pymc_banks
124+
:link-type: doc
125+
:::
126+
:::{grid-item-card} Difference in Differences with scikit-learn models
127+
:class-card: sd-card-h-100
128+
:img-top: ../_static/thumbnails/did_skl.png
129+
:link: did_skl
130+
:link-type: doc
131+
:::
132+
::::
133+
104134
## Regression Discontinuity
105135
::::{grid} 1 2 3 3
106136
:gutter: 3
@@ -131,50 +161,20 @@
131161
:::
132162
::::
133163

134-
## Regression Kink Design
135-
::::{grid} 1 2 3 3
136-
:gutter: 3
137-
138-
:::{grid-item-card} Regression kink design with `pymc` models
139-
:class-card: sd-card-h-100
140-
:img-top: ../_static/thumbnails/rkink_pymc.png
141-
:link: rkink_pymc
142-
:link-type: doc
143-
:::
144-
::::
145-
146-
## Instrumental Variables Regression
147-
::::{grid} 1 2 3 3
148-
:gutter: 3
149-
150-
:::{grid-item-card} Instrumental Variable Modelling (IV) with `pymc` models
151-
:class-card: sd-card-h-100
152-
:img-top: ../_static/thumbnails/iv_pymc.png
153-
:link: iv_pymc
154-
:link-type: doc
155-
:::
156-
:::{grid-item-card} Instrumental Regression and Justifying Instruments with `pymc`
157-
:class-card: sd-card-h-100
158-
:img-top: ../_static/thumbnails/iv_weak_instruments.png
159-
:link: iv_weak_instruments
160-
:link-type: doc
161-
:::
162-
::::
163-
164-
## Inverse Propensity Score Weighting
164+
## Geographical lift testing
165165
::::{grid} 1 2 3 3
166166
:gutter: 3
167167

168-
:::{grid-item-card} The Paradox of Propensity Scores in Bayesian Inference
168+
:::{grid-item-card} Bayesian geolift with CausalPy
169169
:class-card: sd-card-h-100
170-
:img-top: ../_static/thumbnails/inv_prop_latent.png
171-
:link: inv_prop_latent
170+
:img-top: ../_static/thumbnails/geolift1.png
171+
:link: geolift1
172172
:link-type: doc
173173
:::
174-
:::{grid-item-card} Inverse Propensity Score Weighting with `pymc`
174+
:::{grid-item-card} Multi-cell geolift analysis
175175
:class-card: sd-card-h-100
176-
:img-top: ../_static/thumbnails/inv_prop_pymc.png
177-
:link: inv_prop_pymc
176+
:img-top: ../_static/thumbnails/multi_cell_geolift.png
177+
:link: multi_cell_geolift
178178
:link-type: doc
179179
:::
180180
::::

scripts/generate_gallery.py

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"""
99

1010
import base64
11+
import io
1112
import re
1213
import sys
1314
from pathlib import Path
@@ -41,27 +42,23 @@ def load_categories_from_index(index_path: Path) -> dict[str, list[str]]:
4142
dict[str, list[str]]
4243
Mapping from category name to list of notebook names (without .ipynb)
4344
"""
44-
categories: dict[str, list[str]] = {}
45-
current_category = None
46-
4745
if not index_path.exists():
48-
return categories
46+
return {}
4947

5048
try:
51-
with open(index_path, "r", encoding="utf-8") as f:
52-
for line in f:
53-
# Check for category header (## Category Name)
54-
if line.startswith("## "):
55-
current_category = line[3:].strip()
56-
if current_category and current_category != "Example Gallery":
57-
categories[current_category] = []
58-
# Check for notebook links under current category
59-
elif current_category and (match := re.search(r":link:\s+(\S+)", line)):
60-
categories[current_category].append(match.group(1))
49+
categories: dict[str, list[str]] = {}
50+
current_category = None
51+
for line in index_path.read_text(encoding="utf-8").splitlines():
52+
if line.startswith("## "):
53+
current_category = line[3:].strip()
54+
if current_category and current_category != "Example Gallery":
55+
categories[current_category] = []
56+
elif current_category and (match := re.search(r":link:\s+(\S+)", line)):
57+
categories[current_category].append(match.group(1))
58+
return categories
6159
except Exception as e:
6260
print(f"Warning: Could not load categories from {index_path}: {e}")
63-
64-
return categories
61+
return {}
6562

6663

6764
def get_notebook_category(filename: str, category_mapping: dict[str, list[str]]) -> str:
@@ -79,8 +76,7 @@ def get_notebook_category(filename: str, category_mapping: dict[str, list[str]])
7976

8077
def extract_metadata(notebook_path: Path) -> str:
8178
"""Extract title from notebook."""
82-
with open(notebook_path, "r", encoding="utf-8") as f:
83-
nb = nbformat.read(f, as_version=4)
79+
nb = nbformat.reads(notebook_path.read_text(encoding="utf-8"), as_version=4)
8480

8581
# Look for title in first markdown cell
8682
for cell in nb.cells:
@@ -109,8 +105,7 @@ def extract_first_image(notebook_path: Path, output_dir: Path) -> str | None:
109105
return None
110106

111107
try:
112-
with open(notebook_path, "r", encoding="utf-8") as f:
113-
nb = nbformat.read(f, as_version=4)
108+
nb = nbformat.reads(notebook_path.read_text(encoding="utf-8"), as_version=4)
114109

115110
# Try to find images in existing outputs first
116111
if image_data := _find_image_in_notebook(nb):
@@ -145,15 +140,12 @@ def _save_thumbnail(
145140
thumbnail_name = f"{notebook_path.stem}.png"
146141
thumbnail_path = output_dir / thumbnail_name
147142

148-
# Decode and save image
149-
thumbnail_path.write_bytes(base64.b64decode(image_data))
150-
151-
# Resize to uniform size (400x250) with padding
152-
img = Image.open(thumbnail_path)
143+
# Decode and process image in memory
144+
img = Image.open(io.BytesIO(base64.b64decode(image_data)))
153145
target_size = (400, 250)
154146
img.thumbnail(target_size, Image.Resampling.LANCZOS)
155147

156-
# Create padded image
148+
# Create padded image and save
157149
new_img = Image.new("RGB", target_size, (255, 255, 255))
158150
new_img.paste(
159151
img,
@@ -179,9 +171,9 @@ def generate_gallery_markdown(
179171
categories.setdefault(nb_data["category"], []).append(nb_data)
180172

181173
# Sort categories maintaining order from index.md
182-
sorted_categories = [
183-
cat for cat in category_mapping.keys() if cat in categories
184-
] + [cat for cat in categories.keys() if cat not in category_mapping]
174+
sorted_categories = list(category_mapping.keys() & categories.keys()) + list(
175+
categories.keys() - category_mapping.keys()
176+
)
185177

186178
# Generate markdown
187179
lines = ["# Example Gallery\n"]

0 commit comments

Comments
 (0)