Make a note for cardiac system
mkdir -p /home/daytona/workspace/cardiac-note && ls /home/daytona/workspace/cardiac-note/
~/cardiac-note/generate_cardiac_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, ListFlowable, ListItem, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
from reportlab.lib.colors import HexColor
OUTPUT = "/home/daytona/workspace/cardiac-note/Cardiac_System_Nursing_Notes.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
RED = HexColor("#C0392B")
DARK_RED = HexColor("#922B21")
BLUE = HexColor("#1A5276")
LIGHT_BLUE= HexColor("#D6EAF8")
MED_BLUE = HexColor("#2E86C1")
TEAL = HexColor("#1ABC9C")
LIGHT_TEAL= HexColor("#D1F2EB")
ORANGE = HexColor("#E67E22")
LIGHT_ORG = HexColor("#FDEBD0")
PURPLE = HexColor("#7D3C98")
LIGHT_PUR = HexColor("#E8DAEF")
GREEN = HexColor("#1E8449")
LIGHT_GRN = HexColor("#D5F5E3")
YELLOW = HexColor("#F1C40F")
LIGHT_YEL = HexColor("#FEF9E7")
GREY_BG = HexColor("#F2F3F4")
DARK_GREY = HexColor("#2C3E50")
MID_GREY = HexColor("#7F8C8D")
# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def s(name, **kw):
return ParagraphStyle(name, parent=styles['Normal'], **kw)
TITLE_STYLE = s('Title', fontSize=26, textColor=colors.white,
alignment=TA_CENTER, leading=32, fontName='Helvetica-Bold')
SUBTITLE_STYLE = s('Subtitle', fontSize=12, textColor=HexColor("#D6EAF8"),
alignment=TA_CENTER, leading=16, fontName='Helvetica')
H1 = s('H1', fontSize=15, textColor=colors.white,
fontName='Helvetica-Bold', leading=20, spaceAfter=4)
H2 = s('H2', fontSize=12, textColor=DARK_GREY,
fontName='Helvetica-Bold', leading=16, spaceBefore=8, spaceAfter=4)
H3 = s('H3', fontSize=11, textColor=BLUE,
fontName='Helvetica-Bold', leading=14, spaceBefore=6, spaceAfter=3)
BODY = s('Body', fontSize=10, leading=14, textColor=DARK_GREY,
fontName='Helvetica', spaceAfter=4, alignment=TA_JUSTIFY)
BODY_BOLD = s('BodyBold', fontSize=10, leading=14, textColor=DARK_GREY,
fontName='Helvetica-Bold', spaceAfter=2)
BULLET = s('Bullet', fontSize=10, leading=14, textColor=DARK_GREY,
leftIndent=14, bulletIndent=0, spaceAfter=2)
SMALL = s('Small', fontSize=9, leading=12, textColor=MID_GREY,
fontName='Helvetica-Oblique')
TABLE_HDR = s('TblHdr', fontSize=9, textColor=colors.white,
fontName='Helvetica-Bold', alignment=TA_CENTER, leading=12)
TABLE_CELL = s('TblCell', fontSize=9, textColor=DARK_GREY,
fontName='Helvetica', alignment=TA_LEFT, leading=12)
TABLE_CELL_C = s('TblCellC', fontSize=9, textColor=DARK_GREY,
fontName='Helvetica', alignment=TA_CENTER, leading=12)
WARNING = s('Warning', fontSize=10, leading=14, textColor=RED,
fontName='Helvetica-Bold', spaceAfter=4)
NOTE = s('Note', fontSize=9, leading=13, textColor=DARK_GREY,
fontName='Helvetica-Oblique', leftIndent=8)
def para(text, style=BODY):
return Paragraph(text, style)
def bullet(text, style=BULLET):
return Paragraph(f"• {text}", style)
def sp(h=0.2):
return Spacer(1, h * cm)
def hr(color=BLUE, thickness=1):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4)
def section_header(title, bg_color=BLUE):
data = [[Paragraph(title, H1)]]
t = Table(data, colWidths=[17.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg_color),
('ROUNDEDCORNERS', [6]),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 14),
('RIGHTPADDING', (0,0), (-1,-1), 8),
]))
return t
def info_box(title, items, bg=LIGHT_BLUE, border=MED_BLUE):
rows = [[Paragraph(title, s('IH', parent=H2, textColor=border,
fontName='Helvetica-Bold', fontSize=10))]]
for item in items:
rows.append([Paragraph(f"• {item}", TABLE_CELL)])
t = Table(rows, colWidths=[16.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (0,0), 6),
('BOTTOMPADDING', (0,0), (0,0), 2),
('TOPPADDING', (0,1), (-1,-1), 2),
('BOTTOMPADDING', (0,1), (-1,-1), 2),
('BOTTOMPADDING', (0,-1), (-1,-1), 6),
('BOX', (0,0), (-1,-1), 1, border),
('ROUNDEDCORNERS', [4]),
]))
return t
def two_col_table(headers, rows, col_widths=None, hdr_bg=BLUE):
if col_widths is None:
col_widths = [8.5*cm, 8.5*cm]
hdr_row = [Paragraph(h, TABLE_HDR) for h in headers]
data = [hdr_row]
for row in rows:
data.append([Paragraph(str(c), TABLE_CELL) for c in row])
t = Table(data, colWidths=col_widths)
n = len(data)
style = [
('BACKGROUND', (0,0), (-1,0), hdr_bg),
('BACKGROUND', (0,1), (-1,-1), colors.white),
('GRID', (0,0), (-1,-1), 0.5, HexColor("#BDC3C7")),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]
for i in range(1, n, 2):
style.append(('BACKGROUND', (0,i), (-1,i), GREY_BG))
t.setStyle(TableStyle(style))
return t
def multi_col_table(headers, rows, col_widths, hdr_bg=BLUE):
hdr_row = [Paragraph(h, TABLE_HDR) for h in headers]
data = [hdr_row]
for row in rows:
data.append([Paragraph(str(c), TABLE_CELL) for c in row])
t = Table(data, colWidths=col_widths)
n = len(data)
style = [
('BACKGROUND', (0,0), (-1,0), hdr_bg),
('BACKGROUND', (0,1), (-1,-1), colors.white),
('GRID', (0,0), (-1,-1), 0.5, HexColor("#BDC3C7")),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]
for i in range(1, n, 2):
style.append(('BACKGROUND', (0,i), (-1,i), GREY_BG))
t.setStyle(TableStyle(style))
return t
# ── Cover page helper ────────────────────────────────────────────────────────
def cover_page():
elements = []
# Red banner
data = [[Paragraph("CARDIAC SYSTEM", TITLE_STYLE),
Paragraph("Nursing Study Notes", SUBTITLE_STYLE),
Paragraph("Comprehensive Review • 2026", SUBTITLE_STYLE)]]
# flatten into rows
banner_rows = [
[Paragraph("CARDIAC SYSTEM", TITLE_STYLE)],
[Paragraph("Nursing Study Notes", SUBTITLE_STYLE)],
[Paragraph("Comprehensive Review • June 2026", SUBTITLE_STYLE)],
]
t = Table(banner_rows, colWidths=[17.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('TOPPADDING', (0,0), (0,0), 30),
('BOTTOMPADDING', (0,-1), (-1,-1), 30),
('TOPPADDING', (0,1), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-2), 4),
('LEFTPADDING', (0,0), (-1,-1), 20),
('RIGHTPADDING', (0,0), (-1,-1), 20),
]))
elements.append(t)
elements.append(sp(0.6))
# Topics covered box
topics = [
"1. Anatomy of the Heart",
"2. Cardiac Physiology & Blood Flow",
"3. Cardiac Cycle",
"4. Conduction System & Action Potential",
"5. ECG Basics & Interpretation",
"6. Common Cardiac Diseases",
"7. Cardiac Pharmacology",
"8. Nursing Assessments & Interventions",
]
rows = [[Paragraph("Topics Covered", s('TC', parent=H2, textColor=RED, fontSize=12,
fontName='Helvetica-Bold'))]]
for t_ in topics:
rows.append([Paragraph(t_, TABLE_CELL)])
tbl = Table(rows, colWidths=[17.5*cm])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), LIGHT_BLUE),
('LEFTPADDING', (0,0), (-1,-1), 16),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('BOX', (0,0), (-1,-1), 1.5, MED_BLUE),
]))
elements.append(tbl)
elements.append(sp(0.5))
elements.append(para("Reference: Braunwald's Heart Disease (11e) • Fuster and Hurst's The Heart (15e)", SMALL))
elements.append(PageBreak())
return elements
# ─────────────────────────────────────────────────────────────────────────────
# BUILD DOCUMENT
# ─────────────────────────────────────────────────────────────────────────────
def build():
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm,
title="Cardiac System – Nursing Notes",
author="Orris Medical Study Aid",
)
E = [] # elements list
# ── COVER ─────────────────────────────────────────────────────────────────
E += cover_page()
# ═══════════════════════════════════════════════════════════════════════════
# 1. ANATOMY
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("1. ANATOMY OF THE HEART", RED))
E.append(sp(0.3))
E.append(para(
"The heart is a hollow, muscular organ located in the <b>mediastinum</b> of the thoracic cavity, "
"slightly left of the midline. It is enclosed in a double-walled sac called the <b>pericardium</b>. "
"The adult heart weighs approximately 250–350 g.", BODY))
E.append(sp(0.2))
E.append(para("<b>Layers of the Heart Wall</b>", H2))
E.append(multi_col_table(
["Layer", "Location", "Description"],
[
["Epicardium", "Outermost", "Visceral layer of pericardium; contains coronary vessels and fat"],
["Myocardium", "Middle", "Thick cardiac muscle; responsible for pumping action"],
["Endocardium", "Innermost", "Smooth inner lining of chambers and valves; continuous with blood vessel endothelium"],
],
[4*cm, 4*cm, 9.5*cm], hdr_bg=RED
))
E.append(sp(0.3))
E.append(para("<b>Four Chambers</b>", H2))
E.append(multi_col_table(
["Chamber", "Wall Thickness", "Function"],
[
["Right Atrium (RA)", "Thin", "Receives deoxygenated blood from SVC, IVC, and coronary sinus"],
["Right Ventricle (RV)", "Moderate", "Pumps deoxygenated blood to lungs via pulmonary artery"],
["Left Atrium (LA)", "Thin", "Receives oxygenated blood from 4 pulmonary veins"],
["Left Ventricle (LV)", "Thick (12–15 mm)", "Pumps oxygenated blood to systemic circulation; generates highest pressure"],
],
[3.5*cm, 4*cm, 10*cm], hdr_bg=RED
))
E.append(sp(0.3))
E.append(para("<b>Heart Valves</b>", H2))
E.append(multi_col_table(
["Valve", "Type", "Location", "Function"],
[
["Tricuspid", "Atrioventricular (AV)", "Between RA and RV", "Prevents backflow from RV → RA"],
["Pulmonary (Pulmonic)", "Semilunar", "RV → Pulmonary artery", "Prevents backflow from PA → RV"],
["Mitral (Bicuspid)", "Atrioventricular (AV)", "Between LA and LV", "Prevents backflow from LV → LA"],
["Aortic", "Semilunar", "LV → Aorta", "Prevents backflow from Aorta → LV"],
],
[3.5*cm, 4*cm, 5*cm, 5*cm], hdr_bg=RED
))
E.append(sp(0.3))
E.append(para("<b>Coronary Arteries</b>", H2))
E.append(two_col_table(
["Artery", "Areas Supplied"],
[
["Left Anterior Descending (LAD)", "Anterior LV wall, interventricular septum, apex — 'Widow maker'"],
["Left Circumflex (LCx)", "Lateral and posterior LV wall, LA"],
["Right Coronary Artery (RCA)", "RV, inferior LV wall, SA node (60%), AV node (85–90%)"],
],
hdr_bg=RED
))
E.append(sp(0.2))
E.append(info_box("Nursing Key Point — Heart Sounds",
["S1 ('lub') = Closure of mitral & tricuspid (AV) valves — marks start of systole",
"S2 ('dub') = Closure of aortic & pulmonary (semilunar) valves — marks start of diastole",
"S3 = Ventricular gallop — early diastole; normal in young; pathological in heart failure (HF)",
"S4 = Atrial gallop — late diastole; suggests reduced ventricular compliance (hypertension, HCM)"],
bg=LIGHT_GRN, border=GREEN))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 2. PHYSIOLOGY & BLOOD FLOW
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("2. CARDIAC PHYSIOLOGY & BLOOD FLOW", DARK_RED))
E.append(sp(0.3))
E.append(para("<b>Pulmonary vs. Systemic Circulation</b>", H2))
E.append(two_col_table(
["Pulmonary Circulation", "Systemic Circulation"],
[
["RV → Pulmonary artery → Lungs → Pulmonary veins → LA",
"LV → Aorta → Body tissues → Venae cavae → RA"],
["Low pressure (15–25/8–12 mmHg)", "High pressure (120/80 mmHg)"],
["Gas exchange: CO₂ out, O₂ in", "Delivers O₂ & nutrients; removes CO₂ & waste"],
],
hdr_bg=DARK_RED
))
E.append(sp(0.3))
E.append(para("<b>Key Haemodynamic Parameters</b>", H2))
E.append(multi_col_table(
["Parameter", "Normal Value", "Definition / Significance"],
[
["Heart Rate (HR)", "60–100 bpm", "Number of cardiac contractions per minute"],
["Stroke Volume (SV)", "60–100 mL/beat", "Volume ejected per contraction"],
["Cardiac Output (CO)", "4–8 L/min", "CO = HR × SV"],
["Ejection Fraction (EF)", ">55%", "% of end-diastolic volume ejected per beat; key in HF assessment"],
["Preload", "LVEDP 8–12 mmHg", "Ventricular filling pressure; determined by venous return"],
["Afterload", "SVR 800–1200 dyne·s/cm⁵", "Resistance the LV must overcome to eject blood"],
["Cardiac Index (CI)", "2.5–4.0 L/min/m²", "CO adjusted for body surface area"],
],
[4*cm, 4*cm, 9.5*cm], hdr_bg=DARK_RED
))
E.append(sp(0.3))
E.append(para("<b>Frank-Starling Law</b>", H3))
E.append(para(
"As ventricular <b>end-diastolic volume (preload)</b> increases, the myocardium stretches, "
"leading to a stronger subsequent contraction and higher stroke volume — up to a physiological limit. "
"This is the basis for fluid resuscitation in hypotension.", BODY))
E.append(sp(0.2))
E.append(para("<b>Factors Affecting Cardiac Output</b>", H3))
E.append(two_col_table(
["Increases CO", "Decreases CO"],
[
["Increased HR (sympathetic, exercise)", "Bradycardia, heart block"],
["Increased preload (fluid loading)", "Hypovolaemia, diuretics"],
["Increased contractility (catecholamines, digoxin)", "Negative inotropes (beta-blockers, CCBs)"],
["Decreased afterload (vasodilators)", "Increased afterload (hypertension, stenosis)"],
],
hdr_bg=DARK_RED
))
E.append(sp(0.2))
E.append(info_box("Nursing Key Point — Monitoring Haemodynamics",
["Monitor BP, HR, SpO₂ regularly — report HR <60 or >100, SBP <90 or >180 mmHg",
"Assess for signs of low CO: cool/clammy skin, confusion, decreased urine output (<0.5 mL/kg/hr), hypotension",
"Daily weights: 1 kg gain = ~1 L fluid retention — critical in HF management"],
bg=LIGHT_BLUE, border=MED_BLUE))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 3. CARDIAC CYCLE
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("3. THE CARDIAC CYCLE", TEAL))
E.append(sp(0.3))
E.append(para(
"The cardiac cycle represents the sequence of events in one complete heartbeat (~0.8 seconds at 75 bpm), "
"divided into <b>systole</b> (contraction) and <b>diastole</b> (relaxation).", BODY))
E.append(sp(0.2))
E.append(multi_col_table(
["Phase", "Event", "Valves", "Pressure"],
[
["1. Isovolumetric Contraction", "Ventricles start contracting; no volume change",
"All valves CLOSED", "LV pressure rising rapidly"],
["2. Rapid Ejection", "Aortic & pulmonic valves open; blood ejected",
"Semilunar OPEN; AV CLOSED", "LV pressure peaks (~120 mmHg)"],
["3. Reduced Ejection", "Slower ejection as pressure gradient decreases",
"Semilunar OPEN", "LV pressure begins to fall"],
["4. Isovolumetric Relaxation", "Ventricles relax; no volume change",
"All valves CLOSED", "LV pressure drops rapidly"],
["5. Rapid Ventricular Filling", "Mitral/tricuspid open; passive filling",
"AV valves OPEN", "Low ventricular pressure"],
["6. Slow Filling (Diastasis)", "Slow passive filling", "AV valves OPEN", "Equalising pressures"],
["7. Atrial Systole ('Atrial Kick')", "Atria contract; final 20–30% filling",
"AV valves OPEN", "Slight pressure rise"],
],
[4*cm, 4.5*cm, 4.5*cm, 4.5*cm], hdr_bg=TEAL
))
E.append(sp(0.3))
E.append(info_box("Nursing Key Point — Atrial Kick",
["Atrial fibrillation (AF) eliminates the atrial kick, reducing CO by up to 25–30%",
"This is why patients in AF with poor LV function can decompensate rapidly",
"Assess rhythm regularly; rate-control vs. rhythm-control is a key clinical decision"],
bg=LIGHT_TEAL, border=TEAL))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 4. CONDUCTION SYSTEM
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("4. CONDUCTION SYSTEM & ACTION POTENTIAL", ORANGE))
E.append(sp(0.3))
E.append(para("<b>Normal Conduction Pathway</b>", H2))
pathway_data = [
["1", "SA Node", "Right atrial wall near SVC", "60–100/min", "Pacemaker of the heart"],
["2", "AV Node", "Interatrial septum (Koch's triangle)", "40–60/min", "Delays impulse 0.1 sec to allow atrial filling"],
["3", "Bundle of His", "Upper interventricular septum", "—", "Transmits impulse to ventricles"],
["4", "Right & Left Bundle Branches", "Along interventricular septum", "—", "Distribute impulse to each ventricle"],
["5", "Purkinje Fibres", "Ventricular myocardium", "20–40/min", "Rapid conduction; ensures synchronised ventricular contraction"],
]
E.append(multi_col_table(
["Step", "Structure", "Location", "Intrinsic Rate", "Function"],
pathway_data,
[1*cm, 3.5*cm, 4*cm, 2.5*cm, 6.5*cm], hdr_bg=ORANGE
))
E.append(sp(0.3))
E.append(para("<b>Cardiac Action Potential (Ventricular Myocyte)</b>", H2))
ap_data = [
["Phase 0", "Rapid Depolarisation", "Fast Na⁺ channels OPEN — Na⁺ rushes in"],
["Phase 1", "Early Repolarisation", "Na⁺ channels close; transient K⁺ outflow"],
["Phase 2", "Plateau", "Ca²⁺ influx (slow channels) balances K⁺ outflow — unique to cardiac muscle"],
["Phase 3", "Rapid Repolarisation", "Ca²⁺ channels close; K⁺ rapidly exits"],
["Phase 4", "Resting Membrane Potential", "Na⁺/K⁺ ATPase restores balance (−90 mV in ventricular cells)"],
]
E.append(multi_col_table(
["Phase", "Name", "Ion Movement"],
ap_data,
[2*cm, 5*cm, 10.5*cm], hdr_bg=ORANGE
))
E.append(sp(0.2))
E.append(info_box("Nursing Key Point — Refractory Period",
["The long refractory period (Phase 2 plateau) prevents re-stimulation during contraction — protective against tetanic contractions",
"Hypokalaemia shortens repolarisation → risk of arrhythmia; hyperkalaemia prolongs it → risk of bradycardia/asystole",
"Monitor K⁺ levels in patients on diuretics (furosemide) or digoxin — target K⁺ 3.5–5.0 mmol/L"],
bg=LIGHT_ORG, border=ORANGE))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 5. ECG
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("5. ECG BASICS & INTERPRETATION", PURPLE))
E.append(sp(0.3))
E.append(para("<b>ECG Waveform Components</b>", H2))
ecg_data = [
["P wave", "0.06–0.12 s; <2.5 mm", "Atrial depolarisation (SA node firing → atrial contraction)"],
["PR interval", "0.12–0.20 s", "AV node conduction time; prolonged in heart block"],
["QRS complex", "<0.12 s; <25 mm", "Ventricular depolarisation; wide = bundle branch block or VT"],
["ST segment", "Isoelectric", "Ventricular plateau; elevation = STEMI; depression = ischaemia"],
["T wave", "Upright (I, II, V4–6)", "Ventricular repolarisation; inversion = ischaemia; peaked = hyperkalaemia"],
["QT interval", "QTc < 0.44 s (male), <0.46 s (female)", "Total ventricular electrical activity; prolonged = Torsades de Pointes risk"],
]
E.append(multi_col_table(
["Component", "Normal Values", "Clinical Significance"],
ecg_data,
[3.5*cm, 5*cm, 9*cm], hdr_bg=PURPLE
))
E.append(sp(0.3))
E.append(para("<b>Common ECG Rhythms — Nursing Recognition</b>", H2))
rhythm_data = [
["Normal Sinus Rhythm (NSR)", "60–100 bpm, regular, P before each QRS", "Normal"],
["Sinus Bradycardia", "<60 bpm, regular, P before each QRS", "Consider if symptomatic; atropine 0.5 mg IV"],
["Sinus Tachycardia", ">100 bpm, regular", "Treat cause (pain, fever, hypovolaemia, anxiety)"],
["Atrial Fibrillation (AF)", "Irregularly irregular, no distinct P waves, wavy baseline", "Rate control (beta-blockers, digoxin); anticoagulation"],
["Atrial Flutter", "Regular ~150 bpm, sawtooth P waves (300/min), 2:1 block", "Rate/rhythm control; cardioversion"],
["1° AV Block", "PR >0.20 s, regular", "Monitor; usually benign"],
["2° AV Block (Mobitz I)", "Progressive PR lengthening until QRS dropped", "Monitor; may need pacing if symptomatic"],
["2° AV Block (Mobitz II)", "Constant PR, sudden QRS drop", "High risk → pacemaker usually needed"],
["3° (Complete) AV Block", "No relationship between P waves & QRS", "Emergency pacing required"],
["Ventricular Tachycardia (VT)", ">3 wide QRS beats >100 bpm", "Pulseless: CPR + defibrillation; with pulse: amiodarone"],
["Ventricular Fibrillation (VF)", "Chaotic, no organised activity", "CPR + immediate defibrillation (200J)"],
["Asystole", "Flat line", "CPR + adrenaline (epinephrine) 1 mg IV every 3–5 min"],
]
E.append(multi_col_table(
["Rhythm", "ECG Features", "Nursing Action"],
rhythm_data,
[4*cm, 6*cm, 7.5*cm], hdr_bg=PURPLE
))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 6. COMMON CARDIAC DISEASES
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("6. COMMON CARDIAC DISEASES", MED_BLUE))
E.append(sp(0.3))
# 6a - MI
E.append(para("<b>A. Myocardial Infarction (MI / Heart Attack)</b>", H2))
E.append(para(
"<b>Definition:</b> Irreversible myocardial cell death due to prolonged ischaemia, usually from plaque rupture "
"and coronary artery occlusion.", BODY))
E.append(sp(0.1))
E.append(two_col_table(
["STEMI", "NSTEMI"],
[
["Complete occlusion of coronary artery", "Partial occlusion / demand ischaemia"],
["ST elevation ≥1 mm in ≥2 contiguous leads", "ST depression, T-wave inversion, or normal ECG"],
["Troponin elevated (may take 3–6h)", "Troponin elevated"],
["Target: Reperfusion within 90 min (PCI) or 30 min (thrombolysis)", "Medical management ± urgent PCI"],
],
hdr_bg=MED_BLUE
))
E.append(sp(0.15))
E.append(info_box("MONA-B Mnemonic (Initial MI Management)",
["M – Morphine (4–8 mg IV; for unrelieved pain — use cautiously)",
"O – Oxygen (only if SpO₂ <94%; avoid hyperoxia)",
"N – Nitrates (GTN sublingual/IV for pain — contraindicated in hypotension, RV infarct, PDE5 inhibitor use)",
"A – Aspirin 300 mg stat (loading dose) + Ticagrelor/Clopidogrel (dual antiplatelet)",
"B – Beta-blocker (oral, once stable; reduces myocardial O₂ demand)"],
bg=LIGHT_BLUE, border=MED_BLUE))
E.append(sp(0.2))
# 6b - HF
E.append(para("<b>B. Heart Failure (HF)</b>", H2))
E.append(para(
"<b>Definition:</b> Inability of the heart to pump sufficient blood to meet the body's metabolic needs. "
"Classified by ejection fraction: <b>HFrEF</b> (EF <40%), <b>HFmrEF</b> (40–49%), <b>HFpEF</b> (EF ≥50%).", BODY))
E.append(sp(0.1))
E.append(two_col_table(
["Left Heart Failure (LHF)", "Right Heart Failure (RHF)"],
[
["Backward failure → pulmonary oedema", "Backward failure → systemic venous congestion"],
["Dyspnoea, orthopnoea, PND, crackles", "Peripheral oedema, JVD, hepatomegaly, ascites"],
["Pink frothy sputum (acute pulmonary oedema)", "Weight gain, right upper quadrant pain"],
["CXR: Cardiomegaly, Kerley B lines, bat-wing infiltrates", "CXR: Cardiomegaly, pleural effusions"],
],
hdr_bg=MED_BLUE
))
E.append(sp(0.15))
E.append(para("<b>NYHA Classification</b>", H3))
E.append(multi_col_table(
["Class", "Symptoms", "Clinical"],
[
["I", "No symptoms with ordinary activity", "Asymptomatic HF"],
["II", "Slight limitation; comfortable at rest", "Mild HF"],
["III", "Marked limitation; comfortable at rest only", "Moderate HF"],
["IV", "Symptoms at rest; unable to carry on any activity", "Severe HF"],
],
[2*cm, 8*cm, 7.5*cm], hdr_bg=MED_BLUE
))
E.append(sp(0.2))
# 6c - Hypertension
E.append(para("<b>C. Hypertension (HTN)</b>", H2))
E.append(multi_col_table(
["Stage", "Systolic (mmHg)", "Diastolic (mmHg)", "Action"],
[
["Normal", "<120", "<80", "Lifestyle only"],
["Elevated", "120–129", "<80", "Lifestyle modification"],
["Stage 1 HTN", "130–139", "80–89", "Lifestyle ± medication"],
["Stage 2 HTN", "≥140", "≥90", "Medication + lifestyle"],
["Hypertensive Crisis", "≥180", "≥120", "Immediate medical intervention"],
],
[3*cm, 3.5*cm, 3.5*cm, 7.5*cm], hdr_bg=MED_BLUE
))
E.append(sp(0.2))
# 6d - Other conditions
E.append(para("<b>D. Other Common Conditions</b>", H2))
other_cond = [
["Angina Pectoris", "Stable: exertional chest pain relieved by rest/GTN; Unstable: at rest, increasing severity — ACS until proved otherwise",
"Rest, GTN, O₂, ECG, troponin; aspirin; refer if unstable"],
["Atrial Fibrillation (AF)", "Irregular pulse, palpitations, dyspnoea, embolic risk; commonest sustained arrhythmia",
"Rate/rhythm control; anticoagulation (CHA₂DS₂-VASc ≥1); stroke prevention"],
["Cardiogenic Shock", "SBP <90 mmHg, cold/clammy, confusion, oliguria despite adequate filling — severe pump failure",
"IV inotropes (dobutamine), vasopressors (noradrenaline), IABP, urgent revascularisation"],
["Cardiac Arrest", "Pulseless, unresponsive, apnoeic — VF/VT (shockable) or PEA/Asystole (non-shockable)",
"CPR 30:2, defibrillation (shockable), adrenaline 1 mg IV, treat reversible causes (4Hs & 4Ts)"],
["Infective Endocarditis", "Fever, new murmur, embolic phenomena, Osler nodes, Janeway lesions, Roth spots",
"Blood cultures x3 before antibiotics; prolonged IV antibiotics; echo for vegetation"],
]
E.append(multi_col_table(
["Condition", "Key Features", "Initial Management"],
other_cond,
[4*cm, 7*cm, 6.5*cm], hdr_bg=MED_BLUE
))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 7. PHARMACOLOGY
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("7. CARDIAC PHARMACOLOGY", GREEN))
E.append(sp(0.3))
drug_classes = [
("A. Beta-Blockers (β-Blockers)", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Metoprolol, Atenolol, Carvedilol, Bisoprolol",
"Block β1 (and β2) adrenoreceptors → ↓ HR, ↓ contractility, ↓ BP, ↓ renin release",
"HTN, Angina, MI, HFrEF, AF rate control, Arrhythmias",
"Monitor HR (hold if <60 bpm), BP; do NOT stop abruptly (rebound); caution in asthma/COPD; check glucose in diabetics"],
]
]),
("B. ACE Inhibitors (ACEi)", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Ramipril, Lisinopril, Enalapril, Perindopril",
"Inhibit ACE → ↓ Angiotensin II → vasodilation, ↓ aldosterone, ↓ preload & afterload",
"HTN, HFrEF, post-MI, diabetic nephropathy",
"Monitor BP (1st dose hypotension), K⁺ (hyperkalaemia), creatinine (renal function); persistent dry cough → switch to ARB; contraindicated in pregnancy"],
]
]),
("C. Angiotensin Receptor Blockers (ARBs)", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Losartan, Valsartan, Candesartan",
"Block AT1 receptors directly → similar effects to ACEi but without bradykinin (no cough)",
"HTN, HFrEF (if ACEi-intolerant), post-MI",
"Monitor BP, K⁺, renal function; contraindicated in pregnancy; do NOT combine with ACEi routinely"],
]
]),
("D. Diuretics", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Furosemide (loop), Spironolactone (K⁺-sparing), Hydrochlorothiazide (thiazide)",
"Loop: Inhibit Na⁺/K⁺/2Cl⁻ in ascending limb; Thiazide: Inhibit NaCl in DCT; Spiro: Aldosterone antagonist",
"HF (fluid overload), HTN, oedema, hyperaldosteronism",
"Monitor fluid balance, daily weight, electrolytes (K⁺ esp.); furosemide → hypokalaemia; spironolactone → hyperkalaemia; monitor creatinine"],
]
]),
("E. Calcium Channel Blockers (CCBs)", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Amlodipine (DHP), Diltiazem, Verapamil (non-DHP)",
"Block L-type Ca²⁺ channels; DHP: primarily vascular smooth muscle → vasodilation; Non-DHP: also cardiac (↓ HR, ↓ AV conduction)",
"HTN, Angina, AF rate control (diltiazem/verapamil), vasospastic angina",
"DHP: monitor for ankle oedema, flushing, headache; Non-DHP: DO NOT combine with beta-blockers (risk of complete heart block); monitor HR/PR interval"],
]
]),
("F. Nitrates", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["GTN (sublingual, IV, patch), Isosorbide mononitrate",
"Release NO → venous & arterial dilation → ↓ preload & afterload → ↓ myocardial O₂ demand",
"Angina (acute & chronic), Acute HF, STEMI",
"Headache is common initially; tolerance develops with continuous use — provide 8–12 h nitrate-free period for patches; contraindicated with PDE5 inhibitors (sildenafil); hold if SBP <90 mmHg"],
]
]),
("G. Antiplatelets & Anticoagulants", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Aspirin, Clopidogrel, Ticagrelor (antiplatelet); Warfarin, Apixaban, Rivaroxaban (anticoagulant)",
"Antiplatelets: inhibit platelet aggregation (COX-1, P2Y12); Anticoagulants: inhibit clotting cascade (Vit K-dependent factors, Xa, thrombin)",
"ACS/MI (DAPT), AF (anticoagulation), DVT/PE, mechanical valves",
"Bleeding risk — assess skin, stool, urine for blood; do not give NSAIDs with aspirin; DOAC — no routine INR monitoring but check renal function; warfarin — target INR 2–3 (AF), 2.5–3.5 (mechanical valves)"],
]
]),
("H. Digoxin", [
["Drug (Example)", "Mechanism", "Indications", "Key Nursing Points"],
[
["Digoxin",
"Inhibits Na⁺/K⁺ ATPase → ↑ intracellular Ca²⁺ → ↑ contractility; also ↑ vagal tone → ↓ HR & AV conduction",
"HFrEF with AF (rate control), AF rate control",
"NARROW THERAPEUTIC INDEX (0.5–2 ng/mL); toxicity: nausea, vomiting, visual changes (yellow/green halos), bradycardia, AV block; hold if HR <60; hypokalaemia and renal impairment increase toxicity risk"],
]
]),
("I. Antiarrhythmics (Vaughan Williams Classes)", [
["Class / Drug", "Mechanism", "Use"],
[
["Ia: Quinidine, Procainamide", "Na⁺ channel block (intermediate)", "VT, AF, VF"],
["Ib: Lidocaine, Mexiletine", "Na⁺ channel block (fast)", "Ventricular arrhythmias"],
["Ic: Flecainide, Propafenone", "Na⁺ channel block (slow)", "AF, SVT (avoid in structural heart disease)"],
["II: Beta-blockers", "β-adrenoreceptor block", "SVT, VT, rate control"],
["III: Amiodarone, Sotalol", "K⁺ channel block → ↑ action potential duration", "VT, VF, AF — amiodarone is most effective broad-spectrum"],
["IV: Verapamil, Diltiazem", "Ca²⁺ channel block (non-DHP)", "SVT, AF rate control"],
["Adenosine (unclassified)", "AV nodal block (transient)", "First-line for SVT termination"],
]
]),
]
for title, table_data in drug_classes:
E.append(para(f"<b>{title}</b>", H2))
hdrs = table_data[0]
rows = table_data[1]
if len(hdrs) == 4:
E.append(multi_col_table(hdrs, rows, [3.5*cm, 4.5*cm, 4*cm, 5.5*cm], hdr_bg=GREEN))
elif len(hdrs) == 3:
if title.startswith("I."):
E.append(multi_col_table(hdrs, rows, [5*cm, 7*cm, 5.5*cm], hdr_bg=GREEN))
else:
E.append(multi_col_table(hdrs, rows, [4*cm, 7*cm, 6.5*cm], hdr_bg=GREEN))
E.append(sp(0.2))
E.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════
# 8. NURSING ASSESSMENT & INTERVENTIONS
# ═══════════════════════════════════════════════════════════════════════════
E.append(section_header("8. NURSING ASSESSMENTS & INTERVENTIONS", DARK_GREY))
E.append(sp(0.3))
E.append(para("<b>Cardiovascular Assessment — IPPA Approach</b>", H2))
E.append(multi_col_table(
["Step", "Action", "What to Assess"],
[
["Inspection", "Observe patient", "JVD (raised >4 cm above sternal angle = elevated CVP), peripheral oedema, cyanosis, skin colour/temperature, chest deformities, capillary refill (normal <2 sec)"],
["Palpation", "Feel", "Apex beat (5th ICS, MCL), peripheral pulses (rate, rhythm, volume, character), pitting oedema grade"],
["Percussion", "Tap", "Cardiac dullness borders; lung fields for pleural effusion (stony dull)"],
["Auscultation", "Listen", "Heart sounds (S1, S2, extra sounds, murmurs); lung fields (crackles = pulmonary oedema, wheeze = bronchospasm)"],
],
[2.5*cm, 3*cm, 12*cm], hdr_bg=DARK_GREY
))
E.append(sp(0.3))
E.append(para("<b>Critical Nursing Observations</b>", H2))
E.append(multi_col_table(
["Observation", "Normal", "Action if Abnormal"],
[
["Blood Pressure", "100–140 / 60–90 mmHg", "SBP <90: fluid challenge/vasopressors; SBP >180: antihypertensives; report both"],
["Heart Rate", "60–100 bpm", "HR <60 (symptomatic): atropine; HR >150: investigate rhythm; defibrillate if pulseless VT/VF"],
["SpO₂", "≥94% (≥88% in COPD)", "Supplemental O₂; target 94–98%; mask if severe"],
["Urine Output", ">0.5 mL/kg/hr", "Oliguria suggests ↓ CO or AKI; notify doctor; fluid balance review"],
["ECG", "Sinus rhythm, normal intervals", "Print 12-lead; escalate per rhythm; continuous monitoring in ACS/arrhythmia"],
["Troponin", "<0.04 ng/mL (hs-Troponin)", "Elevated at 0 & 3h = myocardial injury; serial measurements; treat as ACS"],
["BNP / NT-proBNP", "BNP <100 pg/mL", "Elevated in HF; higher = worse prognosis; guides diuretic therapy"],
],
[4*cm, 3.5*cm, 10*cm], hdr_bg=DARK_GREY
))
E.append(sp(0.3))
E.append(para("<b>4 Hs and 4 Ts — Reversible Causes of Cardiac Arrest</b>", H2))
E.append(two_col_table(
["4 Hs", "4 Ts"],
[
["Hypoxia", "Tension Pneumothorax"],
["Hypovolaemia", "Tamponade (Cardiac)"],
["Hypo/Hyperkalaemia (+ other metabolic)", "Toxins (drugs/overdose)"],
["Hypothermia", "Thrombosis (PE or Coronary)"],
],
hdr_bg=DARK_GREY
))
E.append(sp(0.3))
E.append(para("<b>Patient Education Checklist</b>", H2))
E.append(info_box("Discharge Teaching Topics",
["Medication compliance: explain each drug, timing, side effects, importance of NOT stopping suddenly",
"Diet: low sodium (<2 g/day in HF), Mediterranean diet, limit saturated fats and alcohol",
"Activity: gradual return; cardiac rehab referral post-MI/HF; report exertional symptoms",
"Weight monitoring: daily weights; report >2 kg gain in 2 days (fluid retention)",
"Smoking cessation: most modifiable risk factor — refer to cessation programme",
"BP and glucose monitoring at home (HTN/DM patients)",
"When to seek emergency care: chest pain, sudden dyspnoea, syncope, palpitations, oedema"],
bg=LIGHT_GRN, border=GREEN))
E.append(sp(0.3))
# Quick reference: Murmurs
E.append(para("<b>Common Cardiac Murmurs — Quick Reference</b>", H2))
E.append(multi_col_table(
["Murmur", "Timing", "Best Heard", "Radiation", "Cause"],
[
["Aortic Stenosis (AS)", "Systolic ejection (crescendo-decrescendo)", "Right 2nd ICS", "Carotids", "Calcified aortic valve; most common in elderly"],
["Aortic Regurgitation (AR)", "Early diastolic (decrescendo)", "Left 3rd/4th ICS (Erb's point)", "—", "Rheumatic fever, aortic dissection, infective endocarditis"],
["Mitral Stenosis (MS)", "Mid-diastolic, low-pitched", "Apex (left lateral decubitus)", "—", "Rheumatic heart disease; 'rumble' with opening snap"],
["Mitral Regurgitation (MR)", "Pansystolic (holosystolic)", "Apex", "Axilla", "Mitral valve prolapse, ischaemic papillary muscle dysfunction"],
],
[3.5*cm, 4*cm, 3.5*cm, 2.5*cm, 4*cm], hdr_bg=DARK_GREY
))
E.append(sp(0.5))
E.append(hr(DARK_GREY))
E.append(para(
"<i>Sources: Braunwald's Heart Disease 11e (Elsevier) • Fuster and Hurst's The Heart 15e (McGraw-Hill) • "
"AHA/ACC 2022 Guidelines • ESC 2023 Guidelines. These notes are intended as a study aid — "
"always consult current clinical guidelines for patient care.</i>",
s('Footer', parent=SMALL, fontSize=8, textColor=MID_GREY, alignment=TA_CENTER)
))
# ── BUILD ─────────────────────────────────────────────────────────────────
doc.build(E)
print(f"PDF created: {OUTPUT}")
if __name__ == "__main__":
build()
cd /home/daytona/workspace/cardiac-note && python generate_cardiac_pdf.py 2>&1
~/cardiac-note/generate_cardiac_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/cardiac-note/generate_cardiac_pdf.py'
"s('IH', parent=" in ~/cardiac-note
~/cardiac-note/generate_cardiac_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/cardiac-note/generate_cardiac_pdf.py'
~/cardiac-note/generate_cardiac_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/cardiac-note/generate_cardiac_pdf.py'
cd /home/daytona/workspace/cardiac-note && python generate_cardiac_pdf.py 2>&1
ls -lh /home/daytona/workspace/cardiac-note/Cardiac_System_Nursing_Notes.pdf
Cardiac System Nursing Notes
PDF Document · PDF
| Section | Contents |
|---|---|
| 1. Anatomy | Heart wall layers, 4 chambers, 4 valves, coronary arteries, heart sounds (S1–S4) |
| 2. Physiology & Blood Flow | Pulmonary vs. systemic circulation, haemodynamic parameters (CO, SV, EF, preload, afterload), Frank-Starling law |
| 3. Cardiac Cycle | 7 phases from isovolumetric contraction to atrial kick, valve states, pressures, atrial fibrillation impact |
| 4. Conduction System | SA → AV → Bundle of His → Purkinje pathway, intrinsic rates, ventricular action potential phases (0–4) with ion movements |
| 5. ECG Basics | Normal waveform values (P, PR, QRS, ST, T, QT), 12 common rhythms with ECG features and nursing actions |
| 6. Cardiac Diseases | MI (STEMI vs. NSTEMI, MONA-B), Heart Failure (LHF vs. RHF, NYHA), HTN staging, Angina, AF, Cardiogenic Shock, Arrest, Endocarditis |
| 7. Pharmacology | Beta-blockers, ACEi, ARBs, Diuretics, CCBs, Nitrates, Antiplatelets/Anticoagulants, Digoxin, Antiarrhythmics (Vaughan Williams Classes I–IV + Adenosine) |
| 8. Nursing Assessments | IPPA cardiovascular assessment, critical observations with action thresholds, 4Hs & 4Ts, discharge education, murmur guide |