Hii
Nan sollurayha nee neyabam vachipeya
Nan pesura mathere pesu
Nan oru MLT 2nd year student
Trichy srm la mgr university under la padikura
Study notes or revision guide create panra?
mkdir -p /home/daytona/workspace/hematology-notes && ls /home/daytona/workspace/
~/hematology-notes/create_hematology_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import HexColor, black, white
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.lib import colors
OUTPUT = "/home/daytona/workspace/hematology-notes/Hematology_Revision_Guide_MLT.pdf"
# Color palette
DARK_BLUE = HexColor("#1A237E")
MED_BLUE = HexColor("#1565C0")
LIGHT_BLUE = HexColor("#E3F2FD")
RED = HexColor("#C62828")
LIGHT_RED = HexColor("#FFEBEE")
GREEN = HexColor("#2E7D32")
LIGHT_GREEN = HexColor("#E8F5E9")
ORANGE = HexColor("#E65100")
LIGHT_ORANGE= HexColor("#FFF3E0")
PURPLE = HexColor("#4A148C")
LIGHT_PURPLE= HexColor("#F3E5F5")
GREY = HexColor("#F5F5F5")
DARK_GREY = HexColor("#424242")
YELLOW_BG = HexColor("#FFFDE7")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=18*mm,
leftMargin=18*mm,
topMargin=20*mm,
bottomMargin=18*mm,
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle("Title", parent=styles["Title"],
fontSize=26, textColor=white, spaceAfter=6,
alignment=TA_CENTER, fontName="Helvetica-Bold")
subtitle_style = ParagraphStyle("Sub", parent=styles["Normal"],
fontSize=13, textColor=LIGHT_BLUE, spaceAfter=4,
alignment=TA_CENTER, fontName="Helvetica")
h1 = ParagraphStyle("H1", parent=styles["Heading1"],
fontSize=16, textColor=white, spaceBefore=14, spaceAfter=6,
fontName="Helvetica-Bold", backColor=MED_BLUE,
leftIndent=-8, rightIndent=-8, leading=20,
borderPad=6)
h2 = ParagraphStyle("H2", parent=styles["Heading2"],
fontSize=13, textColor=DARK_BLUE, spaceBefore=10, spaceAfter=4,
fontName="Helvetica-Bold", borderPad=2)
h3 = ParagraphStyle("H3", parent=styles["Heading3"],
fontSize=11, textColor=MED_BLUE, spaceBefore=7, spaceAfter=3,
fontName="Helvetica-Bold")
body = ParagraphStyle("Body", parent=styles["Normal"],
fontSize=9.5, leading=14, spaceAfter=4,
textColor=DARK_GREY, fontName="Helvetica", alignment=TA_JUSTIFY)
bullet = ParagraphStyle("Bullet", parent=styles["Normal"],
fontSize=9.5, leading=13, spaceAfter=2,
leftIndent=14, bulletIndent=4,
textColor=DARK_GREY, fontName="Helvetica")
note_style = ParagraphStyle("Note", parent=styles["Normal"],
fontSize=9, leading=13, spaceAfter=3,
textColor=GREEN, fontName="Helvetica-Oblique",
leftIndent=8, rightIndent=8, backColor=LIGHT_GREEN,
borderPad=5)
warn_style = ParagraphStyle("Warn", parent=styles["Normal"],
fontSize=9, leading=13, spaceAfter=3,
textColor=RED, fontName="Helvetica-Bold",
leftIndent=8, rightIndent=8, backColor=LIGHT_RED,
borderPad=5)
key_style = ParagraphStyle("Key", parent=styles["Normal"],
fontSize=9.5, leading=14, spaceAfter=3,
textColor=PURPLE, fontName="Helvetica-Bold",
leftIndent=8, backColor=LIGHT_PURPLE, borderPad=5)
story = []
# ─────────────────── COVER PAGE ────────────────────
cover_data = [[Paragraph("🔬 HEMATOLOGY", title_style)],
[Paragraph("Complete Revision Guide", subtitle_style)],
[Paragraph("MLT 2nd Year | MGR University", subtitle_style)],
[Paragraph("SRM Trichy | 2025–26", subtitle_style)]]
cover_table = Table(cover_data, colWidths=[174*mm])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING",(0,0), (-1,-1), 12),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN",(0,0), (-1,-1), "MIDDLE"),
("ROUNDEDCORNERS", (0,0), (-1,-1), 8),
]))
story.append(Spacer(1, 40*mm))
story.append(cover_table)
story.append(Spacer(1, 10*mm))
topics_cover = [
["Topics Covered"],
["1. Blood Composition & Functions"],
["2. Erythrocytes (RBC) & Maturation"],
["3. Hemoglobin - Structure & Types"],
["4. CBC & RBC Indices"],
["5. Anemia - Classification & Types"],
["6. WBC & Differential Count"],
["7. WBC Disorders & Leukemias"],
["8. Platelets & Coagulation"],
["9. Blood Groups (ABO & Rh)"],
["10. Lab Procedures & QC"],
]
tbl = Table(topics_cover, colWidths=[130*mm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), MED_BLUE),
("TEXTCOLOR", (0,0),(0,0), white),
("FONTNAME", (0,0),(0,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(0,0), 11),
("BACKGROUND", (0,1),(-1,-1), LIGHT_BLUE),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,1),(-1,-1), 9.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("GRID", (0,0),(-1,-1), 0.5, MED_BLUE),
]))
story.append(tbl)
story.append(PageBreak())
# ─────────────────── HELPER FUNCTIONS ──────────────
def section_header(title, color=MED_BLUE):
tbl = Table([[Paragraph(title, ParagraphStyle("SH", fontName="Helvetica-Bold",
fontSize=14, textColor=white, alignment=TA_LEFT, leading=18))]], colWidths=[174*mm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), color),
("TOPPADDING", (0,0),(-1,-1), 8),
("BOTTOMPADDING",(0,0),(-1,-1), 8),
("LEFTPADDING",(0,0),(-1,-1), 12),
("ROUNDEDCORNERS",(0,0),(-1,-1),4),
]))
return tbl
def info_box(text, bg=LIGHT_BLUE, fg=DARK_BLUE):
s = ParagraphStyle("ib", fontName="Helvetica", fontSize=9.5, leading=14,
textColor=fg, backColor=bg, leftIndent=8, rightIndent=8, borderPad=6,
spaceAfter=4)
return Paragraph(text, s)
def two_col_table(data, headers=None, col_widths=None):
if col_widths is None:
col_widths = [60*mm, 110*mm]
all_data = []
if headers:
all_data.append(headers)
all_data.extend(data)
t = Table(all_data, colWidths=col_widths)
style = [
("BACKGROUND", (0,0),(-1,0), MED_BLUE if headers else LIGHT_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white if headers else DARK_BLUE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 9),
("ALIGN", (0,0),(-1,-1), "LEFT"),
("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.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, GREY]),
]
t.setStyle(TableStyle(style))
return t
def bullet_list(items, color=DARK_GREY):
paras = []
s = ParagraphStyle("bl", fontName="Helvetica", fontSize=9.5, leading=13,
leftIndent=14, bulletIndent=4, spaceAfter=2, textColor=color)
for item in items:
paras.append(Paragraph(f"• {item}", s))
return paras
# ════════════════════════════════════════════════════
# SECTION 1 — BLOOD COMPOSITION & FUNCTIONS
# ════════════════════════════════════════════════════
story.append(section_header("SECTION 1: BLOOD COMPOSITION & FUNCTIONS"))
story.append(Spacer(1,5))
story.append(Paragraph("Overview", h2))
story.append(Paragraph(
"Blood is a specialized connective tissue that circulates through the cardiovascular system. "
"It consists of <b>plasma (55%)</b> and <b>formed elements (45%)</b>. "
"Total blood volume in an adult = <b>5–6 litres</b>.", body))
story.append(Paragraph("Composition of Blood", h2))
comp_data = [
[Paragraph("<b>Component</b>", ParagraphStyle("ch", fontName="Helvetica-Bold", fontSize=9, textColor=white)),
Paragraph("<b>% / Normal Value</b>", ParagraphStyle("ch", fontName="Helvetica-Bold", fontSize=9, textColor=white)),
Paragraph("<b>Key Points</b>", ParagraphStyle("ch", fontName="Helvetica-Bold", fontSize=9, textColor=white))],
["Plasma", "55%", "Water 90%, Proteins, Electrolytes, Nutrients, Hormones"],
["RBC (Erythrocytes)", "4.5–5.5 M/µL (M) / 4.0–5.0 M/µL (F)", "Transport O2 & CO2 via Hemoglobin"],
["WBC (Leukocytes)", "4,000–11,000/µL", "Immunity & defence"],
["Platelets (Thrombocytes)", "1,50,000–4,00,000/µL", "Haemostasis & clotting"],
["Hematocrit (PCV)", "40–54% (M) / 36–47% (F)", "% of RBC in total blood volume"],
]
tbl = Table(comp_data, colWidths=[45*mm, 50*mm, 79*mm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), MED_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, GREY]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tbl)
story.append(Spacer(1,4))
story.append(info_box("📌 KEY: Plasma proteins include Albumin (60%), Globulins (36%), Fibrinogen (4%). "
"Serum = Plasma − Fibrinogen (clotting factors removed).", YELLOW_BG, ORANGE))
# ════════════════════════════════════════════════════
# SECTION 2 — ERYTHROCYTE MATURATION
# ════════════════════════════════════════════════════
story.append(Spacer(1,6))
story.append(section_header("SECTION 2: ERYTHROCYTES & MATURATION", RED))
story.append(Spacer(1,5))
story.append(Paragraph("RBC - Normal Features", h2))
story.append(Paragraph(
"Normal RBC is a <b>biconcave disc</b>, 7–8 µm in diameter, 2 µm thick at edges and 1 µm at centre. "
"Lacks nucleus and mitochondria. Life span = <b>120 days</b>. Destroyed in spleen (extravascular hemolysis).", body))
story.append(Paragraph("Normoblastic Maturation Sequence", h2))
story.append(info_box(
"Pronormoblast → Basophilic Normoblast → Polychromatophilic Normoblast → "
"Orthochromatic Normoblast → Reticulocyte → Mature RBC", LIGHT_GREEN, GREEN))
mat_data = [
[Paragraph("<b>Stage</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Size</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Nucleus</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Cytoplasm</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Pronormoblast", "~20 µm", "Fine chromatin, nucleoli visible", "Deeply basophilic, no granules"],
["Basophilic Normoblast", "~16 µm", "Coarse chromatin, wheel-spoke pattern", "Deep blue (RNA rich)"],
["Polychromatophilic Normoblast", "~14 µm", "Dense, condensed", "Gray-blue (Hb + RNA)"],
["Orthochromatic Normoblast", "~10 µm", "Pyknotic (small, dense)", "Pink-gray, nearly pink"],
["Reticulocyte", "~8 µm", "No nucleus", "Residual RNA (blue with supravital stain)"],
["Mature RBC", "7–8 µm", "Absent", "Pink, biconcave disc"],
]
tbl2 = Table(mat_data, colWidths=[50*mm, 22*mm, 52*mm, 50*mm])
tbl2.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RED),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_RED]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tbl2)
story.append(Spacer(1,4))
story.append(info_box("📌 Reticulocyte count normal: 0.5–2.5% | Increased in hemolytic anemia & after blood loss | "
"Stained with Brilliant Cresyl Blue (BCB) / New Methylene Blue (NMB)", YELLOW_BG, ORANGE))
story.append(Paragraph("Erythropoiesis Regulation", h2))
story.append(Paragraph(
"Erythropoiesis is stimulated by <b>Erythropoietin (EPO)</b> produced by <b>peritubular cells of the kidney</b> "
"in response to hypoxia. It acts on BFU-E and CFU-E progenitor cells in bone marrow. "
"Iron, Vitamin B12, and Folate are essential cofactors.", body))
# ════════════════════════════════════════════════════
# SECTION 3 — HEMOGLOBIN
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SECTION 3: HEMOGLOBIN - STRUCTURE & TYPES", DARK_BLUE))
story.append(Spacer(1,5))
story.append(Paragraph("Structure of Hemoglobin", h2))
story.append(Paragraph(
"Hemoglobin (Hb) = <b>Globin (protein)</b> + <b>Heme (iron-porphyrin)</b>. "
"MW = 64,500 Da. Each Hb molecule has <b>4 heme groups</b> + <b>4 globin chains</b>. "
"Each heme contains one <b>Fe²⁺ (ferrous)</b> ion that binds one O₂ molecule. "
"So 1 Hb molecule carries 4 O₂ molecules.", body))
story.append(Paragraph("Types of Normal Hemoglobin", h2))
hb_data = [
[Paragraph("<b>Type</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Chains</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>% in Adults</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Notes</b>", ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["HbA (Adult)", "α₂β₂", "~97%", "Major adult hemoglobin"],
["HbA₂", "α₂δ₂", "~2–3%", "↑ in Beta-thalassemia trait"],
["HbF (Fetal)", "α₂γ₂", "<1% in adults", "Predominant in newborns; ↑ O₂ affinity"],
["HbH", "β₄", "Absent normally", "Seen in alpha-thalassemia (3-gene deletion)"],
["HbBarts", "γ₄", "Absent normally", "Hydrops fetalis (4-gene alpha deletion)"],
]
tbl3 = Table(hb_data, colWidths=[35*mm, 25*mm, 35*mm, 79*mm])
tbl3.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tbl3)
story.append(Spacer(1,4))
story.append(Paragraph("Hemoglobin Derivatives", h2))
hbd = [
["Oxyhemoglobin (HbO₂)", "Hb + O₂ in lungs", "Bright red"],
["Deoxyhemoglobin (Hb)", "Hb without O₂ in tissues", "Dark red/purple"],
["Carboxyhemoglobin (HbCO)", "Hb + CO (CO poisoning)", "Cherry red; CO affinity 240× > O₂"],
["Methemoglobin (MetHb)", "Fe²⁺ → Fe³⁺ (cannot carry O₂)", "Chocolate brown; treated with Methylene Blue"],
["Sulfhemoglobin", "Hb + H₂S or drugs", "Green; irreversible"],
]
t = Table([[Paragraph("<b>Derivative</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Formation</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Colour/Notes</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + hbd,
colWidths=[50*mm, 65*mm, 59*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), PURPLE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_PURPLE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(t)
story.append(Paragraph("Cyanmethemoglobin (HiCN) Method", h3))
story.append(info_box(
"GOLD STANDARD method for Hb estimation. Blood + Drabkin's reagent (K₃Fe(CN)₆ + KCN). "
"RBC lysed, Hb → Methemoglobin → Cyanmethemoglobin. Read at 540 nm. "
"Does NOT measure HbS or HbCO well.", LIGHT_GREEN, GREEN))
# ════════════════════════════════════════════════════
# SECTION 4 — CBC & RBC INDICES
# ════════════════════════════════════════════════════
story.append(Spacer(1,6))
story.append(section_header("SECTION 4: CBC & RBC INDICES", GREEN))
story.append(Spacer(1,5))
story.append(Paragraph("Normal CBC Reference Values", h2))
cbc_data = [
[Paragraph("<b>Parameter</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Male</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Female</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Unit</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Hemoglobin (Hb)", "13.5–17.5", "12.0–16.0", "g/dL"],
["RBC Count", "4.5–5.5", "4.0–5.0", "million/µL"],
["Hematocrit / PCV", "40–54%", "36–47%", "%"],
["WBC (TLC)", "4,000–11,000", "4,000–11,000", "/µL"],
["Platelet Count", "1,50,000–4,00,000", "1,50,000–4,00,000", "/µL"],
["MCV", "80–100", "80–100", "fL (femtolitres)"],
["MCH", "27–33", "27–33", "pg (picograms)"],
["MCHC", "32–36", "32–36", "g/dL"],
["RDW", "11.5–14.5%", "11.5–14.5%", "%"],
["Reticulocyte count", "0.5–2.5%", "0.5–2.5%", "%"],
]
tcbc = Table(cbc_data, colWidths=[60*mm, 35*mm, 35*mm, 44*mm])
tcbc.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), GREEN),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_GREEN]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tcbc)
story.append(Spacer(1,4))
story.append(Paragraph("RBC Indices - Formulae", h2))
indices_data = [
[Paragraph("<b>Index</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Formula</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Normal</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Clinical Use</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["MCV (Mean Cell Volume)", "PCV (%) × 10 / RBC (millions/µL)", "80–100 fL", "Micro/Macro/Normocytic anemia classification"],
["MCH (Mean Cell Hb)", "Hb (g/dL) × 10 / RBC (millions/µL)", "27–33 pg", "Hypochromic / Normochromic"],
["MCHC (Mean Cell Hb Conc.)", "Hb (g/dL) × 100 / PCV (%)", "32–36 g/dL", "MCHC >36 = spherocytosis"],
["RDW (RBC Distrib. Width)", "SD of MCV / Mean MCV × 100", "11.5–14.5%", "Anisocytosis detection"],
]
ti = Table(indices_data, colWidths=[45*mm, 50*mm, 28*mm, 51*mm])
ti.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(ti)
# ════════════════════════════════════════════════════
# SECTION 5 — ANEMIA
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SECTION 5: ANEMIA - CLASSIFICATION & TYPES", RED))
story.append(Spacer(1,5))
story.append(Paragraph("Definition", h2))
story.append(Paragraph(
"Anemia = reduction in <b>Hb concentration</b> below the normal for age and sex. "
"WHO criteria: Hb < 13 g/dL in adult males, < 12 g/dL in adult females, < 11 g/dL in children.", body))
story.append(Paragraph("Morphological Classification (MCV-based)", h2))
anemia_morph = [
[Paragraph("<b>Type</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>MCV</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>MCHC</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Examples</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Microcytic Hypochromic", "< 80 fL", "< 32 g/dL", "Iron Deficiency, Thalassemia, Sideroblastic anemia, Lead poisoning"],
["Normocytic Normochromic", "80–100 fL", "32–36 g/dL", "Aplastic anemia, Hemolytic anemia, Acute blood loss, CKD"],
["Macrocytic (Megaloblastic)", "> 100 fL", "32–36 g/dL", "Vit B12 deficiency, Folate deficiency"],
["Macrocytic (Non-megaloblastic)", "> 100 fL", "Normal", "Liver disease, Hypothyroidism, Alcohol"],
]
tam = Table(anemia_morph, colWidths=[50*mm, 20*mm, 25*mm, 79*mm])
tam.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RED),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_RED]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tam)
story.append(Spacer(1,4))
story.append(Paragraph("Iron Deficiency Anemia (IDA)", h2))
story.append(info_box("Most COMMON anemia worldwide. Microcytic Hypochromic.", LIGHT_RED, RED))
ida_data = [
["Serum Iron", "↓ Decreased"],
["TIBC (Total Iron Binding Capacity)", "↑ Increased"],
["Serum Ferritin", "↓ Decreased (earliest marker)"],
["Transferrin Saturation", "< 16% (normal 25–50%)"],
["Peripheral Smear", "Microcytes, Hypochromia, Pencil cells, Target cells, Anisocytosis, Poikilocytosis"],
["Bone Marrow", "Absent iron stores (Prussian blue stain - negative)"],
["Treatment", "Oral Ferrous Sulphate 200mg TID"],
]
for row in ida_data:
story.append(Paragraph(f"<b>{row[0]}:</b> {row[1]}", bullet))
story.append(Spacer(1,4))
story.append(Paragraph("Megaloblastic Anemia", h2))
story.append(Paragraph(
"Caused by deficiency of <b>Vitamin B12</b> or <b>Folic Acid</b> → impaired DNA synthesis "
"→ large, immature red cells (megaloblasts).", body))
mega_data = [
[Paragraph("<b>Feature</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Vit B12 Deficiency</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Folate Deficiency</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Dietary source", "Animal products, dairy", "Green leafy vegetables"],
["Storage", "Liver 3–5 years", "Liver 3–4 months"],
["Intrinsic Factor needed?", "YES (from gastric parietal cells)", "NO"],
["Neurological signs?", "YES (subacute combined degeneration)", "NO"],
["Serum level", "< 200 pg/mL", "< 4 ng/mL (RBC folate)"],
["Peripheral smear", "Macrocytes, Hypersegmented neutrophils (>5 lobes)", "Same"],
["Schilling test", "Used to differentiate cause", "Not applicable"],
]
tmega = Table(mega_data, colWidths=[50*mm, 62*mm, 62*mm])
tmega.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), PURPLE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_PURPLE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tmega)
story.append(Spacer(1,4))
story.append(Paragraph("Hemolytic Anemias", h2))
story.append(Paragraph(
"Characterized by <b>premature destruction of RBCs</b>. Life span < 120 days. "
"Compensatory erythropoiesis increases reticulocyte count.", body))
hemo_types = [
["Hereditary Spherocytosis", "Defect in spectrin/ankyrin; spherocytes on smear; osmotic fragility ↑; Coombs test negative; splenomegaly"],
["G6PD Deficiency", "X-linked; episodic hemolysis (drugs, infection, fava beans); Heinz bodies; bite cells"],
["Sickle Cell Disease (HbSS)", "β-globin gene mutation; HbS polymerizes under low O₂; sickle cells, target cells; Hb electrophoresis confirms"],
["Autoimmune Hemolytic Anemia", "Warm type (IgG) or Cold type (IgM); Direct Coombs Test POSITIVE"],
["PNH (Paroxysmal Nocturnal Hb-uria)", "CD55/CD59 deficiency; Ham's test +ve; Flow cytometry gold standard"],
]
th = Table([[Paragraph("<b>Condition</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Key Features</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + hemo_types,
colWidths=[55*mm, 119*mm])
th.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), ORANGE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_ORANGE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(th)
# ════════════════════════════════════════════════════
# SECTION 6 — WBC & DIFFERENTIAL COUNT
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SECTION 6: WBC & DIFFERENTIAL COUNT", PURPLE))
story.append(Spacer(1,5))
story.append(Paragraph("WBC Types and Normal %", h2))
wbc_data = [
[Paragraph("<b>Cell Type</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Normal %</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Function</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Key Features</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Neutrophils", "50–70%", "Phagocytosis of bacteria", "Multi-lobed nucleus; 1st responders; ↑ in bacterial infection"],
["Lymphocytes", "20–40%", "Humoral & cell-mediated immunity", "Round dark nucleus; B cells & T cells; ↑ in viral infections"],
["Monocytes", "2–8%", "Phagocytosis, Antigen presentation", "Horse-shoe/kidney-shaped nucleus; become macrophages in tissue"],
["Eosinophils", "1–4%", "Parasitic infections, Allergic response", "Bi-lobed nucleus; red granules; ↑ in allergy & parasites (NAACP)"],
["Basophils", "0–1%", "Release histamine & heparin", "Large dark blue-purple granules; ↑ in CML"],
]
twbc = Table(wbc_data, colWidths=[40*mm, 22*mm, 45*mm, 67*mm])
twbc.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), PURPLE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_PURPLE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(twbc)
story.append(Spacer(1,4))
story.append(info_box(
"Memory trick for WBC differential (High → Low): Never Let Monkeys Eat Bananas\n"
"N - Neutrophils (50–70%) | L - Lymphocytes (20–40%) | M - Monocytes (2–8%) | "
"E - Eosinophils (1–4%) | B - Basophils (0–1%)", YELLOW_BG, ORANGE))
story.append(Paragraph("WBC Morphology Changes", h2))
morph_changes = [
["Hypersegmented Neutrophils", "≥5 lobes → Megaloblastic anemia (Vit B12 / Folate deficiency)"],
["Toxic Granulation", "Heavy dark granules → Severe bacterial infection / sepsis"],
["Döhle Bodies", "Light blue inclusions in cytoplasm → Infection, burns, pregnancy"],
["Pelger-Huet Anomaly", "Bilobed (peanut-shaped) neutrophils → congenital or pseudo (drugs)"],
["Auer Rods", "Pink rod-shaped inclusions → AML (Acute Myeloid Leukemia) - PATHOGNOMONIC"],
["Smudge Cells (Basket cells)", "Disrupted fragile lymphocytes → CLL (Chronic Lymphocytic Leukemia)"],
["Reactive Lymphocytes", "Large, irregular, vacuolated → EBV (Infectious Mononucleosis)"],
]
twm = Table([[Paragraph("<b>Finding</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Significance</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + morph_changes,
colWidths=[60*mm, 114*mm])
twm.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(twm)
# ════════════════════════════════════════════════════
# SECTION 7 — LEUKEMIAS
# ════════════════════════════════════════════════════
story.append(Spacer(1,6))
story.append(section_header("SECTION 7: LEUKEMIAS & WBC DISORDERS", DARK_BLUE))
story.append(Spacer(1,5))
story.append(Paragraph("Leukemia Overview", h2))
story.append(Paragraph(
"Leukemia = malignant proliferation of leukocytes. Classified as <b>Acute vs Chronic</b> "
"and <b>Myeloid vs Lymphoid</b>.", body))
leuk_data = [
[Paragraph("<b>Type</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Age Group</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>WBC Count</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Key Features</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["ALL (Acute Lymphoblastic Leukemia)", "Children (2–10 yrs)", "↑↑", "Most common childhood leukemia; Lymphoblasts; TdT+; CD10+ (CALLA)"],
["AML (Acute Myeloid Leukemia)", "Adults (>60 yrs)", "↑↑", "Auer rods pathognomonic; FAB classification M0–M7; M3 = APL (t15;17) → ATRA therapy"],
["CML (Chronic Myeloid Leukemia)", "Adults (40–60 yrs)", "↑↑↑ (>100,000)", "Philadelphia chromosome t(9;22) BCR-ABL; Basophilia; Treated with Imatinib"],
["CLL (Chronic Lymphocytic Leukemia)", "Elderly (>60 yrs)", "↑ Lymphocytes", "Smudge/basket cells; CD5+CD19+CD23+; Indolent course"],
]
tl = Table(leuk_data, colWidths=[55*mm, 28*mm, 22*mm, 69*mm])
tl.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tl)
story.append(Spacer(1,4))
story.append(info_box(
"⭐ HIGH YIELD: Auer rods → AML only | Philadelphia chromosome → CML | "
"Smudge cells → CLL | TdT positive → ALL | t(15;17) → AML-M3 (APL) → treat with ATRA", YELLOW_BG, ORANGE))
# ════════════════════════════════════════════════════
# SECTION 8 — PLATELETS & COAGULATION
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SECTION 8: PLATELETS & COAGULATION", ORANGE))
story.append(Spacer(1,5))
story.append(Paragraph("Platelets", h2))
plt_info = [
"Normal count: 1,50,000 – 4,00,000 / µL",
"Size: 2–3 µm; no nucleus; life span 7–10 days",
"Produced by megakaryocytes in bone marrow (thrombopoietin stimulated)",
"Thrombocytopenia: count < 1,00,000/µL | Severe: < 20,000/µL (spontaneous bleeding)",
"Thrombocytosis: count > 4,00,000/µL (infection, post-splenectomy, CML)",
]
story.extend(bullet_list(plt_info, DARK_GREY))
story.append(Spacer(1,4))
story.append(Paragraph("Coagulation Cascade", h2))
story.append(info_box(
"Extrinsic pathway → Factor VII + Tissue Factor → X activation → Common pathway\n"
"Intrinsic pathway → Factors XII, XI, IX, VIII → X activation → Common pathway\n"
"Common pathway → Factor X + V → Prothrombin → Thrombin → Fibrinogen → Fibrin clot", LIGHT_BLUE, DARK_BLUE))
story.append(Spacer(1,4))
story.append(Paragraph("Coagulation Tests", h2))
coag_data = [
[Paragraph("<b>Test</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Normal Value</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Pathway Tested</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Prolonged in</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["PT (Prothrombin Time)", "11–14 seconds", "Extrinsic + Common", "Warfarin therapy, Vit K deficiency, Liver disease, Factor VII deficiency"],
["aPTT (Activated PTT)", "25–35 seconds", "Intrinsic + Common", "Heparin therapy, Hemophilia A/B, Factor deficiency, Lupus anticoagulant"],
["INR (International Normalized Ratio)", "0.8–1.2 (therapeutic: 2–3)", "Extrinsic", "Monitor Warfarin therapy"],
["TT (Thrombin Time)", "15–20 seconds", "Common (fibrinogen)", "Heparin, Fibrinogen deficiency, DIC"],
["BT (Bleeding Time)", "2–9 minutes (Duke method)", "Platelet function", "ITP, vWD, Aspirin use"],
["CT (Clotting Time – Lee-White)", "5–15 minutes", "Overall coagulation", "Hemophilia, Heparin"],
]
tcoag = Table(coag_data, colWidths=[45*mm, 35*mm, 35*mm, 59*mm])
tcoag.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), ORANGE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_ORANGE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tcoag)
story.append(Spacer(1,4))
story.append(Paragraph("Hemophilia A vs B", h2))
hemo_compare = [
[Paragraph("<b>Feature</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Hemophilia A</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Hemophilia B (Christmas disease)</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["Factor deficiency", "Factor VIII", "Factor IX"],
["Inheritance", "X-linked recessive", "X-linked recessive"],
["aPTT", "↑ Prolonged", "↑ Prolonged"],
["PT/INR", "Normal", "Normal"],
["BT", "Normal", "Normal"],
["Treatment", "Factor VIII concentrate / Desmopressin (DDAVP)", "Factor IX concentrate"],
]
themo = Table(hemo_compare, colWidths=[50*mm, 62*mm, 62*mm])
themo.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RED),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_RED]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(themo)
# ════════════════════════════════════════════════════
# SECTION 9 — BLOOD GROUPS
# ════════════════════════════════════════════════════
story.append(Spacer(1,6))
story.append(section_header("SECTION 9: BLOOD GROUPS (ABO & Rh SYSTEM)", MED_BLUE))
story.append(Spacer(1,5))
story.append(Paragraph("ABO Blood Group System", h2))
abo_data = [
[Paragraph("<b>Blood Group</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Antigen on RBC</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Antibody in Serum</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Can donate to</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Can receive from</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))],
["A", "A antigen", "Anti-B", "A, AB", "A, O"],
["B", "B antigen", "Anti-A", "B, AB", "B, O"],
["AB (Universal Recipient)", "A and B antigens", "None (No antibodies)", "AB only", "A, B, AB, O"],
["O (Universal Donor)", "None", "Anti-A and Anti-B", "A, B, AB, O", "O only"],
]
tabo = Table(abo_data, colWidths=[40*mm, 35*mm, 38*mm, 30*mm, 31*mm])
tabo.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), MED_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tabo)
story.append(Spacer(1,4))
story.append(Paragraph("Rh Blood Group System", h2))
rh_info = [
"Most important antigen: <b>D antigen</b> (Rh factor)",
"Rh positive (Rh+): D antigen present (~85% population)",
"Rh negative (Rh−): D antigen absent",
"Anti-D antibodies: <b>NOT naturally occurring</b> - form only after exposure",
"Hemolytic Disease of Newborn (HDN / Erythroblastosis Fetalis): Rh− mother, Rh+ fetus",
"Prevention: Anti-D immunoglobulin (Rho-GAM) given to Rh− mother within 72 hours of delivery",
]
for item in rh_info:
story.append(Paragraph(f"• {item}", bullet))
story.append(Spacer(1,4))
story.append(Paragraph("Coombs Test (Antiglobulin Test)", h2))
coomb_data = [
["Direct Coombs Test (DCT / DAT)", "Detects antibodies/complement ALREADY attached to RBCs in vivo",
"AIHA, HDN, Transfusion reactions"],
["Indirect Coombs Test (ICT / IAT)", "Detects antibodies FREE in patient's SERUM (in vitro)",
"Crossmatching, Rh antibody screening in pregnancy"],
]
tc = Table([[Paragraph("<b>Test</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Detects</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Uses</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + coomb_data,
colWidths=[52*mm, 72*mm, 50*mm])
tc.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tc)
# ════════════════════════════════════════════════════
# SECTION 10 — LAB PROCEDURES & QC
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SECTION 10: LAB PROCEDURES, STAINS & QC", GREEN))
story.append(Spacer(1,5))
story.append(Paragraph("Blood Sample Collection", h2))
samp_data = [
["EDTA (K₂ / K₃ EDTA)", "CBC, Hb, PCV, Differential count, Reticulocyte count, Blood film"],
["Sodium Citrate (3.2%)", "PT, aPTT, TT, Coagulation studies (9:1 ratio blood:anticoagulant)"],
["Heparin (Lithium/Sodium)", "Blood gas analysis, Chromosome studies"],
["Sodium Fluoride + Potassium Oxalate", "Blood glucose (preserves glucose for 24–48 hrs)"],
["Plain tube (no anticoagulant)", "Serum: Biochemistry, Serology, Blood grouping"],
]
ts = Table([[Paragraph("<b>Anticoagulant / Tube</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Tests Performed</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + samp_data,
colWidths=[68*mm, 106*mm])
ts.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), GREEN),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_GREEN]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(ts)
story.append(Spacer(1,4))
story.append(Paragraph("Peripheral Blood Smear Stains", h2))
stain_data = [
["Leishman stain", "Routine differential count; Romanowsky stain (azure B + eosin)"],
["Giemsa stain", "Malaria parasites, Tropical infections"],
["Wright stain", "Routine; most common stain in western labs"],
["Brilliant Cresyl Blue (BCB)", "Reticulocyte count (supravital stain - stains RNA blue)"],
["Perl's Prussian Blue", "Iron stores in bone marrow; Sideroblastic anemia detection"],
["PAS (Periodic Acid-Schiff)", "Glycogen in cells; positive in ALL; erythroleukemia"],
["Sudan Black B (SBB)", "Lipid granules in myeloid cells; positive in AML (not ALL)"],
["MPO (Myeloperoxidase)", "Positive in AML; Negative in ALL - differentiates AML from ALL"],
["Non-specific esterase (NSE)", "Positive in monocytic leukemia (AML-M5)"],
]
tst = Table([[Paragraph("<b>Stain</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Use / Significance</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + stain_data,
colWidths=[60*mm, 114*mm])
tst.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tst)
story.append(Spacer(1,4))
story.append(Paragraph("ESR (Erythrocyte Sedimentation Rate)", h2))
esr_data = [
["Normal (Westergren)", "Male: 0–15 mm/hr | Female: 0–20 mm/hr | Children: 0–10 mm/hr"],
["Method", "Westergren (gold standard), Wintrobe, Micromethod"],
["Anticoagulant", "Sodium Citrate (4:1 ratio, blood:anticoagulant) for Westergren"],
["↑ ESR (Raised)", "Infection, Inflammation, Malignancy, Anemia, Pregnancy, TB, RA, SLE"],
["↓ ESR (Low)", "Polycythemia vera, Sickle cell anemia, HbC disease, Spherocytosis"],
["Factors ↑ ESR", "Anemia, fibrinogen, immunoglobulins, macrocytosis"],
["Factors ↓ ESR", "Polycythemia, microcytosis, spherocytosis, hyperviscosity"],
]
tesr = Table([[Paragraph("<b>Parameter</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Details</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]] + esr_data,
colWidths=[55*mm, 119*mm])
tesr.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), MED_BLUE),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 9),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_BLUE]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tesr)
# ════════════════════════════════════════════════════
# QUICK REVISION TABLE (LAST PAGE)
# ════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("⭐ QUICK REVISION - HIGH YIELD POINTS", RED))
story.append(Spacer(1,6))
qr_items = [
["Philadelphia chromosome (t9;22) BCR-ABL", "CML (Chronic Myeloid Leukemia)"],
["Auer rods in WBC cytoplasm", "AML (Acute Myeloid Leukemia) - PATHOGNOMONIC"],
["TdT (Terminal deoxynucleotidyl transferase) positive", "ALL (Acute Lymphoblastic Leukemia)"],
["Smudge / Basket cells on smear", "CLL (Chronic Lymphocytic Leukemia)"],
["t(15;17) → APL → treat with ATRA", "AML-M3 (Acute Promyelocytic Leukemia)"],
["Hypersegmented neutrophils (>5 lobes)", "Megaloblastic anemia (B12 / Folate deficiency)"],
["Prussian blue negative in bone marrow", "Iron deficiency anemia (no iron stores)"],
["Osmotic fragility ↑, Coombs negative", "Hereditary Spherocytosis"],
["Heinz bodies + Bite cells", "G6PD Deficiency"],
["Sickle cells on PBS, Hb electrophoresis HbSS", "Sickle Cell Disease"],
["TIBC ↑, Serum iron ↓, Ferritin ↓", "Iron Deficiency Anemia"],
["HbA₂ > 3.5%", "Beta-thalassemia trait"],
["Direct Coombs Test positive", "AIHA, HDN, Transfusion reaction"],
["Cyanmethemoglobin method (540nm)", "Gold standard for Hb estimation"],
["Sodium Citrate (9:1)", "Coagulation studies (PT, aPTT)"],
["EPO produced by", "Peritubular cells of kidney (in response to hypoxia)"],
["Normal RBC life span", "120 days (destroyed in spleen)"],
["Reticulocyte stain", "Brilliant Cresyl Blue (BCB) / New Methylene Blue"],
["MPO positive → AML; MPO negative → ALL", "Cytochemical differentiation of leukemia"],
["Factor VIII deficiency", "Hemophilia A | Factor IX deficiency → Hemophilia B (Christmas)"],
]
qr_table_data = [[Paragraph("<b>Finding / Test</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white)),
Paragraph("<b>Diagnosis / Significance</b>",ParagraphStyle("t",fontName="Helvetica-Bold",fontSize=9,textColor=white))]]
for i, (finding, dx) in enumerate(qr_items):
qr_table_data.append([finding, dx])
tqr = Table(qr_table_data, colWidths=[95*mm, 79*mm])
tqr.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RED),
("TEXTCOLOR", (0,0),(-1,0), white),
("FONTNAME", (0,1),(-1,-1), "Helvetica"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("GRID", (0,0),(-1,-1), 0.4, colors.grey),
("ROWBACKGROUNDS", (0,1),(-1,-1), [white, LIGHT_RED]),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1), 3),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
story.append(tqr)
story.append(Spacer(1,8))
# Footer note
story.append(info_box(
"📚 Sources: Henry's Clinical Diagnosis & Management by Laboratory Methods | "
"Tietz Textbook of Laboratory Medicine | MGR University MLT Syllabus 2025-26 | "
"Prepared by Orris AI for SRM Trichy MLT 2nd Year", LIGHT_GREEN, GREEN))
# ────────── BUILD PDF ──────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /home/daytona/workspace/hematology-notes && python create_hematology_pdf.py 2…
ls -lh /home/daytona/workspace/hematology-notes/
Hematology Revision Guide MLT
PDF Document · PDF
| Section | Topics |
|---|---|
| 1 | Blood Composition & Normal Values |
| 2 | RBC Maturation (Pronormoblast → Mature RBC) table |
| 3 | Hemoglobin types, derivatives, Cyanmethemoglobin method |
| 4 | CBC reference ranges & RBC indices formulae (MCV, MCH, MCHC) |
| 5 | Anemia classification + IDA, Megaloblastic, Hemolytic anemias |
| 6 | WBC differential count + Morphology changes (Auer rods, smudge cells etc.) |
| 7 | ALL, AML, CML, CLL - key differences table |
| 8 | Coagulation cascade + PT/aPTT/BT tables + Hemophilia A vs B |
| 9 | ABO & Rh blood groups + Coombs test (Direct vs Indirect) |
| 10 | Lab stains, anticoagulants, ESR methods |
| ⭐ Last Page | 20 High-yield Quick Revision points |