DIFFERENTIATE ITP VS LEUKEMIA IN PEADS SIMPLY. MAIN 15- 20 MUST KNOW POINTS WITH SUBHEADING ,CHUNKING, SIMPLE LANGUGE , MEDICAL WORD PRESERVED IN A PDF

Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Reading File
Finding Sources
Running Command

ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "workspace ready"

Running Command

mkdir -p /tmp/workspace/itp-vs-leukemia && python3 << 'PYEOF' 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.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, KeepTogether) from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from reportlab.platypus import PageBreak OUTPUT = "/tmp/workspace/itp-vs-leukemia/ITP_vs_Leukemia_Paeds.pdf" doc = SimpleDocTemplate( OUTPUT, pagesize=A4, rightMargin=18*mm, leftMargin=18*mm, topMargin=18*mm, bottomMargin=18*mm, title="ITP vs Leukemia in Paediatrics", author="Orris Medical Education" ) # ── Colour palette ───────────────────────────────────────────────────────── ITP_COL = colors.HexColor("#1565C0") # deep blue LEU_COL = colors.HexColor("#B71C1C") # deep red HEAD_BG = colors.HexColor("#E3F2FD") # light blue LEU_BG = colors.HexColor("#FFEBEE") # light red ALT_BLUE = colors.HexColor("#BBDEFB") ALT_RED = colors.HexColor("#FFCDD2") WHITE = colors.white BLACK = colors.black GOLD = colors.HexColor("#F57F17") DARK_GREY = colors.HexColor("#37474F") LIGHT_GREY= colors.HexColor("#ECEFF1") GREEN = colors.HexColor("#1B5E20") GREEN_BG = colors.HexColor("#E8F5E9") styles = getSampleStyleSheet() # ── Custom paragraph styles ──────────────────────────────────────────────── def make_style(name, **kw): return ParagraphStyle(name, **kw) TITLE_S = make_style("TitleS", fontSize=22, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=28) SUBTITLE_S = make_style("SubS", fontSize=12, fontName="Helvetica", textColor=colors.HexColor("#CFD8DC"), alignment=TA_CENTER, leading=16) SEC_HEAD = make_style("SecHead", fontSize=13, fontName="Helvetica-Bold", textColor=DARK_GREY, alignment=TA_CENTER, leading=18, spaceAfter=4) POINT_NUM = make_style("PointNum", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=14) ITP_CELL = make_style("ItpCell", fontSize=9.5, fontName="Helvetica", textColor=colors.HexColor("#0D47A1"), leading=13, alignment=TA_LEFT) LEU_CELL = make_style("LeuCell", fontSize=9.5, fontName="Helvetica", textColor=colors.HexColor("#B71C1C"), leading=13, alignment=TA_LEFT) FEAT_CELL = make_style("FeatCell", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=13, alignment=TA_LEFT) CAPTION = make_style("Caption", fontSize=7.5, fontName="Helvetica-Oblique", textColor=colors.grey, alignment=TA_CENTER) MNEMONIC = make_style("Mnem", fontSize=9, fontName="Helvetica-Bold", textColor=GREEN, leading=13) MNEM_TEXT = make_style("MnemT", fontSize=9, fontName="Helvetica", textColor=GREEN, leading=13) KEY_BOX = make_style("KeyBox", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=13, alignment=TA_JUSTIFY) FOOTER_S = make_style("FooterS", fontSize=7.5, fontName="Helvetica-Oblique", textColor=colors.grey, alignment=TA_CENTER) # ═══════════════════════════════════════════════════════════════════════════ # HELPER – build a colour banner paragraph inside a 1-cell table # ═══════════════════════════════════════════════════════════════════════════ def banner(text_style_pairs, bg, radius=6): """text_style_pairs = list of (text, style). Returns a Table acting as banner.""" paras = [Paragraph(t, s) for t, s in text_style_pairs] tbl = Table([[p] for p in paras], colWidths=[174*mm]) tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), bg), ("ROUNDEDCORNERS", [radius]), ("TOPPADDING", (0,0), (-1,-1), 8), ("BOTTOMPADDING",(0,0),(-1,-1), 8), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING",(0,0), (-1,-1), 10), ])) return tbl # ═══════════════════════════════════════════════════════════════════════════ # COMPARISON TABLE DATA (20 points) # ═══════════════════════════════════════════════════════════════════════════ points = [ # (No, Feature, ITP, Leukemia) ("1", "Full Name", "Immune Thrombocytopenic Purpura\n(also called ITP)", "Acute Lymphoblastic Leukemia\n(ALL) – most common type in kids"), ("2", "What Goes Wrong?", "Body makes antibodies that destroy its own platelets\n→ Platelet count falls", "Bone marrow makes too many abnormal white blood cells (blasts)\n→ Crowding out normal cells"), ("3", "Typical Age", "Peak age: 2–6 years\nBoth sexes equally affected", "Peak age: 2–5 years (ALL)\nSlightly more in boys"), ("4", "Trigger / Cause", "Usually follows a viral infection\n(URTI, varicella) 1–4 weeks before", "No clear trigger; genetic & environmental factors\n(e.g., Down syndrome = higher risk)"), ("5", "Onset", "SUDDEN – child healthy yesterday,\npetechiae appear overnight", "GRADUAL – weeks of fatigue, pallor,\nrecurrent infections before diagnosis"), ("6", "Bleeding Symptoms", "Petechiae, ecchymoses (bruising),\ngingival bleeding, epistaxis\n(nose bleeds), hematuria", "Bleeding can occur BUT is less prominent;\nbruising may be present"), ("7", "Systemic Symptoms\n(Fever, Weight loss)", "NO fever (unless concurrent viral illness)\nNo weight loss\nChild looks WELL", "YES – fever (recurrent/unexplained)\nNight sweats, weight loss\nChild looks SICK (pallor, lethargy)"), ("8", "Lymphadenopathy\n(Swollen lymph nodes)", "ABSENT\n(Big clue – no lymph node swelling in ITP)", "PRESENT – generalised lymphadenopathy;\ncervical, axillary, inguinal nodes enlarged"), ("9", "Splenomegaly\n(Enlarged spleen)", "Usually ABSENT\n(Up to 10% may have a just-palpable spleen tip)", "PRESENT – spleen often significantly enlarged\n(due to leukemic cell infiltration)"), ("10", "Hepatomegaly\n(Enlarged liver)", "ABSENT", "PRESENT – hepatomegaly common\n(hepatosplenomegaly = classic ALL finding)"), ("11", "Bone / Joint Pain", "ABSENT", "PRESENT – bone pain, limb pain, arthralgia\n(due to marrow infiltration with blasts)"), ("12", "Platelet Count\n(Thrombocytes)", "Very LOW (<20,000/µL in acute ITP)\nSometimes <10,000/µL", "LOW – but due to marrow failure,\nnot destruction of platelets"), ("13", "White Blood Cell\n(WBC / Leucocyte) Count", "NORMAL\nNo abnormal white cells", "Usually HIGH (hyperleukocytosis)\nOR very low; BLASTS seen on smear\n(Auer rods in AML, not ALL)"), ("14", "Haemoglobin /\nAnaemia", "NORMAL haemoglobin\n(only platelets affected)", "ANAEMIA present – pallor, fatigue\n(normocytic normochromic anaemia)"), ("15", "Peripheral Blood Smear", "Large immature platelets (megathrombocytes)\nAll other cell lines NORMAL\nNo blasts", "BLAST CELLS (lymphoblasts) seen\nAnaemia + thrombocytopenia +\nabnormal WBC = pancytopenia pattern"), ("16", "Bone Marrow Biopsy", "Normal / increased megakaryocytes\n(shows platelets ARE being made –\nthey are just being destroyed)\nNOT usually needed for diagnosis", "REQUIRED for diagnosis\nShows >20% blasts (FAB/WHO criteria)\nNormal marrow architecture replaced"), ("17", "LDH / Uric Acid", "NORMAL", "ELEVATED LDH and uric acid\n(markers of high cell turnover)"), ("18", "How Do We Diagnose?", "Clinical diagnosis (exclusion)\nFBC + peripheral smear sufficient\nBone marrow only if atypical features", "FBC + peripheral smear (blasts?)\n→ Bone marrow biopsy (definitive)\n→ Immunophenotyping (flow cytometry)\n→ Cytogenetics / molecular studies"), ("19", "Treatment", "Mild: Observe (most resolve in 6 months)\nModerate/Severe: Steroids (prednisolone),\nIVIG (IV immunoglobulin)\nSplenectomy (last resort, chronic ITP)", "Multi-drug chemotherapy:\nInduction → Consolidation → Maintenance\n(2–3 year protocol)\nSome need stem cell transplant"), ("20", "Prognosis", "EXCELLENT – 80–90% of children with\nacute ITP recover spontaneously\nwithin 6 months", "GOOD with treatment – 85–90% remission\nfor ALL in children\nWorst prognosis: T-ALL, high WBC, infant ALL"), ] # ═══════════════════════════════════════════════════════════════════════════ # BUILD STORY # ═══════════════════════════════════════════════════════════════════════════ story = [] # ── TITLE BANNER ─────────────────────────────────────────────────────────── title_data = [ [Paragraph("ITP vs LEUKEMIA IN PAEDIATRICS", TITLE_S)], [Paragraph("15–20 Must-Know Points | Simple Language | Medical Terms Preserved", SUBTITLE_S)], [Paragraph("A Clinical Comparison for Medical Students & House Officers", SUBTITLE_S)], ] title_tbl = Table(title_data, colWidths=[174*mm]) title_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 10), ("BOTTOMPADDING",(0,0), (-1,-1), 10), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) story.append(title_tbl) story.append(Spacer(1, 6*mm)) # ── QUICK DEFINITIONS BOX ────────────────────────────────────────────────── def_style = ParagraphStyle("DefS", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14, alignment=TA_LEFT) bold_s = ParagraphStyle("BoldS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=14) def_data = [ [Paragraph("QUICK DEFINITIONS", bold_s)], [Paragraph( "<b>ITP (Immune Thrombocytopenic Purpura):</b> An autoimmune condition where the body's own antibodies " "mistakenly destroy <b>platelets</b> (cells that help blood clot). Result: easy bleeding and bruising.", def_style)], [Paragraph( "<b>Leukemia (ALL – Acute Lymphoblastic Leukemia):</b> A cancer of the bone marrow where abnormal " "white blood cells called <b>lymphoblasts (blasts)</b> multiply uncontrollably, crowding out normal blood cells.", def_style)], [Paragraph( "<b>WHY CONFUSE THEM?</b> Both can present with low platelets and bleeding in a child → " "but they are completely different diseases with different management and outlook!", def_style)], ] def_tbl = Table(def_data, colWidths=[174*mm]) def_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING",(0,0), (-1,-1), 4), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING", (0,0), (-1,-1), 10), ("BOX", (0,0), (-1,-1), 1, DARK_GREY), ])) story.append(def_tbl) story.append(Spacer(1, 5*mm)) # ── COLUMN HEADERS ───────────────────────────────────────────────────────── hdr_style_feat = ParagraphStyle("HF", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) hdr_style_itp = ParagraphStyle("HI", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=15) hdr_style_leu = ParagraphStyle("HL", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=15) hdr_row = [ Paragraph("#", hdr_style_feat), Paragraph("FEATURE", hdr_style_feat), Paragraph("🔵 ITP\n(Immune Thrombocytopenic Purpura)", hdr_style_itp), Paragraph("🔴 LEUKEMIA\n(ALL – Acute Lymphoblastic Leukemia)", hdr_style_leu), ] COL_W = [10*mm, 35*mm, 62*mm, 67*mm] table_data = [hdr_row] for no, feat, itp_text, leu_text in points: # Alternate shading row_num = int(no) bg_itp = ALT_BLUE if row_num % 2 == 0 else HEAD_BG bg_leu = ALT_RED if row_num % 2 == 0 else LEU_BG num_p = Paragraph(f"<b>{no}</b>", POINT_NUM) feat_p = Paragraph(feat.replace("\n", "<br/>"), FEAT_CELL) itp_p = Paragraph(itp_text.replace("\n", "<br/>"), ITP_CELL) leu_p = Paragraph(leu_text.replace("\n", "<br/>"), LEU_CELL) table_data.append([num_p, feat_p, itp_p, leu_p]) main_table = Table(table_data, colWidths=COL_W, repeatRows=1) # Build row-level background commands ts_cmds = [ # Header row ("BACKGROUND", (0,0), (0,0), DARK_GREY), ("BACKGROUND", (1,0), (1,0), DARK_GREY), ("BACKGROUND", (2,0), (2,0), ITP_COL), ("BACKGROUND", (3,0), (3,0), LEU_COL), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING",(0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 5), ("RIGHTPADDING", (0,0), (-1,-1), 5), ("VALIGN", (0,0), (-1,-1), "TOP"), ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#B0BEC5")), ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_GREY, WHITE]), # fallback ] # Override per-row colours for i, (no, feat, itp_text, leu_text) in enumerate(points): row_num = int(no) r = i + 1 # row index in table (header = 0) bg_itp = ALT_BLUE if row_num % 2 == 0 else HEAD_BG bg_leu = ALT_RED if row_num % 2 == 0 else LEU_BG bg_num = colors.HexColor("#546E7A") if row_num % 2 == 0 else DARK_GREY ts_cmds += [ ("BACKGROUND", (0,r), (0,r), bg_num), ("BACKGROUND", (1,r), (1,r), LIGHT_GREY), ("BACKGROUND", (2,r), (2,r), bg_itp), ("BACKGROUND", (3,r), (3,r), bg_leu), ("TEXTCOLOR", (0,r), (0,r), WHITE), ] main_table.setStyle(TableStyle(ts_cmds)) story.append(main_table) story.append(Spacer(1, 6*mm)) # ═══════════════════════════════════════════════════════════════════════════ # PAGE 2 – MEMORY AIDS + KEY RULES + SUMMARY # ═══════════════════════════════════════════════════════════════════════════ story.append(PageBreak()) # ── Section title ────────────────────────────────────────────────────────── sec_tbl = Table([[Paragraph("MEMORY AIDS & CLINICAL PEARLS", SEC_HEAD)]], colWidths=[174*mm]) sec_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 8), ("BOTTOMPADDING",(0,0), (-1,-1), 8), ("TEXTCOLOR", (0,0), (-1,-1), WHITE), ])) story.append(sec_tbl) story.append(Spacer(1, 4*mm)) # ── ITP Mnemonic ─────────────────────────────────────────────────────────── mnem_itp_data = [ [Paragraph('ITP = "I\'m The Patient – I\'m Fine!"', ParagraphStyle("MH", fontSize=11, fontName="Helvetica-Bold", textColor=ITP_COL, leading=14))], [Paragraph( "The child with ITP looks <b>WELL</b> despite scary-looking bruises/petechiae.<br/>" "• <b>I</b>solated low platelets (only platelet line affected)<br/>" "• <b>T</b>rigger = recent viral illness<br/>" "• <b>P</b>etechiae + ecchymoses, NO lymphadenopathy, NO hepatosplenomegaly", ParagraphStyle("MI", fontSize=9.5, fontName="Helvetica", textColor=ITP_COL, leading=14))], ] mnem_itp = Table(mnem_itp_data, colWidths=[84*mm]) mnem_itp.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), HEAD_BG), ("BOX", (0,0), (-1,-1), 1.5, ITP_COL), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING",(0,0), (-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) # ── Leukemia Mnemonic ────────────────────────────────────────────────────── mnem_leu_data = [ [Paragraph('ALL = "All Looks Lost"', ParagraphStyle("MH2", fontSize=11, fontName="Helvetica-Bold", textColor=LEU_COL, leading=14))], [Paragraph( "The child with ALL looks <b>SICK</b>.<br/>" "• <b>A</b>naemia (pallor, fatigue) + bone pain<br/>" "• <b>L</b>ymphadenopathy + hepatosplenomegaly<br/>" "• <b>L</b>eukocytosis with BLASTS on blood smear", ParagraphStyle("ML", fontSize=9.5, fontName="Helvetica", textColor=LEU_COL, leading=14))], ] mnem_leu = Table(mnem_leu_data, colWidths=[84*mm]) mnem_leu.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LEU_BG), ("BOX", (0,0), (-1,-1), 1.5, LEU_COL), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING",(0,0), (-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) mnem_outer = Table([[mnem_itp, Paragraph("", styles["Normal"]), mnem_leu]], colWidths=[84*mm, 6*mm, 84*mm]) mnem_outer.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 0), ("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0), ])) story.append(mnem_outer) story.append(Spacer(1, 5*mm)) # ── 5 GOLDEN RULES ───────────────────────────────────────────────────────── rule_head = ParagraphStyle("RH", fontSize=10.5, fontName="Helvetica-Bold", textColor=GOLD, leading=14) rule_body = ParagraphStyle("RB", fontSize=9.5, fontName="Helvetica", textColor=DARK_GREY, leading=14) rules = [ ("Rule 1 – Sick vs. Well", "ITP child = <b>looks well</b>. Leukemia child = <b>looks sick</b>. This single bedside impression is the most powerful differentiator."), ("Rule 2 – Organ Enlargement", "<b>Hepatosplenomegaly + lymphadenopathy</b> = NEVER ITP. Always suspect leukemia or lymphoma."), ("Rule 3 – Peripheral Smear First", "Order a <b>peripheral blood smear</b> in every child with unexplained thrombocytopenia. Blasts = leukemia until proven otherwise."), ("Rule 4 – Isolated vs. Pancytopenia", "ITP = <b>isolated thrombocytopenia</b>. Leukemia = often <b>pancytopenia</b> (low RBC + low WBC + low platelets all at once)."), ("Rule 5 – Bone Pain = Red Flag", "Any child with thrombocytopenia + <b>bone/joint pain</b> → bone marrow biopsy mandatory. This is NOT ITP."), ] rules_data = [] for title, body in rules: rules_data.append([ Paragraph(title, rule_head), Paragraph(body, rule_body) ]) rules_tbl = Table(rules_data, colWidths=[48*mm, 126*mm]) rules_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), GREEN_BG), ("BOX", (0,0), (-1,-1), 1.5, GREEN), ("LINEBELOW", (0,0), (-1,-4), 0.5, colors.HexColor("#A5D6A7")), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING",(0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) golden_header = Table([[Paragraph("5 GOLDEN CLINICAL RULES", ParagraphStyle( "GH", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) golden_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), GREEN), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(golden_header) story.append(rules_tbl) story.append(Spacer(1, 5*mm)) # ── QUICK LAB CHEAT SHEET ───────────────────────────────────────────────── lab_head_s = ParagraphStyle("LH", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) lab_feat_s = ParagraphStyle("LF", fontSize=9, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=12) lab_itp_s = ParagraphStyle("LI", fontSize=9, fontName="Helvetica", textColor=ITP_COL, leading=12) lab_leu_s = ParagraphStyle("LL", fontSize=9, fontName="Helvetica", textColor=LEU_COL, leading=12) lab_rows = [ [Paragraph("Lab Test", lab_head_s), Paragraph("ITP", lab_head_s), Paragraph("Leukemia (ALL)", lab_head_s)], [Paragraph("Platelet count", lab_feat_s), Paragraph("Very Low (<20,000/µL)", lab_itp_s), Paragraph("Low (marrow failure)", lab_leu_s)], [Paragraph("WBC (White Blood Cells)", lab_feat_s), Paragraph("NORMAL", lab_itp_s), Paragraph("High/Low + BLASTS seen", lab_leu_s)], [Paragraph("Haemoglobin", lab_feat_s), Paragraph("NORMAL", lab_itp_s), Paragraph("LOW (anaemia)", lab_leu_s)], [Paragraph("Peripheral smear", lab_feat_s), Paragraph("Large platelets only", lab_itp_s), Paragraph("Blast cells (lymphoblasts)", lab_leu_s)], [Paragraph("Bone marrow", lab_feat_s), Paragraph("↑ Megakaryocytes\n(usually not needed)", lab_itp_s), Paragraph(">20% blasts\n(DIAGNOSTIC)", lab_leu_s)], [Paragraph("LDH / Uric Acid", lab_feat_s), Paragraph("Normal", lab_itp_s), Paragraph("Elevated (tumour lysis markers)", lab_leu_s)], [Paragraph("Coagulation (PT/APTT)", lab_feat_s), Paragraph("Normal", lab_itp_s), Paragraph("Usually normal (unless DIC)", lab_leu_s)], ] lab_tbl = Table(lab_rows, colWidths=[50*mm, 58*mm, 66*mm]) lab_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), DARK_GREY), ("BACKGROUND", (0,1), (-1,1), HEAD_BG), ("BACKGROUND", (0,2), (-1,2), LEU_BG), ("BACKGROUND", (0,3), (-1,3), HEAD_BG), ("BACKGROUND", (0,4), (-1,4), LEU_BG), ("BACKGROUND", (0,5), (-1,5), HEAD_BG), ("BACKGROUND", (0,6), (-1,6), LEU_BG), ("BACKGROUND", (0,7), (-1,7), HEAD_BG), ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#90A4AE")), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING",(0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 6), ("RIGHTPADDING", (0,0), (-1,-1), 6), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ])) lab_header = Table([[Paragraph("QUICK LAB CHEAT SHEET", ParagraphStyle( "LABH", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) lab_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#4527A0")), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(lab_header) story.append(lab_tbl) story.append(Spacer(1, 5*mm)) # ── TREATMENT SUMMARY SIDE-BY-SIDE ──────────────────────────────────────── treat_head = ParagraphStyle("TRH", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) treat_body = ParagraphStyle("TRB", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=13) itp_treat = [ [Paragraph("ITP TREATMENT", treat_head)], [Paragraph( "• <b>Mild</b> (platelets >30,000, no major bleed): Watchful waiting<br/>" "• <b>Moderate/Severe</b>: Prednisolone (steroid) orally<br/>" "• <b>Rapid response needed</b>: IVIG (Intravenous Immunoglobulin)<br/>" "• <b>Anti-D immunoglobulin</b>: Rh+ve children<br/>" "• <b>Chronic ITP</b>: Rituximab, TPO-RA, or Splenectomy<br/>" "• <b>Goal</b>: Prevent serious bleeding (especially intracranial)<br/>" "• Most children <b>recover spontaneously</b> in 6 months", treat_body)], ] itp_treat_tbl = Table(itp_treat, colWidths=[84*mm]) itp_treat_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (0,0), ITP_COL), ("BACKGROUND", (0,1), (0,1), HEAD_BG), ("BOX", (0,0), (-1,-1), 1.5, ITP_COL), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) leu_treat = [ [Paragraph("LEUKEMIA (ALL) TREATMENT", treat_head)], [Paragraph( "• <b>Induction Phase</b> (1 month): Kill blast cells fast<br/>" "&nbsp;&nbsp;– Vincristine + Dexamethasone + L-Asparaginase<br/>" "• <b>Consolidation</b> (weeks): Prevent relapse<br/>" "• <b>Maintenance</b> (2–3 years): Oral methotrexate + 6-MP<br/>" "• <b>CNS prophylaxis</b>: IT (intrathecal) chemotherapy<br/>" "• <b>High-risk</b>: Stem cell transplant (HSCT)<br/>" "• Regular monitoring for <b>tumour lysis syndrome</b> (TLS)", treat_body)], ] leu_treat_tbl = Table(leu_treat, colWidths=[84*mm]) leu_treat_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (0,0), LEU_COL), ("BACKGROUND", (0,1), (0,1), LEU_BG), ("BOX", (0,0), (-1,-1), 1.5, LEU_COL), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) treat_outer = Table([[itp_treat_tbl, Paragraph("", styles["Normal"]), leu_treat_tbl]], colWidths=[84*mm, 6*mm, 84*mm]) treat_outer.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 0), ("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0), ])) treat_banner = Table([[Paragraph("TREATMENT SUMMARY", ParagraphStyle( "TRBAN", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) treat_banner.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(treat_banner) story.append(treat_outer) story.append(Spacer(1, 5*mm)) # ── FOOTER NOTE ──────────────────────────────────────────────────────────── footer_data = [[Paragraph( "Sources: Schwartz's Principles of Surgery 11e | Symptom to Diagnosis 4e | ROSEN's Emergency Medicine | " "Goldman-Cecil Medicine | Roitt's Essential Immunology • Compiled by Orris Medical AI | August 2026", FOOTER_S)]] footer_tbl = Table(footer_data, colWidths=[174*mm]) footer_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING",(0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("BOX", (0,0), (-1,-1), 0.5, colors.grey), ])) story.append(footer_tbl) # ── BUILD PDF ────────────────────────────────────────────────────────────── doc.build(story) print(f"PDF created: {OUTPUT}") PYEOF

Your PDF is ready! Here is your download link:

ITP vs Leukemia Paeds

PDF Document · PDF


What's Inside the PDF (2 Pages, 20 Points)

Page 1 - Main Comparison Table (20 Points)

#FeatureITPLeukemia (ALL)
1Full NameImmune Thrombocytopenic PurpuraAcute Lymphoblastic Leukemia
2What Goes Wrong?Antibodies destroy plateletsBone marrow makes blast cells
3Typical AgePeak 2-6 yrsPeak 2-5 yrs
4Trigger/CausePost-viral (URTI, varicella)No clear trigger; Down syndrome risk
5OnsetSUDDEN (overnight)GRADUAL (weeks)
6Bleeding SymptomsPetechiae, ecchymoses, epistaxisBleeding less prominent
7Systemic SymptomsNO fever, NO weight loss - child looks WELLFever, weight loss - child looks SICK
8LymphadenopathyABSENTPRESENT (generalised)
9SplenomegalyUsually ABSENTPRESENT (infiltration)
10HepatomegalyABSENTPRESENT
11Bone/Joint PainABSENTPRESENT (marrow infiltration)
12Platelet CountVery low (<20,000/µL)Low (marrow failure)
13WBC CountNORMALHigh/low + BLASTS on smear
14HaemoglobinNORMALLOW (anaemia)
15Peripheral SmearLarge platelets, no blastsBLAST CELLS - pancytopenia pattern
16Bone MarrowIncreased megakaryocytes (NOT usually needed)>20% blasts - DIAGNOSTIC
17LDH/Uric AcidNORMALELEVATED
18DiagnosisClinical exclusion + FBC + smearBone marrow biopsy + immunophenotyping
19TreatmentObserve/Steroids/IVIG/SplenectomyChemo: Induction + Consolidation + Maintenance
20Prognosis80-90% resolve in 6 months85-90% remission with treatment

Page 2 - Memory Aids + Clinical Pearls

  • ITP mnemonic - "I'm The Patient - I'm Fine!" (child looks well)
  • ALL mnemonic - "All Looks Lost" (anaemia + lymphadenopathy + leukocytosis with blasts)
  • 5 Golden Clinical Rules (Sick vs. Well, organ enlargement, peripheral smear, isolated vs. pancytopenia, bone pain red flag)
  • Quick Lab Cheat Sheet (platelet, WBC, Hb, smear, bone marrow, LDH side by side)
  • Treatment Summary side-by-side for both conditions
  • Source citations at the bottom

DO THE SAME TO IDA VS THALASSEMIA IN PEADS. BUT DO CHUNKING IN 20 POINTS BUT CATEGORIZE IT UNDER SOME HEADING ,GENERATE PDF THE SAME WAY

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Running Command

mkdir -p /tmp/workspace/ida-vs-thalassemia && python3 << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, KeepTogether) from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY OUTPUT = "/tmp/workspace/ida-vs-thalassemia/IDA_vs_Thalassemia_Paeds.pdf" doc = SimpleDocTemplate( OUTPUT, pagesize=A4, rightMargin=18*mm, leftMargin=18*mm, topMargin=18*mm, bottomMargin=18*mm, title="IDA vs Thalassemia in Paediatrics", author="Orris Medical Education" ) # ── Colour palette ───────────────────────────────────────────────────────── IDA_COL = colors.HexColor("#1B5E20") # deep green (IDA) THAL_COL = colors.HexColor("#4A148C") # deep purple (Thalassemia) IDA_BG = colors.HexColor("#E8F5E9") # light green THAL_BG = colors.HexColor("#EDE7F6") # light purple IDA_MID = colors.HexColor("#C8E6C9") # mid green THAL_MID = colors.HexColor("#D1C4E9") # mid purple WHITE = colors.white BLACK = colors.black DARK_GREY = colors.HexColor("#263238") LIGHT_GREY = colors.HexColor("#ECEFF1") GOLD = colors.HexColor("#F57F17") GREEN_DARK = colors.HexColor("#1B5E20") ORANGE_BG = colors.HexColor("#FFF3E0") ORANGE_COL = colors.HexColor("#E65100") TEAL = colors.HexColor("#006064") TEAL_BG = colors.HexColor("#E0F7FA") def mstyle(name, **kw): return ParagraphStyle(name, **kw) TITLE_S = mstyle("TS", fontSize=22, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=28) SUBT_S = mstyle("SS", fontSize=11, fontName="Helvetica", textColor=colors.HexColor("#CFD8DC"), alignment=TA_CENTER, leading=15) FEAT_S = mstyle("FS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=13, alignment=TA_LEFT) IDA_S = mstyle("IS", fontSize=9.5, fontName="Helvetica", textColor=IDA_COL, leading=13, alignment=TA_LEFT) THAL_S = mstyle("ThS", fontSize=9.5, fontName="Helvetica", textColor=THAL_COL, leading=13, alignment=TA_LEFT) NUM_S = mstyle("NS", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=14) HDR_S = mstyle("HS", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) CAT_S = mstyle("CS", fontSize=10.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=14) DEF_S = mstyle("DS", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14, alignment=TA_LEFT) BOLD_S = mstyle("BS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=14) FOOT_S = mstyle("FoS", fontSize=7.5, fontName="Helvetica-Oblique", textColor=colors.grey, alignment=TA_CENTER) COL_W = [8*mm, 10*mm, 35*mm, 60*mm, 61*mm] # #, Cat#, Feature, IDA, Thalassemia # ═══════════════════════════════════════════════════════════════════════════ # 20 COMPARISON POINTS – CATEGORISED # ═══════════════════════════════════════════════════════════════════════════ # Category labels (point ranges) # A – BASIC SCIENCE (1–3) # B – CLINICAL FEATURES (4–8) # C – LABORATORY FINDINGS (9–14) # D – DIAGNOSIS (15–16) # E – TREATMENT & PROGNOSIS (17–20) CAT_A = colors.HexColor("#01579B") # blue CAT_B = colors.HexColor("#880E4F") # pink/maroon CAT_C = colors.HexColor("#4A148C") # purple CAT_D = colors.HexColor("#006064") # teal CAT_E = colors.HexColor("#1B5E20") # green points = [ # (global_no, cat_label, cat_colour, cat_bg, feature, IDA_text, THAL_text) # ── CATEGORY A: BASIC SCIENCE ────────────────────────────────────────── ("1", "A", CAT_A, colors.HexColor("#E3F2FD"), "Full Name", "Iron Deficiency Anaemia (IDA)\n= Low iron → can't make enough Hb", "Thalassaemia\n= Genetic defect in globin chain production\n(β-Thalassaemia most common in paeds)"), ("2", "A", CAT_A, colors.HexColor("#E3F2FD"), "Root Cause\n(Pathophysiology)", "NUTRITIONAL / ACQUIRED\n• Inadequate dietary iron intake\n• OR chronic blood loss (e.g. hookworm)\n→ Not enough iron to synthesise haem", "GENETIC / HEREDITARY\n• Mutation in β-globin gene (chromosome 11)\n• Defective or absent β-globin chains\n→ Unpaired α-chains → toxic → RBC destruction"), ("3", "A", CAT_A, colors.HexColor("#E3F2FD"), "Inheritance", "NOT inherited\n(Acquired nutritional disorder)\nCommon in weaning-age infants", "Autosomal Recessive\n• Both parents must be carriers (trait)\n• β-Thal Major: homozygous (β⁰/β⁰ or β⁺/β⁺)\n• β-Thal Minor: heterozygous (carrier, often asymptomatic)"), # ── CATEGORY B: CLINICAL FEATURES ───────────────────────────────────── ("4", "B", CAT_B, colors.HexColor("#FCE4EC"), "Typical Age of\nPresentation", "6 months – 2 years\n(peak weaning age, cow's milk diet)\nAlso older children with poor diet", "β-Thal MAJOR: 6 months – 2 years\n(as HbF falls, HbA rises → symptoms emerge)\nβ-Thal Minor: often found incidentally"), ("5", "B", CAT_B, colors.HexColor("#FCE4EC"), "General Appearance /\nChild's Condition", "Usually looks MILDLY unwell\nPallor, fatigue, irritability\nChild may be active despite low Hb", "β-Thal Major: looks SEVERELY SICK\nPallor, jaundice (haemolysis), growth failure\nFacies changes in severe/untreated cases"), ("6", "B", CAT_B, colors.HexColor("#FCE4EC"), "Specific Clinical Signs", "• Pallor (conjunctiva, palms, tongue)\n• Koilonychia (spoon-shaped nails)\n• Angular cheilitis (mouth corners)\n• Pica (eating non-food items: clay, ice)\n• Glossitis (smooth red tongue)", "• Pallor + jaundice (scleral icterus)\n• Frontal bossing (prominent forehead)\n• Maxillary overgrowth → 'chipmunk face'\n• Hepatosplenomegaly (massive)\n• Growth retardation"), ("7", "B", CAT_B, colors.HexColor("#FCE4EC"), "Splenomegaly /\nOrgan Enlargement", "ABSENT\n(or minimal in severe chronic IDA)\nNo hepatosplenomegaly expected", "PROMINENT in β-Thal Major\nMassive splenomegaly (extramedullary haematopoiesis)\nHepatomegaly also present"), ("8", "B", CAT_B, colors.HexColor("#FCE4EC"), "Jaundice", "ABSENT\n(IDA is not a haemolytic condition;\nred cells are just small, not being destroyed rapidly)", "PRESENT in β-Thal Major\nChronic haemolysis → unconjugated hyperbilirubinaemia\n→ mild to moderate jaundice"), # ── CATEGORY C: LABORATORY FINDINGS ─────────────────────────────────── ("9", "C", CAT_C, colors.HexColor("#EDE7F6"), "Haemoglobin (Hb)", "LOW\n(can be severely low in prolonged IDA)\nGradual decline", "LOW in β-Thal Major (often <7 g/dL)\nBeta-Thal Minor: mildly low or normal"), ("10", "C", CAT_C, colors.HexColor("#EDE7F6"), "MCV\n(Mean Cell Volume)", "LOW (microcytic)\nBUT correlates with degree of iron depletion\nRDW ↑ (mixed cell sizes)", "LOW (microcytic)\nSometimes LOWER than in IDA for the same Hb level\nRDW normal or mildly ↑\n→ Mentzer Index helps distinguish (see below)"), ("11", "C", CAT_C, colors.HexColor("#EDE7F6"), "MCH / MCHC\n(Colour of RBCs)", "LOW MCH + LOW MCHC\n= Hypochromic (pale red cells)\nClassic microcytic hypochromic picture", "LOW MCH + LOW MCHC\n= Also hypochromic\n(same morphology – this is why they are confused!)"), ("12", "C", CAT_C, colors.HexColor("#EDE7F6"), "RDW\n(Red Cell Distribution Width)", "HIGH (↑ RDW)\nAnisocytosis – cells of varying sizes\n(iron coming in irregularly)", "NORMAL or slightly ↑\nRDW relatively lower than IDA\nMentzer Index: MCV ÷ RBC count\n <13 = Thalassaemia | >13 = IDA"), ("13", "C", CAT_C, colors.HexColor("#EDE7F6"), "Iron Studies\n(Serum Ferritin,\nSerum Iron, TIBC)", "• Serum Ferritin: LOW ↓\n• Serum Iron: LOW ↓\n• TIBC (Total Iron Binding Capacity): HIGH ↑\n• Transferrin saturation: LOW ↓", "• Serum Ferritin: NORMAL or HIGH ↑\n (due to haemolysis + transfusions)\n• Serum Iron: NORMAL or HIGH\n• TIBC: NORMAL\nIron stores are NOT depleted in thalassaemia!"), ("14", "C", CAT_C, colors.HexColor("#EDE7F6"), "Peripheral Blood Smear\n(PBS)", "• Microcytes + hypochromic cells\n• Pencil cells (elliptocytes)\n• Anisocytosis + poikilocytosis\n• NO target cells (or rare)", "• Microcytes + hypochromic cells\n• TARGET CELLS (codocytes) prominent\n• Teardrop cells, nucleated RBCs\n• Anisocytosis + poikilocytosis\n• Basophilic stippling"), # ── CATEGORY D: DIAGNOSIS ────────────────────────────────────────────── ("15", "D", CAT_D, colors.HexColor("#E0F7FA"), "Definitive Diagnostic\nTest", "Serum FERRITIN\n(best single test for iron stores)\nAlso: serum iron + TIBC\n→ Response to iron therapy also confirms diagnosis", "Haemoglobin ELECTROPHORESIS\n• β-Thal Minor: ↑ HbA2 (>3.5%) + ↑ HbF\n• β-Thal Major: absent/minimal HbA; high HbF\nAlso: DNA molecular testing for mutation"), ("16", "D", CAT_D, colors.HexColor("#E0F7FA"), "Bone Marrow /\nOther Findings", "Bone marrow: ↑ normoblasts, absent iron stores\n(stainable iron = zero)\nRarely needed for diagnosis", "Bone marrow: Erythroid hyperplasia\n(marrow tries to compensate)\nSkeletal X-ray: 'hair-on-end' pattern on skull\n(expanded marrow space → classic sign)"), # ── CATEGORY E: TREATMENT & PROGNOSIS ───────────────────────────────── ("17", "E", CAT_E, colors.HexColor("#E8F5E9"), "Primary Treatment", "ORAL IRON SUPPLEMENTATION\n• Ferrous sulphate 3–6 mg/kg/day elemental iron\n• For 3–4 months (even after Hb normalises,\n to replenish stores)\n• Dietary advice: iron-rich foods, vitamin C", "β-THAL MAJOR:\n• Regular BLOOD TRANSFUSIONS (every 3–4 wks)\n → Target Hb pre-transfusion >9–10 g/dL\n• IRON CHELATION (deferoxamine / deferasirox)\n to prevent iron overload from transfusions\nβ-THAL MINOR: No treatment needed"), ("18", "E", CAT_E, colors.HexColor("#E8F5E9"), "Curative Option", "CURE: Just give iron!\n(Replenish stores, treat underlying cause)\nNo bone marrow transplant needed", "DEFINITIVE CURE:\nAllogeneic Haematopoietic Stem Cell\nTransplantation (HSCT / BMT)\n→ Best outcome if done early in life\n→ Matched sibling donor preferred"), ("19", "E", CAT_E, colors.HexColor("#E8F5E9"), "Monitoring During\nTreatment", "• Hb rises ~1–2 g/dL per week\n• Reticulocyte count rises in 1st week\n (early response indicator)\n• Repeat ferritin after 3 months\n• Hb should normalise in 6–8 weeks", "• Pre-transfusion Hb monitoring\n• Serum FERRITIN every 3 months\n (monitor iron overload)\n• Echo + liver MRI (iron deposition)\n• Endocrine function (diabetes, hypothyroid)\n• Ophthalmology (deferoxamine toxicity)"), ("20", "E", CAT_E, colors.HexColor("#E8F5E9"), "Prognosis", "EXCELLENT\n• Fully reversible with adequate iron\n• No long-term sequelae if treated early\n• Developmental delay if prolonged severe IDA", "β-Thal Minor: Normal life expectancy\nβ-Thal Major (untreated): Death in childhood\nWith good transfusion + chelation:\n→ Survival into 3rd–4th decade\nWith successful HSCT: near-normal life span"), ] # ═══════════════════════════════════════════════════════════════════════════ # BUILD STORY # ═══════════════════════════════════════════════════════════════════════════ story = [] # ── TITLE BANNER ─────────────────────────────────────────────────────────── title_data = [ [Paragraph("IDA vs THALASSAEMIA IN PAEDIATRICS", TITLE_S)], [Paragraph("20 Must-Know Points | Categorised & Chunked | Simple Language | Medical Terms Preserved", SUBT_S)], [Paragraph("A Clinical Comparison for Medical Students & House Officers", SUBT_S)], ] title_tbl = Table(title_data, colWidths=[174*mm]) title_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 10), ("BOTTOMPADDING", (0,0), (-1,-1), 10), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) story.append(title_tbl) story.append(Spacer(1, 5*mm)) # ── QUICK DEFINITIONS ───────────────────────────────────────────────────── def_data = [ [Paragraph("QUICK DEFINITIONS", BOLD_S)], [Paragraph( "<b>IDA (Iron Deficiency Anaemia):</b> The most common anaemia in children worldwide. " "The body does not have enough iron to make adequate <b>haemoglobin (Hb)</b>. " "Caused by poor diet, rapid growth demands, or blood loss. Fully curable with iron.", DEF_S)], [Paragraph( "<b>Thalassaemia:</b> A group of <b>inherited (genetic)</b> blood disorders where the body " "makes abnormal or insufficient globin chains (part of haemoglobin). β-Thalassaemia Major is the most severe " "paediatric form. Requires lifelong transfusions or bone marrow transplant.", DEF_S)], [Paragraph( "<b>WHY CONFUSE THEM?</b> Both give <b>microcytic hypochromic anaemia</b> on FBC " "→ small, pale red cells. The peripheral smear looks similar at first glance. " "But causes, severity, management, and prognosis are completely different!", DEF_S)], ] def_tbl = Table(def_data, colWidths=[174*mm]) def_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 4), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING", (0,0), (-1,-1), 10), ("BOX", (0,0), (-1,-1), 1, DARK_GREY), ])) story.append(def_tbl) story.append(Spacer(1, 5*mm)) # ── CATEGORY LEGEND ─────────────────────────────────────────────────────── leg_s = mstyle("LS", fontSize=8.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) leg_labels = [ (CAT_A, "A Basic Science\n(1–3)"), (CAT_B, "B Clinical Features\n(4–8)"), (CAT_C, "C Lab Findings\n(9–14)"), (CAT_D, "D Diagnosis\n(15–16)"), (CAT_E, "E Treatment &\nPrognosis (17–20)"), ] leg_row = [[Paragraph(txt, leg_s) for _, txt in leg_labels]] leg_tbl = Table(leg_row, colWidths=[34*mm]*5) leg_cmds = [ ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3), ("GRID", (0,0), (-1,-1), 0.5, WHITE), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ] for i, (col, _) in enumerate(leg_labels): leg_cmds.append(("BACKGROUND", (i,0), (i,0), col)) leg_tbl.setStyle(TableStyle(leg_cmds)) legend_header = Table([[Paragraph("CATEGORY LEGEND", mstyle("LHDR", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) legend_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ])) story.append(legend_header) story.append(leg_tbl) story.append(Spacer(1, 4*mm)) # ── COLUMN HEADER ROW ───────────────────────────────────────────────────── hdr_row = [ Paragraph("#", HDR_S), Paragraph("Cat", HDR_S), Paragraph("FEATURE", HDR_S), Paragraph("🟢 IDA\n(Iron Deficiency Anaemia)", HDR_S), Paragraph("🟣 THALASSAEMIA\n(β-Thalassaemia)", HDR_S), ] table_data = [hdr_row] # Track category boundaries for separator rows prev_cat = None for no, cat, cat_col, cat_bg, feat, ida_txt, thal_txt in points: # Insert category separator row when category changes if cat != prev_cat: cat_names = { "A": "A — BASIC SCIENCE", "B": "B — CLINICAL FEATURES", "C": "C — LABORATORY FINDINGS", "D": "D — DIAGNOSIS", "E": "E — TREATMENT & PROGNOSIS", } cat_row = [Paragraph(cat_names[cat], mstyle( f"CR{cat}", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT, leading=13))] table_data.append(["CAT_ROW", cat, cat_col, cat_names[cat]]) prev_cat = cat num_p = Paragraph(f"<b>{no}</b>", NUM_S) cat_p = Paragraph(f"<b>{cat}</b>", mstyle(f"CP{no}", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13)) feat_p = Paragraph(feat.replace("\n", "<br/>"), FEAT_S) ida_p = Paragraph(ida_txt.replace("\n", "<br/>"), IDA_S) thal_p = Paragraph(thal_txt.replace("\n", "<br/>"), THAL_S) table_data.append([num_p, cat_p, feat_p, ida_p, thal_p]) # Build the table with category separators properly # We need to reconstruct table_data as actual row lists final_data = [hdr_row] prev_cat2 = None cat_row_indices = [] # track which rows are category separators for no, cat, cat_col, cat_bg, feat, ida_txt, thal_txt in points: if cat != prev_cat2: cat_names = { "A": "CATEGORY A — BASIC SCIENCE (How Does the Disease Arise?)", "B": "CATEGORY B — CLINICAL FEATURES (What Does the Child Look Like?)", "C": "CATEGORY C — LABORATORY FINDINGS (What Do Tests Show?)", "D": "CATEGORY D — DIAGNOSIS (How Do We Confirm It?)", "E": "CATEGORY E — TREATMENT & PROGNOSIS (What Do We Do?)", } cat_row = [Paragraph(cat_names[cat], mstyle( f"CR{cat}", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT, leading=13)), None, None, None, None] cat_row_indices.append((len(final_data), cat_col)) final_data.append(cat_row) prev_cat2 = cat num_p = Paragraph(f"<b>{no}</b>", NUM_S) cat_p = Paragraph(f"<b>{cat}</b>", mstyle(f"CP{no}", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12)) feat_p = Paragraph(feat.replace("\n", "<br/>"), FEAT_S) ida_p = Paragraph(ida_txt.replace("\n", "<br/>"), IDA_S) thal_p = Paragraph(thal_txt.replace("\n", "<br/>"), THAL_S) final_data.append([num_p, cat_p, feat_p, ida_p, thal_p]) main_tbl = Table(final_data, colWidths=COL_W, repeatRows=1) ts = [ # Header ("BACKGROUND", (0,0), (-1,0), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 4), ("RIGHTPADDING", (0,0), (-1,-1), 4), ("VALIGN", (0,0), (-1,-1), "TOP"), ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#B0BEC5")), ] # Category separator rows styling for row_idx, cat_col in cat_row_indices: ts += [ ("BACKGROUND", (0, row_idx), (-1, row_idx), cat_col), ("SPAN", (0, row_idx), (-1, row_idx)), ("TOPPADDING", (0, row_idx), (-1, row_idx), 5), ("BOTTOMPADDING",(0,row_idx), (-1, row_idx), 5), ("LEFTPADDING", (0, row_idx), (-1, row_idx), 6), ] # Data rows colouring cat_row_set = {r for r, _ in cat_row_indices} cat_map = {} prev_cat3 = None current_cat_info = None for i, row in enumerate(final_data): if i == 0: continue if i in cat_row_set: # find cat colour for r, c in cat_row_indices: if r == i: current_cat_info = c break continue # alternating within category # just alternate IDA/THAL bg per even/odd row r_num = i ts += [ ("BACKGROUND", (0, r_num), (0, r_num), colors.HexColor("#546E7A")), ("BACKGROUND", (1, r_num), (1, r_num), current_cat_info if current_cat_info else DARK_GREY), ("BACKGROUND", (2, r_num), (2, r_num), LIGHT_GREY if i % 2 == 0 else WHITE), ("BACKGROUND", (3, r_num), (3, r_num), IDA_MID if i % 2 == 0 else IDA_BG), ("BACKGROUND", (4, r_num), (4, r_num), THAL_MID if i % 2 == 0 else THAL_BG), ("TEXTCOLOR", (0, r_num), (0, r_num), WHITE), ("TEXTCOLOR", (1, r_num), (1, r_num), WHITE), ] main_tbl.setStyle(TableStyle(ts)) story.append(main_tbl) story.append(Spacer(1, 6*mm)) # ═══════════════════════════════════════════════════════════════════════════ # PAGE 2 – MEMORY AIDS + RULES + LAB CHEAT SHEET + TREATMENT # ═══════════════════════════════════════════════════════════════════════════ story.append(PageBreak()) # ── Section banner ───────────────────────────────────────────────────────── sec_tbl = Table([[Paragraph("MEMORY AIDS & CLINICAL PEARLS", mstyle("SCH", fontSize=13, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) sec_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 8), ("BOTTOMPADDING", (0,0), (-1,-1), 8), ])) story.append(sec_tbl) story.append(Spacer(1, 4*mm)) # ── Mnemonics side by side ──────────────────────────────────────────────── mh_s = mstyle("MHS", fontSize=10.5, fontName="Helvetica-Bold", leading=14) mb_s = mstyle("MBS", fontSize=9.5, fontName="Helvetica", leading=14) ida_mnem = [ [Paragraph('IDA = "I\'m Depleted, Adequately Treat me!"', mstyle("IM", fontSize=10, fontName="Helvetica-Bold", textColor=IDA_COL, leading=14))], [Paragraph( "The IDA child has symptoms from <b>iron depletion</b>:<br/>" "• <b>I</b>ron stores empty (↓ ferritin, ↓ serum iron)<br/>" "• <b>D</b>iet-related / blood loss (acquired, NOT genetic)<br/>" "• <b>A</b>nisocytosis (↑ RDW) + koilonychia + pica<br/>" "<br/>Responds COMPLETELY to iron within weeks!", mstyle("IMS", fontSize=9, fontName="Helvetica", textColor=IDA_COL, leading=14))], ] ida_mnem_tbl = Table(ida_mnem, colWidths=[84*mm]) ida_mnem_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), IDA_BG), ("BOX", (0,0), (-1,-1), 1.5, IDA_COL), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING", (0,0), (-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) thal_mnem = [ [Paragraph('THAL = "Target cells, HbA2 up, Always transfuse, Lifelong!"', mstyle("TM", fontSize=10, fontName="Helvetica-Bold", textColor=THAL_COL, leading=14))], [Paragraph( "The Thalassaemia child needs <b>lifelong management</b>:<br/>" "• <b>T</b>arget cells on smear + ↑ HbA2 on electrophoresis<br/>" "• <b>H</b>epatosplenomegaly + frontal bossing<br/>" "• <b>A</b>lways needs transfusion (β-Thal Major)<br/>" "• <b>L</b>ifelong: chelation / BMT is only cure", mstyle("TMS", fontSize=9, fontName="Helvetica", textColor=THAL_COL, leading=14))], ] thal_mnem_tbl = Table(thal_mnem, colWidths=[84*mm]) thal_mnem_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), THAL_BG), ("BOX", (0,0), (-1,-1), 1.5, THAL_COL), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING", (0,0), (-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ])) mnem_outer = Table([[ida_mnem_tbl, Paragraph("", mstyle("SP", fontSize=9)), thal_mnem_tbl]], colWidths=[84*mm, 6*mm, 84*mm]) mnem_outer.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 0), ("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0), ])) story.append(mnem_outer) story.append(Spacer(1, 5*mm)) # ── MENTZER INDEX BOX ───────────────────────────────────────────────────── ment_s = mstyle("MentS", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14) ment_h = mstyle("MentH", fontSize=10, fontName="Helvetica-Bold", textColor=ORANGE_COL, leading=14) ment_data = [ [Paragraph("THE MENTZER INDEX — Quick Bedside Differentiator", ment_h)], [Paragraph( "<b>Formula:</b> Mentzer Index = MCV ÷ RBC count<br/><br/>" "<b>MCV < 13 → Suggests THALASSAEMIA</b> (RBC count is high despite microcytosis – lots of small cells)<br/>" "<b>MCV > 13 → Suggests IDA</b> (RBC count is low – body can't make enough cells without iron)<br/><br/>" "Example: MCV = 60 fL, RBC = 6.0 × 10¹²/L → 60 ÷ 6 = 10 → <b>Thalassaemia</b><br/>" "Example: MCV = 60 fL, RBC = 3.5 × 10¹²/L → 60 ÷ 3.5 = 17 → <b>IDA</b><br/><br/>" "<i>Note: Mentzer index is a screening tool, not diagnostic. Always confirm with ferritin + Hb electrophoresis.</i>", ment_s)], ] ment_tbl = Table(ment_data, colWidths=[174*mm]) ment_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), ORANGE_BG), ("BOX", (0,0), (-1,-1), 1.5, ORANGE_COL), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING", (0,0), (-1,-1), 10), ])) story.append(ment_tbl) story.append(Spacer(1, 5*mm)) # ── 5 GOLDEN RULES ──────────────────────────────────────────────────────── rules = [ ("Rule 1 – Ferritin is King", "<b>Always check serum ferritin first.</b> Low ferritin = IDA. Normal/high ferritin with microcytosis = think Thalassaemia. " "Ferritin is the best measure of iron stores in the body."), ("Rule 2 – Iron Stores Are Opposite", "In IDA: iron stores are <b>EMPTY</b> (↓ ferritin, ↑ TIBC). In Thalassaemia: iron stores are <b>NORMAL or EXCESS</b>. " "Never give iron to a thalassaemia patient without checking ferritin – iron overload is already a risk!"), ("Rule 3 – RDW Divides Them", "<b>↑ RDW + microcytosis = IDA</b> (anisocytosis from uneven iron supply). " "<b>Normal RDW + microcytosis = Thalassaemia</b> (all cells are uniformly small)."), ("Rule 4 – Target Cells = Thalassaemia", "Prominent target cells (codocytes) on peripheral smear strongly suggest Thalassaemia. " "IDA rarely shows target cells. Nucleated RBCs in a child = think Thal Major."), ("Rule 5 – Family History + Ethnicity", "Thalassaemia is common in: <b>Mediterranean, Middle Eastern, South Asian, Southeast Asian</b> populations. " "Always ask family history. IDA is universal – no ethnic predilection."), ] rule_head_s = mstyle("RHS", fontSize=10, fontName="Helvetica-Bold", textColor=GOLD, leading=14) rule_body_s = mstyle("RBS", fontSize=9.5, fontName="Helvetica", textColor=DARK_GREY, leading=14) rules_data = [[Paragraph(t, rule_head_s), Paragraph(b, rule_body_s)] for t, b in rules] rules_tbl = Table(rules_data, colWidths=[48*mm, 126*mm]) GREEN_R = colors.HexColor("#1B5E20") rules_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#E8F5E9")), ("BOX", (0,0), (-1,-1), 1.5, GREEN_R), ("LINEBELOW", (0,0), (-1,-4), 0.5, colors.HexColor("#A5D6A7")), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) golden_hdr = Table([[Paragraph("5 GOLDEN CLINICAL RULES", mstyle("GH2", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) golden_hdr.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), GREEN_R), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(golden_hdr) story.append(rules_tbl) story.append(Spacer(1, 5*mm)) # ── QUICK LAB CHEAT SHEET ───────────────────────────────────────────────── PURPLE = colors.HexColor("#4A148C") lhdr_s = mstyle("LHDRS", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) lfeat_s = mstyle("LFS", fontSize=9, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=12) lida_s = mstyle("LIS", fontSize=9, fontName="Helvetica", textColor=IDA_COL, leading=12) lthal_s = mstyle("LTS", fontSize=9, fontName="Helvetica", textColor=THAL_COL, leading=12) lab_rows = [ [Paragraph("Lab Test", lhdr_s), Paragraph("IDA", lhdr_s), Paragraph("Thalassaemia", lhdr_s)], [Paragraph("MCV", lfeat_s), Paragraph("LOW (microcytic)", lida_s), Paragraph("LOW (microcytic)", lthal_s)], [Paragraph("MCH / MCHC", lfeat_s), Paragraph("LOW (hypochromic)", lida_s), Paragraph("LOW (hypochromic)", lthal_s)], [Paragraph("RDW", lfeat_s), Paragraph("HIGH ↑ (anisocytosis)", lida_s), Paragraph("Normal or mildly ↑", lthal_s)], [Paragraph("Serum Ferritin", lfeat_s), Paragraph("LOW ↓↓ (depleted stores)", lida_s), Paragraph("NORMAL or HIGH ↑ (iron overload risk)", lthal_s)], [Paragraph("Serum Iron", lfeat_s), Paragraph("LOW ↓", lida_s), Paragraph("Normal / High", lthal_s)], [Paragraph("TIBC", lfeat_s), Paragraph("HIGH ↑ (body craving iron)", lida_s), Paragraph("Normal", lthal_s)], [Paragraph("RBC count", lfeat_s), Paragraph("LOW (less cells made)", lida_s), Paragraph("Normal or HIGH (many small cells)", lthal_s)], [Paragraph("Mentzer Index\n(MCV÷RBC)", lfeat_s), Paragraph("> 13 → IDA", lida_s), Paragraph("< 13 → Thalassaemia", lthal_s)], [Paragraph("Peripheral Smear", lfeat_s), Paragraph("Microcytic hypochromic\nPencil cells\nAnisocytosis\n(NO target cells)", lida_s), Paragraph("Microcytic hypochromic\nTARGET CELLS prominent\nNucleated RBCs\nBasophilic stippling", lthal_s)], [Paragraph("Hb Electrophoresis", lfeat_s), Paragraph("NORMAL\n(no globin chain defect)", lida_s), Paragraph("β-Thal Minor: ↑ HbA2 >3.5%\nβ-Thal Major: absent HbA, ↑ HbF", lthal_s)], [Paragraph("Response to\nIron Therapy", lfeat_s), Paragraph("YES – Hb rises in 2–4 wks\n(confirms IDA)", lida_s), Paragraph("NO RESPONSE\n(definitive way to distinguish!)", lthal_s)], ] lab_tbl = Table(lab_rows, colWidths=[44*mm, 62*mm, 68*mm]) lab_ts = [ ("BACKGROUND", (0,0), (-1,0), DARK_GREY), ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#90A4AE")), ("TOPPADDING", (0,0), (-1,-1), 4), ("BOTTOMPADDING", (0,0), (-1,-1), 4), ("LEFTPADDING", (0,0), (-1,-1), 5), ("RIGHTPADDING", (0,0), (-1,-1), 5), ("VALIGN", (0,0), (-1,-1), "TOP"), ] for i in range(1, len(lab_rows)): bg_ida = IDA_MID if i % 2 == 0 else IDA_BG bg_thal = THAL_MID if i % 2 == 0 else THAL_BG lab_ts += [ ("BACKGROUND", (0,i), (0,i), LIGHT_GREY if i%2==0 else WHITE), ("BACKGROUND", (1,i), (1,i), bg_ida), ("BACKGROUND", (2,i), (2,i), bg_thal), ] lab_tbl.setStyle(TableStyle(lab_ts)) lab_banner = Table([[Paragraph("QUICK LAB CHEAT SHEET", mstyle("LABH2", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) lab_banner.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), PURPLE), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(lab_banner) story.append(lab_tbl) story.append(Spacer(1, 5*mm)) # ── TREATMENT SUMMARY ───────────────────────────────────────────────────── tr_h = mstyle("TRH2", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) tr_b = mstyle("TRB2", fontSize=8.5, fontName="Helvetica", textColor=DARK_GREY, leading=13) ida_treat = [ [Paragraph("IDA TREATMENT", tr_h)], [Paragraph( "1. <b>Oral Iron:</b> Ferrous sulphate 3–6 mg/kg/day<br/>" "2. <b>Duration:</b> 3 months after Hb normalises<br/>" "3. <b>Vitamin C</b> enhances absorption (give with meals)<br/>" "4. <b>Avoid</b> milk, tea, antacids with iron (block absorption)<br/>" "5. <b>Dietary counselling:</b> red meat, green leafy veg, legumes<br/>" "6. <b>Treat underlying cause:</b> hookworm, bleeding<br/>" "7. <b>IV iron</b> if oral not tolerated / severe malabsorption<br/>" "8. <b>Transfusion</b> only if Hb severely low with symptoms", tr_b)], ] ida_treat_tbl = Table(ida_treat, colWidths=[84*mm]) ida_treat_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (0,0), IDA_COL), ("BACKGROUND", (0,1), (0,1), IDA_BG), ("BOX", (0,0), (-1,-1), 1.5, IDA_COL), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) thal_treat = [ [Paragraph("THALASSAEMIA TREATMENT", tr_h)], [Paragraph( "β-<b>Thal MAJOR:</b><br/>" "1. <b>Regular transfusions:</b> every 3–4 weeks<br/>" " Target pre-transfusion Hb ≥ 9–10 g/dL<br/>" "2. <b>Iron chelation:</b> Deferoxamine (SC) or<br/>" " Deferasirox (oral) – prevents iron overload<br/>" "3. <b>Folic acid</b> supplementation<br/>" "4. <b>Splenectomy</b> if hypersplenism / high transfusion needs<br/>" "5. <b>HSCT (Bone Marrow Transplant):</b> only cure<br/>" " Best before age 10, matched sibling donor<br/><br/>" "β-<b>Thal MINOR:</b> No treatment; genetic counselling", tr_b)], ] thal_treat_tbl = Table(thal_treat, colWidths=[84*mm]) thal_treat_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (0,0), THAL_COL), ("BACKGROUND", (0,1), (0,1), THAL_BG), ("BOX", (0,0), (-1,-1), 1.5, THAL_COL), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) treat_outer = Table([[ida_treat_tbl, Paragraph("", mstyle("SP2", fontSize=9)), thal_treat_tbl]], colWidths=[84*mm, 6*mm, 84*mm]) treat_outer.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 0), ("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0), ])) treat_banner2 = Table([[Paragraph("TREATMENT SUMMARY", mstyle("TRBN2", fontSize=11, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[174*mm]) treat_banner2.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_GREY), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(treat_banner2) story.append(treat_outer) story.append(Spacer(1, 5*mm)) # ── FOOTER ──────────────────────────────────────────────────────────────── footer_data = [[Paragraph( "Sources: Robbins & Kumar Basic Pathology | Scott-Brown's Otorhinolaryngology | " "Miller's Anaesthesia | Goldman-Cecil Medicine | Firestein & Kelley's Rheumatology " "• Compiled by Orris Medical AI | August 2026", FOOT_S)]] foot_tbl = Table(footer_data, colWidths=[174*mm]) foot_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8), ("BOX", (0,0), (-1,-1), 0.5, colors.grey), ])) story.append(foot_tbl) # BUILD doc.build(story) print(f"PDF created: {OUTPUT}") PYEOF

Your PDF is ready! Here is your download link:

IDA vs Thalassemia Paeds

PDF Document · PDF


What's Inside (2 Pages, 20 Points in 5 Categories)

Page 1 - Main Comparison Table

The 20 points are organised under 5 colour-coded category banners:
CategoryColourPointsTopics Covered
A - Basic ScienceBlue1-3Full name, root cause (pathophysiology), inheritance
B - Clinical FeaturesPink/Maroon4-8Age, appearance, specific signs (koilonychia, pica, frontal bossing), splenomegaly, jaundice
C - Lab FindingsPurple9-14Hb, MCV, MCH/MCHC, RDW, iron studies (ferritin/TIBC), peripheral blood smear
D - DiagnosisTeal15-16Definitive tests (ferritin vs Hb electrophoresis), bone marrow findings, skull X-ray
E - Treatment & PrognosisGreen17-20Primary treatment, curative options, monitoring, prognosis

Page 2 - Memory Aids & Pearls

  • IDA mnemonic - "I'm Depleted, Adequately Treat me!" (I = iron stores empty, D = diet/blood loss, A = anisocytosis + pica)
  • THAL mnemonic - "Target cells, HbA2 up, Always transfuse, Lifelong!"
  • The Mentzer Index - MCV ÷ RBC count: <13 = Thalassaemia, >13 = IDA (with worked examples)
  • 5 Golden Rules (ferritin is king, iron stores are opposite, RDW divides them, target cells = thal, family history/ethnicity)
  • Quick Lab Cheat Sheet - 12-row side-by-side including the key differentiator: response to iron therapy (IDA responds, Thal does not)
  • Treatment Summary side-by-side with full drug names, doses, and monitoring points

CREATE THE SAME FOR HEAMOPHILLIA AND THE MAIN TYPE DIFFERENT IN PEADS

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/haemophilia && python3 << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak) from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY OUTPUT = "/tmp/workspace/haemophilia/Haemophilia_Types_Paeds.pdf" doc = SimpleDocTemplate( OUTPUT, pagesize=A4, rightMargin=16*mm, leftMargin=16*mm, topMargin=16*mm, bottomMargin=16*mm, title="Haemophilia Types in Paediatrics", author="Orris Medical Education" ) # ── Colour palette ────────────────────────────────────────────────────────── HA_COL = colors.HexColor("#B71C1C") # deep red – Haemophilia A HB_COL = colors.HexColor("#1565C0") # deep blue – Haemophilia B VWD_COL = colors.HexColor("#1B5E20") # deep green – vWD HA_BG = colors.HexColor("#FFEBEE") HB_BG = colors.HexColor("#E3F2FD") VWD_BG = colors.HexColor("#E8F5E9") HA_MID = colors.HexColor("#FFCDD2") HB_MID = colors.HexColor("#BBDEFB") VWD_MID = colors.HexColor("#C8E6C9") WHITE = colors.white DARK_GREY = colors.HexColor("#263238") LIGHT_GREY= colors.HexColor("#ECEFF1") GOLD = colors.HexColor("#F57F17") PURPLE = colors.HexColor("#4A148C") ORANGE_BG = colors.HexColor("#FFF3E0") ORANGE = colors.HexColor("#E65100") TEAL = colors.HexColor("#006064") TEAL_BG = colors.HexColor("#E0F7FA") def ms(name, **kw): return ParagraphStyle(name, **kw) TITLE_S = ms("TS", fontSize=20, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=26) SUBT_S = ms("SS", fontSize=10.5, fontName="Helvetica", textColor=colors.HexColor("#CFD8DC"), alignment=TA_CENTER, leading=15) FEAT_S = ms("FS", fontSize=9, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=13, alignment=TA_LEFT) HA_S = ms("HAS", fontSize=9, fontName="Helvetica", textColor=HA_COL, leading=13, alignment=TA_LEFT) HB_S = ms("HBS", fontSize=9, fontName="Helvetica", textColor=HB_COL, leading=13, alignment=TA_LEFT) VWD_S = ms("VS", fontSize=9, fontName="Helvetica", textColor=VWD_COL, leading=13, alignment=TA_LEFT) NUM_S = ms("NS", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) HDR_S = ms("HdS", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) DEF_S = ms("DS", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14, alignment=TA_LEFT) BOLD_S = ms("BLS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=14) FOOT_S = ms("FoS", fontSize=7.5, fontName="Helvetica-Oblique", textColor=colors.grey, alignment=TA_CENTER) # Column widths: #, Cat, Feature, Haem A, Haem B, vWD COL_W = [7*mm, 8*mm, 34*mm, 47*mm, 47*mm, 49*mm] # ═══════════════════════════════════════════════════════════════════════════ # 20 COMPARISON POINTS — 5 CATEGORIES # ═══════════════════════════════════════════════════════════════════════════ # Cat A – Basic Science (1–3) # Cat B – Clinical Features (4–8) # Cat C – Lab & Diagnosis (9–13) # Cat D – Special Scenarios (14–16) # Cat E – Treatment & Prognosis (17–20) CAT_A = colors.HexColor("#01579B") CAT_B = colors.HexColor("#880E4F") CAT_C = colors.HexColor("#4A148C") CAT_D = colors.HexColor("#006064") CAT_E = colors.HexColor("#1B5E20") points = [ # no, cat, cat_col, feature, HA_text, HB_text, VWD_text # ── CAT A: BASIC SCIENCE ─────────────────────────────────────────────── ("1","A",CAT_A, "Full Name", "Haemophilia A\n(Classic Haemophilia)", "Haemophilia B\n(Christmas Disease)", "von Willebrand Disease\n(vWD) – Most common\ninherited bleeding disorder"), ("2","A",CAT_A, "Deficient Factor /\nProtein", "Factor VIII (8)\n(FVIII – intrinsic pathway)\nCoagulation factor", "Factor IX (9)\n(FIX – intrinsic pathway)\nCoagulation factor", "von Willebrand Factor\n(vWF) – a large\nplatelet-adhesion glycoprotein\n(also carries FVIII)"), ("3","A",CAT_A, "Genetics /\nInheritance", "X-linked RECESSIVE\n• Gene: F8 on X chromosome\n• Boys affected, girls carriers\n• No male-to-male transmission", "X-linked RECESSIVE\n• Gene: F9 on X chromosome\n• Same pattern as Haem A\n• Clinically identical to A", "Autosomal DOMINANT\n(Type 1 & 2)\nAutosomal RECESSIVE\n(Type 3 – rare, severe)\n• Both sexes affected equally"), # ── CAT B: CLINICAL FEATURES ─────────────────────────────────────────── ("4","B",CAT_B, "Prevalence /\nIncidence", "Most common haemophilia\n1:5,000 live male births\n~80% of all haemophilia", "~5× less common than A\n1:25,000–30,000 live\nmale births\n~15% of all haemophilia", "Most common inherited\nbleeding disorder overall\n~1% of general population\nType 1 = 80% of cases"), ("5","B",CAT_B, "Type of Bleeding\n(KEY DIFFERENTIATOR)", "DEEP TISSUE BLEEDING\n• Haemarthrosis (joints)\n• Muscle haematomas\n• Intracranial haemorrhage\n→ 'Internal, deep' bleeds", "DEEP TISSUE BLEEDING\n(Same pattern as Haem A)\n• Haemarthrosis\n• Muscle haematomas\n• Intracranial haemorrhage\n→ Clinically identical to A", "MUCOSAL / SURFACE BLEEDING\n• Epistaxis (nose bleeds)\n• Gingival (gum) bleeding\n• Menorrhagia (heavy periods)\n• Easy bruising\n→ 'Surface' bleeds"), ("6","B",CAT_B, "Haemarthrosis\n(Bleeding into Joints)", "HALLMARK of Haem A\n• Knee, ankle, elbow most\n• Painful, swollen, warm joint\n• Chronic → arthropathy\n• Target joint develops", "PRESENT (same as A)\nHaemarthrosis is equally\na feature of Haem B\nSame joint complications", "RARE / ABSENT in Type 1–2\nMay occur in Type 3 vWD\n(severe, when FVIII also\nvery low)\nNot the typical presentation"), ("7","B",CAT_B, "Severity\nClassification", "Mild: FVIII 5–40%\n (only surgical bleeding)\nModerate: FVIII 1–5%\n (minor trauma bleeds)\nSevere: FVIII <1%\n (spontaneous bleeds)", "Mild: FIX 5–40%\nModerate: FIX 1–5%\nSevere: FIX <1%\n(Same severity grading\nas Haemophilia A)", "Type 1: Mild–moderate\n (commonest, 80%)\nType 2: Variable, qualitative\n vWF defect\nType 3: Severe\n (rare, like haemophilia)"), ("8","B",CAT_B, "When Does It\nPresent?", "Circumcision bleed, cord\nstump bleed (newborn)\nFirst crawl/walk\n→ unexpected bruising\nTeething → gum bleeding", "Same as Haem A:\nNewborn bleeds after\nprocedures, bruising\non first movement", "Later in childhood:\nBruising, epistaxis,\nheavy periods (girls)\nOften found at dental\nextraction or tonsillectomy"), # ── CAT C: LAB & DIAGNOSIS ───────────────────────────────────────────── ("9","C",CAT_C, "Prothrombin Time\n(PT)", "NORMAL\n(extrinsic pathway\nnot affected)", "NORMAL\n(extrinsic pathway\nnot affected)", "NORMAL\n(extrinsic pathway\nnot affected)"), ("10","C",CAT_C, "aPTT\n(Activated Partial\nThromboplastin Time)", "PROLONGED ↑\n(intrinsic pathway\ndefect – FVIII low)", "PROLONGED ↑\n(intrinsic pathway\ndefect – FIX low)", "Normal or mildly ↑\n(prolonged only if\nvWF very low → FVIII\nalso falls → Type 3)"), ("11","C",CAT_C, "Bleeding Time /\nPlatelet Function", "NORMAL bleeding time\nNormal platelet count\nNormal platelet function", "NORMAL bleeding time\nNormal platelet count\nNormal platelet function", "PROLONGED bleeding time\n(vWF mediates platelet\nadhesion to vessel wall)\nPlatelet count: Normal\nPlatelet function: Impaired"), ("12","C",CAT_C, "Specific Factor\nAssay", "FVIII assay: LOW\n(confirms diagnosis)\n• Severe: <1%\n• Mild: 5–40%", "FIX assay: LOW\n(confirms diagnosis)\n• Severe: <1%\n• Mild: 5–40%", "vWF Antigen (vWF:Ag): ↓\nvWF Activity\n(Ristocetin cofactor): ↓\nFVIII activity: ↓ (Type 3)\nvWF multimer analysis for\ntype classification"), ("13","C",CAT_C, "Mixing Study\n(Patient plasma +\nNormal plasma)", "aPTT CORRECTS\n→ suggests factor\ndeficiency (not inhibitor)\n[If not corrected → suspect\nFVIII inhibitor antibody]", "aPTT CORRECTS\n→ FIX deficiency\n[If not corrected → FIX\ninhibitor present]", "May correct\n(not as diagnostically\nrelevant as in haemophilia;\nspecific vWF assays used)"), # ── CAT D: SPECIAL SCENARIOS ─────────────────────────────────────────── ("14","D",CAT_D, "Inhibitors\n(Antibody Complication)", "30% of severe Haem A\ndevelop FVIII inhibitors\n(neutralising antibodies)\n→ Major management challenge\n→ Use bypassing agents\n(FEIBA, rFVIIa, Emicizumab)", "1–3% of Haem B\ndevelop FIX inhibitors\n(less common than A)\nSome also develop\nanaphylaxis to FIX!", "Inhibitors rare in vWD\nNot a typical complication\nof standard treatment"), ("15","D",CAT_D, "Intracranial\nHaemorrhage (ICH)", "LEADING cause of death\nin children with Haem A\nOccurs spontaneously\nor after mild head trauma\nEmergency: give FVIII first,\nCT scan after", "Risk same as Haem A\nICH is the most feared\ncompliance of severe Haem B\nEmergency: give FIX first", "ICH very rare in vWD\n(unless Type 3 with\nvery low FVIII)\nNot a typical emergency\nin Type 1/2 vWD"), ("16","D",CAT_D, "Carrier / Female\nManifestations", "Female carriers may have\nFVIII 30–50% of normal\n→ Mild bleeding symptoms\nMay bleed heavily with\nmenstruation/delivery", "Female carriers may have\nFIX 30–50% of normal\nSimilar mild bleeding\nsymptoms in carriers", "Type 1 vWD affects\nFEMALES equally\nMenorrhagia is often\nfirst presenting symptom\nin adolescent girls"), # ── CAT E: TREATMENT ─────────────────────────────────────────────────── ("17","E",CAT_E, "Specific Factor\nReplacement\n(Primary Treatment)", "FVIII Concentrate\n(recombinant preferred)\nDose: varies by bleed site\nMinor: target FVIII 30–50%\nMajor: target FVIII 80–100%\nProphylaxis: 3×/week", "FIX Concentrate\n(recombinant preferred)\nDose: similar principle\nMinor: target FIX 30–50%\nMajor: target FIX 80–100%\nNote: FIX has longer half-life\n→ twice weekly prophylaxis", "DESMOPRESSIN (DDAVP)\n• Releases stored vWF\n from endothelium\n• Works for Type 1 vWD\n (mild/moderate)\n• IV or intranasal route\nNot effective in Type 3"), ("18","E",CAT_E, "Additional\nTreatments", "Emicizumab (Hemlibra):\nBispecific antibody\nmimics FVIII function\n→ SC injection, weekly\n→ Game changer for\ninhibitor patients\n\nTransexamic acid:\nadjunct for mucosal bleeds", "Fitusiran, Marstacimab:\nnewer agents (gene therapy\nfor Haem B very advanced)\nALA062 gene therapy\n→ Single IV infusion\n→ Near-curative results\n\nTransexamic acid: adjunct", "vWF Concentrate /\nFFP: for Type 2 & 3\nTransexamic acid:\nmucosal bleeds, dental\nOral contraceptives:\nmenorrhagia in girls\nDDAVP nasal spray:\nType 1 (mild episodes)"), ("19","E",CAT_E, "Prophylaxis\n(Prevent Bleeds)", "PRIMARY PROPHYLAXIS:\nStart before age 3 (first\njoint bleed) and before\njoint damage occurs\nFVIII 3× per week or\nemicizumab once weekly\nGoal: prevent arthropathy", "PRIMARY PROPHYLAXIS:\nFIX 2× per week\n(longer half-life than FVIII)\nOr extended half-life FIX\nproducts (once weekly)", "Type 1: On-demand only\n(DDAVP before procedures)\nType 3: Regular vWF\nconcentrate prophylaxis\nAnnual dental review;\nantibiotic prophylaxis\nbefore procedures"), ("20","E",CAT_E, "Prognosis", "Severe Haem A: significant\nmorbidity from arthropathy\nif undertreated\nWith modern prophylaxis:\nnear-normal joint function\nGene therapy: curative\ntrials ongoing\nLife expectancy improving", "Haem B prognosis:\nslightly BETTER than A\nwith gene therapy\nBenefits more from gene\ntherapy (smaller gene)\nFactor IX Padua variant:\nhigh-efficiency gene therapy", "Type 1 vWD:\nExcellent prognosis\nType 3: significant\nbleeding morbidity\nFertility unaffected\nNo joint disease in\nTypes 1 and 2"), ] # ═══════════════════════════════════════════════════════════════════════════ # BUILD STORY # ═══════════════════════════════════════════════════════════════════════════ story = [] # ── TITLE BANNER ─────────────────────────────────────────────────────────── title_data = [ [Paragraph("HAEMOPHILIA & TYPES IN PAEDIATRICS", TITLE_S)], [Paragraph("Haemophilia A vs Haemophilia B vs von Willebrand Disease", SUBT_S)], [Paragraph("20 Must-Know Points | Categorised & Chunked | Simple Language | Medical Terms Preserved", SUBT_S)], ] t_tbl = Table(title_data, colWidths=[190*mm]) t_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0),(-1,-1), DARK_GREY), ("TOPPADDING", (0,0),(-1,-1), 8), ("BOTTOMPADDING", (0,0),(-1,-1), 8), ("LEFTPADDING", (0,0),(-1,-1), 8), ("RIGHTPADDING", (0,0),(-1,-1), 8), ])) story.append(t_tbl) story.append(Spacer(1, 4*mm)) # ── QUICK DEFINITIONS ───────────────────────────────────────────────────── def_data = [ [Paragraph("QUICK DEFINITIONS", BOLD_S)], [Paragraph( "<b>Haemophilia A:</b> Deficiency of <b>Factor VIII (FVIII)</b>. X-linked recessive. Most common haemophilia. " "Causes deep internal bleeds (joints, muscles). Treated with FVIII concentrate or emicizumab.", DEF_S)], [Paragraph( "<b>Haemophilia B (Christmas Disease):</b> Deficiency of <b>Factor IX (FIX)</b>. X-linked recessive. " "Clinically identical to Haem A but less common. Treated with FIX concentrate. Gene therapy most advanced here.", DEF_S)], [Paragraph( "<b>von Willebrand Disease (vWD):</b> Deficiency/dysfunction of <b>von Willebrand Factor (vWF)</b>. " "Most common inherited bleeding disorder. Autosomal — affects both sexes. Mucosal bleeds (epistaxis, gum, menorrhagia). " "Treated with DDAVP or vWF concentrate.", DEF_S)], [Paragraph( "<b>KEY CONCEPT:</b> Haemophilia A & B affect the <b>intrinsic coagulation pathway</b> → deep tissue bleeds, prolonged aPTT, " "NORMAL platelet function. vWD affects <b>primary haemostasis</b> (platelet adhesion) → mucosal bleeds, prolonged bleeding time.", DEF_S)], ] d_tbl = Table(def_data, colWidths=[190*mm]) d_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0),(-1,-1), LIGHT_GREY), ("TOPPADDING", (0,0),(-1,-1), 4), ("BOTTOMPADDING", (0,0),(-1,-1), 4), ("LEFTPADDING", (0,0),(-1,-1), 10), ("RIGHTPADDING", (0,0),(-1,-1), 10), ("BOX", (0,0),(-1,-1), 1, DARK_GREY), ])) story.append(d_tbl) story.append(Spacer(1, 4*mm)) # ── CATEGORY LEGEND ─────────────────────────────────────────────────────── leg_s = ms("LS", fontSize=8, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) leg_labels = [ (CAT_A, "A Basic Science\n(1–3)"), (CAT_B, "B Clinical Features\n(4–8)"), (CAT_C, "C Lab & Diagnosis\n(9–13)"), (CAT_D, "D Special Scenarios\n(14–16)"), (CAT_E, "E Treatment &\nPrognosis (17–20)"), ] leg_row = [[Paragraph(txt, leg_s) for _, txt in leg_labels]] leg_tbl = Table(leg_row, colWidths=[38*mm]*5) leg_cmds = [ ("TOPPADDING", (0,0),(-1,-1), 4), ("BOTTOMPADDING", (0,0),(-1,-1), 4), ("LEFTPADDING", (0,0),(-1,-1), 3), ("RIGHTPADDING", (0,0),(-1,-1), 3), ("GRID", (0,0),(-1,-1), 0.5, WHITE), ("VALIGN", (0,0),(-1,-1), "MIDDLE"), ] for i,(col,_) in enumerate(leg_labels): leg_cmds.append(("BACKGROUND",(i,0),(i,0),col)) leg_tbl.setStyle(TableStyle(leg_cmds)) leg_hdr = Table([[Paragraph("CATEGORY LEGEND", ms("LHDR", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[190*mm]) leg_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),4), ("BOTTOMPADDING",(0,0),(-1,-1),4), ])) story.append(leg_hdr) story.append(leg_tbl) story.append(Spacer(1, 3*mm)) # ── MAIN TABLE HEADER ───────────────────────────────────────────────────── hdr_row = [ Paragraph("#", HDR_S), Paragraph("Cat", HDR_S), Paragraph("FEATURE", HDR_S), Paragraph("🔴 HAEMOPHILIA A\n(Factor VIII Deficiency)", HDR_S), Paragraph("🔵 HAEMOPHILIA B\n(Factor IX Deficiency)", HDR_S), Paragraph("🟢 VON WILLEBRAND\nDISEASE (vWD)", HDR_S), ] final_data = [hdr_row] cat_row_indices = [] prev_cat = None current_cat_col = None cat_names_map = { "A": "CATEGORY A — BASIC SCIENCE (Disease Origin & Genetics)", "B": "CATEGORY B — CLINICAL FEATURES (How the Child Bleeds)", "C": "CATEGORY C — LAB & DIAGNOSIS (Tests & Results)", "D": "CATEGORY D — SPECIAL CLINICAL SCENARIOS", "E": "CATEGORY E — TREATMENT & PROGNOSIS", } for no, cat, cat_col, feat, ha, hb, vwd in points: if cat != prev_cat: cat_row = [ Paragraph(cat_names_map[cat], ms(f"CR{cat}", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT, leading=13)), None, None, None, None, None ] cat_row_indices.append((len(final_data), cat_col)) final_data.append(cat_row) prev_cat = cat current_cat_col = cat_col num_p = Paragraph(f"<b>{no}</b>", NUM_S) cat_p = Paragraph(f"<b>{cat}</b>", ms(f"CP{no}", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12)) feat_p = Paragraph(feat.replace("\n","<br/>"), FEAT_S) ha_p = Paragraph(ha.replace("\n","<br/>"), HA_S) hb_p = Paragraph(hb.replace("\n","<br/>"), HB_S) vwd_p = Paragraph(vwd.replace("\n","<br/>"), VWD_S) final_data.append([num_p, cat_p, feat_p, ha_p, hb_p, vwd_p]) main_tbl = Table(final_data, colWidths=COL_W, repeatRows=1) ts = [ ("BACKGROUND", (0,0),(-1,0), DARK_GREY), ("BACKGROUND", (3,0),(3,0), HA_COL), ("BACKGROUND", (4,0),(4,0), HB_COL), ("BACKGROUND", (5,0),(5,0), VWD_COL), ("TOPPADDING", (0,0),(-1,-1), 4), ("BOTTOMPADDING", (0,0),(-1,-1), 4), ("LEFTPADDING", (0,0),(-1,-1), 3), ("RIGHTPADDING", (0,0),(-1,-1), 3), ("VALIGN", (0,0),(-1,-1), "TOP"), ("GRID", (0,0),(-1,-1), 0.4, colors.HexColor("#B0BEC5")), ] cat_row_set = {r for r,_ in cat_row_indices} for row_idx, cat_col in cat_row_indices: ts += [ ("BACKGROUND", (0,row_idx),(-1,row_idx), cat_col), ("SPAN", (0,row_idx),(-1,row_idx)), ("TOPPADDING", (0,row_idx),(-1,row_idx), 5), ("BOTTOMPADDING",(0,row_idx),(-1,row_idx), 5), ("LEFTPADDING", (0,row_idx),(-1,row_idx), 6), ] current_cat_c = None for i, row in enumerate(final_data): if i == 0: continue if i in cat_row_set: for r,c in cat_row_indices: if r == i: current_cat_c = c; break continue ts += [ ("BACKGROUND",(0,i),(0,i), colors.HexColor("#546E7A")), ("BACKGROUND",(1,i),(1,i), current_cat_c if current_cat_c else DARK_GREY), ("BACKGROUND",(2,i),(2,i), LIGHT_GREY if i%2==0 else WHITE), ("BACKGROUND",(3,i),(3,i), HA_MID if i%2==0 else HA_BG), ("BACKGROUND",(4,i),(4,i), HB_MID if i%2==0 else HB_BG), ("BACKGROUND",(5,i),(5,i), VWD_MID if i%2==0 else VWD_BG), ("TEXTCOLOR", (0,i),(0,i), WHITE), ("TEXTCOLOR", (1,i),(1,i), WHITE), ] main_tbl.setStyle(TableStyle(ts)) story.append(main_tbl) story.append(Spacer(1, 5*mm)) # ═══════════════════════════════════════════════════════════════════════════ # PAGE 2 # ═══════════════════════════════════════════════════════════════════════════ story.append(PageBreak()) # ── Page 2 banner ────────────────────────────────────────────────────────── p2_hdr = Table([[Paragraph("MEMORY AIDS, LAB CHEAT SHEET & CLINICAL PEARLS", ms("P2H", fontSize=12, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[190*mm]) p2_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),7), ("BOTTOMPADDING",(0,0),(-1,-1),7), ])) story.append(p2_hdr) story.append(Spacer(1, 4*mm)) # ── MNEMONICS — 3 columns ───────────────────────────────────────────────── mh = ms("MH3", fontSize=9.5, fontName="Helvetica-Bold", leading=13) mb = ms("MB3", fontSize=8.5, fontName="Helvetica", leading=13) ha_mnem = [ [Paragraph('HAEM A = "EIGHT is the Weight!"', ms("HAM",fontSize=9.5,fontName="Helvetica-Bold",textColor=HA_COL,leading=13))], [Paragraph( "Factor <b>VIII (8)</b> deficiency<br/>" "• <b>E</b>ighth factor missing<br/>" "• <b>I</b>ntrinsic pathway → ↑ aPTT<br/>" "• <b>G</b>irls carry it, boys bleed<br/>" "• <b>H</b>aemarthrosis = hallmark<br/>" "• <b>T</b>reat: FVIII or Emicizumab", ms("HAMB",fontSize=8.5,fontName="Helvetica",textColor=HA_COL,leading=13))], ] ha_m = Table(ha_mnem, colWidths=[60*mm]) ha_m.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),HA_BG), ("BOX",(0,0),(-1,-1),1.5,HA_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ])) hb_mnem = [ [Paragraph('HAEM B = "NINE\'s Christmas Time!"', ms("HBM",fontSize=9.5,fontName="Helvetica-Bold",textColor=HB_COL,leading=13))], [Paragraph( "Factor <b>IX (9)</b> deficiency<br/>" "• <b>N</b>ine = Christmas disease<br/>" "• <b>I</b>ntrinsic → ↑ aPTT<br/>" "• <b>N</b>ormal bleeding time<br/>" "• <b>E</b>xcellent gene therapy options<br/>" "• Treat: FIX concentrate", ms("HBMB",fontSize=8.5,fontName="Helvetica",textColor=HB_COL,leading=13))], ] hb_m = Table(hb_mnem, colWidths=[60*mm]) hb_m.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),HB_BG), ("BOX",(0,0),(-1,-1),1.5,HB_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ])) vwd_mnem = [ [Paragraph('vWD = "Vessel Wall Drama!"', ms("VWM",fontSize=9.5,fontName="Helvetica-Bold",textColor=VWD_COL,leading=13))], [Paragraph( "<b>vWF</b> glues platelets to vessel wall<br/>" "• <b>V</b>WF missing → platelets don't stick<br/>" "• <b>W</b>omen affected (menorrhagia)<br/>" "• <b>D</b>DAVPisa the first-line treatment<br/>" "• Mucosal bleeds (nose, gums)<br/>" "• Autosomal – both sexes!", ms("VWMB",fontSize=8.5,fontName="Helvetica",textColor=VWD_COL,leading=13))], ] vwd_m = Table(vwd_mnem, colWidths=[60*mm]) vwd_m.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),VWD_BG), ("BOX",(0,0),(-1,-1),1.5,VWD_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ])) spacer_p = Paragraph("", ms("SP",fontSize=1)) mnem_outer = Table( [[ha_m, spacer_p, hb_m, spacer_p, vwd_m]], colWidths=[60*mm, 5*mm, 60*mm, 5*mm, 60*mm] ) mnem_outer.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("TOPPADDING",(0,0),(-1,-1),0), ("BOTTOMPADDING",(0,0),(-1,-1),0), ("LEFTPADDING",(0,0),(-1,-1),0), ("RIGHTPADDING",(0,0),(-1,-1),0), ])) story.append(mnem_outer) story.append(Spacer(1, 5*mm)) # ── HAEMOPHILIA A vs B — THE CONFUSER BOX ───────────────────────────────── confuse_data = [ [Paragraph("WHY IS HAEMOPHILIA A vs B SO CONFUSING? — Here's the Simple Difference", ms("CONFH", fontSize=10, fontName="Helvetica-Bold", textColor=ORANGE, leading=14))], [Paragraph( "Haemophilia A and B are <b>CLINICALLY IDENTICAL</b> — you cannot tell them apart by looking at the child or from symptoms alone.<br/>" "The ONLY way to distinguish them is by <b>SPECIFIC FACTOR ASSAY</b>:<br/>" "• If FVIII (Factor 8) is low → <b>Haemophilia A</b><br/>" "• If FIX (Factor 9) is low → <b>Haemophilia B (Christmas Disease)</b><br/><br/>" "Why does it matter? Because the TREATMENT is different:<br/>" "• Haem A: needs <b>FVIII concentrate</b> (or emicizumab)<br/>" "• Haem B: needs <b>FIX concentrate</b><br/>" "Giving the wrong factor will NOT help the child!", ms("CONFB", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14))], ] conf_tbl = Table(confuse_data, colWidths=[190*mm]) conf_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),ORANGE_BG), ("BOX",(0,0),(-1,-1),1.5,ORANGE), ("TOPPADDING",(0,0),(-1,-1),6), ("BOTTOMPADDING",(0,0),(-1,-1),6), ("LEFTPADDING",(0,0),(-1,-1),10), ("RIGHTPADDING",(0,0),(-1,-1),10), ])) story.append(conf_tbl) story.append(Spacer(1, 5*mm)) # ── 5 GOLDEN RULES ──────────────────────────────────────────────────────── rules = [ ("Rule 1 – Deep vs. Mucosal", "<b>Haemophilia A/B</b> = deep bleeds (joints, muscles, ICH). <b>vWD</b> = mucosal/surface bleeds (nose, gums, periods). " "This single distinction guides your initial differential."), ("Rule 2 – aPTT + Bleeding Time", "Haemophilia A/B: <b>↑ aPTT, NORMAL bleeding time</b>. vWD (Type 1/2): <b>NORMAL aPTT, ↑ bleeding time</b>. " "vWD Type 3: both ↑. PT is NORMAL in all three conditions."), ("Rule 3 – Sex Matters", "Haemophilia A/B are X-linked → <b>almost exclusively in boys</b>. " "vWD is autosomal → <b>affects both boys and girls equally</b>. " "A girl with significant bleeding disorder → think vWD first!"), ("Rule 4 – Haemarthrosis = Haemophilia", "Any child with recurrent <b>haemarthrosis (joint bleeds)</b> has Haemophilia (A or B) until proven otherwise. " "vWD does NOT cause haemarthrosis unless it is severe Type 3."), ("Rule 5 – Factor Assay is Definitive", "Diagnose Haemophilia A and B ONLY by specific factor assay (FVIII vs FIX level). " "Diagnose vWD by vWF:Ag + vWF:RCo (ristocetin cofactor activity) + vWF multimer analysis."), ] r_head = ms("RHS2", fontSize=9.5, fontName="Helvetica-Bold", textColor=GOLD, leading=14) r_body = ms("RBS2", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14) rules_data = [[Paragraph(t, r_head), Paragraph(b, r_body)] for t, b in rules] rules_tbl = Table(rules_data, colWidths=[50*mm, 140*mm]) GREEN_R = colors.HexColor("#1B5E20") rules_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0),(-1,-1), colors.HexColor("#E8F5E9")), ("BOX", (0,0),(-1,-1), 1.5, GREEN_R), ("LINEBELOW", (0,0),(-1,-4), 0.5, colors.HexColor("#A5D6A7")), ("TOPPADDING", (0,0),(-1,-1), 5), ("BOTTOMPADDING", (0,0),(-1,-1), 5), ("LEFTPADDING", (0,0),(-1,-1), 8), ("RIGHTPADDING", (0,0),(-1,-1), 8), ("VALIGN", (0,0),(-1,-1), "TOP"), ])) golden_hdr = Table([[Paragraph("5 GOLDEN CLINICAL RULES", ms("GH3", fontSize=10.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[190*mm]) golden_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),GREEN_R), ("TOPPADDING",(0,0),(-1,-1),6), ("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(golden_hdr) story.append(rules_tbl) story.append(Spacer(1, 5*mm)) # ── LAB CHEAT SHEET ─────────────────────────────────────────────────────── lh = ms("LH3", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) lf = ms("LF3", fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=12) la = ms("LA3", fontSize=8.5, fontName="Helvetica", textColor=HA_COL, leading=12) lb = ms("LB3", fontSize=8.5, fontName="Helvetica", textColor=HB_COL, leading=12) lv = ms("LV3", fontSize=8.5, fontName="Helvetica", textColor=VWD_COL, leading=12) lab_rows = [ [Paragraph("Test", lh), Paragraph("Haemophilia A", lh), Paragraph("Haemophilia B", lh), Paragraph("vWD (Type 1/2)", lh)], [Paragraph("PT", lf), Paragraph("NORMAL", la), Paragraph("NORMAL", lb), Paragraph("NORMAL", lv)], [Paragraph("aPTT", lf), Paragraph("PROLONGED ↑↑", la), Paragraph("PROLONGED ↑↑", lb), Paragraph("Normal or ↑ (Type 3: ↑↑)", lv)], [Paragraph("Bleeding Time", lf), Paragraph("NORMAL", la), Paragraph("NORMAL", lb), Paragraph("PROLONGED ↑", lv)], [Paragraph("Platelet Count", lf), Paragraph("Normal", la), Paragraph("Normal", lb), Paragraph("Normal (Type 2B: ↓)", lv)], [Paragraph("FVIII Assay", lf), Paragraph("LOW ↓↓ (diagnostic)", la), Paragraph("Normal or slightly ↓\n(FIX carries FVIII)", lb), Paragraph("↓ in Type 3; mildly ↓ in Type 1\n(vWF carries FVIII)", lv)], [Paragraph("FIX Assay", lf), Paragraph("Normal", la), Paragraph("LOW ↓↓ (diagnostic)", lb), Paragraph("Normal", lv)], [Paragraph("vWF Antigen\n(vWF:Ag)", lf), Paragraph("Normal", la), Paragraph("Normal", lb), Paragraph("LOW ↓ (diagnostic)", lv)], [Paragraph("vWF Activity\n(Ristocetin cofactor)", lf), Paragraph("Normal", la), Paragraph("Normal", lb), Paragraph("LOW ↓ (diagnostic)", lv)], [Paragraph("Mixing Study", lf), Paragraph("aPTT corrects\n(unless inhibitor)", la), Paragraph("aPTT corrects\n(unless inhibitor)", lb), Paragraph("Less relevant;\nvWF assays used", lv)], ] lab_tbl = Table(lab_rows, colWidths=[42*mm, 48*mm, 48*mm, 52*mm]) lab_ts = [ ("BACKGROUND",(0,0),(-1,0),DARK_GREY), ("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#90A4AE")), ("TOPPADDING",(0,0),(-1,-1),4), ("BOTTOMPADDING",(0,0),(-1,-1),4), ("LEFTPADDING",(0,0),(-1,-1),4), ("RIGHTPADDING",(0,0),(-1,-1),4), ("VALIGN",(0,0),(-1,-1),"TOP"), ] for i in range(1, len(lab_rows)): lab_ts += [ ("BACKGROUND",(0,i),(0,i),LIGHT_GREY if i%2==0 else WHITE), ("BACKGROUND",(1,i),(1,i),HA_MID if i%2==0 else HA_BG), ("BACKGROUND",(2,i),(2,i),HB_MID if i%2==0 else HB_BG), ("BACKGROUND",(3,i),(3,i),VWD_MID if i%2==0 else VWD_BG), ] lab_tbl.setStyle(TableStyle(lab_ts)) lab_banner = Table([[Paragraph("QUICK LAB CHEAT SHEET", ms("LABH3", fontSize=10.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[190*mm]) lab_banner.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),PURPLE), ("TOPPADDING",(0,0),(-1,-1),6), ("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(lab_banner) story.append(lab_tbl) story.append(Spacer(1, 5*mm)) # ── TREATMENT SUMMARY — 3 columns ──────────────────────────────────────── th = ms("TH3", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) tb = ms("TB3", fontSize=8.5, fontName="Helvetica", textColor=DARK_GREY, leading=13) ha_treat = [ [Paragraph("HAEMOPHILIA A TREATMENT", th)], [Paragraph( "1. <b>FVIII Concentrate</b> (recombinant)<br/>" "2. <b>Emicizumab</b> (Hemlibra): bispecific Ab<br/>" " SC weekly – now preferred prophylaxis<br/>" "3. DDAVP: mild Haem A (releases FVIII stores)<br/>" "4. Tranexamic acid: mucosal bleeds<br/>" "5. Inhibitors: FEIBA or rFVIIa (bypassing)<br/>" "6. Primary prophylaxis: start before age 3<br/>" "7. Gene therapy: trials ongoing (promising)", tb)], ] ha_t = Table(ha_treat, colWidths=[60*mm]) ha_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),HA_COL), ("BACKGROUND",(0,1),(0,1),HA_BG), ("BOX",(0,0),(-1,-1),1.5,HA_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) hb_treat = [ [Paragraph("HAEMOPHILIA B TREATMENT", th)], [Paragraph( "1. <b>FIX Concentrate</b> (recombinant)<br/>" "2. Extended half-life FIX products<br/>" " (dosing: 1–2× per week only)<br/>" "3. <b>Gene therapy</b>: SPK-9001/Fidanacogene<br/>" " One-time IV infusion → near cure<br/>" " (FIX Padua variant: very high efficiency)<br/>" "4. Tranexamic acid: adjunct<br/>" "5. No DDAVP (doesn't help FIX deficiency)", tb)], ] hb_t = Table(hb_treat, colWidths=[60*mm]) hb_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),HB_COL), ("BACKGROUND",(0,1),(0,1),HB_BG), ("BOX",(0,0),(-1,-1),1.5,HB_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) vwd_treat = [ [Paragraph("vWD TREATMENT", th)], [Paragraph( "<b>Type 1 vWD (mild–moderate):</b><br/>" "1. <b>DDAVP</b> (Desmopressin): first-line<br/>" " Releases stored vWF + FVIII<br/>" " IV or intranasal spray<br/>" "2. Tranexamic acid: mucosal bleeds<br/><br/>" "<b>Type 2 & 3 vWD:</b><br/>" "3. <b>vWF Concentrate</b> (Humate-P)<br/>" " Contains both vWF and FVIII<br/>" "4. OCP / hormones: menorrhagia in girls", tb)], ] vwd_t = Table(vwd_treat, colWidths=[60*mm]) vwd_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),VWD_COL), ("BACKGROUND",(0,1),(0,1),VWD_BG), ("BOX",(0,0),(-1,-1),1.5,VWD_COL), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),6), ("RIGHTPADDING",(0,0),(-1,-1),6), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) sp = Paragraph("", ms("TRSP",fontSize=1)) treat_outer = Table([[ha_t, sp, hb_t, sp, vwd_t]], colWidths=[60*mm,5*mm,60*mm,5*mm,60*mm]) treat_outer.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("TOPPADDING",(0,0),(-1,-1),0), ("BOTTOMPADDING",(0,0),(-1,-1),0), ("LEFTPADDING",(0,0),(-1,-1),0), ("RIGHTPADDING",(0,0),(-1,-1),0), ])) treat_banner = Table([[Paragraph("TREATMENT SUMMARY", ms("TRBN3", fontSize=10.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))]], colWidths=[190*mm]) treat_banner.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),6), ("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(treat_banner) story.append(treat_outer) story.append(Spacer(1, 4*mm)) # ── FOOTER ──────────────────────────────────────────────────────────────── foot_data = [[Paragraph( "Sources: Sabiston Textbook of Surgery | Tintinalli's Emergency Medicine | Harrison's Internal Medicine 22e | " "Emery's Medical Genetics | Goldman-Cecil Medicine • Compiled by Orris Medical AI | August 2026", FOOT_S)]] foot_tbl = Table(foot_data, colWidths=[190*mm]) foot_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),LIGHT_GREY), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),8), ("RIGHTPADDING",(0,0),(-1,-1),8), ("BOX",(0,0),(-1,-1),0.5,colors.grey), ])) story.append(foot_tbl) doc.build(story) print(f"PDF created: {OUTPUT}") PYEOF

Your PDF is ready! Here is your download link:

Haemophilia Types Paeds

PDF Document · PDF


What's Inside (2 Pages, 20 Points in 5 Categories)

The 3 Conditions Compared Side-by-Side

🔴 Haemophilia A🔵 Haemophilia B🟢 von Willebrand Disease
Factor MissingFactor VIII (8)Factor IX (9)von Willebrand Factor (vWF)
GeneticsX-linked recessiveX-linked recessiveAutosomal dominant/recessive
Who gets it?Boys onlyBoys onlyBoys AND girls equally
Type of bleedDeep (joints, muscles)Deep (joints, muscles)Mucosal (nose, gums, periods)
aPTTProlongedProlongedNormal (Type 3: prolonged)
Bleeding timeNormalNormalProlonged
TreatmentFVIII or EmicizumabFIX concentrateDDAVP (Type 1) / vWF conc

Page 1 - Main Table (20 Points, 5 Categories)

CategoryColourPointsTopics
A - Basic ScienceBlue1-3Full names, deficient factor, inheritance
B - Clinical FeaturesMaroon4-8Prevalence, type of bleeding, haemarthrosis, severity grading, when it presents
C - Lab & DiagnosisPurple9-13PT, aPTT, bleeding time, specific factor assay, mixing study
D - Special ScenariosTeal14-16Inhibitors (antibody complication), intracranial haemorrhage, carrier females
E - Treatment & PrognosisGreen17-20Factor replacement, additional agents, prophylaxis, prognosis

Page 2 - Memory Aids & Pearls

  • 3 mnemonics (one per condition) in colour-coded side-by-side boxes
  • "Why A vs B is confusing" - dedicated clarity box explaining they are clinically identical and only a factor assay distinguishes them
  • 5 Golden Rules (deep vs. mucosal, aPTT + bleeding time, sex matters, haemarthrosis = haemophilia, factor assay is definitive)
  • Quick Lab Cheat Sheet (PT, aPTT, bleeding time, platelet count, FVIII, FIX, vWF:Ag, vWF activity, mixing study)
  • Treatment Summary for all 3 conditions including gene therapy for Haemophilia B

DO THE SAME FORR NEPHROTIC SYNDROME IN PEADS VS ACUTE GLOMERULONEPHRITIS

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/nephrotic-vs-agn && python3 << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.lib.styles import ParagraphStyle from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak) from reportlab.lib.enums import TA_CENTER, TA_LEFT OUTPUT = "/tmp/workspace/nephrotic-vs-agn/NephroticSyndrome_vs_AGN_Paeds.pdf" doc = SimpleDocTemplate( OUTPUT, pagesize=A4, rightMargin=17*mm, leftMargin=17*mm, topMargin=16*mm, bottomMargin=16*mm, title="Nephrotic Syndrome vs AGN in Paediatrics", author="Orris Medical Education" ) # ── Colours ──────────────────────────────────────────────────────────────── NS_COL = colors.HexColor("#1565C0") # deep blue – Nephrotic Syndrome AGN_COL = colors.HexColor("#B71C1C") # deep red – AGN NS_BG = colors.HexColor("#E3F2FD") AGN_BG = colors.HexColor("#FFEBEE") NS_MID = colors.HexColor("#BBDEFB") AGN_MID = colors.HexColor("#FFCDD2") WHITE = colors.white DARK_GREY = colors.HexColor("#263238") LIGHT_GREY= colors.HexColor("#ECEFF1") GOLD = colors.HexColor("#F57F17") PURPLE = colors.HexColor("#4A148C") ORANGE_BG = colors.HexColor("#FFF3E0") ORANGE = colors.HexColor("#E65100") GREEN = colors.HexColor("#1B5E20") GREEN_BG = colors.HexColor("#E8F5E9") TEAL = colors.HexColor("#006064") TEAL_BG = colors.HexColor("#E0F7FA") CAT_A = colors.HexColor("#01579B") CAT_B = colors.HexColor("#880E4F") CAT_C = colors.HexColor("#4A148C") CAT_D = colors.HexColor("#006064") CAT_E = colors.HexColor("#1B5E20") def ms(name, **kw): return ParagraphStyle(name, **kw) TITLE_S = ms("TS", fontSize=21, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=27) SUBT_S = ms("SS", fontSize=10.5, fontName="Helvetica", textColor=colors.HexColor("#CFD8DC"), alignment=TA_CENTER, leading=15) FEAT_S = ms("FS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=13, alignment=TA_LEFT) NS_S = ms("NSS", fontSize=9.5, fontName="Helvetica", textColor=NS_COL, leading=13, alignment=TA_LEFT) AGN_S = ms("AGNS",fontSize=9.5, fontName="Helvetica", textColor=AGN_COL, leading=13, alignment=TA_LEFT) NUM_S = ms("NMS", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) HDR_S = ms("HdS", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=13) DEF_S = ms("DS", fontSize=9, fontName="Helvetica", textColor=DARK_GREY, leading=14, alignment=TA_LEFT) BOLD_S = ms("BLS", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=14) FOOT_S = ms("FoS", fontSize=7.5, fontName="Helvetica-Oblique", textColor=colors.grey, alignment=TA_CENTER) COL_W = [8*mm, 9*mm, 38*mm, 67*mm, 70*mm] # ═══════════════════════════════════════════════════════════════════════════ # 20 POINTS — 5 CATEGORIES # A – Basic Science (1–3) # B – Clinical Features (4–9) # C – Urine & Lab Findings (10–14) # D – Complications (15–17) # E – Treatment & Prognosis (18–20) # ═══════════════════════════════════════════════════════════════════════════ cat_names_map = { "A": "CATEGORY A — BASIC SCIENCE (What Goes Wrong at the Glomerulus?)", "B": "CATEGORY B — CLINICAL FEATURES (What Does the Child Look Like?)", "C": "CATEGORY C — URINE & LABORATORY FINDINGS (What Do Tests Show?)", "D": "CATEGORY D — COMPLICATIONS (What Can Go Wrong?)", "E": "CATEGORY E — TREATMENT & PROGNOSIS (How Do We Manage?)", } points = [ # no, cat, cat_col, feature, NS_text, AGN_text # ── CAT A ────────────────────────────────────────────────────────────── ("1","A",CAT_A, "Full Name", "Nephrotic Syndrome (NS)\n• A SYNDROME (not a disease)\n• Collection of signs from\n massive protein loss in urine", "Acute Glomerulonephritis (AGN)\nAlso called:\nPost-Infectious GN (PIGN)\nPost-Streptococcal GN (PSGN)"), ("2","A",CAT_A, "Core Glomerular\nDefect\n(Pathophysiology)", "INCREASED PERMEABILITY to protein\n• Podocyte (foot process) injury\n→ Glomerulus acts like a leaky sieve\n→ Proteins pour into urine\n→ Loss of albumin, immunoglobulins,\n complement, clotting factors", "INFLAMMATION of glomerulus\n• Immune complex deposition\n (antigen-antibody complexes)\n→ Complement activation → injury\n→ Inflammatory cells → block\n glomerular filtration\n→ Haematuria + reduced GFR"), ("3","A",CAT_A, "Trigger / Cause", "Idiopathic (most common in children)\n• Minimal Change Disease (MCD):\n 90% of cases under 10 years!\n• Other: FSGS, Membranous GN\n• Secondary: SLE, drugs, infections\nT-cell dysfunction releases\ncytokine → injures podocytes", "Follows an INFECTION\n• Group A β-haemolytic Streptococcus\n (GABHS) most common:\n → Strep throat (pharyngitis) OR\n → Impetigo (skin infection)\n → 1–3 weeks before GN onset\n• Also: other bacteria, viruses"), # ── CAT B ────────────────────────────────────────────────────────────── ("4","B",CAT_B, "Typical Age &\nSex", "Peak age: 2–6 years\n(preschool child)\nBoys > Girls (2:1)\n→ Younger child with puffy face", "Peak age: 5–12 years\n(school-age child)\nBoys > Girls (2:1)\n→ Older child after sore throat\n or skin infection"), ("5","B",CAT_B, "Oedema\n(Swelling) –\nKEY FEATURE", "MASSIVE, PITTING oedema\n• Periorbital oedema (worst in morning)\n = child's face is puffy on waking\n• Scrotal / labial oedema\n• Ascites (fluid in abdomen)\n• Pleural effusion\nCaused by: low albumin\n→ low oncotic pressure\n→ fluid leaks into tissues", "MILD to MODERATE oedema\n• Periorbital puffiness (less severe)\n• Facial oedema\n• Generally much less oedema\n than nephrotic syndrome\nCaused by: salt & water retention\n(low GFR → oliguria → fluid overload)"), ("6","B",CAT_B, "Hypertension\n(High Blood Pressure)", "USUALLY ABSENT or MILD\n• Hypertension is ATYPICAL\n• If present → suspect FSGS\n or atypical NS requiring biopsy\n• BP is usually normal", "PRESENT and often SIGNIFICANT\n• Hypertension in 60–80% of cases\n• Can be severe → hypertensive\n encephalopathy (headache, fits)\n• Caused by fluid overload +\n RAAS activation"), ("7","B",CAT_B, "Urine Appearance\n(What Parent Notices)", "Urine appears FROTHY/FOAMY\n(due to massive proteinuria)\nColour: normal (pale yellow)\nNOT red or cola-coloured", "Urine appears DARK / RED /\nCOLA-COLOURED (\"smoky urine\")\nDue to: HAEMATURIA\n(blood in urine)\nFoaming less prominent"), ("8","B",CAT_B, "Fever / Systemic\nIllness", "NO fever (unless secondary\ninfection complicating NS)\nChild may appear unwell\ndue to oedema, not infection", "Preceding illness (sore throat /\nskin infection) 1–3 weeks earlier\nFever may be present\nduring the acute phase"), ("9","B",CAT_B, "Oliguria /\nReduced Urine", "Urine output may be reduced\n(due to low albumin → reduced\neffective circulating volume)\nSevere cases: oliguria", "OLIGURIA is common & prominent\n• Reduced GFR → less filtration\n• Dark concentrated urine\n• Anuria in severe cases\n→ risk of AKI (acute kidney injury)"), # ── CAT C ────────────────────────────────────────────────────────────── ("10","C",CAT_C, "Urine Protein\n(Proteinuria)", "MASSIVE PROTEINURIA\n• Urine dipstick: 3+ or 4+ protein\n• >40 mg/m²/hr\n• Urine protein:creatinine ratio\n >2.0 mg/mg\n= HALLMARK of nephrotic syndrome", "MILD to MODERATE proteinuria\n• Urine dipstick: 1+ or 2+ protein\n• Proteinuria present but NOT\n in the nephrotic range\n• Not the dominant finding"), ("11","C",CAT_C, "Urine Blood\n(Haematuria)", "Usually ABSENT\n• Microscopic haematuria in ~20%\n (may occur but not dominant)\n• Macroscopic haematuria UNUSUAL\n• Red urine → think AGN instead!", "HALLMARK OF AGN\n• Macroscopic haematuria: cola/brown\n• Microscopic haematuria: always\n• RBC CASTS in urine microscopy\n = definitive sign of GN\n (red cell casts = glomerular injury)"), ("12","C",CAT_C, "Serum Albumin", "LOW (Hypoalbuminaemia)\n• Serum albumin <2.5 g/dL\n (often <1.5 g/dL in severe NS)\n• Defines nephrotic syndrome\n• Due to: protein lost in urine\n + increased catabolism", "NORMAL albumin\n(No significant protein loss\nin typical AGN)\nAlbumin is NOT the problem\nin glomerulonephritis"), ("13","C",CAT_C, "Serum Cholesterol\n& Lipids", "ELEVATED (Hyperlipidaemia)\n• High total cholesterol\n• High LDL, high triglycerides\n• Compensatory hepatic\n lipoprotein production\n (response to low oncotic pressure)\n• Lipiduria (fat in urine) also seen", "NORMAL cholesterol\nHyperlipidaemia is NOT\na feature of AGN\n(This is a useful differentiator\nfrom nephrotic syndrome)"), ("14","C",CAT_C, "Complement C3\n& Strep Markers", "NORMAL C3, C4\n(Complement levels normal\nin typical idiopathic NS)\nASO titre: negative\n(not strep-related)\nIf C3 is low → suspect MPGN\nor SLE → biopsy required", "LOW C3 (hypocomplementaemia)\n• C3 is consumed by immune\n complex deposition\n• C3 returns to normal\n in 6–8 weeks (important!)\nASO titre: HIGH\n(evidence of Strep infection)\nStreptozyme test: positive"), # ── CAT D ────────────────────────────────────────────────────────────── ("15","D",CAT_D, "Infection Risk\n(Complication)", "HIGH risk of serious infection\n• Low IgG (lost in urine)\n• Low complement\n→ Spontaneous Bacterial\n Peritonitis (SBP): 2–6% risk\n (Strep pneumoniae, E. coli)\n→ Cellulitis, sepsis\nPneumococcal vaccine important", "Infection is the CAUSE, not\na major ongoing complication\nMay get recurrence of Strep\nProphylactic penicillin if\nrecurrent Strep infections\n(prevent further GN episodes)"), ("16","D",CAT_D, "Thrombosis Risk\n(Clotting Complication)", "HIGH thrombosis risk\n• Lost anticoagulant proteins\n (antithrombin III, protein C, S)\n in urine\n• Raised fibrinogen (pro-clot)\n• Risk: renal vein thrombosis,\n DVT, pulmonary embolism\n• Treat: anticoagulation if clot", "LOW thrombosis risk\n(Thromboembolism is NOT\na major feature of AGN)\nMain complication is:\nfluid overload → HTN →\nhypertensive encephalopathy"), ("17","D",CAT_D, "Renal Function /\nAKI Risk", "Usually NORMAL GFR initially\n• AKI rare in pure NS\n• Can develop if severe\n hypovolaemia (albumin very low)\n• Chronic kidney disease:\n risk in FSGS, SRNS\nRenal failure uncommon\nin MCNS", "GFR is REDUCED (AKI is common)\n• Oliguria, rising creatinine\n• Fluid overload + hypertension\n• Usually REVERSIBLE\n• Resolves as inflammation settles\n• <1% progress to RPGN\n (rapidly progressive GN)"), # ── CAT E ────────────────────────────────────────────────────────────── ("18","E",CAT_E, "Specific Treatment\n(First-Line)", "CORTICOSTEROIDS\n• Prednisolone 60 mg/m²/day or\n 2 mg/kg/day (max 60 mg/day)\n• Daily for 4–6 weeks\n• Then alternate-day, taper\n over 6 weeks\n• 90% of MCNS → REMISSION\n within 8 weeks = steroid sensitive", "SUPPORTIVE TREATMENT\n(Most AGN resolves spontaneously!)\n• Fluid restriction + salt restriction\n• Antihypertensives: amlodipine\n or nifedipine (avoid ACEi acute)\n• Furosemide (loop diuretic) for\n fluid overload\n• Antibiotics: penicillin to eradicate\n residual Strep infection"), ("19","E",CAT_E, "Steroid-Sparing /\nSecond-Line", "For FREQUENTLY RELAPSING NS:\n• Levamisole (immunomodulator)\n• Cyclophosphamide (alkylating)\n• Ciclosporin / Tacrolimus (CNI)\n• MMF (mycophenolate mofetil)\n• Rituximab (anti-CD20 monoclonal)\nFor STEROID-RESISTANT NS:\n→ Kidney biopsy essential\n→ CNI + ACEi/ARB for proteinuria", "No steroid treatment for\ntypical PSGN\n(Steroids are NOT indicated\nin post-infectious GN)\nIf RPGN: high-dose IV methylpred\n+ plasmapheresis\nNephrologist referral if:\n→ No improvement in 3–4 weeks\n→ AKI not resolving\n→ Hypertension uncontrolled"), ("20","E",CAT_E, "Prognosis", "MCNS: EXCELLENT\n• 90% remission with steroids\n• ~50% relapse (manage relapses)\n• Up to 85% achieve long-term\n remission eventually\n• Very few → CKD/ESRD\nFSGS/SRNS: guarded prognosis\n→ Risk of CKD and ESRD", "EXCELLENT for typical PSGN\n• >95% fully recover\n• Haematuria resolves in weeks\n• Hypertension settles in 1–2 wks\n• C3 normalises in 6–8 weeks\n• Proteinuria may persist months\n• <1% progress to chronic GN\nLong-term renal function: normal"), ] # ═══════════════════════════════════════════════════════════════════════════ story = [] # ── TITLE ───────────────────────────────────────────────────────────────── t_data = [ [Paragraph("NEPHROTIC SYNDROME vs ACUTE GLOMERULONEPHRITIS", TITLE_S)], [Paragraph("IN PAEDIATRICS", ms("TS2", fontSize=14, fontName="Helvetica-Bold", textColor=colors.HexColor("#90CAF9"), alignment=TA_CENTER, leading=18))], [Paragraph("20 Must-Know Points | Categorised & Chunked | Simple Language | Medical Terms Preserved", SUBT_S)], ] t_tbl = Table(t_data, colWidths=[192*mm]) t_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),8), ("BOTTOMPADDING",(0,0),(-1,-1),8), ("LEFTPADDING",(0,0),(-1,-1),8), ("RIGHTPADDING",(0,0),(-1,-1),8), ])) story.append(t_tbl) story.append(Spacer(1, 4*mm)) # ── DEFINITIONS ─────────────────────────────────────────────────────────── def_data = [ [Paragraph("QUICK DEFINITIONS", BOLD_S)], [Paragraph( "<b>Nephrotic Syndrome (NS):</b> A clinical syndrome of <b>massive proteinuria</b> (>3.5 g/day in adults, " ">40 mg/m²/hr in children) + <b>hypoalbuminaemia</b> + <b>oedema</b> + <b>hyperlipidaemia</b>. " "The glomerulus is leaking protein. Most common cause in children: <b>Minimal Change Disease (MCD)</b>.", DEF_S)], [Paragraph( "<b>Acute Glomerulonephritis (AGN):</b> Inflammation of the glomeruli, usually triggered by an infection. " "Classic = <b>Post-Streptococcal GN (PSGN)</b> after strep throat/impetigo. " "Presents with <b>haematuria</b> (cola-coloured urine), <b>hypertension</b>, <b>oliguria</b>, and mild oedema.", DEF_S)], [Paragraph( "<b>WHY CONFUSE THEM?</b> Both present with <b>oedema</b> (puffy face/body) in a child, and both involve " "the kidney's filtration units (glomeruli). But the underlying problem and the dominant signs are " "<b>completely opposite</b> — NS = leaks protein; AGN = leaks blood.", DEF_S)], [Paragraph( "<b>ONE-LINE RULE:</b> \"Nephrotic = <b>PROTEIN in urine</b> (foamy urine, puffy face, low albumin). " "Nephritic/AGN = <b>BLOOD in urine</b> (cola urine, hypertension, RBC casts).\"", ms("OLR", fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY, leading=14))], ] d_tbl = Table(def_data, colWidths=[192*mm]) d_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),LIGHT_GREY), ("TOPPADDING",(0,0),(-1,-1),4), ("BOTTOMPADDING",(0,0),(-1,-1),4), ("LEFTPADDING",(0,0),(-1,-1),10), ("RIGHTPADDING",(0,0),(-1,-1),10), ("BOX",(0,0),(-1,-1),1,DARK_GREY), ])) story.append(d_tbl) story.append(Spacer(1, 4*mm)) # ── LEGEND ──────────────────────────────────────────────────────────────── leg_s = ms("LS", fontSize=8, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12) leg_labels = [ (CAT_A,"A Basic Science\n(1–3)"), (CAT_B,"B Clinical Features\n(4–9)"), (CAT_C,"C Urine & Lab\n(10–14)"), (CAT_D,"D Complications\n(15–17)"), (CAT_E,"E Treatment &\nPrognosis (18–20)"), ] leg_row = [[Paragraph(t, leg_s) for _,t in leg_labels]] leg_tbl = Table(leg_row, colWidths=[38.4*mm]*5) leg_cmds = [ ("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4), ("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3), ("GRID",(0,0),(-1,-1),0.5,WHITE),("VALIGN",(0,0),(-1,-1),"MIDDLE"), ] for i,(c,_) in enumerate(leg_labels): leg_cmds.append(("BACKGROUND",(i,0),(i,0),c)) leg_tbl.setStyle(TableStyle(leg_cmds)) leg_hdr = Table([[Paragraph("CATEGORY LEGEND", ms("LH",fontSize=9,fontName="Helvetica-Bold", textColor=WHITE,alignment=TA_CENTER))]], colWidths=[192*mm]) leg_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4), ])) story.append(leg_hdr) story.append(leg_tbl) story.append(Spacer(1, 3*mm)) # ── MAIN TABLE ──────────────────────────────────────────────────────────── hdr_row = [ Paragraph("#", HDR_S), Paragraph("Cat", HDR_S), Paragraph("FEATURE", HDR_S), Paragraph("🔵 NEPHROTIC SYNDROME\n(Protein Leaker)", HDR_S), Paragraph("🔴 ACUTE GLOMERULONEPHRITIS\n(Blood Leaker / PSGN)", HDR_S), ] final_data = [hdr_row] cat_row_indices = [] prev_cat = None current_cat_col = None for no, cat, cat_col, feat, ns_txt, agn_txt in points: if cat != prev_cat: cat_row = [ Paragraph(cat_names_map[cat], ms(f"CR{cat}", fontSize=9.5, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT, leading=13)), None, None, None, None ] cat_row_indices.append((len(final_data), cat_col)) final_data.append(cat_row) prev_cat = cat current_cat_col = cat_col num_p = Paragraph(f"<b>{no}</b>", NUM_S) cat_p = Paragraph(f"<b>{cat}</b>", ms(f"CP{no}", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=12)) feat_p = Paragraph(feat.replace("\n","<br/>"), FEAT_S) ns_p = Paragraph(ns_txt.replace("\n","<br/>"), NS_S) agn_p = Paragraph(agn_txt.replace("\n","<br/>"), AGN_S) final_data.append([num_p, cat_p, feat_p, ns_p, agn_p]) main_tbl = Table(final_data, colWidths=COL_W, repeatRows=1) ts = [ ("BACKGROUND",(0,0),(-1,0),DARK_GREY), ("BACKGROUND",(3,0),(3,0),NS_COL), ("BACKGROUND",(4,0),(4,0),AGN_COL), ("TOPPADDING",(0,0),(-1,-1),4), ("BOTTOMPADDING",(0,0),(-1,-1),4), ("LEFTPADDING",(0,0),(-1,-1),4), ("RIGHTPADDING",(0,0),(-1,-1),4), ("VALIGN",(0,0),(-1,-1),"TOP"), ("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#B0BEC5")), ] cat_row_set = {r for r,_ in cat_row_indices} for row_idx, cat_col in cat_row_indices: ts += [ ("BACKGROUND",(0,row_idx),(-1,row_idx),cat_col), ("SPAN",(0,row_idx),(-1,row_idx)), ("TOPPADDING",(0,row_idx),(-1,row_idx),5), ("BOTTOMPADDING",(0,row_idx),(-1,row_idx),5), ("LEFTPADDING",(0,row_idx),(-1,row_idx),6), ] current_cat_c = None for i, row in enumerate(final_data): if i == 0: continue if i in cat_row_set: for r,c in cat_row_indices: if r == i: current_cat_c = c; break continue ts += [ ("BACKGROUND",(0,i),(0,i),colors.HexColor("#546E7A")), ("BACKGROUND",(1,i),(1,i),current_cat_c if current_cat_c else DARK_GREY), ("BACKGROUND",(2,i),(2,i),LIGHT_GREY if i%2==0 else WHITE), ("BACKGROUND",(3,i),(3,i),NS_MID if i%2==0 else NS_BG), ("BACKGROUND",(4,i),(4,i),AGN_MID if i%2==0 else AGN_BG), ("TEXTCOLOR",(0,i),(0,i),WHITE), ("TEXTCOLOR",(1,i),(1,i),WHITE), ] main_tbl.setStyle(TableStyle(ts)) story.append(main_tbl) story.append(Spacer(1,5*mm)) # ═══════════════════════════════════════════════════════════════════════════ # PAGE 2 # ═══════════════════════════════════════════════════════════════════════════ story.append(PageBreak()) p2_hdr = Table([[Paragraph("MEMORY AIDS, CLINICAL PEARLS & LAB CHEAT SHEET", ms("P2H",fontSize=12,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER))]], colWidths=[192*mm]) p2_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),7),("BOTTOMPADDING",(0,0),(-1,-1),7), ])) story.append(p2_hdr) story.append(Spacer(1,4*mm)) # ── MNEMONICS ───────────────────────────────────────────────────────────── ns_mnem = [ [Paragraph('NS = "PHALE" (Protein + Hypo-albumin + Anaemia Low + Lipids + Edema)', ms("NSM",fontSize=9.5,fontName="Helvetica-Bold",textColor=NS_COL,leading=13))], [Paragraph( "Or use: <b>\"POAHE\"</b><br/>" "• <b>P</b>roteinuria (massive, 3–4+ on dipstick)<br/>" "• <b>O</b>edema (periorbital, pitting, ascites)<br/>" "• <b>A</b>lbumin LOW (hypoalbuminaemia)<br/>" "• <b>H</b>yperlipidaemia (high cholesterol)<br/>" "• <b>E</b>xcretion of lipids (lipiduria)<br/><br/>" "<b>Key image:</b> Preschool boy with puffy eyes\nin the morning + frothy urine", ms("NSMB",fontSize=8.5,fontName="Helvetica",textColor=NS_COL,leading=13))], ] ns_m = Table(ns_mnem, colWidths=[92*mm]) ns_m.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),NS_BG), ("BOX",(0,0),(-1,-1),1.5,NS_COL), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ("LEFTPADDING",(0,0),(-1,-1),7),("RIGHTPADDING",(0,0),(-1,-1),7), ])) agn_mnem = [ [Paragraph('AGN = "CHOP" (Cola urine + Hypertension + Oliguria + Post-strep)', ms("AGNM",fontSize=9.5,fontName="Helvetica-Bold",textColor=AGN_COL,leading=13))], [Paragraph( "• <b>C</b>ola / smoky urine (haematuria)<br/>" "• <b>H</b>ypertension (significant, may cause fits)<br/>" "• <b>O</b>liguria (dark, reduced urine output)<br/>" "• <b>P</b>ost-strep (1–3 weeks after throat/skin infection)<br/><br/>" "ALSO: Low <b>C3</b> + High <b>ASO titre</b><br/>" "RBC CASTS in urine = pathognomonic of GN<br/><br/>" "<b>Key image:</b> School-age child with\ncola-coloured urine after sore throat", ms("AGNMB",fontSize=8.5,fontName="Helvetica",textColor=AGN_COL,leading=13))], ] agn_m = Table(agn_mnem, colWidths=[92*mm]) agn_m.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),AGN_BG), ("BOX",(0,0),(-1,-1),1.5,AGN_COL), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ("LEFTPADDING",(0,0),(-1,-1),7),("RIGHTPADDING",(0,0),(-1,-1),7), ])) sp = Paragraph("",ms("SP",fontSize=1)) mnem_out = Table([[ns_m,sp,agn_m]], colWidths=[92*mm,8*mm,92*mm]) mnem_out.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0), ("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0), ])) story.append(mnem_out) story.append(Spacer(1,5*mm)) # ── THE TETRAD BOX ──────────────────────────────────────────────────────── tetrad_data = [ [Paragraph("THE NEPHROTIC TETRAD vs THE NEPHRITIC TRIAD — Master This!", ms("TETRAD_H",fontSize=10,fontName="Helvetica-Bold",textColor=ORANGE,leading=14))], [Paragraph( "<b>NEPHROTIC SYNDROME Tetrad (all 4 together):</b><br/>" "&nbsp;&nbsp;1. <b>Massive Proteinuria</b> (>3.5 g/day) — 'leaky sieve for protein'<br/>" "&nbsp;&nbsp;2. <b>Hypoalbuminaemia</b> (serum albumin <2.5 g/dL)<br/>" "&nbsp;&nbsp;3. <b>Oedema</b> (massive pitting — periorbital, ascites, scrotal)<br/>" "&nbsp;&nbsp;4. <b>Hyperlipidaemia</b> (raised cholesterol + lipiduria)<br/><br/>" "<b>NEPHRITIC SYNDROME Triad (AGN):</b><br/>" "&nbsp;&nbsp;1. <b>Haematuria</b> (RBC in urine — cola/smoky coloured urine + RBC casts)<br/>" "&nbsp;&nbsp;2. <b>Hypertension</b> (elevated BP — fluid retention + RAAS)<br/>" "&nbsp;&nbsp;3. <b>Oliguria</b> (reduced urine output — GFR reduced by inflammation)", ms("TETRAD_B",fontSize=9,fontName="Helvetica",textColor=DARK_GREY,leading=14))], ] tet_tbl = Table(tetrad_data, colWidths=[192*mm]) tet_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),ORANGE_BG), ("BOX",(0,0),(-1,-1),1.5,ORANGE), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ("LEFTPADDING",(0,0),(-1,-1),10),("RIGHTPADDING",(0,0),(-1,-1),10), ])) story.append(tet_tbl) story.append(Spacer(1,5*mm)) # ── 5 GOLDEN RULES ──────────────────────────────────────────────────────── rules = [ ("Rule 1 – Protein vs Blood", "NS = massive <b>PROTEIN</b> in urine (foamy urine, low albumin). AGN = <b>BLOOD</b> in urine (cola-coloured, RBC casts). " "Dipstick tells you immediately: 4+ protein = NS; haematuria + mild protein = AGN."), ("Rule 2 – Hypertension Points to AGN", "<b>Significant hypertension</b> in a child with oedema = think AGN first. " "Hypertension in NS is atypical — if present in NS it is a red flag suggesting FSGS and warrants a kidney biopsy."), ("Rule 3 – C3 is the Separator", "<b>Low C3 + high ASO titre</b> = Post-Streptococcal GN (confirmed). " "<b>Normal C3</b> = Nephrotic Syndrome (typical MCNS). " "Always measure C3 when the diagnosis is uncertain. C3 returns to normal in 6–8 weeks in PSGN."), ("Rule 4 – Age Rule", "Child aged <b>2–6 years</b> with oedema and no blood in urine → Nephrotic Syndrome (MCNS). " "Child aged <b>5–12 years</b> with history of sore throat and cola urine → AGN (PSGN). Age guides your suspicion."), ("Rule 5 – Steroids for NS, Supportive for AGN", "NS (MCNS): start <b>prednisolone</b> empirically. 90% respond. " "AGN: <b>NO steroids</b> for typical PSGN. Treatment is supportive (fluid restriction, antihypertensives, diuretics). " "Steroids only if rapidly progressive GN (RPGN)."), ] r_head = ms("RHS",fontSize=9.5,fontName="Helvetica-Bold",textColor=GOLD,leading=14) r_body = ms("RBS",fontSize=9,fontName="Helvetica",textColor=DARK_GREY,leading=14) rules_data = [[Paragraph(t,r_head),Paragraph(b,r_body)] for t,b in rules] rules_tbl = Table(rules_data, colWidths=[52*mm,140*mm]) rules_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),GREEN_BG), ("BOX",(0,0),(-1,-1),1.5,GREEN), ("LINEBELOW",(0,0),(-1,-4),0.5,colors.HexColor("#A5D6A7")), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),8),("RIGHTPADDING",(0,0),(-1,-1),8), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) golden_hdr = Table([[Paragraph("5 GOLDEN CLINICAL RULES",ms("GH", fontSize=10.5,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER))]], colWidths=[192*mm]) golden_hdr.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),GREEN), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(golden_hdr) story.append(rules_tbl) story.append(Spacer(1,5*mm)) # ── LAB CHEAT SHEET ─────────────────────────────────────────────────────── lh = ms("LH",fontSize=9,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER,leading=12) lf = ms("LF",fontSize=8.5,fontName="Helvetica-Bold",textColor=DARK_GREY,leading=12) ln = ms("LN",fontSize=8.5,fontName="Helvetica",textColor=NS_COL,leading=12) la = ms("LA",fontSize=8.5,fontName="Helvetica",textColor=AGN_COL,leading=12) lab_rows = [ [Paragraph("Test",lh), Paragraph("Nephrotic Syndrome",lh), Paragraph("Acute GN (PSGN)",lh)], [Paragraph("Urine protein",lf), Paragraph("4+ (massive, >40 mg/m²/hr)",ln), Paragraph("1–2+ (mild–moderate)",la)], [Paragraph("Urine blood",lf), Paragraph("Absent or trace",ln), Paragraph("3–4+ (haematuria)",la)], [Paragraph("RBC casts in urine",lf),Paragraph("ABSENT",ln), Paragraph("PRESENT (diagnostic of GN!)",la)], [Paragraph("Serum albumin",lf), Paragraph("LOW (<2.5 g/dL)",ln), Paragraph("NORMAL",la)], [Paragraph("Serum cholesterol",lf), Paragraph("HIGH (hyperlipidaemia)",ln), Paragraph("NORMAL",la)], [Paragraph("Blood pressure",lf), Paragraph("Normal (HTN = atypical)",ln), Paragraph("ELEVATED (common)",la)], [Paragraph("Serum C3",lf), Paragraph("NORMAL",ln), Paragraph("LOW (hypocomplementaemia)",la)], [Paragraph("ASO titre / Streptozyme",lf), Paragraph("NEGATIVE",ln), Paragraph("ELEVATED / POSITIVE",la)], [Paragraph("Serum creatinine/BUN",lf), Paragraph("Usually normal",ln), Paragraph("Elevated (AKI common)",la)], [Paragraph("Urine output",lf), Paragraph("Normal or mildly reduced",ln), Paragraph("OLIGURIA (prominent)",la)], [Paragraph("Kidney biopsy",lf), Paragraph("NOT routinely needed in MCNS;\nneeded if atypical / SRNS",ln), Paragraph("NOT routinely needed in PSGN;\nneeded if RPGN or no improvement",la)], ] lab_tbl = Table(lab_rows, colWidths=[55*mm,68*mm,69*mm]) lab_ts = [ ("BACKGROUND",(0,0),(-1,0),DARK_GREY), ("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#90A4AE")), ("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4), ("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),4), ("VALIGN",(0,0),(-1,-1),"TOP"), ] for i in range(1,len(lab_rows)): lab_ts += [ ("BACKGROUND",(0,i),(0,i),LIGHT_GREY if i%2==0 else WHITE), ("BACKGROUND",(1,i),(1,i),NS_MID if i%2==0 else NS_BG), ("BACKGROUND",(2,i),(2,i),AGN_MID if i%2==0 else AGN_BG), ] lab_tbl.setStyle(TableStyle(lab_ts)) lab_banner = Table([[Paragraph("QUICK LAB CHEAT SHEET",ms("LBH", fontSize=10.5,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER))]], colWidths=[192*mm]) lab_banner.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),PURPLE), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(lab_banner) story.append(lab_tbl) story.append(Spacer(1,5*mm)) # ── TREATMENT SIDE-BY-SIDE ──────────────────────────────────────────────── th = ms("TH",fontSize=9.5,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER,leading=13) tb = ms("TB",fontSize=8.5,fontName="Helvetica",textColor=DARK_GREY,leading=13) ns_treat = [ [Paragraph("NEPHROTIC SYNDROME TREATMENT",th)], [Paragraph( "<b>1st Episode (MCNS – steroid sensitive):</b><br/>" "• Prednisolone 60 mg/m²/day (max 60 mg) × 4–6 wks<br/>" "• Then alternate-day taper × 6 wks<br/>" "• 90% achieve remission within 8 weeks<br/><br/>" "<b>Supportive:</b><br/>" "• Low-salt diet (reduce oedema)<br/>" "• Fluid restriction if hyponatraemia<br/>" "• Albumin + furosemide: severe oedema<br/><br/>" "<b>Relapsing NS:</b><br/>" "• Levamisole / Cyclophosphamide<br/>" "• Ciclosporin / MMF / Rituximab<br/><br/>" "<b>Steroid-resistant NS:</b><br/>" "• Kidney biopsy → CNI ± ACEi/ARB", tb)], ] ns_t = Table(ns_treat, colWidths=[92*mm]) ns_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),NS_COL), ("BACKGROUND",(0,1),(0,1),NS_BG), ("BOX",(0,0),(-1,-1),1.5,NS_COL), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),7),("RIGHTPADDING",(0,0),(-1,-1),7), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) agn_treat = [ [Paragraph("ACUTE GN (PSGN) TREATMENT",th)], [Paragraph( "<b>Mainly SUPPORTIVE — most resolve on own:</b><br/>" "• Fluid restriction + low-salt diet<br/>" "• Furosemide (loop diuretic) for oedema<br/><br/>" "<b>Hypertension:</b><br/>" "• Amlodipine (CCB) or nifedipine<br/>" "• Avoid ACEi/ARBs in acute AKI phase<br/><br/>" "<b>Antibiotics:</b><br/>" "• Penicillin V (10 days) — eradicate<br/>" " residual Strep, prevent spread<br/>" " (does NOT alter GN course)<br/><br/>" "<b>NO STEROIDS in typical PSGN</b><br/><br/>" "<b>If RPGN:</b><br/>" "• IV methylprednisolone pulse<br/>" "• Plasma exchange (plasmapheresis)<br/>" "• Urgent nephrologist referral", tb)], ] agn_t = Table(agn_treat, colWidths=[92*mm]) agn_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),AGN_COL), ("BACKGROUND",(0,1),(0,1),AGN_BG), ("BOX",(0,0),(-1,-1),1.5,AGN_COL), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),7),("RIGHTPADDING",(0,0),(-1,-1),7), ("VALIGN",(0,0),(-1,-1),"TOP"), ])) treat_out = Table([[ns_t,sp,agn_t]], colWidths=[92*mm,8*mm,92*mm]) treat_out.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0), ("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0), ])) treat_banner = Table([[Paragraph("TREATMENT SUMMARY",ms("TRBN", fontSize=10.5,fontName="Helvetica-Bold",textColor=WHITE,alignment=TA_CENTER))]], colWidths=[192*mm]) treat_banner.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),DARK_GREY), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ])) story.append(treat_banner) story.append(treat_out) story.append(Spacer(1,4*mm)) # ── FOOTER ──────────────────────────────────────────────────────────────── foot_data = [[Paragraph( "Sources: Campbell Walsh Wein Urology 3e | Brenner & Rector's The Kidney | " "National Kidney Foundation Primer 8e | Comprehensive Clinical Nephrology 7e " "• Compiled by Orris Medical AI | August 2026", FOOT_S)]] foot_tbl = Table(foot_data, colWidths=[192*mm]) foot_tbl.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,-1),LIGHT_GREY), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),8),("RIGHTPADDING",(0,0),(-1,-1),8), ("BOX",(0,0),(-1,-1),0.5,colors.grey), ])) story.append(foot_tbl) doc.build(story) print(f"PDF created: {OUTPUT}") PYEOF

Your PDF is ready! Here is your download link:

NephroticSyndrome vs AGN Paeds

PDF Document · PDF


What's Inside (2 Pages, 20 Points in 5 Categories)

The Core One-Line Rule (printed in bold in the PDF)

"Nephrotic = PROTEIN in urine (foamy urine, puffy face, low albumin). Nephritic/AGN = BLOOD in urine (cola urine, hypertension, RBC casts)."

Page 1 - Main Comparison Table (20 Points)

CategoryColourPointsTopics Covered
A - Basic ScienceBlue1-3Full names, glomerular defect (leaky sieve vs inflammation), trigger/cause
B - Clinical FeaturesMaroon4-9Age/sex, oedema (massive vs mild), hypertension (absent vs prominent), urine colour (frothy vs cola), fever, oliguria
C - Urine & LabPurple10-14Proteinuria levels, haematuria, serum albumin, cholesterol, C3 complement + ASO titre
D - ComplicationsTeal15-17Infection risk (SBP), thrombosis risk (renal vein thrombosis), AKI/renal function
E - Treatment & PrognosisGreen18-20Steroids for NS vs supportive for AGN, second-line agents, prognosis (90% remission NS; >95% recovery AGN)

Page 2 - Memory Aids & Pearls

  • NS mnemonic - "POAHE" (Proteinuria, Oedema, Albumin low, Hyperlipidaemia, Excretion of lipids)
  • AGN mnemonic - "CHOP" (Cola urine, Hypertension, Oliguria, Post-strep)
  • The Nephrotic Tetrad vs Nephritic Triad - dedicated orange box with all 7 features laid out clearly
  • 5 Golden Rules (protein vs blood, hypertension points to AGN, C3 is the separator, age rule, steroids for NS not AGN)
  • Quick Lab Cheat Sheet - 12 tests side-by-side including RBC casts, C3, ASO titre, albumin, cholesterol
  • Treatment Summary side-by-side with full drug names and special note: "NO STEROIDS in typical PSGN"

DO THE SAME FOR HYPERTHYROIDISM VS CONGENITAL HYPOTHYROIDISM IN PEADS

Finding Sources
Finding Sources
Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.