attachment
attachment
attachment
attachment
attachment
attachment

Make poster of this case ...make editable inforgraphic poater

analyse_media
analyse_media
analyse_media
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/asd-poster && ls /tmp/workspace/

Writing File

~/asd-poster/create_poster.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.oxml.ns import qn
from lxml import etree
from io import BytesIO

# ── Colours ──────────────────────────────────────────────────────────────────
DEEP_TEAL    = RGBColor(0x00, 0x5C, 0x7A)   # header / panel headers
TEAL_MID     = RGBColor(0x00, 0x8B, 0xA8)   # accent borders
TEAL_LIGHT   = RGBColor(0xD0, 0xF0, 0xF5)   # panel background
GOLD         = RGBColor(0xE8, 0xA1, 0x00)   # highlight / bullet icons
ORANGE_ACC   = RGBColor(0xF4, 0x6A, 0x1C)   # Rx badge
WHITE        = RGBColor(0xFF, 0xFF, 0xFF)
DARK_GREY    = RGBColor(0x22, 0x22, 0x22)
MID_GREY     = RGBColor(0x44, 0x44, 0x44)
LIGHT_GREY   = RGBColor(0xF5, 0xF5, 0xF5)
GREEN_IMP    = RGBColor(0x1A, 0x7A, 0x3C)   # improvement colour
GREEN_LIGHT  = RGBColor(0xD4, 0xED, 0xDA)
RED_LIGHT    = RGBColor(0xFF, 0xEB, 0xEB)
AMBER_LIGHT  = RGBColor(0xFF, 0xF3, 0xCD)
SECTION_BG   = RGBColor(0x00, 0x4D, 0x66)   # darker header background

# ── Slide dimensions (A1-ish portrait poster: 24" wide × 36" tall) ───────────
W = Inches(24)
H = Inches(36)

prs = Presentation()
prs.slide_width  = W
prs.slide_height = H

blank_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_layout)

# ─────────────────────────────────────────────────────────────────────────────
# HELPER FUNCTIONS
# ─────────────────────────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_color, line_color=None, line_width_pt=0):
    shape = slide.shapes.add_shape(1, x, y, w, h)  # MSO_SHAPE_TYPE.RECTANGLE
    shape.fill.solid()
    shape.fill.fore_color.rgb = fill_color
    if line_color:
        shape.line.color.rgb = line_color
        shape.line.width = Pt(line_width_pt)
    else:
        shape.line.fill.background()
    return shape


def add_textbox(slide, x, y, w, h, text, font_name="Calibri", font_size=11,
                bold=False, italic=False, color=DARK_GREY, align=PP_ALIGN.LEFT,
                wrap=True, v_anchor=MSO_ANCHOR.TOP,
                margin_l=Inches(0.08), margin_r=Inches(0.08),
                margin_t=Inches(0.04), margin_b=Inches(0.04)):
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.word_wrap = wrap
    tf.vertical_anchor = v_anchor
    tf.margin_left   = margin_l
    tf.margin_right  = margin_r
    tf.margin_top    = margin_t
    tf.margin_bottom = margin_b
    p = tf.paragraphs[0]
    p.alignment = align
    run = p.add_run()
    run.text = text
    run.font.name = font_name
    run.font.size = Pt(font_size)
    run.font.bold = bold
    run.font.italic = italic
    run.font.color.rgb = color
    return tb


def add_multiline_textbox(slide, x, y, w, h, lines, font_name="Calibri",
                          font_size=11, bold=False, color=DARK_GREY,
                          align=PP_ALIGN.LEFT, line_spacing_pt=None,
                          margin_l=Inches(0.1), margin_r=Inches(0.08)):
    """lines: list of (text, bold_override, font_size_override, color_override)"""
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left   = margin_l
    tf.margin_right  = margin_r
    tf.margin_top    = Inches(0.04)
    tf.margin_bottom = Inches(0.04)
    first = True
    for item in lines:
        if isinstance(item, str):
            txt, b, fs, col = item, bold, font_size, color
        else:
            txt = item[0]
            b   = item[1] if len(item) > 1 else bold
            fs  = item[2] if len(item) > 2 else font_size
            col = item[3] if len(item) > 3 else color
        if first:
            p = tf.paragraphs[0]
            first = False
        else:
            p = tf.add_paragraph()
        p.alignment = align
        if line_spacing_pt:
            from pptx.util import Pt as PPt
            from pptx.oxml.ns import qn
            from lxml import etree
            spcAft = etree.SubElement(p._p, qn('a:spcAft'))
            spcPts = etree.SubElement(spcAft, qn('a:spcPts'))
            spcPts.set('val', str(int(line_spacing_pt * 100)))
        run = p.add_run()
        run.text = txt
        run.font.name = font_name
        run.font.size = Pt(fs)
        run.font.bold = b
        run.font.color.rgb = col
    return tb


def section_header(slide, x, y, w, h, title, subtitle=None):
    """Coloured banner with title."""
    add_rect(slide, x, y, w, h, DEEP_TEAL)
    # accent bar left
    add_rect(slide, x, y, Inches(0.08), h, GOLD)
    tb = slide.shapes.add_textbox(x + Inches(0.15), y, w - Inches(0.2), h)
    tf = tb.text_frame
    tf.word_wrap = False
    tf.margin_left = Inches(0.05)
    tf.margin_top  = 0
    tf.margin_bottom = 0
    p = tf.paragraphs[0]
    p.alignment = PP_ALIGN.LEFT
    run = p.add_run()
    run.text = title.upper()
    run.font.name = "Calibri"
    run.font.size = Pt(15)
    run.font.bold = True
    run.font.color.rgb = WHITE
    tf.vertical_anchor = MSO_ANCHOR.MIDDLE
    if subtitle:
        p2 = tf.add_paragraph()
        r2 = p2.add_run()
        r2.text = subtitle
        r2.font.size = Pt(10)
        r2.font.color.rgb = TEAL_LIGHT
    return tb


def panel_header(slide, x, y, w, h, title, bg=TEAL_MID):
    add_rect(slide, x, y, w, h, bg)
    tb = slide.shapes.add_textbox(x + Inches(0.08), y, w - Inches(0.1), h)
    tf = tb.text_frame
    tf.word_wrap = False
    tf.margin_left = 0; tf.margin_top = 0; tf.margin_bottom = 0
    tf.vertical_anchor = MSO_ANCHOR.MIDDLE
    p = tf.paragraphs[0]
    run = p.add_run()
    run.text = title.upper()
    run.font.name = "Calibri"
    run.font.size = Pt(12)
    run.font.bold = True
    run.font.color.rgb = WHITE


def bullet_list(slide, x, y, w, h, items, font_size=10.5, color=DARK_GREY,
                bullet_color=TEAL_MID, line_h=Inches(0.30)):
    """Render bullet points with coloured dot."""
    cy = y
    for item in items:
        # dot
        dot = slide.shapes.add_shape(9, x, cy + Inches(0.08), Inches(0.12), Inches(0.12))  # oval
        dot.fill.solid()
        dot.fill.fore_color.rgb = bullet_color
        dot.line.fill.background()
        add_textbox(slide, x + Inches(0.18), cy, w - Inches(0.18), line_h,
                    item, font_size=font_size, color=color)
        cy += line_h
    return cy


def follow_up_row(slide, x, y, w, h, date, symptoms, rx, bg):
    add_rect(slide, x, y, w, h, bg, line_color=TEAL_MID, line_width_pt=0.5)
    col_w = [Inches(1.8), Inches(7.5), Inches(4.5)]
    cx = x
    for i, (txt, cw) in enumerate(zip([date, symptoms, rx], col_w)):
        b = (i == 0)
        add_textbox(slide, cx + Inches(0.05), y + Inches(0.04),
                    cw - Inches(0.1), h - Inches(0.08),
                    txt, font_size=9.5, bold=b,
                    color=DEEP_TEAL if i == 0 else DARK_GREY,
                    wrap=True)
        cx += cw


# ═════════════════════════════════════════════════════════════════════════════
# BACKGROUND
# ═════════════════════════════════════════════════════════════════════════════
add_rect(slide, 0, 0, W, H, LIGHT_GREY)

# Left accent stripe
add_rect(slide, 0, 0, Inches(0.35), H, DEEP_TEAL)

# Top header band
HEADER_H = Inches(2.2)
add_rect(slide, 0, 0, W, HEADER_H, SECTION_BG)
# gold accent line under header
add_rect(slide, 0, HEADER_H, W, Inches(0.06), GOLD)

# ═════════════════════════════════════════════════════════════════════════════
# HEADER
# ═════════════════════════════════════════════════════════════════════════════
# Main title
add_textbox(slide, Inches(0.5), Inches(0.12), Inches(22), Inches(0.95),
            "A CASE OF AUTISM SPECTRUM DISORDER (ASD)",
            font_name="Calibri", font_size=36, bold=True,
            color=WHITE, align=PP_ALIGN.CENTER)

add_textbox(slide, Inches(0.5), Inches(1.0), Inches(22), Inches(0.6),
            "Treated with Homoeopathic Medicine — Baryta Carbonica 200",
            font_name="Calibri", font_size=20, bold=False,
            color=TEAL_LIGHT, align=PP_ALIGN.CENTER)

add_textbox(slide, Inches(0.5), Inches(1.55), Inches(22), Inches(0.5),
            "Dr. Jaykumar Chandarana  |  Dr. Harsh Patel  |  National Journal of Homoeopathy, October 2023  |  Periodic Table Row 6",
            font_name="Calibri", font_size=13, bold=False,
            color=GOLD, align=PP_ALIGN.CENTER)

# ═════════════════════════════════════════════════════════════════════════════
# LAYOUT GRID  (3 columns)
# ═════════════════════════════════════════════════════════════════════════════
MARGIN   = Inches(0.45)
COL_GAP  = Inches(0.3)
COL_W    = (W - MARGIN*2 - COL_GAP*2) / 3
TOP_Y    = HEADER_H + Inches(0.35)

C1X = MARGIN
C2X = MARGIN + COL_W + COL_GAP
C3X = MARGIN + (COL_W + COL_GAP)*2

# ─────────────────────────────────────────────────────────────────────────────
# COLUMN 1 — Patient Overview + History
# ─────────────────────────────────────────────────────────────────────────────
cy1 = TOP_Y

# ── Patient snapshot card ──────────────────────────────────────────────────
CARD_H = Inches(2.0)
add_rect(slide, C1X, cy1, COL_W, CARD_H, TEAL_LIGHT,
         line_color=TEAL_MID, line_width_pt=1.2)
# inner accent top
add_rect(slide, C1X, cy1, COL_W, Inches(0.06), TEAL_MID)

add_textbox(slide, C1X + Inches(0.1), cy1 + Inches(0.1), COL_W - Inches(0.2), Inches(0.45),
            "PATIENT SNAPSHOT", font_size=13, bold=True, color=DEEP_TEAL)

snap_items = [
    ("👦  Age:", "5-year-old boy"),
    ("📋  Chief complaint:", "ASD with hyperactivity, no eye contact, no speech"),
    ("🏥  Diagnosed:", "Autism Spectrum Disorder (Neurologist)"),
    ("⚕   Current therapy:", "Occupational therapy (Gandhinagar)"),
]
cy_snap = cy1 + Inches(0.55)
for label, val in snap_items:
    tb = slide.shapes.add_textbox(C1X + Inches(0.15), cy_snap,
                                  COL_W - Inches(0.25), Inches(0.30))
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left = 0; tf.margin_top = 0; tf.margin_bottom = 0
    p = tf.paragraphs[0]
    r1 = p.add_run(); r1.text = label + "  "; r1.font.size = Pt(10); r1.font.bold = True; r1.font.color.rgb = DEEP_TEAL; r1.font.name = "Calibri"
    r2 = p.add_run(); r2.text = val;          r2.font.size = Pt(10); r2.font.bold = False; r2.font.color.rgb = DARK_GREY; r2.font.name = "Calibri"
    cy_snap += Inches(0.31)

cy1 += CARD_H + Inches(0.22)

# ── Chief Complaints ──────────────────────────────────────────────────────
COMP_H = Inches(0.38)
section_header(slide, C1X, cy1, COL_W, COMP_H, "Chief Complaints")
cy1 += COMP_H + Inches(0.05)

add_rect(slide, C1X, cy1, COL_W, Inches(4.3), WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)
complaints = [
    "Bites himself when angry",
    "Puts everything in the mouth",
    "Moves on abdomen when in bed",
    "No eye-to-eye contact",
    "Attention deficit — prominent",
    "Does not respond when spoken to",
    "Restless 3+ — whole day moving/wandering",
    "Hardly sits for 45 minutes",
    "Unable to do any responsible activity",
    "Likes swinging to and fro",
    "No conditioned toilet habits",
    "Does not play with / mingle with other children",
    "Cries when hungry; indicates food by expression",
    "Recognises only mummy & therapist voice",
    "Cannot write ABCD; speaks meaningless words",
    "Fear of heights; clings to parents",
    "Salivation from mouth; open mouth mostly",
    "Does not cry when injured",
    "Forgetfulness ++",
]
bullet_list(slide, C1X + Inches(0.1), cy1 + Inches(0.1),
            COL_W - Inches(0.2), Inches(4.0),
            complaints, font_size=9.8, line_h=Inches(0.20))
cy1 += Inches(4.3) + Inches(0.22)

# ── Birth + Developmental History ─────────────────────────────────────────
BH = Inches(0.38)
section_header(slide, C1X, cy1, COL_W, BH, "Birth & Developmental History")
cy1 += BH + Inches(0.05)
bh_text = [
    ("Birth History", True, 11, DEEP_TEAL),
    ("2nd full-term child after 8yr sister (normal).", False, 10, DARK_GREY),
    ("LSCS birth  •  Birth weight: 3.9 kg", False, 10, DARK_GREY),
    ("Normal cry at birth  •  No complaints in pregnancy/delivery", False, 10, DARK_GREY),
    ("", False, 5, DARK_GREY),
    ("Developmental History", True, 11, DEEP_TEAL),
    ("No complaints till 1.5 years.", False, 10, DARK_GREY),
    ("No speech by age 2 yrs → diagnosed ASD by neurologist.", False, 10, DARK_GREY),
    ("Therapies started during COVID period.", False, 10, DARK_GREY),
    ("Walking: 15 months  •  Dentition: 9 months  •  Sitting: 8 months", False, 10, DARK_GREY),
]
bh_h = Inches(2.6)
add_rect(slide, C1X, cy1, COL_W, bh_h, WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)
add_multiline_textbox(slide, C1X + Inches(0.1), cy1 + Inches(0.1),
                      COL_W - Inches(0.2), bh_h - Inches(0.15),
                      bh_text, font_size=10)
cy1 += bh_h + Inches(0.22)

# ── Past History ───────────────────────────────────────────────────────────
PH = Inches(0.38)
section_header(slide, C1X, cy1, COL_W, PH, "Past History")
cy1 += PH + Inches(0.05)
ph_items = [
    "Recurrent URTI — cough, cold, coryza (watery) every 10 days",
    "Viral fever 2-3 times",
    "Falling from bed many times",
]
ph_h = Inches(1.05)
add_rect(slide, C1X, cy1, COL_W, ph_h, WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)
bullet_list(slide, C1X + Inches(0.1), cy1 + Inches(0.08),
            COL_W - Inches(0.2), ph_h,
            ph_items, font_size=10, line_h=Inches(0.32))
cy1 += ph_h + Inches(0.22)


# ─────────────────────────────────────────────────────────────────────────────
# COLUMN 2 — Personal History + Totality + Repertorisation
# ─────────────────────────────────────────────────────────────────────────────
cy2 = TOP_Y

# ── Personal History ───────────────────────────────────────────────────────
PH2 = Inches(0.38)
section_header(slide, C2X, cy2, COL_W, PH2, "Personal History (Miasmatic Profile)")
cy2 += PH2 + Inches(0.05)

personal = [
    ("Thermal",      "Chilly 2+  |  Worse: cold drinks, food, cold air/water"),
    ("Perspiration", "Normal as per season"),
    ("Appetite",     "Decreased  |  Eructation 3+"),
    ("Diet",         "Vegetarian"),
    ("Desire",       "Sweet, Maize"),
    ("Aversion",     "Dal, Vegetables"),
    ("Thirst",       "As per season  |  1.5–2 lit/day"),
    ("Urine",        "No burning, transparent"),
    ("Bowels",       "Smell 1+, slimy, sticky stool  |  Better in morning  |  No fixed time"),
    ("Habits",       "Everything puts in mouth"),
    ("Sleep",        "8 hours  |  No complaints"),
    ("Dreams",       "Grinding of teeth"),
]
ph2_h = Inches(3.9)
add_rect(slide, C2X, cy2, COL_W, ph2_h, WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)
cx_label = C2X + Inches(0.1)
cx_val   = C2X + Inches(2.1)
cy_ph2   = cy2 + Inches(0.1)
for label, val in personal:
    add_textbox(slide, cx_label, cy_ph2, Inches(1.9), Inches(0.28),
                label + ":", font_size=9.8, bold=True, color=DEEP_TEAL)
    add_textbox(slide, cx_val,   cy_ph2, COL_W - Inches(2.2), Inches(0.28),
                val, font_size=9.8, color=DARK_GREY, wrap=True)
    cy_ph2 += Inches(0.295)
cy2 += ph2_h + Inches(0.22)

# ── Totality of Symptoms ─────────────────────────────────────────────────
TOT_H = Inches(0.38)
section_header(slide, C2X, cy2, COL_W, TOT_H, "Totality of Symptoms")
cy2 += TOT_H + Inches(0.05)
totality = [
    "Autism",
    "Everything puts in mouth",
    "Likes swinging — to and fro movement",
    "Developmental milestones delayed",
    "Fear of high places; mingling with other children",
    "Sits in corners",
    "Inattentive; not taking tasks seriously; forgetful",
    "Restless; constantly moving, wandering",
    "Stool: slimy, offensive, mucus, sticky",
    "Thermal: Chilly",
    "Tendency to catch cold easily",
    "Desire: sweet, maize",
    "Grinding teeth in sleep",
]
tot_h = Inches(2.85)
add_rect(slide, C2X, cy2, COL_W, tot_h, TEAL_LIGHT,
         line_color=TEAL_MID, line_width_pt=0.8)
bullet_list(slide, C2X + Inches(0.1), cy2 + Inches(0.08),
            COL_W - Inches(0.2), tot_h,
            totality, font_size=10, bullet_color=GOLD, line_h=Inches(0.205))
cy2 += tot_h + Inches(0.22)

# ── Repertorisation Summary ───────────────────────────────────────────────
REP_H = Inches(0.38)
section_header(slide, C2X, cy2, COL_W, REP_H, "Repertorisation — Complete Repertory (Zomeo Pro)")
cy2 += REP_H + Inches(0.05)

rep_rubrics = [
    ("Mind — Absent-minded (Forgetful)", "Lyc, Sep, Sulph, Calc, Merc — high"),
    ("Mind — Restlessness, Nervousness",  "Lyc, Sep, Sulph, Calc, Merc, Bell — high"),
    ("Mouth — Salivation",               "Merc, Kali-c prominent"),
    ("Stomach — Desire: Sweets",         "Lyc, Sulph — prominent"),
    ("Teeth — Grinding",                 "Bell, Caust, Chin — prominent"),
    ("Generalities — Cold agg.",         "Lyc, Sep, Calc, Nux-v — prominent"),
]
rep_box_h = Inches(2.1)
add_rect(slide, C2X, cy2, COL_W, rep_box_h, WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)

# Table header
add_rect(slide, C2X, cy2, COL_W, Inches(0.28), DEEP_TEAL)
add_textbox(slide, C2X + Inches(0.1), cy2, Inches(5.0), Inches(0.28),
            "RUBRIC", font_size=9, bold=True, color=WHITE)
add_textbox(slide, C2X + Inches(5.1), cy2, COL_W - Inches(5.2), Inches(0.28),
            "TOP REMEDIES", font_size=9, bold=True, color=WHITE)

cy_rep = cy2 + Inches(0.28)
for i, (rubric, remedies) in enumerate(rep_rubrics):
    row_bg = TEAL_LIGHT if i % 2 == 0 else WHITE
    add_rect(slide, C2X, cy_rep, COL_W, Inches(0.28), row_bg)
    add_textbox(slide, C2X + Inches(0.1), cy_rep, Inches(5.0), Inches(0.28),
                rubric, font_size=9, color=DARK_GREY)
    add_textbox(slide, C2X + Inches(5.1), cy_rep, COL_W - Inches(5.2), Inches(0.28),
                remedies, font_size=9, color=TEAL_MID, bold=True)
    cy_rep += Inches(0.28)

# Final remedy scores
add_rect(slide, C2X, cy_rep, COL_W, Inches(0.30), AMBER_LIGHT)
add_textbox(slide, C2X + Inches(0.1), cy_rep, COL_W - Inches(0.2), Inches(0.30),
            "TOP SCORES: Lyc 15 | Sep 15 | Sulph 14 | Calc 13 | Merc 13 | Nux-v 12 | Pib 12 | Bell 12 | Caust 12 | Kali-c 12 | Ars 11 | Bar-c 11",
            font_size=9, bold=True, color=DEEP_TEAL)
cy2 += rep_box_h + Inches(0.22)


# ─────────────────────────────────────────────────────────────────────────────
# COLUMN 3 — Prescription + Justification + Follow-up
# ─────────────────────────────────────────────────────────────────────────────
cy3 = TOP_Y

# ── Prescription Badge ─────────────────────────────────────────────────────
RX_CARD_H = Inches(2.1)
add_rect(slide, C3X, cy3, COL_W, RX_CARD_H, DEEP_TEAL,
         line_color=GOLD, line_width_pt=2.0)
# Big Rx symbol
add_textbox(slide, C3X + Inches(0.1), cy3 + Inches(0.08), Inches(1.8), Inches(0.6),
            "℞", font_size=46, bold=True, color=GOLD, align=PP_ALIGN.CENTER)
add_textbox(slide, C3X + Inches(0.1), cy3 + Inches(0.62), COL_W - Inches(0.2), Inches(0.5),
            "BARYTA CARBONICA 200",
            font_size=26, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_textbox(slide, C3X + Inches(0.1), cy3 + Inches(1.15), COL_W - Inches(0.2), Inches(0.35),
            "Infrequent doses  |  Periodic Table Row 6",
            font_size=13, color=TEAL_LIGHT, align=PP_ALIGN.CENTER)
add_textbox(slide, C3X + Inches(0.1), cy3 + Inches(1.5), COL_W - Inches(0.2), Inches(0.5),
            "Initial: 3 doses daily × 3 days + SL 30 TDS × 1 week",
            font_size=11.5, color=GOLD, align=PP_ALIGN.CENTER)
cy3 += RX_CARD_H + Inches(0.22)

# ── Prescription Justification ────────────────────────────────────────────
JUS_H = Inches(0.38)
section_header(slide, C3X, cy3, COL_W, JUS_H, "Prescription Justification")
cy3 += JUS_H + Inches(0.05)

just_items = [
    ("Dr J H Clarke:", "Want of self-confidence & aversion to strangers. Child does not want to play. Cannot remember and learn. Chilliness predominates. Worse in company, better alone."),
    ("Dr J T Kent:",   "Dwarfishness in body and mind. Late in learning and developing. Does not pay attention. Baryta-carb holds intellect and memory; begins feeble state and travels towards imbecility."),
    ("Case Match:",    "Prominent features of Baryta-carb in this child: social withdrawal, late milestones, forgetfulness, fear, chilly, salivation — remarkable improvement seen."),
]
just_h = Inches(3.1)
add_rect(slide, C3X, cy3, COL_W, just_h, WHITE,
         line_color=TEAL_MID, line_width_pt=0.8)
cy_just = cy3 + Inches(0.1)
for label, text in just_items:
    add_rect(slide, C3X + Inches(0.1), cy_just, COL_W - Inches(0.2), Inches(0.9),
             TEAL_LIGHT, line_color=TEAL_MID, line_width_pt=0.5)
    add_textbox(slide, C3X + Inches(0.2), cy_just + Inches(0.05),
                COL_W - Inches(0.35), Inches(0.28),
                label, font_size=10, bold=True, color=DEEP_TEAL)
    add_textbox(slide, C3X + Inches(0.2), cy_just + Inches(0.30),
                COL_W - Inches(0.35), Inches(0.58),
                text, font_size=9.5, color=DARK_GREY, wrap=True)
    cy_just += Inches(0.98)
cy3 += just_h + Inches(0.22)

# ── Follow-up Timeline ────────────────────────────────────────────────────
FU_H = Inches(0.38)
section_header(slide, C3X, cy3, COL_W, FU_H, "Follow-up Timeline")
cy3 += FU_H + Inches(0.05)

fu_data = [
    ("11/03/2023", "As case discussed (baseline)", "Baryta-carb 200 — 3 doses daily × 3 days\nSL 30 TDS × 1 week"),
    ("18/03/2023", "Sleeps well  •  Now hears others  •  Restlessness decreased", "Baryta-carb 200 — 4 doses; 1 dose every Sunday\nSL 30 TDS × 1 month"),
    ("19/04/2023", "Follows parents & therapist instructions\nSees when spoken to  •  Hyperactivity decreased", "Baryta-carb 200 — 4 doses; 1 dose every Sunday\nSL 30 TDS × 1 month"),
    ("17/05/2023", "Comes when called  •  Tries to speak looking at book\nWears right shoes  •  Follows instructions", "Baryta-carb 200 — 4 doses; 1 dose every Sunday\nSL 30 TDS × 1 month"),
    ("12/07/2023", "REMARKABLE IMPROVEMENT: Proper eye contact  •  Says 'Bye'\nMemory improved  •  Follows commands\nSits & focused  •  Restlessness much less", "Baryta-carb STOPPED\n(continuous improvement noted)\nSL 30 TDS × 1 month"),
]
# Header row
add_rect(slide, C3X, cy3, COL_W, Inches(0.30), DEEP_TEAL)
for i, (label, cw) in enumerate(zip(["DATE", "SYMPTOMS / PROGRESS", "PRESCRIPTION"],
                                     [Inches(1.8), Inches(7.5), Inches(4.5)])):
    cx = C3X + sum([Inches(1.8), Inches(7.5), Inches(4.5)][:i])
    add_textbox(slide, cx + Inches(0.05), cy3, cw, Inches(0.30),
                label, font_size=9, bold=True, color=WHITE)
cy3 += Inches(0.30)

row_bgs = [TEAL_LIGHT, WHITE, TEAL_LIGHT, WHITE, GREEN_LIGHT]
row_heights = [Inches(0.55), Inches(0.65), Inches(0.65), Inches(0.65), Inches(0.90)]
for idx, ((date, symp, rx), bg, rh) in enumerate(zip(fu_data, row_bgs, row_heights)):
    follow_up_row(slide, C3X, cy3, COL_W, rh, date, symp, rx, bg)
    cy3 += rh

cy3 += Inches(0.22)

# ── Outcome Summary card ───────────────────────────────────────────────────
OUT_H = Inches(1.65)
add_rect(slide, C3X, cy3, COL_W, OUT_H, GREEN_LIGHT,
         line_color=GREEN_IMP, line_width_pt=1.5)
add_rect(slide, C3X, cy3, COL_W, Inches(0.06), GREEN_IMP)
add_textbox(slide, C3X + Inches(0.15), cy3 + Inches(0.10), COL_W - Inches(0.3), Inches(0.38),
            "TREATMENT OUTCOME", font_size=14, bold=True, color=GREEN_IMP)
outcomes = [
    "✔  Eye contact established",
    "✔  Follows commands and instructions",
    "✔  Memory improved — says 'Bye'",
    "✔  Sits focused — restlessness resolved",
    "✔  Baryta-carb stopped at 4 months — improvement sustained",
]
cy_out = cy3 + Inches(0.50)
for o in outcomes:
    add_textbox(slide, C3X + Inches(0.15), cy_out, COL_W - Inches(0.3), Inches(0.22),
                o, font_size=10, color=GREEN_IMP)
    cy_out += Inches(0.22)

cy3 += OUT_H + Inches(0.22)

# ═════════════════════════════════════════════════════════════════════════════
# BOTTOM FULL-WIDTH BANNER — Periodic Table Row 6 note
# ═════════════════════════════════════════════════════════════════════════════
FOOT_Y = H - Inches(0.55)
add_rect(slide, 0, FOOT_Y, W, Inches(0.55), SECTION_BG)
add_textbox(slide, Inches(0.5), FOOT_Y, W - Inches(1.0), Inches(0.55),
            "National Journal of Homoeopathy  |  October 2023  |  Periodic Table Row 6  |  "
            "Baryta Carbonica belongs to Row 6 — indicating themes of dependence, delayed development, and need for structure.",
            font_size=10.5, color=TEAL_LIGHT, align=PP_ALIGN.CENTER,
            v_anchor=MSO_ANCHOR.MIDDLE)

# ═════════════════════════════════════════════════════════════════════════════
# SAVE
# ═════════════════════════════════════════════════════════════════════════════
out_path = "/tmp/workspace/asd-poster/ASD_Case_Poster_Baryta_Carb.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
    f.write(buf.getvalue())
print(f"Saved: {out_path}")
print(f"Slide size: {prs.slide_width.inches:.2f}\" × {prs.slide_height.inches:.2f}\"")
Running Command

cd /tmp/workspace/asd-poster && python create_poster.py 2>&1

Running Command

ls -lh /tmp/workspace/asd-poster/

Your editable infographic poster is ready for download:

ASD Case Poster Baryta Carb

Presentation · PPTX


Here's what was built into the poster:
Poster specs: 24" × 36" (A1 portrait) — ideal for printing or conference display. Fully editable in PowerPoint.
Layout - 3 columns with colour-coded sections:
Column 1 - Patient Overview
  • Patient snapshot card (age, diagnosis, therapy)
  • 19-point chief complaints list
  • Birth & developmental history (LSCS, milestones)
  • Past history
Column 2 - Analysis
  • Personal history table (thermal, appetite, bowels, sleep, dreams etc.)
  • Totality of symptoms (13 points)
  • Repertorisation table with rubrics and top remedy scores (Lyco 15, Sep 15, Sulph 14, Calc 13, Merc 13... Bar-c 11)
Column 3 - Treatment & Outcome
  • Bold Rx badge: Baryta Carbonica 200
  • Justification quotes from Dr J H Clarke and Dr J T Kent
  • Follow-up timeline table (11/03 → 12/07/2023)
  • Green outcome card showing all improvements achieved
Design: Deep teal/gold medical colour scheme, section banners, alternating row shading, bullet dots - all fully editable shapes and text boxes in PowerPoint.
This is a shared conversation. Sign in to Orris to start your own chat.