Tyndallisation Nosocomial infections Universal precautions Gaseous disinfectants Bacterial filters Short answers refer apurva sastry 4th edition and gimme a picture format explanation Cover everything but I want to learn it easily
Also called: Fractional Sterilization / Intermittent Sterilization
┌─────────────────────────────────────────────────────────┐
│ WHAT IS TYNDALLISATION? │
│ Method of sterilizing heat-labile media / fluids │
│ that CANNOT withstand 121°C autoclave temperatures │
└─────────────────────────────────────────────────────────┘
Vegetative bacteria → Killed by heat
Spores → Survive heat
→ BUT germinate into vegetative forms
during rest periods
→ Killed in NEXT heating cycle
| Step | Action | What Happens |
|---|---|---|
| Day 1 | Heat at 100°C for 30 min | Vegetative forms killed; spores survive |
| Rest | Incubate at 37°C overnight | Spores germinate → become vegetative |
| Day 2 | Heat at 100°C for 30 min | New vegetative forms killed |
| Rest | Incubate at 37°C overnight | Remaining spores germinate |
| Day 3 | Heat at 100°C for 30 min | Final vegetative forms killed |
MEMORY TIP:
"TYNDALE burned bibles → Tyndall burns bugs
3 days, 3 rounds, 100°C each time"
Greek: "nosokomeion" = hospital
┌──────────────────────────────────────────────────────────┐
│ DEFINITION │
│ Infections acquired DURING hospital care │
│ NOT present or incubating at time of ADMISSION │
│ Time cutoff: > 48 hours after admission │
└──────────────────────────────────────────────────────────┘

Most common → URINARY TRACT (largest segment)
Then: Lower respiratory tract, Surgical site,
Skin/soft tissue, Bacteremia, ENT/Eye
1. UTI ← urinary catheter
2. Surgical wound infection ← operation
3. Pneumonia (VAP) ← ventilator
4. Primary bloodstream infection ← IV line
PATIENTS
/ \
/ SOURCES \
/ \
STAFF ——————— ENVIRONMENT
(dust, linen, air,
sinks, door handles)
D - Direct contact (hands of staff → patient)
D - Droplet infection (coughing/sneezing)
A - Airborne particles
D - Dust release during sweeping/bed making
H - Hospital procedures (catheter, IV, dressings)
| Category | Measures |
|---|---|
| Isolation | Separate infectious from susceptible patients |
| Staff hygiene | Exclude infected staff; PPE use |
| Handwashing | Most important measure (Semmelweis, 1847) |
| Dust control | Wet dusting, vacuum cleaning |
| Disinfection | Instruments, patient articles, body fluids |
| Droplet control | Face masks, bed spacing, ventilation |
| Administrative | Hospital Infection Control Committee |
ESKAPE organisms:
E - Enterococcus faecium
S - Staphylococcus aureus (MRSA)
K - Klebsiella pneumoniae (ESBL)
A - Acinetobacter baumannii
P - Pseudomonas aeruginosa
E - Enterobacter spp.
┌──────────────────────────────────────────────────────────┐
│ DEFINITION │
│ Set of infection control practices applied to ALL │
│ patients regardless of suspected/confirmed diagnosis │
│ Treats ALL blood/body fluids as potentially infectious │
└──────────────────────────────────────────────────────────┘
1985 → CDC introduced "Universal Precautions"
(triggered by HIV/AIDS epidemic)
Based on HBV transmission model
1996 → Replaced by "STANDARD PRECAUTIONS" by CDC
(expanded to include more body fluids)
Standard Precautions = Universal Precautions
+ Body Substance Isolation
✓ Blood
✓ Semen / vaginal secretions
✓ CSF, synovial, pleural, peritoneal, pericardial fluid
✓ Amniotic fluid
✓ Any fluid visibly contaminated with blood
✗ Urine, faeces, sweat, tears, saliva, nasal secretions
(UNLESS visibly bloody)
┌─────────────────────────────────────────────────────┐
│ 1. 🧤 GLOVES │
│ Wear for ALL contact with blood/body fluids │
│ Change between patients │
├─────────────────────────────────────────────────────┤
│ 2. 😷 MASK + EYE PROTECTION │
│ When splashing/spraying anticipated │
├─────────────────────────────────────────────────────┤
│ 3. 🥼 GOWN/APRON │
│ When clothes likely to be contaminated │
│ Washable, tied at back + plastic apron if needed│
├─────────────────────────────────────────────────────┤
│ 4. 💉 SAFE SHARPS HANDLING │
│ Never recap needles │
│ Puncture-resistant sharps containers │
│ Do NOT bend/break/remove needles by hand │
├─────────────────────────────────────────────────────┤
│ 5. 🚿 HANDWASHING │
│ Before and after patient contact │
│ After removing gloves │
│ Alcohol-based rub if soap unavailable │
└─────────────────────────────────────────────────────┘
Needlestick / splash exposure → Report immediately
→ PEP for HIV within 72 hours
→ HBV immunoglobulin if unvaccinated
Universal Precautions were designed to prevent
transmission of BLOOD-BORNE pathogens:
→ HIV
→ HBV (Hepatitis B) ← original model
→ HCV (Hepatitis C)
┌──────────────────────────────────────────────────────────┐
│ GASEOUS DISINFECTANTS / STERILANTS │
│ Used for items SENSITIVE to heat and moisture │
│ Kill microorganisms in GAS phase │
└──────────────────────────────────────────────────────────┘
Formula: C₂H₄O (epoxide ring)
State: Gas at room temp / liquid when compressed
┌────────────────────────────────────────┐
│ MECHANISM OF ACTION │
│ Alkylation of nucleic acids │
│ & proteins → kills ALL organisms │
│ including SPORES │
└────────────────────────────────────────┘
| Feature | Detail |
|---|---|
| Concentration | 450-1200 mg/L |
| Temperature | 55-60°C (low temp!) |
| Humidity | 40-80% RH needed |
| Exposure time | 3-6 hours |
| Aeration needed | YES - 8-12 hours to remove residue |
✓ Plastic/rubber items (catheters, endoscopes)
✓ Electronic equipment
✓ Surgical instruments that can't be autoclaved
✓ Packaged items (gas penetrates packaging)
✗ Toxic, carcinogenic, flammable
✗ Slow process (total cycle = 12-24 hrs)
✗ Expensive equipment
✗ Residual gas toxic → needs aeration
┌────────────────────────────────────────┐
│ MECHANISM │
│ Alkylation of amino, carboxyl, │
│ hydroxyl groups in proteins │
│ → Denatures proteins │
└────────────────────────────────────────┘
1. FORMALIN (40% formaldehyde solution)
→ Fumigation of rooms, cabinets, incubators
2. FORMALDEHYDE GAS
→ Generated by heating formalin tablets (formalin + KMnO₄)
→ Used in FUMIGATION of operation theaters
Method:
→ Seal room completely
→ KMnO₄ (15g) + Formalin (30ml) per 1000 cubic feet
→ Leave for 12-24 hours
→ Ventilate thoroughly before use
→ Neutralize with NH₃ (ammonia) spray
✓ OT fumigation
✓ Sterilization of heat-labile instruments
✓ Preservation (histology, anatomy)
2% alkaline glutaraldehyde (Cidex) = gold standard
for HIGH-LEVEL DISINFECTION
→ Endoscopes, bronchoscopes
→ Kills spores in 10 hours
→ Bactericidal/virucidal/fungicidal in 10-30 min
Used for: Room decontamination in ICUs, clean rooms
Mechanism: Oxidation via free radicals
Available as: Vapor or dry mist systems
| Gas | Mechanism | Main Use | Key Problem |
|---|---|---|---|
| ETO | Alkylation | Heat-labile instruments | Toxic/slow |
| HCHO (Formaldehyde) | Alkylation | OT fumigation | Carcinogenic |
| H₂O₂ vapor | Oxidation | Room decontamination | Costly |
| Glutaraldehyde | Alkylation | Endoscopes | Skin irritant |
MEMORY: "FEGH - Four Gases Everyone Gets High on"
F = Formaldehyde
E = Ethylene oxide
G = Glutaraldehyde
H = Hydrogen peroxide vapor
┌──────────────────────────────────────────────────────────┐
│ DEFINITION │
│ Filters that REMOVE (not kill) bacteria from │
│ liquids or gases by physical filtration │
│ (Not a chemical method - NO heat, NO chemicals) │
└──────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ CLASSIFICATION │
│ │
│ A. FOR LIQUIDS │
│ 1. Seitz filter (asbestos pad) │
│ 2. Chamberland filter (unglazed porcelain) │
│ 3. Berkefeld filter (diatomaceous earth) │
│ 4. Membrane filter (cellulose nitrate/acetate) │
│ │
│ B. FOR AIR / GASES │
│ 1. HEPA filter │
│ 2. Membrane filters on IV sets │
│ 3. Bacterial/viral filters in anesthesia │
└─────────────────────────────────────────────────────┘
| Filter | Material | Pore Size | Mechanism |
|---|---|---|---|
| Seitz | Compressed asbestos/glass fiber | ~0.5 µm | Adsorption + sieving |
| Chamberland | Unglazed porcelain | Variable grades | Sieving |
| Berkefeld | Diatomaceous earth (kieselguhr) | Variable grades | Sieving |
| Membrane (Millipore) | Cellulose nitrate/acetate | 0.22 µm | Sieving (most reliable) |
┌────────────────────────────────────────────────────┐
│ HEPA FILTER │
│ Removes particles ≥ 0.3 µm with 99.97% efficiency│
│ │
│ USES: │
│ → Laminar airflow OTs (operation theaters) │
│ → Isolation rooms (immunocompromised patients) │
│ → Biosafety cabinets (BSL-2, BSL-3) │
│ → Clean rooms (pharmaceutical manufacturing) │
│ → Anesthesia machines │
└────────────────────────────────────────────────────┘
Position 1: Between Y-piece & patient airway
→ Protects patient from machine contamination
Position 2: On expiratory limb of circuit
→ Protects anesthesia machine from patient
Can prevent:
✓ Cross-infection between patients
✓ Contamination of anesthesia machine
✓ Spread of TB, MRSA, COVID-19 in ventilated patients
Smallest bacteria filter pore size = 0.22 µm (membrane filter)
→ Can remove even MYCOPLASMA (smallest bacterium)
→ CANNOT remove viruses (too small: 20-300 nm)
Berkefeld filter grades:
W = Wenig (coarse) - removes large particles
N = Normal (medium)
V = Viel (fine) - removes bacteria
Sterilization by filtration = only method that
physically REMOVES rather than kills organisms
Ideal for: heat-sensitive liquids (sera, vaccines,
toxins, antibiotics, sugars)
| Filter | Removes Bacteria? | Removes Viruses? | Removes Spores? |
|---|---|---|---|
| Membrane 0.22 µm | ✅ Yes | ❌ No | ✅ Yes |
| Berkefeld V | ✅ Yes | ❌ No | Depends |
| HEPA (0.3 µm) | ✅ Yes (air) | ❌ Most no | ✅ Yes |
| Seitz | ✅ Yes | Some | ✅ Yes |
┌──────────────────────────────────────────────────────────┐
│ 5-TOPIC SNAPSHOT │
├──────────────┬───────────────────────────────────────────┤
│ TYNDALLISATION│ 100°C × 3 days → kills vegetative + │
│ │ germinated spores of heat-labile media │
├──────────────┼───────────────────────────────────────────┤
│ NOSOCOMIAL │ Infection >48h after admission │
│ INFECTIONS │ BIG 4: UTI > Pneumonia > SSI > BSI │
├──────────────┼───────────────────────────────────────────┤
│ UNIVERSAL │ Treat ALL blood/body fluids as infectious │
│ PRECAUTIONS │ Gloves + Mask + Gown + Safe sharps + │
│ │ Handwashing = 5 pillars │
├──────────────┼───────────────────────────────────────────┤
│ GASEOUS │ ETO = gold standard (alkylation of DNA) │
│ DISINFECTANTS│ Formaldehyde = OT fumigation │
├──────────────┼───────────────────────────────────────────┤
│ BACTERIAL │ 0.22 µm membrane = gold standard │
│ FILTERS │ HEPA for air; removes not kills │
└──────────────┴───────────────────────────────────────────┘
Sources: Park's Textbook of Preventive & Social Medicine; Sherris & Ryan's Medical Microbiology, 8th ed.; Miller's Anesthesia, 10th ed.; Katzung's Basic & Clinical Pharmacology, 16th ed.
Create a PDF quick reference card with flow diagrams for these 5 topics
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
mkdir -p /tmp/workspace/micro-quickref && python3 -c "from reportlab.lib import colors; print('reportlab ok')" && python3 -c "import matplotlib; print('matplotlib ok')"
~/micro-quickref/make_diagrams.py
"""
Generate flow diagram PNG images for all 5 microbiology topics.
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
import numpy as np
import os
OUT = "/tmp/workspace/micro-quickref/diagrams"
os.makedirs(OUT, exist_ok=True)
# ─── Color palette ────────────────────────────────────────────
C_TITLE = "#1a237e" # deep navy
C_BOX1 = "#1565c0" # blue
C_BOX2 = "#0277bd" # med blue
C_BOX3 = "#00838f" # teal
C_BOX4 = "#2e7d32" # green
C_BOX5 = "#6a1b9a" # purple
C_WARN = "#b71c1c" # red
C_YELLOW = "#f9a825" # amber
C_LITE = "#e3f2fd" # very light blue
C_LITE2 = "#e8f5e9" # very light green
C_LITE3 = "#f3e5f5" # very light purple
C_LITE4 = "#fff8e1" # very light amber
C_WHITE = "#ffffff"
C_DARK = "#212121"
C_GRAY = "#546e7a"
def save(fig, name):
path = f"{OUT}/{name}.png"
fig.savefig(path, dpi=150, bbox_inches='tight', facecolor=fig.get_facecolor())
plt.close(fig)
print(f"Saved: {path}")
def rounded_box(ax, x, y, w, h, text, facecolor, textcolor='white',
fontsize=9, bold=False, radius=0.03, zorder=2, wrap=True):
box = FancyBboxPatch((x - w/2, y - h/2), w, h,
boxstyle=f"round,pad={radius}",
facecolor=facecolor, edgecolor='white',
linewidth=1.5, zorder=zorder)
ax.add_patch(box)
weight = 'bold' if bold else 'normal'
ax.text(x, y, text, ha='center', va='center',
fontsize=fontsize, color=textcolor, weight=weight,
zorder=zorder+1, wrap=wrap,
multialignment='center')
def arrow(ax, x1, y1, x2, y2, color='#455a64', lw=1.5, style='->', zorder=1):
ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
arrowprops=dict(arrowstyle=style, color=color,
lw=lw, connectionstyle='arc3,rad=0'))
# ═══════════════════════════════════════════════════════════════
# 1. TYNDALLISATION
# ═══════════════════════════════════════════════════════════════
def make_tyndall():
fig, ax = plt.subplots(figsize=(10, 7))
fig.patch.set_facecolor('#f0f4f8')
ax.set_facecolor('#f0f4f8')
ax.set_xlim(0, 10); ax.set_ylim(0, 7)
ax.axis('off')
# Title banner
ax.add_patch(FancyBboxPatch((0.1, 6.3), 9.8, 0.6, boxstyle="round,pad=0.05",
facecolor=C_TITLE, edgecolor='none'))
ax.text(5, 6.62, "TYNDALLISATION (Fractional / Intermittent Sterilization)",
ha='center', va='center', fontsize=13, color='white', weight='bold')
# Sub-info row
ax.text(2.5, 6.05, "Named after: John Tyndall (1877)", ha='center', va='center',
fontsize=8.5, color=C_TITLE, style='italic')
ax.text(7.5, 6.05, "Principle: Kill vegetative → Wait spores to germinate → Kill again",
ha='center', va='center', fontsize=8.5, color=C_TITLE)
# Flow steps – horizontal band
steps = [
(1.2, 4.5, "DAY 1\n100°C × 30 min\n(steam/Arnold's\nsterilizer)", C_BOX1),
(3.3, 4.5, "REST\nIncubate\n37°C overnight\n(spores germinate)", C_BOX2),
(5.4, 4.5, "DAY 2\n100°C × 30 min\n(kills germinated\nvegetative forms)", C_BOX3),
(7.5, 4.5, "REST\nIncubate\n37°C overnight", C_BOX2),
(9.3, 4.5, "DAY 3\n100°C × 30 min\nSTERILE ✓", C_BOX4),
]
for x, y, txt, col in steps:
rounded_box(ax, x, y, 1.7, 1.6, txt, col, fontsize=7.8, bold=False)
# Arrows between steps
xs = [s[0] for s in steps]
for i in range(len(xs)-1):
arrow(ax, xs[i]+0.85, 4.5, xs[i+1]-0.85, 4.5, color=C_GRAY, lw=2)
# Spore lifecycle annotation arc
ax.annotate('', xy=(7.5, 5.4), xytext=(3.3, 5.4),
arrowprops=dict(arrowstyle='<->', color=C_WARN, lw=1.2,
connectionstyle='arc3,rad=-0.35'))
ax.text(5.4, 6.0, "Repeat cycle ensures spore germination & killing",
ha='center', va='center', fontsize=7.5, color=C_WARN, style='italic')
# Bottom two panels: Uses vs Limitations
ax.add_patch(FancyBboxPatch((0.2, 0.2), 4.5, 3.4, boxstyle="round,pad=0.1",
facecolor=C_LITE, edgecolor=C_BOX1, linewidth=1))
ax.text(2.45, 3.45, "USES", ha='center', va='center', fontsize=10,
color=C_BOX1, weight='bold')
uses = [
"• Media with egg / serum / sugars",
" (denature above 100°C)",
"• Inspissated media (LJ medium)",
"• Heat-labile liquid media",
"• Cannot withstand autoclave (121°C)",
]
for i, u in enumerate(uses):
ax.text(0.5, 3.1 - i*0.52, u, va='center', fontsize=8.2, color=C_DARK)
ax.add_patch(FancyBboxPatch((5.3, 0.2), 4.5, 3.4, boxstyle="round,pad=0.1",
facecolor='#fce4ec', edgecolor=C_WARN, linewidth=1))
ax.text(7.55, 3.45, "LIMITATIONS", ha='center', va='center', fontsize=10,
color=C_WARN, weight='bold')
lims = [
"• Time-consuming (3 days)",
"• Requires both steamer +",
" incubator simultaneously",
"• NOT suitable for dry heat",
" or truly resistant spores",
"• Less certain than autoclave",
]
for i, l in enumerate(lims):
ax.text(5.5, 3.1 - i*0.52, l, va='center', fontsize=8.2, color=C_DARK)
# Memory tip
ax.add_patch(FancyBboxPatch((0.2, 0.05), 9.6, 0.12, boxstyle="round,pad=0.02",
facecolor=C_YELLOW, edgecolor='none', alpha=0.5))
save(fig, "1_tyndallisation")
# ═══════════════════════════════════════════════════════════════
# 2. NOSOCOMIAL INFECTIONS
# ═══════════════════════════════════════════════════════════════
def make_nosocomial():
fig, ax = plt.subplots(figsize=(10, 8))
fig.patch.set_facecolor('#f0f4f8')
ax.set_facecolor('#f0f4f8')
ax.set_xlim(0, 10); ax.set_ylim(0, 8)
ax.axis('off')
# Title
ax.add_patch(FancyBboxPatch((0.1, 7.3), 9.8, 0.62,
boxstyle="round,pad=0.05", facecolor=C_TITLE, edgecolor='none'))
ax.text(5, 7.62, "NOSOCOMIAL INFECTIONS (Hospital-Acquired Infections)",
ha='center', va='center', fontsize=13, color='white', weight='bold')
# Definition box
ax.add_patch(FancyBboxPatch((0.5, 6.5), 9, 0.65,
boxstyle="round,pad=0.08", facecolor='#e8eaf6', edgecolor=C_BOX1, lw=1.5))
ax.text(5, 6.82,
"Infection acquired during hospital care | NOT present at admission | Onset > 48 hours after admission",
ha='center', va='center', fontsize=8.5, color=C_TITLE, weight='bold')
# Triangle of sources
tri_x = [2.0, 5.0, 8.0, 2.0]
tri_y = [3.5, 5.8, 3.5, 3.5]
ax.plot(tri_x, tri_y, color=C_BOX1, lw=2, zorder=1)
rounded_box(ax, 2.0, 3.5, 2.5, 0.7, "PATIENTS\n(infected cases, carriers)", C_BOX1, fontsize=7.5)
rounded_box(ax, 8.0, 3.5, 2.5, 0.7, "ENVIRONMENT\n(dust, air, linen, sinks)", C_BOX3, fontsize=7.5)
rounded_box(ax, 5.0, 5.8, 2.5, 0.7, "STAFF\n(doctors, nurses, ward boys)", C_BOX2, fontsize=7.5)
ax.text(5.0, 4.6, "SOURCES", ha='center', va='center',
fontsize=11, color=C_BOX1, weight='bold', alpha=0.25)
# Routes of spread - right side
ax.add_patch(FancyBboxPatch((6.8, 0.2), 3.1, 3.1, boxstyle="round,pad=0.1",
facecolor=C_LITE, edgecolor=C_BOX2, lw=1))
ax.text(8.35, 3.1, "ROUTES OF SPREAD", ha='center', fontsize=9, color=C_BOX2, weight='bold')
routes = ["Direct contact (hands)", "Droplet infection", "Airborne particles",
"Hospital dust", "Invasive procedures\n(catheter, IV, dressings)"]
icons = ["✋", "💨", "🌫️", "🧹", "💉"]
for i, (r, ic) in enumerate(zip(routes, icons)):
ax.text(7.0, 2.75 - i*0.52, f"{ic} {r}", va='center', fontsize=7.8, color=C_DARK)
# BIG 4 nosocomial infections
ax.add_patch(FancyBboxPatch((0.2, 0.2), 3.2, 3.1, boxstyle="round,pad=0.1",
facecolor='#fce4ec', edgecolor=C_WARN, lw=1))
ax.text(1.8, 3.1, "THE BIG 4", ha='center', fontsize=9, color=C_WARN, weight='bold')
big4 = [("1.", "UTI", "← Urinary catheter"),
("2.", "Pneumonia (VAP)", "← Ventilator"),
("3.", "Surgical site", "← Operation"),
("4.", "Bloodstream (BSI)", "← IV line")]
for i, (n, inf, dev) in enumerate(big4):
ax.text(0.4, 2.75 - i*0.62, f"{n} {inf}", va='center', fontsize=8, color=C_DARK, weight='bold')
ax.text(0.4, 2.75 - i*0.62 - 0.22, f" {dev}", va='center', fontsize=7.5, color=C_GRAY)
# Prevention column
ax.add_patch(FancyBboxPatch((3.5, 0.2), 3.2, 3.1, boxstyle="round,pad=0.1",
facecolor=C_LITE2, edgecolor=C_BOX4, lw=1))
ax.text(5.1, 3.1, "PREVENTION", ha='center', fontsize=9, color=C_BOX4, weight='bold')
prevs = ["✅ HANDWASHING (#1 measure)",
"✅ Patient isolation",
"✅ Dust control (wet dusting)",
"✅ Disinfection of articles",
"✅ Masks + bed spacing",
"✅ Infection Control Committee"]
for i, p in enumerate(prevs):
ax.text(3.65, 2.78 - i*0.45, p, va='center', fontsize=7.5, color=C_DARK)
save(fig, "2_nosocomial")
# ═══════════════════════════════════════════════════════════════
# 3. UNIVERSAL PRECAUTIONS
# ═══════════════════════════════════════════════════════════════
def make_universal():
fig, ax = plt.subplots(figsize=(10, 8))
fig.patch.set_facecolor('#f0f4f8')
ax.set_facecolor('#f0f4f8')
ax.set_xlim(0, 10); ax.set_ylim(0, 8)
ax.axis('off')
# Title
ax.add_patch(FancyBboxPatch((0.1, 7.3), 9.8, 0.62,
boxstyle="round,pad=0.05", facecolor=C_BOX5, edgecolor='none'))
ax.text(5, 7.62, "UNIVERSAL PRECAUTIONS",
ha='center', va='center', fontsize=14, color='white', weight='bold')
# Definition
ax.add_patch(FancyBboxPatch((0.5, 6.5), 9, 0.65,
boxstyle="round,pad=0.08", facecolor='#ede7f6', edgecolor=C_BOX5, lw=1.5))
ax.text(5, 6.82,
"Treat ALL patients' blood & body fluids as potentially infectious, regardless of diagnosis",
ha='center', va='center', fontsize=9, color=C_BOX5, weight='bold')
# History timeline
ax.add_patch(FancyBboxPatch((0.2, 5.6), 9.6, 0.75,
boxstyle="round,pad=0.05", facecolor='#fff9c4', edgecolor=C_YELLOW, lw=1))
ax.text(1.2, 6.1, "1985", fontsize=9, color=C_DARK, weight='bold', ha='center')
ax.text(1.2, 5.85, "CDC: Universal\nPrecautions born\n(HIV/AIDS era)", fontsize=7, color=C_GRAY, ha='center')
ax.annotate('', xy=(4.5, 5.95), xytext=(2.5, 5.95),
arrowprops=dict(arrowstyle='->', color=C_GRAY, lw=1.5))
ax.text(5.0, 6.1, "1996", fontsize=9, color=C_DARK, weight='bold', ha='center')
ax.text(5.0, 5.85, "Replaced by\nSTANDARD PRECAUTIONS\n(broader scope)", fontsize=7, color=C_GRAY, ha='center')
ax.annotate('', xy=(7.5, 5.95), xytext=(6.5, 5.95),
arrowprops=dict(arrowstyle='->', color=C_GRAY, lw=1.5))
ax.text(8.5, 5.95, "Standard Precautions =\nUniversal Precautions +\nBody Substance Isolation",
fontsize=7.5, color=C_BOX5, ha='center', va='center', weight='bold')
# 5 pillars as vertical boxes
pillars = [
("1\n🧤", "GLOVES", "Wear for ALL\nblood/body fluid\ncontact\nChange between pts", C_BOX1),
("2\n😷", "MASK+\nEYE PROT.", "When splash/\nspray\nanticipated", C_BOX2),
("3\n🥼", "GOWN /\nAPRON", "If clothes may\nbe contaminated\n(plastic apron\nover gown)", C_BOX3),
("4\n💉", "SAFE\nSHARPS", "Never recap\nneedles\nPuncture-proof\ncontainers", C_WARN),
("5\n🚿", "HAND-\nWASHING", "Before/after\npatient contact\nAfter removing\ngloves", C_BOX4),
]
for i, (num, title, body, col) in enumerate(pillars):
x = 1.0 + i*2.0
# number circle
circ = plt.Circle((x, 4.85), 0.32, color=col, zorder=3)
ax.add_patch(circ)
ax.text(x, 4.85, num, ha='center', va='center', fontsize=7, color='white',
weight='bold', zorder=4)
# title box
rounded_box(ax, x, 4.2, 1.7, 0.55, title, col, fontsize=8.5, bold=True)
# body box
rounded_box(ax, x, 3.0, 1.7, 1.55, body, C_LITE3, textcolor=C_DARK, fontsize=7.5)
# Body fluids covered
ax.add_patch(FancyBboxPatch((0.2, 0.2), 4.5, 2.55, boxstyle="round,pad=0.1",
facecolor=C_LITE2, edgecolor=C_BOX4, lw=1))
ax.text(2.45, 2.6, "BODY FLUIDS COVERED", ha='center', fontsize=9, color=C_BOX4, weight='bold')
incl = ["✅ Blood", "✅ Semen / vaginal secretions",
"✅ CSF, synovial, pleural, amniotic fluid",
"✅ Any fluid visibly contaminated with blood",
"❌ Urine/faeces/sweat/saliva (unless bloody)"]
for i, t in enumerate(incl):
ax.text(0.4, 2.3 - i*0.44, t, va='center', fontsize=8, color=C_DARK)
# Target pathogens
ax.add_patch(FancyBboxPatch((5.3, 0.2), 4.5, 2.55, boxstyle="round,pad=0.1",
facecolor='#fce4ec', edgecolor=C_WARN, lw=1))
ax.text(7.55, 2.6, "TARGET PATHOGENS", ha='center', fontsize=9, color=C_WARN, weight='bold')
pats = ["💉 HIV (original trigger: AIDS epidemic)",
"🅱 HBV (worst-case model used by CDC)",
"© HCV (blood-borne hepatitis)",
"PEP: start within 72h of exposure",
" HIV needlestick → PEP immediately"]
for i, t in enumerate(pats):
ax.text(5.5, 2.3 - i*0.44, t, va='center', fontsize=8, color=C_DARK)
save(fig, "3_universal_precautions")
# ═══════════════════════════════════════════════════════════════
# 4. GASEOUS DISINFECTANTS
# ═══════════════════════════════════════════════════════════════
def make_gaseous():
fig, ax = plt.subplots(figsize=(10, 9))
fig.patch.set_facecolor('#f0f4f8')
ax.set_facecolor('#f0f4f8')
ax.set_xlim(0, 10); ax.set_ylim(0, 9)
ax.axis('off')
# Title
ax.add_patch(FancyBboxPatch((0.1, 8.3), 9.8, 0.62,
boxstyle="round,pad=0.05", facecolor="#004d40", edgecolor='none'))
ax.text(5, 8.62, "GASEOUS DISINFECTANTS / STERILANTS",
ha='center', va='center', fontsize=13, color='white', weight='bold')
# Indication banner
ax.add_patch(FancyBboxPatch((0.5, 7.65), 9, 0.5,
boxstyle="round,pad=0.05", facecolor='#e0f2f1', edgecolor="#004d40", lw=1))
ax.text(5, 7.9, "Used for items SENSITIVE to heat & moisture that cannot be autoclaved",
ha='center', va='center', fontsize=9, color="#004d40", weight='bold')
# 4 gas cards in 2×2 grid
cards = [
# (cx, cy, w, h, title, details, color, textcol)
(2.5, 6.0, 4.5, 2.4,
"ETHYLENE OXIDE (ETO) ⭐ GOLD STANDARD",
["Formula: C₂H₄O (epoxide ring)",
"Mechanism: Alkylation of DNA/proteins",
"Kills ALL incl. SPORES",
"Temp: 55-60°C | Humidity: 40-80% RH",
"Exposure: 3-6 h + Aeration: 8-12 h",
"Uses: plastics, rubber, electronics, packaged items",
"⚠ Toxic, carcinogenic, flammable, expensive"],
"#1a237e", "white"),
(7.5, 6.0, 4.5, 2.4,
"FORMALDEHYDE GAS",
["Source: Formalin (40% sol) or tablets",
"Mechanism: Alkylation of -NH₂,-COOH,-OH",
"OT Fumigation: KMnO₄ 15g + Formalin 30ml",
" per 1000 cubic feet",
"Leave 12-24 h → Ventilate → NH₃ to neutralize",
"Uses: OT fumigation, heat-labile instruments",
"⚠ Carcinogenic, irritant to mucosae"],
"#b71c1c", "white"),
(2.5, 3.0, 4.5, 2.4,
"GLUTARALDEHYDE (2% alkaline)",
["Brand: Cidex (activated alkaline solution)",
"Mechanism: Cross-links amino groups",
"Bactericidal/virucidal/fungicidal: 10-30 min",
"Sporicidal: 10 hours",
"Uses: Endoscopes, bronchoscopes, heat-sensitive",
" instruments (HIGH-LEVEL DISINFECTION)",
"⚠ Skin/respiratory irritant, not for skin use"],
"#4a148c", "white"),
(7.5, 3.0, 4.5, 2.4,
"HYDROGEN PEROXIDE VAPOR (HPV)",
["Form: Vapor or dry mist systems",
"Mechanism: Oxidation via free radicals (OH·)",
"Highly effective broad-spectrum sporicidal",
"Uses: Room decontamination (ICU, clean rooms)",
" Biosafety cabinet decontamination",
" Pharmaceutical clean rooms",
"⚠ Costly equipment; requires sealed rooms"],
"#006064", "white"),
]
for cx, cy, w, h, title, details, col, tc in cards:
ax.add_patch(FancyBboxPatch((cx-w/2, cy-h/2), w, h,
boxstyle="round,pad=0.12",
facecolor=col, edgecolor='white', lw=1.5))
ax.text(cx, cy+h/2-0.22, title, ha='center', va='center',
fontsize=8.5, color='white', weight='bold')
ax.plot([cx-w/2+0.15, cx+w/2-0.15], [cy+h/2-0.42, cy+h/2-0.42],
color='white', alpha=0.4, lw=0.8)
for i, d in enumerate(details):
ax.text(cx-w/2+0.18, cy+h/2-0.65-i*0.28, d, va='top',
fontsize=7.2, color='white')
# Comparison table
ax.add_patch(FancyBboxPatch((0.2, 0.15), 9.6, 2.55,
boxstyle="round,pad=0.1",
facecolor='#eceff1', edgecolor=C_GRAY, lw=1))
ax.text(5, 2.55, "QUICK COMPARISON", ha='center', fontsize=10,
color=C_DARK, weight='bold')
headers = ["Agent", "Mechanism", "Main Use", "Key Hazard"]
rows = [
["ETO", "Alkylation DNA/protein", "Heat-labile instruments", "Toxic, carcinogenic, flammable"],
["Formaldehyde", "Alkylation of proteins", "OT fumigation", "Carcinogenic, irritant"],
["Glutaraldehyde", "Cross-links amino groups", "Endoscopes (HLD)", "Skin/respiratory irritant"],
["H₂O₂ vapor", "Oxidation (free radicals)", "Room decontamination", "Costly equipment"],
]
col_x = [0.7, 2.7, 5.2, 7.7]
hdr_y = 2.3
for j, (h, cx) in enumerate(zip(headers, col_x)):
ax.text(cx, hdr_y, h, fontsize=8.5, color=C_BOX1, weight='bold')
for i, row in enumerate(rows):
y = 2.0 - i*0.42
bg = '#ffffff' if i%2==0 else '#e3f2fd'
ax.add_patch(FancyBboxPatch((0.3, y-0.18), 9.4, 0.38,
boxstyle="round,pad=0.02", facecolor=bg, edgecolor='none'))
for j, (cell, cx) in enumerate(zip(row, col_x)):
ax.text(cx, y, cell, fontsize=7.5, color=C_DARK, va='center')
save(fig, "4_gaseous_disinfectants")
# ═══════════════════════════════════════════════════════════════
# 5. BACTERIAL FILTERS
# ═══════════════════════════════════════════════════════════════
def make_filters():
fig, ax = plt.subplots(figsize=(10, 9))
fig.patch.set_facecolor('#f0f4f8')
ax.set_facecolor('#f0f4f8')
ax.set_xlim(0, 10); ax.set_ylim(0, 9)
ax.axis('off')
# Title
ax.add_patch(FancyBboxPatch((0.1, 8.3), 9.8, 0.62,
boxstyle="round,pad=0.05", facecolor="#37474f", edgecolor='none'))
ax.text(5, 8.62, "BACTERIAL FILTERS",
ha='center', va='center', fontsize=14, color='white', weight='bold')
# Definition
ax.add_patch(FancyBboxPatch((0.5, 7.65), 9, 0.5,
boxstyle="round,pad=0.05", facecolor='#eceff1', edgecolor="#37474f", lw=1))
ax.text(5, 7.9, "REMOVE (not kill) microorganisms by physical filtration | NO heat | NO chemicals",
ha='center', va='center', fontsize=9, color="#37474f", weight='bold')
# Two branches: LIQUID and AIR
rounded_box(ax, 5, 7.1, 2.5, 0.45, "BACTERIAL FILTERS", "#37474f", fontsize=9, bold=True)
arrow(ax, 3.0, 7.1, 2.0, 6.6, color=C_BOX1)
arrow(ax, 7.0, 7.1, 8.0, 6.6, color=C_BOX3)
rounded_box(ax, 2.0, 6.35, 3.2, 0.45, "FOR LIQUIDS", C_BOX1, fontsize=9, bold=True)
rounded_box(ax, 8.0, 6.35, 3.2, 0.45, "FOR AIR/GAS", C_BOX3, fontsize=9, bold=True)
# Liquid filters
liq_filters = [
("Seitz Filter", "Compressed asbestos/\nglass fiber pad", "~0.5 µm", "Adsorption\n+ sieving"),
("Chamberland", "Unglazed porcelain\n(Pasteur-Chamberland)", "Variable grades\nL1-L13", "Sieving"),
("Berkefeld", "Diatomaceous earth\n(kieselguhr)", "W/N/V grades\n(coarse→fine)", "Sieving"),
("Membrane\n(Millipore) ⭐", "Cellulose nitrate/\nacetate", "0.22 µm\n(gold std)", "Sieving"),
]
for i, (name, mat, pore, mech) in enumerate(liq_filters):
y = 5.6 - i*1.2
rounded_box(ax, 1.0, y, 1.5, 0.85, name, C_BOX1, fontsize=7.5, bold=True)
rounded_box(ax, 2.6, y, 1.7, 0.85, mat, C_LITE, textcolor=C_DARK, fontsize=7)
rounded_box(ax, 4.0, y, 1.2, 0.85, pore, "#e8eaf6", textcolor=C_BOX1, fontsize=7.5, bold=True)
arrow(ax, 1.75, y, 1.75, y, color=C_BOX1)
# Air filters - HEPA hero
ax.add_patch(FancyBboxPatch((5.7, 3.0), 4.2, 3.15,
boxstyle="round,pad=0.1",
facecolor='#e0f7fa', edgecolor=C_BOX3, lw=2))
ax.text(7.8, 5.95, "HEPA FILTER", ha='center', fontsize=11, color=C_BOX3, weight='bold')
ax.text(7.8, 5.65, "(High Efficiency Particulate Air)", ha='center', fontsize=8, color=C_GRAY)
hepa = ["Removes ≥ 0.3 µm particles",
"with 99.97% efficiency",
"",
"Uses:",
"• Laminar airflow OTs",
"• Isolation rooms",
" (immunocompromised pts)",
"• Biosafety cabinets (BSL 2/3)",
"• Anesthesia machines",
"• Pharma clean rooms"]
for i, t in enumerate(hepa):
ax.text(6.0, 5.35 - i*0.29, t, va='center', fontsize=8,
color=C_DARK if not t.startswith("Uses") else C_BOX3,
weight='bold' if t.startswith("Uses") else 'normal')
# Anesthesia filter positions
ax.add_patch(FancyBboxPatch((5.7, 0.15), 4.2, 2.7,
boxstyle="round,pad=0.1",
facecolor='#fff3e0', edgecolor=C_YELLOW, lw=1.5))
ax.text(7.8, 2.65, "ANESTHESIA CIRCUIT FILTERS", ha='center',
fontsize=8.5, color="#e65100", weight='bold')
anes = ["Position 1: Y-piece ↔ Patient airway",
" → Protects patient from machine",
"Position 2: Expiratory limb of circuit",
" → Protects machine from patient",
"Prevents: TB, MRSA, COVID-19 spread"]
for i, t in enumerate(anes):
ax.text(5.9, 2.35 - i*0.41, t, va='center', fontsize=7.8, color=C_DARK)
# Key exam facts at bottom
ax.add_patch(FancyBboxPatch((0.2, 0.15), 5.3, 2.7,
boxstyle="round,pad=0.1",
facecolor='#fff8e1', edgecolor=C_YELLOW, lw=1.5))
ax.text(2.85, 2.65, "KEY EXAM FACTS", ha='center', fontsize=9, color="#e65100", weight='bold')
facts = ["• 0.22 µm membrane = GOLD STANDARD for liquids",
"• Removes Mycoplasma (smallest bacterium)",
"• Does NOT remove viruses (too small: 20-300nm)",
"• Sterilization by filtration = REMOVES, not kills",
"• Berkefeld grades: W (coarse) N (normal) V (fine)",
"• Seitz filter: adsorption + sieving mechanism",
"• Ideal for: sera, vaccines, toxins, antibiotics"]
for i, t in enumerate(facts):
ax.text(0.4, 2.35 - i*0.34, t, va='center', fontsize=7.8, color=C_DARK)
save(fig, "5_bacterial_filters")
# Run all
make_tyndall()
make_nosocomial()
make_universal()
make_gaseous()
make_filters()
print("ALL DIAGRAMS DONE")
cd /tmp/workspace/micro-quickref && python3 make_diagrams.py 2>&1
~/micro-quickref/make_pdf.py
"""
Build the Quick Reference PDF card for 5 Microbiology topics.
Uses ReportLab for PDF generation + embeds the matplotlib diagram PNGs.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.platypus import (SimpleDocTemplate, Image, Paragraph, Spacer,
Table, TableStyle, PageBreak, HRFlowable)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import KeepTogether
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor
import os
OUT_PDF = "/tmp/workspace/micro-quickref/Microbiology_QuickRef_Card.pdf"
DIAG_DIR = "/tmp/workspace/micro-quickref/diagrams"
W, H = A4 # 595.27 x 841.89 pts
# ─── Color constants ─────────────────────────────────────────
NAVY = HexColor("#1a237e")
BLUE = HexColor("#1565c0")
TEAL = HexColor("#004d40")
GREEN = HexColor("#2e7d32")
PURPLE = HexColor("#4a148c")
RED = HexColor("#b71c1c")
AMBER = HexColor("#f57f17")
LGRAY = HexColor("#eceff1")
MGRAY = HexColor("#90a4ae")
DARK = HexColor("#212121")
WHITE = colors.white
TOPIC_COLORS = [NAVY, HexColor("#880e4f"), PURPLE, TEAL, HexColor("#37474f")]
# ─── Canvas callback for page decorations ────────────────────
def on_page(canvas_obj, doc):
canvas_obj.saveState()
# thin footer bar
canvas_obj.setFillColor(NAVY)
canvas_obj.rect(0, 0, W, 14, fill=1, stroke=0)
canvas_obj.setFillColor(WHITE)
canvas_obj.setFont("Helvetica", 7)
canvas_obj.drawCentredString(W/2, 4,
"Microbiology Quick Reference | Ref: Park's PSM, Sherris Medical Microbiology, Apurva Sastry 4e "
f"| Page {doc.page}")
# thin header line (not on cover page)
if doc.page > 1:
canvas_obj.setStrokeColor(NAVY)
canvas_obj.setLineWidth(1.5)
canvas_obj.line(20, H-18, W-20, H-18)
canvas_obj.restoreState()
# ─── Styles ───────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle", fontSize=32, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=38, spaceAfter=6)
cover_sub = S("CoverSub", fontSize=14, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica", leading=18)
cover_tag = S("CoverTag", fontSize=10, textColor=HexColor("#b3e5fc"),
alignment=TA_CENTER, fontName="Helvetica-Oblique", leading=14)
sec_title = S("SecTitle", fontSize=16, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=20, spaceBefore=4, spaceAfter=4)
body = S("Body", fontSize=9, textColor=DARK, leading=13,
fontName="Helvetica", spaceAfter=3)
body_bold = S("BodyBold", fontSize=9, textColor=DARK, leading=13,
fontName="Helvetica-Bold", spaceAfter=3)
small = S("Small", fontSize=7.5, textColor=DARK, leading=11,
fontName="Helvetica")
bullet_s = S("Bullet", fontSize=8.5, textColor=DARK, leading=13,
fontName="Helvetica", leftIndent=12, bulletIndent=0)
def colored_heading(text, bg_color, font_size=14):
"""Returns a Table that looks like a colored heading banner."""
p = Paragraph(f'<font color="white"><b>{text}</b></font>',
ParagraphStyle("hd", fontSize=font_size, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold",
leading=font_size+4))
t = Table([[p]], colWidths=[W - 50])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg_color),
('ROUNDEDCORNERS', [6, 6, 6, 6]),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
]))
return t
def info_box(text_list, bg=LGRAY, border=BLUE, font_size=8.5):
"""Returns a shaded info box containing bullet lines."""
paras = [Paragraph(t, ParagraphStyle("ib", fontSize=font_size,
textColor=DARK, leading=13, fontName="Helvetica",
leftIndent=6)) for t in text_list]
t = Table([[p] for p in paras], colWidths=[W - 54])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 0.8, border),
('ROUNDEDCORNERS', [4,4,4,4]),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
]))
return t
def two_col_table(left_content, right_content, left_bg, right_bg,
left_border, right_border, heading_l, heading_r,
hbg_l=None, hbg_r=None):
"""Two-column shaded box side-by-side."""
if hbg_l is None: hbg_l = left_border
if hbg_r is None: hbg_r = right_border
def make_cell(heading, content_list, hbg, cbg, border):
h = Paragraph(f'<font color="white"><b>{heading}</b></font>',
ParagraphStyle("ch", fontSize=9, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold",
leading=12))
rows = [[h]]
for item in content_list:
rows.append([Paragraph(item, ParagraphStyle("ci", fontSize=8,
textColor=DARK, leading=12, fontName="Helvetica",
leftIndent=4))])
col_w = (W - 54) / 2
t = Table(rows, colWidths=[col_w])
ts = TableStyle([
('BACKGROUND', (0,0), (0,0), hbg),
('BACKGROUND', (0,1), (-1,-1), cbg),
('BOX', (0,0), (-1,-1), 0.8, border),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
])
t.setStyle(ts)
return t
left_cell = make_cell(heading_l, left_content, hbg_l, left_bg, left_border)
right_cell = make_cell(heading_r, right_content, hbg_r, right_bg, right_border)
outer = Table([[left_cell, right_cell]], colWidths=[(W-54)/2+2, (W-54)/2+2])
outer.setStyle(TableStyle([
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('TOPPADDING', (0,0), (-1,-1), 0),
('BOTTOMPADDING',(0,0), (-1,-1), 0),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
return outer
def embed_diagram(filename, width_pct=0.95):
path = os.path.join(DIAG_DIR, filename)
img_w = (W - 50) * width_pct
img = Image(path, width=img_w, height=img_w * 0.7)
img.hAlign = 'CENTER'
return img
def sp(h=4): return Spacer(1, h)
# ════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════
story = []
# ── COVER PAGE ───────────────────────────────────────────────────────────────
class CoverPage:
"""Draws the cover using canvas directly."""
def wrap(self, available_width, available_height):
self.w = available_width
return (available_width, available_height)
def draw(self):
pass
def draw_cover(c, doc):
if doc.page != 1:
return
# Gradient-like solid background
c.setFillColor(HexColor("#0d1b4b"))
c.rect(0, 0, W, H, fill=1, stroke=0)
# Decorative diagonal stripe
c.setFillColor(HexColor("#1a3a8f"))
from reportlab.graphics.shapes import Polygon
pts = [0, H*0.55, W*0.7, H, W, H, W, H*0.4, W*0.3, 0, 0, 0]
c.setFillColor(HexColor("#162d7a"))
path = c.beginPath()
path.moveTo(0, H*0.60)
path.lineTo(W, H*0.35)
path.lineTo(W, H)
path.lineTo(0, H)
path.close()
c.drawPath(path, fill=1, stroke=0)
# Title
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 28)
c.drawCentredString(W/2, H - 130, "MICROBIOLOGY")
c.setFont("Helvetica-Bold", 22)
c.drawCentredString(W/2, H - 162, "Quick Reference Card")
# Subtitle underline
c.setStrokeColor(AMBER)
c.setLineWidth(3)
c.line(W/2 - 120, H-172, W/2+120, H-172)
# Topic list
topics = [
("1", "Tyndallisation", "#42a5f5"),
("2", "Nosocomial Infections", "#ef5350"),
("3", "Universal Precautions", "#ab47bc"),
("4", "Gaseous Disinfectants", "#26a69a"),
("5", "Bacterial Filters", "#78909c"),
]
c.setFont("Helvetica-Bold", 11)
c.setFillColor(HexColor("#b3e5fc"))
c.drawCentredString(W/2, H-200, "5 High-Yield Topics with Flow Diagrams")
for i, (num, topic, col) in enumerate(topics):
y = H - 240 - i*52
# badge
c.setFillColor(HexColor(col))
c.roundRect(W/2 - 160, y - 14, 320, 40, 8, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 14)
c.drawCentredString(W/2, y + 8, f"{num}. {topic}")
# Reference line
c.setFont("Helvetica-Oblique", 8.5)
c.setFillColor(HexColor("#b3e5fc"))
c.drawCentredString(W/2, 80, "Ref: Apurva Sastry 4th Ed | Park's Textbook PSM")
c.drawCentredString(W/2, 66, "Sherris & Ryan Medical Microbiology 8th Ed")
# Footer bar
c.setFillColor(HexColor("#0a1535"))
c.rect(0, 0, W, 50, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(AMBER)
c.drawCentredString(W/2, 30, "MICROBIOLOGY | Quick Reference | Flow Diagrams")
c.setFont("Helvetica", 8)
c.setFillColor(HexColor("#90a4ae"))
c.drawCentredString(W/2, 16, "For educational use only")
# Cover spacer (the actual cover is drawn on_page for page 1)
story.append(Spacer(1, H - 100))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# TOPIC 1: TYNDALLISATION
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("1. TYNDALLISATION (Fractional / Intermittent Sterilization)", NAVY))
story.append(sp(6))
story.append(info_box([
"<b>Definition:</b> A method of sterilizing heat-labile media/fluids that CANNOT withstand autoclave (121°C).",
"<b>Named after:</b> John Tyndall, Irish physicist (1877) - discovered spores resist a single boiling.",
"<b>Principle:</b> Vegetative forms killed by heat → Rest period allows spores to germinate "
"→ Next heat cycle kills the new vegetative forms → Repeat 3 times = STERILE.",
], bg=HexColor("#e8eaf6"), border=NAVY))
story.append(sp(8))
story.append(embed_diagram("1_tyndallisation.png", width_pct=0.95))
story.append(sp(8))
story.append(two_col_table(
left_content=[
"• Media containing EGG (e.g., LJ medium)",
"• Media containing SERUM",
"• Sugar-containing media",
"• Any fluid that denatures above 100°C",
"• Heat-labile liquids",
],
right_content=[
"• Time-consuming: 3 full days",
"• Needs steamer + incubator simultaneously",
"• Less reliable than autoclave",
"• NOT for dry heat or truly resistant spores",
"• Uncertain sterility guarantee vs autoclave",
],
left_bg=HexColor("#e8f5e9"), right_bg=HexColor("#fce4ec"),
left_border=GREEN, right_border=RED,
heading_l="USES", heading_r="LIMITATIONS",
hbg_l=GREEN, hbg_r=RED
))
story.append(sp(6))
story.append(info_box([
"<b>Memory Tip:</b> 3 Days | 3 Rounds of 100°C x 30 min | Rest at 37°C between rounds",
"<b>Equipment used:</b> Arnold's steam sterilizer (or Koch's steamer) | Incubator at 37°C",
], bg=HexColor("#fff9c4"), border=AMBER))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# TOPIC 2: NOSOCOMIAL INFECTIONS
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("2. NOSOCOMIAL INFECTIONS (Hospital-Acquired Infections)",
HexColor("#880e4f")))
story.append(sp(6))
story.append(info_box([
"<b>Definition (Park's PSM):</b> Infections acquired during hospital care, NOT present or incubating "
"at the time of admission. Onset > 48 hours after admission.",
"<b>Also includes:</b> Infections in staff/visitors acquired in the hospital setting.",
], bg=HexColor("#fce4ec"), border=HexColor("#880e4f")))
story.append(sp(8))
story.append(embed_diagram("2_nosocomial.png", width_pct=0.95))
story.append(sp(8))
# 3 panels: Sources, Routes, BIG 4
data = [
[
Paragraph('<font color="white"><b>SOURCES</b></font>',
ParagraphStyle("h", fontSize=9, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=13)),
Paragraph('<font color="white"><b>ROUTES OF SPREAD</b></font>',
ParagraphStyle("h", fontSize=9, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=13)),
Paragraph('<font color="white"><b>THE BIG 4</b></font>',
ParagraphStyle("h", fontSize=9, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=13)),
],
[
Paragraph("Patients (infectious diseases)<br/>"
"Staff (nasal carriers, skin)<br/>"
"Environment (dust, linen, air, sinks, door handles)",
ParagraphStyle("c", fontSize=8, leading=12, fontName="Helvetica",
textColor=DARK, leftIndent=4)),
Paragraph("1. Direct contact (hands)<br/>"
"2. Droplet infection<br/>"
"3. Airborne particles<br/>"
"4. Hospital dust<br/>"
"5. Invasive procedures (catheter, IV, dressings)",
ParagraphStyle("c", fontSize=8, leading=12, fontName="Helvetica",
textColor=DARK, leftIndent=4)),
Paragraph("<b>1. UTI</b> - urinary catheter<br/>"
"<b>2. Pneumonia (VAP)</b> - ventilator<br/>"
"<b>3. Surgical site</b> - operation<br/>"
"<b>4. Bloodstream (BSI)</b> - IV line",
ParagraphStyle("c", fontSize=8, leading=12.5, fontName="Helvetica",
textColor=DARK, leftIndent=4)),
],
]
cw = (W - 54) / 3
t = Table(data, colWidths=[cw, cw, cw])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,0), BLUE),
('BACKGROUND', (1,0), (1,0), HexColor("#880e4f")),
('BACKGROUND', (2,0), (2,0), HexColor("#b71c1c")),
('BACKGROUND', (0,1), (0,1), HexColor("#e8eaf6")),
('BACKGROUND', (1,1), (1,1), HexColor("#fce4ec")),
('BACKGROUND', (2,1), (2,1), HexColor("#fff3e0")),
('BOX', (0,0), (-1,-1), 0.5, MGRAY),
('INNERGRID', (0,0), (-1,-1), 0.5, MGRAY),
('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'),
]))
story.append(t)
story.append(sp(8))
story.append(info_box([
"<b>Prevention (mnemonic: I S H D D N A):</b> Isolation | Staff hygiene | "
"Handwashing (#1 measure) | Dust control | Disinfection | "
"Nursing techniques (barrier nursing) | Administrative (Infection Control Committee)",
"<b>Key pathogens (ESKAPE):</b> Enterococcus, S. aureus (MRSA), Klebsiella, "
"Acinetobacter, Pseudomonas, Enterobacter",
], bg=HexColor("#e8f5e9"), border=GREEN))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# TOPIC 3: UNIVERSAL PRECAUTIONS
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("3. UNIVERSAL PRECAUTIONS", HexColor("#4a148c")))
story.append(sp(6))
story.append(info_box([
"<b>Definition:</b> A set of infection control practices applied to ALL patients, "
"regardless of suspected/confirmed diagnosis. Treats ALL blood/body fluids as potentially infectious.",
"<b>History:</b> 1985 CDC introduced 'Universal Precautions' (triggered by HIV/AIDS epidemic, modeled on HBV transmission). "
"1996: Replaced by 'Standard Precautions' = Universal Precautions + Body Substance Isolation.",
], bg=HexColor("#f3e5f5"), border=HexColor("#4a148c")))
story.append(sp(8))
story.append(embed_diagram("3_universal_precautions.png", width_pct=0.95))
story.append(sp(8))
story.append(two_col_table(
left_content=[
"COVERED (treat as infectious):",
" Blood",
" Semen / vaginal secretions",
" CSF, synovial, pleural, peritoneal, pericardial fluid",
" Amniotic fluid",
" Any fluid visibly contaminated with blood",
],
right_content=[
"NOT covered (unless visibly bloody):",
" Urine",
" Faeces",
" Sweat, tears, nasal secretions, saliva",
"",
"Target pathogens: HIV, HBV, HCV",
],
left_bg=HexColor("#e8f5e9"), right_bg=HexColor("#fce4ec"),
left_border=GREEN, right_border=RED,
heading_l="BODY FLUIDS COVERED", heading_r="EXCLUSIONS + TARGETS",
hbg_l=GREEN, hbg_r=RED
))
story.append(sp(6))
story.append(info_box([
"<b>5 Pillars:</b> (1) Gloves | (2) Mask + Eye protection | (3) Gown/Apron "
"| (4) Safe sharps (never recap needles) | (5) Handwashing",
"<b>PEP after needlestick:</b> Report immediately | HIV PEP within 72 hours "
"| HBIg if unvaccinated against HBV",
], bg=HexColor("#fff9c4"), border=AMBER))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# TOPIC 4: GASEOUS DISINFECTANTS
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("4. GASEOUS DISINFECTANTS / STERILANTS", TEAL))
story.append(sp(6))
story.append(info_box([
"<b>Definition:</b> Agents that sterilize/disinfect in gaseous/vapor phase. "
"Used for items SENSITIVE to heat and moisture that cannot withstand autoclave.",
"<b>Key advantage:</b> Penetrate packaging; work at low temperatures; kill ALL organisms including spores.",
], bg=HexColor("#e0f2f1"), border=TEAL))
story.append(sp(8))
story.append(embed_diagram("4_gaseous_disinfectants.png", width_pct=0.95))
story.append(sp(8))
# 4 gas mini-table
gas_data = [
[Paragraph('<font color="white"><b>GAS</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>MECHANISM</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>MAIN USE</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>KEY HAZARD</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
],
["ETO (Ethylene Oxide) Gold Std", "Alkylation of DNA/proteins", "Heat-labile instruments, packaged goods", "Toxic, carcinogenic, flammable"],
["Formaldehyde (HCHO)", "Alkylation of -NH2/-COOH/-OH groups", "OT fumigation (KMnO4 + Formalin)", "Carcinogenic, mucosal irritant"],
["Glutaraldehyde 2% (Cidex)", "Cross-links amino groups", "Endoscopes - High Level Disinfection", "Skin/respiratory irritant"],
["H2O2 Vapor (HPV)", "Oxidation via free radicals (OH*)", "Room decontamination (ICU)", "Costly; needs sealed room"],
]
cws = [(W-54)*0.22, (W-54)*0.28, (W-54)*0.28, (W-54)*0.22]
gt = Table(gas_data, colWidths=cws)
gt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), TEAL),
('BACKGROUND', (0,1), (-1,1), HexColor("#e0f2f1")),
('BACKGROUND', (0,2), (-1,2), HexColor("#f3e5f5")),
('BACKGROUND', (0,3), (-1,3), HexColor("#e8eaf6")),
('BACKGROUND', (0,4), (-1,4), HexColor("#fff8e1")),
('BOX', (0,0), (-1,-1), 0.5, MGRAY),
('INNERGRID', (0,0), (-1,-1), 0.5, MGRAY),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('FONTSIZE', (0,1), (-1,-1), 8),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(gt)
story.append(sp(6))
story.append(info_box([
"<b>OT Fumigation with Formaldehyde:</b> Seal room completely | "
"KMnO4 15g + Formalin 30ml per 1000 cubic feet | Leave 12-24 hours | "
"Ventilate | Neutralize with NH3 (ammonia) spray",
"<b>ETO cycle:</b> 55-60°C | 40-80% RH | Exposure 3-6 h | Aeration 8-12 h (residue removal)",
], bg=HexColor("#fff9c4"), border=AMBER))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# TOPIC 5: BACTERIAL FILTERS
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("5. BACTERIAL FILTERS", HexColor("#37474f")))
story.append(sp(6))
story.append(info_box([
"<b>Definition:</b> Filters that REMOVE (not kill) microorganisms from liquids or gases "
"by physical filtration. No heat, no chemicals involved.",
"<b>Principle of sterilization by filtration:</b> The ONLY sterilization method that physically "
"removes rather than kills organisms. Ideal for heat-sensitive liquids (sera, vaccines, toxins, antibiotics).",
], bg=HexColor("#eceff1"), border=HexColor("#37474f")))
story.append(sp(8))
story.append(embed_diagram("5_bacterial_filters.png", width_pct=0.95))
story.append(sp(8))
# Filter comparison table
filter_data = [
[Paragraph('<font color="white"><b>Filter</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>Material</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>Pore Size</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
Paragraph('<font color="white"><b>Mechanism</b></font>',
ParagraphStyle("h", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold")),
],
["Seitz", "Compressed asbestos / glass fiber", "~0.5 um", "Adsorption + Sieving"],
["Chamberland", "Unglazed porcelain (Pasteur)", "Variable L1-L13", "Sieving"],
["Berkefeld", "Diatomaceous earth (kieselguhr)", "W/N/V grades", "Sieving"],
["Membrane (Millipore) GOLD STD", "Cellulose nitrate / acetate", "0.22 um", "Sieving (most reliable)"],
["HEPA (Air)", "Borosilicate glass fiber", "0.3 um (99.97%)", "Sieving + Impaction"],
]
fw = (W-54)
fcw = [fw*0.22, fw*0.30, fw*0.22, fw*0.26]
ft = Table(filter_data, colWidths=fcw)
ft.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), HexColor("#37474f")),
('BACKGROUND', (0,1), (-1,1), HexColor("#eceff1")),
('BACKGROUND', (0,2), (-1,2), HexColor("#e3f2fd")),
('BACKGROUND', (0,3), (-1,3), HexColor("#eceff1")),
('BACKGROUND', (0,4), (-1,4), HexColor("#e8f5e9")),
('BACKGROUND', (0,5), (-1,5), HexColor("#e8eaf6")),
('BOX', (0,0), (-1,-1), 0.5, MGRAY),
('INNERGRID', (0,0), (-1,-1), 0.5, MGRAY),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('FONTSIZE', (0,1), (-1,-1), 8),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(ft)
story.append(sp(6))
story.append(info_box([
"<b>Gold standard for liquid filtration:</b> Membrane filter (0.22 um) | "
"Removes Mycoplasma (smallest bacterium, 300 nm) | Does NOT remove viruses (20-300 nm range).",
"<b>Berkefeld grades:</b> W = Wenig (coarse) | N = Normal (medium) | V = Viel (fine, removes bacteria)",
"<b>HEPA filter uses:</b> Laminar airflow OT | Isolation rooms | Biosafety cabinets (BSL-2/3) "
"| Anesthesia machines | Pharmaceutical clean rooms",
"<b>Anesthesia circuit filters:</b> Position 1 (Y-piece to airway) protects patient | "
"Position 2 (expiratory limb) protects machine | Prevents TB, MRSA, COVID-19 cross-transmission",
], bg=HexColor("#e0f7fa"), border=HexColor("#37474f")))
story.append(PageBreak())
# ────────────────────────────────────────────────────────────────────────────
# MASTER REVISION SUMMARY PAGE
# ────────────────────────────────────────────────────────────────────────────
story.append(colored_heading("MASTER REVISION SUMMARY - 5 Topics at a Glance", NAVY))
story.append(sp(10))
summary_data = [
[Paragraph('<font color="white"><b>TOPIC</b></font>',
ParagraphStyle("h", fontSize=10, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=14)),
Paragraph('<font color="white"><b>DEFINITION / KEY POINT</b></font>',
ParagraphStyle("h", fontSize=10, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=14)),
Paragraph('<font color="white"><b>MUST KNOW</b></font>',
ParagraphStyle("h", fontSize=10, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", leading=14)),
],
[
Paragraph('<b>Tyndallisation</b>', ParagraphStyle("c", fontSize=9, fontName="Helvetica-Bold", textColor=NAVY, leading=13)),
Paragraph("Fractional sterilization using 100°C x 30 min repeated 3 times over 3 days, with 37°C incubation between cycles.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
Paragraph("For heat-labile media (egg, serum, sugar). Named after John Tyndall (1877).", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
],
[
Paragraph('<b>Nosocomial Infections</b>', ParagraphStyle("c", fontSize=9, fontName="Helvetica-Bold", textColor=HexColor("#880e4f"), leading=13)),
Paragraph("Hospital-acquired infection. NOT present at admission. Onset > 48h after admission. Endemic or epidemic.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
Paragraph("BIG 4: UTI > Pneumonia > SSI > BSI. Sources: Patient/Staff/Environment. #1 prevention = Handwashing.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
],
[
Paragraph('<b>Universal Precautions</b>', ParagraphStyle("c", fontSize=9, fontName="Helvetica-Bold", textColor=HexColor("#4a148c"), leading=13)),
Paragraph("Treat ALL patients' blood and body fluids as infectious regardless of diagnosis. Introduced by CDC 1985.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
Paragraph("5 pillars: Gloves, Mask+Eye, Gown, Safe sharps, Handwashing. Targets: HIV, HBV, HCV. PEP within 72h.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
],
[
Paragraph('<b>Gaseous Disinfectants</b>', ParagraphStyle("c", fontSize=9, fontName="Helvetica-Bold", textColor=TEAL, leading=13)),
Paragraph("Kill microorganisms in gaseous/vapor phase. Used for heat + moisture sensitive items.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
Paragraph("ETO = Gold standard (alkylation, 55-60°C). HCHO = OT fumigation. Glutaraldehyde = endoscopes (HLD).", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
],
[
Paragraph('<b>Bacterial Filters</b>', ParagraphStyle("c", fontSize=9, fontName="Helvetica-Bold", textColor=HexColor("#37474f"), leading=13)),
Paragraph("REMOVE (not kill) organisms by physical filtration. Only sterilization method that removes rather than kills.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
Paragraph("0.22 um membrane = Gold standard. HEPA for air (99.97% at 0.3 um). Cannot remove viruses.", ParagraphStyle("c", fontSize=8.5, fontName="Helvetica", textColor=DARK, leading=12)),
],
]
sw = W - 54
scw = [sw*0.20, sw*0.42, sw*0.38]
row_bgs = [NAVY, HexColor("#e8eaf6"), HexColor("#fce4ec"),
HexColor("#f3e5f5"), HexColor("#e0f2f1"), HexColor("#eceff1")]
st = Table(summary_data, colWidths=scw)
ts_styles = [
('BACKGROUND', (0,0), (-1,0), NAVY),
('BOX', (0,0), (-1,-1), 1, NAVY),
('INNERGRID', (0,0), (-1,-1), 0.5, MGRAY),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 7),
('RIGHTPADDING', (0,0), (-1,-1), 7),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]
for i, bg in enumerate(row_bgs[1:], 1):
ts_styles.append(('BACKGROUND', (0,i), (-1,i), bg))
st.setStyle(TableStyle(ts_styles))
story.append(st)
story.append(sp(14))
# Mnemonics box
story.append(colored_heading("QUICK MNEMONICS", AMBER))
story.append(sp(6))
story.append(info_box([
"<b>Tyndallisation:</b> '3 Rounds, 3 Days, 100 degrees' - heat, rest, heat, rest, heat",
"<b>Nosocomial BIG 4:</b> 'UTI Pumps Surgical Blood' = UTI | Pneumonia | Surgical site | Bloodstream",
"<b>Universal Precautions 5 pillars:</b> 'GMEHS' = Gloves, Mask+Eye, gown (H=hands)",
"<b>Gaseous disinfectants:</b> 'FEGH = Four gases Everyone Gets Hazardous from'",
" F = Formaldehyde | E = Ethylene oxide | G = Glutaraldehyde | H = H2O2 vapor",
"<b>Bacterial filter sizes:</b> Membrane 0.22 um > HEPA 0.3 um > Seitz ~0.5 um",
"<b>Berkefeld grades:</b> W-N-V = Wenig (coarse) Normal Viel (fine) = Win No Virus",
], bg=HexColor("#fff9c4"), border=AMBER))
# ════════════════════════════════════════════════════════════════
# BUILD PDF
# ════════════════════════════════════════════════════════════════
doc = SimpleDocTemplate(
OUT_PDF,
pagesize=A4,
leftMargin=25, rightMargin=25,
topMargin=28, bottomMargin=24,
title="Microbiology Quick Reference Card",
author="Orris AI | Ref: Apurva Sastry 4e, Park's PSM, Sherris",
subject="Tyndallisation, Nosocomial, Universal Precautions, Gaseous Disinfectants, Bacterial Filters",
)
def page_template(c, d):
on_page(c, d)
if d.page == 1:
draw_cover(c, d)
doc.build(story, onFirstPage=page_template, onLaterPages=page_template)
print(f"PDF saved: {OUT_PDF}")
cd /tmp/workspace/micro-quickref && python3 make_pdf.py 2>&1
ls -lh /tmp/workspace/micro-quickref/Microbiology_QuickRef_Card.pdf && ls -lh /tmp/workspace/micro-quickref/diagrams/
Microbiology QuickRef Card
PDF Document · PDF
| Page | Content |
|---|---|
| 1 | Cover page - dark navy with all 5 topic badges |
| 2 | Tyndallisation - step-by-step flow diagram + Uses vs Limitations side-by-side table |
| 3 | Nosocomial Infections - triangle of sources, routes of spread, BIG 4, prevention |
| 4 | Universal Precautions - history timeline, 5 pillars diagram, body fluids covered |
| 5 | Gaseous Disinfectants - 4 gas cards (ETO/Formaldehyde/Glutaraldehyde/H2O2), comparison table |
| 6 | Bacterial Filters - liquid vs air filter types, HEPA details, anesthesia positions |
| 7 | Master Revision Summary - all 5 topics in one table + Quick Mnemonics box |