Make a presentation of a air pollution pathogenesis for community medicine
mkdir -p /tmp/workspace/air-pollution-pptx && ls /tmp/workspace/air-pollution-pptx/
~/air-pollution-pptx/build_pptx.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import copy
# ─── COLOUR PALETTE ───────────────────────────────────────────────────────────
C_NAVY = RGBColor(0x1A, 0x37, 0x5E) # dark navy
C_TEAL = RGBColor(0x00, 0x8B, 0x8B) # dark teal
C_ORANGE = RGBColor(0xE8, 0x6B, 0x1A) # accent orange
C_LTBLUE = RGBColor(0xD6, 0xE8, 0xF5) # light blue fill
C_LTGRAY = RGBColor(0xF2, 0xF4, 0xF7) # light gray bg
C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
C_DARK = RGBColor(0x1E, 0x1E, 0x2E) # near-black text
C_GREEN = RGBColor(0x21, 0x7A, 0x3C) # green
C_RED = RGBColor(0xC0, 0x39, 0x2B) # red
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ─── HELPER FUNCTIONS ─────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_rgb=None, line_rgb=None, line_width_pt=0):
from pptx.util import Pt
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
Inches(x), Inches(y), Inches(w), Inches(h)
)
fill = shape.fill
if fill_rgb:
fill.solid()
fill.fore_color.rgb = fill_rgb
else:
fill.background()
line = shape.line
if line_rgb:
line.color.rgb = line_rgb
line.width = Pt(line_width_pt)
else:
line.fill.background()
return shape
def add_textbox(slide, x, y, w, h, text, fontsize=18, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, wrap=True, italic=False, font_name="Calibri"):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.margin_left = Pt(0)
tf.margin_right = Pt(0)
tf.margin_top = Pt(0)
tf.margin_bottom = Pt(0)
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(fontsize)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tb
def add_bullet_textbox(slide, x, y, w, h, items, fontsize=14, title=None,
title_size=16, title_color=C_NAVY, bullet_color=C_DARK,
bg=None, padding=0.12, line_spacing=1.2):
"""Add a box with optional title and bullet list."""
if bg:
add_rect(slide, x, y, w, h, fill_rgb=bg)
tb = slide.shapes.add_textbox(
Inches(x + padding), Inches(y + padding),
Inches(w - 2*padding), Inches(h - 2*padding)
)
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = Pt(2)
tf.margin_right = Pt(2)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
first = True
if title:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
r = p.add_run()
r.text = title
r.font.name = "Calibri"
r.font.bold = True
r.font.size = Pt(title_size)
r.font.color.rgb = title_color
p.alignment = PP_ALIGN.LEFT
for item in items:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
p.alignment = PP_ALIGN.LEFT
from pptx.oxml.ns import qn
from lxml import etree
pPr = p._pPr if p._pPr is not None else p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '●')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(fontsize)
r.font.color.rgb = bullet_color
return tb
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — TITLE SLIDE
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
# Full-bleed navy background
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_NAVY)
# Teal accent bar left
add_rect(slide, 0, 0, 0.4, 7.5, fill_rgb=C_TEAL)
# Orange accent stripe
add_rect(slide, 0.4, 3.05, 12.933, 0.08, fill_rgb=C_ORANGE)
# Subtitle label
add_textbox(slide, 0.7, 1.2, 12, 0.7,
"COMMUNITY MEDICINE SEMINAR SERIES",
fontsize=14, bold=False, color=C_ORANGE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Main title
add_textbox(slide, 0.7, 1.9, 12, 1.5,
"AIR POLLUTION:",
fontsize=52, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 0.7, 3.2, 12, 1.1,
"Pathogenesis & Health Impact",
fontsize=38, bold=False, color=C_LTBLUE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Divider line
add_rect(slide, 0.7, 4.45, 4.0, 0.04, fill_rgb=C_ORANGE)
# Tagline
add_textbox(slide, 0.7, 4.6, 12, 0.5,
"Sources ● Pollutants ● Mechanisms ● Disease Burden ● Prevention",
fontsize=13, bold=False, color=RGBColor(0xA8, 0xC4, 0xE0),
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 0.7, 5.4, 12, 0.4,
"Based on Park's Textbook of Preventive & Social Medicine | Murray & Nadel's Respiratory Medicine",
fontsize=11, bold=False, color=RGBColor(0x80, 0xA0, 0xC0),
align=PP_ALIGN.LEFT, font_name="Calibri")
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — DEFINITION & OVERVIEW
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"DEFINITION & OVERVIEW",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Definition box
add_rect(slide, 0.4, 1.3, 12.5, 1.5, fill_rgb=C_NAVY, line_rgb=C_TEAL, line_width_pt=1.5)
add_textbox(slide, 0.55, 1.35, 12.2, 1.4,
"\"Air pollution signifies the presence in the ambient atmosphere of substances — gases, "
"mixtures of gases and particulate matter — generated by human activities in concentrations "
"that interfere with human health, safety or comfort, or injurious to vegetation, animals "
"and other environmental media.\"",
fontsize=13, bold=False, color=C_WHITE, italic=True,
align=PP_ALIGN.LEFT, font_name="Calibri")
# 3 columns
cols = [
("Primary\nPollutants", "Emitted directly from sources: factory chimneys, exhaust pipes, wind-suspended dust", C_TEAL),
("Secondary\nPollutants", "Formed within the atmosphere via chemical reactions (e.g. Ozone from NOx + hydrocarbons in sunlight)", C_ORANGE),
("Particulate\nMatter (PM)", "Solid/liquid particles suspended in air. PM2.5 (<2.5 μm) most hazardous — penetrates deep alveoli", C_GREEN),
]
for i, (title, body, col) in enumerate(cols):
xpos = 0.4 + i * 4.3
add_rect(slide, xpos, 3.0, 4.1, 3.8, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
add_rect(slide, xpos, 3.0, 4.1, 0.55, fill_rgb=col)
add_textbox(slide, xpos+0.1, 3.03, 3.9, 0.5, title,
fontsize=14, bold=True, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_textbox(slide, xpos+0.15, 3.65, 3.8, 3.0, body,
fontsize=13, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Page number
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "2", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — SOURCES OF AIR POLLUTION
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_ORANGE)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"SOURCES OF AIR POLLUTION",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
sources = [
("🚗 Automobiles", "Motor vehicles emit hydrocarbons, CO, lead, NOx & PM.\nDiesel engines produce black smoke & malodorous fumes.\nIn sunlight, NOx + hydrocarbons → photochemical smog (ozone)", C_ORANGE),
("🏭 Industries", "Combustion of fuel → smoke, SO₂, NOx, fly ash.\nPetrochemical: HF, HCl, organic halides.\nReleased from high chimneys at high temperature.", C_NAVY),
("🏠 Domestic", "Coal, wood, biomass burning → smoke, CO, SO₂.\nMajor source in developing countries / rural areas.\nCooking fires: indoor PM2.5 levels far exceed outdoor.", C_TEAL),
("🌱 Natural", "Volcanic eruptions, dust storms, forest fires, pollen.\nContribute to background PM & SO₂ levels.\nOften exacerbated by human land-use changes.", C_GREEN),
("☢️ Radioactive", "Radon gas from soil/rocks, nuclear facilities.\nBeta/gamma-emitting particles from fallout.\nIndoor accumulation in poorly ventilated buildings.", C_RED),
("🌾 Agricultural", "Ammonia from fertilizers & livestock → PM2.5.\nPesticide spraying releases VOCs.\nCrop residue burning — major seasonal PM spike.", RGBColor(0x80, 0x40, 0x10)),
]
for i, (title, body, col) in enumerate(sources):
row, c = divmod(i, 3)
xpos = 0.3 + c * 4.35
ypos = 1.3 + row * 2.9
add_rect(slide, xpos, ypos, 4.1, 2.6, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
add_rect(slide, xpos, ypos, 4.1, 0.5, fill_rgb=col)
add_textbox(slide, xpos+0.1, ypos+0.04, 3.9, 0.45, title,
fontsize=13, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, xpos+0.12, ypos+0.58, 3.85, 1.9, body,
fontsize=11.5, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "3", fontsize=10, color=C_ORANGE, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — KEY POLLUTANTS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"KEY AIR POLLUTANTS & THEIR EFFECTS",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
pollutants = [
("SO₂\nSulphur Dioxide", "Combustion of fossil fuels.\nForms H₂SO₄ (acid rain).\nBronchospasm, mucus hypersecretion.", C_RED),
("NO₂\nNitrogen Dioxide", "Vehicle exhaust, power plants.\nPrecursor to ozone & smog.\nAirway inflammation, reduced lung function.", C_ORANGE),
("CO\nCarbon Monoxide", "Incomplete combustion.\nBinds Hb (COHb) — tissue hypoxia.\nCNS effects, cardiac ischaemia.", C_NAVY),
("O₃\nOzone", "Secondary pollutant from NOx + HC.\nOxidant — damages airway epithelium.\nExacerbates asthma/COPD.", C_TEAL),
("PM2.5\nFine Particles", "Deep alveolar deposition.\nSystemic inflammation, oxidative stress.\nCardiovascular & lung cancer risk.", C_RED),
("Pb Lead", "Leaded petrol, paint, smelters.\nNeurotoxic — IQ loss in children.\nCritical route: air → food chain.", RGBColor(0x55, 0x00, 0x88)),
("Benzene\n& VOCs", "Petrol vapour, paints, solvents.\nCarcinogenic — leukaemia risk.\nMucous membrane irritants.", RGBColor(0x80, 0x40, 0x00)),
("Radon", "Soil/rock decay (U-238).\nIndoor accumulation in basements.\nLeading cause of lung cancer in non-smokers.", C_GREEN),
]
for i, (pollutant, detail, col) in enumerate(pollutants):
row, c = divmod(i, 4)
xpos = 0.25 + c * 3.26
ypos = 1.28 + row * 2.88
add_rect(slide, xpos, ypos, 3.1, 2.6, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=1.5)
add_rect(slide, xpos, ypos, 3.1, 0.68, fill_rgb=col)
add_textbox(slide, xpos+0.08, ypos+0.05, 2.95, 0.6, pollutant,
fontsize=12, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, xpos+0.1, ypos+0.72, 2.9, 1.8, detail,
fontsize=11, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "4", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — PATHOGENESIS (MECHANISTIC OVERVIEW)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_RED)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"PATHOGENESIS — MECHANISTIC OVERVIEW",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Flow diagram — horizontal cascade
steps = [
("INHALATION\nEXPOSURE", "Gases, PM2.5,\nOzone, SO₂,\nNO₂", C_NAVY),
("DEPOSITION\nIN AIRWAY", "Upper tract:\nwater-soluble gases\nAlveoli: PM <2.5μm", C_TEAL),
("OXIDATIVE\nSTRESS", "ROS overwhelm\nantioxidant defenses\n(SOD, catalase, GSH)", C_ORANGE),
("INFLAMMATION", "NF-κB activation\nCytokines, chemokines\nNeutrophil influx", C_RED),
("TISSUE\nDAMAGE", "Epithelial injury\nAirway remodelling\nSystemic effects", RGBColor(0x7B, 0x00, 0x7B)),
]
box_w = 2.1
box_h = 3.2
arrow_w = 0.35
total_used = len(steps) * box_w + (len(steps)-1) * arrow_w
start_x = (13.333 - total_used) / 2
for i, (title, body, col) in enumerate(steps):
xpos = start_x + i * (box_w + arrow_w)
ypos = 1.7
# Box
add_rect(slide, xpos, ypos, box_w, box_h, fill_rgb=col)
add_textbox(slide, xpos+0.08, ypos+0.12, box_w-0.16, 0.65, title,
fontsize=12, bold=True, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
# Divider
add_rect(slide, xpos+0.08, ypos+0.78, box_w-0.16, 0.04, fill_rgb=C_WHITE)
add_textbox(slide, xpos+0.1, ypos+0.88, box_w-0.2, 2.15, body,
fontsize=11, bold=False, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Arrow (not after last)
if i < len(steps) - 1:
ax = xpos + box_w + 0.02
ay = ypos + box_h/2 - 0.1
add_textbox(slide, ax, ay, arrow_w, 0.35,
"►", fontsize=22, bold=True, color=C_NAVY,
align=PP_ALIGN.CENTER, font_name="Calibri")
# Bottom note
add_rect(slide, 0.4, 5.1, 12.5, 1.9, fill_rgb=C_WHITE, line_rgb=C_NAVY, line_width_pt=1)
add_textbox(slide, 0.55, 5.18, 12.2, 1.75,
"Phase 2 Response: When oxidant burden is great, excess ROS activate Nrf2 transcription factor → upregulates "
"heme oxygenase-1, glutathione-S-transferase, catalase, superoxide dismutase & glutathione peroxidase. "
"If Phase 2 fails → lipid peroxidation, protein oxidation, DNA damage → apoptosis. "
"Proinflammatory cascades upregulate IL-6, IL-8, TNF-α, ICAM-1 → systemic vascular inflammation.",
fontsize=11.5, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "5", fontsize=10, color=C_RED, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — RESPIRATORY PATHOGENESIS (detailed)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"RESPIRATORY PATHOGENESIS IN DETAIL",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Left column — Obstructive
add_rect(slide, 0.3, 1.25, 6.1, 5.95, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width_pt=2)
add_rect(slide, 0.3, 1.25, 6.1, 0.55, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 1.28, 5.9, 0.48, "OBSTRUCTIVE LUNG DISEASE (COPD / Asthma)",
fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
copd_items = [
"SO₂ & NO₂ → airway hyperresponsiveness & bronchoconstriction",
"PM2.5 inhaled → alveolar macrophage activation → MMP release → elastin/collagen destruction (emphysema)",
"Chronic neutrophilic/eosinophilic airway inflammation → mucus gland hypertrophy (chronic bronchitis)",
"PM triggers mast cell degranulation → IgE-mediated asthma exacerbation",
"Ozone (O₃): direct oxidant → ciliary damage → impaired mucociliary clearance → ↑ infection susceptibility",
"Repeated exposure → airway wall remodelling, irreversible obstruction (↓ FEV₁/FVC)",
]
tb = slide.shapes.add_textbox(Inches(0.42), Inches(1.9), Inches(5.86), Inches(5.1))
tf = tb.text_frame
tf.word_wrap = True
from lxml import etree
from pptx.oxml.ns import qn
first = True
for item in copd_items:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
# Right column — Lung Cancer / Cardiovascular
add_rect(slide, 6.7, 1.25, 6.3, 2.95, fill_rgb=C_WHITE, line_rgb=C_RED, line_width_pt=2)
add_rect(slide, 6.7, 1.25, 6.3, 0.55, fill_rgb=C_RED)
add_textbox(slide, 6.82, 1.28, 6.06, 0.48, "LUNG CANCER",
fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
lung_items = [
"PAHs, benzene, nitrosamines → DNA adduct formation → oncogene activation (KRAS, EGFR mutations)",
"Chronic oxidative stress → DNA strand breaks → TP53 mutations",
"PM2.5 → epigenetic changes, global methylation shifts",
"IARC Group 1 carcinogen: outdoor air pollution causes lung cancer",
]
tb2 = slide.shapes.add_textbox(Inches(6.82), Inches(1.9), Inches(6.06), Inches(2.1))
tf2 = tb2.text_frame
tf2.word_wrap = True
first = True
for item in lung_items:
p = tf2.paragraphs[0] if first else tf2.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
# Right bottom — Cardiovascular
add_rect(slide, 6.7, 4.38, 6.3, 2.82, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width_pt=2)
add_rect(slide, 6.7, 4.38, 6.3, 0.55, fill_rgb=C_ORANGE)
add_textbox(slide, 6.82, 4.41, 6.06, 0.48, "CARDIOVASCULAR PATHOGENESIS",
fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
cvd_items = [
"PM2.5 enters systemic circulation → endothelial dysfunction, ↑CRP, fibrinogen",
"Autonomic imbalance: ↑sympathetic tone → ↑HR, hypertension",
"Accelerated atherosclerosis via oxidised LDL & foam cell formation",
"Acute ischaemic events: plaque rupture & thrombosis triggered by PM2.5 peaks",
]
tb3 = slide.shapes.add_textbox(Inches(6.82), Inches(5.02), Inches(6.06), Inches(1.95))
tf3 = tb3.text_frame
tf3.word_wrap = True
first = True
for item in cvd_items:
p = tf3.paragraphs[0] if first else tf3.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "6", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — HEALTH EFFECTS (DISEASE BURDEN)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"HEALTH EFFECTS & DISEASE BURDEN",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Stats boxes at top
stats = [
("7 million", "deaths/year\nattributable to air\npollution (WHO)", C_RED),
("PM2.5 ↑10μg/m³", "+~6% CVD mortality\n+~8% lung cancer\nrisk (meta-analyses)", C_ORANGE),
("15–20%", "higher mortality\nin high-pollution\ncities vs clean cities", C_NAVY),
("IARC 2013", "Declared outdoor air\npollution as Group 1\nHuman Carcinogen", C_TEAL),
]
for i, (val, label, col) in enumerate(stats):
xpos = 0.3 + i * 3.2
add_rect(slide, xpos, 1.28, 3.0, 1.8, fill_rgb=col)
add_textbox(slide, xpos+0.1, 1.32, 2.8, 0.75, val,
fontsize=24, bold=True, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_textbox(slide, xpos+0.1, 2.0, 2.8, 0.9, label,
fontsize=11, bold=False, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
# Effect categories
effects = [
("Respiratory", [
"Asthma exacerbations",
"COPD progression",
"Chronic bronchitis",
"Acute lower respiratory infections (children)",
"Impaired lung development in children",
], C_TEAL),
("Cardiovascular", [
"Ischaemic heart disease",
"Stroke",
"Arrhythmias / sudden cardiac death",
"Hypertension",
"Heart failure exacerbations",
], C_ORANGE),
("Systemic / Other", [
"Lung & bladder cancer",
"Adverse pregnancy outcomes (LBW, preterm)",
"Neurotoxicity (lead: IQ loss in children)",
"Type 2 diabetes mellitus",
"Cognitive decline / dementia",
], C_NAVY),
]
for i, (category, items, col) in enumerate(effects):
xpos = 0.3 + i * 4.35
add_rect(slide, xpos, 3.25, 4.1, 3.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
add_rect(slide, xpos, 3.25, 4.1, 0.48, fill_rgb=col)
add_textbox(slide, xpos+0.1, 3.28, 3.9, 0.42, category,
fontsize=13, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
tb = slide.shapes.add_textbox(Inches(xpos+0.12), Inches(3.82), Inches(3.86), Inches(3.25))
tf = tb.text_frame
tf.word_wrap = True
first = True
for item in items:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '●')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(12)
r.font.color.rgb = C_DARK
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "7", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — INDOOR AIR POLLUTION
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_ORANGE)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"INDOOR AIR POLLUTION",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Intro banner
add_rect(slide, 0.3, 1.25, 12.7, 0.75, fill_rgb=C_NAVY, line_rgb=C_ORANGE, line_width_pt=1)
add_textbox(slide, 0.5, 1.3, 12.3, 0.65,
"People spend >90% of time indoors. Indoor air often 2–5× more polluted than outdoor. "
"Solid fuel combustion (biomass, coal) is the leading indoor pollution source globally.",
fontsize=12, bold=False, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Left panel
add_rect(slide, 0.3, 2.18, 6.0, 5.05, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width_pt=1.5)
add_rect(slide, 0.3, 2.18, 6.0, 0.52, fill_rgb=C_TEAL)
add_textbox(slide, 0.42, 2.21, 5.76, 0.46, "INDOOR POLLUTANT SOURCES",
fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
indoor_sources = [
"Biomass/coal combustion: CO, PM2.5, PAHs, formaldehyde",
"Tobacco smoke: >70 carcinogens incl. benzene, NNK, arsenic",
"Radon: from soil/rocks, ↑ lung cancer risk (non-smokers)",
"Building materials: formaldehyde (MDF), asbestos, VOCs from paints",
"Mould/biological contaminants: triggers allergic inflammation",
"Pesticides: organophosphates — respiratory & CNS toxicity",
"Carbon monoxide from gas stoves/heaters: ↓ COHb oxygen-carrying capacity",
]
tb = slide.shapes.add_textbox(Inches(0.42), Inches(2.82), Inches(5.76), Inches(4.2))
tf = tb.text_frame; tf.word_wrap = True
first = True
for item in indoor_sources:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
# Right panel
add_rect(slide, 6.7, 2.18, 6.3, 5.05, fill_rgb=C_WHITE, line_rgb=C_RED, line_width_pt=1.5)
add_rect(slide, 6.7, 2.18, 6.3, 0.52, fill_rgb=C_RED)
add_textbox(slide, 6.82, 2.21, 6.06, 0.46, "HEALTH CONSEQUENCES",
fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
indoor_health = [
"Acute lower respiratory infections — leading cause of child mortality in LMICs",
"COPD: indoor solid fuel use → 2–3× risk (women, non-smokers)",
"Lung cancer: radon — attributable fraction ~10% of all lung cancer deaths",
"Cardiovascular disease: CO & PM cause myocardial stress",
"Adverse birth outcomes: LBW, stillbirth from chronic CO exposure",
"Eye diseases: smoke irritation, corneal damage (biomass users)",
"Musculoskeletal: carried firewood; burns from open fires",
]
tb2 = slide.shapes.add_textbox(Inches(6.82), Inches(2.82), Inches(6.06), Inches(4.2))
tf2 = tb2.text_frame; tf2.word_wrap = True
first = True
for item in indoor_health:
p = tf2.paragraphs[0] if first else tf2.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "8", fontsize=10, color=C_ORANGE, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — WHO AQG & MEASUREMENT
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"WHO AIR QUALITY GUIDELINES (AQG 2005/2021)",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Table header
add_rect(slide, 0.3, 1.25, 12.7, 0.55, fill_rgb=C_NAVY)
for col_info in [
(0.3, 2.5, "POLLUTANT"),
(2.8, 2.8, "AQG VALUE"),
(5.6, 2.5, "AVERAGING TIME"),
(8.1, 2.0, "BASIS FOR LIMIT"),
(10.1, 2.9, "HEALTH CONCERN"),
]:
x, w, label = col_info
add_textbox(slide, x+0.1, 1.28, w-0.15, 0.46, label,
fontsize=11, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
rows = [
("PM2.5", "10 μg/m³ (annual)\n25 μg/m³ (24-hr)", "Annual / 24-hr", "Cardiovascular & respiratory mortality — no safe threshold", C_LTGRAY),
("PM10", "20 μg/m³ (annual)\n50 μg/m³ (24-hr)", "Annual / 24-hr", "Respiratory hospital admissions, COPD exacerbations", C_WHITE),
("NO₂", "40 μg/m³ (annual)\n200 μg/m³ (1-hr)", "Annual / 1-hr", "Airway inflammation, ↑ asthma exacerbations", C_LTGRAY),
("SO₂", "500 μg/m³ (10-min)\n350 μg/m³ (1-hr)", "10-min / 1-hr", "Bronchoconstriction, especially in asthmatics", C_WHITE),
("Ozone", "100 μg/m³ (8-hr)\n150-200 μg/m³ (1-hr)", "8-hr / 1-hr", "Lung damage, reduced FEV₁, premature death", C_LTGRAY),
("CO", "10 mg/m³ (8-hr)\n100 mg/m³ (15-min)", "8-hr / 15-min", "Tissue hypoxia, cardiac ischaemia, neurotoxicity", C_WHITE),
("Lead", "0.5–1.0 μg/m³", "Annual", "Neurotoxicity (children), CVD, renal effects", C_LTGRAY),
]
row_h = 0.7
for i, (pollutant, value, time, basis, bg) in enumerate(rows):
ypos = 1.8 + i * row_h
add_rect(slide, 0.3, ypos, 12.7, row_h, fill_rgb=bg)
add_textbox(slide, 0.4, ypos+0.06, 2.35, row_h-0.1, pollutant,
fontsize=11, bold=True, color=C_NAVY,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 2.9, ypos+0.04, 2.65, row_h-0.06, value,
fontsize=10.5, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 5.65, ypos+0.06, 2.4, row_h-0.1, time,
fontsize=10.5, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 8.15, ypos+0.04, 4.8, row_h-0.06, basis,
fontsize=10, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Border around table
add_rect(slide, 0.3, 1.25, 12.7, 1.8 + len(rows)*row_h - 1.25,
fill_rgb=None, line_rgb=C_NAVY, line_width_pt=1.5)
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "9", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — SCALE & TRANSPORT
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"SPATIAL SCALE & TRANSPORT OF POLLUTANTS",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
scales = [
("LOCAL\n(Metres–Km)", "Household biomass burning\nRoad-side traffic\nAtmospheric lifetime: minutes–hours\nPollutants: PM, CO, NO₂, SO₂",
"Poorly controlled neighbourhood\nsources; burning of biomass fuels\ncommon in developing countries.", C_RED),
("URBAN\n(City-wide)", "Vehicle exhaust, industry stacks\nAtmospheric lifetime: hours\nHigh conc. throughout city\nPollutants: NO, CO, VOCs",
"Urban populations continuously\nexposed; hotspots near arterials,\nindustrial zones, waste-burning sites.", C_ORANGE),
("REGIONAL\n(100s–1000s km)", "Fine PM (<2.5μm) & ozone\nAtmospheric lifetime: days–weeks\nLong-range transport across borders\nAcid rain: SO₂ → H₂SO₄",
"Ozone crosses national boundaries.\nWhitehorse Protocol covers SO₂\nand transboundary pollution.", C_TEAL),
("GLOBAL\n(Hemispheric)", "CO₂, N₂O, CH₄, CFCs\nAtmospheric lifetime: years–centuries\nGreenhouse warming effect\nOzone layer depletion",
"Climate change amplifies pollution:\nheatwaves ↑ ozone; wildfires ↑ PM;\nlonger allergy seasons.", C_NAVY),
]
for i, (title, body1, body2, col) in enumerate(scales):
xpos = 0.3 + i * 3.25
add_rect(slide, xpos, 1.28, 3.0, 3.5, fill_rgb=col)
add_textbox(slide, xpos+0.1, 1.32, 2.8, 0.7, title,
fontsize=13, bold=True, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_rect(slide, xpos+0.08, 2.02, 2.84, 0.04, fill_rgb=C_WHITE)
add_textbox(slide, xpos+0.1, 2.1, 2.8, 2.5, body1,
fontsize=11, bold=False, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_rect(slide, xpos, 4.9, 3.0, 2.3, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=1.5)
add_textbox(slide, xpos+0.1, 4.95, 2.8, 2.1, body2,
fontsize=11, bold=False, color=C_DARK,
align=PP_ALIGN.LEFT, font_name="Calibri")
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "10", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 11 — CONTROL MEASURES
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"CONTROL MEASURES & PREVENTION",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# 3 levels of intervention
interventions = [
("POLICY /\nLEGISLATIVE", [
"Clean Air Acts — national ambient air quality standards (NAAQS)",
"Vehicle emission norms (BS-VI / Euro 6)",
"Mandatory EIA for new industries",
"WHO AQG implementation & monitoring networks",
"International: UNEP, WHO Global Action Plan on Air Pollution",
"Phase-out of leaded petrol (achieved globally by 2021)",
], C_NAVY),
("TECHNICAL /\nENGINEERING", [
"Catalytic converters, diesel particulate filters in vehicles",
"Electrostatic precipitators & scrubbers in industry",
"Tall stacks with dispersion modelling",
"Transition to clean energy: solar, wind, hydro, nuclear",
"Improved cook stoves / LPG substitution for biomass",
"Green building design with ventilation & HEPA filtration",
], C_TEAL),
("COMMUNITY /\nINDIVIDUAL", [
"Air Quality Index (AQI) dissemination & public alerts",
"N95/P100 respirator use during pollution episodes",
"Indoor plants & air purifiers (HEPA) for indoor protection",
"Avoid outdoor exercise during high PM2.5/ozone days",
"School health programs on clean cooking fuel adoption",
"Avoid crop residue burning; promote composting",
], C_GREEN),
]
for i, (title, items, col) in enumerate(interventions):
xpos = 0.3 + i * 4.35
add_rect(slide, xpos, 1.28, 4.1, 5.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
add_rect(slide, xpos, 1.28, 4.1, 0.7, fill_rgb=col)
add_textbox(slide, xpos+0.1, 1.3, 3.9, 0.66, title,
fontsize=13, bold=True, color=C_WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
tb = slide.shapes.add_textbox(Inches(xpos+0.15), Inches(2.08), Inches(3.8), Inches(5.0))
tf = tb.text_frame; tf.word_wrap = True
first = True
for item in items:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '✓')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11.5)
r.font.color.rgb = C_DARK
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "11", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 12 — VULNERABLE POPULATIONS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_RED)
add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
"VULNERABLE POPULATIONS & EQUITY",
fontsize=28, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
groups = [
("👶 Children", [
"Developing lungs — high ventilation/kg BW",
"Impaired lung growth → ↓ peak lung function",
"Lead: neurotoxicity, IQ loss, learning disabilities",
"Acute RTI — major cause of child mortality",
], C_TEAL),
("🤰 Pregnant\nWomen", [
"Transplacental transfer of CO, Pb, PAHs",
"Low birth weight, preterm delivery, stillbirth",
"Intrauterine growth restriction",
"Placental oxidative stress & inflammation",
], C_ORANGE),
("👴 Elderly", [
"Pre-existing COPD/CHD amplifies risk",
"↓ antioxidant reserves & immune response",
"PM2.5 → acute hospital admissions",
"Higher case-fatality from pollution episodes",
], C_NAVY),
("💊 Pre-existing\nDisease", [
"Asthmatics: SO₂, NO₂, O₃ trigger attacks",
"COPD patients: PM exacerbates breathlessness",
"IHD: PM2.5 → plaque destabilization, arrhythmia",
"Diabetics: impaired detoxification pathways",
], C_RED),
("🏚 Socioeconomic\nDisadvantage", [
"Reside near industrial/traffic zones",
"Biomass cooking → constant indoor exposure",
"No access to healthcare or clean alternatives",
"Disproportionate burden in LMICs & slums",
], C_GREEN),
]
for i, (group, items, col) in enumerate(groups):
row, c = divmod(i, 3)
if i < 3:
xpos = 0.3 + c * 4.35
ypos = 1.28
else:
xpos = 1.6 + (i-3) * 4.35
ypos = 4.48
add_rect(slide, xpos, ypos, 4.1, 2.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
add_rect(slide, xpos, ypos, 4.1, 0.55, fill_rgb=col)
add_textbox(slide, xpos+0.1, ypos+0.06, 3.9, 0.46, group,
fontsize=13, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
tb = slide.shapes.add_textbox(Inches(xpos+0.12), Inches(ypos+0.65), Inches(3.86), Inches(2.2))
tf = tb.text_frame; tf.word_wrap = True
first = True
for item in items:
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
pPr = p._p.get_or_add_pPr()
buChar = etree.SubElement(pPr, qn('a:buChar'))
buChar.set('char', '▸')
r = p.add_run()
r.text = " " + item
r.font.name = "Calibri"
r.font.size = Pt(11)
r.font.color.rgb = C_DARK
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "12", fontsize=10, color=C_RED, align=PP_ALIGN.RIGHT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 13 — SUMMARY / KEY TAKEAWAYS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_NAVY)
add_rect(slide, 0, 0, 0.4, 7.5, fill_rgb=C_TEAL)
add_rect(slide, 0.4, 1.1, 12.933, 0.07, fill_rgb=C_ORANGE)
add_textbox(slide, 0.7, 0.2, 12, 0.85,
"KEY TAKEAWAYS",
fontsize=32, bold=True, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
takeaways = [
("1", "Air pollution is a global public health emergency — 7 million deaths/year; no safe lower threshold for PM2.5.", C_ORANGE),
("2", "Pathogenesis centres on ROS-driven oxidative stress → NF-κB activation → systemic inflammation → "
"respiratory, cardiovascular and carcinogenic endpoints.", C_TEAL),
("3", "PM2.5 is the most hazardous fraction — penetrates alveoli, crosses into systemic circulation, "
"triggers endothelial dysfunction and atherosclerosis.", C_GREEN),
("4", "Indoor air pollution (biomass combustion) causes acute RTIs in children and COPD/lung cancer in women — "
"disproportionate burden in LMICs.", C_ORANGE),
("5", "Effective control requires multilevel intervention: legislation (AQG), engineering (clean energy, "
"catalytic converters) and community education.", C_TEAL),
("6", "Vulnerable groups — children, pregnant women, elderly, low SES — require targeted protective policies "
"and access to clean cooking fuel alternatives.", C_GREEN),
]
for i, (num, text, col) in enumerate(takeaways):
ypos = 1.3 + i * 0.98
add_rect(slide, 0.7, ypos, 0.52, 0.72, fill_rgb=col)
add_textbox(slide, 0.72, ypos+0.1, 0.48, 0.55, num,
fontsize=22, bold=True, color=C_DARK,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_textbox(slide, 1.35, ypos+0.1, 11.6, 0.65, text,
fontsize=13, bold=False, color=C_WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
# Reference line
add_textbox(slide, 0.7, 7.12, 12, 0.3,
"Sources: Park's Textbook of Preventive & Social Medicine (24th ed.) ● Murray & Nadel's Textbook of Respiratory Medicine "
"● WHO Air Quality Guidelines 2005/2021",
fontsize=9.5, bold=False, color=RGBColor(0x80, 0xA0, 0xC0),
align=PP_ALIGN.LEFT, font_name="Calibri")
# Save
out_path = "/tmp/workspace/air-pollution-pptx/Air_Pollution_Pathogenesis_Community_Medicine.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
cd /tmp/workspace/air-pollution-pptx && python build_pptx.py 2>&1
ls -lh /tmp/workspace/air-pollution-pptx/Air_Pollution_Pathogenesis_Community_Medicine.pptx
Air Pollution Pathogenesis Community Medicine
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide (navy/teal/orange theme) |
| 2 | Definition & Overview — primary vs secondary pollutants, PM classification |
| 3 | Sources of Air Pollution — automobiles, industries, domestic, natural, radioactive, agricultural |
| 4 | Key Pollutants — SO₂, NO₂, CO, O₃, PM2.5, Lead, Benzene, Radon with mechanisms |
| 5 | Pathogenesis — mechanistic flow diagram (Inhalation → Deposition → Oxidative Stress → Inflammation → Tissue Damage) |
| 6 | Respiratory Pathogenesis in Detail — COPD/asthma, lung cancer, cardiovascular |
| 7 | Health Effects & Disease Burden — WHO stats, disease categories |
| 8 | Indoor Air Pollution — sources, health consequences (biomass, radon, CO, VOCs) |
| 9 | WHO AQG Table — PM2.5, PM10, NO₂, SO₂, Ozone, CO, Lead guideline values |
| 10 | Spatial Scale & Transport — local, urban, regional, global pollutant dynamics |
| 11 | Control Measures — policy/legislative, technical/engineering, community/individual |
| 12 | Vulnerable Populations & Equity — children, pregnant women, elderly, low SES |
| 13 | Summary / Key Takeaways |