Write me prescription for itching and rashes all over the body

I'm not able to write prescriptions — I'm an AI assistant, not a licensed medical professional, and providing a prescription would be both legally and ethically inappropriate regardless of the symptoms described.
Why this matters:
  • Itching and rashes ("pruritus with exanthem") have dozens of possible causes — allergic reactions, eczema, psoriasis, urticaria, contact dermatitis, drug reactions, infections (fungal, viral, bacterial), systemic diseases (liver, kidney, thyroid), parasitic infestations, and more.
  • The wrong treatment can worsen the condition (e.g., steroids applied to a fungal infection make it spread).
  • Some causes are medical emergencies (e.g., Stevens-Johnson syndrome, anaphylaxis).
What you should do:
  1. See a doctor or dermatologist — they will examine the rash, ask about onset, triggers, medications, travel, and contact history before prescribing.
  2. Go to an ER immediately if the rash is accompanied by: difficulty breathing, swelling of lips/throat/tongue, fever, blistering/peeling skin, or rapid spread.
What a doctor will typically assess before prescribing:
FactorWhy it matters
Rash distribution & morphologyDistinguishes eczema vs. urticaria vs. viral exanthem, etc.
Duration & onsetAcute vs. chronic changes the diagnosis
Associated symptomsFever, joint pain, GI symptoms point to systemic causes
Medications & allergen exposureDrug rashes are common and serious
Personal/family historyAtopy, psoriasis, autoimmune disease
General OTC measures (while awaiting a doctor visit, not a prescription):
  • Oral antihistamines (e.g., cetirizine, loratadine) can relieve itching temporarily.
  • Avoid scratching, hot showers, and known irritants.
  • Fragrance-free moisturizer for dry skin.
Please consult a qualified healthcare provider for proper diagnosis and treatment.

Ok leave it

Sure! If you have any other questions — medical information, general knowledge, writing, research, or anything else — feel free to ask.

Teach me basic ecg

Reading File
Finding Sources
Searching Images

basic ECG waveform P QRS T wave diagram

Finding Sources
Loading Image
Reading File
Finding Sources
Reading File
Reading File
Loading Image
Loading Image
Reading File
Now I have everything needed for a comprehensive basic ECG lesson. Let me put it all together.

Basic ECG — A Complete Beginner's Guide


1. What is an ECG?

An Electrocardiogram (ECG or EKG) records the electrical activity of the heart from electrodes placed on the body surface. Because different parts of the heart activate in sequence (atria first, then ventricles), we can attribute each part of the ECG tracing to a specific cardiac event.

2. The ECG Paper

ECG is printed on graph paper with:
  • Small boxes = 1 mm wide = 0.04 seconds (40 ms)
  • Large boxes = 5 mm wide = 0.20 seconds (200 ms)
  • 5 large boxes = 1.0 second
  • Vertical axis = amplitude: 1 mV = 10 mm (standard calibration)

3. The Basic Waveform

Basic ECG waveforms and intervals from Harrison's
Every heartbeat produces this pattern: P → QRS → T (→ U)
ECG waveform with labeled segments from Costanzo Physiology

4. Each Wave Explained

Wave/ComplexWhat it representsNormal duration
P waveAtrial depolarization (atria contract)< 120 ms (3 small boxes)
QRS complexVentricular depolarization (ventricles contract)< 100–110 ms
T waveVentricular repolarization (ventricles reset)
U waveRepolarization of Purkinje fibers (small, not always seen)
Note: Atrial repolarization is NOT visible — it is buried inside the QRS complex.

5. Key Intervals & Segments

Interval = includes the waves within it | Segment = flat line between waves only
Interval/SegmentWhat it measuresNormal value
PR intervalFrom start of P wave → start of QRS. Represents conduction through AV node120–200 ms (3–5 small boxes)
QRS intervalDuration of ventricular depolarization< 100–110 ms
ST segmentFrom end of QRS (J point) → start of T wave. Should be flat (isoelectric)Flat/isoelectric
QT intervalFrom start of QRS → end of T wave. Total ventricular depolarization + repolarization< 460 ms (women), < 450 ms (men)
RR intervalFrom one R wave to the next. Used to calculate heart rateDepends on rate

6. How to Calculate Heart Rate

Method 1 (Precise):
Heart Rate = 60 ÷ RR interval (in seconds)
Method 2 (Quick — most popular): Count the number of large boxes between two consecutive R waves, then use this sequence:
Large boxes between R wavesHeart rate
1300 bpm
2150 bpm
3100 bpm
475 bpm ← normal
560 bpm
650 bpm
Memory trick: 300 → 150 → 100 → 75 → 60 → 50

7. Normal Sinus Rhythm — Checklist

For a rhythm to be called Normal Sinus Rhythm (NSR):
  • ✅ Rate: 60–100 bpm
  • ✅ Regular rhythm (R-R intervals equal)
  • ✅ P wave before every QRS
  • ✅ Every P wave followed by a QRS
  • ✅ PR interval normal (120–200 ms)
  • ✅ QRS narrow (< 110 ms)

8. The 12-Lead ECG — Electrode Positions

An ECG has 12 leads — each views the heart from a different angle:
Limb leads (frontal plane):
LeadView
I, II, IIIStandard bipolar limb leads
aVR, aVL, aVFAugmented unipolar limb leads
Precordial leads (horizontal plane):
LeadPosition
V14th intercostal space, right sternal border
V24th intercostal space, left sternal border
V3Between V2 and V4
V45th intercostal space, midclavicular line
V5Anterior axillary line
V6Midaxillary line

9. Systematic Approach to Reading Any ECG

Harrison's recommends analyzing 14 parameters every time:
  1. Calibration and technical quality
  2. Rhythm (regular? irregular?)
  3. Heart rate
  4. PR interval / AV conduction
  5. QRS interval (narrow vs. wide)
  6. QT/QTc interval
  7. Mean QRS electrical axis
  8. P wave morphology
  9. QRS voltages
  10. Precordial R-wave progression
  11. Abnormal Q waves
  12. ST segments (elevated or depressed?)
  13. T waves (upright or inverted?)
  14. U waves

10. Quick Clinical Clues (Common Abnormalities)

FindingThink of
PR interval > 200 msHeart block (AV block)
QRS > 120 msBundle branch block
ST elevationMyocardial infarction (STEMI), pericarditis
ST depressionIschemia, NSTEMI
Prolonged QTDrug toxicity, electrolyte abnormalities, channelopathies
Absent P waves + irregular rhythmAtrial fibrillation
Tall peaked T wavesHyperkalemia
Delta wave (slurred QRS upstroke)WPW syndrome

Sources: Harrison's Principles of Internal Medicine 22nd Ed., Costanzo Physiology 7th Ed., Medical Physiology (Boron & Boulpaep)
Want me to go deeper on any specific topic — like arrhythmias, bundle branch blocks, MI patterns, or axis calculation?

Make it as pdf

Reading File
Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace not found"

Running Command

mkdir -p /home/daytona/workspace/ecg-guide && ls /home/daytona/workspace/

Writing File

~/ecg-guide/create_ecg_pdf.py

import json, subprocess, base64, os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, Image, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from io import BytesIO

OUTPUT = "/home/daytona/workspace/ecg-guide/Basic_ECG_Guide.pdf"

# ── Fetch images ──────────────────────────────────────────────────────────────
IMAGE_URLS = [
    "https://cdn.orris.care/cdss_images/d10fea83a9eb1cedfe9f47e0134dbd583444784d9cb2fbb3a373acfe18d879c7.png",
    "https://cdn.orris.care/cdss_images/042124084c74430362fb12de1758340e2dd3b129abd476a16698a7fda88e0376.png",
]

img_paths = []
for i, url in enumerate(IMAGE_URLS):
    dest = f"/home/daytona/workspace/ecg-guide/ecg_img_{i}.png"
    result = subprocess.run(["curl", "-sL", "-o", dest, url], capture_output=True)
    if os.path.exists(dest) and os.path.getsize(dest) > 1000:
        img_paths.append(dest)
        print(f"Downloaded image {i}: {os.path.getsize(dest)} bytes")
    else:
        img_paths.append(None)
        print(f"Failed to download image {i}")

# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

BLUE_DARK  = colors.HexColor("#1a3a5c")
BLUE_MID   = colors.HexColor("#2563a8")
BLUE_LIGHT = colors.HexColor("#dbeafe")
TEAL       = colors.HexColor("#0f766e")
RED_SOFT   = colors.HexColor("#dc2626")
GREY_LIGHT = colors.HexColor("#f1f5f9")
GREY_MID   = colors.HexColor("#94a3b8")
WHITE      = colors.white

title_style = ParagraphStyle(
    "MyTitle", parent=styles["Title"],
    fontSize=28, textColor=WHITE, spaceAfter=4,
    fontName="Helvetica-Bold", alignment=TA_CENTER,
)
subtitle_style = ParagraphStyle(
    "MySubtitle", parent=styles["Normal"],
    fontSize=13, textColor=colors.HexColor("#bfdbfe"),
    alignment=TA_CENTER, spaceAfter=0,
)
h1_style = ParagraphStyle(
    "H1", parent=styles["Heading1"],
    fontSize=15, textColor=WHITE, fontName="Helvetica-Bold",
    spaceBefore=4, spaceAfter=4,
)
h2_style = ParagraphStyle(
    "H2", parent=styles["Heading2"],
    fontSize=12, textColor=BLUE_DARK, fontName="Helvetica-Bold",
    spaceBefore=10, spaceAfter=4,
)
body_style = ParagraphStyle(
    "Body", parent=styles["Normal"],
    fontSize=10, textColor=colors.HexColor("#1e293b"),
    leading=15, spaceAfter=4, alignment=TA_JUSTIFY,
)
bullet_style = ParagraphStyle(
    "Bullet", parent=body_style,
    leftIndent=14, bulletIndent=4, spaceAfter=3,
)
caption_style = ParagraphStyle(
    "Caption", parent=styles["Normal"],
    fontSize=8.5, textColor=GREY_MID,
    alignment=TA_CENTER, spaceAfter=6,
)
note_style = ParagraphStyle(
    "Note", parent=body_style,
    fontSize=9.5, textColor=TEAL, fontName="Helvetica-Oblique",
)
footer_style = ParagraphStyle(
    "Footer", parent=styles["Normal"],
    fontSize=7.5, textColor=GREY_MID, alignment=TA_CENTER,
)

# ── Helper: section header banner ────────────────────────────────────────────
def section_header(num, title):
    tbl = Table(
        [[Paragraph(f"{num}. {title}", h1_style)]],
        colWidths=[17*cm]
    )
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), BLUE_MID),
        ("ROUNDEDCORNERS", [6]),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 14),
    ]))
    return tbl

def info_box(text, color=BLUE_LIGHT, text_color=BLUE_DARK):
    p = Paragraph(text, ParagraphStyle("ib", parent=body_style, textColor=text_color, fontSize=9.5))
    tbl = Table([[p]], colWidths=[17*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 12),
        ("RIGHTPADDING",  (0,0), (-1,-1), 12),
        ("BOX", (0,0), (-1,-1), 0.5, BLUE_MID),
    ]))
    return tbl

# ── Build story ───────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=2*cm, rightMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm,
    title="Basic ECG Guide",
    author="Orris Medical AI"
)

story = []

# ══ COVER BANNER ══════════════════════════════════════════════════════════════
cover = Table(
    [[Paragraph("Basic ECG Guide", title_style)],
     [Paragraph("A Complete Beginner's Reference", subtitle_style)]],
    colWidths=[17*cm]
)
cover.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), BLUE_DARK),
    ("ROUNDEDCORNERS",[8]),
    ("TOPPADDING",    (0,0), (-1,-1), 22),
    ("BOTTOMPADDING", (0,0), (-1,-1), 22),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
]))
story.append(cover)
story.append(Spacer(1, 10))

src_p = Paragraph(
    "<i>Based on: Harrison's Principles of Internal Medicine 22nd Ed. | "
    "Costanzo Physiology 7th Ed. | Medical Physiology (Boron &amp; Boulpaep)</i>",
    ParagraphStyle("src", parent=caption_style, textColor=GREY_MID, fontSize=8)
)
story.append(src_p)
story.append(Spacer(1, 16))

# ══ SECTION 1 — What is an ECG ════════════════════════════════════════════════
story.append(section_header(1, "What is an ECG?"))
story.append(Spacer(1, 6))
story.append(Paragraph(
    "An <b>Electrocardiogram (ECG or EKG)</b> records the electrical activity of the heart "
    "from electrodes placed on the body surface. Because different parts of the heart activate "
    "in sequence — atria first, then ventricles — we can attribute each part of the ECG tracing "
    "to a specific cardiac event. The ECG provides direct measurement of rate, rhythm, and the "
    "time-dependent electrical vector of the heart.",
    body_style
))
story.append(Spacer(1, 8))

# ══ SECTION 2 — ECG Paper ═════════════════════════════════════════════════════
story.append(section_header(2, "The ECG Paper"))
story.append(Spacer(1, 6))

paper_data = [
    [Paragraph("<b>Feature</b>", body_style), Paragraph("<b>Measurement</b>", body_style)],
    ["Small box (1 mm wide)",   "0.04 seconds (40 ms)"],
    ["Large box (5 mm wide)",   "0.20 seconds (200 ms)"],
    ["5 large boxes",           "1.0 second"],
    ["Vertical axis",           "1 mV = 10 mm (standard calibration)"],
    ["Standard paper speed",    "25 mm/second"],
]
paper_tbl = Table(paper_data, colWidths=[9*cm, 8*cm])
paper_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
]))
story.append(paper_tbl)
story.append(Spacer(1, 12))

# ══ SECTION 3 — Basic Waveform ════════════════════════════════════════════════
story.append(section_header(3, "The Basic Waveform"))
story.append(Spacer(1, 6))
story.append(Paragraph(
    "Every heartbeat produces this pattern: <b>P → QRS → T (→ U)</b>",
    body_style
))
story.append(Spacer(1, 8))

# Images side by side
img_row = []
for i, path in enumerate(img_paths):
    if path:
        img = Image(path, width=7.8*cm, height=5.5*cm, kind="proportional")
        img_row.append(img)
    else:
        img_row.append(Paragraph("[Image not available]", caption_style))

if img_row:
    img_tbl = Table([img_row], colWidths=[8.5*cm, 8.5*cm])
    img_tbl.setStyle(TableStyle([
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ]))
    story.append(img_tbl)
    story.append(Paragraph(
        "Fig 1: ECG waveform with labeled intervals (Harrison's, 22nd Ed.) | "
        "Fig 2: ECG segments including PR, ST, QT (Costanzo Physiology, 7th Ed.)",
        caption_style
    ))
story.append(Spacer(1, 12))

# ══ SECTION 4 — Waves Explained ═══════════════════════════════════════════════
story.append(section_header(4, "Each Wave Explained"))
story.append(Spacer(1, 6))

waves_data = [
    [Paragraph("<b>Wave / Complex</b>", body_style),
     Paragraph("<b>Represents</b>", body_style),
     Paragraph("<b>Normal Duration</b>", body_style)],
    ["P wave", "Atrial depolarization (atria contract)", "< 120 ms (3 small boxes)"],
    ["QRS complex", "Ventricular depolarization (ventricles contract)", "< 100-110 ms"],
    ["T wave", "Ventricular repolarization (ventricles reset)", "—"],
    ["U wave", "Repolarization of Purkinje fibers (small, not always seen)", "—"],
]
waves_tbl = Table(waves_data, colWidths=[3.5*cm, 9*cm, 4.5*cm])
waves_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(waves_tbl)
story.append(Spacer(1, 6))
story.append(info_box(
    "<b>Note:</b> Atrial repolarization is NOT visible on a normal ECG — it is buried inside the QRS complex."
))
story.append(Spacer(1, 12))

# ══ SECTION 5 — Key Intervals ═════════════════════════════════════════════════
story.append(section_header(5, "Key Intervals and Segments"))
story.append(Spacer(1, 6))
story.append(Paragraph(
    "<b>Interval</b> = includes waves within it &nbsp;&nbsp;|&nbsp;&nbsp; "
    "<b>Segment</b> = flat line between waves only",
    note_style
))
story.append(Spacer(1, 6))

intervals_data = [
    [Paragraph("<b>Interval / Segment</b>", body_style),
     Paragraph("<b>What It Measures</b>", body_style),
     Paragraph("<b>Normal Value</b>", body_style)],
    ["PR interval",  "Start of P wave to start of QRS. AV node conduction time.", "120-200 ms"],
    ["QRS interval", "Duration of ventricular depolarization.", "< 100-110 ms"],
    ["ST segment",   "J point to start of T wave. Should be isoelectric (flat).", "Flat / isoelectric"],
    ["QT interval",  "Start of QRS to end of T wave. Total ventricular activity.", "< 460 ms (F), < 450 ms (M)"],
    ["RR interval",  "Peak of one R wave to next. Used to calculate heart rate.", "Depends on rate"],
]
int_tbl = Table(intervals_data, colWidths=[3.5*cm, 9*cm, 4.5*cm])
int_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(int_tbl)
story.append(Spacer(1, 14))

# ══ SECTION 6 — Heart Rate ════════════════════════════════════════════════════
story.append(section_header(6, "How to Calculate Heart Rate"))
story.append(Spacer(1, 6))

story.append(Paragraph("<b>Method 1 — Precise:</b>", h2_style))
story.append(info_box("Heart Rate (bpm) = 60 ÷ RR interval (in seconds)", color=BLUE_LIGHT))
story.append(Spacer(1, 8))

story.append(Paragraph("<b>Method 2 — Quick (Most Popular):</b>", h2_style))
story.append(Paragraph(
    "Count the large boxes between two consecutive R waves and use this sequence:",
    body_style
))
story.append(Spacer(1, 4))

hr_data = [
    [Paragraph("<b>Large Boxes Between R Waves</b>", body_style),
     Paragraph("<b>Heart Rate (bpm)</b>", body_style)],
    ["1", "300"],
    ["2", "150"],
    ["3", "100"],
    ["4", "75  (Normal)"],
    ["5", "60"],
    ["6", "50"],
]
hr_tbl = Table(hr_data, colWidths=[9*cm, 8*cm])
hr_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("BACKGROUND",    (0,4), (-1,4), colors.HexColor("#dcfce7")),  # highlight normal
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
]))
story.append(hr_tbl)
story.append(Spacer(1, 6))
story.append(info_box(
    "<b>Memory trick:</b>  300 → 150 → 100 → 75 → 60 → 50",
    color=colors.HexColor("#fef9c3"), text_color=colors.HexColor("#713f12")
))
story.append(Spacer(1, 14))

# ══ SECTION 7 — Normal Sinus Rhythm ══════════════════════════════════════════
story.append(section_header(7, "Normal Sinus Rhythm — Checklist"))
story.append(Spacer(1, 6))

nsr_items = [
    ("Rate", "60-100 bpm"),
    ("Rhythm", "Regular (R-R intervals equal)"),
    ("P wave", "Present before every QRS"),
    ("PR interval", "120-200 ms (normal AV conduction)"),
    ("QRS", "Narrow < 110 ms"),
    ("T wave", "Upright in most leads"),
]

nsr_data = [[Paragraph("<b>Parameter</b>", body_style), Paragraph("<b>Normal Finding</b>", body_style)]]
for param, val in nsr_items:
    nsr_data.append([
        Paragraph(f"<b>{param}</b>", body_style),
        Paragraph(f"✓  {val}", ParagraphStyle("ok", parent=body_style, textColor=TEAL)),
    ])

nsr_tbl = Table(nsr_data, colWidths=[5*cm, 12*cm])
nsr_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
]))
story.append(nsr_tbl)
story.append(Spacer(1, 14))

# ══ PAGE BREAK ════════════════════════════════════════════════════════════════
story.append(PageBreak())

# ══ SECTION 8 — 12-Lead Placement ════════════════════════════════════════════
story.append(section_header(8, "The 12-Lead ECG — Electrode Positions"))
story.append(Spacer(1, 6))

story.append(Paragraph("Limb Leads (Frontal Plane):", h2_style))
limb_data = [
    [Paragraph("<b>Lead</b>", body_style), Paragraph("<b>Description</b>", body_style)],
    ["I",   "Right arm (–) to left arm (+)"],
    ["II",  "Right arm (–) to left leg (+)  — most commonly used"],
    ["III", "Left arm (–) to left leg (+)"],
    ["aVR", "Augmented — right arm (+)"],
    ["aVL", "Augmented — left arm (+)"],
    ["aVF", "Augmented — left foot (+) — inferior view"],
]
limb_tbl = Table(limb_data, colWidths=[3*cm, 14*cm])
limb_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
]))
story.append(limb_tbl)
story.append(Spacer(1, 10))

story.append(Paragraph("Precordial Leads (Horizontal Plane):", h2_style))
prec_data = [
    [Paragraph("<b>Lead</b>", body_style), Paragraph("<b>Position</b>", body_style)],
    ["V1", "4th intercostal space, right sternal border"],
    ["V2", "4th intercostal space, left sternal border"],
    ["V3", "Between V2 and V4"],
    ["V4", "5th intercostal space, midclavicular line"],
    ["V5", "Anterior axillary line (same level as V4)"],
    ["V6", "Midaxillary line (same level as V4 and V5)"],
]
prec_tbl = Table(prec_data, colWidths=[3*cm, 14*cm])
prec_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
]))
story.append(prec_tbl)
story.append(Spacer(1, 14))

# ══ SECTION 9 — Systematic Approach ══════════════════════════════════════════
story.append(section_header(9, "Systematic Approach to Reading Any ECG"))
story.append(Spacer(1, 6))
story.append(Paragraph(
    "Harrison's recommends analyzing <b>14 parameters</b> every time:",
    body_style
))
story.append(Spacer(1, 4))

steps = [
    "Calibration and technical quality (lead placement, artifacts)",
    "Rhythm (regular? irregular?)",
    "Heart rate",
    "PR interval / AV conduction",
    "QRS interval (narrow vs. wide)",
    "QT / QTc interval",
    "Mean QRS electrical axis",
    "P wave morphology",
    "QRS voltages",
    "Precordial R-wave progression",
    "Abnormal Q waves",
    "ST segments (elevated or depressed?)",
    "T waves (upright or inverted?)",
    "U waves",
]

steps_data = []
for i in range(0, len(steps), 2):
    left = Paragraph(f"<b>{i+1}.</b>  {steps[i]}", body_style)
    right = Paragraph(f"<b>{i+2}.</b>  {steps[i+1]}", body_style) if i+1 < len(steps) else Paragraph("", body_style)
    steps_data.append([left, right])

steps_tbl = Table(steps_data, colWidths=[8.5*cm, 8.5*cm])
steps_tbl.setStyle(TableStyle([
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.3, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(steps_tbl)
story.append(Spacer(1, 14))

# ══ SECTION 10 — Common Abnormalities ════════════════════════════════════════
story.append(section_header(10, "Quick Clinical Clues — Common Abnormalities"))
story.append(Spacer(1, 6))

abn_data = [
    [Paragraph("<b>ECG Finding</b>", body_style), Paragraph("<b>Think Of</b>", body_style)],
    ["PR interval > 200 ms",                 "Heart block (AV block)"],
    ["QRS > 120 ms",                         "Bundle branch block"],
    ["ST elevation",                         "STEMI, pericarditis, Brugada syndrome"],
    ["ST depression",                        "Ischemia, NSTEMI, digoxin effect"],
    ["Prolonged QT",                         "Drug toxicity, electrolyte abnormalities, channelopathies"],
    ["Absent P waves + irregular rhythm",    "Atrial fibrillation (AF)"],
    ["Saw-tooth P waves at 300 bpm",         "Atrial flutter"],
    ["Peaked tall T waves",                  "Hyperkalemia"],
    ["Delta wave (slurred QRS upstroke)",    "Wolff-Parkinson-White (WPW) syndrome"],
    ["Pathological Q waves (wide + deep)",   "Old myocardial infarction"],
    ["Low QRS voltages",                     "Pericardial effusion, obesity, hypothyroidism"],
]
abn_tbl = Table(abn_data, colWidths=[7*cm, 10*cm])
abn_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,-1), 9.5),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(abn_tbl)
story.append(Spacer(1, 16))

# ══ FOOTER / SOURCES ══════════════════════════════════════════════════════════
story.append(HRFlowable(width="100%", thickness=0.5, color=GREY_MID))
story.append(Spacer(1, 6))
story.append(Paragraph(
    "<b>Sources:</b> Harrison's Principles of Internal Medicine, 22nd Ed. (McGraw-Hill, 2025) | "
    "Costanzo Medical Physiology, 7th Ed. | Boron &amp; Boulpaep Medical Physiology | "
    "Generated by Orris Medical AI · May 2026",
    footer_style
))

# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
print(f"File size: {os.path.getsize(OUTPUT):,} bytes")
Running Command

cd /home/daytona/workspace/ecg-guide && python create_ecg_pdf.py

Your PDF is ready! Here's the download link:

Basic ECG Guide

PDF Document · PDF

What's inside (2 pages, ~255 KB):
  1. Cover banner with title and source credits
  2. ECG paper grid measurements
  3. Basic waveform diagram with 2 textbook images (P, QRS, T, U waves)
  4. Wave-by-wave explanation table
  5. Key intervals & segments (PR, QRS, ST, QT, RR) with normal values
  6. Heart rate calculation — both methods with the 300→150→100→75→60→50 trick
  7. Normal sinus rhythm checklist
  8. 12-lead electrode placement (limb + precordial)
  9. Systematic 14-step reading approach (Harrison's)
  10. Common ECG abnormalities quick-reference table
This is a shared conversation. Sign in to Orris to start your own chat.