Definition,measurement of HRQOL, Common HRQOL measures , create a ppt for this topic

Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Finding Sources
Reading File
Running Command

mkdir -p /tmp/workspace/hrqol-ppt && ls /tmp/workspace/hrqol-ppt/

Writing File

~/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}")
Running Command

cd /tmp/workspace/hrqol-ppt && python build_ppt.py 2>&1

Running Command

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)\"}') "

All 12 slides built and verified. Here's your presentation:

HRQOL Presentation

Presentation · PPTX


What's inside (12 slides, Navy/Teal theme)

#Slide TitleContent
1CoverTitle, subtitle, source credits
2Definition of HRQoL3 key definitions (Calman, Cella & Tulsky, Aaronson); quote box; distinction from overall QoL
3Core Components4 domain boxes (Physical, Psychological, Social, Health Perceptions) + additional components
4Why Measure HRQoL?4 numbered rationale cards: primary outcome, independence from clinical measures, patient-centred care, regulatory requirement
5Measurement PrinciplesObjective function + patient-reported bother; 5 measurement approaches (self-administered, interviewer, utility, profile, global)
6Generic vs Disease-SpecificSide-by-side comparison panels with advantages and instrument lists
7SF-36 Deep Dive8 domain boxes grouped into PCS/MCS; MCID values; SF-12/SF-8 variants
8EQ-5D5 dimension cards + VAS + utility index scoring; advantages
9Other Generic MeasuresSIP, NHP, QWB Scale, PROMIS-29 with item counts and descriptions
10Disease-Specific MeasuresTable: FACT-G, EORTC QLQ-C30, FACT-P, UCLA Index, LupusQoL, SLE-QoL, Sarcoidosis tools
11Measurement Properties4 columns: Reliability, Validity, Responsiveness, Feasibility
12Key Takeaways5 numbered summary points
Sources used: Campbell-Walsh-Wein Urology, Kaplan & Sadock's Comprehensive Textbook of Psychiatry, Rheumatology (Elsevier 2022), Murray & Nadel's Respiratory Medicine.
This is a shared conversation. Sign in to Orris to start your own chat.