I have send you my marrow notes and textbook notes of DKA tell me what to add in my marrow notes to complete my answer
| What you have | What's missing |
|---|---|
| Insulinopenia + counter-regulatory hormones | Add catecholamines explicitly alongside GH, glucagon, cortisol |
| Hyperglycemia + lipolysis | Add: osmotic diuresis → urinary water loss → dehydration (your notes show intracellular dehydration but miss the osmotic diuresis/polyuria pathway) |
| Ketone bodies listed | Add that β-hydroxybutyrate is measured clinically (β-HB ≥ 5.3 mmol/L) |
| Pseudohyponatremia noted | Add: acidosis shifts K⁺ and PO₄³⁻ from ICF → ECF (the potassium/phosphate shift is missing) |
| — | Add: serum K⁺ is initially HIGH → becomes hypokalemic with insulin therapy (this is a high-yield point completely absent from your notes) |
| Presentation | DDx |
|---|---|
| Encephalopathy | CNS infections, severe malaria, poisoning |
| Acute abdomen | Pancreatitis, appendicitis |
| Dehydration | Gastroenteritis |
| Tachypnea | Bronchial asthma, pneumonia |
| Hyperglycemia with acidosis, no ketones | Renal failure, septicemia |
| Ketoacidosis without hyperglycemia | Starvation, salicylate poisoning, organic acidemia |
| Parameter | Expected | Concern | Action |
|---|---|---|---|
| Blood glucose | Decrease 50-100 mg/dL/hr | Decline > 100 mg/dL/hr | Add dextrose |
| Decline < 50 mg/dL/hr | Prepare fresh insulin, flush tubing | ||
| Blood pH | Resolution by 12 hr | Persistent at 12 hr | Exclude infection, shock, lactic acidosis |
| Serum Na⁺ | Increase | Increase < 2 mmol/L/hr | Increase sodium in IV fluid |
| Serum K⁺ | Gradual decrease | Hypokalemia | Increase K⁺ in IV fluid |
| Anion gap | Resolution by 12 hr | Elevated at 12 hr | Exclude lactic acidosis/infection |
| Plasma osmolality | Stable | Decrease > 2 mOsm/kg/hr | Increase Na, decrease fluid rate |
| Blood urea | Decrease | Persistently elevated | Exclude renal failure |
Give that is required for university final year theory examination
"Most severe acute complication of DM; seen in T1D, increasingly in T2D and MODY"
Acidosis → shifts K⁺ and PO₄³⁻ from ICF → ECF → Serum K⁺ initially HIGH → becomes LOW once insulin started
| Presentation | Think DKA when ruling out |
|---|---|
| Encephalopathy | CNS infection, malaria, poisoning |
| Acute abdomen | Pancreatitis, appendicitis |
| Dehydration | Gastroenteritis |
| Tachypnea | Asthma, pneumonia |
| Acidosis without ketones | Renal failure, septicemia |
| Ketosis without hyperglycemia | Starvation, salicylate poisoning |
| Investigation | Finding | Significance |
|---|---|---|
| Serum Na⁺ | Low (false - pseudohyponatremia) | Use corrected Na⁺. Rapid fall = risk of cerebral edema |
| Serum K⁺ | Normal/High (despite total body deficit 3-6 mEq/kg) | Becomes dangerously low with insulin |
| Serum phosphate | Low | Treat if < 1 mg/dL |
| WBC | Transient leukocytosis | Normal in DKA. Persistent = suspect infection |
| Blood urea | High | Indicates severe DKA |
| ECG | — | Screens for hypo/hyperkalemia |
| Blood gas | pH < 7.3, HCO₃ < 15 | Confirms acidosis |
K⁺ < 3.5 mEq/L → Give K⁺ BEFORE insulin
K⁺ 3.5-6 mEq/L → Add 40 mEq/L KCl when starting insulin
K⁺ > 6 mEq/L → Do NOT give K⁺ (also if anuric / ECG changes)
Avoided routinely. Give only if pH < 6.9 + hemodynamic compromise OR K⁺ > 6.5 mEq/L with ECG changes
Age < 5 yr | Severe acidosis | Hydration excess | Insulin bolus | CO₂ < 10 mmol/L + alkali
| Parameter | Frequency | Concern if... |
|---|---|---|
| Neuro status, HR, BP, I/O | Hourly | Any deterioration |
| Blood glucose | Hourly | Fall > 100 mg/dL/hr → add dextrose; Fall < 50 → change insulin |
| pH, HCO₃, electrolytes, ketones | 4-hourly | pH not resolving by 12 hr → exclude infection |
| Serum Na⁺ | 4-hourly | Not rising → increase Na in fluid |
Make pdf for differential diagnosis investigation management in short marrow textbook mix notes complications monitoring
mkdir -p /tmp/workspace/dka-notes && ls /tmp/workspace/dka-notes/
~/dka-notes/make_dka_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
OUTPUT = "/tmp/workspace/dka-notes/DKA_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm,
leftMargin=1.8*cm,
topMargin=2*cm,
bottomMargin=2*cm,
)
# ── Colour palette ──────────────────────────────────────────────
C_NAVY = colors.HexColor("#1A3A5C")
C_TEAL = colors.HexColor("#0B6E6E")
C_ORANGE = colors.HexColor("#D45A00")
C_RED = colors.HexColor("#B82020")
C_YELLOW = colors.HexColor("#FFF3B0")
C_LTBLUE = colors.HexColor("#E8F4FD")
C_LTGREEN = colors.HexColor("#E8F8F0")
C_LTRED = colors.HexColor("#FDF0F0")
C_LTORANGE= colors.HexColor("#FFF5E6")
C_GREY = colors.HexColor("#F4F4F4")
C_WHITE = colors.white
C_BLACK = colors.HexColor("#1A1A1A")
styles = getSampleStyleSheet()
def sty(name, **kwargs):
return ParagraphStyle(name, **kwargs)
TITLE_STYLE = sty("Title",
fontSize=22, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_CENTER,
spaceAfter=4, spaceBefore=4)
SUBTITLE_STYLE = sty("Subtitle",
fontSize=11, fontName="Helvetica",
textColor=C_WHITE, alignment=TA_CENTER,
spaceAfter=2)
H1 = sty("H1",
fontSize=13, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_LEFT,
spaceBefore=10, spaceAfter=2,
leftIndent=4)
H2 = sty("H2",
fontSize=11, fontName="Helvetica-Bold",
textColor=C_NAVY,
spaceBefore=8, spaceAfter=3)
BODY = sty("Body",
fontSize=9.5, fontName="Helvetica",
textColor=C_BLACK,
spaceBefore=2, spaceAfter=2,
leading=14)
BODY_BOLD = sty("BodyBold",
fontSize=9.5, fontName="Helvetica-Bold",
textColor=C_NAVY,
spaceBefore=2, spaceAfter=2,
leading=14)
SMALL = sty("Small",
fontSize=8.5, fontName="Helvetica",
textColor=C_BLACK, leading=12,
spaceBefore=1, spaceAfter=1)
SMALL_BOLD = sty("SmallBold",
fontSize=8.5, fontName="Helvetica-Bold",
textColor=C_NAVY, leading=12)
WARN = sty("Warn",
fontSize=9, fontName="Helvetica-Bold",
textColor=C_RED, leading=13)
NOTE = sty("Note",
fontSize=8.5, fontName="Helvetica-Oblique",
textColor=C_TEAL, leading=12)
TABLE_HEADER = sty("TH",
fontSize=9, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_CENTER, leading=12)
TABLE_CELL = sty("TC",
fontSize=8.5, fontName="Helvetica",
textColor=C_BLACK, alignment=TA_LEFT, leading=12)
TABLE_CELL_C = sty("TCC",
fontSize=8.5, fontName="Helvetica",
textColor=C_BLACK, alignment=TA_CENTER, leading=12)
TABLE_CELL_BOLD = sty("TCB",
fontSize=8.5, fontName="Helvetica-Bold",
textColor=C_NAVY, alignment=TA_LEFT, leading=12)
# ── Helper builders ─────────────────────────────────────────────
def section_header(text, bg=C_NAVY):
t = Table([[Paragraph(text, H1)]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("ROWPADDING", (0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return t
def hr():
return HRFlowable(width="100%", thickness=1, color=C_TEAL, spaceAfter=4, spaceBefore=4)
def sp(h=6):
return Spacer(1, h)
def p(text, style=BODY):
return Paragraph(text, style)
def bullet(items, style=BODY):
out = []
for item in items:
out.append(Paragraph(f"<bullet>\u2022</bullet> {item}", style))
return out
def key_val_table(rows, col1=6.5*cm, col2=None):
if col2 is None:
col2 = doc.width - col1
data = []
for k, v in rows:
data.append([
Paragraph(k, TABLE_CELL_BOLD),
Paragraph(v, TABLE_CELL)
])
t = Table(data, colWidths=[col1, col2])
t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("ROWBACKGROUNDS", (0,0), (-1,-1), [C_WHITE, C_GREY]),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
return t
def generic_table(headers, rows, col_widths, row_colors=None, header_bg=C_NAVY):
data = [[Paragraph(h, TABLE_HEADER) for h in headers]]
for i, row in enumerate(rows):
data.append([Paragraph(str(c), TABLE_CELL) for c in row])
t = Table(data, colWidths=col_widths)
style_cmds = [
("BACKGROUND", (0,0), (-1,0), header_bg),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]
if row_colors:
for i, bg in enumerate(row_colors):
style_cmds.append(("BACKGROUND", (0, i+1), (-1, i+1), bg))
else:
for i in range(len(rows)):
bg = C_WHITE if i % 2 == 0 else C_GREY
style_cmds.append(("BACKGROUND", (0, i+1), (-1, i+1), bg))
t.setStyle(TableStyle(style_cmds))
return t
def info_box(text, bg=C_LTBLUE, border=C_TEAL):
t = Table([[Paragraph(text, BODY)]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("BOX", (0,0), (-1,-1), 1.5, border),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return t
def warn_box(text):
return info_box(text, bg=C_LTRED, border=C_RED)
def tip_box(text):
return info_box(text, bg=C_LTORANGE, border=C_ORANGE)
# ═══════════════════════════════════════════════════════════════
# BUILD CONTENT
# ═══════════════════════════════════════════════════════════════
story = []
# ── TITLE BANNER ────────────────────────────────────────────────
title_data = [[
Paragraph("DIABETIC KETOACIDOSIS", TITLE_STYLE),
Paragraph("DKA", sty("TL", fontSize=28, fontName="Helvetica-Bold",
textColor=colors.HexColor("#FFFFFF66"),
alignment=TA_CENTER))
]]
title_table = Table(title_data, colWidths=[doc.width - 3*cm, 3*cm])
title_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_NAVY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("LEFTPADDING", (0,0), (-1,-1), 12),
("ROUNDEDCORNERS", [6,6,6,6]),
]))
story.append(title_table)
sub_data = [[
Paragraph("Marrow + Textbook Notes | Final Year Theory Exam | ISPAD Guidelines", SUBTITLE_STYLE)
]]
sub_table = Table(sub_data, colWidths=[doc.width])
sub_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_TEAL),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
story.append(sub_table)
story.append(sp(10))
# ═══════════════════════════════════════════════════════
# SECTION 1: DIFFERENTIAL DIAGNOSIS
# ═══════════════════════════════════════════════════════
story.append(section_header("1. DIFFERENTIAL DIAGNOSIS — WHEN TO SUSPECT DKA"))
story.append(sp(6))
story.append(p("DKA must be considered in the differential diagnosis of the following presentations:", BODY))
story.append(sp(4))
dd_data = [
[Paragraph("PRESENTATION", TABLE_HEADER),
Paragraph("CONDITIONS TO RULE OUT", TABLE_HEADER),
Paragraph("DKA CLUE", TABLE_HEADER)],
[Paragraph("Encephalopathy / altered sensorium", TABLE_CELL_BOLD),
Paragraph("CNS infections, severe malaria, poisoning", TABLE_CELL),
Paragraph("Hyperglycemia + ketones", TABLE_CELL)],
[Paragraph("Acute abdomen", TABLE_CELL_BOLD),
Paragraph("Pancreatitis, appendicitis", TABLE_CELL),
Paragraph("Abdominal pain d/t acidosis", TABLE_CELL)],
[Paragraph("Dehydration", TABLE_CELL_BOLD),
Paragraph("Gastroenteritis", TABLE_CELL),
Paragraph("No diarrhoea; osmotic diuresis", TABLE_CELL)],
[Paragraph("Tachypnea / respiratory distress", TABLE_CELL_BOLD),
Paragraph("Bronchial asthma, pneumonia", TABLE_CELL),
Paragraph("Kussmaul breathing (deep, not wheeze)", TABLE_CELL)],
[Paragraph("Hyperglycemia + acidosis, NO ketones", TABLE_CELL_BOLD),
Paragraph("Renal failure, septicemia", TABLE_CELL),
Paragraph("Ketonuria absent; BUN very high", TABLE_CELL)],
[Paragraph("Ketoacidosis, NO hyperglycemia", TABLE_CELL_BOLD),
Paragraph("Starvation, salicylate poisoning, organic acidemia", TABLE_CELL),
Paragraph("Glucose normal / low", TABLE_CELL)],
]
dd_table = Table(dd_data, colWidths=[4.5*cm, 6.5*cm, doc.width-11*cm])
dd_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
*[("BACKGROUND", (0,i), (-1,i), C_WHITE if i%2==1 else C_GREY) for i in range(1,8)],
]))
story.append(dd_table)
story.append(sp(8))
# ═══════════════════════════════════════════════════════
# SECTION 2: INVESTIGATIONS
# ═══════════════════════════════════════════════════════
story.append(section_header("2. INVESTIGATIONS", bg=C_TEAL))
story.append(sp(6))
inv_data = [
[Paragraph("INVESTIGATION", TABLE_HEADER),
Paragraph("FINDING IN DKA", TABLE_HEADER),
Paragraph("SIGNIFICANCE / ACTION", TABLE_HEADER)],
[Paragraph("Serum Na⁺", TABLE_CELL_BOLD),
Paragraph("LOW (falsely - pseudohyponatremia)\nTrue deficit: 4-6 mEq/kg", TABLE_CELL),
Paragraph("Use corrected Na⁺. Rapid fall in Na⁺ = risk for cerebral edema", TABLE_CELL)],
[Paragraph("Serum K⁺", TABLE_CELL_BOLD),
Paragraph("NORMAL or HIGH at presentation\nTrue deficit: 3-6 mEq/kg (ICF depleted)", TABLE_CELL),
Paragraph("Becomes dangerously LOW once insulin started. Monitor carefully.", TABLE_CELL)],
[Paragraph("Serum Phosphate", TABLE_CELL_BOLD),
Paragraph("LOW (significant deficit)", TABLE_CELL),
Paragraph("Treat if phosphate < 1 mg/dL", TABLE_CELL)],
[Paragraph("Blood glucose", TABLE_CELL_BOLD),
Paragraph("> 200 mg/dL", TABLE_CELL),
Paragraph("Confirm diagnosis; monitor hourly", TABLE_CELL)],
[Paragraph("Blood gas (VBG)", TABLE_CELL_BOLD),
Paragraph("pH < 7.3, HCO₃ < 15 mEq/L", TABLE_CELL),
Paragraph("Confirms acidosis; severity assessment", TABLE_CELL)],
[Paragraph("Urine/blood ketones", TABLE_CELL_BOLD),
Paragraph("Ketonuria ≥ 2+ on dipstick\nor β-HB ≥ 5.3 mmol/L", TABLE_CELL),
Paragraph("Confirms ketosis", TABLE_CELL)],
[Paragraph("WBC count", TABLE_CELL_BOLD),
Paragraph("Transient leukocytosis = NORMAL in DKA", TABLE_CELL),
Paragraph("PERSISTENT leukocytosis + fever = suspect infection", TABLE_CELL)],
[Paragraph("Blood urea / BUN", TABLE_CELL_BOLD),
Paragraph("High BUN", TABLE_CELL),
Paragraph("Indicator of SEVERE DKA", TABLE_CELL)],
[Paragraph("ECG", TABLE_CELL_BOLD),
Paragraph("May show hypo/hyperkalemia changes", TABLE_CELL),
Paragraph("Peaked T = hyperkalemia; Flat T, U wave = hypokalemia", TABLE_CELL)],
[Paragraph("Serum osmolality", TABLE_CELL_BOLD),
Paragraph("High (due to hyperglycemia)", TABLE_CELL),
Paragraph("If very high: extend fluid correction to 72 hr", TABLE_CELL)],
[Paragraph("Anion gap", TABLE_CELL_BOLD),
Paragraph("Elevated (> 12 mEq/L)", TABLE_CELL),
Paragraph("Should resolve by 12 hr of treatment", TABLE_CELL)],
]
inv_table = Table(inv_data, colWidths=[3.8*cm, 5.8*cm, doc.width-9.6*cm])
inv_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_TEAL),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
*[("BACKGROUND", (0,i), (-1,i), C_WHITE if i%2==1 else C_LTBLUE) for i in range(1,13)],
]))
story.append(inv_table)
story.append(sp(6))
story.append(tip_box(
"<b>KEY POINT (High Yield):</b> Serum K⁺ is normal/HIGH at presentation despite total body K⁺ depletion "
"because acidosis drives K⁺ out of cells (ICF → ECF). Once insulin corrects acidosis, "
"K⁺ shifts back into cells → life-threatening HYPOKALEMIA."
))
story.append(sp(10))
# ═══════════════════════════════════════════════════════
# SECTION 3: MANAGEMENT
# ═══════════════════════════════════════════════════════
story.append(section_header("3. MANAGEMENT", bg=C_ORANGE))
story.append(sp(6))
story.append(p("<b>3 Pillars of Management:</b>", BODY_BOLD))
pillars_data = [[
Paragraph("1\nCorrect the Pathology\n(Insulin for hyperglycemia)", sty("P1",
fontSize=9, fontName="Helvetica-Bold", textColor=C_WHITE,
alignment=TA_CENTER, leading=13)),
Paragraph("2\nCorrect Dehydration\n(Fluid restoration)", sty("P2",
fontSize=9, fontName="Helvetica-Bold", textColor=C_WHITE,
alignment=TA_CENTER, leading=13)),
Paragraph("3\nIdentify & Treat\nPrecipitating Event", sty("P3",
fontSize=9, fontName="Helvetica-Bold", textColor=C_WHITE,
alignment=TA_CENTER, leading=13)),
]]
pillars_table = Table(pillars_data, colWidths=[doc.width/3]*3)
pillars_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), C_NAVY),
("BACKGROUND", (1,0), (1,0), C_TEAL),
("BACKGROUND", (2,0), (2,0), C_ORANGE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("INNERGRID", (0,0), (-1,-1), 2, C_WHITE),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
story.append(pillars_table)
story.append(sp(8))
# ICU criteria
story.append(warn_box(
"<b>ICU ADMISSION CRITERIA:</b> Age < 2 years | Severe DKA (pH < 7.1) "
"| Altered consciousness"
))
story.append(sp(6))
# ── 3A. Initial Stabilization
story.append(p("<b>A. INITIAL STABILIZATION</b>", H2))
init_items = [
"Assess Airway, Breathing, Circulation (ABC)",
"Oxygen and respiratory support if needed",
"IV access; send blood for investigations",
"Insert NG tube + urinary catheter if <b>unconscious</b>",
"<b>Defer intubation</b> - worsens CNS acidosis (IMPORTANT)",
"Nil by mouth",
"Neurological evaluation: pupils, cranial nerves (6th nerve palsy = cerebral edema), DTR",
]
for item in init_items:
story.append(Paragraph(f"<bullet>\u2022</bullet> {item}", BODY))
story.append(sp(6))
# ── 3B. Fluid Therapy
story.append(p("<b>B. FLUID THERAPY (Mainstay of treatment)</b>", H2))
fluid_data = [
[Paragraph("CONDITION", TABLE_HEADER),
Paragraph("FEATURES", TABLE_HEADER),
Paragraph("FLUID REGIME", TABLE_HEADER)],
[Paragraph("Minimal dehydration (Mild DKA)", TABLE_CELL_BOLD),
Paragraph("Tolerates oral fluids", TABLE_CELL),
Paragraph("Oral fluids; S/C insulin", TABLE_CELL)],
[Paragraph("Moderate/Severe dehydration (not in shock)", TABLE_CELL_BOLD),
Paragraph("Vomiting, intolerant to oral, dehydrated", TABLE_CELL),
Paragraph("10-20 mL/kg IV NS (0.9%) over 20-30 min", TABLE_CELL)],
[Paragraph("Shock", TABLE_CELL_BOLD),
Paragraph("Thready pulse, altered consciousness/coma", TABLE_CELL),
Paragraph("Secure ABC; IV bolus 20 mL/kg 0.9% NS", TABLE_CELL)],
]
fluid_table = Table(fluid_data, colWidths=[4.5*cm, 5*cm, doc.width-9.5*cm])
fluid_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_ORANGE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
*[("BACKGROUND", (0,i), (-1,i), C_WHITE if i%2==1 else C_LTORANGE) for i in range(1,4)],
]))
story.append(fluid_table)
story.append(sp(5))
fluid_details = [
("Deficit", "5-10% body weight in most children"),
("Rate", "3-3.5 L/m²/day. <b>Never exceed 4 L/m²/day</b> (cerebral edema risk)"),
("Duration", "Correct over <b>48 hours</b> (72 hr if high plasma osmolality)"),
("IV fluid choice", "<b>Normal saline (NS) for first 6 hours</b>, then Na content 77-154 mEq/L"),
("Add dextrose when", "Blood glucose < <b>270 mg/dL</b> — add 5% dextrose to IV fluid"),
("Important note", "Count fluids already given at referring centre in total calculation"),
]
story.append(key_val_table(fluid_details, col1=5*cm))
story.append(sp(5))
story.append(warn_box(
"<b>WARNING:</b> Rapid and excessive fluid = risk for CEREBRAL EDEMA. "
"Slow rise in serum Na with rapid fall in glucose = cerebral edema risk."
))
story.append(sp(8))
# ── 3C. Insulin Therapy
story.append(p("<b>C. INSULIN THERAPY</b>", H2))
story.append(info_box(
"<b>RULE:</b> Start insulin <b>1 hour AFTER</b> starting fluids. "
"Early insulin = drastic fall in osmolality + hypokalemia + cerebral edema risk."
))
story.append(sp(5))
insulin_details = [
("Route", "<b>IV continuous infusion</b> (preferred). Flush tubing with insulin first — insulin binds to plastic."),
("Standard dose", "<b>0.05-0.1 u/kg/hr</b> IV infusion"),
("Infants / mild DKA", "0.05 u/kg/hr"),
("Increase dose if", "Glucose not falling ≥ 50 mg/dL/hr OR acidosis not resolving → increase by <b>0.02 u/kg/hr</b>"),
("NEVER reduce insulin", "When glucose falls — <b>ADD dextrose instead</b> (reducing insulin prolongs acidosis)"),
("No bolus", "<b>NO initial insulin bolus</b> — C/I due to cerebral edema risk"),
("If no IV available", "IM regular insulin: <b>0.3 u/kg loading</b>, then <b>0.1 u/kg/hr</b>"),
("SC insulin", "<b>NOT recommended</b> in moderate/severe DKA — poor perfusion = poor absorption"),
]
story.append(key_val_table(insulin_details, col1=4.5*cm))
story.append(sp(8))
# ── 3D. Potassium Protocol
story.append(p("<b>D. POTASSIUM REPLACEMENT PROTOCOL (High Yield)</b>", H2))
k_data = [
[Paragraph("SERUM K⁺ LEVEL", TABLE_HEADER),
Paragraph("ACTION", TABLE_HEADER),
Paragraph("REASON", TABLE_HEADER)],
[Paragraph("< 3.5 mEq/L", sty("kl", fontSize=9.5, fontName="Helvetica-Bold",
textColor=C_RED, leading=12)),
Paragraph("<b>Give K⁺ BEFORE starting insulin</b>", TABLE_CELL),
Paragraph("Insulin will drop K⁺ further - dangerous", TABLE_CELL)],
[Paragraph("3.5 - 6.0 mEq/L", TABLE_CELL_BOLD),
Paragraph("Add <b>40 mEq/L KCl</b> to IV fluid at time of starting insulin", TABLE_CELL),
Paragraph("Standard protocol", TABLE_CELL)],
[Paragraph("> 6.0 mEq/L\nOR anuric\nOR ECG hyperkalemia changes", sty("kh", fontSize=9.5,
fontName="Helvetica-Bold", textColor=C_RED, leading=12)),
Paragraph("<b>DO NOT give K⁺</b>", TABLE_CELL),
Paragraph("Risk of fatal hyperkalemia", TABLE_CELL)],
]
k_table = Table(k_data, colWidths=[3.8*cm, 7*cm, doc.width-10.8*cm])
k_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 6),
("BACKGROUND", (0,1), (-1,1), C_LTRED),
("BACKGROUND", (0,2), (-1,2), C_LTGREEN),
("BACKGROUND", (0,3), (-1,3), C_LTRED),
]))
story.append(k_table)
story.append(sp(8))
# ── 3E. Acid-base / Bicarbonate
story.append(p("<b>E. BICARBONATE THERAPY</b>", H2))
story.append(warn_box(
"<b>AVOID bicarbonate routinely</b> — risks: cerebral edema, lactic acidosis, hypokalemia, worsens CNS acidosis."
))
story.append(sp(4))
story.append(info_box(
"<b>EXCEPTION — Give bicarbonate ONLY IF:</b><br/>"
"1. pH < 6.9 WITH hemodynamic compromise, OR<br/>"
"2. Severe hyperkalemia: K⁺ > 6.5 mEq/L with ECG changes"
))
story.append(sp(8))
# ── 3F. Dextrose rule
story.append(p("<b>F. DEXTROSE RULE</b>", H2))
story.append(info_box(
"Add <b>5% dextrose</b> to IV fluids once blood glucose < <b>270-300 mg/dL</b>.<br/>"
"Hyperglycemia resolves BEFORE acidosis — so do NOT stop insulin; add dextrose to maintain infusion."
))
story.append(sp(8))
# ── 3G. Transition / Stopping treatment
story.append(p("<b>G. DISCONTINUATION OF ACUTE TREATMENT</b>", H2))
transition_items = [
"Switch to S/C insulin when: <b>conscious + tolerating oral feeds + acidosis resolved</b>",
"Give <b>regular/rapid-acting insulin 0.25 u/kg</b> S/C 30 minutes BEFORE first meal",
"Stop IV insulin infusion <b>30 minutes AFTER</b> S/C dose (overlap prevents rebound hyperglycemia)",
"Start basal-bolus or mix-split SC insulin regime",
]
for item in transition_items:
story.append(Paragraph(f"<bullet>\u2022</bullet> {item}", BODY))
story.append(sp(10))
# ═══════════════════════════════════════════════════════
# SECTION 4: COMPLICATIONS
# ═══════════════════════════════════════════════════════
story.append(section_header("4. COMPLICATIONS OF DKA", bg=C_RED))
story.append(sp(6))
# Cerebral edema box
ce_header = Table([[Paragraph(
"CEREBRAL EDEMA — Most common cause of death in DKA",
sty("CEH", fontSize=11, fontName="Helvetica-Bold", textColor=C_WHITE, alignment=TA_CENTER)
)]], colWidths=[doc.width])
ce_header.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_RED),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
story.append(ce_header)
story.append(sp(4))
ce_left = [
[Paragraph("TIMING", TABLE_CELL_BOLD)],
[Paragraph("Usually <b>4-12 hours</b> after starting treatment (rarely at diagnosis)", TABLE_CELL)],
[Paragraph("", TABLE_CELL)],
[Paragraph("RISK FACTORS (mnemonic: ASHIC)", TABLE_CELL_BOLD)],
[Paragraph("<b>A</b>ge < 5 years", TABLE_CELL)],
[Paragraph("<b>S</b>evere acidosis", TABLE_CELL)],
[Paragraph("<b>H</b>ydration excessive (rapid/excess IV fluids)", TABLE_CELL)],
[Paragraph("<b>I</b>nsulin bolus given", TABLE_CELL)],
[Paragraph("<b>C</b>O₂ < 10 mmol/L; alkali treatment", TABLE_CELL)],
[Paragraph("Rapid fall in serum Na⁺ or osmolality", TABLE_CELL)],
]
ce_right = [
[Paragraph("EARLY SIGNS", TABLE_CELL_BOLD)],
[Paragraph("Headache, vomiting, drowsiness, irritability", TABLE_CELL)],
[Paragraph("<b>Hypertension + Bradycardia</b> (Cushing's triad)", TABLE_CELL)],
[Paragraph("", TABLE_CELL)],
[Paragraph("LATE/SEVERE SIGNS", TABLE_CELL_BOLD)],
[Paragraph("Unconsciousness", TABLE_CELL)],
[Paragraph("Focal neurological deficits", TABLE_CELL)],
[Paragraph("<b>Papilledema</b>, fixed dilated pupils", TABLE_CELL)],
[Paragraph("<b>6th nerve palsy</b> (early sign)", TABLE_CELL)],
[Paragraph("Brisk DTR (raised ICP)", TABLE_CELL)],
]
ce_cols_left = Table(ce_left, colWidths=[doc.width/2 - 0.5*cm])
ce_cols_right = Table(ce_right, colWidths=[doc.width/2 - 0.5*cm])
ce_cols_left.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
ce_cols_right.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
ce_two_col = Table([[ce_cols_left, ce_cols_right]], colWidths=[doc.width/2, doc.width/2])
ce_two_col.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("BOX", (0,0), (-1,-1), 1, C_RED),
("INNERGRID", (0,0), (-1,-1), 0.5, colors.HexColor("#FFCCCC")),
("BACKGROUND", (0,0), (-1,-1), C_LTRED),
("LEFTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
story.append(ce_two_col)
story.append(sp(5))
story.append(info_box(
"<b>TREATMENT OF CEREBRAL EDEMA:</b><br/>"
"1. IV <b>Mannitol 5 mL/kg</b> stat (osmotic agent)<br/>"
"2. <b>Fluid restriction</b><br/>"
"3. <b>Head elevation</b><br/>"
"4. Diagnosis is CLINICAL — do not wait for imaging<br/>"
"5. Hypertonic saline (3%) 2.5-5 mL/kg may be used as alternative to mannitol",
bg=C_LTRED, border=C_RED
))
story.append(sp(8))
# Other complications
story.append(p("<b>OTHER COMPLICATIONS</b>", H2))
other_comp = [
("Hypokalemia", "Life-threatening; occurs after insulin starts; prevent with K⁺ protocol"),
("Hypoglycemia", "Add dextrose when glucose < 270 mg/dL"),
("Hypernatremia", "From excessive NS; monitor corrected Na⁺"),
("Infection (bacterial/fungal)", "Persistent fever + leukocytosis. Watch for:<br/>- <b>Black nasal discharge</b> = Rhinocerebral mucormycosis<br/>- <b>Hemoptysis</b> = Pulmonary aspergillosis"),
("Cerebral thrombosis", "Rare; due to dehydration and hyperviscosity"),
("Aspiration pneumonia", "From vomiting; hence NG tube if unconscious"),
("Acute renal failure", "From severe dehydration; high BUN indicates severity"),
]
story.append(key_val_table(other_comp, col1=4.5*cm))
story.append(sp(10))
# ═══════════════════════════════════════════════════════
# SECTION 5: MONITORING
# ═══════════════════════════════════════════════════════
story.append(section_header("5. MONITORING", bg=C_TEAL))
story.append(sp(6))
story.append(p("<b>Clinical Monitoring (Hourly):</b>", BODY_BOLD))
clin_items = [
"Neurological status (GCS, pupils, cranial nerves)",
"Heart rate, blood pressure",
"Fluid input/output",
"Signs of cerebral edema: headache, vomiting, drowsiness, bradycardia",
]
for item in clin_items:
story.append(Paragraph(f"<bullet>\u2022</bullet> {item}", BODY))
story.append(sp(5))
story.append(p("<b>Laboratory Monitoring:</b>", BODY_BOLD))
lab_freq = [
[Paragraph("PARAMETER", TABLE_HEADER),
Paragraph("FREQUENCY", TABLE_HEADER)],
[Paragraph("Blood glucose", TABLE_CELL),
Paragraph("Every 1 hour", TABLE_CELL)],
[Paragraph("Blood ketones", TABLE_CELL),
Paragraph("Every 4 hours", TABLE_CELL)],
[Paragraph("pH, bicarbonate, electrolytes", TABLE_CELL),
Paragraph("Every 4 hours", TABLE_CELL)],
[Paragraph("Serum sodium (corrected)", TABLE_CELL),
Paragraph("Every 4 hours", TABLE_CELL)],
]
lab_table = Table(lab_freq, colWidths=[doc.width*0.55, doc.width*0.45])
lab_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_TEAL),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_LTBLUE]),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(lab_table)
story.append(sp(8))
# Response to treatment table (high yield)
story.append(p("<b>RESPONSE TO TREATMENT TABLE (Table 18.36 - High Yield for Exams)</b>", BODY_BOLD))
story.append(sp(4))
rtt_data = [
[Paragraph("PARAMETER", TABLE_HEADER),
Paragraph("EXPECTED RESPONSE", TABLE_HEADER),
Paragraph("CONCERN", TABLE_HEADER),
Paragraph("ACTION", TABLE_HEADER)],
[Paragraph("Blood glucose", TABLE_CELL_BOLD),
Paragraph("Decrease 50-100 mg/dL/hr", TABLE_CELL),
Paragraph("Fall > 100 mg/dL/hr\nFall < 50 mg/dL/hr", TABLE_CELL),
Paragraph("Add dextrose to IV fluid\nPrepare fresh insulin; flush tubing", TABLE_CELL)],
[Paragraph("Blood pH", TABLE_CELL_BOLD),
Paragraph("Resolution by 12 hours", TABLE_CELL),
Paragraph("Persistent at 12 hours", TABLE_CELL),
Paragraph("Exclude infection, shock, lactic acidosis", TABLE_CELL)],
[Paragraph("Serum Na⁺", TABLE_CELL_BOLD),
Paragraph("Should increase", TABLE_CELL),
Paragraph("Rise < 2 mmol/L/hr", TABLE_CELL),
Paragraph("Increase Na concentration in IV fluid", TABLE_CELL)],
[Paragraph("Serum K⁺", TABLE_CELL_BOLD),
Paragraph("Gradual decrease", TABLE_CELL),
Paragraph("Hypokalemia", TABLE_CELL),
Paragraph("Increase K⁺ in IV fluid", TABLE_CELL)],
[Paragraph("Anion gap", TABLE_CELL_BOLD),
Paragraph("Resolution by 12 hours", TABLE_CELL),
Paragraph("Elevated at 12 hours", TABLE_CELL),
Paragraph("Exclude lactic acidosis, consider infection", TABLE_CELL)],
[Paragraph("Plasma osmolality", TABLE_CELL_BOLD),
Paragraph("Stable", TABLE_CELL),
Paragraph("Decrease > 2 mOsm/kg/hr", TABLE_CELL),
Paragraph("Increase Na concentration; decrease fluid rate", TABLE_CELL)],
[Paragraph("Blood urea", TABLE_CELL_BOLD),
Paragraph("Should decrease", TABLE_CELL),
Paragraph("Persistently elevated", TABLE_CELL),
Paragraph("Exclude renal failure", TABLE_CELL)],
]
rtt_col = [3.2*cm, 4*cm, 4*cm, doc.width-11.2*cm]
rtt_table = Table(rtt_data, colWidths=rtt_col)
rtt_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_TEAL),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
*[("BACKGROUND", (0,i), (-1,i), C_WHITE if i%2==1 else C_LTBLUE) for i in range(1,9)],
]))
story.append(rtt_table)
story.append(sp(10))
# ── FOOTER
footer_data = [[
Paragraph(
"DKA Notes | Marrow + Essential Pediatrics | ISPAD Guidelines | Final Year Theory Exam",
sty("FT", fontSize=8, fontName="Helvetica", textColor=C_WHITE, alignment=TA_CENTER)
)
]]
footer = Table(footer_data, colWidths=[doc.width])
footer.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_NAVY),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
story.append(footer)
# BUILD
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /tmp/workspace/dka-notes && python make_dka_pdf.py 2>&1
DKA Notes
PDF Document · PDF
| Section | Colour | Content |
|---|---|---|
| 1. Differential Diagnosis | Navy | When to suspect DKA table with DDx + clues |
| 2. Investigations | Teal | All 12 investigations with findings + significance |
| 3. Management | Orange | 3 pillars, initial stabilization, fluid therapy, insulin, K⁺ protocol, bicarbonate exceptions, dextrose rule, transition criteria |
| 4. Complications | Red | Full cerebral edema box (risk factors - ASHIC mnemonic, signs, treatment), other complications |
| 5. Monitoring | Teal | Clinical + lab monitoring frequency + full Response to Treatment table (Table 18.36) |
Tell me points that I must add in my marrow notes
Acidosis → K⁺ + PO₄³⁻ shift ICF → ECF → Serum K⁺ initially HIGH → becomes LOW after insulin starts
Your notes say HCO₃ < 18 mmol/L → textbook says < 15 mEq/L (Write both: < 18 ISPAD / < 15 textbook)
| Presentation | DDx |
|---|---|
| Encephalopathy | CNS infection, malaria, poisoning |
| Acute abdomen | Pancreatitis, appendicitis |
| Dehydration | Gastroenteritis |
| Tachypnea | Asthma, pneumonia |
| Acidosis + NO ketones | Renal failure, septicemia |
| Ketosis + NO hyperglycemia | Starvation, salicylate poisoning |
| Investigation | Key Point |
|---|---|
| Serum K⁺ | Normal/HIGH despite deficit (3-6 mEq/kg). Falls dangerously after insulin |
| Serum Na⁺ | Falsely low. Use corrected Na⁺. Rapid fall = cerebral edema risk |
| Serum phosphate | Treat if < 1 mg/dL |
| WBC | Transient leukocytosis = normal. Persistent = infection |
| Blood urea | High BUN = severe DKA |
| ECG | Screen for hypo/hyperkalemia |
Age < 2 years OR Severe DKA → ICU
K⁺ < 3.5 → Give K⁺ BEFORE insulin
K⁺ 3.5-6.0 → 40 mEq/L KCl with insulin (already in notes ✓)
K⁺ > 6.0 → DO NOT give K⁺
Anuric / ECG hyperkalemia → DO NOT give K⁺
Give ONLY IF: pH < 6.9 + hemodynamic compromise OR K⁺ > 6.5 mEq/L with ECG changes
Once conscious + oral feeds tolerated + acidosis resolved:
- SC insulin 0.25 u/kg 30 min before first meal
- Stop IV insulin 30 min after SC dose
Hypothyroidism in children clinical feature investigation management Congenital hypothyroidism Criticism What points to add in my notes from textbook
Prevalence = 1 in 2,000 newborns (India: much higher)
Secondary/Tertiary (<5% of cases):
- Septo-optic dysplasia, holoprosencephaly
- CNS insults: trauma, surgery, radiation, infection
- CNS tumors: Craniopharyngioma, germinoma
Hypoglycemia + micropenis + midline facial defects = hypothalamic-pituitary etiology
Pendred syndrome = pendrin gene defect → iodine transport defect + deafness
Always ask: maternal thyroid disease history? Maternal antithyroid drug use? Family history?
| Congenital ONLY | Acquired ONLY | Both |
|---|---|---|
| Open posterior fontanel | Myopathy + pseudohypertrophy of limb muscles | Growth retardation |
| Umbilical hernia | Enlarged sella | Sallow edematous facies |
| Delayed neurodevelopment | Pseudotumor cerebri | Delayed skeletal maturation |
| Large tongue | — | Rough dry skin, hypothermia |
| — | — | Delayed puberty, constipation, hypotonia |
| Pattern | Interpretation |
|---|---|
| Low FT4 + High TSH | Primary hypothyroidism |
| Low FT4 + Low/Normal TSH | Central hypothyroidism |
| Normal FT4 + High TSH | Subclinical hypothyroidism |
| High FT3/FT4 + Undetectable TSH | Hyperthyroid state |
TSH = most sensitive indicator of primary hypothyroidism Free T4 > Total T4 (TBG variability makes total unreliable)
Early diagnosis + treatment = normal intellectual outcome Diagnosed beyond early infancy = neurocognitive disability + short stature (irreversible)
| Neurological type | Myxedematous type | |
|---|---|---|
| Severity | Most severe | Less severe |
| Intellect | Very low IQ | Less severe intellectual impairment |
| Stature | Normal | Severe short stature |
| Goiter | Present | Absent |
| Features | Deaf-mutism, squint, proximal spasticity, rigidity | Coarse facial features, myxedema |
AIT may be associated with other autoimmune conditions:
- Adrenal insufficiency, Type 1 DM, hypoparathyroidism (Schmidt syndrome/polyglandular)
These children should be periodically screened even without symptoms:
- Down syndrome
- Turner syndrome
- Celiac disease
- Type 1 diabetes
Mild TSH elevation (< 10 mU/L) with normal FT4 Usually reverses in 3-6 months Treat if: thyromegaly + anti-TPO antibodies present + family history
| Priority | Add |
|---|---|
| ⭐⭐⭐ | TFT interpretation table (primary vs central vs subclinical) |
| ⭐⭐⭐ | TSH screening cut-offs (40/20/10 mU/L) + 48-hour rule |
| ⭐⭐⭐ | Endemic cretinism — 2 types table |
| ⭐⭐⭐ | Acquired hypothyroidism screening indications (Down, Turner, T1DM) |
| ⭐⭐ | Congenital vs Acquired clinical features table |
| ⭐⭐ | Thyroxine dosing details + timing (empty stomach, iron/Ca separation) |
| ⭐⭐ | Transient CH protocol (stop at 3 years, retest) |
| ⭐⭐ | Subclinical hypothyroidism |
| ⭐ | Pendred syndrome |
| ⭐ | Cortisol precedes thyroxine in adrenal insufficiency |
Make notes on congestive cardiac failure Exam orientated points for university theory examination final year mbbs More focus on signs symptoms management Pdf
~/dka-notes/make_ccf_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
OUTPUT = "/tmp/workspace/dka-notes/CCF_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm,
)
W = doc.width
# ── Palette ──────────────────────────────────
C_NAVY = colors.HexColor("#1A3A5C")
C_TEAL = colors.HexColor("#0B6E6E")
C_ORANGE = colors.HexColor("#C85000")
C_RED = colors.HexColor("#B82020")
C_PURPLE = colors.HexColor("#5B2D8E")
C_GREEN = colors.HexColor("#1A6E3C")
C_LTBLUE = colors.HexColor("#E8F4FD")
C_LTGREEN = colors.HexColor("#E8F8F0")
C_LTRED = colors.HexColor("#FDF0F0")
C_LTORANGE= colors.HexColor("#FFF5E6")
C_LTPURPLE= colors.HexColor("#F3EEF8")
C_GREY = colors.HexColor("#F4F4F4")
C_WHITE = colors.white
C_BLACK = colors.HexColor("#1A1A1A")
C_YELLOW = colors.HexColor("#FFFBE6")
# ── Styles ────────────────────────────────────
def sty(name, **kw): return ParagraphStyle(name, **kw)
TITLE = sty("T", fontSize=22, fontName="Helvetica-Bold", textColor=C_WHITE, alignment=TA_CENTER, spaceAfter=2)
SUB = sty("S", fontSize=10, fontName="Helvetica", textColor=C_WHITE, alignment=TA_CENTER)
H1 = sty("H1", fontSize=12, fontName="Helvetica-Bold", textColor=C_WHITE, spaceBefore=4, spaceAfter=2, leftIndent=4)
H2 = sty("H2", fontSize=10.5, fontName="Helvetica-Bold", textColor=C_NAVY, spaceBefore=7, spaceAfter=3)
BODY = sty("B", fontSize=9, fontName="Helvetica", textColor=C_BLACK, spaceBefore=2, spaceAfter=2, leading=13)
BBOLD = sty("BB", fontSize=9, fontName="Helvetica-Bold", textColor=C_NAVY, spaceBefore=2, spaceAfter=2, leading=13)
SMALL = sty("SM", fontSize=8.5, fontName="Helvetica", textColor=C_BLACK, leading=12)
TH = sty("TH", fontSize=8.5, fontName="Helvetica-Bold", textColor=C_WHITE, alignment=TA_CENTER, leading=11)
TC = sty("TC", fontSize=8.5, fontName="Helvetica", textColor=C_BLACK, leading=12)
TCB = sty("TCB", fontSize=8.5, fontName="Helvetica-Bold", textColor=C_NAVY, leading=12)
TCC = sty("TCC", fontSize=8.5, fontName="Helvetica", textColor=C_BLACK, alignment=TA_CENTER, leading=12)
WARN = sty("W", fontSize=8.5, fontName="Helvetica-Bold", textColor=C_RED, leading=12)
NOTE = sty("N", fontSize=8.5, fontName="Helvetica-Oblique", textColor=C_TEAL, leading=12)
def sp(h=6): return Spacer(1, h)
def hr(): return HRFlowable(width="100%", thickness=0.8, color=C_TEAL, spaceAfter=3, spaceBefore=3)
def sec(text, bg=C_NAVY):
t = Table([[Paragraph(text, H1)]], colWidths=[W])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),bg),
("ROWPADDING",(0,0),(-1,-1),7),
]))
return t
def box(text, bg=C_LTBLUE, border=C_TEAL, style=BODY):
t = Table([[Paragraph(text, style)]], colWidths=[W])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),bg),
("BOX",(0,0),(-1,-1),1.5,border),
("LEFTPADDING",(0,0),(-1,-1),8),
("RIGHTPADDING",(0,0),(-1,-1),8),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
]))
return t
def warnbox(text): return box(text, C_LTRED, C_RED, WARN)
def tipbox(text): return box(text, C_LTORANGE, C_ORANGE, BODY)
def b(text): return Paragraph(f"<bullet>\u2022</bullet> {text}", BODY)
def bb(text): return Paragraph(f"<bullet>\u2022</bullet> {text}", BBOLD)
def twocol(left_items, right_items, ratio=0.5):
lw = W * ratio - 3*mm
rw = W * (1-ratio) - 3*mm
lt = Table([[i] for i in left_items], colWidths=[lw])
rt = Table([[i] for i in right_items], colWidths=[rw])
lt.setStyle(TableStyle([("LEFTPADDING",(0,0),(-1,-1),0),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0)]))
rt.setStyle(TableStyle([("LEFTPADDING",(0,0),(-1,-1),0),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0)]))
t = Table([[lt, rt]], colWidths=[W*ratio, W*(1-ratio)])
t.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0)]))
return t
def gtable(headers, rows, cws, hbg=C_NAVY):
data = [[Paragraph(h, TH) for h in headers]]
for row in rows:
data.append([Paragraph(str(c), TC) for c in row])
t = Table(data, colWidths=cws)
cmds = [
("BACKGROUND",(0,0),(-1,0),hbg),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),5),
("RIGHTPADDING",(0,0),(-1,-1),5),
]
for i in range(len(rows)):
cmds.append(("BACKGROUND",(0,i+1),(-1,i+1),C_WHITE if i%2==0 else C_GREY))
t.setStyle(TableStyle(cmds))
return t
# ═══════════════════════════════════════════
story = []
# ── TITLE ─────────────────────────────────
tb = Table([[
Paragraph("CONGESTIVE CARDIAC FAILURE", TITLE),
Paragraph("CCF", sty("TL", fontSize=26, fontName="Helvetica-Bold",
textColor=colors.HexColor("#FFFFFF55"), alignment=TA_CENTER))
]], colWidths=[W-2.5*cm, 2.5*cm])
tb.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),C_NAVY),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("TOPPADDING",(0,0),(-1,-1),12),
("BOTTOMPADDING",(0,0),(-1,-1),12),
("LEFTPADDING",(0,0),(-1,-1),10),
]))
story.append(tb)
sub = Table([[Paragraph("Pediatric Cardiology | Essential Pediatrics | Final Year MBBS Theory Exam", SUB)]], colWidths=[W])
sub.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),C_TEAL),("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5)]))
story.append(sub)
story.append(sp(10))
# ═══════════════════════════════════════════
# 1. DEFINITION
# ═══════════════════════════════════════════
story.append(sec("1. DEFINITION"))
story.append(sp(5))
story.append(box(
"<b>CCF = Inability of the heart to maintain an output</b> (at rest or during stress) "
"necessary for the metabolic needs of the body.<br/><br/>"
"<b>Systolic failure:</b> Unable to propel blood into the aorta (low cardiac output).<br/>"
"<b>Diastolic failure:</b> Cannot receive blood at low pressure during diastole "
"(increased filling pressures with preserved systolic function).<br/><br/>"
"<b>Left-sided</b> pressure rise \u2192 Pulmonary congestion \u2192 Dyspnea<br/>"
"<b>Right-sided</b> pressure rise \u2192 Hepatomegaly + Edema",
C_LTBLUE, C_NAVY
))
story.append(sp(8))
# ═══════════════════════════════════════════
# 2. CAUSES / ETIOLOGY
# ═══════════════════════════════════════════
story.append(sec("2. ETIOLOGY / CAUSES (By Age Group)", bg=C_TEAL))
story.append(sp(6))
cause_data = [
[Paragraph("AGE", TH), Paragraph("CAUSES", TH)],
[Paragraph("Infants", TCB),
Paragraph("Congenital heart disease (m/c)\nMyocarditis, primary myocardial disease\nTachyarrhythmias (HR >180/min), bradyarrhythmias (complete heart block)\nKawasaki disease with coronary occlusion\nPulmonary hypertension (PPHN, primary PH, upper airway obstruction)\nAnemia (Hb < 5 g/dL), Hypoglycemia, Infections, Hypocalcemia\nNeonatal asphyxia", TC)],
[Paragraph("Children", TCB),
Paragraph("Rheumatic fever / Rheumatic heart disease (beyond 5 yrs)\nCHD complicated by anemia, infection or endocarditis\nSystemic hypertension\nMyocarditis, primary myocardial disease\nPulmonary hypertension (primary, secondary)", TC)],
]
ctbl = Table(cause_data, colWidths=[3*cm, W-3*cm])
ctbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),C_TEAL),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),6),
("BACKGROUND",(0,1),(-1,1),C_LTBLUE),
("BACKGROUND",(0,2),(-1,2),C_WHITE),
]))
story.append(ctbl)
story.append(sp(5))
# Diastolic failure causes
story.append(Paragraph("<b>Causes of Diastolic Heart Failure (Table 16.1):</b>", BBOLD))
diastolic_left = [
b("Mitral/tricuspid valve stenosis (MS, TS)"),
b("Constrictive pericarditis (CP)"),
b("Restrictive cardiomyopathy (RCM)"),
b("Acute ventricular volume overload (acute MR/AR)"),
]
diastolic_right = [
b("Myocardial ischemia (MI)"),
b("Marked ventricular hypertrophy (HCM, severe HTN, severe AS/PS)"),
b("Dilated cardiomyopathy* (DCM)"),
Paragraph("<i>*DCM has combined systolic + diastolic dysfunction</i>", NOTE),
]
story.append(twocol(diastolic_left, diastolic_right))
story.append(sp(5))
story.append(tipbox(
"<b>Age clue for CHD type:</b> CHD from left-to-right shunts \u2192 CCF at 6-8 weeks of life. "
"Valve leaks (MR/TR) \u2192 CCF earlier. "
"CCF earlier than expected for a shunt lesion \u2192 suspect <b>coarctation of aorta</b>."
))
story.append(sp(10))
# ═══════════════════════════════════════════
# 3. CLINICAL FEATURES
# ═══════════════════════════════════════════
story.append(sec("3. CLINICAL FEATURES — SYMPTOMS & SIGNS", bg=C_ORANGE))
story.append(sp(6))
# Symptoms
story.append(Paragraph("<b>A. SYMPTOMS (Table 16.4)</b>", H2))
sym_data = [
[Paragraph("SYMPTOM", TH), Paragraph("DETAIL / MECHANISM", TH)],
[Paragraph("Poor weight gain", TCB),
Paragraph("Inadequate feeding + excessive calorie loss from increased work of breathing", TC)],
[Paragraph("Difficulty in feeding / Poor feeder", TCB),
Paragraph("Takes < 1-2 oz at a time; gets breathless; hungry again within minutes of a small feed", TC)],
[Paragraph("Breathes too fast while feeding", TCB),
Paragraph("More comfortable when held against shoulder = equivalent of ORTHOPNEA in older children", TC)],
[Paragraph("Persistent cough and wheezing", TCB),
Paragraph("Left-sided failure; often mistaken for asthma/bronchiolitis", TC)],
[Paragraph("Irritability, excessive perspiration, restlessness", TCB),
Paragraph("Sympathetic activation; high metabolic state", TC)],
[Paragraph("Pedal edema", TCB),
Paragraph("Occurs late in children (vs. early in adults). Facial puffiness more common in infants", TC)],
[Paragraph("Unusual short-term weight GAIN", TCB),
Paragraph("Water retention manifesting as facial puffiness or foot edema", TC)],
[Paragraph("Hoarse cry / persistent crying", TCB),
Paragraph("Left heart failure; pulmonary congestion", TC)],
]
stbl = Table(sym_data, colWidths=[4.5*cm, W-4.5*cm])
stbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),C_ORANGE),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
*[("BACKGROUND",(0,i),(-1,i),C_WHITE if i%2==1 else C_LTORANGE) for i in range(1,9)],
]))
story.append(stbl)
story.append(sp(8))
# Signs
story.append(Paragraph("<b>B. SIGNS (Table 16.5)</b>", H2))
sign_data = [
[Paragraph("LEFT-SIDED FAILURE", sty("LH",fontSize=8.5,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER)),
Paragraph("FAILURE OF EITHER SIDE", sty("EH",fontSize=8.5,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER)),
Paragraph("RIGHT-SIDED FAILURE", sty("RH",fontSize=8.5,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER))],
[Paragraph("Tachypnea", TC), Paragraph("Cardiac enlargement", TCB), Paragraph("Hepatomegaly", TC)],
[Paragraph("Tachycardia", TC), Paragraph("Gallop rhythm (S3)", TCB), Paragraph("Facial edema / puffiness", TC)],
[Paragraph("Cough", TC), Paragraph("Peripheral cyanosis", TC), Paragraph("Jugular venous engorgement*", TC)],
[Paragraph("Wheezing", TC), Paragraph("Small volume pulse", TC), Paragraph("Pedal edema (late)", TC)],
[Paragraph("Rales in chest\n(often NOT audible)", TC), Paragraph("Lack of weight gain", TC), Paragraph("", TC)],
]
sgn_col = [W/3, W/3, W/3]
sgntbl = Table(sign_data, colWidths=sgn_col)
sgntbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,0),C_TEAL),
("BACKGROUND",(1,0),(1,0),C_NAVY),
("BACKGROUND",(2,0),(2,0),C_ORANGE),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),6),
*[("BACKGROUND",(0,i),(-1,i),C_WHITE if i%2==1 else C_GREY) for i in range(1,7)],
]))
story.append(sgntbl)
story.append(sp(4))
story.append(Paragraph(
"<i>*JVE not helpful in small infants (short fat neck; right atrial pressures stay normal in many infants with CCF)</i>",
NOTE))
story.append(sp(5))
story.append(box(
"<b>Common to BOTH left and right failure:</b> "
"Cardiac enlargement + Gallop rhythm (S3) + Poor peripheral pulses ± Cyanosis",
C_LTBLUE, C_NAVY
))
story.append(sp(10))
# ═══════════════════════════════════════════
# 4. INVESTIGATIONS
# ═══════════════════════════════════════════
story.append(sec("4. INVESTIGATIONS", bg=C_TEAL))
story.append(sp(6))
inv_left = [
Paragraph("<b>Chest X-ray:</b>", BBOLD),
b("Cardiomegaly (CTR > 0.55 in children, > 0.60 in infants)"),
b("Increased pulmonary vascular markings"),
b("Pulmonary edema / congestion"),
b("Pleural effusion (right > left)"),
sp(3),
Paragraph("<b>ECG:</b>", BBOLD),
b("Tachycardia, arrhythmias"),
b("Ventricular hypertrophy (LVH/RVH)"),
b("ST-T changes (myocarditis, ischemia)"),
b("Heart block / SVT - if arrhythmia is cause"),
sp(3),
Paragraph("<b>Blood investigations:</b>", BBOLD),
b("CBC: Anemia (Hb < 5 g/dL causes CCF in normal hearts)"),
b("Blood glucose (hypoglycemia as cause)"),
b("Serum calcium (hypocalcemia as cause)"),
b("Serum electrolytes, RFT"),
b("BNP / NT-proBNP: elevated in heart failure"),
]
inv_right = [
Paragraph("<b>Echocardiography (ECHO):</b>", BBOLD),
b("Most important investigation"),
b("Confirms diagnosis, identifies structural defect"),
b("Assesses LV/RV function, EF (ejection fraction)"),
b("Identifies CHD: VSD, ASD, PDA, AVSD"),
b("Pericardial effusion"),
b("Valve abnormalities"),
sp(3),
Paragraph("<b>Arterial Blood Gas (ABG):</b>", BBOLD),
b("Metabolic acidosis in severe CCF"),
b("Respiratory alkalosis in mild left-sided failure"),
sp(3),
Paragraph("<b>Urine output:</b>", BBOLD),
b("Decreased (< 0.5 mL/kg/hr) = poor cardiac output"),
b("Normal urine output + warm extremities + normal lactate = adequate perfusion"),
]
story.append(twocol(inv_left, inv_right))
story.append(sp(10))
# ═══════════════════════════════════════════
# 5. MANAGEMENT
# ═══════════════════════════════════════════
story.append(sec("5. MANAGEMENT — 4 PRONGED APPROACH", bg=C_RED))
story.append(sp(6))
pillars = Table([[
Paragraph("1\nReduce Cardiac Work", sty("P1",fontSize=9,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER,leading=13)),
Paragraph("2\nAugment Myocardial Contractility", sty("P2",fontSize=9,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER,leading=13)),
Paragraph("3\nImprove Cardiac Performance\n(Reduce Preload)", sty("P3",fontSize=9,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER,leading=13)),
Paragraph("4\nCorrect Underlying Cause", sty("P4",fontSize=9,fontName="Helvetica-Bold",textColor=C_WHITE,alignment=TA_CENTER,leading=13)),
]], colWidths=[W/4]*4)
pillars.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,0),C_NAVY),
("BACKGROUND",(1,0),(1,0),C_TEAL),
("BACKGROUND",(2,0),(2,0),C_ORANGE),
("BACKGROUND",(3,0),(3,0),C_RED),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("INNERGRID",(0,0),(-1,-1),2,C_WHITE),
("ALIGN",(0,0),(-1,-1),"CENTER"),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(pillars)
story.append(sp(8))
story.append(warnbox(
"IDENTIFICATION AND CORRECTION OF THE UNDERLYING CAUSE IS THE MOST IMPORTANT STEP "
"— it has direct bearing on survival. "
"Management focus has entirely shifted towards correcting the cause as early as possible."
))
story.append(sp(8))
# ── PILLAR 1: Reduce cardiac work
story.append(Paragraph("<b>PILLAR 1 — REDUCING CARDIAC WORK</b>", H2))
rw_left = [
bb("Nursing in incubator (neonates)"),
b("Handled minimally"),
bb("Prop up at 30\u00b0 incline") + sp(0),
b("Pooling of edema in dependent areas \u2192 reduces lung fluid"),
bb("Temperature 36-37\u00b0C") + sp(0),
b("Minimizes circulatory and metabolic demands"),
bb("Humidified O\u2082 40-50%"),
b("Improves oxygenation from pulmonary congestion"),
]
rw_right = [
bb("Restrict patient activity"),
b("Treat fever, anemia, obesity, infection"),
bb("Mechanical ventilation if severe") + sp(0),
b("Eliminates work of breathing entirely"),
bb("Cautious sedation") + sp(0),
b("Only if restless/dyspneic - very select cases"),
Paragraph("<b>CAUTION:</b> O\u2082 in L\u2192R shunts can worsen CCF by increasing pulmonary blood flow at cost of systemic perfusion!", WARN),
]
# flatten lists
rw_l2 = []
rw_r2 = []
for x in rw_left:
if isinstance(x, list):
rw_l2.extend(x)
else:
rw_l2.append(x)
for x in rw_right:
if isinstance(x, list):
rw_r2.extend(x)
else:
rw_r2.append(x)
story.append(twocol(rw_l2, rw_r2))
story.append(sp(8))
# ── PILLAR 2: Augment contractility
story.append(Paragraph("<b>PILLAR 2 — AUGMENTING MYOCARDIAL CONTRACTILITY (Inotropes)</b>", H2))
story.append(Paragraph("<b>A. DIGOXIN (Oral Inotrope)</b>", BBOLD))
dig_pts = [
b("Mechanism: Inhibits Na/K ATPase \u2192 increases intracellular Ca\u00b2\u207a \u2192 increases contractility"),
b("Rapid onset; eliminated quickly. Available oral + parenteral"),
b("Oral: 0.25 mg tablets OR elixir (1 mL = 0.05 mg)"),
b("Parenteral dose = <b>70% of oral dose</b>"),
b("Beneficial in mild to severe CCF with or without sinus rhythm"),
b("Can be combined with ACE inhibitors (synergistic)"),
b("<b>Use of digoxin for heart failure has declined considerably in recent years</b>"),
]
for pt in dig_pts:
story.append(pt)
story.append(sp(4))
# Digoxin dose table
dig_data = [
[Paragraph("AGE GROUP", TH), Paragraph("DIGITALIZING DOSE (mg/kg)", TH), Paragraph("MAINTENANCE DOSE (mg/kg/day)", TH)],
[Paragraph("Premature / Neonates", TC), Paragraph("0.04", TCC), Paragraph("0.01", TCC)],
[Paragraph("1 month - 1 year", TC), Paragraph("0.08", TCC), Paragraph("0.02 - 0.025", TCC)],
[Paragraph("1 - 3 years", TC), Paragraph("0.06", TCC), Paragraph("0.015 - 0.02", TCC)],
[Paragraph("Above 3 years", TC), Paragraph("0.04", TCC), Paragraph("0.017", TCC)],
]
story.append(gtable(
["AGE GROUP","DIGITALIZING DOSE (mg/kg)","MAINTENANCE DOSE (mg/kg/day)"],
[["Premature / Neonates","0.04","0.01"],
["1 month - 1 year","0.08","0.02 - 0.025"],
["1 - 3 years","0.06","0.015 - 0.02"],
["Above 3 years","0.04","0.017"]],
[5.5*cm, 5.5*cm, W-11*cm], hbg=C_NAVY
))
story.append(sp(6))
# IV inotropes
story.append(Paragraph("<b>B. INTRAVENOUS INOTROPIC AGENTS</b>", BBOLD))
iv_data = [
[Paragraph("DRUG", TH), Paragraph("CLASS", TH), Paragraph("DOSE", TH), Paragraph("KEY POINTS", TH)],
[Paragraph("Dopamine", TCB), Paragraph("Catecholamine\ninotrope", TC),
Paragraph("< 5 \u03bcg/kg/min: \u2193 vasodilation\n> 5 \u03bcg/kg/min: vasoconstriction", TC),
Paragraph("Use when BP low. Low dose: improves renal blood flow + natriuresis", TC)],
[Paragraph("Dobutamine", TCB), Paragraph("Catecholamine\ninotrope", TC),
Paragraph("2.5 - 15 \u03bcg/kg/min", TC),
Paragraph("Increase gradually till desired response. Dilated CMP: 24-hr infusion once/twice weekly", TC)],
[Paragraph("Milrinone", TCB), Paragraph("Phosphodiesterase\ninhibitor (inodilator)", TC),
Paragraph("Loading: 50 \u03bcg/kg\nInfusion: 0.3-0.7 \u03bcg/kg/min\n(omit loading if hypotension concern)", TC),
Paragraph("Inotrope + vasodilator. Popular post-cardiac surgery", TC)],
[Paragraph("Levosimendan", TCB), Paragraph("Calcium sensitizer\n(inodilator)", TC),
Paragraph("Loading: 6-12 \u03bcg/kg over 10 min\nInfusion: 0.05-0.2 \u03bcg/kg/min", TC),
Paragraph("Unlike milrinone, does NOT increase risk of arrhythmias. Popular in acute care", TC)],
[Paragraph("Adrenaline\n(Epinephrine)", TCB), Paragraph("Catecholamine", TC),
Paragraph("IV infusion", TC),
Paragraph("Used when no improvement on other inotropes. Last resort before advanced support", TC)],
]
ivtbl = Table(iv_data, colWidths=[2.8*cm, 3.2*cm, 4.2*cm, W-10.2*cm])
ivtbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),C_NAVY),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
*[("BACKGROUND",(0,i),(-1,i),C_WHITE if i%2==1 else C_LTBLUE) for i in range(1,7)],
]))
story.append(ivtbl)
story.append(sp(8))
# ── PILLAR 3: Diuretics / Preload
story.append(Paragraph("<b>PILLAR 3 — IMPROVING CARDIAC PERFORMANCE BY REDUCING PRELOAD (Diuretics)</b>", H2))
story.append(box(
"<b>Diuretics are FIRST LINE of management in congestive failure.</b><br/>"
"Action: Reduce blood volume \u2192 \u2193 venous return \u2192 \u2193 preload \u2192 \u2193 work of heart.<br/>"
"Oral furosemide action starts within <b>20 minutes</b>.",
C_LTGREEN, C_GREEN
))
story.append(sp(4))
# Diuretic dose table
story.append(gtable(
["DRUG","DOSE","ROUTE","NOTES"],
[["Furosemide (Loop diuretic)","1-3 mg/kg/day oral\n1 mg/kg/dose IV","PO / IV",
"First line. Activates RAAS. Combine with K-sparing diuretic (NOT K supplements)"],
["Spironolactone (K-sparing)","1 mg/kg every 12 hr","PO",
"Prevents K+/Mg2+ loss. Reduces arrhythmia risk. Synergistic with furosemide"],
["Triamterene / Amiloride","K-sparing agents","PO",
"Alternative K-sparing agents"],],
[4.5*cm, 3.5*cm, 2*cm, W-10*cm], hbg=C_TEAL
))
story.append(sp(4))
story.append(tipbox(
"<b>Furosemide + ACE inhibitor = SYNERGISTIC combination:</b> "
"Furosemide activates RAAS (vasoconstriction + Na/water retention). "
"ACE inhibitors suppress RAAS. Together they cancel RAAS activation."
))
story.append(sp(5))
story.append(b("<b>Sodium restriction:</b> Recommended but difficult in infants. Use only if CCF uncontrolled by digoxin + diuretics + ACE inhibitors. Advise avoiding chips, pickles."))
story.append(b("<b>Adequate calorie intake:</b> CCF increases calorie requirements - adequate nutrition is essential."))
story.append(sp(8))
# ── Vasodilators
story.append(Paragraph("<b>VASODILATORS</b>", H2))
story.append(Paragraph(
"Vasodilators counteract excessive compensatory vasoconstriction in CCF, reducing afterload (arteriolar) and preload (venous), improving cardiac output.",
BODY))
story.append(sp(4))
vd_data = [
[Paragraph("DRUG", TH), Paragraph("TYPE", TH), Paragraph("DOSE / ROUTE", TH), Paragraph("KEY POINTS", TH)],
[Paragraph("ACE Inhibitors\n(Captopril, Enalapril)", TCB),
Paragraph("Arteriolar + venous dilator\nMost useful oral vasodilator", TC),
Paragraph("Start at 1/4 of calculated dose\nMonitor creatinine + electrolytes\nevery 1-2 weeks for 4-6 weeks", TC),
Paragraph("Suppress RAAS. Prevent arrhythmias. Avoid in: dehydration, neonates (AKI risk). SE: Cough \u2192 switch to ARB (Losartan)", TC)],
[Paragraph("ARBs\n(Losartan)", TCB),
Paragraph("Arteriolar + venous dilator", TC),
Paragraph("When ACE inhibitor cough is persistent", TC),
Paragraph("Alternative to ACE inhibitors. Same mechanism without bradykinin-related cough", TC)],
[Paragraph("Nitrates", TCB),
Paragraph("Preferential VENODILATOR", TC),
Paragraph("IV / sublingual", TC),
Paragraph("Reduce preload. Useful in acute pulmonary edema", TC)],
[Paragraph("Sodium Nitroprusside", TCB),
Paragraph("Arterial + venous dilator", TC),
Paragraph("IV infusion (acute setting)", TC),
Paragraph("Acts on both venous and arterial systems. Acute MR, AR, postoperative", TC)],
[Paragraph("Beta Blockers\n(Carvedilol, Metoprolol)", TCB),
Paragraph("Beta-blocker with vasodilation (carvedilol)", TC),
Paragraph("Carvedilol: 0.08-0.4 mg/kg/day\n(max 1 mg/kg/day)\nStart low, increase slowly", TC),
Paragraph("For dilated CMP with tachycardia. Carvedilol preferred (has vasodilatory properties). AVOID CCB in CCF.", TC)],
]
vdtbl = Table(vd_data, colWidths=[3.2*cm, 3.2*cm, 4*cm, W-10.4*cm])
vdtbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),C_PURPLE),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
*[("BACKGROUND",(0,i),(-1,i),C_WHITE if i%2==1 else C_LTPURPLE) for i in range(1,7)],
]))
story.append(vdtbl)
story.append(sp(4))
story.append(warnbox(
"CALCIUM CHANNEL BLOCKERS are CONTRAINDICATED in heart failure "
"(unless specifically indicated for systemic hypertension)."
))
story.append(sp(8))
# ── PILLAR 4: Correct underlying cause
story.append(Paragraph("<b>PILLAR 4 — CORRECTING THE UNDERLYING CAUSE</b>", H2))
story.append(b("Most important step; has direct bearing on survival"))
story.append(b("CHD: curative or palliative surgery"))
story.append(b("<b>Do not miss:</b> Sustained tachyarrhythmias, coarctation of aorta, anomalous left coronary artery from pulmonary artery (ALCAPA), hypocalcemia"))
story.append(b("Idiopathic DCM = diagnosis of exclusion; rule out all treatable causes first"))
story.append(b("Rheumatic heart disease + CCF: does NOT necessarily mean active carditis. If active carditis excluded and medical management adequate \u2192 consider surgery"))
story.append(b("Uncommon causes to exclude: Upper airway obstruction, hypoglycemia, neonatal asphyxia, hypocalcemia"))
story.append(sp(10))
# ═══════════════════════════════════════════
# 6. MANAGEMENT ALGORITHM
# ═══════════════════════════════════════════
story.append(sec("6. MANAGEMENT ALGORITHM (Fig. 16.4)", bg=C_NAVY))
story.append(sp(6))
algo_data = [
[Paragraph("RISK CATEGORY", TH), Paragraph("CRITERIA", TH), Paragraph("MANAGEMENT", TH)],
[Paragraph("LOW RISK", sty("LR",fontSize=9,fontName="Helvetica-Bold",textColor=C_GREEN,leading=12)),
Paragraph("NO hypotension, tachycardia, or respiratory distress\nLV dysfunction present", TC),
Paragraph("ACE inhibitor\n+/- Beta blockers\nDigoxin in some circumstances\nWean over 2-3 days if improvement", TC)],
[Paragraph("INTERMEDIATE RISK", sty("IR",fontSize=9,fontName="Helvetica-Bold",textColor=C_ORANGE,leading=12)),
Paragraph("SOME features of hypotension / tachycardia / respiratory distress", TC),
Paragraph("Admit to ward\nLoop diuretics\nReassess improvement over 2-3 days\nIf no improvement \u2192 escalate to High Risk", TC)],
[Paragraph("HIGH RISK", sty("HR",fontSize=9,fontName="Helvetica-Bold",textColor=C_RED,leading=12)),
Paragraph("YES to hypotension + tachycardia + respiratory distress\nPoor tissue perfusion\n(low urine output, cold extremities, elevated lactate)", TC),
Paragraph("Admit ICU\nIV furosemide\nInotrope / vasodilator\nConsider positive pressure ventilation\nIf no improvement: Ventilate + epinephrine\nNo improvement \u2192 Advanced circulatory support", TC)],
]
algtbl = Table(algo_data, colWidths=[3.2*cm, 5.5*cm, W-8.7*cm])
algtbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),C_NAVY),
("VALIGN",(0,0),(-1,-1),"TOP"),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#AAAAAA")),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
("BACKGROUND",(0,1),(-1,1),C_LTGREEN),
("BACKGROUND",(0,2),(-1,2),C_LTORANGE),
("BACKGROUND",(0,3),(-1,3),C_LTRED),
]))
story.append(algtbl)
story.append(sp(5))
story.append(box(
"<b>Tissue perfusion adequacy check:</b> Urine output + warm extremities + normal lactate = adequate perfusion.",
C_LTBLUE, C_NAVY
))
story.append(sp(10))
# ═══════════════════════════════════════════
# 7. HIGH YIELD EXAM POINTS
# ═══════════════════════════════════════════
story.append(sec("7. HIGH YIELD EXAM POINTS (Must Know)", bg=C_RED))
story.append(sp(6))
hy_left = [
Paragraph("<b>Pathophysiology MCQs:</b>", BBOLD),
b("CCF in left-to-right shunt \u2192 at 6-8 weeks"),
b("HR > 180/min \u2192 precipitates CCF in infancy"),
b("Normal Hb 5 g/dL \u2192 CCF in normal heart"),
b("Hb 7-8 g/dL \u2192 CCF in diseased heart"),
b("Orthopnea equivalent in infant = breathes better held against shoulder"),
sp(4),
Paragraph("<b>Signs MCQs:</b>", BBOLD),
b("S3 gallop = most important cardiac sign of CCF"),
b("JVE not reliable in infants"),
b("Pedal edema = late sign in children"),
b("Facial puffiness = more common than pedal edema in infants"),
b("Basal rales usually NOT audible in infant CCF"),
]
hy_right = [
Paragraph("<b>Drug MCQs:</b>", BBOLD),
b("Diuretics = FIRST LINE treatment"),
b("ACE inhibitors = most useful ORAL vasodilators"),
b("Digoxin parenteral dose = 70% of oral dose"),
b("Furosemide oral action starts in 20 min"),
b("Levosimendan does NOT cause arrhythmias (unlike milrinone)"),
b("CCB CONTRAINDICATED in CCF"),
b("O\u2082 can WORSEN CCF in L\u2192R shunts"),
b("Nitrates = preferential VENOdilators"),
sp(4),
Paragraph("<b>Missed causes to always remember:</b>", BBOLD),
b("ALCAPA (anomalous left coronary from pulmonary artery)"),
b("Coarctation of aorta in infant with shunt"),
b("Sustained tachyarrhythmia mimicking DCM"),
b("Hypocalcemia, hypoglycemia"),
]
story.append(twocol(hy_left, hy_right))
story.append(sp(10))
# ── FOOTER ──────────────────────────────────
footer = Table([[Paragraph(
"CCF Notes | Essential Pediatrics (Chapter 16) | Final Year MBBS Theory Exam",
sty("FT",fontSize=8,fontName="Helvetica",textColor=C_WHITE,alignment=TA_CENTER)
)]], colWidths=[W])
footer.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),C_NAVY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
]))
story.append(footer)
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /tmp/workspace/dka-notes && python make_ccf_pdf.py 2>&1
~/dka-notes/make_ccf_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/dka-notes/make_ccf_pdf.py'
cd /tmp/workspace/dka-notes && python make_ccf_pdf.py 2>&1
CCF Notes
PDF Document · PDF
| Section | Colour | Content |
|---|---|---|
| 1. Definition | Navy | Systolic vs diastolic failure explained |
| 2. Etiology | Teal | Causes by age group (infants vs children) + diastolic failure causes table |
| 3. Clinical Features | Orange | Full symptoms table with mechanisms + Signs table (Left/Both/Right sided) |
| 4. Investigations | Teal | CXR, ECG, ECHO, ABG, blood tests |
| 5. Management | Red | All 4 pillars — Reduce cardiac work, Inotropes (digoxin dose table + IV agents dose table), Diuretics, Vasodilators (ACE/ARB/beta-blockers with doses) |
| 6. Management Algorithm | Navy | Risk stratification: Low/Intermediate/High risk with step-by-step management |
| 7. High Yield Exam Points | Red | All exam-favourite MCQ/SAQ points in one box |
Is it enough or I need to add points from textbook to my marrow notes