Prepare notes for this
| Stem/Prefix | Drug Class | Examples |
|---|---|---|
| -olol | Beta-blockers | Propranolol, Atenolol |
| -pril | ACE Inhibitors | Lisinopril, Enalapril |
| -cillin | Penicillin derivatives | Ampicillin |
| -statin | HMG-CoA reductase inhibitors | Atorvastatin |
| Es- | S-enantiomer (stereoisomer prefix) | Esomeprazole |
| Levo- | Levorotatory isomer | Levothyroxine |
Tip: Recognizing these stems in any drug name immediately tells you the class and likely mechanism of action.
| Topic | Key Point |
|---|---|
| -olol | Beta-blocker (e.g., atenolol) |
| -pril | ACE inhibitor (e.g., enalapril) |
| -statin | Cholesterol-lowering (HMG-CoA inhibitor) |
| -cillin | Antibiotic - penicillin family |
| Es- / Levo- | Stereoisomer prefixes |
| IV route | Fastest onset; used in emergencies & unconscious patients |
| Oral route | Contraindicated in vomiting/NPO |
| Intrathecal | CNS delivery; bypasses BBB |
| Lipophilicity | Better membrane crossing & CNS penetration |
Create a study guide document on pharmacokinetics principles
mkdir -p /home/daytona/workspace/pharmacokinetics-guide && ls /home/daytona/work…
~/pharmacokinetics-guide/generate_pk_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import ListFlowable, ListItem
OUTPUT_PATH = "/home/daytona/workspace/pharmacokinetics-guide/Pharmacokinetics_Study_Guide.pdf"
# ── Color Palette ──────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1a3a5c")
TEAL = colors.HexColor("#0d6e8a")
LIGHT_TEAL = colors.HexColor("#e8f4f8")
ACCENT = colors.HexColor("#e8a020")
LIGHT_GRAY = colors.HexColor("#f5f5f5")
MED_GRAY = colors.HexColor("#cccccc")
WHITE = colors.white
RED_BOX = colors.HexColor("#fff3f3")
RED_BORDER = colors.HexColor("#c0392b")
GREEN_BOX = colors.HexColor("#f0fff4")
GREEN_BORDER = colors.HexColor("#27ae60")
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.5*cm, bottomMargin=2.5*cm,
title="Pharmacokinetics Study Guide",
author="Orris Medical Education",
)
styles = getSampleStyleSheet()
# Custom styles
cover_title = ParagraphStyle("CoverTitle", parent=styles["Title"],
fontSize=32, textColor=WHITE, alignment=TA_CENTER, spaceAfter=6,
fontName="Helvetica-Bold", leading=38)
cover_sub = ParagraphStyle("CoverSub", parent=styles["Normal"],
fontSize=14, textColor=colors.HexColor("#d0eaf5"), alignment=TA_CENTER,
fontName="Helvetica", spaceAfter=4)
chapter_heading = ParagraphStyle("ChapterHeading",
fontSize=18, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_LEFT, spaceAfter=4, spaceBefore=8, leading=22,
backColor=NAVY, borderPad=(8, 8, 8, 8))
section_heading = ParagraphStyle("SectionHeading",
fontSize=13, textColor=NAVY, fontName="Helvetica-Bold",
spaceBefore=12, spaceAfter=4, leading=16, borderPad=4)
sub_heading = ParagraphStyle("SubHeading",
fontSize=11, textColor=TEAL, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3, leading=14)
body = ParagraphStyle("Body", parent=styles["Normal"],
fontSize=10, leading=15, spaceAfter=5, alignment=TA_JUSTIFY,
fontName="Helvetica")
bullet_style = ParagraphStyle("Bullet", parent=body,
leftIndent=16, bulletIndent=4, spaceAfter=3, leading=14)
formula_style = ParagraphStyle("Formula",
fontSize=11, fontName="Helvetica-Bold", textColor=NAVY,
alignment=TA_CENTER, spaceBefore=6, spaceAfter=6,
backColor=LIGHT_TEAL, borderPad=8, leading=16)
callout_style = ParagraphStyle("Callout",
fontSize=9.5, fontName="Helvetica", leading=14,
textColor=colors.HexColor("#333333"), spaceAfter=4)
tip_title = ParagraphStyle("TipTitle",
fontSize=10, fontName="Helvetica-Bold", textColor=GREEN_BORDER,
spaceAfter=2, leading=13)
warn_title = ParagraphStyle("WarnTitle",
fontSize=10, fontName="Helvetica-Bold", textColor=RED_BORDER,
spaceAfter=2, leading=13)
story = []
# ═══════════════════════════════════════════════════════════════════
# COVER PAGE
# ═══════════════════════════════════════════════════════════════════
cover_table = Table(
[[Paragraph("PHARMACOKINETICS", cover_title),
Paragraph("A Complete Study Guide for Medical Students", cover_sub),
Paragraph("MBBS · MD · Pharmacology", cover_sub),
Spacer(1, 0.5*cm),
Paragraph("Based on: Lippincott Illustrated Reviews: Pharmacology · Goodman & Gilman's · Katzung's",
ParagraphStyle("CoverRef", parent=cover_sub, fontSize=9, textColor=colors.HexColor("#a0c8e0"))),
]],
colWidths=[17*cm],
rowHeights=[None]
)
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 60),
("BOTTOMPADDING", (0,0), (-1,-1), 60),
("LEFTPADDING", (0,0), (-1,-1), 30),
("RIGHTPADDING", (0,0), (-1,-1), 30),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(cover_table)
# Decorative accent bar
story.append(Table([[""]], colWidths=[17*cm], rowHeights=[0.4*cm],
style=[("BACKGROUND",(0,0),(-1,-1), ACCENT)]))
story.append(Spacer(1, 0.3*cm))
def section_divider(title):
t = Table([[Paragraph(f" {title}", chapter_heading)]], colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), NAVY),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),12),
]))
return t
def callout_box(title, items, bg=LIGHT_TEAL, border=TEAL, title_color=TEAL):
title_p = Paragraph(title, ParagraphStyle("CBTitle", fontSize=10,
fontName="Helvetica-Bold", textColor=title_color, spaceAfter=3))
content = [title_p]
for item in items:
content.append(Paragraph(f"• {item}", callout_style))
t = Table([[content]], colWidths=[16*cm])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), bg),
("BOX",(0,0),(-1,-1), 1, border),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),12),
("RIGHTPADDING",(0,0),(-1,-1),8),
]))
return t
def formula_box(formula_text, label=None):
items = []
if label:
items.append(Paragraph(label, ParagraphStyle("FLabel", fontSize=9,
fontName="Helvetica", textColor=TEAL, spaceAfter=2, alignment=TA_CENTER)))
items.append(Paragraph(formula_text, formula_style))
t = Table([[ items ]], colWidths=[16*cm])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), LIGHT_TEAL),
("BOX",(0,0),(-1,-1), 1.5, TEAL),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
]))
return t
# ═══════════════════════════════════════════════════════════════════
# CONTENTS PAGE
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(Paragraph("Contents", ParagraphStyle("TOCTitle", fontSize=20,
fontName="Helvetica-Bold", textColor=NAVY, spaceAfter=16, spaceBefore=4)))
story.append(HRFlowable(width="100%", thickness=2, color=TEAL, spaceAfter=10))
toc_items = [
("1", "Overview of Pharmacokinetics"),
("2", "Absorption"),
("3", "Bioavailability & First-Pass Metabolism"),
("4", "Distribution"),
("5", "Metabolism (Biotransformation)"),
("6", "Elimination & Renal Excretion"),
("7", "Key Pharmacokinetic Parameters"),
("8", "Half-Life & Steady State"),
("9", "Dosage Regimens"),
("10", "Special Populations"),
("11", "Quick-Reference Formulas"),
("12", "MCQ-Style Revision Quiz"),
]
toc_data = []
for num, title in toc_items:
toc_data.append([
Paragraph(f"<b>{num}.</b>", ParagraphStyle("TOCNum", fontSize=10,
fontName="Helvetica-Bold", textColor=TEAL)),
Paragraph(title, ParagraphStyle("TOCItem", fontSize=10,
fontName="Helvetica", textColor=colors.HexColor("#222"))),
])
toc_table = Table(toc_data, colWidths=[1.2*cm, 15*cm])
toc_table.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LINEBELOW",(0,0),(-1,-1),0.3,MED_GRAY),
]))
story.append(toc_table)
# ═══════════════════════════════════════════════════════════════════
# SECTION 1 – OVERVIEW
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("1 Overview of Pharmacokinetics"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"<b>Pharmacokinetics (PK)</b> is the study of <i>what the body does to a drug</i>. "
"It encompasses the processes of <b>Absorption, Distribution, Metabolism, and Elimination (ADME)</b>. "
"Together, these four processes determine the onset, intensity, and duration of drug action.",
body))
story.append(Spacer(1, 0.2*cm))
story.append(callout_box("ADME at a Glance", [
"Absorption – drug enters the systemic circulation from the site of administration",
"Distribution – drug reversibly leaves the bloodstream into interstitial and intracellular fluids",
"Metabolism – biotransformation by the liver (mainly) or other tissues",
"Elimination – removal from the body via urine, bile, or feces",
], bg=LIGHT_TEAL, border=TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Clinicians use PK parameters to design optimal drug regimens – choosing the correct "
"<b>route of administration, dose, frequency, and duration</b> of treatment.",
body))
# ═══════════════════════════════════════════════════════════════════
# SECTION 2 – ABSORPTION
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("2 Absorption"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"Absorption is the movement of a drug from its site of administration into the systemic circulation. "
"The rate and extent of absorption depend on the drug's physicochemical properties and the route used.",
body))
story.append(Paragraph("2.1 Routes of Administration", section_heading))
routes_data = [
[Paragraph("<b>Route</b>", callout_style), Paragraph("<b>Onset</b>", callout_style),
Paragraph("<b>Key Features</b>", callout_style), Paragraph("<b>Examples</b>", callout_style)],
["Oral (PO)", "Slow–Moderate", "Convenient; subject to first-pass metabolism; GI absorption", "Most tablets, capsules"],
["Sublingual/Buccal", "Fast", "Bypasses first-pass; absorbed via oral mucosa", "Nitroglycerine, Buprenorphine"],
["Intravenous (IV)", "Immediate", "100% bioavailability; no absorption step", "Antibiotics, chemotherapy"],
["Intramuscular (IM)", "Moderate", "Good for depot preparations; bypasses GI", "Vaccines, Haloperidol decanoate"],
["Subcutaneous (SC)", "Moderate", "Slower than IM; suitable for proteins/insulins", "Insulin, Heparin"],
["Transdermal", "Very slow", "Sustained release; bypasses first-pass", "Nicotine patch, Fentanyl patch"],
["Inhalation", "Fast", "Large surface area; direct lung delivery", "Salbutamol, Anaesthetic gases"],
["Rectal", "Variable", "Partial first-pass bypass; used in vomiting/children", "Diazepam rectal gel"],
["Intrathecal", "Immediate (CNS)", "Bypasses blood-brain barrier directly", "Spinal anaesthetics, Methotrexate"],
]
rt = Table(routes_data, colWidths=[3*cm, 2.4*cm, 6.5*cm, 5.1*cm])
rt.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4, MED_GRAY),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
]))
story.append(rt)
story.append(Paragraph("2.2 Mechanisms of Drug Absorption", section_heading))
mech_data = [
["Passive Diffusion", "Most common. Drug moves down concentration gradient (high to low). Lipid-soluble drugs cross membranes easily. No energy required."],
["Facilitated Diffusion", "Uses carrier protein (transporter). Down concentration gradient. No energy. E.g., glucose transport."],
["Active Transport", "Requires energy (ATP). Against concentration gradient. Saturable and inhibitable. E.g., P-glycoprotein efflux."],
["Endocytosis/Pinocytosis", "Cell engulfs drug. Important for large molecules (proteins, vaccines)."],
["Filtration", "Water-soluble small molecules pass through pores/slit junctions (e.g., capillary endothelium)."],
]
mt = Table(mech_data, colWidths=[4.5*cm, 12.5*cm])
mt.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,-1), LIGHT_TEAL),
("FONTNAME",(0,0),(0,-1),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
]))
story.append(mt)
story.append(Spacer(1, 0.3*cm))
story.append(callout_box("Henderson-Hasselbalch Principle",
["Weak acids (pKa 3-5): mostly un-ionized in stomach (acidic) → better absorbed from stomach",
"Weak bases (pKa 8-10): mostly un-ionized in small intestine (alkaline) → better absorbed from intestine",
"Un-ionized form is lipid-soluble and crosses membranes; ionized form is water-soluble and trapped",
"Ion trapping: acidic drugs accumulate in alkaline compartments (e.g., basic urine) and vice versa"],
bg=LIGHT_TEAL, border=TEAL))
# ═══════════════════════════════════════════════════════════════════
# SECTION 3 – BIOAVAILABILITY
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("3 Bioavailability & First-Pass Metabolism"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"<b>Bioavailability (F)</b> is the fraction of an administered dose that reaches the systemic circulation "
"in an unchanged (active) form. IV administration gives 100% bioavailability by definition. "
"Oral bioavailability is almost always less than 100% due to incomplete absorption and first-pass metabolism.",
body))
story.append(Spacer(1, 0.2*cm))
story.append(formula_box(
"F = AUC<sub>oral</sub> / AUC<sub>IV</sub> × 100%",
"Bioavailability Formula (AUC = Area Under the Plasma Concentration-Time Curve)"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("3.1 First-Pass (Presystemic) Metabolism", section_heading))
story.append(Paragraph(
"After oral ingestion, a drug is absorbed from the GI tract and transported to the liver via the portal vein "
"<i>before</i> reaching the systemic circulation. Hepatic enzymes (mainly CYP450) may metabolize a significant "
"fraction of the drug, reducing the amount available. This is called the <b>first-pass effect</b> "
"or <b>presystemic elimination</b>.",
body))
story.append(Spacer(1, 0.2*cm))
fp_data = [
[Paragraph("<b>High First-Pass Drugs</b>", callout_style), Paragraph("<b>Strategy to Bypass</b>", callout_style)],
["Morphine, Meperidine", "Use IV or IM route"],
["Midazolam, Nifedipine", "Sublingual / IV"],
["Nitroglycerin", "Sublingual or transdermal patch"],
["Lidocaine", "IV (not oral)"],
["Propranolol", "Oral dose must be much higher than IV dose"],
["Estradiol", "Transdermal patch, vaginal preparation"],
]
fpt = Table(fp_data, colWidths=[8.5*cm, 8.5*cm])
fpt.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), TEAL),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),8),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(fpt)
story.append(Spacer(1, 0.3*cm))
story.append(callout_box("Factors Affecting Bioavailability",
["Drug solubility and particle size (dissolution step must occur first)",
"Gut wall metabolism by CYP3A4 (e.g., reduces midazolam bioavailability)",
"Efflux transporters: P-glycoprotein pumps drug back into gut lumen",
"GI pH and motility – affect dissolution and absorption rate",
"Food interactions – high-fat meals may increase or decrease absorption"],
bg=LIGHT_TEAL, border=TEAL))
# ═══════════════════════════════════════════════════════════════════
# SECTION 4 – DISTRIBUTION
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("4 Distribution"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"After absorption, drugs distribute from the plasma into the interstitial and intracellular fluids. "
"The extent of distribution depends on <b>lipophilicity, plasma protein binding, tissue binding, "
"and blood flow</b> to organs.",
body))
story.append(Paragraph("4.1 Volume of Distribution (Vd)", section_heading))
story.append(Paragraph(
"The <b>apparent volume of distribution (Vd)</b> is the theoretical volume that would be required "
"to contain the total body drug at the same concentration as measured in plasma. "
"It does not correspond to a real physiological volume.",
body))
story.append(formula_box(
"Vd = Dose / C₀ (liters)",
"Vd = Amount of drug in body ÷ Plasma drug concentration at time zero (C₀)"))
story.append(Spacer(1, 0.3*cm))
vd_data = [
[Paragraph("<b>Vd (approx.)</b>", callout_style), Paragraph("<b>Compartment</b>", callout_style),
Paragraph("<b>Drug Type</b>", callout_style), Paragraph("<b>Example</b>", callout_style)],
["~4 L", "Plasma (vascular)", "High MW or extensively protein-bound", "Heparin, Warfarin"],
["~14 L", "Extracellular fluid", "Low MW, hydrophilic", "Aminoglycosides, Mannitol"],
["~42 L", "Total body water", "Low MW, moderately lipophilic", "Ethanol, Many small drugs"],
[">100 L", "Tissue sequestration", "Highly lipophilic / tissue-bound", "Chloroquine, Amiodarone"],
]
vdt = Table(vd_data, colWidths=[2.5*cm, 4.5*cm, 5.5*cm, 4.5*cm])
vdt.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(vdt)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("4.2 Plasma Protein Binding", section_heading))
story.append(Paragraph(
"Many drugs bind reversibly to plasma proteins (mainly <b>albumin</b> for acidic drugs; "
"<b>alpha-1-acid glycoprotein</b> for basic drugs). Only the <b>free (unbound)</b> fraction "
"is pharmacologically active and can cross membranes, reach target tissues, be metabolized, "
"or be excreted.",
body))
story.append(callout_box("Protein Binding – Key Points",
["Highly protein-bound drugs (>90%): Warfarin, Phenytoin, NSAIDs",
"Drug displacement interactions: two highly bound drugs compete for binding sites – free concentration rises → risk of toxicity",
"Hypoalbuminaemia (e.g., liver disease, malnutrition) → increased free drug fraction",
"Large Vd = drug has left plasma and concentrated in tissues",
"Small Vd = drug remains mostly in plasma (e.g., highly protein-bound)"],
bg=LIGHT_TEAL, border=TEAL))
story.append(Paragraph("4.3 Blood-Brain Barrier (BBB)", section_heading))
story.append(Paragraph(
"The BBB consists of tight junctions between brain capillary endothelial cells. "
"Only <b>lipophilic, un-ionized, and low-molecular-weight</b> drugs can cross it. "
"P-glycoprotein efflux transporters further limit CNS penetration. "
"Inflammation (e.g., meningitis) can transiently disrupt the BBB.",
body))
# ═══════════════════════════════════════════════════════════════════
# SECTION 5 – METABOLISM
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("5 Metabolism (Biotransformation)"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"Drug metabolism converts lipophilic drugs into more polar (water-soluble) metabolites, "
"making them easier to excrete. The <b>liver</b> is the primary site, though the gut wall, "
"lungs, kidneys, and plasma also contribute. Metabolism may <b>inactivate, activate, or alter</b> drug activity.",
body))
story.append(Paragraph("5.1 Phase I Reactions", section_heading))
story.append(Paragraph(
"<b>Phase I</b> reactions introduce or unmask a polar functional group. "
"The main enzyme system is the <b>cytochrome P450 (CYP450)</b> superfamily located in "
"the hepatic smooth endoplasmic reticulum.",
body))
phase1_data = [
[Paragraph("<b>Reaction</b>", callout_style), Paragraph("<b>Description</b>", callout_style)],
["Oxidation", "Most common. CYP450-mediated. Adds oxygen or removes hydrogen."],
["Reduction", "Adds hydrogen / removes oxygen. Less common."],
["Hydrolysis", "Cleaves ester or amide bonds. Plasma esterases, intestinal enzymes."],
]
p1t = Table(phase1_data, colWidths=[4*cm, 13*cm])
p1t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), TEAL),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),8),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(p1t)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("5.2 Phase II Reactions", section_heading))
story.append(Paragraph(
"<b>Phase II</b> reactions are conjugation reactions. They attach an endogenous molecule to the "
"drug or its Phase I metabolite. The resulting product is almost always pharmacologically inactive "
"and more water-soluble, facilitating excretion.",
body))
phase2_data = [
["Glucuronidation", "UDP-glucuronyltransferase. Most common Phase II reaction."],
["Sulfation", "Sulfotransferase. High affinity, low capacity."],
["Acetylation", "N-acetyltransferase. Genetic polymorphism: fast vs. slow acetylators."],
["Glutathione conjugation", "Protects against reactive metabolites (e.g., NAPQI from paracetamol)."],
["Methylation", "Catecholamines, histamine."],
]
p2t = Table(phase2_data, colWidths=[4.5*cm, 12.5*cm])
p2t.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,-1), LIGHT_TEAL),
("FONTNAME",(0,0),(0,-1),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(p2t)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("5.3 CYP450 Isoforms – Clinical Importance", section_heading))
cyp_data = [
[Paragraph("<b>Isoform</b>", callout_style), Paragraph("<b>Major Substrates</b>", callout_style),
Paragraph("<b>Inducers</b>", callout_style), Paragraph("<b>Inhibitors</b>", callout_style)],
["CYP3A4", "Cyclosporine, Midazolam, Simvastatin, Nifedipine, ~50% of all drugs",
"Rifampicin, Carbamazepine, St John's Wort", "Ketoconazole, Erythromycin, Grapefruit juice"],
["CYP2D6", "Codeine (→Morphine), Beta-blockers, SSRIs, TCAs",
"Rifampicin", "Fluoxetine, Paroxetine, Quinidine"],
["CYP2C9", "Warfarin (S-), Phenytoin, NSAIDs",
"Rifampicin", "Amiodarone, Fluconazole, Metronidazole"],
["CYP2C19", "Omeprazole, Clopidogrel (prodrug→active), Diazepam",
"Rifampicin", "Omeprazole, Fluoxetine"],
["CYP1A2", "Theophylline, Caffeine, Clozapine",
"Smoking, Char-grilled meat", "Ciprofloxacin, Fluvoxamine"],
]
cyp = Table(cyp_data, colWidths=[2.5*cm, 5*cm, 5*cm, 4.5*cm])
cyp.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(cyp)
story.append(Spacer(1, 0.3*cm))
story.append(callout_box("Induction vs. Inhibition",
["Enzyme induction: increases metabolism → decreased drug levels → therapeutic failure. Takes days to weeks.",
"Enzyme inhibition: decreases metabolism → increased drug levels → toxicity. Often immediate.",
"Example: Rifampicin (inducer) + OCP → contraceptive failure",
"Example: Ketoconazole (inhibitor) + Simvastatin → rhabdomyolysis risk",
"CYP2D6 and CYP2C19 have genetic polymorphisms: poor vs. extensive metabolizers"],
bg=RED_BOX, border=RED_BORDER, title_color=RED_BORDER))
story.append(Paragraph("5.4 Prodrugs", section_heading))
story.append(Paragraph(
"A <b>prodrug</b> is an inactive precursor that requires metabolic conversion to produce the active form. "
"They are used to improve bioavailability, stability, or targeting.",
body))
story.append(Paragraph(
"Examples: <b>Enalapril</b> → Enalaprilat (ACE inhibitor) | "
"<b>Codeine</b> → Morphine (via CYP2D6) | "
"<b>Clopidogrel</b> → Active thiol metabolite (via CYP2C19) | "
"<b>Levodopa</b> → Dopamine (crosses BBB)",
body))
# ═══════════════════════════════════════════════════════════════════
# SECTION 6 – ELIMINATION
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("6 Elimination & Renal Excretion"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"Elimination refers to the irreversible removal of drug from the body. "
"The <b>kidneys</b> are the primary organ of excretion, though drugs may also be excreted "
"in bile (→ feces), exhaled air, breast milk, sweat, and saliva.",
body))
story.append(Paragraph("6.1 Renal Excretion – Three Processes", section_heading))
ren_data = [
[Paragraph("<b>Process</b>", callout_style), Paragraph("<b>Mechanism</b>", callout_style),
Paragraph("<b>Clinical Relevance</b>", callout_style)],
["Glomerular filtration", "Passive. Only free (unbound) drug filtered. Molecular weight <20,000 Da.",
"Reduced in renal impairment → drug accumulation"],
["Tubular secretion", "Active transport (OAT, OCT transporters). Can excrete protein-bound drug.",
"Drug-drug interactions (e.g., Probenecid blocks penicillin secretion)"],
["Tubular reabsorption", "Passive. Lipophilic/un-ionized drugs reabsorbed back into blood.",
"Urinary pH manipulation: alkaline urine traps acidic drugs (aspirin OD treatment)"],
]
rent = Table(ren_data, colWidths=[4*cm, 7*cm, 6*cm])
rent.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(rent)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("6.2 Biliary Excretion & Enterohepatic Circulation", section_heading))
story.append(Paragraph(
"Drugs conjugated in the liver (especially glucuronides) are excreted into bile and enter the intestine. "
"Gut bacteria can hydrolyze the conjugate, releasing the free drug, which is reabsorbed – "
"this is <b>enterohepatic circulation</b>. It prolongs the drug's half-life. "
"Examples: Oral contraceptives, Morphine, Chloramphenicol.",
body))
story.append(Paragraph("6.3 Clearance (CL)", section_heading))
story.append(Paragraph(
"<b>Clearance</b> is the volume of plasma cleared of drug per unit time (mL/min or L/h). "
"It is the most important PK parameter for determining drug dosing.",
body))
story.append(formula_box(
"CL = Rate of elimination / Plasma drug concentration = Dose / AUC",
"Drug Clearance"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Total clearance = Renal CL + Hepatic CL + other CL. "
"CL is <b>independent of dose</b> for first-order drugs.",
body))
# ═══════════════════════════════════════════════════════════════════
# SECTION 7 – KEY PK PARAMETERS
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("7 Key Pharmacokinetic Parameters"))
story.append(Spacer(1, 0.3*cm))
param_data = [
[Paragraph("<b>Parameter</b>", callout_style), Paragraph("<b>Symbol</b>", callout_style),
Paragraph("<b>Formula</b>", callout_style), Paragraph("<b>Clinical Meaning</b>", callout_style)],
["Bioavailability", "F", "AUCoral / AUCIV", "Fraction reaching systemic circulation"],
["Volume of Distribution", "Vd", "Dose / C₀", "Drug distribution in body (L or L/kg)"],
["Clearance", "CL", "Dose / AUC", "Plasma volume cleared per unit time"],
["Half-life (elimination)", "t½", "0.693 × Vd / CL", "Time for plasma conc. to fall by 50%"],
["Elimination rate constant", "ke", "CL / Vd = 0.693 / t½", "Fraction eliminated per unit time"],
["AUC", "AUC", "∫₀^∞ Cp·dt", "Total drug exposure; proportional to dose (linear PK)"],
["Cmax", "Cmax", "—", "Peak plasma concentration after dose"],
["Tmax", "Tmax", "—", "Time to reach peak plasma concentration"],
["Steady-state concentration", "Css", "Dosing rate / CL", "Avg. plasma conc. at steady state"],
["Loading dose", "LD", "Vd × Css / F", "Rapid attainment of therapeutic level"],
["Maintenance dose", "MD", "CL × Css × τ / F", "Dose to maintain steady state (τ = interval)"],
]
pd = Table(param_data, colWidths=[4*cm, 2*cm, 4.5*cm, 6.5*cm])
pd.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(pd)
# ═══════════════════════════════════════════════════════════════════
# SECTION 8 – HALF-LIFE & STEADY STATE
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("8 Half-Life & Steady State"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("8.1 Elimination Half-Life (t½)", section_heading))
story.append(Paragraph(
"The elimination half-life is the time required for the plasma concentration of a drug to "
"decrease by 50%. For first-order kinetics, t½ is constant regardless of dose.",
body))
story.append(formula_box("t½ = 0.693 × Vd / CL",
"Half-life is determined by BOTH volume of distribution AND clearance"))
story.append(Spacer(1, 0.3*cm))
hl_data = [
["Half-lives elapsed", "1", "2", "3", "4", "5"],
["Drug remaining (%)", "50", "25", "12.5", "6.25", "3.13"],
["Drug eliminated (%)", "50", "75", "87.5", "93.75", "96.87"],
["Steady state achieved (%)", "50", "75", "87.5", "93.75", "96.87"],
]
hlt = Table(hl_data, colWidths=[5*cm]+[2.4*cm]*5)
hlt.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,-1), NAVY),
("TEXTCOLOR",(0,0),(0,-1), WHITE),
("BACKGROUND",(0,0),(-1,0), TEAL),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTNAME",(0,0),(0,-1),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9.5),
("ALIGN",(1,0),(-1,-1),"CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY, WHITE]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),6),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(hlt)
story.append(Spacer(1, 0.2*cm))
story.append(callout_box("Clinical Rules",
["Steady state (Css) is reached in approximately 4-5 half-lives",
"50% of steady state is achieved after 1 half-life",
"~90% of steady state is reached in 3.3 half-lives",
"A drug is considered essentially eliminated after 5 half-lives",
"Changing dose frequency does NOT change the rate of reaching steady state – only t½ determines this",
"To reach steady state faster → give a loading dose"],
bg=GREEN_BOX, border=GREEN_BORDER, title_color=GREEN_BORDER))
story.append(Paragraph("8.2 Order of Elimination Kinetics", section_heading))
story.append(Paragraph(
"<b>First-order kinetics:</b> A constant <i>fraction</i> of drug is eliminated per unit time. "
"Plasma concentration falls exponentially. t½ is constant. Applies to most drugs at therapeutic concentrations.",
body))
story.append(Paragraph(
"<b>Zero-order kinetics:</b> A constant <i>amount</i> of drug is eliminated per unit time "
"(enzyme saturation). t½ is not constant – increases with dose. "
"Classic examples: Ethanol (~10 mL/hr), Phenytoin at high doses, Aspirin in overdose.",
body))
story.append(callout_box("Zero-order danger",
["When enzyme systems are saturated, a small increase in dose → disproportionately large rise in plasma levels",
"Phenytoin toxicity: narrow therapeutic index + zero-order kinetics = high risk",
"Ethanol: regardless of how much you drink, the liver can only metabolize ~1 unit/hour"],
bg=RED_BOX, border=RED_BORDER, title_color=RED_BORDER))
# ═══════════════════════════════════════════════════════════════════
# SECTION 9 – DOSAGE REGIMENS
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("9 Dosage Regimens"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("9.1 Steady State and Continuous Infusion", section_heading))
story.append(Paragraph(
"When a drug is administered at a constant rate (IV infusion), plasma levels rise until the rate of "
"input equals the rate of elimination – this is <b>steady state (Css)</b>. "
"The time to reach Css depends only on t½, not on the infusion rate.",
body))
story.append(formula_box("Css = Infusion rate / CL", "Steady-State Concentration (continuous IV infusion)"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("9.2 Loading Dose", section_heading))
story.append(Paragraph(
"A <b>loading dose</b> rapidly achieves the desired therapeutic plasma concentration before the "
"drug reaches steady state. It is particularly useful for drugs with long half-lives "
"(e.g., Digoxin, Amiodarone, Phenytoin).",
body))
story.append(formula_box(
"Loading Dose = Vd × Css / F",
"Loading Dose Calculation"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("9.3 Maintenance Dose", section_heading))
story.append(Paragraph(
"The <b>maintenance dose</b> is designed to maintain the steady-state concentration over time "
"by replacing drug that has been eliminated during the dosing interval (τ).",
body))
story.append(formula_box(
"Maintenance Dose = CL × Css × τ / F",
"Maintenance Dose Calculation (τ = dosing interval)"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("9.4 Therapeutic Drug Monitoring (TDM)", section_heading))
story.append(Paragraph(
"TDM is used for drugs with a <b>narrow therapeutic index</b> where small concentration changes "
"can cause toxicity or therapeutic failure.",
body))
tdm_data = [
[Paragraph("<b>Drug</b>", callout_style), Paragraph("<b>Therapeutic Range</b>", callout_style),
Paragraph("<b>Toxicity Concern</b>", callout_style)],
["Digoxin", "0.5–2 ng/mL", "Arrhythmias, AV block"],
["Phenytoin", "10–20 mg/L", "Nystagmus, ataxia, encephalopathy"],
["Lithium", "0.6–1.2 mmol/L", "Tremor, nephrogenic DI, cardiac effects"],
["Gentamicin", "Peak 5–10 mg/L; Trough <2 mg/L", "Nephrotoxicity, ototoxicity"],
["Vancomycin", "Trough 10–20 mg/L (AUC/MIC guided)", "Nephrotoxicity, 'red man syndrome'"],
["Theophylline", "10–20 mg/L", "Arrhythmias, seizures"],
["Cyclosporine", "100–400 ng/mL (varies)", "Nephrotoxicity, hypertension"],
["Methotrexate", ">0.1 µmol/L at 48h is toxic", "Myelosuppression, mucositis"],
]
tdm = Table(tdm_data, colWidths=[4*cm, 5.5*cm, 7.5*cm])
tdm.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),9),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),5),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(tdm)
# ═══════════════════════════════════════════════════════════════════
# SECTION 10 – SPECIAL POPULATIONS
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("10 Special Populations"))
story.append(Spacer(1, 0.3*cm))
sp_data = [
[Paragraph("<b>Population</b>", callout_style), Paragraph("<b>PK Changes</b>", callout_style),
Paragraph("<b>Clinical Action</b>", callout_style)],
["Renal Impairment",
"↓ GFR → ↓ renal clearance → drug accumulation. Digoxin, aminoglycosides, lithium, metformin affected.",
"Reduce dose or extend interval. Monitor drug levels. Avoid nephrotoxic drugs."],
["Hepatic Impairment",
"↓ CYP450 activity → ↓ metabolism. ↓ albumin → ↑ free drug fraction. ↑ first-pass bypass via portosystemic shunts.",
"Reduce doses of high-extraction drugs (morphine, midazolam). Avoid hepatotoxic drugs."],
["Elderly",
"↓ GFR (normal aging). ↓ hepatic CYP activity. ↓ plasma albumin. ↑ body fat → ↑ Vd for lipophilic drugs. ↓ gastric acid.",
"Start low, go slow. Adjust for renal function (Cockcroft-Gault). Beware polypharmacy."],
["Pediatrics",
"Neonates: immature CYP450, immature renal function. Higher total body water → larger Vd for hydrophilic drugs.",
"Weight-based dosing. Avoid chloramphenicol (grey baby syndrome), sulfonamides, aspirin (Reye syndrome)."],
["Pregnancy",
"↑ GFR → ↑ renal clearance. ↑ plasma volume → dilution. ↑ CYP3A4 activity. ↓ albumin. Placental transfer concerns.",
"Many drugs cross placenta – check pregnancy category. Folate supplementation important."],
["Obesity",
"↑ Vd for lipophilic drugs. Variable changes in clearance. Loading dose may need adjustment.",
"Use actual vs. ideal body weight carefully depending on drug lipophilicity."],
]
spt = Table(sp_data, colWidths=[3.5*cm, 7*cm, 6.5*cm])
spt.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0), NAVY),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("GRID",(0,0),(-1,-1),0.4,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),5),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(spt)
# ═══════════════════════════════════════════════════════════════════
# SECTION 11 – FORMULA REFERENCE
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("11 Quick-Reference Formula Sheet"))
story.append(Spacer(1, 0.3*cm))
formulas = [
("Bioavailability", "F = AUC(oral) / AUC(IV) × 100%"),
("Volume of Distribution", "Vd = Dose / C₀"),
("Clearance", "CL = Dose / AUC = Rate of elimination / Cp"),
("Half-life", "t½ = 0.693 × Vd / CL"),
("Elimination rate constant", "ke = 0.693 / t½ = CL / Vd"),
("Steady-state (infusion)", "Css = Infusion rate / CL"),
("Steady-state (oral)", "Css(avg) = F × Dose / (CL × τ)"),
("Loading dose", "LD = Vd × Css / F"),
("Maintenance dose", "MD = CL × Css × τ / F"),
("Cockcroft-Gault (CrCl)", "CrCl = [(140−Age) × Weight(kg)] / [72 × Scr] × 0.85 (female)"),
]
for name, formula in formulas:
row = Table([[
Paragraph(name, ParagraphStyle("FName", fontSize=9.5, fontName="Helvetica-Bold",
textColor=NAVY, alignment=TA_LEFT)),
Paragraph(formula, ParagraphStyle("FFormula", fontSize=11, fontName="Helvetica-Bold",
textColor=TEAL, alignment=TA_CENTER)),
]], colWidths=[5*cm, 12*cm])
row.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), LIGHT_TEAL),
("LINEBELOW",(0,0),(-1,-1),0.5,TEAL),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),8),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(row)
story.append(Spacer(1, 0.1*cm))
# ═══════════════════════════════════════════════════════════════════
# SECTION 12 – MCQ QUIZ
# ═══════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_divider("12 MCQ-Style Revision Quiz"))
story.append(Spacer(1, 0.3*cm))
mcq_questions = [
("1", "A drug has a Vd of 42 L in a 70 kg patient. This suggests:",
["A. The drug is confined to plasma", "B. The drug distributes into total body water",
"C. The drug is highly protein-bound", "D. The drug cannot cross cell membranes"], "B"),
("2", "Nitroglycerin is given sublingually rather than orally because:",
["A. It is not absorbed orally", "B. It has extensive first-pass hepatic metabolism",
"C. It is too lipophilic for GI absorption", "D. It requires a sustained-release mechanism"], "B"),
("3", "A drug follows zero-order kinetics. Which of the following is TRUE?",
["A. Half-life is constant", "B. A constant fraction is eliminated per unit time",
"C. A constant amount is eliminated per unit time", "D. AUC is proportional to dose"], "C"),
("4", "CYP2D6 poor metabolizers given codeine will:",
["A. Have enhanced morphine production and analgesia", "B. Have reduced morphine production and reduced analgesia",
"C. Metabolize codeine faster", "D. Experience delayed onset but same peak effect"], "B"),
("5", "Which parameter is used to calculate the loading dose?",
["A. Clearance × half-life", "B. Vd × target Css / F",
"C. AUC × bioavailability", "D. CL × dosing interval"], "B"),
("6", "A drug with a t½ of 8 hours is given by constant IV infusion. When is steady state reached?",
["A. 8 hours", "B. 16 hours", "C. 32–40 hours (4–5 × t½)", "D. 24 hours"], "C"),
("7", "Rifampicin is co-prescribed with warfarin. The most likely outcome is:",
["A. Warfarin levels increase → bleeding risk", "B. Warfarin levels decrease → thrombotic risk",
"C. No interaction", "D. Warfarin becomes toxic"], "B"),
("8", "In alkaline urine, the clearance of aspirin (a weak acid) is:",
["A. Decreased – more reabsorbed", "B. Increased – more ionized and trapped in urine",
"C. Unchanged", "D. Dependent on plasma protein binding"], "B"),
]
for q_num, question, options, answer in mcq_questions:
q_block = [
Paragraph(f"<b>Q{q_num}.</b> {question}", ParagraphStyle("Qtext",
fontSize=10, fontName="Helvetica-Bold", textColor=NAVY,
spaceAfter=4, spaceBefore=8, leading=14)),
]
for opt in options:
q_block.append(Paragraph(f" {opt}", ParagraphStyle("Opt",
fontSize=9.5, fontName="Helvetica", leading=13, spaceAfter=2)))
q_block.append(Paragraph(
f"<font color='#27ae60'><b>Answer: {answer}</b></font>",
ParagraphStyle("Ans", fontSize=9.5, fontName="Helvetica-Bold",
leading=13, spaceBefore=4, spaceAfter=4)))
qbox = Table([[q_block]], colWidths=[17*cm])
qbox.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), LIGHT_GRAY),
("BOX",(0,0),(-1,-1),0.5,MED_GRAY),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
]))
story.append(qbox)
story.append(Spacer(1, 0.2*cm))
# ── Final footer page ──
story.append(PageBreak())
footer_table = Table(
[[Paragraph("Pharmacokinetics Study Guide", ParagraphStyle("FTTitle",
fontSize=16, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, spaceAfter=8)),
Paragraph("Sources: Lippincott Illustrated Reviews: Pharmacology · Goodman & Gilman's "
"The Pharmacological Basis of Therapeutics · Katzung's Basic & Clinical Pharmacology · "
"Harrison's Principles of Internal Medicine",
ParagraphStyle("FTSrc", fontSize=9, fontName="Helvetica", textColor=colors.HexColor("#c8e0f0"),
alignment=TA_CENTER, leading=13)),
]],
colWidths=[17*cm],
)
footer_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), NAVY),
("TOPPADDING",(0,0),(-1,-1),40),
("BOTTOMPADDING",(0,0),(-1,-1),40),
("LEFTPADDING",(0,0),(-1,-1),20),
("RIGHTPADDING",(0,0),(-1,-1),20),
]))
story.append(footer_table)
doc.build(story)
print(f"PDF created: {OUTPUT_PATH}")
cd /home/daytona/workspace/pharmacokinetics-guide && python generate_pk_guide.py
ls -lh /home/daytona/workspace/pharmacokinetics-guide/Pharmacokinetics_Study_Gui…
Pharmacokinetics Study Guide
PDF Document · PDF
| Section | Content |
|---|---|
| 1 - Overview | What PK is, ADME framework, clinical relevance |
| 2 - Absorption | All routes of administration (table), absorption mechanisms, Henderson-Hasselbalch principle |
| 3 - Bioavailability | F formula, first-pass metabolism, drugs with high first-pass, factors affecting bioavailability |
| 4 - Distribution | Volume of distribution (Vd) table with body compartments, plasma protein binding, blood-brain barrier |
| 5 - Metabolism | Phase I & II reactions, CYP450 isoforms table (substrates, inducers, inhibitors), prodrugs |
| 6 - Elimination | Renal excretion (filtration, secretion, reabsorption), enterohepatic circulation, clearance |
| 7 - Key Parameters | All 11 major PK parameters with symbols and formulas |
| 8 - Half-life & Steady State | t½ table (drug remaining vs. half-lives), first vs. zero-order kinetics, clinical rules |
| 9 - Dosage Regimens | Loading dose, maintenance dose, Css, TDM drugs with therapeutic ranges |
| 10 - Special Populations | Renal/hepatic impairment, elderly, pediatrics, pregnancy, obesity |
| 11 - Formula Sheet | All key formulas in one quick-reference page |
| 12 - MCQ Quiz | 8 exam-style questions with answers covering all major concepts |