Hi
Am working as mbbs intern
Yes i want all
"Patient with chest pain, BP 90/60, diaphoresis - what do I do?"
"Dose of metformin in a newly diagnosed T2DM patient"
"Explain the mechanism of ACE inhibitors"
"Steps for IV cannulation / pleural tap / lumbar puncture"
"DDx for a young patient with painless jaundice"
"What labs to order for suspected sepsis?"
If patuentvcame with sore throat
| Cause | Frequency | Clue |
|---|---|---|
| Rhinovirus / Coronavirus | ~25% | Common cold symptoms, runny nose, cough |
| Adenovirus | 5% | Fever, conjunctivitis, pharyngitis |
| Group A beta-hemolytic Strep (GABHS) | 5-15% adults, 20-30% children | Exudate, no cough, fever |
| EBV (Mono) | 1-6% young adults | Posterior cervical LN, splenomegaly |
| Influenza A/B | 2% | Myalgia, fever, headache |
| HSV | 4% | Ulcers/vesicles |
| HIV (acute) | Rare | High-risk history |
| Score | GAS Probability | Action |
|---|---|---|
| 0 | 2% | No test, no antibiotic |
| 1 | 3% | No test, no antibiotic |
| 2 | 8% | Do rapid strep test |
| 3 | 19% | Do rapid strep test |
| 4 | 41% | Treat empirically OR rapid test |
In children - always confirm with test even if criteria met, as Centor is less specific in kids.
β οΈ Must complete 7-10 days even if symptoms resolve earlier - shorter courses are less effective for strep!
| Suppurative | Nonsuppurative |
|---|---|
| Peritonsillar abscess | Acute Rheumatic Fever |
| Retropharyngeal abscess | Post-streptococcal glomerulonephritis |
| Otitis media | Scarlet fever |
| Sinusitis |
This is why we treat confirmed strep - to prevent rheumatic fever (especially important in India where prevalence is higher).
Create a quick reference guide on pharyngitis for my internship
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"
mkdir -p /home/daytona/workspace/pharyngitis-guide
~/pharyngitis-guide/create_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import 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 Flowable
# ββ Color palette ββββββββββββββββββββββββββββββββββββββββββββββββββ
DARK_BLUE = colors.HexColor("#1a3a5c")
MED_BLUE = colors.HexColor("#2563a8")
LIGHT_BLUE = colors.HexColor("#dbeafe")
ORANGE = colors.HexColor("#ea580c")
ORANGE_LIGHT= colors.HexColor("#fff7ed")
GREEN = colors.HexColor("#166534")
GREEN_LIGHT = colors.HexColor("#dcfce7")
RED = colors.HexColor("#991b1b")
RED_LIGHT = colors.HexColor("#fee2e2")
YELLOW = colors.HexColor("#854d0e")
YELLOW_LIGHT= colors.HexColor("#fef9c3")
GREY_BG = colors.HexColor("#f1f5f9")
GREY_LINE = colors.HexColor("#cbd5e1")
WHITE = colors.white
BLACK = colors.HexColor("#1e293b")
# ββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def make_style(name, parent='Normal', **kw):
s = ParagraphStyle(name, parent=styles[parent], **kw)
return s
title_style = make_style('DocTitle', fontSize=22, textColor=WHITE,
fontName='Helvetica-Bold', alignment=TA_CENTER,
spaceAfter=4)
subtitle_style = make_style('DocSub', fontSize=11, textColor=colors.HexColor("#bfdbfe"),
fontName='Helvetica', alignment=TA_CENTER, spaceAfter=2)
badge_style = make_style('Badge', fontSize=9, textColor=WHITE,
fontName='Helvetica-Bold', alignment=TA_CENTER)
section_head = make_style('SecHead', fontSize=12, textColor=WHITE,
fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=2, spaceAfter=2)
body = make_style('Body', fontSize=9, textColor=BLACK,
fontName='Helvetica', leading=14, spaceAfter=2)
body_bold = make_style('BodyBold', fontSize=9, textColor=BLACK,
fontName='Helvetica-Bold', leading=14)
small = make_style('Small', fontSize=8, textColor=colors.HexColor("#475569"),
fontName='Helvetica', leading=11)
small_bold = make_style('SmallBold', fontSize=8, textColor=BLACK,
fontName='Helvetica-Bold', leading=11)
footnote = make_style('Footnote', fontSize=7.5, textColor=colors.HexColor("#64748b"),
fontName='Helvetica-Oblique', alignment=TA_CENTER, leading=11)
red_alert = make_style('RedAlert', fontSize=9, textColor=RED,
fontName='Helvetica-Bold', leading=14)
# ββ Helper: coloured section header row βββββββββββββββββββββββββββ
def section_table(text, bg=MED_BLUE, emoji=""):
label = f"{emoji} {text}" if emoji else text
t = Table([[Paragraph(label, section_head)]], colWidths=[17.6*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('ROUNDEDCORNERS', [4,4,4,4]),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
return t
def coloured_box(content_rows, bg=LIGHT_BLUE, col_widths=None):
"""Wrap a list of [cell, cell] rows in a coloured box table."""
if col_widths is None:
col_widths = [17.6*cm]
t = Table(content_rows, colWidths=col_widths)
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
return t
# ββ Document setup βββββββββββββββββββββββββββββββββββββββββββββββββ
output_path = "/home/daytona/workspace/pharyngitis-guide/Pharyngitis_Quick_Reference.pdf"
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
leftMargin=1.2*cm, rightMargin=1.2*cm,
topMargin=1.0*cm, bottomMargin=1.2*cm,
title="Pharyngitis Quick Reference Guide",
author="Orris Medical"
)
story = []
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# HEADER BANNER
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
header_data = [[
Paragraph("PHARYNGITIS", title_style),
],[
Paragraph("Quick Reference Guide for MBBS Interns | ENT / General OPD", subtitle_style),
],[
Paragraph("Sources: Harrison's Principles 22E Β· Symptom to Diagnosis 4E Β· Scott-Brown's ORL Β· Textbook of Family Medicine 9E", footnote),
]]
header_table = Table(header_data, colWidths=[17.6*cm])
header_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), DARK_BLUE),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 12),
('ROUNDEDCORNERS', [6,6,6,6]),
]))
story.append(header_table)
story.append(Spacer(1, 0.3*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 1 β DEFINITION + EPIDEMIOLOGY
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("1. DEFINITION & EPIDEMIOLOGY", bg=MED_BLUE))
story.append(Spacer(1, 0.15*cm))
epi_data = [
[Paragraph("<b>Pharyngitis</b>", small_bold),
Paragraph("Inflammation of the pharynx and/or tonsils. One of the most common OPD presentations.", small)],
[Paragraph("<b>Viral (most common)</b>", small_bold),
Paragraph("Rhinovirus & coronavirus account for ~25% of all sore throats", small)],
[Paragraph("<b>GABHS (bacterial)</b>", small_bold),
Paragraph("5β15% in adults | 20β30% in children β most common bacterial cause", small)],
[Paragraph("<b>Peak season</b>", small_bold),
Paragraph("Winter and early spring", small)],
[Paragraph("<b>High-risk groups</b>", small_bold),
Paragraph("Children 5β15 yrs, healthcare workers, teachers, parents of young children", small)],
]
t = Table(epi_data, colWidths=[4*cm, 13.6*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), LIGHT_BLUE),
('BACKGROUND', (1,0), (1,-1), WHITE),
('ROWBACKGROUNDS', (1,0), (1,-1), [WHITE, GREY_BG]),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(t)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 2 β DIFFERENTIAL DIAGNOSIS TABLE
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("2. DIFFERENTIAL DIAGNOSIS", bg=MED_BLUE))
story.append(Spacer(1, 0.15*cm))
ddx_header = [
Paragraph("<b>Pathogen</b>", small_bold),
Paragraph("<b>Type</b>", small_bold),
Paragraph("<b>Freq.</b>", small_bold),
Paragraph("<b>Key Clinical Features</b>", small_bold),
]
ddx_rows = [
[Paragraph("Rhinovirus / Coronavirus", small), Paragraph("Viral", small), Paragraph("~25%", small), Paragraph("Common cold, runny nose, mild throat pain, NO fever", small)],
[Paragraph("Adenovirus", small), Paragraph("Viral", small), Paragraph("5%", small), Paragraph("Pharyngo-conjunctival fever: sore throat + conjunctivitis + fever", small)],
[Paragraph("Influenza A/B", small), Paragraph("Viral", small), Paragraph("2%", small), Paragraph("High fever, myalgia, headache, non-exudative pharyngitis", small)],
[Paragraph("HSV 1/2", small), Paragraph("Viral", small), Paragraph("4%", small), Paragraph("Vesicles/ulcers on pharynx or lips, stomatitis", small)],
[Paragraph("EBV (Mono)", small), Paragraph("Viral", small), Paragraph("1β6%", small), Paragraph("Exudate + posterior cervical LAP + splenomegaly; young adults", small)],
[Paragraph("HIV (acute)", small), Paragraph("Viral", small), Paragraph("Rare", small), Paragraph("Mono-like illness; high-risk history; fever, rash, LAP", small)],
[Paragraph("GABHS (Strep A)", small), Paragraph("Bacterial", small), Paragraph("5β30%", small), Paragraph("Exudate, fever, NO cough, tender ant. cervical LN β USE CENTOR", small)],
[Paragraph("Fusobacterium", small), Paragraph("Bacterial", small), Paragraph("Uncommon", small), Paragraph("Unilateral severe sore throat; risk of Lemierre syndrome", small)],
[Paragraph("N. gonorrhoeae", small), Paragraph("Bacterial", small), Paragraph("~1%", small), Paragraph("STI history, often asymptomatic or exudative pharyngitis", small)],
[Paragraph("C. diphtheriae", small), Paragraph("Bacterial", small), Paragraph("Rare", small), Paragraph("Grey pseudomembrane, bull neck, unvaccinated patient", small)],
]
ddx_table_data = [ddx_header] + ddx_rows
ddx_col_w = [4.0*cm, 2.0*cm, 1.8*cm, 9.8*cm]
ddx_t = Table(ddx_table_data, colWidths=ddx_col_w)
ddx_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
# Highlight GABHS row (index 7)
('BACKGROUND', (0,7), (-1,7), colors.HexColor("#fef3c7")),
]))
story.append(ddx_t)
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("β
Non-infectious causes: GERD, postnasal drip, allergies, smoking, acute thyroiditis, neoplasm (consider if chronic/recurrent)", small))
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 3 β CENTOR SCORE (2 columns)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("3. CENTOR SCORE (Identifies likely GABHS in Adults)", bg=colors.HexColor("#d97706")))
story.append(Spacer(1, 0.15*cm))
# Left: criteria | Right: score table
centor_criteria = Table([
[Paragraph("<b>Score 1 point for each criterion:</b>", small_bold)],
[Paragraph("1. History of <b>fever</b>", small)],
[Paragraph("2. <b>Absence of cough</b>", small)],
[Paragraph("3. Tender <b>anterior cervical lymphadenopathy</b>", small)],
[Paragraph("4. <b>Tonsillar exudate</b> or swelling", small)],
[Paragraph(" ", small)],
[Paragraph("<i>In children: always confirm with rapid test\nregardless of score (Centor less specific).</i>", small)],
], colWidths=[8.4*cm])
centor_criteria.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), YELLOW_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0, WHITE),
]))
score_data = [
[Paragraph("<b>Score</b>", small_bold), Paragraph("<b>GAS Prob.</b>", small_bold), Paragraph("<b>Action</b>", small_bold)],
[Paragraph("0", small), Paragraph("2%", small), Paragraph("No test, no antibiotic", small)],
[Paragraph("1", small), Paragraph("3%", small), Paragraph("No test, no antibiotic", small)],
[Paragraph("2", small), Paragraph("8%", small), Paragraph("Rapid strep test", small)],
[Paragraph("3", small), Paragraph("19%", small), Paragraph("Rapid strep test", small)],
[Paragraph("4", small), Paragraph("41%", small), Paragraph("<b>Treat empirically OR rapid test</b>", small)],
]
score_t = Table(score_data, colWidths=[1.6*cm, 2.4*cm, 5.0*cm])
score_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#92400e")),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('BACKGROUND', (0,5), (-1,5), colors.HexColor("#fde68a")),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('ALIGN', (0,0), (1,-1), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
centor_combined = Table([[centor_criteria, score_t]], colWidths=[8.6*cm, 9.0*cm])
centor_combined.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 0),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
]))
story.append(centor_combined)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 4 β INVESTIGATIONS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("4. INVESTIGATIONS", bg=colors.HexColor("#0f766e")))
story.append(Spacer(1, 0.15*cm))
inv_data = [
[Paragraph("<b>Test</b>", small_bold), Paragraph("<b>Details</b>", small_bold), Paragraph("<b>When to order</b>", small_bold)],
[Paragraph("Rapid Strep Antigen", small),
Paragraph("Sensitivity ~80%, Specificity ~95%. Results in minutes.", small),
Paragraph("Centor score 2β4", small)],
[Paragraph("Throat Culture", small),
Paragraph("Sensitivity 85β90%. Takes 24β48 hrs. Not routine in adults.", small),
Paragraph("Children, treatment failure", small)],
[Paragraph("CBC + Peripheral Smear", small),
Paragraph("Atypical lymphocytes >10% β EBV mono", small),
Paragraph("Suspect mono (young adult + posterior LAP)", small)],
[Paragraph("Monospot Test", small),
Paragraph("Rapid heterophile antibody test for EBV", small),
Paragraph("Suspect mono", small)],
[Paragraph("Throat swab for culture", small),
Paragraph("GC culture on Thayer-Martin medium", small),
Paragraph("STI risk / gonorrheal pharyngitis", small)],
[Paragraph("HIV test", small),
Paragraph("4th gen Ag/Ab combo test", small),
Paragraph("High risk history, mono-like illness", small)],
]
inv_t = Table(inv_data, colWidths=[4.0*cm, 8.0*cm, 5.6*cm])
inv_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#134e4a")),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREEN_LIGHT]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(inv_t)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 5 β TREATMENT (2 cols: symptomatic | antibiotics)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("5. TREATMENT", bg=colors.HexColor("#7c3aed")))
story.append(Spacer(1, 0.15*cm))
sym_box = Table([
[Paragraph("<b>Symptomatic (ALL pharyngitis)</b>", small_bold)],
[Paragraph("β’ Paracetamol 500 mgβ1 g PO q6h PRN", small)],
[Paragraph("β’ NSAIDs (Ibuprofen 400 mg TDS with food)", small)],
[Paragraph("β’ Warm saline gargles 3β4Γ daily", small)],
[Paragraph("β’ Soft diet, warm fluids, honey in tea", small)],
[Paragraph("β’ Humidification", small)],
[Paragraph("<i>Note: Glucocorticoids NOT recommended routinely.\nMay reduce pain at 24 h but risk of sepsis, GI bleed,\nVTE within 30 days.</i>", small)],
], colWidths=[8.4*cm])
sym_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#f5f3ff")),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
abx_box = Table([
[Paragraph("<b>Antibiotics β ONLY for confirmed/likely GABHS</b>", small_bold)],
[Paragraph("<b>1st line:</b> Penicillin V 500 mg PO BDβTDS Γ 10 days", small)],
[Paragraph("<b>Children:</b> Amoxicillin 50 mg/kg/day (palatable syrup)", small)],
[Paragraph("<b>Mild PCN allergy:</b> Cephalexin or Cefadroxil Γ 10 days", small)],
[Paragraph("<b>Severe PCN allergy:</b> Erythromycin / Clarithromycin / Clindamycin", small)],
[Paragraph(" ", small)],
[Paragraph("β Complete full 7β10 day course even if symptoms\nresolve earlier. Shorter courses are less effective.", red_alert)],
], colWidths=[9.0*cm])
abx_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#fdf4ff")),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
tx_combined = Table([[sym_box, abx_box]], colWidths=[8.6*cm, 9.0*cm])
tx_combined.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 0),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
story.append(tx_combined)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 6 β RED FLAGS + COMPLICATIONS (2 cols)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("6. RED FLAGS & COMPLICATIONS", bg=colors.HexColor("#be123c")))
story.append(Spacer(1, 0.15*cm))
red_flags_box = Table([
[Paragraph("<b>π¨ Red Flags β Refer/Act Immediately</b>", small_bold)],
[Paragraph("β’ Stridor or respiratory distress", small)],
[Paragraph("β’ Drooling / inability to swallow (Epiglottitis / PTA)", small)],
[Paragraph("β’ 'Hot potato' muffled voice β Peritonsillar Abscess", small)],
[Paragraph("β’ Neck swelling beyond lymphadenopathy", small)],
[Paragraph("β’ Shaking chills / rigors (bacteraemia)", small)],
[Paragraph("β’ Symptoms not improving after 5 days", small)],
[Paragraph("β’ Unilateral tonsillar enlargement (malignancy?)", small)],
[Paragraph("β’ Trismus (difficulty opening mouth)", small)],
], colWidths=[8.4*cm])
red_flags_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
comp_box = Table([
[Paragraph("<b>Complications of Strep Pharyngitis</b>", small_bold)],
[Paragraph("<b>Suppurative:</b>", small_bold)],
[Paragraph("β’ Peritonsillar abscess (Quinsy)", small)],
[Paragraph("β’ Retropharyngeal abscess", small)],
[Paragraph("β’ Otitis media", small)],
[Paragraph("β’ Sinusitis", small)],
[Paragraph("<b>Non-suppurative:</b>", small_bold)],
[Paragraph("β’ Acute Rheumatic Fever (ARF) β treat to PREVENT", small)],
[Paragraph("β’ Post-streptococcal GN", small)],
[Paragraph("β’ Scarlet fever", small)],
], colWidths=[9.0*cm])
comp_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#fff1f2")),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
rf_combined = Table([[red_flags_box, comp_box]], colWidths=[8.6*cm, 9.0*cm])
rf_combined.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 0),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
story.append(rf_combined)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 7 β SPECIAL SCENARIOS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_table("7. SPECIAL SCENARIOS", bg=colors.HexColor("#0369a1")))
story.append(Spacer(1, 0.15*cm))
sp_data = [
[Paragraph("<b>Scenario</b>", small_bold), Paragraph("<b>Key Clues</b>", small_bold), Paragraph("<b>Action</b>", small_bold)],
[Paragraph("Infectious Mono (EBV)", small),
Paragraph("Young adult, posterior cervical LAP, splenomegaly, petechiae on palate, atypical lymphocytes", small),
Paragraph("Monospot + CBC. No amoxicillin (causes rash). No contact sports (spleen rupture risk).", small)],
[Paragraph("Peritonsillar Abscess", small),
Paragraph("Unilateral bulge, uvula deviation, muffled 'hot potato' voice, trismus", small),
Paragraph("ENT referral for I&D. IV antibiotics. Admit.", small)],
[Paragraph("Diphtheria", small),
Paragraph("Grey pseudomembrane, bull neck, unvaccinated / incomplete vaccines, sweet-smelling breath", small),
Paragraph("Antitoxin + Penicillin/Erythromycin. Isolate. Notify.", small)],
[Paragraph("Gonococcal", small),
Paragraph("STI history, mild or no symptoms, exudative pharyngitis", small),
Paragraph("Throat swab GC culture. Ceftriaxone 500 mg IM single dose.", small)],
[Paragraph("History of ARF", small),
Paragraph("Any pharyngitis in a patient with prior ARF", small),
Paragraph("Lower threshold to treat empirically for GABHS. Long-term penicillin prophylaxis.", small)],
]
sp_t = Table(sp_data, colWidths=[3.8*cm, 7.0*cm, 6.8*cm])
sp_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#075985")),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(sp_t)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# FOOTER
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(HRFlowable(width="100%", thickness=0.5, color=GREY_LINE))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
"References: Harrison's Principles of Internal Medicine 22E (2025) Β· Symptom to Diagnosis 4E Β· "
"Scott-Brown's ORL Head & Neck Surgery Β· Textbook of Family Medicine 9E | "
"Compiled by Orris AI Β· July 2026 | For educational use only β always apply clinical judgment.",
footnote
))
# ββ Build ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
doc.build(story)
print(f"PDF created: {output_path}")
cd /home/daytona/workspace/pharyngitis-guide && python create_guide.py 2>&1
ls -lh /home/daytona/workspace/pharyngitis-guide/
Pharyngitis Quick Reference
PDF Document Β· PDF
Create a guide for another common OPD complaint (fever, cough, abdomen pain, jaundice)
~/pharyngitis-guide/abdominal_pain_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, HRFlowable)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
# ββ Color palette ββββββββββββββββββββββββββββββββββββββββββββββββββ
DARK_TEAL = colors.HexColor("#0f4c5c")
MED_TEAL = colors.HexColor("#0e7490")
LIGHT_TEAL = colors.HexColor("#cffafe")
ORANGE = colors.HexColor("#c2410c")
ORANGE_LIGHT= colors.HexColor("#fff7ed")
GREEN = colors.HexColor("#166534")
GREEN_LIGHT = colors.HexColor("#dcfce7")
RED = colors.HexColor("#991b1b")
RED_LIGHT = colors.HexColor("#fee2e2")
PURPLE = colors.HexColor("#6d28d9")
PURPLE_LIGHT= colors.HexColor("#ede9fe")
YELLOW = colors.HexColor("#92400e")
YELLOW_LIGHT= colors.HexColor("#fef3c7")
GREY_BG = colors.HexColor("#f1f5f9")
GREY_LINE = colors.HexColor("#cbd5e1")
WHITE = colors.white
BLACK = colors.HexColor("#1e293b")
DARK_BLUE = colors.HexColor("#1e3a5f")
MED_BLUE = colors.HexColor("#2563a8")
LIGHT_BLUE = colors.HexColor("#dbeafe")
# ββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def ms(name, parent='Normal', **kw):
return ParagraphStyle(name, parent=styles[parent], **kw)
title_s = ms('T', fontSize=22, textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER, spaceAfter=3)
subtitle_s= ms('S', fontSize=10, textColor=colors.HexColor("#a5f3fc"), fontName='Helvetica', alignment=TA_CENTER)
sec_s = ms('H', fontSize=11, textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_LEFT, spaceBefore=1, spaceAfter=1)
body = ms('B', fontSize=8.5, textColor=BLACK, fontName='Helvetica', leading=13)
body_b = ms('BB', fontSize=8.5, textColor=BLACK, fontName='Helvetica-Bold', leading=13)
small = ms('Sm', fontSize=8, textColor=BLACK, fontName='Helvetica', leading=12)
small_b = ms('SmB', fontSize=8, textColor=BLACK, fontName='Helvetica-Bold', leading=12)
red_s = ms('R', fontSize=8, textColor=RED, fontName='Helvetica-Bold', leading=12)
foot_s = ms('F', fontSize=7, textColor=colors.HexColor("#64748b"), fontName='Helvetica-Oblique', alignment=TA_CENTER, leading=10)
def sec_hdr(text, bg=MED_TEAL):
t = Table([[Paragraph(text, sec_s)]], colWidths=[17.6*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 9),
]))
return t
# ββ Document βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
out = "/home/daytona/workspace/pharyngitis-guide/AbdominalPain_Quick_Reference.pdf"
doc = SimpleDocTemplate(out, pagesize=A4,
leftMargin=1.2*cm, rightMargin=1.2*cm,
topMargin=1.0*cm, bottomMargin=1.2*cm,
title="Abdominal Pain Quick Reference Guide")
story = []
# ββ HEADER βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
hdr = Table([
[Paragraph("ABDOMINAL PAIN", title_s)],
[Paragraph("Quick Reference Guide for MBBS Interns | General OPD / Emergency", subtitle_s)],
[Paragraph("Sources: Yamada's Gastroenterology 7E Β· Harrison's 22E Β· Rosen's Emergency Medicine Β· Bailey & Love 28E Β· Textbook of Family Medicine 9E", foot_s)],
], colWidths=[17.6*cm])
hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), DARK_TEAL),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
story.append(hdr)
story.append(Spacer(1, 0.25*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 1. HISTORY β SOCRATES
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("1. HISTORY β USE SOCRATES + KEY QUESTIONS", bg=DARK_TEAL))
story.append(Spacer(1, 0.12*cm))
soc_data = [
[Paragraph("<b>S</b>ite", small_b), Paragraph("Where exactly? Point with one finger. Quadrant / diffuse?", small),
Paragraph("<b>A</b>ssociated Sx", small_b), Paragraph("N/V, fever, jaundice, change in bowel/urinary habits, menstrual hx", small)],
[Paragraph("<b>O</b>nset", small_b), Paragraph("Sudden (perforation/torsion/AAA) vs gradual (IBD/PUD/cancer)", small),
Paragraph("<b>R</b>elieving", small_b), Paragraph("Food (PUD improves/worsens), posture, defecation (IBS), antacids", small)],
[Paragraph("<b>C</b>haracter", small_b), Paragraph("Colicky = hollow viscus; Burning = PUD; Tearing = AAA; Dull/aching = solid organ", small),
Paragraph("<b>T</b>iming", small_b), Paragraph("Constant vs intermittent; post-meal (mesenteric ischaemia); nocturnal waking (PUD)", small)],
[Paragraph("<b>R</b>adiation", small_b), Paragraph("Shoulder tip (diaphragm/liver/spleen); Back (pancreatitis/AAA); Groin (ureteric colic)", small),
Paragraph("<b>S</b>everity", small_b), Paragraph("Score 0β10. Severity β seriousness (peritonitis may be deceptively mild in elderly)", small)],
[Paragraph("<b>E</b>xacerbating", small_b), Paragraph("Movement (peritonitis); eating (mesenteric ischaemia/PUD); inspiration (cholecystitis)", small),
Paragraph("<b>Key extras</b>", small_b), Paragraph("Last menstrual period (women); recent travel; medications (NSAIDs, steroids, antibiotics)", small)],
]
soc_t = Table(soc_data, colWidths=[2.4*cm, 6.4*cm, 2.6*cm, 6.2*cm])
soc_t.setStyle(TableStyle([
('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, GREY_BG]),
('BACKGROUND', (0,0), (0,-1), LIGHT_TEAL),
('BACKGROUND', (2,0), (2,-1), LIGHT_TEAL),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(soc_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 2. DDx BY QUADRANT
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("2. DIFFERENTIAL DIAGNOSIS BY QUADRANT / REGION", bg=MED_TEAL))
story.append(Spacer(1, 0.12*cm))
ddx_header = [
Paragraph("<b>Region</b>", small_b),
Paragraph("<b>Common Causes</b>", small_b),
Paragraph("<b>Don't Miss</b>", small_b),
]
ddx_rows = [
[Paragraph("RUQ", small_b),
Paragraph("Acute cholecystitis, cholelithiasis, hepatitis (A/B/E), PUD, GERD, right lower lobe pneumonia, liver abscess, Fitz-Hugh-Curtis syndrome", small),
Paragraph("Inferior wall MI, ruptured liver abscess, cholangitis (Charcot's triad)", small)],
[Paragraph("LUQ", small_b),
Paragraph("Gastritis, PUD (gastric ulcer), splenic pathology (splenomegaly, infarct), pancreatitis tail, left lower lobe pneumonia", small),
Paragraph("Splenic rupture (trauma/mono), aortic dissection", small)],
[Paragraph("Epigastric", small_b),
Paragraph("PUD, GERD, gastritis, pancreatitis, early appendicitis, MI (inferior wall)", small),
Paragraph("Leaking AAA, perforated peptic ulcer, acute MI β ECG mandatory!", small)],
[Paragraph("RLQ", small_b),
Paragraph("Acute appendicitis, Meckel's diverticulitis, Crohn's disease (terminal ileum), mesenteric lymphadenitis, ectopic pregnancy (female), ovarian cyst/torsion (female), renal/ureteral calculi", small),
Paragraph("Ectopic pregnancy (must exclude in all females of reproductive age), appendicitis in retrocecal position", small)],
[Paragraph("LLQ", small_b),
Paragraph("Diverticulitis (sigmoid), constipation, IBS, IBD (ulcerative colitis), renal/ureteral calculi, ectopic pregnancy, ovarian cyst/torsion", small),
Paragraph("Sigmoid volvulus, perforated diverticulitis", small)],
[Paragraph("Central / Periumbilical", small_b),
Paragraph("Early appendicitis (migrates to RLQ), small bowel obstruction, mesenteric ischaemia, aortic aneurysm, IBD", small),
Paragraph("Mesenteric ischaemia (pain out of proportion to findings), AAA", small)],
[Paragraph("Hypogastric / Suprapubic", small_b),
Paragraph("UTI/cystitis, PID, ectopic pregnancy, ovarian pathology, constipation, urinary retention, IBS", small),
Paragraph("Ectopic pregnancy, ovarian torsion, urinary retention in elderly males", small)],
[Paragraph("Diffuse / Generalised", small_b),
Paragraph("Peritonitis (any cause), gastroenteritis, IBD, bowel obstruction, DKA, constipation, IBS", small),
Paragraph("Perforated viscus, mesenteric ischaemia, ruptured AAA, DKA", small)],
]
ddx_data = [ddx_header] + ddx_rows
ddx_t = Table(ddx_data, colWidths=[2.8*cm, 8.4*cm, 6.4*cm])
ddx_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), DARK_TEAL),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('BACKGROUND', (2,1), (2,-1), RED_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(ddx_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 3. CLINICAL SIGNS TABLE
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("3. KEY CLINICAL SIGNS & WHAT THEY MEAN", bg=colors.HexColor("#1d4ed8")))
story.append(Spacer(1, 0.12*cm))
signs_data = [
[Paragraph("<b>Sign</b>", small_b), Paragraph("<b>How to Elicit</b>", small_b), Paragraph("<b>Positive if...</b>", small_b), Paragraph("<b>Suggests</b>", small_b)],
[Paragraph("Murphy's Sign", small), Paragraph("Deep palpation RUQ + ask patient to inspire deeply", small), Paragraph("Pain arrests inspiration", small), Paragraph("Acute cholecystitis (Sens 65%, Spec 87%)", small)],
[Paragraph("Rovsing's Sign", small), Paragraph("Press/release LLQ", small), Paragraph("Pain felt in RLQ", small), Paragraph("Appendicitis (indirect rebound)", small)],
[Paragraph("Psoas Sign", small), Paragraph("Patient lifts right thigh vs resistance (supine)", small), Paragraph("RLQ pain increases", small), Paragraph("Retrocecal appendicitis, psoas abscess", small)],
[Paragraph("Obturator Sign", small), Paragraph("Flex R hip+knee 90Β°, rotate internally/externally", small), Paragraph("Pain reproduced", small), Paragraph("Appendicitis, PID, pelvic abscess", small)],
[Paragraph("Guarding / Rigidity", small), Paragraph("Gentle palpation; assess muscle tone during respiration", small), Paragraph("Board-like abdomen", small), Paragraph("Peritonitis (involuntary > voluntary)", small)],
[Paragraph("CVAT", small), Paragraph("Firm fist percussion over costovertebral angle", small), Paragraph("Tenderness elicited", small), Paragraph("Pyelonephritis, renal calculus", small)],
[Paragraph("Cullen's / Grey Turner's", small), Paragraph("Periumbilical (Cullen) or flank (Grey Turner) discolouration", small), Paragraph("Bruising visible", small), Paragraph("Retroperitoneal bleed, severe pancreatitis", small)],
]
signs_t = Table(signs_data, colWidths=[3.2*cm, 5.0*cm, 4.0*cm, 5.4*cm])
signs_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#1e3a8a")),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(signs_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 4. INVESTIGATIONS + 5. RED FLAGS side by side
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("4. INVESTIGATIONS 5. RED FLAGS", bg=colors.HexColor("#6d28d9")))
story.append(Spacer(1, 0.12*cm))
inv_box = Table([
[Paragraph("<b>Basic workup (most patients)</b>", small_b)],
[Paragraph("β’ CBC β WBCβ (infection/inflammation), Hbβ (bleed/perforation)", small)],
[Paragraph("β’ CRP / ESR β infection, IBD, abscess", small)],
[Paragraph("β’ LFTs β hepatitis, biliary, pancreatitis (AST/ALT)", small)],
[Paragraph("β’ Serum amylase/lipase β pancreatitis (lipase more specific)", small)],
[Paragraph("β’ RFTs + electrolytes β renal colic, obstruction", small)],
[Paragraph("β’ Urine routine / microscopy β UTI, renal calculi, DKA", small)],
[Paragraph("β’ Urine Ξ²-hCG β all females of reproductive age (MANDATORY)", small_b)],
[Paragraph(" ", small)],
[Paragraph("<b>Targeted investigations</b>", small_b)],
[Paragraph("β’ USG abdomen β biliary, liver, kidney, gynaecological, AAA", small)],
[Paragraph("β’ CECT abdomen/pelvis β appendicitis, pancreatitis, malignancy", small)],
[Paragraph("β’ ECG β mandatory in all epigastric pain (rule out MI)", small_b)],
[Paragraph("β’ Stool exam β dysentery, parasite, occult blood", small)],
[Paragraph("β’ Blood culture β if febrile (suspect sepsis/peritonitis)", small)],
], colWidths=[8.4*cm])
inv_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), PURPLE_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
rf_box = Table([
[Paragraph("<b>π¨ Red Flags β Urgent / Surgical Referral</b>", red_s)],
[Paragraph("β’ Sudden onset severe pain (perforation, AAA, torsion)", small)],
[Paragraph("β’ Hemodynamic instability β BPβ, HRβ, sweating", small)],
[Paragraph("β’ Peritonism β guarding, rigidity, rebound tenderness", small)],
[Paragraph("β’ Positive pregnancy test + pain (ectopic pregnancy)", small)],
[Paragraph("β’ Abdominal distension + absolute constipation (obstruction)", small)],
[Paragraph("β’ Pulsatile abdominal mass (AAA)", small)],
[Paragraph("β’ Fever >38.5Β°C + RLQ pain + Rovsing/Psoas/Obturator +ve (appendicitis)", small)],
[Paragraph("β’ Jaundice + fever + RUQ pain = Charcot's triad β Cholangitis", small)],
[Paragraph("β’ Pain out of proportion to physical findings β mesenteric ischaemia", small)],
[Paragraph("β’ Blood PR (fresh or melena) β GI bleed", small)],
[Paragraph("β’ Age >60 with new-onset abdominal pain β always take seriously", small)],
[Paragraph(" ", small)],
[Paragraph("<b>Populations requiring extra caution:</b>", small_b)],
[Paragraph("Elderly | Pregnant | Immunocompromised | Post-bariatric surgery | Known vascular disease", small)],
], colWidths=[9.0*cm])
rf_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
inv_rf = Table([[inv_box, rf_box]], colWidths=[8.6*cm, 9.0*cm])
inv_rf.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('TOPPADDING', (0,0), (-1,-1), 0),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
story.append(inv_rf)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 6. COMMON CONDITIONS AT A GLANCE
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("6. COMMON CONDITIONS β QUICK RECOGNITION & INITIAL MANAGEMENT", bg=colors.HexColor("#065f46")))
story.append(Spacer(1, 0.12*cm))
cond_data = [
[Paragraph("<b>Condition</b>", small_b), Paragraph("<b>Classic Presentation</b>", small_b), Paragraph("<b>Key Test</b>", small_b), Paragraph("<b>Initial Management</b>", small_b)],
[Paragraph("Acute Appendicitis", small),
Paragraph("Periumbilical pain β RLQ, N/V, low-grade fever, RLQ tenderness, Rovsing +ve", small),
Paragraph("USG / CECT abdomen; WBCβ", small),
Paragraph("NBM, IV fluids, analgesia, surgical referral", small)],
[Paragraph("Acute Cholecystitis", small),
Paragraph("RUQ colicky pain post-fatty meal, N/V, Murphy's sign +ve, fever", small),
Paragraph("USG abdomen (gallstones + wall thickening)", small),
Paragraph("NBM, analgesia, IV fluids, antibiotics, surgical consult", small)],
[Paragraph("Acute Pancreatitis", small),
Paragraph("Severe epigastric pain radiating to back, N/V, relieved by leaning forward; H/O alcohol or gallstones", small),
Paragraph("Serum lipase >3Γ ULN; CECT for severity (Balthazar score)", small),
Paragraph("NBM, aggressive IV fluids, analgesia, monitor vitals. No food until pain-free.", small)],
[Paragraph("Peptic Ulcer / Perforation", small),
Paragraph("Epigastric burning; H/O NSAIDs/H.pylori; Perforation: sudden board-like rigidity", small),
Paragraph("Erect CXR (free air under diaphragm); OGD", small),
Paragraph("Perforation: emergency surgery. PUD: PPI, H.pylori eradication (Triple therapy)", small)],
[Paragraph("Intestinal Obstruction", small),
Paragraph("Colicky central pain, distension, absolute constipation, bilious vomiting, visible peristalsis", small),
Paragraph("Plain X-ray abdomen erect + supine (air-fluid levels, dilated loops)", small),
Paragraph("NGT suction, IV fluids, NBM, Foley catheter, surgical referral", small)],
[Paragraph("Renal / Ureteric Colic", small),
Paragraph("Severe loin-to-groin colicky pain, hematuria, restlessness (can't sit still), N/V", small),
Paragraph("Urine microscopy; NCCT KUB (best); USG", small),
Paragraph("Diclofenac 75 mg IM or IV, adequate hydration, sieve urine, urology referral if stone >5 mm", small)],
[Paragraph("Ectopic Pregnancy", small),
Paragraph("Amenorrhoea + LLQ/RLQ pain + vaginal bleeding; haemodynamic instability possible", small),
Paragraph("Urine/serum Ξ²-hCG; Transvaginal USG", small),
Paragraph("EMERGENCY β IV access, fluid resuscitation, O2, urgent gynae referral / OT", small)],
[Paragraph("PID / Salpingitis", small),
Paragraph("Young female; bilateral lower abdominal pain, cervical motion tenderness, vaginal discharge, fever", small),
Paragraph("Pelvic exam, HVS, HCG (rule out ectopic)", small),
Paragraph("Doxycycline + Metronidazole Β± Ceftriaxone; outpatient if mild", small)],
[Paragraph("Acute Gastroenteritis", small),
Paragraph("N/V + diarrhoea Β± cramping, often diffuse tenderness, fever, recent food hx", small),
Paragraph("Stool exam, culture; CBC if severe", small),
Paragraph("Oral/IV rehydration; antibiotics only if bacterial (Ciprofloxacin for severe shigella/salmonella)", small)],
]
cond_t = Table(cond_data, colWidths=[3.0*cm, 5.5*cm, 3.8*cm, 5.3*cm])
cond_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#014737")),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREEN_LIGHT]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
# Highlight ectopic row (index 7) as high danger
('BACKGROUND', (0,7), (-1,7), colors.HexColor("#fde68a")),
]))
story.append(cond_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 7. ANALGESIA NOTE + BOTTOM TIPS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(sec_hdr("7. ANALGESIA & PRACTICAL TIPS", bg=colors.HexColor("#b45309")))
story.append(Spacer(1, 0.12*cm))
tips_data = [
[Paragraph("<b>On analgesia:</b> Studies confirm that giving analgesics does NOT mask diagnosis or increase diagnostic errors. Do not withhold pain relief while evaluating. Use IV morphine 0.1 mg/kg titrated or IV paracetamol.", small),
Paragraph("<b>On referral:</b> Immediate surgical referral if: peritonism, haemodynamic instability, suspected perforation, obstruction, ectopic pregnancy, or any patient where diagnosis is unclear after initial assessment.", small)],
[Paragraph("<b>Nonspecific Abdominal Pain (NSAP):</b> ~40% of acute abdominal pain admissions. Diagnosis of exclusion. Active observation with serial examinations is acceptable. Early laparoscopy improves diagnosis rate but not clinical outcomes.", small),
Paragraph("<b>Elderly caution:</b> Reduced peritoneal reaction β examination findings underestimate severity. Higher threshold for admission. Common causes missed: mesenteric ischaemia, aortic aneurysm, acute MI (atypical presentation).", small)],
]
tips_t = Table(tips_data, colWidths=[8.6*cm, 9.0*cm])
tips_t.setStyle(TableStyle([
('ROWBACKGROUNDS', (0,0), (-1,-1), [YELLOW_LIGHT, colors.HexColor("#fff7ed")]),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(tips_t)
story.append(Spacer(1, 0.15*cm))
# ββ FOOTER βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(HRFlowable(width="100%", thickness=0.5, color=GREY_LINE))
story.append(Spacer(1, 0.08*cm))
story.append(Paragraph(
"References: Yamada's Textbook of Gastroenterology 7E Β· Harrison's Principles of Internal Medicine 22E (2025) Β· "
"Rosen's Emergency Medicine Β· Bailey & Love's Short Practice of Surgery 28E Β· Textbook of Family Medicine 9E | "
"Compiled by Orris AI Β· July 2026 | For educational use only β always apply clinical judgment.",
foot_s
))
doc.build(story)
print(f"PDF created: {out}")
cd /home/daytona/workspace/pharyngitis-guide && python abdominal_pain_guide.py 2>&1
ls -lh /home/daytona/workspace/pharyngitis-guide/
AbdominalPain Quick Reference
PDF Document Β· PDF
Cough
~/pharyngitis-guide/cough_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, HRFlowable)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
# ββ Palette ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DARK_GREEN = colors.HexColor("#14532d")
MED_GREEN = colors.HexColor("#16a34a")
LIGHT_GREEN = colors.HexColor("#dcfce7")
TEAL_DARK = colors.HexColor("#0f4c5c")
TEAL = colors.HexColor("#0e7490")
TEAL_LIGHT = colors.HexColor("#cffafe")
BLUE_DARK = colors.HexColor("#1e3a8a")
BLUE = colors.HexColor("#2563eb")
BLUE_LIGHT = colors.HexColor("#dbeafe")
ORANGE_DARK = colors.HexColor("#9a3412")
ORANGE = colors.HexColor("#c2410c")
ORANGE_LIGHT = colors.HexColor("#fff7ed")
RED = colors.HexColor("#991b1b")
RED_LIGHT = colors.HexColor("#fee2e2")
PURPLE_DARK = colors.HexColor("#4c1d95")
PURPLE = colors.HexColor("#7c3aed")
PURPLE_LIGHT = colors.HexColor("#ede9fe")
YELLOW_DARK = colors.HexColor("#78350f")
YELLOW_LIGHT = colors.HexColor("#fef3c7")
GREY_BG = colors.HexColor("#f1f5f9")
GREY_LINE = colors.HexColor("#cbd5e1")
WHITE = colors.white
BLACK = colors.HexColor("#1e293b")
styles = getSampleStyleSheet()
def ms(name, **kw):
return ParagraphStyle(name, parent=styles['Normal'], **kw)
title_s = ms('T', fontSize=22, textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER, spaceAfter=3)
sub_s = ms('S', fontSize=10, textColor=colors.HexColor("#bbf7d0"), fontName='Helvetica', alignment=TA_CENTER)
sec_s = ms('H', fontSize=11, textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_LEFT, spaceBefore=1, spaceAfter=1)
small = ms('Sm', fontSize=8, textColor=BLACK, fontName='Helvetica', leading=12)
small_b = ms('SmB', fontSize=8, textColor=BLACK, fontName='Helvetica-Bold', leading=12)
red_s = ms('R', fontSize=8, textColor=RED, fontName='Helvetica-Bold', leading=12)
orange_s = ms('O', fontSize=8, textColor=ORANGE, fontName='Helvetica-Bold', leading=12)
foot_s = ms('F', fontSize=7, textColor=colors.HexColor("#64748b"), fontName='Helvetica-Oblique', alignment=TA_CENTER, leading=10)
def shdr(text, bg=TEAL_DARK):
t = Table([[Paragraph(text, sec_s)]], colWidths=[17.6*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 9),
]))
return t
out = "/home/daytona/workspace/pharyngitis-guide/Cough_Quick_Reference.pdf"
doc = SimpleDocTemplate(out, pagesize=A4,
leftMargin=1.2*cm, rightMargin=1.2*cm,
topMargin=1.0*cm, bottomMargin=1.2*cm,
title="Cough Quick Reference Guide")
story = []
# ββ HEADER ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
hdr = Table([
[Paragraph("COUGH", title_s)],
[Paragraph("Quick Reference Guide for MBBS Interns | General OPD / Respiratory Clinic", sub_s)],
[Paragraph("Sources: Murray & Nadel's Respiratory Medicine 7E Β· Textbook of Family Medicine 9E Β· Harrison's 22E Β· Rosen's Emergency Medicine", foot_s)],
], colWidths=[17.6*cm])
hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), DARK_GREEN),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
story.append(hdr)
story.append(Spacer(1, 0.22*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 1. CLASSIFICATION BY DURATION
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(shdr("1. CLASSIFY FIRST β DURATION OF COUGH", bg=DARK_GREEN))
story.append(Spacer(1, 0.12*cm))
dur_data = [
[Paragraph("<b>Type</b>", small_b), Paragraph("<b>Duration</b>", small_b), Paragraph("<b>Most Common Causes</b>", small_b), Paragraph("<b>Key Action</b>", small_b)],
[Paragraph("ACUTE", small_b),
Paragraph("<3 weeks", small),
Paragraph("Viral URTI (most common), acute bronchitis, sinusitis, pneumonia, exacerbation of asthma/COPD, foreign body (children)", small),
Paragraph("Treat conservatively. No antibiotics unless bacterial infection confirmed. CXR if fever, hemoptysis, or SOB.", small)],
[Paragraph("SUBACUTE", small_b),
Paragraph("3β8 weeks", small),
Paragraph("Post-infectious cough (most common), pertussis (Bordetella), UACS/postnasal drip, asthma exacerbation", small),
Paragraph("Consider pertussis especially if whooping + post-tussive vomiting. Macrolide if pertussis confirmed.", small)],
[Paragraph("CHRONIC", small_b),
Paragraph(">8 weeks", small),
Paragraph("Non-smoker: Postnasal drip, Asthma, GERD, ACE inhibitor (PAGA mnemonic). Smoker: Add chronic bronchitis, lung cancer, bronchiectasis, TB", small),
Paragraph("CXR mandatory. Spirometry. Trial of empiric therapy. ACE inhibitor? Switch to ARB.", small)],
]
dur_t = Table(dur_data, colWidths=[2.2*cm, 2.0*cm, 7.4*cm, 6.0*cm])
dur_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), DARK_GREEN),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_GREEN]),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('BACKGROUND', (0,3), (1,3), colors.HexColor("#fde68a")),
]))
story.append(dur_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 2. HISTORY β KEY QUESTIONS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(shdr("2. HISTORY β KEY QUESTIONS TO ASK", bg=TEAL_DARK))
story.append(Spacer(1, 0.12*cm))
hx_data = [
[Paragraph("<b>Question</b>", small_b), Paragraph("<b>What it suggests</b>", small_b),
Paragraph("<b>Question</b>", small_b), Paragraph("<b>What it suggests</b>", small_b)],
[Paragraph("Productive or dry?", small),
Paragraph("<b>Dry:</b> Asthma, GERD, ACE inhibitor, IPF, viral | <b>Productive:</b> Infection, bronchiectasis, TB, lung abscess", small),
Paragraph("Nocturnal cough?", small),
Paragraph("Asthma (classic!), GERD, postnasal drip, heart failure", small)],
[Paragraph("Sputum colour?", small),
Paragraph("<b>Clear/white:</b> Viral, asthma | <b>Yellow/green:</b> Bacterial | <b>Rusty:</b> Pneumococcal pneumonia | <b>Pink frothy:</b> Pulmonary oedema", small),
Paragraph("Post-tussive vomiting?", small),
Paragraph("Pertussis (whooping cough) β especially with paroxysmal nature", small)],
[Paragraph("Haemoptysis?", small),
Paragraph("TB, bronchiectasis, lung carcinoma, pulmonary embolism, mitral stenosis β NEVER ignore!", small),
Paragraph("Wheezing / SOB?", small),
Paragraph("Asthma, COPD, bronchitis, cardiac failure (cardiac asthma)", small)],
[Paragraph("Heartburn / regurgitation?", small),
Paragraph("GERD-related cough β often no GI symptoms despite GERD being the cause", small),
Paragraph("Smoking history?", small),
Paragraph("Chronic bronchitis, lung cancer, COPD. Pack-year history essential.", small)],
[Paragraph("ACE inhibitor use?", small),
Paragraph("Dry persistent cough β up to 15% of patients on ACEi. Switch to ARB.", small),
Paragraph("TB contacts / travel?", small),
Paragraph("TB β ask about weight loss, night sweats, fever. Mandatory in India.", small)],
[Paragraph("Occupation / exposure?", small),
Paragraph("Coal/grain dust β pneumoconiosis; birds β hypersensitivity pneumonitis; asbestos β mesothelioma", small),
Paragraph("Child with sudden onset?", small),
Paragraph("Foreign body aspiration until proven otherwise", small)],
]
hx_t = Table(hx_data, colWidths=[3.0*cm, 5.8*cm, 3.0*cm, 5.8*cm])
hx_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), TEAL_DARK),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, TEAL_LIGHT]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(hx_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 3. COMMON CAUSES WITH RECOGNITION + MANAGEMENT
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(shdr("3. COMMON CAUSES β RECOGNITION & MANAGEMENT", bg=BLUE_DARK))
story.append(Spacer(1, 0.12*cm))
cond_data = [
[Paragraph("<b>Condition</b>", small_b), Paragraph("<b>Classic Clues</b>", small_b), Paragraph("<b>Test</b>", small_b), Paragraph("<b>Management</b>", small_b)],
[Paragraph("Viral URTI / Acute Bronchitis", small),
Paragraph("Acute cough, runny nose, sore throat, no fever >38Β°C, self-limiting <3 weeks", small),
Paragraph("Clinical diagnosis. No investigations needed routinely.", small),
Paragraph("Supportive: fluids, honey, steam inhalation. No antibiotics. Paracetamol for fever.", small)],
[Paragraph("Pneumonia", small),
Paragraph("Fever, productive cough, tachypnoea, pleuritic chest pain, dullness on percussion, bronchial breath sounds", small),
Paragraph("CXR (consolidation); CBC (WBCβ); sputum culture; SpO2", small),
Paragraph("CAP: Amoxicillin 500 mg TDS Γ 5β7 days (outpatient). Severe/atypical: Add Azithromycin/Doxycycline. Admit if CURB-65 β₯2.", small)],
[Paragraph("Asthma / Cough-variant Asthma", small),
Paragraph("Nocturnal dry cough Β± wheeze, breathlessness, reversible with bronchodilator; episodic; triggered by cold, exercise, allergens", small),
Paragraph("Spirometry (FEV1/FVC <0.7, reversible); Peak flow variability >20%; CXR (hyperinflation)", small),
Paragraph("Inhaled SABA (Salbutamol) for acute. Add ICS (Beclomethasone) for persistent. Trial of oral prednisolone if diagnosis unclear.", small)],
[Paragraph("Postnasal Drip (UACS)", small),
Paragraph("Sensation of drip at back of throat, throat clearing, cobblestoning of pharynx, often no nasal symptoms", small),
Paragraph("Clinical. CT sinuses if recurrent sinusitis.", small),
Paragraph("Nasal topical steroid (Fluticasone spray) + antihistamine. Ipratropium nasal spray for excessive secretions. Antibiotics if bacterial sinusitis.", small)],
[Paragraph("GERD", small),
Paragraph("Chronic dry cough worsened by lying down, post-meal; heartburn may be absent! Responds to PPI trial.", small),
Paragraph("Clinical + PPI trial. OGD if refractory.", small),
Paragraph("PPI (Omeprazole 20β40 mg OD) Γ 8 weeks. Elevate head of bed, avoid triggers (spicy food, coffee, alcohol, late meals).", small)],
[Paragraph("ACE Inhibitor Cough", small),
Paragraph("Persistent dry tickly cough starting weeksβmonths after ACEi initiation; no other symptoms", small),
Paragraph("Clinical. Drug history.", small),
Paragraph("Stop ACE inhibitor. Switch to ARB (Losartan). Cough resolves in 1β4 weeks.", small)],
[Paragraph("Tuberculosis (TB)", small),
Paragraph("Chronic productive cough >3 weeks, haemoptysis, evening fever, night sweats, weight loss, TB contact", small),
Paragraph("Sputum AFB Γ 3 (or CBNAAT/Xpert MTB), CXR (upper lobe involvement, cavitation)", small),
Paragraph("Refer to DOTS centre. RHEZ (Rifampicin, INH, Ethambutol, Pyrazinamide) Γ 2 months then RH Γ 4 months.", small)],
[Paragraph("COPD (exacerbation)", small),
Paragraph("Smoker, chronic productive cough + increased sputum volume/purulence, worsening dyspnoea", small),
Paragraph("Spirometry (FEV1/FVC <0.7, not fully reversible); CXR; ABG if severe", small),
Paragraph("SABD (Salbutamol + Ipratropium), systemic steroids (Prednisolone 30β40 mg Γ 5 days), antibiotics if purulent sputum (Amoxicillin/Doxycycline).", small)],
[Paragraph("Bronchiectasis", small),
Paragraph("Chronic copious mucopurulent/foul-smelling sputum, daily cough, recurrent chest infections, finger clubbing possible", small),
Paragraph("HRCT chest (gold standard: dilated thick-walled bronchi)", small),
Paragraph("Postural drainage/chest physiotherapy. Antibiotics for exacerbations. Inhaled LABA + ICS. Treat underlying cause.", small)],
[Paragraph("Lung Cancer", small),
Paragraph("Smoker >40 yrs, new or changed cough, haemoptysis, weight loss, hoarseness (recurrent laryngeal nerve), clubbing", small),
Paragraph("CXR β CT chest (mass lesion). Bronchoscopy + biopsy.", small),
Paragraph("Urgent oncology/pulmonology referral. Staging required before treatment.", small)],
]
cond_t = Table(cond_data, colWidths=[3.0*cm, 5.0*cm, 3.8*cm, 5.8*cm])
cond_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BLUE_DARK),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, BLUE_LIGHT]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
# Highlight TB row (index 7) - important in India
('BACKGROUND', (0,7), (-1,7), colors.HexColor("#fde68a")),
# Highlight lung cancer row (index 10)
('BACKGROUND', (0,10), (-1,10), RED_LIGHT),
]))
story.append(cond_t)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 4. INVESTIGATIONS + 5. RED FLAGS (side by side)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(shdr("4. INVESTIGATIONS 5. RED FLAGS", bg=PURPLE_DARK))
story.append(Spacer(1, 0.12*cm))
inv_box = Table([
[Paragraph("<b>All patients with cough >3 weeks:</b>", small_b)],
[Paragraph("β’ CXR PA view β MOST valuable single test", small_b)],
[Paragraph("β’ CBC β eosinophilia (asthma), WBCβ (infection), anaemia (malignancy)", small)],
[Paragraph("β’ SpO2 β assess respiratory compromise", small)],
[Paragraph(" ", small)],
[Paragraph("<b>Targeted by suspected cause:</b>", small_b)],
[Paragraph("β’ Sputum AFB Γ 3 / CBNAAT β if TB suspected (>3 wks cough in India)", small)],
[Paragraph("β’ Spirometry β if asthma/COPD suspected (reversibility test)", small)],
[Paragraph("β’ HRCT chest β bronchiectasis (dilated bronchi), ILD, malignancy", small)],
[Paragraph("β’ CT sinuses β recurrent sinusitis/UACS", small)],
[Paragraph("β’ OGD / 24h pH study β refractory GERD-related cough", small)],
[Paragraph("β’ Sputum cytology β if malignancy suspected", small)],
[Paragraph("β’ Bronchoscopy β haemoptysis, suspected malignancy, FB aspiration", small)],
[Paragraph("β’ Mantoux/IGRA (Quantiferon) β TB latent/active workup", small)],
[Paragraph(" ", small)],
[Paragraph("<b>Empiric trials (if CXR normal, non-smoker):</b>", small_b)],
[Paragraph("Stop ACEi β Wait 4 weeks | PPI trial Γ 8 wks | Nasal steroid Γ 4 wks | ICS trial Γ 6 wks", small)],
], colWidths=[8.4*cm])
inv_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), PURPLE_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
rf_box = Table([
[Paragraph("<b>π¨ Red Flags β Urgent Evaluation / Refer</b>", red_s)],
[Paragraph("β’ Haemoptysis β never ignore (TB, cancer, PE)", small)],
[Paragraph("β’ Weight loss + night sweats + chronic cough β TB / malignancy", small)],
[Paragraph("β’ Stridor β upper airway obstruction (epiglottitis, foreign body, tumour)", small)],
[Paragraph("β’ SpO2 <94% on air β respiratory failure", small)],
[Paragraph("β’ Respiratory rate >30/min β severe pneumonia / sepsis", small)],
[Paragraph("β’ Pleuritic chest pain + SOB β PE, pneumonia, pneumothorax", small)],
[Paragraph("β’ Hoarse voice + cough β recurrent laryngeal nerve palsy (lung cancer)", small)],
[Paragraph("β’ Clubbing + chronic cough β bronchiectasis, IPF, malignancy", small)],
[Paragraph("β’ Cough + superior vena cava syndrome (face/arm oedema, JVPβ)", small)],
[Paragraph("β’ Sudden onset severe dyspnoea + cough β pneumothorax, massive PE", small)],
[Paragraph("β’ Child: sudden onset cough after playing with small objects β FB aspiration", small)],
[Paragraph(" ", small)],
[Paragraph("<b>CURB-65 (Admit if score β₯2):</b>", small_b)],
[Paragraph("C=Confusion | U=Urea >7 mmol/L | R=RR β₯30 | B=BP<90/60 | 65=Ageβ₯65", small)],
[Paragraph("Score 0β1: Home | Score 2: Hospital | Score 3β5: ICU consider", small)],
], colWidths=[9.0*cm])
rf_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
combined = Table([[inv_box, rf_box]], colWidths=[8.6*cm, 9.0*cm])
combined.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('TOPPADDING', (0,0), (-1,-1), 0),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
story.append(combined)
story.append(Spacer(1, 0.2*cm))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 6. CHRONIC COUGH MNEMONIC + SPECIAL NOTES
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(shdr("6. CHRONIC COUGH MNEMONIC + SPECIAL CLINICAL NOTES", bg=colors.HexColor("#b45309")))
story.append(Spacer(1, 0.12*cm))
memo_box = Table([
[Paragraph("<b>PAGA β Top 4 Causes of Chronic Cough (Non-smoker)</b>", small_b)],
[Paragraph("<b>P</b> β Postnasal drip / Upper Airway Cough Syndrome (UACS) β most common", small)],
[Paragraph("<b>A</b> β Asthma (including cough-variant asthma) β nocturnal, reversible", small)],
[Paragraph("<b>G</b> β GERD β dry cough, no GI symptoms in 40%; PPI trial diagnostic", small)],
[Paragraph("<b>A</b> β ACE inhibitor β dry tickly cough, 10β15% of users; stops when drug stopped", small)],
[Paragraph(" ", small)],
[Paragraph("<b>In Smokers, add:</b> Chronic bronchitis | Lung carcinoma | Bronchiectasis | TB", small_b)],
], colWidths=[8.4*cm])
memo_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), YELLOW_LIGHT),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
notes_box = Table([
[Paragraph("<b>Practical Tips for OPD</b>", small_b)],
[Paragraph("β’ <b>Cough-variant asthma:</b> Cough is the ONLY symptom in up to 57% of asthmatics. No wheeze needed for diagnosis.", small)],
[Paragraph("β’ <b>GERD cough:</b> May be completely silent β no heartburn or regurgitation. Diagnose by PPI trial response.", small)],
[Paragraph("β’ <b>Pertussis in adults:</b> Whooping sound or post-tussive vomiting + paroxysmal cough + 3β8 week duration = suspect pertussis. Treat with Azithromycin 500 mg OD Γ 3 days.", small)],
[Paragraph("β’ <b>TB in India:</b> Any cough >2β3 weeks needs sputum AFB / CBNAAT. Do not delay testing. Free DOTS treatment available.", small)],
[Paragraph("β’ <b>IPF:</b> Chronic dry cough + progressive dyspnoea + Velcro crackles at bases = suspect IPF. HRCT is diagnostic. Refer pulmonology.", small)],
[Paragraph("β’ <b>Foreign body (children):</b> Sudden onset choking + cough after playing = FB until proven otherwise. Urgent bronchoscopy.", small)],
], colWidths=[9.0*cm])
notes_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), LIGHT_GREEN),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
tips = Table([[memo_box, notes_box]], colWidths=[8.6*cm, 9.0*cm])
tips.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('TOPPADDING', (0,0), (-1,-1), 0),
('GRID', (0,0), (-1,-1), 0.3, GREY_LINE),
]))
story.append(tips)
story.append(Spacer(1, 0.15*cm))
# ββ FOOTER ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(HRFlowable(width="100%", thickness=0.5, color=GREY_LINE))
story.append(Spacer(1, 0.08*cm))
story.append(Paragraph(
"References: Murray & Nadel's Textbook of Respiratory Medicine 7E Β· Textbook of Family Medicine 9E Β· "
"Harrison's Principles of Internal Medicine 22E (2025) Β· Rosen's Emergency Medicine | "
"Compiled by Orris AI Β· July 2026 | For educational use only β always apply clinical judgment.",
foot_s
))
doc.build(story)
print(f"PDF created: {out}")
cd /home/daytona/workspace/pharyngitis-guide && python cough_guide.py 2>&1
ls -lh /home/daytona/workspace/pharyngitis-guide/
Cough Quick Reference
PDF Document Β· PDF