Cbc

| Test | Description | Normal Range (Male) | Normal Range (Female) |
|---|---|---|---|
| Hemoglobin (Hb) | O2-carrying capacity of blood | 13.5-17.5 g/dL | 12.0-16.0 g/dL |
| Hematocrit (Hct) | % of whole blood volume occupied by RBCs | 39-49% | 35-45% |
| RBC count | Erythrocyte count | 4.3-5.7 × 10⁶ cells/µL | 3.8-5.1 × 10⁶ cells/µL |
| MCV (Mean Corpuscular Volume) | Average RBC size | 80-100 fL | 80-100 fL |
| MCH (Mean Corpuscular Hgb) | Hb per RBC (Hb ÷ RBC) | 27-33 pg | 27-33 pg |
| MCHC (Mean Corpuscular Hgb Concentration) | Hb concentration per volume of RBCs | 33-36 g/dL | 33-36 g/dL |
| RDW (Red Cell Distribution Width) | Variation in RBC size (anisocytosis) | 11.5-14.5% | 11.5-14.5% |
| Reticulocyte count | Immature RBCs; reflects bone marrow activity | 0.5-1.5% of RBCs |
| Test | Normal Range |
|---|---|
| Total WBC count | 4,500-11,000 cells/mm³ |
| Neutrophils (segs + bands) | 50-70% (absolute: 1,800-7,000/µL) |
| Lymphocytes | 20-40% |
| Monocytes | 2-8% |
| Eosinophils | 1-4% |
| Basophils | 0.5-1% |
| Test | Normal Range |
|---|---|
| Platelet count | 150,000-400,000/mm³ |
| MPV (Mean Platelet Volume) | 7.5-12.5 fL |
| Finding | Definition | Common Causes |
|---|---|---|
| Leukocytosis | WBC > 10,000/mm³ | Infection, inflammation, leukemia, steroids, stress |
| Leukopenia | WBC < 4,500/mm³ | Viral infection, drugs, autoimmune, B12/folate deficiency |
| Neutrophilia | ANC > 7,000/µL | Bacterial infection, steroids, stress, burns, MI |
| Neutropenia | ANC < 1,800/µL (severe: <500) | Drug reaction, viral infection, aplastic anemia |
| Lymphocytosis | Lymphs > 4,000/µL (adult) | Viral infections (EBV, CMV), CLL, pertussis |
| Lymphopenia | Lymphs < 1,500/µL (adult) | HIV, steroids, radiation, immunosuppressants |
| Eosinophilia | Eosinophils > 500/µL | Parasites, atopy/asthma, drug reactions, vasculitis |
| Monocytosis | Monocytes > 800/µL | Chronic infection (TB), inflammatory disease, malignancy |
Create a quick reference PDF guide for CBC interpretation
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace not found"
mkdir -p /home/daytona/workspace/cbc-guide
~/cbc-guide/generate_cbc_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.colors import HexColor
import os
OUTPUT = "/home/daytona/workspace/cbc-guide/CBC_Quick_Reference.pdf"
# --- Colour palette ---
DEEP_BLUE = HexColor("#1A3C5E")
MED_BLUE = HexColor("#2E6DA4")
LIGHT_BLUE = HexColor("#D6E8F7")
RED_COL = HexColor("#C0392B")
ORANGE_COL = HexColor("#E67E22")
GREEN_COL = HexColor("#27AE60")
GREY_BG = HexColor("#F4F6F8")
GREY_LINE = HexColor("#BDC3C7")
WHITE = colors.white
BLACK = colors.black
# --- Document ---
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=15*mm, bottomMargin=15*mm,
title="CBC Quick Reference Guide",
author="Orris Medical"
)
W, H = A4
CONTENT_W = W - 30*mm
styles = getSampleStyleSheet()
def style(name, **kw):
base = styles[name] if name in styles else styles["Normal"]
s = ParagraphStyle(name + "_custom", parent=base, **kw)
return s
# Custom styles
TITLE_S = style("Title", fontSize=22, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=2, fontName="Helvetica-Bold")
SUBTITLE_S= style("Normal", fontSize=10, textColor=HexColor("#AED6F1"),
alignment=TA_CENTER, spaceAfter=0, fontName="Helvetica")
SEC_S = style("Heading1",fontSize=11, textColor=WHITE,
fontName="Helvetica-Bold", spaceBefore=0, spaceAfter=0,
alignment=TA_LEFT)
BODY_S = style("Normal", fontSize=8.5, textColor=BLACK,
fontName="Helvetica", leading=12, spaceAfter=2)
BOLD_S = style("Normal", fontSize=8.5, textColor=DEEP_BLUE,
fontName="Helvetica-Bold", leading=12)
SMALL_S = style("Normal", fontSize=7.5, textColor=HexColor("#555555"),
fontName="Helvetica", leading=11)
CELL_HDR = style("Normal", fontSize=8, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=10)
CELL_S = style("Normal", fontSize=8, textColor=BLACK,
fontName="Helvetica", leading=10)
CELL_B = style("Normal", fontSize=8, textColor=DEEP_BLUE,
fontName="Helvetica-Bold", leading=10)
NOTE_S = style("Normal", fontSize=7.5, textColor=HexColor("#7F8C8D"),
fontName="Helvetica-Oblique", leading=10)
FORMULA_S = style("Normal", fontSize=8, textColor=DEEP_BLUE,
fontName="Helvetica-Bold", leading=11, alignment=TA_CENTER)
# ============================================================
# HELPER: section banner
# ============================================================
def section_banner(title, color=MED_BLUE):
tbl = Table([[Paragraph(title, SEC_S)]], colWidths=[CONTENT_W])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4]),
]))
return tbl
# ============================================================
# TITLE BLOCK
# ============================================================
def title_block():
tbl = Table(
[[Paragraph("CBC Quick Reference Guide", TITLE_S)],
[Paragraph("Complete Blood Count • Normal Values • Interpretation • Clinical Pearls", SUBTITLE_S)]],
colWidths=[CONTENT_W]
)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DEEP_BLUE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [6]),
]))
return tbl
# ============================================================
# 1. RBC PARAMETERS TABLE
# ============================================================
def rbc_table():
headers = ["Parameter", "Description", "Male", "Female", "SI Units"]
data = [
["Hemoglobin (Hb)", "O2-carrying capacity", "13.5-17.5 g/dL", "12.0-16.0 g/dL", "135-175 / 120-160 g/L"],
["Hematocrit (Hct)", "% volume of RBCs in blood", "39-49%", "35-45%", "0.39-0.49 / 0.35-0.45"],
["RBC Count", "Erythrocyte count", "4.3-5.7 x10\u2076/µL", "3.8-5.1 x10\u2076/µL", "x10\u00b9\u00b2/L"],
["MCV", "Mean cell volume (size)", "80-100 fL", "80-100 fL", "Same"],
["MCH", "Mean cell Hb (Hb / RBC)", "27-33 pg", "27-33 pg", "Same"],
["MCHC", "Mean cell Hb concentration", "33-36 g/dL", "33-36 g/dL", "330-360 g/L"],
["RDW", "Size variation of RBCs", "11.5-14.5%", "11.5-14.5%", "Same"],
["Reticulocytes", "Immature RBCs (BM activity)", "0.5-1.5%", "0.5-1.5%", "Same"],
]
rows = [[Paragraph(h, CELL_HDR) for h in headers]]
for i, row in enumerate(data):
cells = [Paragraph(row[0], CELL_B)] + [Paragraph(c, CELL_S) for c in row[1:]]
rows.append(cells)
col_w = [38*mm, 48*mm, 28*mm, 28*mm, 38*mm]
tbl = Table(rows, colWidths=col_w, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("BACKGROUND", (0,1), (-1,-1), WHITE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LINEBELOW", (0,0), (-1,0), 1, DEEP_BLUE),
]))
return tbl
# ============================================================
# 2. WBC TABLE
# ============================================================
def wbc_table():
headers = ["Cell Type", "% (Differential)", "Absolute Count", "Key Role"]
data = [
["Neutrophils (segs+bands)", "50-70%", "1,800-7,000/µL", "First responders; bacterial/fungal infection"],
["Lymphocytes", "20-40%", "1,000-4,800/µL", "Adaptive immunity; viral defense"],
["Monocytes", "2-8%", "200-800/µL", "Phagocytosis; antigen presentation"],
["Eosinophils", "1-4%", "45-440/µL", "Parasites; allergic/hypersensitivity reactions"],
["Basophils", "0.5-1%", "0-100/µL", "IgE-mediated allergy; heparin release"],
["Total WBC", "—", "4,500-11,000/µL", "Overall leukocyte burden"],
]
rows = [[Paragraph(h, CELL_HDR) for h in headers]]
bg_col = [HexColor("#EAF4FD"), HexColor("#F0FBF4"), HexColor("#FDF6E3"),
HexColor("#FDF0ED"), HexColor("#F3EDF7"), GREY_BG]
for i, row in enumerate(data):
bg = bg_col[i]
cells = [Paragraph(row[0], CELL_B)] + [Paragraph(c, CELL_S) for c in row[1:]]
rows.append(cells)
col_w = [42*mm, 30*mm, 32*mm, 76*mm]
tbl = Table(rows, colWidths=col_w, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LINEBELOW", (0,0), (-1,0), 1, DEEP_BLUE),
]))
return tbl
# ============================================================
# 3. ANEMIA CLASSIFICATION
# ============================================================
def anemia_table():
headers = ["Type", "MCV", "Common Causes", "Key Initial Test"]
data = [
["Microcytic", "< 80 fL",
"Iron deficiency, Thalassemia, Anemia of chronic disease (late), Sideroblastic",
"Serum Ferritin (<30 ng/mL = iron def.)"],
["Normocytic", "80-100 fL",
"Acute blood loss, Hemolysis, Renal failure (CKD), Early mixed deficiency, Aplastic anemia",
"Reticulocyte count, BMP, LFTs"],
["Macrocytic", "> 100 fL",
"B12 / Folate deficiency, Alcohol, Hypothyroidism, Meds (MTX, hydroxyurea, AZT)",
"B12, Folate, TFTs, peripheral smear"],
]
row_colors = [HexColor("#FDECEA"), HexColor("#EAF4FD"), HexColor("#F0FBF4")]
rows = [[Paragraph(h, CELL_HDR) for h in headers]]
for i, row in enumerate(data):
cells = [Paragraph(row[0], CELL_B),
Paragraph(row[1], FORMULA_S),
Paragraph(row[2], CELL_S),
Paragraph(row[3], CELL_S)]
rows.append(cells)
col_w = [25*mm, 18*mm, 72*mm, 65*mm]
tbl = Table(rows, colWidths=col_w, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("BACKGROUND", (0,1), (1,1), HexColor("#FDECEA")),
("BACKGROUND", (0,2), (1,2), HexColor("#EAF4FD")),
("BACKGROUND", (0,3), (1,3), HexColor("#F0FBF4")),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [HexColor("#FDECEA"), HexColor("#EAF4FD"), HexColor("#F0FBF4")]),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LINEBELOW", (0,0), (-1,0), 1, DEEP_BLUE),
]))
return tbl
# ============================================================
# 4. WBC ABNORMALITIES TABLE
# ============================================================
def wbc_abnorm_table():
headers = ["Finding", "Definition", "Common Causes"]
data = [
["Leukocytosis", "WBC > 11,000/µL",
"Bacterial infection, inflammation, steroids, stress, CML, leukemoid reaction"],
["Leukopenia", "WBC < 4,500/µL",
"Viral infections, medications, autoimmune, B12/folate deficiency, aplastic anemia"],
["Neutrophilia", "ANC > 7,000/µL",
"Bacterial infection, trauma, MI, burns, surgery, steroids, myeloproliferative disorders"],
["Neutropenia", "ANC < 1,500/µL (severe <500)",
"Chemotherapy/radiation, drug reaction (clozapine, carbimazole), viral infection, SLE, aplastic anemia"],
["Lymphocytosis", "Lymphs > 4,000/µL (adult)",
"Viral (EBV/CMV/hepatitis), CLL, ALL, pertussis, toxoplasmosis"],
["Lymphopenia", "Lymphs < 1,500/µL",
"HIV/AIDS, corticosteroids, immunosuppressants, radiation, autoimmune"],
["Eosinophilia", "Eos > 500/µL",
"Parasites (NAACP), atopy/asthma, drug hypersensitivity, Addison's, malignancy, vasculitis"],
["Monocytosis", "Monos > 800/µL",
"Chronic infections (TB, SBE), inflammatory bowel disease, myelomonocytic leukemia"],
["Basophilia", "Basos > 100/µL",
"CML (hallmark), myeloproliferative disorders, hypothyroidism, allergic states"],
]
rows = [[Paragraph(h, CELL_HDR) for h in headers]]
for i, row in enumerate(data):
cells = [Paragraph(row[0], CELL_B),
Paragraph(row[1], CELL_S),
Paragraph(row[2], CELL_S)]
rows.append(cells)
col_w = [33*mm, 42*mm, 105*mm]
tbl = Table(rows, colWidths=col_w, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LINEBELOW", (0,0), (-1,0), 1, DEEP_BLUE),
]))
return tbl
# ============================================================
# 5. PLATELET TABLE
# ============================================================
def platelet_table():
headers = ["Finding", "Count", "Decreased Production", "Increased Destruction / Sequestration"]
data = [
["Normal", "150-400 x10\u00b3/µL", "—", "—"],
["Mild Thrombocytopenia","100-149 x10\u00b3/µL", "Observe; low bleeding risk", "ITP (early)"],
["Moderate", "50-99 x10\u00b3/µL",
"B12/folate def., chemotherapy, alcohol",
"ITP, DIC, HIT, HUS/TTP, HELLP"],
["Severe", "< 50 x10\u00b3/µL",
"Aplastic anemia, leukemia, infiltration",
"Sepsis, massive transfusion, cardiopulmonary bypass"],
["Thrombocytosis", "> 400 x10\u00b3/µL",
"Reactive: infection, iron def., post-splenectomy",
"Primary: Essential thrombocythemia, PV, CML"],
]
rows = [[Paragraph(h, CELL_HDR) for h in headers]]
row_bgs = [HexColor("#E8F5E9"), HexColor("#FFF9C4"), HexColor("#FFE0B2"),
HexColor("#FFCDD2"), HexColor("#E3F2FD")]
for i, row in enumerate(data):
cells = [Paragraph(row[0], CELL_B)] + [Paragraph(c, CELL_S) for c in row[1:]]
rows.append(cells)
col_w = [33*mm, 30*mm, 54*mm, 63*mm]
tbl = Table(rows, colWidths=col_w, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [HexColor("#E8F5E9"), HexColor("#FFF9C4"),
HexColor("#FFE0B2"), HexColor("#FFCDD2"),
HexColor("#E3F2FD")]),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LINEBELOW", (0,0), (-1,0), 1, DEEP_BLUE),
]))
return tbl
# ============================================================
# 6. CLINICAL PEARLS (2-column layout)
# ============================================================
def pearls_block():
pearls = [
("ANC Formula",
"ANC = Total WBC x (% Segs + % Bands)\nSevere neutropenia: ANC < 500 — high infection risk"),
("Anemia in Acute Hemorrhage",
"Hb/Hct may be NORMAL initially (takes 12-24 h for plasma to equilibrate). Check reticulocytes + clinical context."),
("Left Shift",
"Increased bands/metamyelocytes in peripheral blood. Suggests active bacterial infection or sepsis. May correct the automated WBC count upward."),
("Pancytopenia",
"All 3 cell lines low. Consider: aplastic anemia, B12/folate def., hypersplenism, bone marrow infiltration, leukemia."),
("Reactive vs. Leukemic Leukocytosis",
"Leukemoid reaction (>50,000/µL) — check LAP score, BCR-ABL, and smear morphology. Blasts suggest leukemia."),
("Smear Indications",
"Order peripheral smear for: suspected hemolysis, RBC inclusions, blast cells, unexplained cytopenias, thrombocytopenia, myelodysplasia."),
("RDW Significance",
"Elevated RDW (>14.5%) = anisocytosis. Helps differentiate iron def. anemia (high RDW) from thalassemia trait (normal RDW, low MCV)."),
("Polycythemia Vera Clues",
"Elevated RBC + WBC + Platelets together. Check JAK2 V617F mutation. Erythropoietin level low (vs. secondary erythrocytosis)."),
]
rows = []
for i in range(0, len(pearls), 2):
left = pearls[i]
right = pearls[i+1] if i+1 < len(pearls) else ("", "")
left_cell = [
Paragraph(left[0], BOLD_S),
Paragraph(left[1].replace("\n", "<br/>"), SMALL_S)
]
right_cell = [
Paragraph(right[0], BOLD_S),
Paragraph(right[1].replace("\n", "<br/>"), SMALL_S)
] if right[0] else [Paragraph("", SMALL_S)]
rows.append([left_cell, right_cell])
# Flatten for Table
flat_rows = []
for row in rows:
flat_rows.append([row[0], row[1]])
# We can't put lists in Table cells — convert to nested tables
col_w_half = CONTENT_W / 2 - 2*mm
outer_rows = []
for row in rows:
left_tbl = Table([[c] for c in row[0]], colWidths=[col_w_half - 6*mm])
left_tbl.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 1),
("BOTTOMPADDING", (0,0), (-1,-1), 1),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
right_tbl = Table([[c] for c in row[1]], colWidths=[col_w_half - 6*mm])
right_tbl.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 1),
("BOTTOMPADDING", (0,0), (-1,-1), 1),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
outer_rows.append([left_tbl, right_tbl])
tbl = Table(outer_rows, colWidths=[col_w_half, col_w_half])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GREY_BG),
("ROWBACKGROUNDS",(0,0), (-1,-1), [GREY_BG, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, GREY_LINE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return tbl
# ============================================================
# 7. FOOTER
# ============================================================
def footer_block():
tbl = Table(
[[Paragraph(
"For educational reference only. Always interpret CBC in clinical context. "
"Reference ranges may vary by laboratory and patient age. "
"Sources: Textbook of Family Medicine 9e • Henry's Clinical Diagnosis & Management by Laboratory Methods • Junqueira's Basic Histology 17e",
NOTE_S)]],
colWidths=[CONTENT_W]
)
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), HexColor("#ECF0F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("LINEABOVE", (0,0), (-1,0), 1, GREY_LINE),
]))
return tbl
# ============================================================
# BUILD STORY
# ============================================================
story = []
# Title
story.append(title_block())
story.append(Spacer(1, 5*mm))
# 1. RBC Parameters
story.append(KeepTogether([
section_banner("1. RED BLOOD CELL (RBC) PARAMETERS"),
Spacer(1, 1.5*mm),
rbc_table(),
]))
story.append(Spacer(1, 4*mm))
# 2. WBC Differential
story.append(KeepTogether([
section_banner("2. WHITE BLOOD CELL (WBC) DIFFERENTIAL"),
Spacer(1, 1.5*mm),
wbc_table(),
]))
story.append(Spacer(1, 4*mm))
# 3. Anemia Classification
story.append(KeepTogether([
section_banner("3. ANEMIA CLASSIFICATION BY MCV", color=HexColor("#1A5276")),
Spacer(1, 1.5*mm),
anemia_table(),
Spacer(1, 1.5*mm),
Paragraph(
"<b>Tip:</b> In early anemia, MCV may change before Hb/Hct become abnormal. "
"Always check reticulocyte count to assess bone marrow response.",
NOTE_S
),
]))
story.append(Spacer(1, 4*mm))
# 4. WBC Abnormalities
story.append(section_banner("4. WBC ABNORMALITIES", color=HexColor("#6E2F82")))
story.append(Spacer(1, 1.5*mm))
story.append(wbc_abnorm_table())
story.append(Spacer(1, 4*mm))
# 5. Platelet Interpretation
story.append(KeepTogether([
section_banner("5. PLATELET INTERPRETATION", color=HexColor("#7D3C0A")),
Spacer(1, 1.5*mm),
platelet_table(),
Spacer(1, 1.5*mm),
Paragraph(
"<b>Bleeding risk:</b> Spontaneous bleeding rare with platelets >50,000; "
"major surgery safe >100,000; prophylactic transfusion threshold typically <10,000 (stable) or <20,000 (fever/active bleeding).",
NOTE_S
),
]))
story.append(Spacer(1, 4*mm))
# 6. Clinical Pearls
story.append(KeepTogether([
section_banner("6. CLINICAL PEARLS & INTERPRETATION TIPS", color=HexColor("#1A5C3A")),
Spacer(1, 1.5*mm),
pearls_block(),
]))
story.append(Spacer(1, 5*mm))
# Footer
story.append(footer_block())
# Build
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
cd /home/daytona/workspace/cbc-guide && python generate_cbc_pdf.py 2>&1
ls -lh /home/daytona/workspace/cbc-guide/CBC_Quick_Reference.pdf
python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/cbc-guide/CBC_Quick_Reference.pdf') print(f'Pages: {len(r.pages)}') for i,p in enumerate(r.pages): t = p.extract_text() print(f'--- Page {i+1} ({len(t)} chars) ---') print(t[:400]) print() "
python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/cbc-guide/CBC_Quick_Reference.pdf') for i,p in enumerate(r.pages): t = p.extract_text() print(f'--- Page {i+1} FULL ---') print(t) print() "
CBC Quick Reference
PDF Document · PDF
| Section | Content |
|---|---|
| 1. RBC Parameters | Hb, Hct, RBC count, MCV, MCH, MCHC, RDW, Reticulocytes with male/female/SI ranges |
| 2. WBC Differential | All 5 cell types with % ranges, absolute counts, and clinical roles |
| 3. Anemia by MCV | Micro/Normo/Macrocytic classification, causes, and first-line tests |
| 4. WBC Abnormalities | Leukocytosis, leukopenia, neutrophilia/penia, lymphocytosis/penia, eosinophilia, monocytosis, basophilia |
| 5. Platelet Interpretation | Severity grading from normal to severe thrombocytopenia + thrombocytosis, bleeding thresholds |
| 6. Clinical Pearls | ANC formula, acute hemorrhage caveat, left shift, pancytopenia, reactive vs. leukemic leukocytosis, smear indications, RDW significance, PV clues |