And these obs questions and in details laq manner use flow charts pic for easy understanding and heading point wise detailed point wise answer I have exam Tommorow us obs dc dutta eveied edition as source and other authentic books
| # | Question | Covered |
|---|---|---|
| Q1-2 | Classify & Types of Breech | ✅ Classification flowchart, 4 types |
| Q3 | Etiology of Breech | ✅ Fetal/uterine/maternal/liquor causes |
| Q4 | Mechanism of Breech Labour | ✅ Step-by-step flowchart, methods for after-coming head |
| Q5 | Etiology of Preterm Labour | ✅ Maternal/fetal/social causes |
| Q6 | Clinical Presentation of Preterm Labour | ✅ Symptoms, signs, investigations, management flowchart |
| Q7 | Classify Abortion | ✅ Types + comparison table |
| Q8 | Causes of APH | ✅ Placental vs extraplacental |
| Q9 | C/F of Abruptio Placenta | ✅ Symptoms, signs, complications |
| Q10 | Differentiate Abruptio vs Placenta Previa | ✅ Full comparison table |
| Q11 | Define Primary PPH | ✅ Definitions, types, blood loss criteria |
| Q12 | Management of Primary PPH | ✅ 4 T's flowchart, stepwise Rx |
| Q13 | Management of Pre-eclampsia | ✅ Full flowchart, MgSO4, delivery timing |
| 2nd BHMS Q1-3 | Hyperemesis etiology, Onset of labour, Mechanism | ✅ All covered with flowcharts |
Create a quick reference cheat sheet with key mnemonics and definitions
mkdir -p /tmp/workspace/obs-cheatsheet && ls /tmp/workspace/obs-cheatsheet/
~/obs-cheatsheet/make_cheatsheet.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.lib.colors import HexColor
OUTPUT = "/tmp/workspace/obs-cheatsheet/OBS_CheatSheet.pdf"
# ── Colour palette ──────────────────────────────────────────────
C_BG = HexColor("#1a1a2e") # dark navy (page header bg)
C_RED = HexColor("#e63946") # danger red
C_ORANGE = HexColor("#f4a261") # warning orange
C_TEAL = HexColor("#2a9d8f") # teal (section headers)
C_BLUE = HexColor("#457b9d") # mid blue
C_LBLUE = HexColor("#a8dadc") # light blue (table alt rows)
C_YELLOW = HexColor("#ffd166") # highlight yellow
C_GREEN = HexColor("#06d6a0") # mnemonic green
C_WHITE = colors.white
C_NEAR_WHITE = HexColor("#f1faee")
C_DARK = HexColor("#1d3557")
C_LIGHT_GRAY = HexColor("#f8f9fa")
C_MID_GRAY = HexColor("#dee2e6")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.2*cm, rightMargin=1.2*cm,
topMargin=1.2*cm, bottomMargin=1.2*cm
)
# ── Styles ───────────────────────────────────────────────────────
base = getSampleStyleSheet()
def sty(name, parent="Normal", **kw):
return ParagraphStyle(name, parent=base[parent], **kw)
S_PAGE_TITLE = sty("PageTitle",
fontSize=20, leading=24, textColor=C_WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=2)
S_PAGE_SUB = sty("PageSub",
fontSize=9, leading=11, textColor=C_LBLUE,
fontName="Helvetica", alignment=TA_CENTER, spaceAfter=4)
S_SEC = sty("SecHead",
fontSize=11, leading=14, textColor=C_WHITE,
fontName="Helvetica-Bold", alignment=TA_LEFT,
spaceBefore=6, spaceAfter=2)
S_MNEM_TITLE = sty("MnemTitle",
fontSize=10, leading=13, textColor=C_YELLOW,
fontName="Helvetica-Bold", spaceBefore=4, spaceAfter=1)
S_BODY = sty("Body",
fontSize=8.2, leading=11, textColor=C_DARK,
fontName="Helvetica", spaceBefore=1, spaceAfter=1)
S_BODY_B = sty("BodyB",
fontSize=8.2, leading=11, textColor=C_DARK,
fontName="Helvetica-Bold", spaceBefore=1, spaceAfter=1)
S_DEF = sty("Def",
fontSize=8, leading=11, textColor=HexColor("#212529"),
fontName="Helvetica", spaceBefore=1, spaceAfter=1,
leftIndent=8)
S_BULLET = sty("Bullet",
fontSize=8, leading=11, textColor=C_DARK,
fontName="Helvetica", leftIndent=10, firstLineIndent=-8,
spaceBefore=0, spaceAfter=0)
S_WARN = sty("Warn",
fontSize=8, leading=11, textColor=C_RED,
fontName="Helvetica-Bold", spaceBefore=1, spaceAfter=1)
S_GREEN = sty("GreenTxt",
fontSize=8.2, leading=11, textColor=HexColor("#006644"),
fontName="Helvetica-Bold", spaceBefore=1, spaceAfter=1)
# ── Helpers ──────────────────────────────────────────────────────
def section_header(text, bg=C_TEAL):
data = [[Paragraph(text, S_SEC)]]
t = Table(data, colWidths=[17.6*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("ROUNDEDCORNERS", [4,4,4,4]),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return t
def mini_header(text, bg=C_BLUE):
data = [[Paragraph(f"<b>{text}</b>", S_BODY_B)]]
t = Table(data, colWidths=[17.6*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 8),
("TEXTCOLOR", (0,0), (-1,-1), C_WHITE),
]))
return t
def mnemonic_box(acronym, meaning_pairs, bg=HexColor("#fff3cd"), title_extra=""):
"""acronym = 'ABCDE', meaning_pairs = list of ('A','word'), ..."""
header_txt = f"<b><font color='#7c4e00'>{acronym}</font></b>"
if title_extra:
header_txt += f" <font color='#495057' size='7'>— {title_extra}</font>"
rows = [[Paragraph(header_txt, sty("X", fontSize=10, leading=13, fontName="Helvetica-Bold"))]]
for letter, meaning in meaning_pairs:
cell = Paragraph(
f"<b><font color='{C_RED.hexval()}'>{letter}</font></b>"
f"<font color='#1d3557'> — {meaning}</font>",
S_DEF
)
rows.append([cell])
t = Table(rows, colWidths=[17.6*cm])
ts = [
("BACKGROUND", (0,0), (-1,-1), bg),
("BACKGROUND", (0,0), (-1,0), HexColor("#ffd166")),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 0.8, HexColor("#e9c46a")),
("LINEBELOW", (0,0), (-1,0), 0.5, HexColor("#e9c46a")),
]
t.setStyle(TableStyle(ts))
return t
def compare_table(headers, rows, col_widths=None):
all_rows = [headers] + rows
if col_widths is None:
w = 17.6*cm / len(headers)
col_widths = [w]*len(headers)
t = Table([[Paragraph(str(c), sty("th", fontSize=7.5, leading=10,
fontName="Helvetica-Bold", textColor=C_WHITE)) for c in r]
if i == 0 else
[Paragraph(str(c), sty("td", fontSize=7.5, leading=10,
fontName="Helvetica")) for c in r]
for i, r in enumerate(all_rows)],
colWidths=col_widths)
styles = [
("BACKGROUND", (0,0), (-1,0), C_DARK),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("GRID", (0,0), (-1,-1), 0.4, C_MID_GRAY),
]
for i in range(1, len(all_rows)):
if i % 2 == 0:
styles.append(("BACKGROUND", (0,i), (-1,i), C_LIGHT_GRAY))
t.setStyle(TableStyle(styles))
return t
def page_title_block(title, subtitle):
data = [[
Paragraph(title, S_PAGE_TITLE),
Paragraph(subtitle, S_PAGE_SUB),
]]
t = Table(data, colWidths=[10*cm, 7.6*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_BG),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 12),
("ROUNDEDCORNERS", [6,6,6,6]),
]))
return t
def two_col(left_items, right_items):
"""Two-column layout. Each item is a Flowable."""
left_str = "".join(p.text if hasattr(p,'text') else '' for p in left_items)
right_str = "".join(p.text if hasattr(p,'text') else '' for p in right_items)
# wrap in nested table
left_cell = [p for p in left_items]
right_cell = [p for p in right_items]
data = [[left_cell, right_cell]]
t = Table(data, colWidths=[8.7*cm, 8.7*cm],
style=[
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING",(0,0), (-1,-1), 0),
])
return t
def bullet(txt, color="•"):
return Paragraph(f"{color} {txt}", S_BULLET)
def sp(h=3):
return Spacer(1, h)
def hr(color=C_MID_GRAY):
return HRFlowable(width="100%", thickness=0.5, color=color, spaceAfter=3, spaceBefore=3)
# ════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════
story = []
# ── PAGE TITLE ──────────────────────────────────────────────────
story.append(page_title_block(
"🩺 OBSTETRICS QUICK REFERENCE",
"DC Dutta 7th Ed. · BHMS Exam Cheat Sheet\nAll key definitions, mnemonics & comparison tables"
))
story.append(sp(6))
# ════════════════════════════════════════════════════════
# SECTION 1: KEY DEFINITIONS
# ════════════════════════════════════════════════════════
story.append(section_header("📖 SECTION 1 — KEY DEFINITIONS (Learn Every Single One)"))
story.append(sp(4))
defs = [
("Breech Presentation",
"Longitudinal lie where fetal BUTTOCKS/FEET present at pelvic brim. Incidence: 3-4% at term."),
("Frank / Extended Breech",
"Both hips flexed, both knees EXTENDED (legs alongside trunk). MOST COMMON (65-70%)."),
("Complete / Flexed Breech",
"Both hips AND knees flexed. Feet alongside buttocks. Cross-legged sitting. (5-10%)."),
("Footling / Incomplete Breech",
"One/both hips NOT fully flexed. Single or double foot presents. HIGHEST cord prolapse risk."),
("Preterm Labour",
"Regular uterine contractions + cervical change BEFORE 37 completed weeks of gestation."),
("Abortion",
"Expulsion/extraction of products of conception weighing < 500 g (or < 22 weeks)."),
("Threatened Abortion",
"Bleeding per vaginum with CLOSED os. Live fetus on USG. May or may not progress."),
("Inevitable Abortion",
"Bleeding + pain + OPEN os. Products still inside. Cannot be saved."),
("Missed Abortion",
"Dead fetus retained in-utero. No cardiac activity on USG. Os CLOSED. May be asymptomatic."),
("Septic Abortion",
"Infected abortion. Features: fever, foul-smelling discharge, tender uterus, systemic sepsis."),
("Antepartum Haemorrhage (APH)",
"Bleeding from genital tract AFTER 28 weeks of pregnancy and BEFORE delivery of baby."),
("Abruptio Placenta",
"Premature separation of NORMALLY SITUATED placenta after 28 weeks. = Accidental haemorrhage."),
("Placenta Previa",
"Placenta implanted in LOWER UTERINE SEGMENT, partially or wholly covering the os."),
("Primary PPH",
"Blood loss ≥ 500 ml (vaginal) or ≥ 1000 ml (LSCS) within FIRST 24 HOURS of delivery."),
("Secondary PPH",
"Abnormal/excessive bleeding from 24 HOURS to 12 WEEKS postpartum. Usually infection/retained POC."),
("Pre-eclampsia",
"BP ≥ 140/90 mmHg + Proteinuria ≥ 300 mg/24h, after 20 WEEKS gestation in prev. normotensive."),
("Eclampsia",
"Convulsions superimposed on pre-eclampsia. NOT attributed to other causes."),
("HELLP Syndrome",
"Haemolysis + Elevated Liver enzymes + Low Platelets. Severe variant of pre-eclampsia."),
("Hyperemesis Gravidarum",
"Intractable vomiting in pregnancy causing > 5% weight loss + dehydration + ketonuria, needing admission."),
("Couvelaire Uterus",
"Extravasation of blood into uterine musculature in severe abruption → blue/purple uterus → atony → PPH."),
("Cervical Incompetence",
"Painless cervical dilatation + expulsion of fetus in 2nd trimester without contractions."),
("Engagement",
"Widest transverse diameter (biparietal ~9.5 cm) passes BELOW the pelvic brim / pelvic inlet."),
("Crowning",
"Largest diameter of fetal head (suboccipitobregmatic) passes through vulval ring without receding."),
]
def_rows = []
for term, defn in defs:
def_rows.append([
Paragraph(f"<b>{term}</b>", sty("dt", fontSize=8, leading=11, fontName="Helvetica-Bold", textColor=C_DARK)),
Paragraph(defn, sty("dd", fontSize=7.8, leading=10.5, fontName="Helvetica", textColor=HexColor("#343a40")))
])
def_table = Table(def_rows, colWidths=[5.2*cm, 12.2*cm])
def_table.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("GRID", (0,0), (-1,-1), 0.3, C_MID_GRAY),
*[("BACKGROUND", (0,i), (-1,i), C_LIGHT_GRAY if i%2==0 else C_WHITE) for i in range(len(def_rows))],
("BACKGROUND", (0,0), (0,-1), HexColor("#e8f4f8")),
]))
story.append(def_table)
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 2: MNEMONICS
# ════════════════════════════════════════════════════════
story.append(section_header("🧠 SECTION 2 — MNEMONICS (Memory Anchors)"))
story.append(sp(4))
# Row 1: 4T + EDIT
row1_left = [
mnemonic_box(
"4 T's of PPH",
[("T1","TONE — Uterine atony (80% of PPH) → Oxytocin 1st"),
("T2","TRAUMA — Genital tract lacerations → Suture"),
("T3","TISSUE — Retained placenta/clots → ERPC"),
("T4","THROMBIN — Coagulopathy/DIC → FFP, platelets")],
title_extra="Causes of Primary PPH"
),
sp(4),
mnemonic_box(
"EDIT — Abortion Types",
[("E","Expulsion complete → COMPLETE abortion"),
("D","Dead inside (missed) → MISSED abortion"),
("I","Incomplete expelled → INCOMPLETE abortion"),
("T","Threatened → Os CLOSED, alive fetus")],
title_extra="Remember abortion types"
),
]
row1_right = [
mnemonic_box(
"EVERY DECENT FETAL INFANT REQUIRES EXPERT ATTENTION",
[("E","Engagement"),
("D","Descent"),
("F","Flexion"),
("I","Internal Rotation"),
("R","Extension (Restitution begins here conceptually)"),
("E","Extension / Crowning"),
("A","restitution → External Rotation (Anterior shoulder first)")],
title_extra="7 Cardinal Movements of Labour",
bg=HexColor("#e8f5e9")
),
]
mnemo_table = Table([[row1_left, row1_right]], colWidths=[8.7*cm, 8.7*cm],
style=[("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),0),
("BOTTOMPADDING",(0,0),(-1,-1),0)])
story.append(mnemo_table)
story.append(sp(5))
# Row 2: ABRUPTIO + HELLP
row2_left = [
mnemonic_box(
"ABRUPTIO",
[("A","Abdominal pain — hallmark sign"),
("B","Board-like / rigid uterus"),
("R","Retro-placental clot (concealed blood)"),
("U","Uterus tense, tender, enlarged"),
("P","Painful — differentiates from placenta previa"),
("T","Toxaemia / pre-eclampsia often associated"),
("I","Internal / concealed bleeding common"),
("O","Often leads to DIC, renal failure, fetal death")],
title_extra="Clinical features",
bg=HexColor("#fff0f0")
),
]
row2_right = [
mnemonic_box(
"HELLP",
[("H","Haemolysis (microangiopathic)"),
("E","Elevated Liver enzymes (AST, ALT ↑)"),
("L","Low Platelets (< 100,000)"),
("L","Leads to severe maternal morbidity"),
("P","Pre-eclampsia — the underlying condition")],
title_extra="Severe pre-eclampsia variant",
bg=HexColor("#e8f0fe")
),
sp(4),
mnemonic_box(
"MgSO₄ TOXICITY — CAMP",
[("C","C reflexes lost (patellar reflex first to go) → STOP Mg"),
("A","Arrest of breathing (Respiratory depression)"),
("M","Monitor: Urine output > 25ml/hr"),
("P","Antidote: CALCIUM GLUCONATE 1g IV slow push")],
title_extra="Monitoring MgSO4 therapy",
bg=HexColor("#fce4ec")
),
]
mnemo_table2 = Table([[row2_left, row2_right]], colWidths=[8.7*cm, 8.7*cm],
style=[("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),0),
("BOTTOMPADDING",(0,0),(-1,-1),0)])
story.append(mnemo_table2)
story.append(sp(5))
# Row 3: Breech + Pre-E
row3_left = [
mnemonic_box(
"BREECH CAUSES — PUMP F",
[("P","Prematurity (most common; self-corrects usually)"),
("U","Uterine anomaly (bicornuate, septate, fibroid)"),
("M","Multiple pregnancy"),
("P","Placenta — fundal/cornual OR previa"),
("F","Fetal anomaly — hydrocephalus, anencephaly, NMD")],
title_extra="Etiology of breech"
),
]
row3_right = [
mnemonic_box(
"Pre-eclampsia Rx — MADE",
[("M","MgSO4 — anticonvulsant, NOT antihypertensive"),
("A","Antihypertensives — Nifedipine / Labetalol / Hydralazine"),
("D","Deliver — ONLY cure (timing depends on severity)"),
("E","Expectant — if < 34 wks and stable; give steroids")],
title_extra="Management pillars",
bg=HexColor("#e8f0fe")
),
]
mnemo_table3 = Table([[row3_left, row3_right]], colWidths=[8.7*cm, 8.7*cm],
style=[("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),0),
("BOTTOMPADDING",(0,0),(-1,-1),0)])
story.append(mnemo_table3)
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 3: COMPARISON TABLE — ABRUPTION vs PREVIA
# ════════════════════════════════════════════════════════
story.append(section_header("⚡ SECTION 3 — MUST-KNOW COMPARISON: Abruptio Placenta vs Placenta Previa"))
story.append(sp(4))
headers = ["Feature", "Abruptio Placenta", "Placenta Previa"]
comp_rows = [
["PAIN", "⚠️ PAINFUL (hallmark)", "✅ PAINLESS (hallmark)"],
["Bleeding colour", "Dark red / may be absent", "Bright red, fresh"],
["Onset", "Sudden; may follow trauma/hypertension", "Spontaneous, unprovoked"],
["Uterus", "Tense, board-like, TENDER", "Soft, NON-TENDER"],
["Uterus size", "Larger than expected (concealed blood)", "Normal"],
["Fetal parts", "Difficult to palpate (rigid uterus)", "Easily felt"],
["Fetal lie", "Usually normal", "Often malpresentation (transverse/oblique)"],
["Presenting part", "May be engaged", "HIGH / Not engaged"],
["FHS (fetal heart)", "Often absent / severely distressed", "Usually normal"],
["Shock", "Disproportionate to visible blood loss", "Proportionate to visible loss"],
["Placenta on USG", "Normal / upper uterine segment", "Lower segment (praevia)"],
["DIC", "COMMON (especially severe type)", "Rare"],
["Cause of bleed", "Retro-placental haematoma → separation", "Edge of low placenta bleeds"],
["PV examination", "Contraindicated", "ABSOLUTELY CONTRAINDICATED"],
["Recurrence", "Less likely", "More likely in subsequent pregnancy"],
]
story.append(compare_table(headers, comp_rows, col_widths=[4.5*cm, 6.5*cm, 6.6*cm]))
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 4: ABORTION TYPES TABLE
# ════════════════════════════════════════════════════════
story.append(section_header("📋 SECTION 4 — ABORTION TYPES AT A GLANCE"))
story.append(sp(4))
ab_headers = ["Type", "Bleeding", "Pain", "Os", "USG / POC", "Management"]
ab_rows = [
["Threatened", "Mild, spotting", "Mild / Nil", "CLOSED", "Live embryo", "Bed rest, progesterone"],
["Inevitable", "Moderate-heavy", "Severe", "OPEN", "Intact sac inside", "Admit; may need ERPC"],
["Incomplete", "Heavy", "Severe", "OPEN", "Partial expulsion", "ERPC / Manual vacuum aspiration"],
["Complete", "Stops", "Stops", "CLOSED", "Empty uterus", "Confirm on USG; no Rx needed"],
["Missed", "Nil / minimal", "Nil", "CLOSED", "No cardiac activity", "Misoprostol or surgical ERPC"],
["Septic", "Offensive", "Present", "Open/Cl","Retained ± foul smell", "Antibiotics + ERPC + ICU if needed"],
["Recurrent", "Varies", "Varies", "Varies", "3+ consecutive losses", "Investigate: anti-phospholipid, karyotype, cervix"],
]
story.append(compare_table(ab_headers, ab_rows,
col_widths=[2.6*cm, 2.5*cm, 2.0*cm, 1.8*cm, 3.8*cm, 4.7*cm]))
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 5: STAGES OF LABOUR + DRUGS QUICK REF
# ════════════════════════════════════════════════════════
story.append(section_header("🔬 SECTION 5 — STAGES OF LABOUR + KEY DRUG DOSES"))
story.append(sp(4))
# Stages
stg_headers = ["Stage", "Duration (Primi)", "Duration (Multi)", "Definition / Events"]
stg_rows = [
["1st Stage\n(Latent+Active)", "12–18 hrs total\n(Active: 8 hrs)", "6–12 hrs total\n(Active: 5 hrs)", "Onset of true labour → Full cervical dilatation (10 cm)\nLatent: 0-4cm | Active: 4-10cm"],
["2nd Stage", "45 min – 2 hrs", "15 – 45 min", "Full dilatation → Delivery of baby\n7 cardinal movements occur here"],
["3rd Stage", "5 – 30 min", "5 – 20 min", "Delivery of placenta + membranes\nActive management: Oxytocin 10 IU IM"],
["4th Stage", "First 2 hours PP", "First 2 hours PP", "Observation period. Watch for PRIMARY PPH!"],
]
story.append(compare_table(stg_headers, stg_rows,
col_widths=[3.2*cm, 3.2*cm, 3.2*cm, 7.8*cm]))
story.append(sp(5))
# Drug table
story.append(Paragraph("<b>KEY DRUG DOSES (Memorise for Viva & Theory)</b>", S_MNEM_TITLE))
story.append(sp(3))
drug_headers = ["Drug", "Indication", "Dose / Route", "Note"]
drug_rows = [
["Oxytocin", "PPH / 3rd stage", "10 IU IM or IV infusion", "1st LINE uterotonic"],
["Ergometrine", "PPH", "0.2 mg IM (or 0.1mg IV)", "Avoid in hypertension"],
["Misoprostol", "PPH / IOL", "600-1000 mcg PR/SL", "Heat-stable; community use"],
["Carboprost", "Refractory PPH", "0.25 mg IM q 15min (×8)", "PGF2α; avoid asthma"],
["MgSO₄ (Eclampsia)", "Prevent/Treat eclampsia", "4g IV load + 1g/hr maint.", "Monitor reflexes, RR, UO"],
["Ca Gluconate", "MgSO₄ antidote", "1g (10 ml of 10%) IV slow", "Give if Mg toxicity"],
["Nifedipine", "Tocolysis / Anti-HTN", "10-20mg oral", "1st line tocolytic + anti-HTN"],
["Betamethasone", "Fetal lung maturity", "12mg IM × 2 (24h apart)", "< 34 weeks preterm labour"],
["Atosiban", "Tocolysis", "IV infusion protocol", "Oxytocin receptor antagonist"],
["Penicillin G", "GBS prophylaxis", "5 MU IV then 2.5 MU q4h", "PROM + preterm labour"],
]
story.append(compare_table(drug_headers, drug_rows,
col_widths=[3.5*cm, 4.2*cm, 4.6*cm, 5.1*cm]))
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 6: PPH MANAGEMENT FLOWCHART (text-based)
# ════════════════════════════════════════════════════════
story.append(section_header("🚨 SECTION 6 — PRIMARY PPH: STEP-BY-STEP MANAGEMENT ALGORITHM"))
story.append(sp(4))
pph_steps = [
("STEP 1", "CALL FOR HELP immediately. Activate PPH protocol / alert senior.", C_RED),
("STEP 2", "RESUSCITATE: 2 large-bore IV lines · O2 by mask · IV fluids (N/S or Ringer's) · Blood X-match · Foley catheter", C_BLUE),
("STEP 3", "IDENTIFY CAUSE — Apply 4 T's (Tone → Trauma → Tissue → Thrombin)", C_TEAL),
("TONE\n(80%)", "Bimanual compression → Oxytocin 10 IU → Ergometrine 0.2mg → Misoprostol 1000mcg PR → Carboprost 0.25mg IM q15min", HexColor("#e63946")),
("TRAUMA", "Inspect cervix, vagina, perineum → Suture all lacerations under good light", HexColor("#f4a261")),
("TISSUE", "Check placenta complete → Manual removal / ERPC if retained products", HexColor("#2a9d8f")),
("THROMBIN", "Check coagulation (PT, APTT, fibrinogen) → Give FFP, cryoprecipitate, platelets", HexColor("#457b9d")),
("STEP 4", "SURGICAL: Bakri balloon tamponade (91% success) → B-Lynch suture → O'Leary sutures → Internal iliac ligation", HexColor("#6d6875")),
("STEP 5", "UTERINE ARTERY EMBOLISATION (if radiology available + patient stable)", HexColor("#403d39")),
("LAST RESORT", "HYSTERECTOMY — life-saving. Do NOT delay if above measures fail.", C_RED),
]
pph_rows = []
for step, desc, col in pph_steps:
pph_rows.append([
Paragraph(f"<b>{step}</b>", sty("ps", fontSize=8.5, fontName="Helvetica-Bold", textColor=C_WHITE, leading=11)),
Paragraph(desc, sty("pd", fontSize=8, fontName="Helvetica", textColor=C_DARK, leading=11))
])
pt = Table(pph_rows, colWidths=[3*cm, 14.6*cm])
pts = [
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.3, C_MID_GRAY),
("BACKGROUND", (1,0), (1,-1), C_LIGHT_GRAY),
]
for i,(step,_,col) in enumerate(pph_steps):
pts.append(("BACKGROUND", (0,i), (0,i), col))
pt.setStyle(TableStyle(pts))
story.append(pt)
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 7: Pre-eclampsia Criteria Quick Box
# ════════════════════════════════════════════════════════
story.append(section_header("💊 SECTION 7 — PRE-ECLAMPSIA: CRITERIA, SEVERITY & TARGETS"))
story.append(sp(4))
pe_headers = ["Parameter", "Mild-Moderate", "Severe (ANY one = severe)"]
pe_rows = [
["Blood Pressure", "140-159 / 90-109 mmHg", "≥ 160 / ≥ 110 mmHg"],
["Proteinuria", "300 mg – 5 g / 24h", "> 5 g / 24h (or 3+ dipstick)"],
["Platelets", "Normal", "< 100,000 / µL"],
["Liver enzymes", "Normal", "AST/ALT > 2× normal"],
["Creatinine", "Normal", "> 1.1 mg/dl or doubling"],
["Pulm. oedema", "Absent", "Present"],
["Symptoms", "Mild headache", "Severe headache, visual changes, epigastric pain"],
["Delivery timing", "≥ 37 wks → Deliver", "≥ 34 wks → Deliver after stabilisation"],
["MgSO₄", "NOT routinely indicated", "GIVE for 24h (loading + maintenance)"],
["BP target", "< 150/100 mmHg", "< 150/100 mmHg (avoid over-lowering)"],
]
story.append(compare_table(pe_headers, pe_rows, col_widths=[4.2*cm, 6.7*cm, 6.7*cm]))
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 8: HIGH-YIELD NUMBERS & FACTS
# ════════════════════════════════════════════════════════
story.append(section_header("🔢 SECTION 8 — HIGH-YIELD NUMBERS TO MEMORISE"))
story.append(sp(4))
num_data = [
["Breech incidence at term", "3 – 4%"],
["Breech at 18-22 weeks", "24%"],
["Fundal-cornual placenta in breech","7% of all pregnancies"],
["Uterine atony causes PPH", "> 80%"],
["Bakri balloon success rate", "91%"],
["Primary PPH blood loss (vaginal)", "≥ 500 ml"],
["Primary PPH blood loss (LSCS)", "≥ 1000 ml"],
["APH definition (gestation)", "After 28 weeks (some sources: 20 weeks)"],
["Preterm labour definition", "< 37 completed weeks"],
["Bitrochanteric diameter (breech)","10 cm (engages in transverse)"],
["Biparietal diameter (head)", "9.5 cm"],
["Suboccipitobregmatic diameter", "9.5 cm — presented in well-flexed vertex"],
["Occipitofrontal diameter", "11.5 cm — deflexed head (larger = harder)"],
["1st stage duration (primi)", "12–18 hours"],
["Normal active phase progress", "≥ 1 cm/hour cervical dilatation"],
["3rd stage – active management", "Oxytocin 10 IU IM immediately after delivery"],
["MgSO4 loading dose (eclampsia)", "4 g IV over 20 min"],
["MgSO4 maintenance", "1 g/hr IV infusion for 24 hours post-delivery"],
["Betamethasone dose", "12 mg IM × 2 doses, 24 hours apart"],
["Pre-eclampsia onset", "After 20 completed weeks gestation"],
["hCG peak (hyperemesis)", "10 – 12 weeks (correlates with worst vomiting)"],
["Recurrent abortion definition", "3 or more consecutive pregnancy losses"],
]
num_rows_left = num_data[:11]
num_rows_right = num_data[11:]
def num_mini_table(rows):
trows = [[
Paragraph(f"<b>{r[0]}</b>", sty("nl", fontSize=7.5, fontName="Helvetica-Bold", leading=10, textColor=C_DARK)),
Paragraph(r[1], sty("nr", fontSize=7.5, fontName="Helvetica", leading=10, textColor=HexColor("#e63946")))
] for r in rows]
t = Table(trows, colWidths=[6.5*cm, 2.0*cm])
t.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.3, C_MID_GRAY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
*[("BACKGROUND", (0,i), (-1,i), C_LIGHT_GRAY if i%2==0 else C_WHITE) for i in range(len(rows))]
]))
return t
num_table = Table([[num_mini_table(num_rows_left), num_mini_table(num_rows_right)]],
colWidths=[8.7*cm, 8.7*cm],
style=[("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),0),
("BOTTOMPADDING",(0,0),(-1,-1),0)])
story.append(num_table)
story.append(sp(8))
# ════════════════════════════════════════════════════════
# SECTION 9: RAPID-FIRE DIFFERENTIATORS
# ════════════════════════════════════════════════════════
story.append(section_header("⚡ SECTION 9 — RAPID-FIRE EXAM DIFFERENTIATORS"))
story.append(sp(4))
fire_items = [
("Painless APH =", "PLACENTA PREVIA until proven otherwise"),
("Painful APH =", "ABRUPTIO PLACENTA until proven otherwise"),
("Shock > visible blood =", "CONCEALED ABRUPTIO (retroplacental clot)"),
("Board-like uterus =", "ABRUPTIO (Couvelaire in severe cases)"),
("Uterus not contracting after delivery =", "UTERINE ATONY — give Oxytocin NOW"),
("Convulsions in pregnancy =", "ECLAMPSIA — Give MgSO4 immediately"),
("MgSO4 antidote =", "CALCIUM GLUCONATE 1 g IV"),
("First sign MgSO4 toxicity =","Loss of deep tendon reflexes (patellar)"),
("Only cure for pre-eclampsia =", "DELIVERY of baby and placenta"),
("Best single tocolytic =", "NIFEDIPINE (calcium channel blocker)"),
("Highest cord prolapse risk breech =", "FOOTLING (incomplete) breech"),
("Most common cause of footling breech =", "PREMATURITY"),
("Denominator in breech =", "SACRUM"),
("Most common PPH cause =", "UTERINE ATONY (Tone, 80%)"),
("hCG peaks at =", "10-12 WEEKS (= worst hyperemesis)"),
("Higher hCG → worse HG in =", "MOLAR PREGNANCY and MULTIPLE PREGNANCY"),
("Cardinal movement that reduces fetal head diameter =", "FLEXION (11.5cm → 9.5cm)"),
("Fetal neuroprotection drug <32 wks =", "MAGNESIUM SULPHATE"),
]
fire_rows = []
for q, a in fire_items:
fire_rows.append([
Paragraph(q, sty("fq", fontSize=8, fontName="Helvetica", leading=11, textColor=HexColor("#495057"))),
Paragraph(f"<b>{a}</b>", sty("fa", fontSize=8, fontName="Helvetica-Bold", leading=11, textColor=C_RED))
])
ft = Table(fire_rows, colWidths=[9*cm, 8.4*cm])
ft.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.3, C_MID_GRAY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 7),
*[("BACKGROUND", (0,i), (-1,i), HexColor("#fff9f9") if i%2==0 else C_WHITE) for i in range(len(fire_rows))]
]))
story.append(ft)
story.append(sp(8))
# ════════════════════════════════════════════════════════
# FOOTER
# ════════════════════════════════════════════════════════
story.append(hr(C_TEAL))
story.append(Paragraph(
"<b>Source:</b> DC Dutta's Textbook of Obstetrics, 7th Ed. | Creasy & Resnik's Maternal-Fetal Medicine | Grainger & Allison's Diagnostic Radiology "
"— <i>Good luck on your exam!</i> 🎓",
sty("foot", fontSize=7.5, fontName="Helvetica", textColor=HexColor("#6c757d"), leading=10, alignment=TA_CENTER)
))
# ── Build ────────────────────────────────────────────────────────
doc.build(story)
print("PDF created:", OUTPUT)
cd /tmp/workspace/obs-cheatsheet && python make_cheatsheet.py 2>&1
OBS CheatSheet
PDF Document · PDF
| Section | Contents |
|---|---|
| 1. Key Definitions | 23 terms - every definition you need, formatted as a two-column reference table |
| 2. Mnemonics | 4 T's of PPH, ABRUPTIO, HELLP, EVERY DECENT FETAL... (7 movements), PUMP F (breech causes), MgSO4 CAMP toxicity, Pre-E MADE |
| 3. Abruption vs Previa | 15-row comparison table - the most asked exam topic |
| 4. Abortion Types | All 7 types with bleeding, pain, os, USG and management side by side |
| 5. Stages of Labour + Drug Doses | All 4 stages with durations + 10 drugs with exact doses and routes |
| 6. PPH Algorithm | Step-by-step colour-coded management flowchart (Steps 1-5 + Last Resort) |
| 7. Pre-eclampsia Criteria | Mild vs Severe with every parameter, BP targets, MgSO4 guidance |
| 8. Numbers to Memorise | 22 high-yield numerical facts (incidences, diameters, doses, durations) |
| 9. Rapid-Fire Differentiators | 18 Q&A pairs - if you see X in the exam, the answer is Y |