Give me the notes about the general pharmacology


| Mechanism | Description |
|---|---|
| Passive diffusion | Down concentration gradient; most common; lipid-soluble drugs |
| Facilitated diffusion | Carrier-mediated, no energy required |
| Active transport | Carrier-mediated, energy required, can work against gradient |
| Endocytosis | For large molecules (e.g., vitamin B12) |


| Isoform | Key substrates | Inducers | Inhibitors |
|---|---|---|---|
| CYP3A4/5 | Cyclosporine, midazolam, statins | Rifampin, carbamazepine | Ketoconazole, erythromycin |
| CYP2D6 | Codeine, beta-blockers, antidepressants | None significant | Fluoxetine, quinidine |
| CYP2C9 | Warfarin, phenytoin, NSAIDs | Rifampin | Fluconazole |
| CYP1A2 | Theophylline, caffeine, clozapine | Smoking, rifampin | Ciprofloxacin |


| Receptor Type | Mechanism | Onset | Example Drugs |
|---|---|---|---|
| Ligand-gated ion channels (ionotropic) | Opens ion channel directly | Milliseconds | Benzodiazepines (GABA-A), nicotine |
| G-protein coupled receptors (GPCRs) | Activates G-protein → second messengers (cAMP, IP3) | Seconds | Beta-blockers, opioids, muscarinic drugs |
| Enzyme-linked receptors (tyrosine kinase) | Autophosphorylation → intracellular signaling | Minutes | Insulin, growth factors |
| Intracellular/nuclear receptors | Alter gene transcription | Hours/days | Corticosteroids, thyroid hormone |
| Type | Description | Example |
|---|---|---|
| Synergism | Combined effect > sum of individual effects | Alcohol + benzodiazepines |
| Additive | Combined effect = sum of individual effects | Two NSAIDs |
| Antagonism | One drug reduces effect of another | Naloxone + opioids |
| Pharmacokinetic | One drug alters ADME of another | Rifampin induces CYP3A4, reducing oral contraceptive levels |
| Parameter | Formula | Clinical Use |
|---|---|---|
| Bioavailability (F) | F = AUC(oral)/AUC(IV) × 100% | Determines dosing ratio IV to oral |
| Volume of Distribution | Vd = Amount in body / Plasma concentration | Estimate loading dose |
| Half-life | t½ = 0.693 × Vd / CL | Time to steady state, dosing interval |
| Clearance | CL = 0.693 × Vd / t½ | Rate of drug removal |
| Loading dose | Vd × C(target) / F | Rapid achievement of steady state |
| Maintenance dose | C(ss) × CL × interval / F | Long-term dosing |
Make a PDF summary of pharmacokinetics vs pharmacodynamics
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not foun…
mkdir -p /home/daytona/workspace/pharmacology-pdf
~/pharmacology-pdf/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
OUTPUT = "/home/daytona/workspace/pharmacology-pdf/PK_vs_PD_Summary.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
PK_COLOR = colors.HexColor("#1A6FA8") # deep blue – pharmacokinetics
PD_COLOR = colors.HexColor("#C0392B") # deep red – pharmacodynamics
ACCENT = colors.HexColor("#2ECC71") # green – highlights
LIGHT_PK = colors.HexColor("#D6EAF8") # light blue
LIGHT_PD = colors.HexColor("#FADBD8") # light red
HEADER_BG = colors.HexColor("#1A252F") # near-black
WHITE = colors.white
GRAY_LIGHT = colors.HexColor("#F2F3F4")
GRAY_MID = colors.HexColor("#BDC3C7")
TEXT_DARK = colors.HexColor("#1C2833")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm,
title="Pharmacokinetics vs Pharmacodynamics",
author="Orris Medical AI"
)
styles = getSampleStyleSheet()
# ── Custom styles ────────────────────────────────────────────────────────────
def style(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = style("CoverTitle",
fontSize=28, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER, leading=34, spaceAfter=6)
cover_sub = style("CoverSub",
fontSize=14, fontName="Helvetica",
textColor=colors.HexColor("#AEB6BF"), alignment=TA_CENTER, leading=20, spaceAfter=4)
cover_note = style("CoverNote",
fontSize=9, fontName="Helvetica-Oblique",
textColor=colors.HexColor("#717D7E"), alignment=TA_CENTER)
section_hdr = style("SectionHdr",
fontSize=15, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_LEFT, leading=20,
spaceAfter=2, spaceBefore=14)
sub_hdr = style("SubHdr",
fontSize=11, fontName="Helvetica-Bold",
textColor=TEXT_DARK, leading=15, spaceBefore=8, spaceAfter=3)
body = style("Body",
fontSize=9.5, fontName="Helvetica",
textColor=TEXT_DARK, leading=14, spaceAfter=3, alignment=TA_JUSTIFY)
bullet = style("Bullet",
fontSize=9.5, fontName="Helvetica",
textColor=TEXT_DARK, leading=13, leftIndent=12,
bulletIndent=0, spaceAfter=2, alignment=TA_LEFT)
formula = style("Formula",
fontSize=9.5, fontName="Courier-Bold",
textColor=colors.HexColor("#1A5276"),
backColor=colors.HexColor("#EAF2FF"),
leading=14, leftIndent=10, spaceAfter=4, alignment=TA_LEFT)
caption = style("Caption",
fontSize=8, fontName="Helvetica-Oblique",
textColor=colors.HexColor("#717D7E"), alignment=TA_CENTER, spaceAfter=6)
story = []
# ════════════════════════════════════════════════════════════════════════════
# COVER BLOCK
# ════════════════════════════════════════════════════════════════════════════
cover_data = [[
Paragraph("Pharmacokinetics vs Pharmacodynamics", cover_title)
]]
cover_tbl = Table(cover_data, colWidths=[17.4*cm])
cover_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), HEADER_BG),
("ROUNDEDCORNERS", [8]),
("TOPPADDING", (0,0), (-1,-1), 30),
("BOTTOMPADDING", (0,0), (-1,-1), 30),
("LEFTPADDING", (0,0), (-1,-1), 20),
("RIGHTPADDING", (0,0), (-1,-1), 20),
]))
story.append(cover_tbl)
story.append(Spacer(1, 6*mm))
story.append(Paragraph("A side-by-side clinical summary", cover_sub))
story.append(Paragraph("Source: Lippincott Illustrated Reviews Pharmacology · Katzung 16th Ed. · Goodman & Gilman", cover_note))
story.append(Spacer(1, 10*mm))
# ════════════════════════════════════════════════════════════════════════════
# QUICK DEFINITION BOX
# ════════════════════════════════════════════════════════════════════════════
def section_banner(text, bg_color):
data = [[Paragraph(text, section_hdr)]]
t = Table(data, colWidths=[17.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("ROUNDEDCORNERS", [6]),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 12),
]))
return t
def two_col_banner(left_text, right_text, left_bg, right_bg):
data = [[
Paragraph(left_text, style("lh", fontSize=13, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=18)),
Paragraph(right_text, style("rh", fontSize=13, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER, leading=18)),
]]
t = Table(data, colWidths=[8.5*cm, 8.5*cm], hAlign="CENTER")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), left_bg),
("BACKGROUND", (1,0), (1,0), right_bg),
("ROUNDEDCORNERS", [6]),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
]))
return t
# ── At-a-glance comparison table ─────────────────────────────────────────────
story.append(section_banner("At a Glance", HEADER_BG))
story.append(Spacer(1, 3*mm))
glance_header = [
Paragraph("Feature", style("th", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("PHARMACOKINETICS (PK)", style("th", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("PHARMACODYNAMICS (PD)", style("th", fontSize=10, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
]
glance_rows = [
["Definition", "What the body does to the drug", "What the drug does to the body"],
["Mnemonic", "Absorption · Distribution · Metabolism · Elimination (ADME)", "Drug–receptor interaction → effect"],
["Key question", "How much drug reaches the target?", "How does the drug produce its effect?"],
["Parameters", "Bioavailability, Vd, CL, t½", "Efficacy, potency, EC50, TI, Emax"],
["Main organ", "Liver (metabolism), Kidney (excretion)", "Target tissue / receptor"],
["Time scale", "Minutes to hours (absorption/elimination)", "Milliseconds (ion channels) to days (nuclear receptors)"],
["Clinical use", "Dose calculation, dosing interval, drug interactions", "Drug selection, safety margin, tolerance"],
]
glance_data = [glance_header]
for row in glance_rows:
glance_data.append([
Paragraph(row[0], style("gc", fontSize=9, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=13)),
Paragraph(row[1], style("gc2", fontSize=9, fontName="Helvetica", textColor=TEXT_DARK, leading=13)),
Paragraph(row[2], style("gc3", fontSize=9, fontName="Helvetica", textColor=TEXT_DARK, leading=13)),
])
glance_tbl = Table(glance_data, colWidths=[3.5*cm, 7*cm, 7*cm])
glance_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), HEADER_BG),
("BACKGROUND", (0,1), (0,-1), GRAY_LIGHT),
("ROWBACKGROUNDS",(1,1), (-1,-1), [WHITE, GRAY_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("LINEABOVE", (0,1), (-1,1), 1, PK_COLOR),
]))
story.append(glance_tbl)
story.append(Spacer(1, 8*mm))
# ════════════════════════════════════════════════════════════════════════════
# PHARMACOKINETICS SECTION
# ════════════════════════════════════════════════════════════════════════════
story.append(section_banner("PHARMACOKINETICS — What the Body Does to the Drug", PK_COLOR))
story.append(Spacer(1, 3*mm))
# ADME overview two-col layout
adme_left = [
[Paragraph("A – ABSORPTION", style("al", fontSize=10, fontName="Helvetica-Bold", textColor=PK_COLOR, leading=14, spaceBefore=0, spaceAfter=2))],
[Paragraph("• Entry of drug into the plasma from the site of administration<br/>• Routes: oral, sublingual, IV, IM, SC, inhalation, transdermal<br/>• Oral = most convenient; subject to first-pass metabolism<br/>• IV = 100% bioavailability (reference standard)<br/>• Sublingual/transdermal = bypass first-pass effect", bullet)],
[Spacer(1, 3*mm)],
[Paragraph("D – DISTRIBUTION", style("al2", fontSize=10, fontName="Helvetica-Bold", textColor=PK_COLOR, leading=14, spaceBefore=0, spaceAfter=2))],
[Paragraph("• Drug leaves bloodstream and enters tissues<br/>• Affected by: blood flow, plasma protein binding, lipophilicity, capillary permeability<br/>• Only <b>free (unbound)</b> drug is pharmacologically active<br/>• Blood–brain barrier requires lipophilic drugs or active transport", bullet)],
]
adme_right = [
[Paragraph("M – METABOLISM", style("ar", fontSize=10, fontName="Helvetica-Bold", textColor=PK_COLOR, leading=14, spaceBefore=0, spaceAfter=2))],
[Paragraph("• Primarily in the liver (also gut wall, lung, plasma)<br/>• <b>Phase I</b>: Oxidation/reduction/hydrolysis via CYP450 enzymes<br/>• <b>Phase II</b>: Conjugation (glucuronidation, sulfation) → inactive, polar products<br/>• CYP3A4 metabolises ~50% of all drugs<br/>• Prodrugs require metabolism for activation (e.g. codeine → morphine)", bullet)],
[Spacer(1, 3*mm)],
[Paragraph("E – ELIMINATION", style("ar2", fontSize=10, fontName="Helvetica-Bold", textColor=PK_COLOR, leading=14, spaceBefore=0, spaceAfter=2))],
[Paragraph("• Mainly renal: filtration, secretion, reabsorption<br/>• Also biliary, pulmonary, breast milk<br/>• <b>Ion trapping</b>: alkaline urine traps acid drugs (e.g. aspirin overdose → give NaHCO₃)<br/>• Steady state reached after <b>4–5 half-lives</b>", bullet)],
]
def mini_table(rows, bg):
t = Table(rows, colWidths=[8.1*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 0.5, PK_COLOR),
("ROUNDEDCORNERS", [4]),
]))
return t
adme_tbl = Table(
[[mini_table(adme_left, LIGHT_PK), mini_table(adme_right, LIGHT_PK)]],
colWidths=[8.5*cm, 8.5*cm]
)
adme_tbl.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 2),
("RIGHTPADDING",(0,0), (-1,-1), 2),
]))
story.append(adme_tbl)
story.append(Spacer(1, 5*mm))
# ── Key PK Parameters ─────────────────────────────────────────────────────
story.append(Paragraph("Key PK Parameters & Formulas", sub_hdr))
pk_params = [
[
Paragraph("Parameter", style("ph", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Definition", style("ph", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Formula", style("ph", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Clinical Significance", style("ph", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
],
["Bioavailability (F)", "Fraction of dose reaching systemic circulation", "F = AUC(oral) / AUC(IV)", "Determines oral vs IV dose ratio"],
["Volume of Distrib. (Vd)", "Apparent volume drug distributes into", "Vd = Dose / C₀", "Calculate loading dose; large Vd = tissue sequestration"],
["Half-life (t½)", "Time for plasma conc. to fall 50%", "t½ = 0.693 × Vd / CL", "Dosing interval; time to steady state (×4–5)"],
["Clearance (CL)", "Volume of plasma cleared per unit time", "CL = 0.693 × Vd / t½", "Determines maintenance dose"],
["Loading Dose", "Initial large dose for rapid Css", "LD = Vd × C(target) / F", "Fast onset for drugs with long t½"],
["Maintenance Dose", "Dose to maintain steady-state", "MD = Css × CL × interval / F", "Long-term dosing optimisation"],
]
pk_s = style("pks", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
pk_s_bold = style("pkb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
pk_code = style("pkc", fontSize=8.5, fontName="Courier-Bold", textColor=colors.HexColor("#1A5276"), leading=12)
pk_data = [pk_params[0]]
for row in pk_params[1:]:
pk_data.append([
Paragraph(row[0], pk_s_bold),
Paragraph(row[1], pk_s),
Paragraph(row[2], pk_code),
Paragraph(row[3], pk_s),
])
pk_tbl = Table(pk_data, colWidths=[3.5*cm, 4*cm, 4*cm, 5.4*cm])
pk_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PK_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PK]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(pk_tbl)
story.append(Spacer(1, 5*mm))
# ── CYP450 table ──────────────────────────────────────────────────────────
story.append(Paragraph("CYP450 Isoforms — Clinical Drug Interactions", sub_hdr))
cyp_header = [
Paragraph(x, style("cy", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))
for x in ["Isoform", "Major Substrates", "Inducers (↑ metabolism)", "Inhibitors (↓ metabolism)"]
]
cyp_rows = [
["CYP3A4/5 (~50%)", "Cyclosporine, midazolam, statins, calcium channel blockers", "Rifampin, carbamazepine, phenytoin, St. John's Wort", "Ketoconazole, erythromycin, clarithromycin, grapefruit"],
["CYP2D6", "Codeine, tramadol, beta-blockers, SSRIs, TCAs", "None clinically significant", "Fluoxetine, paroxetine, quinidine, bupropion"],
["CYP2C9", "Warfarin, phenytoin, NSAIDs, sulfonylureas", "Rifampin, carbamazepine", "Fluconazole, amiodarone, metronidazole"],
["CYP1A2", "Theophylline, caffeine, clozapine, haloperidol", "Cigarette smoke, rifampin, omeprazole", "Ciprofloxacin, fluvoxamine, cimetidine"],
["CYP2C19", "Clopidogrel (prodrug), omeprazole, diazepam", "Rifampin, carbamazepine", "Omeprazole, fluoxetine, fluvoxamine"],
]
cyp_s = style("cs", fontSize=8, fontName="Helvetica", textColor=TEXT_DARK, leading=11)
cyp_sb = style("csb", fontSize=8, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=11)
cyp_data = [cyp_header]
for row in cyp_rows:
cyp_data.append([Paragraph(row[i], cyp_sb if i == 0 else cyp_s) for i in range(4)])
cyp_tbl = Table(cyp_data, colWidths=[2.5*cm, 5*cm, 5*cm, 4.4*cm])
cyp_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PK_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PK]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(cyp_tbl)
story.append(Spacer(1, 8*mm))
# ════════════════════════════════════════════════════════════════════════════
# PHARMACODYNAMICS SECTION
# ════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_banner("PHARMACODYNAMICS — What the Drug Does to the Body", PD_COLOR))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Pharmacodynamics studies how drugs produce their effects through interactions with receptors, enzymes, ion channels, or transport proteins.",
body))
story.append(Spacer(1, 2*mm))
# Drug types
story.append(Paragraph("Drug Types by Receptor Action", sub_hdr))
drug_types = [
["AGONIST", "Binds & activates receptor", "Mimics endogenous ligand at full effect", "Salbutamol (β2), morphine (μ-opioid)"],
["PARTIAL AGONIST", "Binds & activates — but submaximal Emax", "Acts as agonist in absence, antagonist in presence of full agonist", "Buprenorphine, buspirone"],
["ANTAGONIST", "Binds receptor — NO activation", "Blocks endogenous ligand or agonist", "Propranolol (β1/β2), naloxone (μ-opioid)"],
["INVERSE AGONIST", "Binds receptor — opposite effect to agonist", "Reduces baseline (constitutive) receptor activity", "Some antihistamines (H1)"],
]
dt_header = [
Paragraph(x, style("dth", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))
for x in ["Drug Type", "Mechanism", "Key Feature", "Example"]
]
dt_data = [dt_header]
dt_s = style("dts", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
dt_sb = style("dtsb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
for row in drug_types:
dt_data.append([Paragraph(row[i], dt_sb if i == 0 else dt_s) for i in range(4)])
dt_tbl = Table(dt_data, colWidths=[3.2*cm, 4.5*cm, 5*cm, 4*cm])
dt_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PD_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PD]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(dt_tbl)
story.append(Spacer(1, 5*mm))
# Receptor types
story.append(Paragraph("Types of Drug Receptors", sub_hdr))
rec_types = [
["Ligand-gated ion\nchannels (ionotropic)", "Milliseconds", "Direct ion channel opening", "GABA-A (benzodiazepines, barbiturates), nAChR (nicotine)"],
["G-protein coupled\nreceptors (GPCRs)", "Seconds", "→ cAMP, IP3/DAG, Ca²⁺ cascade", "β-blockers, opioids, muscarinic agents, α-adrenergic"],
["Enzyme-linked\n(receptor tyrosine kinase)", "Minutes", "Autophosphorylation → intracellular cascade", "Insulin, growth factors (EGF, IGF-1)"],
["Intracellular /\nnuclear receptors", "Hours–days", "Alter gene transcription", "Corticosteroids, thyroid hormone, vitamin D, sex steroids"],
]
rh = [
Paragraph(x, style("rth", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))
for x in ["Receptor Class", "Onset", "Mechanism", "Drug Examples"]
]
r_data = [rh]
r_s = style("rs", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
r_sb = style("rsb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
for row in rec_types:
r_data.append([Paragraph(row[i], r_sb if i == 0 else r_s) for i in range(4)])
r_tbl = Table(r_data, colWidths=[3.6*cm, 2*cm, 5*cm, 5.4*cm])
r_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PD_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PD]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(r_tbl)
story.append(Spacer(1, 5*mm))
# ── Key PD Parameters ─────────────────────────────────────────────────────
story.append(Paragraph("Key PD Parameters", sub_hdr))
pd_params_data = [
[
Paragraph("Parameter", style("pdh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Definition", style("pdh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Clinical Importance", style("pdh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
],
["Efficacy (Emax)", "Maximum response a drug can produce regardless of dose (intrinsic activity)", "Determines whether a drug can produce full therapeutic effect"],
["Potency (EC50)", "Concentration producing 50% of maximum effect — lower EC50 = more potent", "More potent drug needs smaller dose; potency ≠ clinical superiority"],
["Therapeutic Index (TI)", "TI = TD50 / ED50 (or LD50 / ED50) — ratio of toxic to effective dose", "Narrow TI drugs (digoxin, lithium, warfarin) require therapeutic drug monitoring"],
["Competitive Antagonism", "Blocks receptor reversibly; can be overcome by ↑ agonist conc; shifts D-R curve RIGHT, Emax unchanged", "Dose adjustment may overcome effect; e.g. atropine vs. ACh"],
["Non-competitive Antagonism", "Irreversible block; cannot be overcome; ↓ Emax, curve shifts DOWN", "Requires new receptor synthesis to recover; e.g. phenoxybenzamine"],
]
pd_s = style("pds", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
pd_sb = style("pdsb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
pd_pdata = [pd_params_data[0]]
for row in pd_params_data[1:]:
pd_pdata.append([Paragraph(row[i], pd_sb if i == 0 else pd_s) for i in range(3)])
pd_tbl = Table(pd_pdata, colWidths=[3.8*cm, 7*cm, 5.5*cm])
pd_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PD_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PD]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(pd_tbl)
story.append(Spacer(1, 5*mm))
# ── Tolerance & Dependence ──────────────────────────────────────────────
story.append(Paragraph("Tolerance, Dependence & Drug Interactions", sub_hdr))
tol_data = [
[
Paragraph("Concept", style("toh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Description", style("toh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
Paragraph("Examples", style("toh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER)),
],
["Tolerance", "Reduced response after repeated dosing → requires higher dose for same effect", "Opioids, nitrates, benzodiazepines"],
["Tachyphylaxis", "Rapid tolerance developing within minutes to hours", "Nitrates, amphetamines, ephedrine"],
["Cross-tolerance", "Tolerance to one drug → tolerance to another in same class", "Heroin → morphine; alcohol → benzodiazepines"],
["Dependence", "Physical/psychological need; discontinuation causes withdrawal", "Opioids, alcohol, benzodiazepines, nicotine"],
["Synergism", "Combined effect > sum of individual effects", "Alcohol + benzodiazepines → CNS depression"],
["Antagonism", "One drug reduces effect of another", "Naloxone reverses opioid effects"],
]
tol_s = style("ts", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
tol_sb = style("tsb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
tol_pdata = [tol_data[0]]
for row in tol_data[1:]:
tol_pdata.append([Paragraph(row[i], tol_sb if i == 0 else tol_s) for i in range(3)])
tol_tbl = Table(tol_pdata, colWidths=[3.2*cm, 8.4*cm, 5*cm])
tol_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PD_COLOR),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_PD]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(tol_tbl)
story.append(Spacer(1, 8*mm))
# ════════════════════════════════════════════════════════════════════════════
# NARROW THERAPEUTIC INDEX DRUGS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Narrow Therapeutic Index (NTI) Drugs — Require TDM", HEADER_BG))
story.append(Spacer(1, 3*mm))
nti_rows = [
["Drug", "Class", "Target Range", "Toxic Effects"],
["Digoxin", "Cardiac glycoside", "0.5–2 ng/mL", "Bradycardia, heart block, visual disturbances"],
["Lithium", "Mood stabiliser", "0.6–1.2 mEq/L", "Tremor, confusion, nephrogenic DI, arrhythmia"],
["Warfarin", "Anticoagulant", "INR 2–3 (most indications)", "Bleeding; influenced by CYP2C9/VKORC1 polymorphisms"],
["Phenytoin", "Anticonvulsant", "10–20 µg/mL", "Nystagmus, ataxia, gingival hyperplasia"],
["Theophylline","Bronchodilator", "10–20 µg/mL", "Seizures, arrhythmia, nausea/vomiting"],
["Aminoglycosides","Antibiotic", "Peak/trough monitored", "Ototoxicity, nephrotoxicity"],
["Cyclosporine", "Immunosuppressant", "100–400 ng/mL", "Nephrotoxicity, hypertension, tremor"],
["Vancomycin", "Antibiotic (glycopeptide)", "AUC/MIC 400–600", "Nephrotoxicity, ototoxicity, red man syndrome"],
]
nti_s = style("ns", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
nti_sb = style("nsb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
nti_data = []
for i, row in enumerate(nti_rows):
if i == 0:
nti_data.append([
Paragraph(row[j], style("nth", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))
for j in range(4)
])
else:
nti_data.append([Paragraph(row[j], nti_sb if j == 0 else nti_s) for j in range(4)])
nti_tbl = Table(nti_data, colWidths=[3.2*cm, 3.5*cm, 4*cm, 6*cm])
nti_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), HEADER_BG),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GRAY_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(nti_tbl)
story.append(Spacer(1, 8*mm))
# ════════════════════════════════════════════════════════════════════════════
# CLINICAL INTEGRATION — PK + PD TOGETHER
# ════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Clinical Integration — PK/PD Working Together", colors.HexColor("#117A65")))
story.append(Spacer(1, 3*mm))
int_body = style("ib", fontSize=9.5, fontName="Helvetica", textColor=TEXT_DARK, leading=14, spaceAfter=3)
int_bold = style("ibb", fontSize=9.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=14, spaceAfter=2)
story.append(Paragraph("Why both matter clinically:", int_bold))
story.append(Paragraph(
"PK tells you <b>how much drug reaches the receptor</b>. PD tells you <b>what happens when it gets there</b>. "
"Both are needed to predict whether a drug will work at a given dose in a given patient.", int_body))
int_examples = [
["Clinical Scenario", "PK Consideration", "PD Consideration"],
["Renal failure patient", "↑ t½ of renally cleared drugs → drug accumulates; reduce dose/frequency", "Same receptor sensitivity; toxicity risk from elevated plasma concentration"],
["Hepatic failure", "↓ First-pass metabolism → ↑ bioavailability of oral drugs; ↓ clearance", "Reduced albumin → more free drug available → ↑ pharmacological effect"],
["Elderly patient", "↓ Vd (less fat/muscle), ↓ CL, ↑ t½ of many drugs", "↑ CNS receptor sensitivity → higher PD response to same concentration"],
["CYP2D6 poor metaboliser", "Codeine NOT converted to morphine (PK change)", "No analgesic effect (PD consequence); switch to non-CYP2D6-dependent opioid"],
["Loading dose (e.g. digoxin)", "Large Vd → large LD needed to fill tissue stores", "Quick attainment of target concentration → faster therapeutic effect onset"],
["Aspirin overdose", "Alkalinize urine (NaHCO₃) → ion trap salicylate → ↑ renal excretion (PK)", "Reduce plasma free drug level → reverse CNS + respiratory PD effects"],
]
ie_s = style("ies", fontSize=8.5, fontName="Helvetica", textColor=TEXT_DARK, leading=12)
ie_sb = style("iesb", fontSize=8.5, fontName="Helvetica-Bold", textColor=TEXT_DARK, leading=12)
ie_data = []
for i, row in enumerate(int_examples):
if i == 0:
ie_data.append([
Paragraph(row[j], style("ieh", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_CENTER))
for j in range(3)
])
else:
ie_data.append([Paragraph(row[j], ie_sb if j == 0 else ie_s) for j in range(3)])
ie_tbl = Table(ie_data, colWidths=[4*cm, 6.5*cm, 6*cm])
ie_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#117A65")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, colors.HexColor("#E8F8F5")]),
("GRID", (0,0), (-1,-1), 0.4, GRAY_MID),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(ie_tbl)
story.append(Spacer(1, 8*mm))
# ════════════════════════════════════════════════════════════════════════════
# FOOTER
# ════════════════════════════════════════════════════════════════════════════
story.append(HRFlowable(width="100%", thickness=0.5, color=GRAY_MID))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Sources: Lippincott Illustrated Reviews Pharmacology (7th Ed.) · Katzung Basic & Clinical Pharmacology (16th Ed.) · "
"Goodman & Gilman's The Pharmacological Basis of Therapeutics (14th Ed.)",
style("footer", fontSize=7.5, fontName="Helvetica-Oblique", textColor=GRAY_MID, alignment=TA_CENTER)
))
# ════════════════════════════════════════════════════════════════════════════
# BUILD
# ════════════════════════════════════════════════════════════════════════════
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
cd /home/daytona/workspace/pharmacology-pdf && python generate_pdf.py 2>&1
PK vs PD Summary
PDF Document · PDF