Detailed notes on cpr for adults and children
AHA 2024 CPR guidelines adults children BLS
https://cpr.heart.org/en/resuscitation-science/cpr-and-ecc-g…
pediatric CPR children infants 2024 guidelines compression depth ratio AHA PALS
| Step | Action |
|---|---|
| 1 | Verify environmental safety |
| 2 | Check responsiveness (tap and shout) |
| 3 | Call for help / activate emergency response system (call 911) |
| 4 | Send someone for AED |
| 5 | Check for pulse (carotid) - no more than 10 seconds |
| 6 | If no pulse / unsure, begin chest compressions immediately |
| 7 | After 30 compressions, open airway (head-tilt chin-lift), give 2 rescue breaths |
| 8 | Continue 30:2 cycles until AED arrives / EMS takes over / signs of ROSC |
| 9 | Apply AED as soon as available and follow prompts |
| Parameter | Recommendation |
|---|---|
| Hand placement | Heel of both hands on the lower half of the sternum (breastbone) |
| Arm position | Arms straight at elbows; use shoulder/back as fulcrum |
| Rate | 100-120 compressions/minute |
| Depth | At least 2 inches (5 cm), no more than 2.4 inches (6 cm) |
| Chest recoil | Allow full recoil after each compression - do NOT lean on the chest |
| Interruptions | Limit to less than 10 seconds |
| Compression fraction | Aim for at least 60% of total CPR time as active compressions |
| Rescuer rotation | Switch compressor every 2 minutes (compression quality declines after 90-120 sec) |
| Situation | Ratio |
|---|---|
| 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 duration | 1 second |
Note: For adults without an advanced airway, healthcare professionals may consider continuous chest compressions with asynchronous breaths as an alternative (AHA Class 2b).
| Step | Action |
|---|---|
| 1 | Verify safety; check responsiveness |
| 2 | Call for help |
| 3 | If witnessed collapse: call 911 immediately, then CPR |
| 4 | If unwitnessed collapse (child/infant alone): give 2 minutes of CPR first, then call 911 and get AED |
| 5 | Check brachial pulse in infants; carotid or femoral in children (no more than 10 sec) |
| 6 | Begin compressions if pulseless or pulse <60/min with signs of poor perfusion |
| 7 | Apply 30:2 (single rescuer) or 15:2 (2+ rescuers, pre-puberty) |
| 8 | Attach AED when available |
| Age Group | Technique | Depth | Rate |
|---|---|---|---|
| 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 diameter | 100-120/min |
| Small child (1-8 yr) | One hand on lower sternum | ~2 inches (5 cm) / 1/3 AP diameter | 100-120/min |
| Older child/adolescent | Two 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.
| Situation | Ratio |
|---|---|
| Single rescuer, any age child | 30:2 |
| 2+ rescuers, pre-puberty child | 15:2 |
| 2+ rescuers, post-puberty (adolescent) | 30:2 |
| Advanced airway in place | Continuous compressions + 1 breath every 2-3 seconds (20-30/min) |
This differs from adults where it is always 30:2 regardless of rescuer count.
| Parameter | Dose |
|---|---|
| First shock | 2 J/kg |
| Second shock | 4 J/kg |
| Subsequent shocks | ≥4 J/kg, max 10 J/kg or adult dose |
| Drug | Dose |
|---|---|
| Epinephrine IV/IO | 0.01 mg/kg (0.1 mg/mL concentration), max dose 1 mg, every 3-5 min |
| Amiodarone or Lidocaine | For shockable rhythms (VF/pVT), after 2nd shock |
| Component | Adult | Child | Infant |
|---|---|---|---|
| Compression rate | 100-120/min | 100-120/min | 100-120/min |
| Compression depth | 2-2.4 inches (5-6 cm) | ~2 inches (5 cm) / 1/3 AP | ~1.5 inches (4 cm) / 1/3 AP |
| Hand position | 2 hands, lower sternum | 1-2 hands, lower sternum | 2 thumbs or 1 hand heel |
| Ratio (1 rescuer) | 30:2 | 30:2 | 30:2 |
| Ratio (2+ rescuers) | 30:2 | 15:2 (pre-puberty) | 15:2 |
| Advanced airway breath rate | 10/min (1 per 6 sec) | 20-30/min (1 per 2-3 sec) | 20-30/min |
| Recoil | Full recoil, no leaning | Full recoil | Full recoil |
| Interruption limit | < 10 seconds | < 10 seconds | < 10 seconds |
| First defibrillation energy | 200 J (biphasic) | 2 J/kg | 2 J/kg |
Create a quick reference PDF or CPR cheat sheet I can print
ls /home/daytona/workspace/ 2>/dev/null && python3 -c "import reportlab; print('…
mkdir -p /home/daytona/workspace/cpr-cheatsheet
~/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 (<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 (<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}")
python3 /home/daytona/workspace/cpr-cheatsheet/build_cpr.py
ls -lh /home/daytona/workspace/cpr-cheatsheet/CPR_Quick_Reference.pdf
CPR Quick Reference
PDF Document · PDF
Make notes on basic life support cpr for non medical people
When in doubt, start CPR. Doing nothing is always the wrong choice.
Push hard. Push fast. Don't be afraid of breaking ribs - cracked ribs heal; death doesn't.
If you're not comfortable giving rescue breaths, keep doing compressions. Compressions-only CPR is far better than no CPR.
30 COMPRESSIONS → 2 BREATHS → repeat
(or just keep doing compressions if untrained)
| Fear | Reality |
|---|---|
| "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. |
| Letter | Meaning |
|---|---|
| D | Danger - check you're safe |
| R | Response - tap and shout |
| A | Airway - tilt head, lift chin |
| B | Breathing - look, listen, feel (10 sec) |
| C | Compressions - start CPR, call 999 |
| What | Number |
|---|---|
| Compression rate | 100-120 per minute |
| Compression depth (adult) | At least 2 inches (5 cm) |
| Compressions before breaths | 30 |
| Rescue breaths | 2 |
| Seconds to check for breathing | No 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
ls /home/daytona/workspace/cpr-cheatsheet/
~/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 & 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 & 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 | EMS arrives | AED is ready | 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 & 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 (<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}")
python3 /home/daytona/workspace/cpr-cheatsheet/build_checklist.py
ls -lh /home/daytona/workspace/cpr-cheatsheet/CPR_Checklist.pdf
CPR Checklist
PDF Document · PDF