Definition,measurement of HRQOL, Common HRQOL measures , create a ppt for this topic
mkdir -p /tmp/workspace/hrqol-ppt && ls /tmp/workspace/hrqol-ppt/
~/hrqol-ppt/build_ppt.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 ────────────────────────────────────────────────────────────
NAVY = RGBColor(0x1A, 0x37, 0x6C) # dark navy
TEAL = RGBColor(0x00, 0x86, 0x8B) # teal accent
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_BG = RGBColor(0xF0, 0xF4, 0xF8) # very light blue-grey
MID_GREY = RGBColor(0x60, 0x60, 0x60)
ACCENT = RGBColor(0xFF, 0x9F, 0x1C) # amber accent
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6] # fully blank
# ═══════════════════════════════════════════════════════════════════════════════
# Helper functions
# ═══════════════════════════════════════════════════════════════════════════════
def add_rect(slide, x, y, w, h, fill_color, alpha=None):
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
Inches(x), Inches(y), Inches(w), Inches(h)
)
fill = shape.fill
fill.solid()
fill.fore_color.rgb = fill_color
shape.line.fill.background()
return shape
def add_tb(slide, x, y, w, h, text, font_size, bold=False, color=WHITE,
align=PP_ALIGN.LEFT, italic=False, wrap=True):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(font_size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
run.font.name = "Calibri"
return tb
def add_multiline_tb(slide, x, y, w, h, lines, font_size=16, color=MID_GREY,
bold=False, line_spacing=None, align=PP_ALIGN.LEFT):
"""lines = list of (text, bold, color) tuples or plain strings"""
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = 0
first = True
for item in lines:
if isinstance(item, str):
txt, b, col = item, bold, color
else:
txt, b, col = item
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
p.alignment = align
if line_spacing:
p.line_spacing = Pt(line_spacing)
run = p.add_run()
run.text = txt
run.font.size = Pt(font_size)
run.font.bold = b
run.font.color.rgb = col
run.font.name = "Calibri"
return tb
def slide_header(slide, title, subtitle=None):
"""Teal top bar with white title"""
add_rect(slide, 0, 0, 13.333, 1.2, NAVY)
add_tb(slide, 0.4, 0.15, 12.5, 0.9, title, 30, bold=True,
color=WHITE, align=PP_ALIGN.LEFT)
if subtitle:
add_tb(slide, 0.4, 0.9, 12.5, 0.35, subtitle, 14,
bold=False, color=RGBColor(0xB0, 0xD0, 0xE8), align=PP_ALIGN.LEFT)
# thin teal accent bar beneath
add_rect(slide, 0, 1.2, 13.333, 0.06, TEAL)
def bullet_slide(slide, title, bullets, subtitle=None, two_col=False, col_split=6.3):
"""Standard slide with header + bullets"""
slide_header(slide, title, subtitle)
add_rect(slide, 0, 1.26, 13.333, 6.24, LIGHT_BG)
if not two_col:
add_multiline_tb(slide, 0.5, 1.5, 12.3, 5.8, bullets, font_size=17,
color=RGBColor(0x22, 0x22, 0x44), line_spacing=22)
else:
mid = col_split
left = [b for b in bullets if b[0] == "L"]
right = [b for b in bullets if b[0] == "R"]
# strip L/R tag
left = [(t[1], b, c) for (_, t, b, c) in [(*x,) for x in left]] # fallback
right = [(t[1], b, c) for (_, t, b, c) in [(*x,) for x in right]]
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — Title / Cover
# ═══════════════════════════════════════════════════════════════════════════════
s1 = prs.slides.add_slide(blank)
# Full navy background
add_rect(s1, 0, 0, 13.333, 7.5, NAVY)
# Teal diagonal accent strip (tall rectangle rotated via position trick)
add_rect(s1, 10.2, 0, 0.18, 7.5, TEAL)
add_rect(s1, 10.5, 0, 0.08, 7.5, ACCENT)
add_tb(s1, 1.0, 1.5, 9.0, 1.2,
"Health-Related Quality of Life",
42, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
add_tb(s1, 1.0, 2.8, 9.0, 0.6,
"Definition | Measurement | Common Measures",
22, bold=False, color=TEAL, align=PP_ALIGN.LEFT)
add_tb(s1, 1.0, 4.2, 9.0, 0.5,
"A structured overview for clinical practice & research",
16, bold=False, color=RGBColor(0xB0, 0xD0, 0xE8), align=PP_ALIGN.LEFT)
# bottom strip
add_rect(s1, 0, 6.9, 13.333, 0.6, TEAL)
add_tb(s1, 0.4, 6.92, 12, 0.4,
"Sources: Campbell-Walsh-Wein Urology · Kaplan & Sadock Psychiatry · Rheumatology (Elsevier 2022)",
11, color=WHITE, align=PP_ALIGN.LEFT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — Definition of HRQoL
# ═══════════════════════════════════════════════════════════════════════════════
s2 = prs.slides.add_slide(blank)
slide_header(s2, "What is Health-Related Quality of Life?",
subtitle="Defining the construct")
add_rect(s2, 0, 1.26, 13.333, 6.24, LIGHT_BG)
# Quote box
add_rect(s2, 0.5, 1.5, 12.3, 1.3, TEAL)
add_tb(s2, 0.7, 1.6, 11.9, 1.1,
'"The impact of disease on the physical, psychological, mental, and social aspects '
'of health, influenced by the expectations and life experiences of the individual patient."',
15, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
bullets2 = [
("HRQoL refers to the elements of a patient's life specifically affected by their health status.", True, NAVY),
("", False, MID_GREY),
("Calman (1984): HRQoL = the gap between a patient's expectations and actual experiences.", False, MID_GREY),
("", False, MID_GREY),
("Cella & Tulsky (1990): extent to which medical interventions impact the functional,", False, MID_GREY),
(" psychological, social and economic life of the patient.", False, MID_GREY),
("", False, MID_GREY),
("Aaronson et al. (1986): a patient's appraisal of and satisfaction with their current level", False, MID_GREY),
(" of functioning compared to what they perceive to be possible or ideal.", False, MID_GREY),
("", False, MID_GREY),
("Key distinction: HRQoL ≠ overall quality of life — it is specifically health-related.", True, NAVY),
]
add_multiline_tb(s2, 0.5, 2.95, 12.3, 4.3, bullets2, font_size=15.5)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — Components & Dimensions
# ═══════════════════════════════════════════════════════════════════════════════
s3 = prs.slides.add_slide(blank)
slide_header(s3, "Core Components of HRQoL",
subtitle="A broad, multidimensional construct")
add_rect(s3, 0, 1.26, 13.333, 6.24, LIGHT_BG)
# Four component boxes
boxes = [
("Physical\nFunction", "Mobility, self-care, daily activities,\npain, fatigue, physical symptoms"),
("Psychological\nWell-being", "Emotional state, anxiety, depression,\ncognition, coping"),
("Social\nFunction", "Social roles, relationships,\ncommunity participation"),
("General\nHealth Perceptions", "Patient-rated overall health,\nenergy, vitality, satisfaction"),
]
colors = [NAVY, TEAL, RGBColor(0x2E, 0x86, 0xAB), RGBColor(0xF7, 0x7F, 0x00)]
for i, (title, body) in enumerate(boxes):
bx = 0.4 + i * 3.22
add_rect(s3, bx, 1.55, 3.0, 1.5, colors[i])
add_tb(s3, bx + 0.1, 1.6, 2.8, 0.7, title, 15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s3, bx + 0.1, 2.3, 2.8, 0.7, body, 12, color=WHITE, align=PP_ALIGN.CENTER)
# Additional components list
add_tb(s3, 0.5, 3.25, 12.3, 0.4,
"Additional components include:", 15, bold=True, color=NAVY)
bullets3 = [
"• Health perceptions — patient's own view of their health status",
"• Patient preferences and values regarding health states",
"• Overall patient satisfaction with care received",
"• Economic impact — productivity, work capacity, financial burden",
"• Access to adequate food, shelter, and social support systems (Patrick & Erickson, 1993)",
]
add_multiline_tb(s3, 0.5, 3.7, 12.3, 3.5,
[(b, False, MID_GREY) for b in bullets3], font_size=15.5, line_spacing=21)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — Why Measure HRQoL?
# ═══════════════════════════════════════════════════════════════════════════════
s4 = prs.slides.add_slide(blank)
slide_header(s4, "Why Measure HRQoL?",
subtitle="Clinical, research and policy rationale")
add_rect(s4, 0, 1.26, 13.333, 6.24, LIGHT_BG)
reasons = [
("🎯 Primary Outcome",
"For many interventions — especially urologic, oncologic, chronic disease — improvement\nin HRQoL is the primary treatment goal (not mortality or biomarkers alone)."),
("📊 Independent from Clinical Measures",
"Disease activity, organ damage, and HRQoL are independent of each other (SLE evidence).\nEach reflects a different domain and must be captured separately."),
("🧑⚕️ Patient-Centred Care",
"Patients prioritise quality of life over objective test results (e.g. >1800 European sarcoidosis\npatients ranked QoL above PFTs). Incorporating HRQoL aligns care with patient priorities."),
("📈 Research & Regulatory",
"Regulatory agencies (FDA, EMA) require patient-reported outcomes (PROs) in RCTs.\nHRQoL data supports drug approval, health technology assessment and guideline development."),
]
for i, (head, body) in enumerate(reasons):
by = 1.55 + i * 1.38
add_rect(s4, 0.4, by, 0.55, 1.1, TEAL)
add_tb(s4, 0.4, by + 0.1, 0.55, 0.9, str(i+1), 26, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s4, 1.1, by, 11.8, 0.45, head, 15, bold=True, color=NAVY)
add_tb(s4, 1.1, by + 0.45, 11.8, 0.8, body, 13.5, color=MID_GREY)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — Measurement Principles
# ═══════════════════════════════════════════════════════════════════════════════
s5 = prs.slides.add_slide(blank)
slide_header(s5, "Measurement of HRQoL — Key Principles",
subtitle="How do we measure it?")
add_rect(s5, 0, 1.26, 13.333, 6.24, LIGHT_BG)
add_tb(s5, 0.5, 1.45, 12.3, 0.45,
"Any valid HRQoL assessment should include both:", 16, bold=True, color=NAVY)
# Two boxes side by side
add_rect(s5, 0.5, 1.95, 5.8, 1.1, NAVY)
add_tb(s5, 0.6, 2.0, 5.6, 0.45, "Objective Functional Assessment", 15, bold=True, color=WHITE)
add_tb(s5, 0.6, 2.45, 5.6, 0.55,
"Relatively objective measure of the patient's ability to perform physical, social and daily tasks",
13, color=RGBColor(0xB0, 0xD0, 0xE8))
add_rect(s5, 6.85, 1.95, 5.8, 1.1, TEAL)
add_tb(s5, 6.95, 2.0, 5.6, 0.45, "Patient-Reported Bother/Impact", 15, bold=True, color=WHITE)
add_tb(s5, 6.95, 2.45, 5.6, 0.55,
"Amount of bother the patient experiences from decrements in their functional status",
13, color=RGBColor(0xB0, 0xD0, 0xE8))
add_tb(s5, 6.2, 2.4, 0.6, 0.5, "+", 30, bold=True, color=ACCENT, align=PP_ALIGN.CENTER)
add_tb(s5, 0.5, 3.2, 12.3, 0.4,
"Measurement approaches:", 15, bold=True, color=NAVY)
bullets5 = [
("• Self-administered questionnaires — most widely used (patient-reported outcomes, PROs)", False, MID_GREY),
("• Interviewer-administered instruments — for low literacy or cognitively impaired populations", False, MID_GREY),
("• Utility measures — convert health states to a single preference-based score (e.g., EQ-5D)", False, MID_GREY),
("• Profile measures — yield a separate score for each domain (e.g., SF-36 8 domains)", False, MID_GREY),
("• Global/summary measures — collapse all domains into a single composite score", False, MID_GREY),
]
add_multiline_tb(s5, 0.5, 3.65, 12.3, 3.6, bullets5, font_size=15.5, line_spacing=21)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — Generic vs Disease-Specific
# ═══════════════════════════════════════════════════════════════════════════════
s6 = prs.slides.add_slide(blank)
slide_header(s6, "Generic vs Disease-Specific HRQoL Instruments",
subtitle="Two major categories")
add_rect(s6, 0, 1.26, 13.333, 6.24, LIGHT_BG)
# Left panel — Generic
add_rect(s6, 0.4, 1.5, 5.9, 5.7, NAVY)
add_rect(s6, 0.4, 1.5, 5.9, 0.55, TEAL)
add_tb(s6, 0.5, 1.52, 5.7, 0.5, "GENERIC (GENERAL) MEASURES", 15,
bold=True, color=WHITE, align=PP_ALIGN.CENTER)
gen_bullets = [
"Applicable across all diseases & populations",
"Allow cross-disease comparison",
"Capture broad health domains",
"May miss disease-specific concerns",
"",
"Examples:",
" • SF-36 / SF-12 / SF-8",
" • EuroQoL EQ-5D",
" • Sickness Impact Profile (SIP)",
" • Nottingham Health Profile (NHP)",
" • Quality of Well-Being Scale",
" • PROMIS-29",
]
add_multiline_tb(s6, 0.55, 2.15, 5.6, 4.8,
[(b, b.startswith("Examples"), WHITE) for b in gen_bullets],
font_size=14, line_spacing=19)
# Right panel — Disease-specific
add_rect(s6, 6.9, 1.5, 5.9, 5.7, RGBColor(0x0A, 0x5C, 0x6B))
add_rect(s6, 6.9, 1.5, 5.9, 0.55, ACCENT)
add_tb(s6, 7.0, 1.52, 5.7, 0.5, "DISEASE-SPECIFIC MEASURES", 15,
bold=True, color=WHITE, align=PP_ALIGN.CENTER)
dis_bullets = [
"Designed for a particular condition",
"More sensitive to clinically meaningful change",
"Higher content validity for that disease",
"Cannot compare across diseases",
"",
"Examples:",
" • FACT-G / FACT-P (cancer/prostate)",
" • EORTC QLQ-C30 (cancer)",
" • LupusQoL / SLE-QoL (SLE)",
" • IPSS (prostate / LUTS)",
" • King's Sarcoidosis Questionnaire",
" • UCLA Prostate Cancer Index",
]
add_multiline_tb(s6, 7.05, 2.15, 5.6, 4.8,
[(b, b.startswith("Examples"), WHITE) for b in dis_bullets],
font_size=14, line_spacing=19)
add_tb(s6, 6.3, 2.8, 0.6, 1.0, "VS", 22, bold=True, color=NAVY, align=PP_ALIGN.CENTER)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — SF-36 Deep Dive
# ═══════════════════════════════════════════════════════════════════════════════
s7 = prs.slides.add_slide(blank)
slide_header(s7, "SF-36: The Gold Standard Generic Measure",
subtitle="Medical Outcomes Study Short Form 36 — Ware et al., 1992")
add_rect(s7, 0, 1.26, 13.333, 6.24, LIGHT_BG)
# 8 domain boxes in 2 rows of 4
domains_physical = [
("Physical\nFunctioning", "Activities of daily living,\nmobility"),
("Role-\nPhysical", "Limitations due to\nphysical health"),
("Bodily\nPain", "Pain severity\nand interference"),
("General\nHealth", "Overall health\nperceptions"),
]
domains_mental = [
("Vitality", "Energy levels\nand fatigue"),
("Social\nFunctioning", "Social activities,\nrelationships"),
("Role-\nEmotional", "Limitations due to\nemotional problems"),
("Mental\nHealth", "Psychological well-being,\nanxiety, depression"),
]
add_rect(s7, 0.4, 1.5, 12.5, 0.3, RGBColor(0xCC, 0xE5, 0xFF))
add_tb(s7, 0.5, 1.5, 6.0, 0.3,
"Physical Component Summary (PCS)", 12, bold=True, color=NAVY)
add_tb(s7, 6.9, 1.5, 5.8, 0.3,
"Mental Component Summary (MCS)", 12, bold=True, color=TEAL)
for i, (ttl, desc) in enumerate(domains_physical):
bx = 0.4 + i * 3.05
add_rect(s7, bx, 1.85, 2.85, 1.5, NAVY)
add_tb(s7, bx+0.1, 1.9, 2.65, 0.65, ttl, 13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s7, bx+0.1, 2.55, 2.65, 0.75, desc, 11.5, color=RGBColor(0xB0,0xD0,0xE8), align=PP_ALIGN.CENTER)
for i, (ttl, desc) in enumerate(domains_mental):
bx = 0.4 + i * 3.05
add_rect(s7, bx, 3.5, 2.85, 1.5, TEAL)
add_tb(s7, bx+0.1, 3.55, 2.65, 0.65, ttl, 13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s7, bx+0.1, 4.2, 2.65, 0.75, desc, 11.5, color=WHITE, align=PP_ALIGN.CENTER)
notes = [
"• 36 items total | Scores 0–100 (higher = better HRQoL)",
"• Minimum clinically important difference (MCID): PCS/MCS ≥ 2.5 improvement; domain ≥ 5.0",
"• Widely used in RCTs (e.g. BLISS-52/76 in SLE); also SF-12 (12 items) and SF-8 (8 items) for brevity",
]
add_multiline_tb(s7, 0.5, 5.15, 12.3, 2.1,
[(n, False, MID_GREY) for n in notes], font_size=14.5, line_spacing=20)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — EQ-5D
# ═══════════════════════════════════════════════════════════════════════════════
s8 = prs.slides.add_slide(blank)
slide_header(s8, "EuroQoL EQ-5D: Utility / Preference-Based Measure",
subtitle="Brazier et al., 1991 | 5 items + VAS")
add_rect(s8, 0, 1.26, 13.333, 6.24, LIGHT_BG)
eq5d_dims = [
("1", "Mobility", "Walking ability"),
("2", "Self-Care", "Washing, dressing"),
("3", "Usual Activities", "Work, study, housework"),
("4", "Pain / Discomfort", "Severity of pain"),
("5", "Anxiety / Depression", "Mood and emotional state"),
]
for i, (num, dim, desc) in enumerate(eq5d_dims):
bx = 0.4 + i * 2.5
add_rect(s8, bx, 1.55, 2.3, 2.1, NAVY)
add_rect(s8, bx, 1.55, 2.3, 0.5, TEAL)
add_tb(s8, bx+0.05, 1.57, 2.2, 0.46, f"Dimension {num}", 13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s8, bx+0.05, 2.1, 2.2, 0.55, dim, 14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s8, bx+0.05, 2.7, 2.2, 0.6, desc, 12, color=RGBColor(0xB0,0xD0,0xE8), align=PP_ALIGN.CENTER)
# VAS box
add_rect(s8, 0.4, 3.8, 5.5, 1.1, RGBColor(0x2E, 0x86, 0xAB))
add_tb(s8, 0.5, 3.85, 5.3, 0.45, "EQ Visual Analogue Scale (VAS)", 14, bold=True, color=WHITE)
add_tb(s8, 0.5, 4.3, 5.3, 0.55,
"Patient rates their overall health today on a 0–100 scale (0 = worst imaginable; 100 = best imaginable)",
12.5, color=WHITE)
# Scoring box
add_rect(s8, 6.5, 3.8, 6.4, 1.1, RGBColor(0x1A, 0x37, 0x6C))
add_tb(s8, 6.6, 3.85, 6.2, 0.45, "Scoring & Index Value", 14, bold=True, color=WHITE)
add_tb(s8, 6.6, 4.3, 6.2, 0.55,
"Each dimension rated on 3- or 5-level scale → combined into a single utility index (0 = death; 1 = full health)",
12.5, color=RGBColor(0xB0,0xD0,0xE8))
add_tb(s8, 0.5, 5.05, 12.3, 0.4,
"Advantages of EQ-5D:", 14, bold=True, color=NAVY)
eq5_pts = [
"• Very brief (5 + 1 VAS) — minimal respondent burden",
"• Produces a single index value useful for health economic analyses (QALYs)",
"• Available in >170 languages; validated across diseases and countries",
]
add_multiline_tb(s8, 0.5, 5.5, 12.3, 1.8,
[(p, False, MID_GREY) for p in eq5_pts], font_size=14.5, line_spacing=19)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — Other Generic Measures
# ═══════════════════════════════════════════════════════════════════════════════
s9 = prs.slides.add_slide(blank)
slide_header(s9, "Other Common Generic HRQoL Measures",
subtitle="SIP · NHP · QWB · PROMIS")
add_rect(s9, 0, 1.26, 13.333, 6.24, LIGHT_BG)
generic_measures = [
("Sickness Impact Profile (SIP)", "Bergner et al., 1983",
"136 items across 12 categories. Highly comprehensive, covers physical and psychosocial dimensions. Lengthy but detailed; suitable for chronic disease research."),
("Nottingham Health Profile (NHP)", "Moineau et al., 1989",
"28 items across 6 domains: energy, pain, emotional reactions, sleep, social isolation, physical mobility. Binary yes/no responses. Easy to administer."),
("Quality of Well-Being Scale (QWB)", "Kaplan et al., 1976",
"34 items. Combines mobility, physical activity, social activity, and symptom/problem complex. Produces a preference-weighted index. Used in cost-effectiveness analyses."),
("PROMIS-29", "PROMIS Network, 2010",
"Patient-Reported Outcomes Measurement Information System, 29-item Health Profile. Covers 7 domains (pain, fatigue, sleep, physical function, anxiety, depression, social function). Item Response Theory based; can be used as a CAT."),
]
for i, (name, author, desc) in enumerate(generic_measures):
by = 1.55 + i * 1.45
add_rect(s9, 0.4, by, 0.15, 1.2, TEAL)
add_tb(s9, 0.65, by, 4.0, 0.45, name, 14.5, bold=True, color=NAVY)
add_tb(s9, 0.65, by + 0.42, 2.5, 0.35, author, 12, italic=True, color=TEAL)
add_tb(s9, 0.65, by + 0.75, 12.1, 0.65, desc, 13, color=MID_GREY)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — Disease-Specific Measures (Cancer & Rheumatology)
# ═══════════════════════════════════════════════════════════════════════════════
s10 = prs.slides.add_slide(blank)
slide_header(s10, "Disease-Specific HRQoL Measures",
subtitle="Cancer, Rheumatology & Urology")
add_rect(s10, 0, 1.26, 13.333, 6.24, LIGHT_BG)
# Table header
add_rect(s10, 0.4, 1.5, 12.3, 0.45, NAVY)
for col_x, col_w, col_text in [(0.5, 3.8, "Instrument"), (4.4, 2.0, "Items"), (6.5, 5.9, "Target Population / Notes")]:
add_tb(s10, col_x, 1.52, col_w, 0.4, col_text, 13, bold=True, color=WHITE)
rows = [
("FACT-G (Functional Assessment Cancer Therapy-General)", "28", "General cancer; covers physical, social, emotional, functional well-being"),
("EORTC QLQ-C30", "30", "Cancer RCTs; 5 functional, 3 symptom, 1 global health/QoL scale"),
("FACT-P", "47", "Prostate cancer — adds prostate-specific subscale to FACT-G"),
("UCLA Prostate Cancer Index", "20", "Urinary, bowel, sexual function after prostate cancer treatment"),
("LupusQoL", "34", "Systemic lupus; 8 domains; only SLE tool with RCT data; 13 languages"),
("SLE-QoL", "40", "SLE; physical + psychological; less emphasis on physical function than LupusQoL"),
("Sarcoidosis Health Questionnaire", "29", "Pulmonary sarcoidosis; daily functioning, vitality"),
("King's Sarcoidosis Questionnaire", "29", "Sarcoidosis; lung, skin, eyes, medications, general"),
]
row_bg = [LIGHT_BG, RGBColor(0xE0, 0xEC, 0xF4)]
for i, (name, items, note) in enumerate(rows):
by = 2.0 + i * 0.6
add_rect(s10, 0.4, by, 12.3, 0.57, row_bg[i % 2])
add_tb(s10, 0.5, by + 0.04, 3.8, 0.5, name, 11.5, bold=False, color=NAVY)
add_tb(s10, 4.4, by + 0.04, 2.0, 0.5, items, 12, color=MID_GREY, align=PP_ALIGN.CENTER)
add_tb(s10, 6.5, by + 0.04, 5.9, 0.5, note, 11.5, color=MID_GREY)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 11 — Measurement Properties
# ═══════════════════════════════════════════════════════════════════════════════
s11 = prs.slides.add_slide(blank)
slide_header(s11, "Properties of a Good HRQoL Instrument",
subtitle="Reliability · Validity · Responsiveness")
add_rect(s11, 0, 1.26, 13.333, 6.24, LIGHT_BG)
props = [
("Reliability", NAVY,
"Consistency of measurement.\n• Test-retest: stable over time when health is unchanged\n• Internal consistency (Cronbach's α ≥ 0.70)\n• Inter-rater: same results across observers"),
("Validity", TEAL,
"Does it measure what it claims?\n• Content validity: covers all relevant domains\n• Construct validity: correlates with related measures\n• Criterion validity: agrees with gold standard"),
("Responsiveness", RGBColor(0x2E, 0x86, 0xAB),
"Ability to detect clinically meaningful change.\n• MCID (minimum clinically important difference)\n• e.g., SF-36 PCS/MCS: MCID = 2.5 points\n• Effect size, standardised response mean"),
("Feasibility", RGBColor(0xF7, 0x77, 0x00),
"Practical considerations:\n• Respondent burden (length, complexity)\n• Mode of administration (paper, electronic, interview)\n• Translation & cross-cultural validity\n• Cost and licensing"),
]
for i, (head, col, body) in enumerate(props):
bx = 0.4 + i * 3.2
add_rect(s11, bx, 1.55, 3.0, 5.5, RGBColor(0xF8, 0xF9, 0xFF))
add_rect(s11, bx, 1.55, 3.0, 0.55, col)
add_tb(s11, bx+0.1, 1.57, 2.8, 0.5, head, 15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s11, bx+0.1, 2.18, 2.8, 4.7, body, 13, color=MID_GREY)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 12 — Summary / Key Takeaways
# ═══════════════════════════════════════════════════════════════════════════════
s12 = prs.slides.add_slide(blank)
add_rect(s12, 0, 0, 13.333, 7.5, NAVY)
add_rect(s12, 0, 0, 13.333, 1.2, TEAL)
add_tb(s12, 0.4, 0.15, 12.5, 0.9, "Key Takeaways", 32, bold=True, color=WHITE)
add_rect(s12, 0, 1.2, 13.333, 0.06, ACCENT)
takeaways = [
("1", "HRQoL is the patient-perceived impact of health on physical, psychological, social and economic domains — distinct from overall QoL."),
("2", "Measurement requires both objective functional data and patient-reported bother/impact — neither alone is sufficient."),
("3", "Generic instruments (SF-36, EQ-5D, SIP, PROMIS-29) allow cross-disease comparisons; disease-specific tools (EORTC, FACT, LupusQoL) are more sensitive to clinically meaningful change."),
("4", "A good HRQoL instrument must demonstrate reliability, validity, responsiveness, and feasibility for the target population."),
("5", "Regulatory bodies now expect HRQoL data (PROs) as primary or secondary endpoints in clinical trials — making valid measurement a clinical and scientific imperative."),
]
for i, (num, text) in enumerate(takeaways):
by = 1.45 + i * 1.16
add_rect(s12, 0.5, by, 0.65, 0.9, TEAL)
add_tb(s12, 0.5, by+0.05, 0.65, 0.85, num, 22, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_tb(s12, 1.35, by + 0.05, 11.5, 0.9, text, 14.5, color=WHITE)
add_rect(s12, 0, 6.9, 13.333, 0.6, TEAL)
add_tb(s12, 0.4, 6.92, 12, 0.4,
"Sources: Campbell-Walsh-Wein Urology · Kaplan & Sadock's Psychiatry · Rheumatology (Elsevier 2022) · Murray & Nadel Respiratory Medicine",
11, color=WHITE)
# ═══════════════════════════════════════════════════════════════════════════════
# Save
# ═══════════════════════════════════════════════════════════════════════════════
out_path = "/tmp/workspace/hrqol-ppt/HRQOL_Presentation.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
cd /tmp/workspace/hrqol-ppt && python build_ppt.py 2>&1
python -c " from pptx import Presentation prs = Presentation('/tmp/workspace/hrqol-ppt/HRQOL_Presentation.pptx') print(f'Slides: {len(prs.slides)}') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text.strip() for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f' Slide {i}: {texts[0] if texts else \"(empty)\"}') "
HRQOL Presentation
Presentation · PPTX
| # | Slide Title | Content |
|---|---|---|
| 1 | Cover | Title, subtitle, source credits |
| 2 | Definition of HRQoL | 3 key definitions (Calman, Cella & Tulsky, Aaronson); quote box; distinction from overall QoL |
| 3 | Core Components | 4 domain boxes (Physical, Psychological, Social, Health Perceptions) + additional components |
| 4 | Why Measure HRQoL? | 4 numbered rationale cards: primary outcome, independence from clinical measures, patient-centred care, regulatory requirement |
| 5 | Measurement Principles | Objective function + patient-reported bother; 5 measurement approaches (self-administered, interviewer, utility, profile, global) |
| 6 | Generic vs Disease-Specific | Side-by-side comparison panels with advantages and instrument lists |
| 7 | SF-36 Deep Dive | 8 domain boxes grouped into PCS/MCS; MCID values; SF-12/SF-8 variants |
| 8 | EQ-5D | 5 dimension cards + VAS + utility index scoring; advantages |
| 9 | Other Generic Measures | SIP, NHP, QWB Scale, PROMIS-29 with item counts and descriptions |
| 10 | Disease-Specific Measures | Table: FACT-G, EORTC QLQ-C30, FACT-P, UCLA Index, LupusQoL, SLE-QoL, Sarcoidosis tools |
| 11 | Measurement Properties | 4 columns: Reliability, Validity, Responsiveness, Feasibility |
| 12 | Key Takeaways | 5 numbered summary points |