import csv
import datetime
import urllib.request
import json
import matplotlib.pyplot as plt
import numpy as np
AWARD_DAY = 10
AWARD_MONTH = 12
CSV_FILENAME = "physics_nobel_laureates_ages_1901_2025.csv"
def parse_date(s):
parts = [int(p) for p in s.split('-')]
if len(parts) == 3:
return datetime.date(parts[0], max(1, parts[1]), max(1, parts[2]))
elif len(parts) == 2:
return datetime.date(parts[0], max(1, parts[1]), 1)
else:
return datetime.date(parts[0], 1, 1)
def age_on(dob, year):
award_date = datetime.date(year, AWARD_MONTH, AWARD_DAY)
years = award_date.year - dob.year - (
(award_date.month, award_date.day) < (dob.month, dob.day))
return years
LURL = "https://[Log in to view URL]"
with urllib.request.urlopen(LURL) as url:
data = json.loads(url.read().decode())
rows = []
for person in data.get("laureates", []):
if person.get("knownName") is None:
continue
name = person["knownName"]["en"]
birth = person.get("birth", {})
birthdate = birth.get("date")
if not birthdate:
continue
dob = parse_date(birthdate)
for prize in person.get("nobelPrizes", []):
if prize.get("category", {}).get("en") != "Physics":
continue
year = int(prize["awardYear"])
age = age_on(dob, year)
rows.append({
"year": year,
"laureate": name,
"birthdate": birthdate,
"age_on_award_date": age
})
extra_2025 = [
("John Clarke", "1942-02-10"),
("Michel H. Devoret", "1953-01-01"),
("John M. Martinis", "1958-01-01"),
]
for name, birthdate in extra_2025:
dob = parse_date(birthdate)
rows.append({
"year": 2025,
"laureate": name,
"birthdate": birthdate,
"age_on_award_date": age_on(dob, 2025),
})
seen = set()
deduped = []
for r in rows:
key = (r["year"], r["laureate"])
if key in seen:
continue
seen.add(key)
deduped.append(r)
deduped.sort(key=lambda r: (r["year"], r["laureate"]))
# --- Write to CSV ---
with open(CSV_FILENAME, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["year", "laureate", "birthdate", "age_on_award_date"])
writer.writeheader()
writer.writerows(deduped)
print(f"Wrote {len(deduped)} rows to {CSV_FILENAME}")
years = [r["year"] for r in deduped]
ages = [r["age_on_award_date"] for r in deduped]
plt.figure(figsize=(10, 8))
plt.scatter(years, ages, color='orange', label="Laureates")
slope, intercept = np.polyfit(years, ages, 1)
plt.plot(years, slope * np.array(years) + intercept, color='red',
label=f"Trend: y = {slope:.2f}x + {intercept:.1f}")
plt.title("Age of Nobel Physics Laureates (1901–2025)")
plt.xlabel("Year")
plt.ylabel("Age at Award")
plt.legend()
plt.grid(True)
plt.show()
To embed this project on your website, copy the following code and paste it into your website's HTML: