Detailed notes on cpr for adults and children

Reading File
Finding Sources
Finding Sources
Searching the Web

AHA 2024 CPR guidelines adults children BLS

Finding Sources
Reading Web Page

https://cpr.heart.org/en/resuscitation-science/cpr-and-ecc-g…

Reading File
Finding Sources
Searching the Web

pediatric CPR children infants 2024 guidelines compression depth ratio AHA PALS

Reading File
Reading File
I now have rich, authoritative content from multiple medical textbooks and current AHA/AAP guidelines. Let me compile comprehensive notes.

Cardiopulmonary Resuscitation (CPR) - Detailed Notes

Adults and Children (AHA 2020/2024/2025 Guidelines)


1. What Is CPR and Why It Matters

CPR (Cardiopulmonary Resuscitation) is a series of actions designed to maintain circulation and oxygenation when the heart stops. The goal of Basic Life Support (BLS) is to maintain viability of the central nervous system, heart, and other vital organs until definitive return of spontaneous circulation (ROSC) can be achieved.
Survival impact:
  • For in-hospital cardiac arrest, survival to discharge was 33% when CPR was started within the first minute vs. 14% when delayed beyond 1 minute.
  • When VF was the initial rhythm: 50% vs. 32% with early vs. delayed CPR.
  • Bystander CPR significantly improves pediatric survival but is still infrequently administered.
(Source: Braunwald's Heart Disease, p. 667; Rosen's Emergency Medicine)

2. The Chain of Survival

Both adult and pediatric cardiac arrest share a unified chain:
  1. Prevention and preparedness (pre-arrest)
  2. Early recognition of cardiac arrest
  3. Activation of emergency services (call 911 / emergency response)
  4. High-quality CPR (compressions + ventilation)
  5. Defibrillation (AED / manual)
  6. Advanced life support / ACLS/PALS
  7. Post-resuscitation care

3. Sequence: C-A-B (Not A-B-C)

The older A-B-C (Airway-Breathing-Compressions) sequence was replaced by C-A-B (Compressions-Airway-Breathing) based on evidence that:
  • Starting with compressions minimizes delay to perfusion.
  • Avoids excessive ventilation.
  • Makes bystanders more likely to attempt CPR.
  • Simulated models showed no delay in ventilation initiation with C-A-B vs. A-B-C.
Exception: Pediatric respiratory arrest (where the primary cause is respiratory, not cardiac) - the A-B-C approach may still be preferred, but C-A-B is acceptable and feasible.

4. Adult CPR

Step-by-Step

StepAction
1Verify environmental safety
2Check responsiveness (tap and shout)
3Call for help / activate emergency response system (call 911)
4Send someone for AED
5Check for pulse (carotid) - no more than 10 seconds
6If no pulse / unsure, begin chest compressions immediately
7After 30 compressions, open airway (head-tilt chin-lift), give 2 rescue breaths
8Continue 30:2 cycles until AED arrives / EMS takes over / signs of ROSC
9Apply AED as soon as available and follow prompts
  • If alone without a phone: leave the victim briefly to call 911 and get AED, then return and start CPR.
  • If others are present: delegate one person to call 911 and another to get AED while you start CPR immediately.

Compression Technique (Adults)

ParameterRecommendation
Hand placementHeel of both hands on the lower half of the sternum (breastbone)
Arm positionArms straight at elbows; use shoulder/back as fulcrum
Rate100-120 compressions/minute
DepthAt least 2 inches (5 cm), no more than 2.4 inches (6 cm)
Chest recoilAllow full recoil after each compression - do NOT lean on the chest
InterruptionsLimit to less than 10 seconds
Compression fractionAim for at least 60% of total CPR time as active compressions
Rescuer rotationSwitch compressor every 2 minutes (compression quality declines after 90-120 sec)
(Source: AHA 2024 Adult BLS Guidelines; Braunwald's Heart Disease)

Compression:Ventilation Ratio (Adults)

SituationRatio
No advanced airway (1 or 2 rescuers)30:2
Advanced airway in place (ETT or supraglottic)Continuous compressions at 100-120/min + 1 breath every 6 seconds (10/min)
Each rescue breath duration1 second
Note: For adults without an advanced airway, healthcare professionals may consider continuous chest compressions with asynchronous breaths as an alternative (AHA Class 2b).

AED Use in Adults

  • Attach as soon as available; follow prompts.
  • Minimize pause in compressions for rhythm analysis and shock delivery.
  • After shock: resume CPR immediately for 2 minutes before re-checking rhythm.
  • Audiovisual feedback devices are recommended to optimize CPR quality in real time (AHA Class 2a).

5. Pediatric CPR

Key Principle: Children Are NOT Small Adults

Cardiac arrest in children is usually secondary to respiratory failure (hypoxia leads to asystole/PEA), rather than the primary cardiac event more common in adults. This makes effective ventilation especially important in children.
Most common pediatric arrest rhythms: Asystole and PEA (not VF as in adults).
Age definitions used:
  • Infant: Birth to 1 year
  • Child: 1 year to puberty (axillary hair in males / breast development in females)
  • Adolescent/Adult protocol: Post-puberty or >55 kg

Step-by-Step Pediatric CPR

StepAction
1Verify safety; check responsiveness
2Call for help
3If witnessed collapse: call 911 immediately, then CPR
4If unwitnessed collapse (child/infant alone): give 2 minutes of CPR first, then call 911 and get AED
5Check brachial pulse in infants; carotid or femoral in children (no more than 10 sec)
6Begin compressions if pulseless or pulse <60/min with signs of poor perfusion
7Apply 30:2 (single rescuer) or 15:2 (2+ rescuers, pre-puberty)
8Attach AED when available

Compression Technique (Pediatric)

Age GroupTechniqueDepthRate
Infant (< 1 yr)Two-thumb encircling hands technique (preferred, 2+ rescuers) OR heel of one hand if cannot encircle~1.5 inches (4 cm) / 1/3 AP diameter100-120/min
Small child (1-8 yr)One hand on lower sternum~2 inches (5 cm) / 1/3 AP diameter100-120/min
Older child/adolescentTwo hands (same as adult)Same as adult (5-6 cm)100-120/min
Important update (2025): The two-finger technique along the sternum for infants has been eliminated - it was found ineffective at achieving proper depth. Use one-hand or two-thumb encircling technique.
(Source: Barash Clinical Anesthesia, p. 4937; Rosen's Emergency Medicine; AHA/AAP 2025 Guidelines)

Compression:Ventilation Ratio (Children)

SituationRatio
Single rescuer, any age child30:2
2+ rescuers, pre-puberty child15:2
2+ rescuers, post-puberty (adolescent)30:2
Advanced airway in placeContinuous compressions + 1 breath every 2-3 seconds (20-30/min)
This differs from adults where it is always 30:2 regardless of rescuer count.

Defibrillation in Children

ParameterDose
First shock2 J/kg
Second shock4 J/kg
Subsequent shocks≥4 J/kg, max 10 J/kg or adult dose
Defibrillation is less frequently necessary in children (since VF is less common), but the same principles apply.

Drug Therapy in Pediatric Arrest

DrugDose
Epinephrine IV/IO0.01 mg/kg (0.1 mg/mL concentration), max dose 1 mg, every 3-5 min
Amiodarone or LidocaineFor shockable rhythms (VF/pVT), after 2nd shock
  • Interosseous (IO) route in the anterior tibia is especially useful in small children for rapid vascular access.

6. Infant-Specific Considerations

  • Airway: Mouth-to-mouth-and-nose technique (cover both mouth and nose of infant).
  • Foreign body airway obstruction (FBAO):
    • Infants: 5 back blows alternating with 5 chest thrusts (NOT abdominal thrusts - abdominal thrusts are contraindicated in infants).
    • Children: 5 back blows alternating with 5 abdominal thrusts (updated from abdominal thrusts only).
  • Pulse check: Brachial artery (infants), not carotid.
  • Resuscitation board: Place under the child to ensure a firm surface.

7. High-Quality CPR - Summary of Key Metrics

ComponentAdultChildInfant
Compression rate100-120/min100-120/min100-120/min
Compression depth2-2.4 inches (5-6 cm)~2 inches (5 cm) / 1/3 AP~1.5 inches (4 cm) / 1/3 AP
Hand position2 hands, lower sternum1-2 hands, lower sternum2 thumbs or 1 hand heel
Ratio (1 rescuer)30:230:230:2
Ratio (2+ rescuers)30:215:2 (pre-puberty)15:2
Advanced airway breath rate10/min (1 per 6 sec)20-30/min (1 per 2-3 sec)20-30/min
RecoilFull recoil, no leaningFull recoilFull recoil
Interruption limit< 10 seconds< 10 seconds< 10 seconds
First defibrillation energy200 J (biphasic)2 J/kg2 J/kg

8. Post-Resuscitation Care (After ROSC)

After successful ROSC, the priorities are:
  1. Correct reversible causes - the "H's and T's":
    • Hypovolemia, Hypoxia, Hydrogen ion (acidosis), Hypo/Hyperkalemia, Hypothermia
    • Tension pneumothorax, Tamponade (cardiac), Toxins, Thrombosis (PE/coronary)
  2. Coronary reperfusion - immediate PCI if coronary cause suspected.
  3. Targeted Temperature Management (TTM) - prevents secondary neurological injury.
  4. Neurological critical care - monitor and protect brain function.
  5. Transport to facility capable of aggressive post-arrest care (PCI, TTM, ICU).
Post-arrest myocardial dysfunction is common even after brief arrest due to generalized decrease in myocardial function (similar to regional hypoperfusion/stunning).
(Source: Barash Clinical Anesthesia, p. 4937)

9. Precordial Thump

  • A single firm blow to the junction of the middle and lower thirds of the sternum from a height of 8-10 inches.
  • May be attempted by a properly trained rescuer in a pulseless cardiac arrest without monitoring when a defibrillator is NOT immediately available.
  • Does NOT impact overall ROSC or survival.
  • Do NOT use in an unmonitored patient with rapid tachycardia without complete loss of consciousness.
  • Abandon if spontaneous pulse does not return immediately.
(Source: Braunwald's Heart Disease)

10. Special Circumstances

Drowning

  • CPR with rescue breaths should be started before AED application (hypoxia is the primary driver).
  • AED use is still reasonable once CPR has been initiated.

Witnessed VF Arrest (Adult)

  • Survival increases dramatically: from 4.7% to 17.6% with improved early resuscitation techniques.
  • For witnessed VF: attach AED and shock as soon as possible; resume CPR immediately after.

Sources

Create a quick reference PDF or CPR cheat sheet I can print

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null && python3 -c "import reportlab; print('…

Running Command

mkdir -p /home/daytona/workspace/cpr-cheatsheet

Writing File

~/cpr-cheatsheet/build_cpr.py

from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.platypus import (
    SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer,
    HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/cpr-cheatsheet/CPR_Quick_Reference.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
RED      = colors.HexColor("#C0392B")
DARK_RED = colors.HexColor("#922B21")
BLUE     = colors.HexColor("#1A5276")
TEAL     = colors.HexColor("#117A65")
ORANGE   = colors.HexColor("#D35400")
GREY     = colors.HexColor("#F2F3F4")
LGREY    = colors.HexColor("#D5D8DC")
WHITE    = colors.white
BLACK    = colors.black
YELLOW   = colors.HexColor("#F9E79F")

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

def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_style = S("Title", fontSize=22, textColor=WHITE, alignment=TA_CENTER,
                fontName="Helvetica-Bold", spaceAfter=2)
subtitle_style = S("Subtitle", fontSize=9, textColor=YELLOW, alignment=TA_CENTER,
                   fontName="Helvetica", spaceAfter=0)
section_style = S("Section", fontSize=11, textColor=WHITE, alignment=TA_CENTER,
                  fontName="Helvetica-Bold", spaceAfter=0, spaceBefore=0)
body_style = S("Body", fontSize=8.5, textColor=BLACK, fontName="Helvetica",
               leading=12, spaceAfter=2)
bold_body = S("BoldBody", fontSize=8.5, textColor=BLACK, fontName="Helvetica-Bold",
              leading=12)
small_style = S("Small", fontSize=7.5, textColor=colors.HexColor("#555555"),
                fontName="Helvetica", leading=10)
note_style  = S("Note",  fontSize=7.5, textColor=DARK_RED, fontName="Helvetica-BoldOblique",
                leading=10, alignment=TA_CENTER)
col_head = S("ColHead", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold",
             alignment=TA_CENTER, leading=11)
cell_c = S("CellC", fontSize=8, textColor=BLACK, fontName="Helvetica",
           alignment=TA_CENTER, leading=11)
cell_l = S("CellL", fontSize=8, textColor=BLACK, fontName="Helvetica",
           alignment=TA_LEFT, leading=11)

def hdr_para(text, bg, fg=WHITE, size=11):
    st = S(text[:10], fontSize=size, textColor=fg, fontName="Helvetica-Bold",
           alignment=TA_CENTER, backColor=bg)
    return Paragraph(text, st)

# ── Helper: section header bar ───────────────────────────────────────────────
def section_header(text, bg_color, fg_color=WHITE):
    data = [[Paragraph(text, S("sh", fontSize=10, textColor=fg_color,
                                fontName="Helvetica-Bold", alignment=TA_CENTER))]]
    t = Table(data, colWidths=[7.5*inch])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg_color),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
        ("RIGHTPADDING",  (0,0),(-1,-1), 6),
        ("ROUNDEDCORNERS", [3]),
    ]))
    return t

def table_style(header_color, alt_color=GREY):
    return TableStyle([
        ("BACKGROUND",    (0,0), (-1,0),  header_color),
        ("TEXTCOLOR",     (0,0), (-1,0),  WHITE),
        ("FONTNAME",      (0,0), (-1,0),  "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,-1), 8),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, alt_color]),
        ("GRID",          (0,0), (-1,-1), 0.4, LGREY),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("RIGHTPADDING",  (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ])

# ── Document ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=letter,
    leftMargin=0.5*inch,
    rightMargin=0.5*inch,
    topMargin=0.45*inch,
    bottomMargin=0.4*inch,
    title="CPR Quick Reference",
    author="AHA 2024/2025 Guidelines"
)

story = []
W = 7.5 * inch   # usable width

# ══════════════════════════════════════════════════════════════════
# TITLE BANNER
# ══════════════════════════════════════════════════════════════════
title_data = [[
    Paragraph("CPR Quick Reference Card", title_style),
]]
title_table = Table(title_data, colWidths=[W])
title_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), RED),
    ("TOPPADDING",    (0,0),(-1,-1), 10),
    ("BOTTOMPADDING", (0,0),(-1,-1), 4),
    ("LEFTPADDING",   (0,0),(-1,-1), 6),
    ("RIGHTPADDING",  (0,0),(-1,-1), 6),
]))
story.append(title_table)

sub_data = [[Paragraph("Based on AHA 2024/2025 Guidelines  |  Adults • Children • Infants", subtitle_style)]]
sub_table = Table(sub_data, colWidths=[W])
sub_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), DARK_RED),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
]))
story.append(sub_table)
story.append(Spacer(1, 6))

# ══════════════════════════════════════════════════════════════════
# CHAIN OF SURVIVAL  (horizontal)
# ══════════════════════════════════════════════════════════════════
story.append(section_header("⛓  CHAIN OF SURVIVAL", BLUE))
story.append(Spacer(1, 3))

chain_items = [
    ("1", "Recognize\nCollapse"),
    ("2", "Call 911 /\nGet AED"),
    ("3", "High-Quality\nCPR"),
    ("4", "Defibrillate\n(AED)"),
    ("5", "Advanced\nLife Support"),
    ("6", "Post-Arrest\nCare"),
]
chain_data = [[Paragraph(f"<b>{n}</b><br/><font size='7'>{t}</font>",
               S(f"ch{n}", fontSize=8, textColor=WHITE, fontName="Helvetica-Bold",
                 alignment=TA_CENTER, leading=11))
               for n,t in chain_items]]
chain_widths = [W/6] * 6
chain_table = Table(chain_data, colWidths=chain_widths)
chain_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), BLUE),
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [BLUE]),
    ("GRID",          (0,0), (-1,-1), 0.6, WHITE),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(chain_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# SEQUENCE  C-A-B
# ══════════════════════════════════════════════════════════════════
story.append(section_header("📋  UNIVERSAL SEQUENCE  (C-A-B)", TEAL))
story.append(Spacer(1, 3))

seq_data = [
    [Paragraph("<b>Step</b>", col_head), Paragraph("<b>Action</b>", col_head)],
    ["1", "Verify scene safety"],
    ["2", "Check responsiveness — tap shoulders, shout 'Are you OK?'"],
    ["3", "Shout for help; send someone to call 911 and get AED"],
    ["4", "Check pulse (≤10 sec): Carotid (adult/child) | Brachial (infant)"],
    ["5", "No pulse / unsure → begin CHEST COMPRESSIONS immediately"],
    ["6", "After 30 compressions: open airway (head-tilt chin-lift), give 2 rescue breaths (1 sec each)"],
    ["7", "Continue CPR cycles; attach AED as soon as available and follow prompts"],
    ["8", "Rotate compressor every 2 min to maintain compression quality"],
]
col_w = [0.35*inch, 7.15*inch]
seq_table = Table(seq_data, colWidths=col_w)
seq_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  TEAL),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,1),(-1,-1), "Helvetica"),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 8),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 5),
    ("RIGHTPADDING",  (0,0),(-1,-1), 5),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(0,-1),  "CENTER"),
    ("ALIGN",         (1,0),(1,-1),  "LEFT"),
    ("FONTNAME",      (0,5),(1,5),   "Helvetica-Bold"),
]))
story.append(seq_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# COMPRESSION PARAMETERS  (3-column comparison)
# ══════════════════════════════════════════════════════════════════
story.append(section_header("💪  COMPRESSION PARAMETERS", RED))
story.append(Spacer(1, 3))

comp_data = [
    [Paragraph("<b>Parameter</b>", col_head),
     Paragraph("<b>Adult</b>", col_head),
     Paragraph("<b>Child (1yr–puberty)</b>", col_head),
     Paragraph("<b>Infant (&lt;1 yr)</b>", col_head)],
    ["Rate",      "100–120 / min",     "100–120 / min",     "100–120 / min"],
    ["Depth",     "2–2.4 in (5–6 cm)", "~2 in (5 cm)\n1/3 AP diameter", "~1.5 in (4 cm)\n1/3 AP diameter"],
    ["Hand\nPlacement", "2 hands – lower sternum", "1 hand – lower sternum", "2-thumb encircling\n(preferred 2+ rescuers)\nOR heel of 1 hand"],
    ["Recoil",    "Full — do NOT lean on chest",  "Full — do NOT lean",  "Full — do NOT lean"],
    ["Interruptions", "< 10 seconds",  "< 10 seconds",  "< 10 seconds"],
]
comp_widths = [1.3*inch, 2.1*inch, 2.1*inch, 2.0*inch]
comp_table = Table(comp_data, colWidths=comp_widths)
comp_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  RED),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 8),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
    ("RIGHTPADDING",  (0,0),(-1,-1), 4),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(-1,-1), "CENTER"),
    ("FONTNAME",      (0,3),(0,-1),  "Helvetica-Bold"),
]))
story.append(comp_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# COMPRESSION : VENTILATION RATIO
# ══════════════════════════════════════════════════════════════════
story.append(section_header("🫁  COMPRESSION : VENTILATION RATIO", ORANGE))
story.append(Spacer(1, 3))

cv_data = [
    [Paragraph("<b>Situation</b>", col_head),
     Paragraph("<b>Adult</b>", col_head),
     Paragraph("<b>Child (pre-puberty)</b>", col_head),
     Paragraph("<b>Child (post-puberty)</b>", col_head)],
    ["Single rescuer\n(no advanced airway)",     "30:2", "30:2", "30:2"],
    ["2+ rescuers\n(no advanced airway)",         "30:2", "15:2", "30:2"],
    ["Advanced airway\n(ETT or SGA)",
     "Continuous compressions\n+ 1 breath / 6 sec (10/min)",
     "Continuous compressions\n+ 1 breath / 2–3 sec (20–30/min)",
     "Continuous compressions\n+ 1 breath / 2–3 sec"],
]
cv_widths = [1.55*inch, 1.95*inch, 2.0*inch, 2.0*inch]
cv_table = Table(cv_data, colWidths=cv_widths)
cv_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  ORANGE),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 8),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
    ("RIGHTPADDING",  (0,0),(-1,-1), 4),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(-1,-1), "CENTER"),
    ("FONTNAME",      (0,1),(0,-1),  "Helvetica-Bold"),
]))
story.append(cv_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# DEFIBRILLATION
# ══════════════════════════════════════════════════════════════════
story.append(section_header("⚡  DEFIBRILLATION (AED)", BLUE))
story.append(Spacer(1, 3))

def_data = [
    [Paragraph("<b>Parameter</b>", col_head),
     Paragraph("<b>Adult / Adolescent</b>", col_head),
     Paragraph("<b>Child (&lt;55 kg / pre-puberty)</b>", col_head)],
    ["1st Shock Energy",   "200 J (biphasic)\nor per device",  "2 J/kg"],
    ["2nd Shock Energy",   "200–360 J",                        "4 J/kg"],
    ["Subsequent Shocks",  "≥ 200 J",                          "≥ 4 J/kg  (max 10 J/kg or adult dose)"],
    ["AED pads",           "Adult pads",                        "Pediatric pads preferred (<8 yr)\nAdult pads if no pediatric available"],
    ["After each shock",   "Resume CPR immediately for 2 min, THEN check rhythm",
                           "Resume CPR immediately for 2 min, THEN check rhythm"],
]
def_widths = [1.6*inch, 2.9*inch, 3.0*inch]
def_table = Table(def_data, colWidths=def_widths)
def_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  BLUE),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 8),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
    ("RIGHTPADDING",  (0,0),(-1,-1), 4),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(-1,-1), "CENTER"),
]))
story.append(def_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# SIDE-BY-SIDE: DRUGS  +  REVERSIBLE CAUSES
# ══════════════════════════════════════════════════════════════════
story.append(section_header("💊  DRUG THERAPY  &  REVERSIBLE CAUSES (H's & T's)", TEAL))
story.append(Spacer(1, 3))

drug_rows = [
    [Paragraph("<b>Drug</b>", col_head), Paragraph("<b>Adult Dose</b>", col_head), Paragraph("<b>Pediatric Dose</b>", col_head)],
    ["Epinephrine", "1 mg IV/IO every 3–5 min", "0.01 mg/kg IV/IO\n(max 1 mg) every 3–5 min"],
    ["Amiodarone\n(shockable VF/pVT)", "300 mg IV/IO\nThen 150 mg", "5 mg/kg IV/IO\n(max 300 mg)"],
    ["Lidocaine\n(alt. to amiodarone)", "1–1.5 mg/kg IV/IO", "1 mg/kg IV/IO"],
]
drug_widths = [1.6*inch, 2.3*inch, 2.3*inch]
drug_table = Table(drug_rows, colWidths=drug_widths)
drug_table.setStyle(table_style(TEAL))

ht_rows = [
    [Paragraph("<b>H's</b>", col_head), Paragraph("<b>T's</b>", col_head)],
    ["Hypovolemia",          "Tension Pneumothorax"],
    ["Hypoxia",              "Tamponade (cardiac)"],
    ["Hydrogen ion (acidosis)", "Toxins"],
    ["Hypo/Hyperkalemia",    "Thrombosis – Pulmonary"],
    ["Hypothermia",          "Thrombosis – Coronary"],
]
ht_widths = [1.15*inch, 1.1*inch]
ht_table = Table(ht_rows, colWidths=ht_widths)
ht_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  colors.HexColor("#922B21")),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 7.5),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
    ("RIGHTPADDING",  (0,0),(-1,-1), 4),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(-1,-1), "CENTER"),
]))

combined = Table([[drug_table, Spacer(0.1*inch, 1), ht_table]],
                 colWidths=[6.2*inch, 0.1*inch, 2.3*inch])
combined.setStyle(TableStyle([
    ("VALIGN", (0,0),(-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0),(-1,-1), 0),
    ("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
story.append(combined)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# SPECIAL SITUATIONS
# ══════════════════════════════════════════════════════════════════
story.append(section_header("⚠  SPECIAL SITUATIONS", colors.HexColor("#6C3483")))
story.append(Spacer(1, 3))

sp_data = [
    [Paragraph("<b>Situation</b>", col_head), Paragraph("<b>Key Modification</b>", col_head)],
    ["Drowning",
     "Start CPR with rescue BREATHS before AED (hypoxia is primary cause). AED still reasonable once CPR initiated."],
    ["Unwitnessed collapse\n(child / infant alone)",
     "Give 2 MINUTES of CPR first, then call 911 and retrieve AED."],
    ["Witnessed VF arrest (adult)",
     "Attach AED and shock as soon as possible. Resume CPR immediately after shock."],
    ["Infant choking (FBAO)",
     "5 back blows + 5 CHEST THRUSTS (alternating). NO abdominal thrusts in infants."],
    ["Child choking (FBAO)",
     "5 back blows + 5 ABDOMINAL thrusts (alternating). Updated from abdominal thrusts only."],
    ["Advanced airway placed",
     "Switch to continuous compressions; asynchronous ventilations. Do NOT pause for breaths."],
    ["2-rescuer, post-puberty child",
     "Use adult 30:2 ratio (NOT 15:2)."],
]
sp_widths = [1.7*inch, 5.8*inch]
sp_table = Table(sp_data, colWidths=sp_widths)
sp_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  colors.HexColor("#6C3483")),
    ("TEXTCOLOR",     (0,0),(-1,0),  WHITE),
    ("FONTNAME",      (0,0),(-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0),(-1,-1), 8),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
    ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("LEFTPADDING",   (0,0),(-1,-1), 5),
    ("RIGHTPADDING",  (0,0),(-1,-1), 5),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0),(0,-1),  "CENTER"),
    ("ALIGN",         (1,0),(1,-1),  "LEFT"),
    ("FONTNAME",      (0,1),(0,-1),  "Helvetica-Bold"),
]))
story.append(sp_table)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════
# HIGH-QUALITY CPR CHECKLIST  +  POST-ROSC
# ══════════════════════════════════════════════════════════════════
hq_items = [
    "☐  Push HARD: ≥2 in adults | ≥1/3 AP diameter children & infants",
    "☐  Push FAST: 100–120 compressions/min (use a metronome or feedback device)",
    "☐  Allow FULL chest recoil — do NOT lean between compressions",
    "☐  MINIMIZE interruptions — target chest compression fraction ≥60%",
    "☐  Pause for rhythm/pulse check ≤10 seconds",
    "☐  Rotate compressor every 2 minutes",
    "☐  Avoid EXCESSIVE ventilation — 1 sec per breath, visible chest rise only",
]

post_items = [
    "☐  Correct reversible causes (H's & T's)",
    "☐  Immediate PCI if coronary cause suspected",
    "☐  Targeted Temperature Management (TTM)",
    "☐  Transport to advanced post-arrest care facility",
    "☐  Neurological critical care monitoring",
]

def make_checklist(title, items, bg, width):
    rows = [[Paragraph(f"<b>{title}</b>", S("clhdr", fontSize=9, textColor=WHITE,
             fontName="Helvetica-Bold", alignment=TA_CENTER))]]
    for item in items:
        rows.append([Paragraph(item, S("cli", fontSize=7.5, textColor=BLACK,
                     fontName="Helvetica", leading=11))])
    t = Table(rows, colWidths=[width])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), bg),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
        ("GRID",          (0,0),(-1,-1), 0.4, LGREY),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
        ("RIGHTPADDING",  (0,0),(-1,-1), 6),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    return t

hq_table   = make_checklist("✔  HIGH-QUALITY CPR CHECKLIST", hq_items, RED,    4.2*inch)
post_table = make_checklist("🏥  POST-ROSC PRIORITIES",       post_items, TEAL, 3.2*inch)

bottom_pair = Table([[hq_table, Spacer(0.1*inch,1), post_table]],
                    colWidths=[4.2*inch, 0.1*inch, 3.2*inch])
bottom_pair.setStyle(TableStyle([
    ("VALIGN", (0,0),(-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0),(-1,-1), 0),
    ("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
story.append(bottom_pair)
story.append(Spacer(1, 6))

# ── Footer ────────────────────────────────────────────────────────────────────
footer_data = [[Paragraph(
    "Sources: AHA 2024 Adult BLS Guidelines | AHA/AAP 2025 PALS Algorithm | Braunwald's Heart Disease | Barash's Clinical Anesthesia | Rosen's Emergency Medicine",
    S("footer", fontSize=6.5, textColor=colors.HexColor("#666666"),
      fontName="Helvetica", alignment=TA_CENTER))]]
footer_table = Table(footer_data, colWidths=[W])
footer_table.setStyle(TableStyle([
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("BACKGROUND",    (0,0),(-1,-1), GREY),
    ("GRID",          (0,0),(-1,-1), 0.3, LGREY),
]))
story.append(footer_table)

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
Running Command

python3 /home/daytona/workspace/cpr-cheatsheet/build_cpr.py

Running Command

ls -lh /home/daytona/workspace/cpr-cheatsheet/CPR_Quick_Reference.pdf

Your CPR Quick Reference PDF is ready to download and print:

CPR Quick Reference

PDF Document · PDF


What's included on the single-page cheat sheet:
  • Chain of Survival - 6-step visual bar (color-coded in blue)
  • Universal Sequence (C-A-B) - 8-step numbered table
  • Compression Parameters - Side-by-side comparison: Adult | Child | Infant (rate, depth, hand placement, recoil rules)
  • Compression:Ventilation Ratios - All rescuer scenarios and advanced airway situations
  • Defibrillation - Shock energies for adults and pediatrics, AED pad guidance
  • Drug Therapy - Epinephrine, Amiodarone, Lidocaine doses for both adults and children
  • Reversible Causes - The H's and T's at a glance
  • Special Situations - Drowning, unwitnessed collapse, infant/child choking (FBAO), post-puberty rules
  • High-Quality CPR Checklist - Printable tick-boxes
  • Post-ROSC Priorities - Post-arrest care steps
The sheet is formatted for US Letter paper (8.5" x 11") and prints cleanly on one page. Based on AHA 2024/2025 and AAP guidelines.

Make notes on basic life support cpr for non medical people

Here are clear, plain-language notes on CPR for everyday people - no medical background needed.

Basic Life Support (CPR) for Everyone

What to Do When Someone Collapses


What Is CPR and Why Does It Matter?

CPR stands for Cardiopulmonary Resuscitation - it's a way of keeping blood and oxygen flowing to the brain when someone's heart has stopped.
The brain starts dying within 4-6 minutes of no blood flow. CPR buys time until an ambulance arrives.
You don't need to be a doctor or nurse to save a life. Bystander CPR doubles or triples survival chances.

How to Know If Someone Needs CPR

Look for ALL of these:
  • They are unresponsive - won't wake up when you tap their shoulders and shout their name
  • They are not breathing normally - gasping, gurgling ("agonal breathing"), or completely not breathing
  • They have no pulse - but if you're not trained to check, just assume there's none and start
When in doubt, start CPR. Doing nothing is always the wrong choice.

Step 1 - Make Sure You're Safe

Before touching anyone, look around:
  • Is there traffic, fire, live electrical wires, or other danger?
  • Only approach if it's safe for YOU

Step 2 - Call for Help

Shout loudly: "Call 999 / 911 / 112 now!"
  • Point at a specific person - "You in the red shirt - call an ambulance!"
  • If you're alone, call emergency services yourself (put on speaker) before starting CPR
  • Ask someone to find a nearby AED (defibrillator) - often on walls in train stations, airports, shopping centres, gyms

Step 3 - Check the Person

Tap their shoulders firmly, shout "Are you OK?"
If no response:
  • Kneel beside them
  • Tilt their head back gently and lift their chin - this opens the airway
  • Look, listen and feel for normal breathing for no more than 10 seconds
If they are NOT breathing normally → start CPR immediately

Step 4 - Chest Compressions (The Most Important Part)

Place the person on their back on a firm, flat surface (floor is ideal - not a sofa).

Hand position:

  1. Find the centre of their chest - roughly where the two halves of the ribcage meet (lower half of the breastbone)
  2. Place the heel of one hand there
  3. Place your other hand on top, fingers interlocked
  4. Keep your fingers raised - only the heel of your palm should press down

How to compress:

  • Keep your arms straight - use your body weight, not just your arms
  • Push straight down at least 2 inches (5 cm) - this feels like a lot, and that's correct
  • Let the chest fully spring back up between each compression - don't lean on the chest
  • Compress at a rate of 100-120 per minute - this is roughly the beat of the song "Stayin' Alive" by the Bee Gees
  • Don't stop - fatigue sets in fast; swap with someone else every 2 minutes if possible
Push hard. Push fast. Don't be afraid of breaking ribs - cracked ribs heal; death doesn't.

Step 5 - Rescue Breaths (Optional for Untrained People)

If you have NOT been trained in CPR: just do chest compressions only (called Hands-Only CPR). This is perfectly effective for the first few minutes.
If you ARE trained in CPR:
  • After every 30 compressions, give 2 rescue breaths
  • Tilt the head back, lift the chin
  • Pinch the nose closed, seal your mouth over theirs
  • Blow steadily for 1 second until you see the chest rise
  • Remove your mouth, let the chest fall
  • Give a second breath, then resume 30 compressions
If you're not comfortable giving rescue breaths, keep doing compressions. Compressions-only CPR is far better than no CPR.

Step 6 - Using an AED (Defibrillator)

An AED is a machine that can shock the heart back into a normal rhythm. They are designed for anyone to use - the machine talks you through every step.
  • Turn it on (open the lid or press the button - it will speak to you)
  • Attach the pads to bare skin - one on the upper right chest, one on the lower left side
  • The machine will analyse the heart rhythm and tell you if a shock is needed
  • If it says "stand back, shock advised" - make sure nobody is touching the person, press the button
  • Resume CPR immediately after the shock
AEDs are safe. You cannot accidentally shock someone who doesn't need it.

The CPR Cycle - Summary

30 COMPRESSIONS  →  2 BREATHS  →  repeat
         (or just keep doing compressions if untrained)
Continue until:
  • The person starts breathing normally
  • Emergency services take over
  • An AED is ready to use
  • You are physically unable to continue

Children and Infants

Children (aged 1 to puberty):

  • Same steps as adults
  • Use 1 hand instead of 2 for smaller children
  • Compress about 2 inches deep (roughly 5 cm) / about one-third of chest depth
  • Compression rate: same - 100-120 per minute
  • If alone and no phone nearby: do 2 minutes of CPR first, then call 999/911

Babies and infants (under 1 year):

  • Use 2 fingers in the centre of the chest, just below the nipple line (or 2 thumbs if a second rescuer can wrap their hands around)
  • Compress about 1.5 inches (4 cm) deep / one-third of chest depth
  • Cover both the mouth AND nose with your mouth for rescue breaths
  • For choking infants: 5 back blows + 5 chest thrusts - never abdominal thrusts

Choking (Foreign Body Airway Obstruction)

Adult or child who is conscious and choking:

  1. Encourage them to cough
  2. Give 5 firm back blows between the shoulder blades with the heel of your hand
  3. Give 5 abdominal thrusts (Heimlich manoeuvre) - stand behind them, arms around their waist, hands just above the belly button, sharp inward-upward thrust
  4. Alternate back blows and abdominal thrusts until the object is dislodged or they lose consciousness
  5. If they lose consciousness → lower them to the floor and start CPR

Infant who is choking (conscious):

  • Face-down on your forearm: 5 back blows
  • Turn face-up: 5 chest thrusts (2 fingers on centre of chest)
  • Alternate until object is out or infant becomes unresponsive

Recovery Position

If someone is breathing but unconscious (after ROSC, or if they faint), do NOT start CPR. Place them in the recovery position:
  1. Kneel beside them
  2. Place the arm nearest to you at a right angle to their body
  3. Pull the far arm across and hold their hand against their cheek
  4. Pull their far knee up so the foot is flat on the floor
  5. Roll them toward you onto their side
  6. Tilt their head back slightly to keep the airway open
  7. Monitor their breathing until help arrives

Common Fears - and Why They're Wrong

FearReality
"I'll break their ribs"Ribs can crack - that's OK. The person was dying. Broken ribs heal; CPR saves lives.
"I'll hurt them if I do it wrong"You cannot make things worse. A person without CPR has a near-zero chance of survival.
"What if I get in legal trouble?"Good Samaritan laws in most countries protect bystanders who help in good faith.
"I don't know how to do it properly"Hands-only CPR with no training is still highly effective in the first few minutes.
"CPR never works"CPR alone achieves ROSC in many cases; combined with an AED, survival rates can reach 50-70% for witnessed VF arrest.

Quick Memory Aid

"DR ABC"

LetterMeaning
DDanger - check you're safe
RResponse - tap and shout
AAirway - tilt head, lift chin
BBreathing - look, listen, feel (10 sec)
CCompressions - start CPR, call 999

Key Numbers to Remember

WhatNumber
Compression rate100-120 per minute
Compression depth (adult)At least 2 inches (5 cm)
Compressions before breaths30
Rescue breaths2
Seconds to check for breathingNo more than 10
Minutes before calling 911 (unwitnessed child collapse)2 (do CPR first)
Song to keep your pace"Stayin' Alive" - Bee Gees (~100 BPM)

The single most important thing: If someone collapses and is not breathing normally, call for help and push hard and fast on the centre of their chest. That's it. You can save a life.

Make a simplified one-page checklist for CPR steps

Running Command

ls /home/daytona/workspace/cpr-cheatsheet/

Writing File

~/cpr-cheatsheet/build_checklist.py

from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.platypus import (
    SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
)
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT

OUTPUT = "/home/daytona/workspace/cpr-cheatsheet/CPR_Checklist.pdf"

# ── Colours ──────────────────────────────────────────────────────────────────
RED      = colors.HexColor("#C0392B")
DARK_RED = colors.HexColor("#922B21")
GREEN    = colors.HexColor("#1E8449")
BLUE     = colors.HexColor("#1A5276")
ORANGE   = colors.HexColor("#CA6F1E")
PURPLE   = colors.HexColor("#6C3483")
TEAL     = colors.HexColor("#117A65")
LGREY    = colors.HexColor("#F2F3F4")
BORDERGREY = colors.HexColor("#D5D8DC")
WHITE    = colors.white
BLACK    = colors.black
YELLOW   = colors.HexColor("#FEF9E7")

W = 7.5 * inch

def S(name, **kw):
    return ParagraphStyle(name, **kw)

# ── Document ──────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=letter,
    leftMargin=0.5*inch,
    rightMargin=0.5*inch,
    topMargin=0.4*inch,
    bottomMargin=0.35*inch,
    title="CPR Step-by-Step Checklist",
)

story = []

# ══════════════════════════════════════════════════════════════
# TITLE BANNER
# ══════════════════════════════════════════════════════════════
title_para = Paragraph(
    "🫀  CPR Step-by-Step Checklist",
    S("T", fontSize=22, textColor=WHITE, fontName="Helvetica-Bold",
      alignment=TA_CENTER, leading=26)
)
sub_para = Paragraph(
    "For Everyday People  •  Hands-Only or Full CPR  •  Adults, Children &amp; Infants",
    S("Sub", fontSize=9, textColor=colors.HexColor("#F9E79F"),
      fontName="Helvetica", alignment=TA_CENTER)
)
banner = Table([[title_para], [sub_para]], colWidths=[W])
banner.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), RED),
    ("TOPPADDING",    (0,0),(-1,0),  10),
    ("BOTTOMPADDING", (0,0),(-1,0),  2),
    ("TOPPADDING",    (0,1),(-1,1),  0),
    ("BOTTOMPADDING", (0,1),(-1,1),  8),
]))
story.append(banner)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════
# Helper: step row builder
# ══════════════════════════════════════════════════════════════
def step_row(number, emoji, heading, detail, bg_num, bg_detail=WHITE):
    num_para = Paragraph(
        f"<b>{number}</b>",
        S(f"n{number}", fontSize=18, textColor=WHITE, fontName="Helvetica-Bold",
          alignment=TA_CENTER)
    )
    head_para = Paragraph(
        f"{emoji}  <b>{heading}</b>",
        S(f"h{number}", fontSize=11.5, textColor=WHITE, fontName="Helvetica-Bold",
          leading=14)
    )
    detail_para = Paragraph(
        detail,
        S(f"d{number}", fontSize=8.5, textColor=BLACK, fontName="Helvetica",
          leading=12)
    )
    check_para = Paragraph(
        "☐",
        S(f"c{number}", fontSize=16, textColor=colors.HexColor("#555555"),
          alignment=TA_CENTER)
    )
    row = Table(
        [[num_para, head_para, detail_para, check_para]],
        colWidths=[0.42*inch, 2.2*inch, 4.48*inch, 0.4*inch]
    )
    row.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(0,0),  bg_num),
        ("BACKGROUND",    (1,0),(1,0),  bg_num),
        ("BACKGROUND",    (2,0),(2,0),  bg_detail),
        ("BACKGROUND",    (3,0),(3,0),  LGREY),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("LEFTPADDING",   (0,0),(0,0),  4),
        ("RIGHTPADDING",  (0,0),(0,0),  4),
        ("LEFTPADDING",   (1,0),(1,0),  6),
        ("RIGHTPADDING",  (1,0),(1,0),  6),
        ("LEFTPADDING",   (2,0),(2,0),  8),
        ("RIGHTPADDING",  (2,0),(2,0),  6),
        ("LEFTPADDING",   (3,0),(3,0),  4),
        ("TOPPADDING",    (0,0),(-1,-1), 6),
        ("BOTTOMPADDING", (0,0),(-1,-1), 6),
        ("LINEBELOW",     (0,0),(-1,-1), 0.5, BORDERGREY),
    ]))
    return row

# ══════════════════════════════════════════════════════════════
# STEPS 1–7
# ══════════════════════════════════════════════════════════════
steps = [
    (
        "1", "🔍", "Check for DANGER",
        "Look around before you touch anyone. Is there traffic, fire, or electricity nearby? "
        "Only approach if it is safe for YOU.",
        RED
    ),
    (
        "2", "📣", "Check RESPONSE",
        "Tap both shoulders firmly and shout <b>'Are you OK?'</b>  "
        "If they do not respond → they need help.",
        BLUE
    ),
    (
        "3", "📞", "CALL for Help",
        "Shout for bystanders. Point at someone: <b>'You — call 999 / 911 now!'</b>  "
        "If alone, call yourself (put on speaker). Ask someone to find the nearest <b>AED</b>.",
        GREEN
    ),
    (
        "4", "🌬️", "Open AIRWAY &amp; Check Breathing",
        "Tilt their head back gently, lift the chin. Look, listen and feel for normal breathing "
        "for <b>no more than 10 seconds.</b>  Gasping or gurgling = NOT normal breathing → start CPR.",
        ORANGE
    ),
    (
        "5", "💪", "Start CHEST COMPRESSIONS",
        "<b>Place hands:</b> Heel of one hand on the centre of the chest (lower half of breastbone). "
        "Other hand on top, fingers laced.  "
        "<b>Push:</b> Straight arms, use body weight. Push <b>hard and fast</b> — at least <b>2 inches (5 cm)</b> deep.  "
        "<b>Rate:</b> 100–120 per minute (beat of <i>'Stayin' Alive'</i>).  "
        "<b>Recoil:</b> Let chest fully rise back after each compression — don't lean on it.",
        RED
    ),
    (
        "6", "😮‍💨", "Give RESCUE BREATHS  (if trained)",
        "After every <b>30 compressions</b>: tilt head back, pinch nose, seal your mouth over theirs, "
        "blow steadily for <b>1 second</b> until chest rises. Give <b>2 breaths</b>, then resume compressions.  "
        "<b>Not trained or uncomfortable?</b> Skip breaths — <b>hands-only CPR is still effective.</b>",
        TEAL
    ),
    (
        "7", "⚡", "Use the AED",
        "Turn it on — <b>it talks you through every step.</b>  "
        "Attach pads to bare skin as shown on the pictures.  "
        "Make sure <b>nobody is touching</b> the person when it says 'stand clear.'  "
        "Press the shock button if prompted. <b>Resume CPR immediately after the shock.</b>",
        PURPLE
    ),
]

for s in steps:
    story.append(step_row(*s))

story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════
# KEEP GOING banner
# ══════════════════════════════════════════════════════════════
keep_going = Table(
    [[Paragraph(
        "🔄  <b>KEEP GOING</b> — Repeat 30 compressions + 2 breaths until: "
        "the person breathes normally &nbsp;|&nbsp; EMS arrives &nbsp;|&nbsp; AED is ready &nbsp;|&nbsp; you cannot continue",
        S("kg", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
          alignment=TA_CENTER, leading=13)
    )]],
    colWidths=[W]
)
keep_going.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), colors.HexColor("#1B2631")),
    ("TOPPADDING",    (0,0),(-1,-1), 6),
    ("BOTTOMPADDING", (0,0),(-1,-1), 6),
]))
story.append(keep_going)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════
# BOTTOM ROW: Key Numbers  |  Children  |  Hands-Only reminder
# ══════════════════════════════════════════════════════════════
def mini_box(title, lines, bg):
    rows = [[Paragraph(f"<b>{title}</b>",
             S("mbt", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold",
               alignment=TA_CENTER))]]
    for line in lines:
        rows.append([Paragraph(line, S("mbl", fontSize=7.8, textColor=BLACK,
                     fontName="Helvetica", leading=11))])
    t = Table(rows, colWidths=[2.35*inch])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0),  bg),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, LGREY]),
        ("GRID",          (0,0),(-1,-1), 0.4, BORDERGREY),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
        ("RIGHTPADDING",  (0,0),(-1,-1), 6),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    return t

numbers_box = mini_box("🔢  Key Numbers", [
    "Rate:  100–120 compressions / min",
    "Depth (adult):  ≥ 2 inches (5 cm)",
    "Depth (child):  ~2 in / 1/3 chest depth",
    "Depth (infant):  ~1.5 in / 1/3 chest depth",
    "Ratio:  30 compressions : 2 breaths",
    "Check breathing:  ≤ 10 seconds",
    "Swap compressor:  every 2 minutes",
], RED)

children_box = mini_box("👶  Children &amp; Infants", [
    "<b>Child (1 yr – puberty):</b>",
    "  • 1 hand on lower sternum",
    "  • 30:2 (1 rescuer) | 15:2 (2+ rescuers)",
    "  • If alone: 2 min CPR FIRST, then call 911",
    "<b>Infant (&lt;1 yr):</b>",
    "  • 2-thumb encircling OR heel of 1 hand",
    "  • Cover mouth AND nose for breaths",
    "  • Choking: 5 back blows + 5 chest thrusts",
], BLUE)

handsonly_box = mini_box("🙌  Hands-Only CPR", [
    "If you are <b>not trained</b> or uncomfortable",
    "giving rescue breaths:",
    " ",
    "Just push hard and fast on the centre",
    "of the chest — <b>no breaths needed.</b>",
    " ",
    "This alone can keep someone alive",
    "until the ambulance arrives.",
], GREEN)

bottom_row = Table(
    [[numbers_box, Spacer(0.075*inch, 1), children_box, Spacer(0.075*inch, 1), handsonly_box]],
    colWidths=[2.35*inch, 0.075*inch, 2.35*inch, 0.075*inch, 2.35*inch]
)
bottom_row.setStyle(TableStyle([
    ("VALIGN", (0,0),(-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0),(-1,-1), 0),
    ("RIGHTPADDING", (0,0),(-1,-1), 0),
    ("TOPPADDING",   (0,0),(-1,-1), 0),
    ("BOTTOMPADDING",(0,0),(-1,-1), 0),
]))
story.append(bottom_row)
story.append(Spacer(1, 6))

# ══════════════════════════════════════════════════════════════
# SONG REMINDER strip
# ══════════════════════════════════════════════════════════════
song = Table([[Paragraph(
    "🎵  <b>Can't remember the rate?</b>  Compress to the beat of <b><i>'Stayin' Alive'</i></b> by the Bee Gees — it's almost exactly 100 BPM.",
    S("song", fontSize=8.5, textColor=BLACK, fontName="Helvetica",
      alignment=TA_CENTER, leading=12)
)]], colWidths=[W])
song.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), colors.HexColor("#FEF9E7")),
    ("TOPPADDING",    (0,0),(-1,-1), 5),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
    ("BOX",           (0,0),(-1,-1), 0.8, colors.HexColor("#F0B27A")),
]))
story.append(song)
story.append(Spacer(1, 4))

# ── Footer ────────────────────────────────────────────────────
footer = Table([[Paragraph(
    "Based on AHA 2024/2025 BLS Guidelines  •  For training purposes only  •  "
    "This card does not replace certified CPR training",
    S("ft", fontSize=6.5, textColor=colors.HexColor("#777777"),
      fontName="Helvetica", alignment=TA_CENTER)
)]], colWidths=[W])
footer.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), LGREY),
    ("TOPPADDING",    (0,0),(-1,-1), 3),
    ("BOTTOMPADDING", (0,0),(-1,-1), 3),
    ("BOX",           (0,0),(-1,-1), 0.3, BORDERGREY),
]))
story.append(footer)

# ── Build ─────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
Running Command

python3 /home/daytona/workspace/cpr-cheatsheet/build_checklist.py

Running Command

ls -lh /home/daytona/workspace/cpr-cheatsheet/CPR_Checklist.pdf

Your printable CPR checklist is ready:

CPR Checklist

PDF Document · PDF


What's on the one-page checklist:
  • 7 colour-coded step rows - each with a tick box (☐), step number, emoji, bold heading, and plain-English instruction. Designed so anyone can follow under stress.
    • 🔍 Check Danger
    • 📣 Check Response
    • 📞 Call for Help
    • 🌬️ Open Airway & Check Breathing
    • 💪 Start Chest Compressions (with hand placement, depth, rate)
    • 😮‍💨 Rescue Breaths - with a clear note that you can skip if untrained
    • ⚡ Use the AED
  • "Keep Going" reminder bar - when to stop
  • 3 quick-reference boxes at the bottom:
    • Key numbers (rate, depth, ratio)
    • Children & infant differences
    • Hands-only CPR option
  • "Stayin' Alive" BPM reminder strip at the bottom
Prints cleanly on a single US Letter (8.5" × 11") page. Good to stick on a fridge, in a first aid kit, or post in a workplace.
This is a shared conversation. Sign in to Orris to start your own chat.