For my pharmacology exam create a high quality pdf include diagrams and flowcharts for a 10 marks answer 1. Short note on B complex

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

mkdir -p /tmp/workspace/b-complex-pdf && ls /tmp/workspace/b-complex-pdf/

Writing File

~/b-complex-pdf/generate_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Circle, Polygon, Path
from reportlab.graphics.shapes import Group
from reportlab.graphics import renderPDF
from reportlab.lib.colors import HexColor, Color
import textwrap

# ── Colour palette ──────────────────────────────────────────────────────────
NAVY    = HexColor('#1A2E52')
TEAL    = HexColor('#00838F')
ORANGE  = HexColor('#E65C00')
YELLOW  = HexColor('#FFC107')
GREEN   = HexColor('#2E7D32')
RED     = HexColor('#C62828')
PURPLE  = HexColor('#6A1B9A')
LBLUE   = HexColor('#E3F2FD')
LTEAL   = HexColor('#E0F7FA')
LGREEN  = HexColor('#E8F5E9')
LORANGE = HexColor('#FFF3E0')
LPURPLE = HexColor('#F3E5F5')
LGREY   = HexColor('#F5F5F5')
WHITE   = colors.white
BLACK   = colors.black
GREY    = HexColor('#607D8B')

PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def make_style(name, parent='Normal', **kw):
    s = ParagraphStyle(name, parent=styles[parent], **kw)
    return s

title_style = make_style('DocTitle', 'Normal',
    fontSize=26, textColor=WHITE, fontName='Helvetica-Bold',
    alignment=1, leading=32)

subtitle_style = make_style('DocSub', 'Normal',
    fontSize=13, textColor=HexColor('#B2EBF2'), fontName='Helvetica',
    alignment=1, leading=18)

section_style = make_style('Section', 'Normal',
    fontSize=14, textColor=WHITE, fontName='Helvetica-Bold',
    leading=18, leftIndent=6, spaceBefore=4)

body_style = make_style('Body', 'Normal',
    fontSize=10, textColor=HexColor('#212121'), fontName='Helvetica',
    leading=15, spaceBefore=3, spaceAfter=3)

bullet_style = make_style('Bullet', 'Normal',
    fontSize=10, textColor=HexColor('#212121'), fontName='Helvetica',
    leading=14, leftIndent=18, bulletIndent=8, spaceBefore=2)

bold_body = make_style('BoldBody', 'Normal',
    fontSize=10, textColor=NAVY, fontName='Helvetica-Bold',
    leading=14, spaceBefore=3)

caption_style = make_style('Caption', 'Normal',
    fontSize=8.5, textColor=GREY, fontName='Helvetica-Oblique',
    alignment=1, leading=12)

table_header_style = make_style('TblHdr', 'Normal',
    fontSize=9, textColor=WHITE, fontName='Helvetica-Bold',
    alignment=1, leading=12)

table_cell_style = make_style('TblCell', 'Normal',
    fontSize=8.5, textColor=HexColor('#212121'), fontName='Helvetica',
    leading=12, leftIndent=4)

# ────────────────────────────────────────────────────────────────────────────
# Custom Flowable: Banner header for each section
# ────────────────────────────────────────────────────────────────────────────
class SectionBanner(Flowable):
    def __init__(self, text, color=NAVY, width=None, height=32):
        super().__init__()
        self.text = text
        self.color = color
        self.width = width or (PAGE_W - 2 * MARGIN)
        self.height = height

    def wrap(self, aW, aH):
        self.width = aW
        return aW, self.height + 4

    def draw(self):
        c = self.canv
        w, h = self.width, self.height
        c.setFillColor(self.color)
        c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 13)
        c.drawCentredString(w / 2, h / 2 - 5, self.text)


# ────────────────────────────────────────────────────────────────────────────
# Title page box
# ────────────────────────────────────────────────────────────────────────────
class TitleBox(Flowable):
    def __init__(self, width=None, height=220):
        super().__init__()
        self.width = width or (PAGE_W - 2 * MARGIN)
        self.height = height

    def wrap(self, aW, aH):
        self.width = aW
        return aW, self.height

    def draw(self):
        c = self.canv
        w, h = self.width, self.height
        # Gradient-like background (two overlapping rects)
        c.setFillColor(NAVY)
        c.roundRect(0, 0, w, h, 12, fill=1, stroke=0)
        c.setFillColor(TEAL)
        c.setFillAlpha(0.35)
        c.roundRect(w * 0.55, 0, w * 0.45, h, 12, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Decorative dots
        c.setFillColor(WHITE)
        c.setFillAlpha(0.08)
        for i in range(5):
            r = 30 + i * 15
            c.circle(w * 0.85, h * 0.6, r, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Text
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 28)
        c.drawCentredString(w / 2, h - 55, 'SHORT NOTE ON B COMPLEX')
        c.setFont('Helvetica', 14)
        c.setFillColor(HexColor('#B2EBF2'))
        c.drawCentredString(w / 2, h - 85, 'Pharmacology | 10 Marks Answer')
        c.setFont('Helvetica', 10)
        c.setFillColor(HexColor('#80DEEA'))
        c.drawCentredString(w / 2, h - 110, 'Water-Soluble Vitamins  •  Mechanisms  •  Deficiencies  •  Clinical Uses')
        # Divider
        c.setStrokeColor(YELLOW)
        c.setLineWidth(1.5)
        c.line(w * 0.2, h - 125, w * 0.8, h - 125)
        # Tags
        tags = ['B1 Thiamine', 'B2 Riboflavin', 'B3 Niacin', 'B5 Pantothenic Acid',
                'B6 Pyridoxine', 'B7 Biotin', 'B9 Folate', 'B12 Cobalamin']
        tag_w = (w - 20) / 4
        tag_h = 22
        for i, t in enumerate(tags):
            col = i % 4
            row = i // 4
            x = 10 + col * tag_w
            y = 30 + row * 30
            c.setFillColor(TEAL if row == 0 else ORANGE)
            c.setFillAlpha(0.85)
            c.roundRect(x + 2, y, tag_w - 6, tag_h, 4, fill=1, stroke=0)
            c.setFillAlpha(1)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 9)
            c.drawCentredString(x + tag_w / 2, y + 7, t)


# ────────────────────────────────────────────────────────────────────────────
# Flowchart: Metabolic roles
# ────────────────────────────────────────────────────────────────────────────
class MetabolicFlowchart(Flowable):
    def __init__(self, width=None, height=330):
        super().__init__()
        self.width = width or (PAGE_W - 2 * MARGIN)
        self.height = height

    def wrap(self, aW, aH):
        self.width = aW
        return aW, self.height

    def _box(self, c, x, y, w, h, text, bg, fg=WHITE, font_size=9, radius=6):
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, radius, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', font_size)
        lines = textwrap.wrap(text, width=int(w / 5.5))
        total_h = len(lines) * (font_size + 2)
        start_y = y + h / 2 + total_h / 2 - font_size
        for i, line in enumerate(lines):
            c.drawCentredString(x + w / 2, start_y - i * (font_size + 2), line)

    def _arrow(self, c, x1, y1, x2, y2, color=GREY):
        c.setStrokeColor(color)
        c.setLineWidth(1.5)
        c.line(x1, y1, x2, y2)
        # arrowhead
        import math
        angle = math.atan2(y2 - y1, x2 - x1)
        arr_len = 8
        arr_ang = 0.4
        c.setFillColor(color)
        c.beginPath()
        c.moveTo(x2, y2)
        c.lineTo(x2 - arr_len * math.cos(angle - arr_ang),
                 y2 - arr_len * math.sin(angle - arr_ang))
        c.lineTo(x2 - arr_len * math.cos(angle + arr_ang),
                 y2 - arr_len * math.sin(angle + arr_ang))
        c.closePath()
        c.fill()

    def draw(self):
        c = self.canv
        w, h = self.width, self.height

        # Background
        c.setFillColor(LGREY)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)

        # Title
        c.setFillColor(NAVY)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w / 2, h - 20, 'METABOLIC ROLES OF B VITAMINS')

        # Central node: Glucose
        cx, cy_top = w / 2, h - 55
        box_w, box_h = 130, 30

        self._box(c, cx - box_w/2, cy_top, box_w, box_h,
                  'DIETARY CARBOHYDRATES', NAVY, font_size=9)

        # Step 1: Pyruvate
        py_y = cy_top - 55
        self._box(c, cx - 65, py_y, 130, 28, 'PYRUVATE', TEAL, font_size=9)
        self._arrow(c, cx, cy_top, cx, py_y + 28)

        # B1 label on arrow
        c.setFillColor(ORANGE)
        c.roundRect(cx + 4, py_y + 38, 70, 16, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(cx + 8, py_y + 42, 'B1-TPP coenzyme')

        # Step 2: Acetyl-CoA
        ac_y = py_y - 55
        self._box(c, cx - 65, ac_y, 130, 28, 'ACETYL-CoA', GREEN, font_size=9)
        self._arrow(c, cx, py_y, cx, ac_y + 28)
        c.setFillColor(RED)
        c.roundRect(cx + 4, ac_y + 38, 65, 16, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(cx + 8, ac_y + 42, 'B5 (CoA synthesis)')

        # TCA cycle box
        tca_y = ac_y - 60
        self._box(c, cx - 65, tca_y, 130, 32, 'TCA CYCLE / ETC', PURPLE, font_size=9)
        self._arrow(c, cx, ac_y, cx, tca_y + 32)

        # B2, B3 label
        c.setFillColor(PURPLE)
        c.roundRect(cx + 4, tca_y + 40, 90, 16, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(cx + 8, tca_y + 44, 'B2 (FAD/FMN)  B3 (NAD)')

        # ATP
        atp_y = tca_y - 50
        self._box(c, cx - 50, atp_y, 100, 28, 'ATP (ENERGY)', ORANGE, font_size=9)
        self._arrow(c, cx, tca_y, cx, atp_y + 28)

        # Side branches
        # LEFT: Amino acid metabolism
        lx = 60
        self._box(c, lx - 55, py_y - 10, 110, 26,
                  'Amino Acid Metab.', HexColor('#37474F'), font_size=8)
        self._arrow(c, cx - 65, py_y + 5, lx + 55, py_y + 5)
        c.setFillColor(HexColor('#FF6F00'))
        c.roundRect(lx - 35, py_y + 14, 90, 14, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7)
        c.drawString(lx - 30, py_y + 18, 'B6 (transamination)')

        # RIGHT: DNA synthesis
        rx = w - 60
        self._box(c, rx - 55, py_y - 10, 110, 26,
                  'DNA / Cell Division', HexColor('#1565C0'), font_size=8)
        self._arrow(c, cx + 65, py_y + 5, rx - 55, py_y + 5)
        c.setFillColor(HexColor('#1565C0'))
        c.roundRect(rx - 40, py_y + 14, 80, 14, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7)
        c.drawString(rx - 35, py_y + 18, 'B9/B12 (1C transfer)')

        # Fatty acid synthesis (bottom left)
        self._box(c, lx - 55, ac_y - 10, 110, 26,
                  'Fatty Acid Synth.', HexColor('#00695C'), font_size=8)
        self._arrow(c, cx - 65, ac_y + 5, lx + 55, ac_y + 5)
        c.setFillColor(HexColor('#00695C'))
        c.roundRect(lx - 35, ac_y + 14, 80, 14, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7)
        c.drawString(lx - 30, ac_y + 18, 'B7 (carboxylases)')

        # Nerve function (bottom right)
        self._box(c, rx - 55, ac_y - 10, 110, 26,
                  'Nerve Function', HexColor('#4527A0'), font_size=8)
        self._arrow(c, cx + 65, ac_y + 5, rx - 55, ac_y + 5)
        c.setFillColor(HexColor('#4527A0'))
        c.roundRect(rx - 35, ac_y + 14, 80, 14, 3, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 7)
        c.drawString(rx - 30, ac_y + 18, 'B1/B12 (myelin)')


# ────────────────────────────────────────────────────────────────────────────
# Deficiency flowchart
# ────────────────────────────────────────────────────────────────────────────
class DeficiencyFlowchart(Flowable):
    def __init__(self, width=None, height=280):
        super().__init__()
        self.width = width or (PAGE_W - 2 * MARGIN)
        self.height = height

    def wrap(self, aW, aH):
        self.width = aW
        return aW, self.height

    def draw(self):
        c = self.canv
        w, h = self.width, self.height

        c.setFillColor(LORANGE)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)

        c.setFillColor(ORANGE)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h - 20, 'B VITAMIN DEFICIENCY SYNDROMES')

        data = [
            ('B1\nThiamine', 'Beriberi', 'Wet: cardiac failure + oedema\nDry: peripheral neuropathy\nWernicke-Korsakoff (alcoholics)', TEAL),
            ('B2\nRiboflavin', 'Ariboflavinosis', 'Cheilosis, angular stomatitis\nGlossitis (magenta tongue)\nSeborrhoeic dermatitis', PURPLE),
            ('B3\nNiacin', 'Pellagra', '3 Ds: Dermatitis, Diarrhoea,\nDementia (+ death if untreated)\nCarcinoid / Hartnup disease', RED),
            ('B6\nPyridoxine', 'Pyridoxine def.', 'Microcytic anaemia\nEpileptiform convulsions\nPeripheral neuropathy (excess)', GREEN),
            ('B9\nFolate', 'Folate def.', 'Megaloblastic anaemia\nNeural tube defects (NTD)\nImpaired cell division', NAVY),
            ('B12\nCobalamin', 'Pernicious anaemia', 'Megaloblastic anaemia\nSubacute combined degeneration\nNeuropsychiatric symptoms', HexColor('#1565C0')),
        ]

        col_w = [70, 90, (w - 200), 0]
        row_h = 38
        start_y = h - 42
        x_start = 10

        # Headers
        hdrs = ['Vitamin', 'Syndrome', 'Features']
        hdr_widths = [70, 90, w - 180]
        for i, (hdr, hw) in enumerate(zip(hdrs, hdr_widths)):
            c.setFillColor(NAVY)
            c.rect(x_start + sum(hdr_widths[:i]), start_y, hw, 20, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 9)
            c.drawCentredString(x_start + sum(hdr_widths[:i]) + hw/2, start_y + 6, hdr)

        for idx, (vit, syn, feat, col) in enumerate(data):
            y = start_y - (idx + 1) * row_h
            # Row background alternating
            c.setFillColor(WHITE if idx % 2 == 0 else HexColor('#FFF8E1'))
            c.rect(x_start, y, w - 20, row_h - 2, fill=1, stroke=0)

            # Vitamin cell
            c.setFillColor(col)
            c.roundRect(x_start + 2, y + 3, 64, row_h - 8, 5, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 8)
            lines = vit.split('\n')
            for li, line in enumerate(lines):
                c.drawCentredString(x_start + 34, y + row_h - 14 - li * 11, line)

            # Syndrome cell
            c.setFillColor(HexColor('#37474F'))
            c.setFont('Helvetica-Bold', 8.5)
            c.drawString(x_start + 80, y + row_h // 2 - 4, syn)

            # Features cell
            c.setFillColor(HexColor('#212121'))
            c.setFont('Helvetica', 7.5)
            for li, line in enumerate(feat.split('\n')):
                c.drawString(x_start + 172, y + row_h - 10 - li * 10, '• ' + line)


# ────────────────────────────────────────────────────────────────────────────
# Clinical Uses diagram
# ────────────────────────────────────────────────────────────────────────────
class ClinicalUsesDiagram(Flowable):
    def __init__(self, width=None, height=240):
        super().__init__()
        self.width = width or (PAGE_W - 2 * MARGIN)
        self.height = height

    def wrap(self, aW, aH):
        self.width = aW
        return aW, self.height

    def draw(self):
        import math
        c = self.canv
        w, h = self.width, self.height

        c.setFillColor(LTEAL)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)

        c.setFillColor(TEAL)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h - 20, 'CLINICAL USES OF B COMPLEX')

        # Central circle
        cx, cy = w / 2, h / 2 - 10
        cr = 40
        c.setFillColor(NAVY)
        c.circle(cx, cy, cr, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(cx, cy + 4, 'B COMPLEX')
        c.setFont('Helvetica', 7.5)
        c.drawCentredString(cx, cy - 8, 'VITAMINS')

        # Surrounding uses
        uses = [
            ('Beriberi\n(B1)', 270),
            ('Pellagra\n(B3)', 225),
            ('Megaloblastic\nAnaemia (B9/B12)', 180),
            ('Peripheral\nNeuropathy', 135),
            ('Alcoholic\nNeuritis (B1)', 90),
            ('Pregnancy\n(B9/folate)', 45),
            ('Isoniazid\nneuritis (B6)', 0),
            ('Hyperlipidaemia\n(B3-Niacin)', 315),
        ]
        radius = 90
        box_w, box_h = 80, 32
        for text, angle in uses:
            rad = math.radians(angle)
            bx = cx + radius * math.cos(rad)
            by = cy + radius * math.sin(rad)
            # line from center to box
            c.setStrokeColor(TEAL)
            c.setLineWidth(1)
            c.line(cx + cr * math.cos(rad), cy + cr * math.sin(rad),
                   bx - (box_w/2) * math.cos(rad),
                   by - (box_h/2) * math.sin(rad))
            # box
            c.setFillColor(TEAL)
            c.roundRect(bx - box_w/2, by - box_h/2, box_w, box_h, 5, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 7.5)
            lines = text.split('\n')
            for li, line in enumerate(lines):
                c.drawCentredString(bx, by + 5 - li * 10, line)


# ────────────────────────────────────────────────────────────────────────────
# Coenzyme summary box
# ────────────────────────────────────────────────────────────────────────────
def coenzyme_table(doc_width):
    col_w = [70, 90, 100, doc_width - 280]
    data = [
        [Paragraph('<b>Vitamin</b>', table_header_style),
         Paragraph('<b>Coenzyme</b>', table_header_style),
         Paragraph('<b>Reaction Type</b>', table_header_style),
         Paragraph('<b>Pathway</b>', table_header_style)],
        [Paragraph('B1 (Thiamine)', table_cell_style),
         Paragraph('TPP (Thiamine PyroPhosphate)', table_cell_style),
         Paragraph('Oxidative decarboxylation', table_cell_style),
         Paragraph('Pyruvate→Acetyl-CoA; α-KG dehydrogenase; Pentose-P pathway', table_cell_style)],
        [Paragraph('B2 (Riboflavin)', table_cell_style),
         Paragraph('FAD / FMN', table_cell_style),
         Paragraph('Electron carrier (redox)', table_cell_style),
         Paragraph('ETC, β-oxidation, citric acid cycle', table_cell_style)],
        [Paragraph('B3 (Niacin)', table_cell_style),
         Paragraph('NAD⁺ / NADP⁺', table_cell_style),
         Paragraph('Hydride transfer (redox)', table_cell_style),
         Paragraph('Glycolysis, TCA, fatty acid synth, steroidogenesis', table_cell_style)],
        [Paragraph('B5 (Pantothenic acid)', table_cell_style),
         Paragraph('Coenzyme A (CoA)', table_cell_style),
         Paragraph('Acyl group transfer', table_cell_style),
         Paragraph('Acetyl-CoA metabolism, fatty acid synthesis/oxidation', table_cell_style)],
        [Paragraph('B6 (Pyridoxine)', table_cell_style),
         Paragraph('PLP (Pyridoxal-5-phosphate)', table_cell_style),
         Paragraph('Transamination, decarboxylation', table_cell_style),
         Paragraph('Amino acid metabolism, neurotransmitter synthesis (GABA, serotonin)', table_cell_style)],
        [Paragraph('B7 (Biotin)', table_cell_style),
         Paragraph('Biotinyl-enzyme', table_cell_style),
         Paragraph('CO₂ fixation (carboxylation)', table_cell_style),
         Paragraph('Pyruvate carboxylase, ACC, Propionyl-CoA carboxylase', table_cell_style)],
        [Paragraph('B9 (Folate)', table_cell_style),
         Paragraph('THF (Tetrahydrofolate)', table_cell_style),
         Paragraph('1-carbon transfer', table_cell_style),
         Paragraph('Purine synthesis, thymidylate synthesis, methionine cycle', table_cell_style)],
        [Paragraph('B12 (Cobalamin)', table_cell_style),
         Paragraph('Methylcobalamin / Adenosylcobalamin', table_cell_style),
         Paragraph('Methyl transfer, isomerisation', table_cell_style),
         Paragraph('Methionine synthesis (with B9), methylmalonyl-CoA→succinyl-CoA', table_cell_style)],
    ]
    ts = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), NAVY),
        ('TEXTCOLOR', (0,0), (-1,0), WHITE),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LGREY]),
        ('GRID', (0,0), (-1,-1), 0.4, HexColor('#B0BEC5')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING', (0,0), (-1,-1), 6),
    ])
    t = Table(data, colWidths=col_w, repeatRows=1)
    t.setStyle(ts)
    return t


# ────────────────────────────────────────────────────────────────────────────
# BUILD DOCUMENT
# ────────────────────────────────────────────────────────────────────────────
output_path = '/tmp/workspace/b-complex-pdf/B_Complex_Pharmacology.pdf'

doc = SimpleDocTemplate(
    output_path,
    pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=MARGIN, bottomMargin=MARGIN,
    title='Short Note on B Complex Vitamins',
    author='Pharmacology Notes'
)

story = []
doc_width = PAGE_W - 2 * MARGIN

# ── PAGE 1: Title + Overview ─────────────────────────────────────────────────
story.append(TitleBox(width=doc_width, height=210))
story.append(Spacer(1, 12))

# Introduction
story.append(SectionBanner('1. INTRODUCTION', color=NAVY))
story.append(Spacer(1, 6))
story.append(Paragraph(
    'The <b>B-complex vitamins</b> are a group of <b>eight water-soluble vitamins</b> that are '
    'essential cofactors in cellular metabolism. Unlike fat-soluble vitamins, they cannot be stored '
    'in large amounts and must be regularly consumed in the diet. They primarily function as '
    '<b>coenzymes</b> in energy-producing reactions and are collectively critical for the health of '
    'the nervous system, red blood cell formation, and DNA synthesis.',
    body_style))
story.append(Spacer(1, 6))

# Members box
members_data = [
    [Paragraph('<b>Vitamin</b>', table_header_style),
     Paragraph('<b>Chemical Name</b>', table_header_style),
     Paragraph('<b>Key Source</b>', table_header_style),
     Paragraph('<b>RDA (Adult)</b>', table_header_style)],
    ['B1', 'Thiamine', 'Whole grains, pork, legumes', '1.1–1.2 mg/day'],
    ['B2', 'Riboflavin', 'Dairy, meat, eggs, green vegetables', '1.1–1.3 mg/day'],
    ['B3', 'Niacin (Nicotinamide)', 'Meat, fish, peanuts, fortified cereals', '14–16 mg NE/day'],
    ['B5', 'Pantothenic Acid', 'Meat, avocado, whole grains', '5 mg/day (AI)'],
    ['B6', 'Pyridoxine', 'Poultry, fish, bananas, potatoes', '1.3–1.7 mg/day'],
    ['B7', 'Biotin', 'Egg yolk, liver, nuts, legumes', '30 µg/day (AI)'],
    ['B9', 'Folic Acid / Folate', 'Leafy greens, legumes, citrus fruits', '400 µg DFE/day'],
    ['B12', 'Cobalamin', 'Animal products only (meat, dairy, eggs)', '2.4 µg/day'],
]
for i in range(1, len(members_data)):
    members_data[i] = [Paragraph(str(cell), table_cell_style) for cell in members_data[i]]

members_ts = TableStyle([
    ('BACKGROUND', (0,0), (-1,0), TEAL),
    ('TEXTCOLOR', (0,0), (-1,0), WHITE),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LTEAL]),
    ('GRID', (0,0), (-1,-1), 0.4, HexColor('#B0BEC5')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
    ('TEXTCOLOR', (0,1), (0,-1), TEAL),
])
col_widths = [35, 100, 140, doc_width - 295]
members_t = Table(members_data, colWidths=col_widths, repeatRows=1)
members_t.setStyle(members_ts)
story.append(members_t)
story.append(Spacer(1, 10))

# ── PAGE 2: Metabolic Flowchart ──────────────────────────────────────────────
story.append(PageBreak())
story.append(SectionBanner('2. MECHANISMS & METABOLIC ROLES', color=TEAL))
story.append(Spacer(1, 8))
story.append(MetabolicFlowchart(width=doc_width, height=340))
story.append(Spacer(1, 10))
story.append(Paragraph(
    '<b>Key Point:</b> B vitamins act as coenzymes - they are the "spark plugs" that activate '
    'enzymatic reactions. Without them, cellular respiration, fatty acid oxidation, and nucleotide '
    'synthesis come to a halt. Deficiency therefore causes multi-system disease.',
    make_style('Note', 'Normal', fontSize=9, textColor=GREEN, fontName='Helvetica-Bold',
               leading=13, leftIndent=10, borderPadding=6)))
story.append(Spacer(1, 10))

# Coenzyme table
story.append(SectionBanner('3. COENZYME FORMS & REACTIONS', color=GREEN))
story.append(Spacer(1, 6))
story.append(coenzyme_table(doc_width))

# ── PAGE 3: Deficiencies ─────────────────────────────────────────────────────
story.append(PageBreak())
story.append(SectionBanner('4. DEFICIENCY SYNDROMES', color=RED))
story.append(Spacer(1, 8))
story.append(DeficiencyFlowchart(width=doc_width, height=280))
story.append(Spacer(1, 10))

# Wernicke / B12 notes
story.append(SectionBanner("4a. IMPORTANT DEFICIENCY DETAILS", color=HexColor('#880E4F')))
story.append(Spacer(1, 6))

detail_data = [
    [Paragraph('<b>Condition</b>', table_header_style),
     Paragraph('<b>Vitamin</b>', table_header_style),
     Paragraph('<b>Mechanism</b>', table_header_style),
     Paragraph('<b>Treatment</b>', table_header_style)],

    [Paragraph('Wernicke Encephalopathy\n→ Korsakoff Psychosis', table_cell_style),
     Paragraph('B1 (Thiamine)', table_cell_style),
     Paragraph('TPP deficiency → impaired pyruvate dehydrogenase → lactic acidosis + mamillary body necrosis', table_cell_style),
     Paragraph('IV thiamine 100 mg BEFORE glucose in alcoholics', table_cell_style)],

    [Paragraph('Subacute Combined\nDegeneration of Cord', table_cell_style),
     Paragraph('B12 (Cobalamin)', table_cell_style),
     Paragraph('Impaired methylmalonyl-CoA conversion → myelin loss in dorsal + lateral columns', table_cell_style),
     Paragraph('IM hydroxocobalamin or oral cyanocobalamin (large doses)', table_cell_style)],

    [Paragraph('Pellagra (3 Ds)', table_cell_style),
     Paragraph('B3 (Niacin)', table_cell_style),
     Paragraph('NAD/NADP deficiency; also in carcinoid (tryptophan→5-HT) and isoniazid Rx', table_cell_style),
     Paragraph('Nicotinamide 100 mg TDS; treat underlying cause', table_cell_style)],

    [Paragraph('Neural Tube Defects', table_cell_style),
     Paragraph('B9 (Folate)', table_cell_style),
     Paragraph('Impaired thymidylate synthesis → defective neural tube closure in embryogenesis', table_cell_style),
     Paragraph('Folic acid 5 mg/day pre-conception and first trimester', table_cell_style)],

    [Paragraph('Isoniazid-induced\nNeuropathy', table_cell_style),
     Paragraph('B6 (Pyridoxine)', table_cell_style),
     Paragraph('INH antagonises PLP (competes for apoenzyme binding) → peripheral neuropathy', table_cell_style),
     Paragraph('Pyridoxine 10–50 mg/day with INH as prophylaxis', table_cell_style)],
]
detail_ts = TableStyle([
    ('BACKGROUND', (0,0), (-1,0), HexColor('#880E4F')),
    ('TEXTCOLOR', (0,0), (-1,0), WHITE),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LPURPLE]),
    ('GRID', (0,0), (-1,-1), 0.4, HexColor('#B0BEC5')),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
])
col_w2 = [110, 75, 170, doc_width - 375]
detail_t = Table(detail_data, colWidths=col_w2, repeatRows=1)
detail_t.setStyle(detail_ts)
story.append(detail_t)

# ── PAGE 4: Clinical Uses + Pharmacology ────────────────────────────────────
story.append(PageBreak())
story.append(SectionBanner('5. CLINICAL USES / THERAPEUTIC APPLICATIONS', color=TEAL))
story.append(Spacer(1, 8))
story.append(ClinicalUsesDiagram(width=doc_width, height=240))
story.append(Spacer(1, 10))

# Pharmacology details table
story.append(SectionBanner('6. PHARMACOLOGY OF INDIVIDUAL B VITAMINS', color=PURPLE))
story.append(Spacer(1, 6))

pharma_data = [
    [Paragraph('<b>Vitamin</b>', table_header_style),
     Paragraph('<b>Absorption</b>', table_header_style),
     Paragraph('<b>Special Properties</b>', table_header_style),
     Paragraph('<b>Toxicity / Notes</b>', table_header_style)],
    [Paragraph('B1', table_cell_style),
     Paragraph('Active transport at low doses; passive at high doses', table_cell_style),
     Paragraph('Triphosphate form activates chloride channels in nerves', table_cell_style),
     Paragraph('Non-toxic; excess excreted in urine', table_cell_style)],
    [Paragraph('B2', table_cell_style),
     Paragraph('Carrier-mediated; bile salts enhance', table_cell_style),
     Paragraph('Generates superoxide radicals (oxidant stress)', table_cell_style),
     Paragraph('Urine turns yellow - harmless', table_cell_style)],
    [Paragraph('B3 (Niacin)', table_cell_style),
     Paragraph('Rapid GI absorption; first-pass hepatic', table_cell_style),
     Paragraph('<b>Pharmacological dose (1–3 g)</b>: ↓ LDL, ↓ TG, ↑ HDL; inhibits lipolysis', table_cell_style),
     Paragraph('<b>Flushing</b> (prostaglandin-mediated; blocked by aspirin); hepatotoxicity at high dose', table_cell_style)],
    [Paragraph('B6', table_cell_style),
     Paragraph('Absorbed throughout small intestine', table_cell_style),
     Paragraph('PLP required for >100 enzyme reactions; neurotransmitter synthesis', table_cell_style),
     Paragraph('<b>Sensory neuropathy</b> with chronic excess (>200 mg/day)', table_cell_style)],
    [Paragraph('B9 (Folic acid)', table_cell_style),
     Paragraph('Jejunum; PCFT (proton-coupled folate transporter)', table_cell_style),
     Paragraph('Given in pregnancy; masks B12 deficiency if given alone', table_cell_style),
     Paragraph('Folinic acid (leucovorin) = active form; bypasses DHFR', table_cell_style)],
    [Paragraph('B12', table_cell_style),
     Paragraph('Requires intrinsic factor (IF) from gastric parietal cells', table_cell_style),
     Paragraph('Stored in liver (3–5 yr supply); deficiency takes years to manifest', table_cell_style),
     Paragraph('Pernicious anaemia = anti-IF antibodies; give parenterally', table_cell_style)],
]
pharma_ts = TableStyle([
    ('BACKGROUND', (0,0), (-1,0), PURPLE),
    ('TEXTCOLOR', (0,0), (-1,0), WHITE),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LPURPLE]),
    ('GRID', (0,0), (-1,-1), 0.4, HexColor('#B0BEC5')),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
])
pharma_t = Table(pharma_data, colWidths=[40, 100, 185, doc_width - 345], repeatRows=1)
pharma_t.setStyle(pharma_ts)
story.append(pharma_t)
story.append(Spacer(1, 12))

# Niacin special section
story.append(SectionBanner('6a. NIACIN AS A HYPOLIPIDAEMIC DRUG', color=ORANGE))
story.append(Spacer(1, 6))
story.append(Paragraph(
    'At <b>pharmacological doses (1–3 g/day)</b>, niacin (nicotinic acid) has the following effects:',
    body_style))
niacin_bullets = [
    '↓ VLDL synthesis → ↓ LDL-cholesterol and ↓ triglycerides',
    '↑ HDL-cholesterol (most effective agent for raising HDL)',
    'Mechanism: inhibits adipocyte lipolysis via GPR109A receptor → ↓ FFA delivery to liver → ↓ VLDL assembly',
    'Side effect: <b>cutaneous flushing</b> (prostaglandin-mediated) - prevented by aspirin or extended-release formulations',
    'Hepatotoxicity with sustained-release forms; monitor LFTs',
    'May worsen insulin resistance and gout',
]
for b in niacin_bullets:
    story.append(Paragraph('• ' + b, bullet_style))
story.append(Spacer(1, 10))

# ── PAGE 5: B9/B12 Folate Cycle ─────────────────────────────────────────────
story.append(PageBreak())
story.append(SectionBanner('7. FOLATE-B12 METHIONINE CYCLE (Key for MCQs)', color=NAVY))
story.append(Spacer(1, 8))

# Draw folate cycle as a table-based diagram
folate_text = [
    'The folate-B12 methionine cycle is essential for <b>1-carbon metabolism</b>.',
    '',
    '<b>Step 1:</b> Dietary folate → dihydrofolate (DHF) → tetrahydrofolate (THF)  [enzyme: DHFR, inhibited by methotrexate]',
    '<b>Step 2:</b> THF → 5,10-methylene-THF  [used for thymidylate synthesis - DNA]',
    '<b>Step 3:</b> 5,10-methylene-THF → 5-methyl-THF  [irreversible "methyl trap"]',
    '<b>Step 4:</b> 5-methyl-THF + homocysteine → methionine + THF  [enzyme: methionine synthase; coenzyme: <b>B12</b>]',
    '',
    '<b>Methyl Trap Hypothesis:</b> In B12 deficiency, 5-methyl-THF accumulates (trapped) → functional folate deficiency → megaloblastic anaemia even with adequate dietary folate.',
    '',
    '<b>Clinical relevance:</b>',
    '• Giving folate alone in B12 deficiency corrects anaemia but NOT the neurological damage → always exclude B12 deficiency before starting folate',
    '• Homocysteine rises in both B9 and B12 deficiency → cardiovascular risk marker',
    '• Methotrexate blocks DHFR → rescued by folinic acid (leucovorin)',
]
for line in folate_text:
    if line == '':
        story.append(Spacer(1, 5))
    else:
        story.append(Paragraph(line, body_style))

story.append(Spacer(1, 12))

# ── Summary / Exam Points ────────────────────────────────────────────────────
story.append(SectionBanner('8. HIGH-YIELD EXAM POINTS', color=HexColor('#E65100')))
story.append(Spacer(1, 6))

exam_points = [
    ('<b>3 Ds of Pellagra</b> (B3 deficiency):', 'Dermatitis, Diarrhoea, Dementia (+ Death if untreated)'),
    ('<b>Wernicke-Korsakoff</b>:', 'Give IV thiamine BEFORE glucose in any confused alcoholic - glucose alone can precipitate acute Wernicke\'s'),
    ('<b>Pernicious Anaemia</b>:', 'Due to anti-IF antibodies; treat with IM B12 (hydroxocobalamin); oral high-dose also works'),
    ('<b>Neural Tube Defects</b>:', 'Folic acid 5 mg pre-conception + first trimester; mandatory supplementation in epileptics on valproate/carbamazepine'),
    ('<b>Isoniazid neuropathy</b>:', 'Always co-prescribe pyridoxine B6 with INH, especially in malnourished/diabetic/pregnant patients'),
    ('<b>Niacin flushing</b>:', 'Mediated by prostaglandins → give aspirin 325 mg 30 min before niacin dose'),
    ('<b>B7 (Biotin) deficiency</b>:', 'Caused by eating raw egg whites (avidin binds biotin); also complication of long-term TPN without supplementation'),
    ('<b>B6 toxicity</b>:', 'Sensory peripheral neuropathy (paradox - excess pyridoxine causes the very neuropathy its deficiency also causes)'),
]
for bold_part, detail in exam_points:
    story.append(Paragraph(f'{bold_part} {detail}', bullet_style))
    story.append(Spacer(1, 3))

story.append(Spacer(1, 10))
story.append(HRFlowable(width=doc_width, thickness=1, color=NAVY, dash=(3,3)))
story.append(Spacer(1, 6))
story.append(Paragraph(
    'References: Harper\'s Illustrated Biochemistry 32e | Basic Medical Biochemistry 6e | '
    'Henry\'s Clinical Diagnosis & Management by Laboratory Methods',
    caption_style))

# ── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {output_path}")
Running Command

cd /tmp/workspace/b-complex-pdf && python generate_pdf.py 2>&1

Editing File

~/b-complex-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/b-complex-pdf/generate_pdf.py'
Editing File

~/b-complex-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/b-complex-pdf/generate_pdf.py'
Running Command

cd /tmp/workspace/b-complex-pdf && python generate_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/b-complex-pdf/B_Complex_Pharmacology.pdf

Your PDF is ready! Here's what's packed into the 5-page document:

B Complex Pharmacology

PDF Document · PDF


What's inside the PDF

Page 1 - Introduction & Members Table
  • Colour-coded title banner with all 8 B vitamins listed
  • Complete table: chemical names, key food sources, and RDA values for all B1-B12
Page 2 - Metabolic Roles (Flowchart)
  • Custom flowchart: Dietary carbohydrates → Pyruvate → Acetyl-CoA → TCA Cycle → ATP
  • Each arrow annotated with the B vitamin cofactor (B1/TPP, B5/CoA, B2/FAD, B3/NAD)
  • Side branches showing amino acid metabolism (B6), DNA synthesis (B9/B12), fatty acid synthesis (B7), and nerve function (B1/B12)
  • Full coenzyme table: coenzyme forms, reaction types, and pathways for each vitamin
Page 3 - Deficiency Syndromes (Table Diagram)
  • Colour-coded deficiency chart: Beriberi, Ariboflavinosis, Pellagra, Pyridoxine def., Folate def., Pernicious anaemia
  • Detailed table for high-yield deficiencies: Wernicke-Korsakoff, Subacute combined degeneration, Pellagra (3Ds), NTDs, INH neuropathy - with mechanisms and treatments
Page 4 - Clinical Uses (Spider/Hub Diagram) + Pharmacology Table
  • Hub-and-spoke diagram: B Complex at centre, 8 clinical uses radiating outward
  • Pharmacology table: absorption, special properties, toxicities for B1, B2, B3, B6, B9, B12
  • Niacin as a hypolipidaemic drug (pharmacological doses, GPR109A mechanism, flushing)
Page 5 - Folate-B12 Cycle + High-Yield Exam Points
  • Methyl trap hypothesis explained step-by-step
  • 8 bullet high-yield exam points (Pellagra 3Ds, Wernicke glucose rule, Pernicious anaemia, NTDs, INH/B6, Niacin flushing, Biotin/avidin, B6 toxicity paradox)

Define drug interactions discuss various combined effects of drugs such as additive effect , synergism, potentiation, and antagonism with examples

Reading File
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Loading Image
Reading File
Reading File
Excellent - I have the isobologram from Goodman & Gilman's and all the textbook content I need. Now I have comprehensive information to write a thorough answer.

Drug Interactions

Definition

A drug interaction occurs when the pharmacological effect of one drug is altered (enhanced, diminished, or qualitatively changed) by the concurrent or sequential administration of another drug, food, or endogenous substance. The combined effects can be classified as: additive, synergism, potentiation, and antagonism.
(Goodman & Gilman's Pharmacological Basis of Therapeutics)

Classification of Combined Drug Effects

1. Additive Effect

Definition: The combined effect of two drugs equals the arithmetic sum of their individual effects when given alone.
Formula: Effect (A + B) = Effect (A) + Effect (B)
  • Both drugs act on the same receptor or same system but are administered independently.
  • Neither drug augments nor diminishes the other's action - they simply "add up."
  • Mathematically expressed as: 1 + 1 = 2
Mechanism: Both drugs produce the same qualitative pharmacological response through the same or similar mechanism. Each drug contributes its own share of the total effect.
Clinical Examples:
Drug ADrug BCombined Additive Effect
Aspirin (analgesic)Paracetamol (analgesic)Combined analgesia = sum of both
Two NSAIDs(e.g., aspirin + ibuprofen)Additive GI ulceration and bleeding risk
Alcohol (CNS depressant)Diazepam (CNS depressant)Additive CNS depression
Thiazide diureticLoop diureticAdditive diuresis and electrolyte loss
Clinical Relevance: Additive toxicity is a common reason for adverse drug reactions - e.g., combining two nephrotoxic drugs (aminoglycoside + amphotericin B) causes additive nephrotoxicity.

2. Synergism (Supra-additive Effect)

Definition: The combined effect of two drugs is greater than the arithmetic sum of their individual effects.
Formula: Effect (A + B) > Effect (A) + Effect (B)
  • Expressed mathematically as: 1 + 1 > 2 (often described as "2 + 2 = 5")
  • Also called positive synergism or superadditivity
  • The two drugs act at different sites or by different mechanisms but converge on the same final outcome
The Isobologram (from Goodman & Gilman's, Fig. 3-5):
Isobologram showing additive vs synergistic vs subadditive drug combinations
The isobologram plots combinations of Drug A and Drug B needed to produce a 50% effect. A combination that falls below the line of additivity (the straight line joining EC50-A on the x-axis and EC50-B on the y-axis) exhibits positive synergism (superadditivity). A combination that falls above the line is subadditive (negative synergism).
Types of Synergism:
TypeMechanismExample
Bactericidal synergismTwo agents alone are only bacteriostatic, but together they are bactericidalPenicillin + Aminoglycoside in Enterococcal endocarditis
Sequential block synergismTwo drugs block sequential steps in the same pathwayTrimethoprim + Sulfamethoxazole (block sequential steps in folate synthesis)
Receptor-effector synergismDrugs act at different receptors whose downstream effects summate supra-additivelyMorphine + Ketamine (pain pathways)
Clinical Examples:
  • Trimethoprim + Sulfamethoxazole (Co-trimoxazole): Sulfonamide inhibits dihydropteroate synthase; trimethoprim inhibits dihydrofolate reductase - they block sequential steps in bacterial folate synthesis, producing 20-100x greater antibacterial activity than either alone. (Goldman-Cecil Medicine)
  • Penicillin + Aminoglycoside: Penicillin damages the bacterial cell wall (allowing aminoglycoside entry) and aminoglycosides inhibit protein synthesis - together they are bactericidal against enterococci that neither drug kills alone.
  • Levodopa + Carbidopa: Carbidopa inhibits peripheral DOPA decarboxylase, allowing more levodopa to reach the brain - a synergistic pharmacokinetic interaction that greatly increases CNS dopamine.
  • β-lactam + β-lactamase inhibitor (e.g., Amoxicillin + Clavulanate): Clavulanate alone has no antibacterial activity but protects amoxicillin from enzymatic destruction.

3. Potentiation

Definition: One drug (which has no activity of its own on a particular system) increases the effect of another drug that does have activity on that system.
Formula: Effect (A alone) = 0; Effect (A + B) >> Effect (B) Expressed as: 0 + 1 = 3 (i.e., inactive drug amplifies the active one)
Key distinction from synergism:
  • In synergism, both drugs are pharmacologically active on the system in question.
  • In potentiation, one drug is inactive on that particular system but enhances the active drug's effect.
Mechanism of Potentiation:
  • Inhibition of metabolism (prolonging the active drug's half-life)
  • Inhibition of elimination/excretion
  • Displacement from protein binding
  • Facilitation of receptor binding
Clinical Examples:
Inactive Drug (Potentiator)Active DrugEffect
Probenecid (no antimicrobial activity)PenicillinBlocks renal tubular secretion of penicillin → prolongs and raises penicillin plasma levels
Clavulanate (no antibacterial activity alone)AmoxicillinInhibits β-lactamase → potentiates amoxicillin's antibacterial effect
Dantrolene (no NMJ blocking activity)Neuromuscular blockersPrevents Ca²⁺ release from sarcoplasmic reticulum → potentiates NMB-induced weakness (Miller's Anesthesia)
CYP inhibitor (e.g., ketoconazole)Statins / Protease inhibitorsReduces CYP3A4-mediated metabolism → raises plasma levels of active drug (Goodman & Gilman's)
SulfonamideWarfarinInhibits CYP2C9 + displaces warfarin from albumin → potentiates anticoagulant effect (Lippincott Pharmacology)
Clinically Important Potentiations:
  • MAO inhibitors + Pethidine (Meperidine): MAOIs inhibit breakdown of serotonin/noradrenaline; pethidine triggers serotonin release → life-threatening serotonin syndrome (hyperthermia, rigidity, seizures).
  • Linezolid + SSRIs: Linezolid is a reversible MAOI; with SSRIs, potentiates serotonin → serotonin syndrome. (Goldman-Cecil Medicine)

4. Antagonism

Definition: One drug reduces or abolishes the effect of another drug. The combined effect is less than that of either drug alone.
Formula: Effect (A + B) < Effect (A) or Effect (B) Expressed as: 1 + 1 < 2 or even 1 + 1 = 0
Types of Antagonism:

a) Pharmacological (Receptor) Antagonism

Both agonist and antagonist act at the same receptor.
Sub-typeMechanismReversibilityExample
Competitive (surmountable)Antagonist reversibly competes for same binding site; can be overcome by increasing agonist doseReversibleAtropine antagonises acetylcholine at muscarinic receptors; Naloxone antagonises morphine at opioid receptors
Non-competitive (insurmountable)Antagonist binds irreversibly to receptor or an allosteric site; cannot be overcome by increasing agonistIrreversiblePhenoxybenzamine (irreversible α-blocker) antagonises noradrenaline

b) Physiological (Functional) Antagonism

Two drugs produce opposite effects through different receptors or mechanisms - their effects cancel out.
  • Example: Adrenaline (sympathomimetic - bronchodilator, vasoconstrictor) antagonises the bronchoconstriction and hypotension caused by histamine in anaphylaxis. They act at entirely different receptors (adrenergic vs. histamine receptors) but on the same end-organ systems.
  • Example: Glucagon antagonises insulin-induced hypoglycaemia (opposite effects on blood glucose via different receptors).

c) Chemical Antagonism (Physical/Chemical Inactivation)

The two drugs interact chemically outside the body or in the GIT and neutralise each other.
  • Example: Protamine sulphate + Heparin - protamine (cationic protein) forms an inactive ionic complex with heparin (anionic) → complete neutralisation of anticoagulant effect.
  • Example: Chelation therapy - EDTA chelates heavy metals (lead, mercury), forming insoluble complexes for excretion.
  • Example: Antacids reduce absorption of tetracyclines and quinolones by chelation with divalent cations (Ca²⁺, Mg²⁺, Al³⁺).

d) Pharmacokinetic Antagonism

One drug accelerates the elimination or reduces the absorption of another.
  • Example: Rifampicin induces CYP3A4 and P-glycoprotein → dramatically reduces plasma levels of oral contraceptives, warfarin, protease inhibitors → therapeutic failure. (Goldman-Cecil Medicine)
  • Example: Activated charcoal adsorbs drugs in the GIT → prevents absorption.
  • Example: Cholestyramine reduces absorption of digoxin, warfarin, and thyroxine.

Comparative Summary Table

TypeMathematical ExpressionMechanismClassic Example
Additive1 + 1 = 2Same receptor/system; effects sum normallyAspirin + Paracetamol
Synergism1 + 1 > 2Different mechanisms converge; supra-additiveTMP + SMX; Penicillin + Aminoglycoside
Potentiation0 + 1 = 3Inactive drug amplifies active drugProbenecid + Penicillin; Clavulanate + Amoxicillin
Competitive Antagonism1 + 1 → 0 (reversible)Same receptor, reversible blockNaloxone + Morphine
Non-competitive Antagonism1 + 1 → 0 (irreversible)Same receptor, irreversible blockPhenoxybenzamine + NA
Physiological Antagonism1 + 1 → 0 (different receptors)Opposing effects, different receptorsAdrenaline + Histamine
Chemical Antagonism1 + 1 → 0 (direct inactivation)Direct chemical inactivationProtamine + Heparin

Clinical Importance of Drug Interactions

  1. Therapeutic exploitation - Synergism and potentiation are deliberately used to increase efficacy (e.g., co-trimoxazole, HAART for HIV, anti-TB combinations) and reduce resistance.
  2. Dose reduction - Synergism allows lower doses of each drug → reduced side effects (e.g., lower opioid dose when combined with ketamine).
  3. Adverse outcomes - Unintended potentiation or additive toxicity is a major cause of hospital admissions (e.g., warfarin + sulfonamide causing bleeding; MAOI + pethidine causing serotonin syndrome).
  4. Narrow therapeutic index drugs - Interactions are most dangerous with drugs like warfarin, digoxin, lithium, theophylline, phenytoin, cyclosporine, and aminoglycosides where small plasma level changes cause toxicity. (Goodman & Gilman's)
  5. CYP-mediated interactions - Most pharmacokinetic interactions involve CYP3A4, CYP2C9, CYP1A2 induction (rifampicin, carbamazepine) or inhibition (ketoconazole, grapefruit juice, erythromycin).

Sources: Goodman & Gilman's Pharmacological Basis of Therapeutics | Goldman-Cecil Medicine | Lippincott Illustrated Reviews: Pharmacology | Miller's Anesthesia 10e

Create a detailed study guide PDF on drug interactions with mechanism diagrams

Running Command

mkdir -p /tmp/workspace/drug-interactions-pdf && ls /tmp/workspace/drug-interactions-pdf/

Writing File

~/drug-interactions-pdf/build_pdf.py

"""
Drug Interactions - Detailed Study Guide PDF
Pharmacology Exam Preparation
"""
import math, textwrap
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether, ListFlowable, ListItem
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.colors import HexColor

# ── Palette ──────────────────────────────────────────────────────────────────
NAVY    = HexColor('#0D2137')
TEAL    = HexColor('#006D77')
ORANGE  = HexColor('#E07B39')
GREEN   = HexColor('#2D6A4F')
RED     = HexColor('#AE2012')
PURPLE  = HexColor('#5C4B8A')
CRIMSON = HexColor('#C62828')
GOLD    = HexColor('#B8860B')
BLUE    = HexColor('#1565C0')
DKGREY  = HexColor('#37474F')
MDGREY  = HexColor('#607D8B')
WHITE   = colors.white
BLACK   = colors.black

LNAVY   = HexColor('#E8EDF3')
LTEAL   = HexColor('#E0F5F5')
LORANGE = HexColor('#FFF3E0')
LGREEN  = HexColor('#E8F5E9')
LRED    = HexColor('#FFEBEE')
LPURPLE = HexColor('#EDE7F6')
LGOLD   = HexColor('#FFFDE7')
LBLUE   = HexColor('#E3F2FD')
LGREY   = HexColor('#F5F5F5')

PAGE_W, PAGE_H = A4
MARGIN = 1.7 * cm
CONTENT_W = PAGE_W - 2 * MARGIN

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, parent='Normal', **kw):
    return ParagraphStyle(name, parent=styles[parent], **kw)

body    = S('body',    fontSize=10, leading=15, textColor=DKGREY, spaceBefore=3, spaceAfter=3)
bodyB   = S('bodyB',  fontSize=10, leading=15, textColor=NAVY, fontName='Helvetica-Bold')
small   = S('small',  fontSize=8.5, leading=13, textColor=DKGREY)
bullet  = S('bullet', fontSize=9.5, leading=14, textColor=DKGREY, leftIndent=16, bulletIndent=6, spaceBefore=2)
caption = S('caption',fontSize=8, leading=12, textColor=MDGREY, fontName='Helvetica-Oblique', alignment=1)
th      = S('th', fontSize=9, leading=12, textColor=WHITE, fontName='Helvetica-Bold', alignment=1)
td      = S('td', fontSize=8.5, leading=12, textColor=DKGREY)
tdB     = S('tdB',fontSize=8.5, leading=12, textColor=NAVY, fontName='Helvetica-Bold')
note    = S('note', fontSize=9, leading=13, textColor=GREEN, fontName='Helvetica-Bold',
            leftIndent=10, borderPadding=5, backColor=LGREEN)

# ── Helpers ──────────────────────────────────────────────────────────────────
def banner(text, color=NAVY, height=30):
    class _Banner(Flowable):
        def __init__(self):
            super().__init__()
        def wrap(self, aW, aH):
            self._w = aW
            return aW, height + 6
        def draw(self):
            c = self.canv
            c.setFillColor(color)
            c.roundRect(0, 0, self._w, height, 7, fill=1, stroke=0)
            # left accent strip
            c.setFillColor(WHITE)
            c.setFillAlpha(0.25)
            c.roundRect(0, 0, 8, height, 4, fill=1, stroke=0)
            c.setFillAlpha(1)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 12)
            c.drawCentredString(self._w / 2, height / 2 - 5, text)
    return _Banner()


def sub_banner(text, color=TEAL, height=24):
    class _SBanner(Flowable):
        def __init__(self):
            super().__init__()
        def wrap(self, aW, aH):
            self._w = aW
            return aW, height + 4
        def draw(self):
            c = self.canv
            c.setFillColor(color)
            c.setFillAlpha(0.15)
            c.roundRect(0, 0, self._w, height, 5, fill=1, stroke=0)
            c.setFillAlpha(1)
            c.setStrokeColor(color)
            c.setLineWidth(2.5)
            c.line(0, 0, 0, height)
            c.setFillColor(color)
            c.setFont('Helvetica-Bold', 11)
            c.drawString(14, height / 2 - 5, text)
    return _SBanner()


def spacer(h=8):
    return Spacer(1, h)


def hr(color=NAVY, dash=None):
    return HRFlowable(width=CONTENT_W, thickness=0.7, color=color, dash=dash or (4, 4))


def tbl(data, col_widths, hdr_color=NAVY, alt=None, row_heights=None):
    alt_colors = alt or [WHITE, LGREY]
    rows = len(data)
    ts = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), hdr_color),
        ('TEXTCOLOR',  (0,0), (-1,0), WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,0), 9),
        ('ALIGN',      (0,0), (-1,0), 'CENTER'),
        ('VALIGN',     (0,0), (-1,-1), 'MIDDLE'),
        ('GRID',       (0,0), (-1,-1), 0.35, HexColor('#CFD8DC')),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING',(0,0),(-1,-1), 5),
        ('LEFTPADDING',(0,0), (-1,-1), 6),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), alt_colors),
    ])
    t = Table(data, colWidths=col_widths, repeatRows=1, rowHeights=row_heights)
    t.setStyle(ts)
    return t


# ════════════════════════════════════════════════════════════════════════════
# CUSTOM FLOWABLE DIAGRAMS
# ════════════════════════════════════════════════════════════════════════════

# ── 1. Title Page ─────────────────────────────────────────────────────────────
class TitlePage(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 260
    def draw(self):
        c = self.canv
        w, h = self._w, 260
        # Background gradient simulation
        c.setFillColor(NAVY)
        c.roundRect(0, 0, w, h, 14, fill=1, stroke=0)
        c.setFillColor(TEAL)
        c.setFillAlpha(0.3)
        c.roundRect(w*0.6, 0, w*0.4, h, 14, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Decorative circles
        for r, a in [(90,0.04),(60,0.06),(35,0.08)]:
            c.setFillColor(WHITE)
            c.setFillAlpha(a)
            c.circle(w*0.88, h*0.62, r, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Rx symbol area
        c.setFillColor(ORANGE)
        c.setFillAlpha(0.9)
        c.roundRect(w*0.04, h-70, 52, 52, 8, fill=1, stroke=0)
        c.setFillAlpha(1)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 26)
        c.drawCentredString(w*0.04+26, h-50, 'Rx')
        # Title
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 24)
        c.drawString(w*0.04+65, h-48, 'DRUG INTERACTIONS')
        c.setFont('Helvetica', 13)
        c.setFillColor(HexColor('#80CBC4'))
        c.drawString(w*0.04+65, h-68, 'Detailed Study Guide  |  Pharmacology')
        # Divider
        c.setStrokeColor(ORANGE)
        c.setLineWidth(1.8)
        c.line(w*0.04, h-82, w*0.96, h-82)
        # Subtitle blocks
        topics = ['Definition & Classification','Additive Effect','Synergism',
                  'Potentiation','Antagonism Types','Pharmacokinetic Interactions',
                  'CYP450 Interactions','Clinical High-Yield Points']
        cols = 4
        bw = (w - 20) / cols
        bh = 26
        for i, t in enumerate(topics):
            col = i % cols
            row = i // cols
            x = 10 + col * bw
            y = h - 82 - 16 - row * 32
            bg = TEAL if row == 0 else ORANGE
            c.setFillColor(bg)
            c.setFillAlpha(0.85)
            c.roundRect(x+2, y, bw-6, bh, 5, fill=1, stroke=0)
            c.setFillAlpha(1)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 7.5)
            c.drawCentredString(x + bw/2, y + 8, t)
        # Footer
        c.setFillColor(HexColor('#B2DFDB'))
        c.setFont('Helvetica', 8.5)
        c.drawCentredString(w/2, 12,
            'Goodman & Gilman\'s  |  Goldman-Cecil Medicine  |  Lippincott Pharmacology  |  Katzung Basic & Clinical Pharmacology')


# ── 2. Definition Mind-Map ────────────────────────────────────────────────────
class DefinitionMindMap(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 220
    def _rbox(self, c, x, y, w, h, text, bg, fg=WHITE, fs=9, r=6, bold=True):
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, r, fill=1, stroke=0)
        c.setFillColor(fg)
        fn = 'Helvetica-Bold' if bold else 'Helvetica'
        c.setFont(fn, fs)
        lines = textwrap.wrap(text, width=max(int(w/5.2), 8))
        total = len(lines) * (fs + 2)
        sy = y + h/2 + total/2 - fs
        for i, ln in enumerate(lines):
            c.drawCentredString(x + w/2, sy - i*(fs+2), ln)
    def _line(self, c, x1, y1, x2, y2, color=MDGREY, lw=1.2):
        c.setStrokeColor(color)
        c.setLineWidth(lw)
        c.line(x1, y1, x2, y2)
    def draw(self):
        c = self.canv
        w, h = self._w, 220
        c.setFillColor(LGREY)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
        # Central box
        cx, cy, bw, bh = w/2, h/2, 140, 44
        self._rbox(c, cx-bw/2, cy-bh/2, bw, bh,
                   'DRUG INTERACTION', NAVY, fs=12)
        # Branches
        branches = [
            # (angle_deg, text, short_desc, color)
            (80,  'Pharmacodynamic', 'Additive / Synergism\nPotentiation / Antagonism', TEAL),
            (140, 'Pharmacokinetic', 'ADME-based\nCYP450 / Protein binding', BLUE),
            (220, 'Pharmaceutical', 'Physical/Chemical\nIncompatibility in syringe', PURPLE),
            (310, 'Beneficial', 'Co-trimoxazole\nAMOX-Clavulanate', GREEN),
        ]
        r_inner = 80
        for ang, label, desc, col in branches:
            rad = math.radians(ang)
            tx = cx + r_inner * math.cos(rad)
            ty = cy + r_inner * math.sin(rad) - 5
            # line from centre
            self._line(c, cx + 70*math.cos(rad), cy + 70*math.sin(rad),
                       tx - 55*math.cos(rad), ty + 5 + 55*math.sin(rad),
                       color=col, lw=1.5)
            # box
            bx, by = tx - 75, ty - 28
            self._rbox(c, bx, by, 80, 26, label, col, fs=8.5)
            # sub-text
            c.setFillColor(DKGREY)
            c.setFont('Helvetica', 7)
            for di, dl in enumerate(desc.split('\n')):
                c.drawCentredString(tx - 35, by - 12 - di*10, dl)


# ── 3. Additive Effect Diagram ────────────────────────────────────────────────
class AdditiveBarChart(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 190
    def draw(self):
        c = self.canv
        w, h = self._w, 190
        c.setFillColor(LGREEN)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
        # Title
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'ADDITIVE EFFECT  —  1 + 1 = 2')
        # Axes
        ox, oy = 60, 35
        chart_w = w - 130
        chart_h = 120
        c.setStrokeColor(DKGREY)
        c.setLineWidth(1.2)
        c.line(ox, oy, ox, oy+chart_h)
        c.line(ox, oy, ox+chart_w, oy)
        # Y label
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 8)
        c.saveState()
        c.translate(ox-22, oy+chart_h/2)
        c.rotate(90)
        c.drawCentredString(0, 0, 'Effect (%)')
        c.restoreState()
        # X ticks
        bars = [
            ('Drug A\nalone', 40, TEAL),
            ('Drug B\nalone', 60, BLUE),
            ('A + B\n(Additive)', 100, GREEN),
        ]
        bar_w = (chart_w - 40) / len(bars)
        for i, (lbl, val, col) in enumerate(bars):
            x = ox + 20 + i * bar_w
            bh_px = val * chart_h / 110
            # bar
            c.setFillColor(col)
            c.roundRect(x, oy, bar_w-10, bh_px, 4, fill=1, stroke=0)
            # value label
            c.setFillColor(col)
            c.setFont('Helvetica-Bold', 10)
            c.drawCentredString(x + (bar_w-10)/2, oy + bh_px + 5, f'{val}%')
            # x label
            c.setFillColor(DKGREY)
            c.setFont('Helvetica', 8)
            for li, ll in enumerate(lbl.split('\n')):
                c.drawCentredString(x + (bar_w-10)/2, oy - 14 - li*10, ll)
        # dashed line at 100%
        c.setStrokeColor(GREEN)
        c.setDash([3,3])
        c.setLineWidth(1)
        c.line(ox, oy + 100*chart_h/110, ox+chart_w, oy + 100*chart_h/110)
        c.setDash([])
        # annotation
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(ox+chart_w+4, oy + 100*chart_h/110 - 3, '= A + B')
        # formula box
        c.setFillColor(GREEN)
        c.roundRect(w-80, h-40, 72, 20, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w-44, h-27, 'E(A+B) = E(A)+E(B)')


# ── 4. Synergism Isobologram ───────────────────────────────────────────────────
class IsobologramDiagram(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 240
    def draw(self):
        c = self.canv
        w, h = self._w, 240
        c.setFillColor(LTEAL)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
        c.setFillColor(TEAL)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'ISOBOLOGRAM — SYNERGISM vs ADDITIVITY vs SUBADDITIVITY')
        # Axes
        ox, oy = 65, 35
        ax_w, ax_h = w - 140, 168
        c.setStrokeColor(DKGREY)
        c.setLineWidth(1.4)
        c.line(ox, oy, ox, oy+ax_h)
        c.line(ox, oy, ox+ax_w, oy)
        # Axis labels
        c.setFillColor(DKGREY)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(ox + ax_w/2, oy - 20, '[Drug A]  →')
        c.saveState()
        c.translate(ox - 30, oy + ax_h/2)
        c.rotate(90)
        c.drawCentredString(0, 0, '[Drug B]  →')
        c.restoreState()
        # EC50 ticks
        c.setFillColor(MDGREY)
        c.setFont('Helvetica', 8)
        c.drawString(ox + ax_w - 6, oy - 14, 'EC₅₀ A')
        c.drawString(ox - 30, oy + ax_h - 6, 'EC₅₀ B')
        # Additive line (straight diagonal)
        c.setStrokeColor(DKGREY)
        c.setLineWidth(2)
        c.line(ox + ax_w, oy, ox, oy + ax_h)
        c.setFillColor(DKGREY)
        c.setFont('Helvetica-Bold', 8.5)
        mid_x = ox + ax_w*0.55
        mid_y = oy + ax_h*0.44
        c.saveState()
        c.translate(mid_x, mid_y)
        c.rotate(math.degrees(math.atan2(ax_h, -ax_w)))
        c.drawCentredString(0, 5, 'Additive (line of additivity)')
        c.restoreState()
        # Synergism curve (bows inward = below additive line)
        c.setStrokeColor(GREEN)
        c.setLineWidth(2.2)
        p = c.beginPath()
        p.moveTo(ox + ax_w, oy)
        p.curveTo(ox + ax_w*0.65, oy + ax_h*0.15,
                  ox + ax_w*0.18, oy + ax_h*0.65,
                  ox, oy + ax_h)
        c.drawPath(p, fill=0, stroke=1)
        # Fill synergism region
        c.setFillColor(GREEN)
        c.setFillAlpha(0.12)
        p2 = c.beginPath()
        p2.moveTo(ox + ax_w, oy)
        p2.curveTo(ox + ax_w*0.65, oy + ax_h*0.15,
                   ox + ax_w*0.18, oy + ax_h*0.65,
                   ox, oy + ax_h)
        p2.lineTo(ox, oy + ax_h)
        p2.lineTo(ox + ax_w, oy)
        p2.close()
        c.drawPath(p2, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Subadditivity curve (bows outward = above additive line)
        c.setStrokeColor(RED)
        c.setLineWidth(2.2)
        p3 = c.beginPath()
        p3.moveTo(ox + ax_w, oy)
        p3.curveTo(ox + ax_w*0.9, oy + ax_h*0.35,
                   ox + ax_w*0.38, oy + ax_h*0.9,
                   ox, oy + ax_h)
        c.drawPath(p3, fill=0, stroke=1)
        c.setFillColor(RED)
        c.setFillAlpha(0.10)
        p4 = c.beginPath()
        p4.moveTo(ox + ax_w, oy)
        p4.curveTo(ox + ax_w*0.9, oy + ax_h*0.35,
                   ox + ax_w*0.38, oy + ax_h*0.9,
                   ox, oy + ax_h)
        p4.lineTo(ox, oy + ax_h)
        p4.lineTo(ox + ax_w, oy)
        p4.close()
        c.drawPath(p4, fill=1, stroke=0)
        c.setFillAlpha(1)
        # Labels
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 9)
        c.drawString(ox + 15, oy + 30, '✓ Positive Synergism')
        c.setFont('Helvetica', 8)
        c.drawString(ox + 15, oy + 19, '(Superadditive)')
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 9)
        c.drawString(ox + ax_w - 95, oy + ax_h - 20, '✗ Negative Synergism')
        c.setFont('Helvetica', 8)
        c.drawString(ox + ax_w - 80, oy + ax_h - 31, '(Subadditive)')
        # Legend formula boxes
        fboxes = [
            (ox, oy + ax_h + 12, 'Synergism: 1+1 > 2', GREEN),
            (ox + ax_w/2 - 40, oy + ax_h + 12, 'Additive: 1+1 = 2', DKGREY),
        ]
        for fx, fy, ft, fc in fboxes:
            c.setFillColor(fc)
            c.roundRect(fx, fy, 130, 16, 3, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 8)
            c.drawCentredString(fx+65, fy+5, ft)


# ── 5. Potentiation Mechanism Diagram ────────────────────────────────────────
class PotentiationDiagram(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 220
    def _box(self, c, x, y, w, h, text, bg, fg=WHITE, fs=9, r=6):
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, r, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', fs)
        lines = textwrap.wrap(text, width=max(int(w/5.3),6))
        total = len(lines)*(fs+2)
        sy = y+h/2+total/2-fs
        for i,ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy-i*(fs+2), ln)
    def _arrow(self, c, x1, y1, x2, y2, color=MDGREY, label='', lw=1.5):
        angle = math.atan2(y2-y1, x2-x1)
        c.setStrokeColor(color)
        c.setLineWidth(lw)
        c.line(x1, y1, x2, y2)
        arr=8; ang=0.4
        c.setFillColor(color)
        p = c.beginPath()
        p.moveTo(x2, y2)
        p.lineTo(x2-arr*math.cos(angle-ang), y2-arr*math.sin(angle-ang))
        p.lineTo(x2-arr*math.cos(angle+ang), y2-arr*math.sin(angle+ang))
        p.close()
        c.drawPath(p, fill=1, stroke=0)
        if label:
            mx,my = (x1+x2)/2, (y1+y2)/2
            c.setFillColor(color)
            c.setFont('Helvetica-Bold', 7.5)
            c.drawCentredString(mx, my+5, label)
    def draw(self):
        c = self.canv
        w, h = self._w, 220
        c.setFillColor(LORANGE)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
        c.setFillColor(ORANGE)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'POTENTIATION MECHANISM  —  0 + 1 = 3')
        # Example: Probenecid + Penicillin
        # Row 1: Without Probenecid
        y1 = h - 55
        self._box(c, 10, y1, 100, 30, 'Penicillin (alone)', BLUE, fs=9)
        self._arrow(c, 110, y1+15, 190, y1+15, BLUE, 'plasma')
        self._box(c, 190, y1, 90, 30, 'Kidney\nTubular Secretion', CRIMSON, fs=8)
        self._arrow(c, 280, y1+15, 340, y1+15, CRIMSON, 'excreted')
        self._box(c, 340, y1, 80, 30, 'Short t½\nLow levels', CRIMSON, fs=8)
        # Label
        c.setFillColor(BLUE)
        c.setFont('Helvetica-Bold', 8.5)
        c.drawString(10, y1+34, 'WITHOUT PROBENECID:')
        # Row 2: With Probenecid
        y2 = h - 120
        self._box(c, 10, y2, 100, 30, 'Penicillin\n+ Probenecid', ORANGE, fs=9)
        self._arrow(c, 110, y2+15, 190, y2+15, ORANGE, 'plasma')
        self._box(c, 190, y2, 90, 30, 'Kidney\nTubular Secretion', HexColor('#5D4037'), fs=8)
        # BLOCKED arrow
        c.setStrokeColor(RED)
        c.setLineWidth(2.5)
        c.line(280, y2+5, 310, y2+25)
        c.line(280, y2+25, 310, y2+5)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(295, y2-8, 'BLOCKED')
        self._box(c, 340, y2, 80, 30, 'Prolonged t½\n↑ Plasma levels', GREEN, fs=8)
        c.setFillColor(ORANGE)
        c.setFont('Helvetica-Bold', 8.5)
        c.drawString(10, y2+34, 'WITH PROBENECID (Potentiator):')
        # Result box
        c.setFillColor(GREEN)
        c.roundRect(10, 10, w-20, 28, 6, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 9.5)
        c.drawCentredString(w/2, 22,
            'Probenecid has NO antibacterial activity but POTENTIATES penicillin by blocking renal tubular secretion')


# ── 6. Antagonism Type Diagrams ───────────────────────────────────────────────
class AntagonismDiagram(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 310
    def _receptor(self, c, cx, cy, r=20, color=TEAL, label='R'):
        c.setFillColor(color)
        c.circle(cx, cy, r, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(cx, cy-4, label)
    def _arrow(self, c, x1, y1, x2, y2, color=DKGREY, lw=1.5, dash=None):
        if dash:
            c.setDash(dash)
        c.setStrokeColor(color)
        c.setLineWidth(lw)
        c.line(x1, y1, x2, y2)
        c.setDash([])
        angle = math.atan2(y2-y1, x2-x1)
        arr=7; ang=0.4
        c.setFillColor(color)
        p = c.beginPath()
        p.moveTo(x2, y2)
        p.lineTo(x2-arr*math.cos(angle-ang), y2-arr*math.sin(angle-ang))
        p.lineTo(x2-arr*math.cos(angle+ang), y2-arr*math.sin(angle+ang))
        p.close()
        c.drawPath(p, fill=1, stroke=0)
    def _cross(self, c, cx, cy, size=8):
        c.setStrokeColor(RED)
        c.setLineWidth(2.5)
        c.line(cx-size, cy-size, cx+size, cy+size)
        c.line(cx-size, cy+size, cx+size, cy-size)
    def draw(self):
        c = self.canv
        w, h = self._w, 310
        c.setFillColor(LRED)
        c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'TYPES OF ANTAGONISM')
        # ── (A) Competitive ───────────────────────────────────────────
        panel_w = w/2 - 15
        # Panel A
        c.setFillColor(WHITE)
        c.roundRect(8, h-160, panel_w, 130, 7, fill=1, stroke=0)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 9.5)
        c.drawString(18, h-44, 'A) COMPETITIVE ANTAGONISM')
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 8)
        c.drawString(18, h-56, '(Reversible / Surmountable)')
        # Receptor
        rx, ry = 80, h-110
        self._receptor(c, rx, ry, r=18, color=TEAL, label='R')
        # Agonist molecule
        c.setFillColor(BLUE)
        c.roundRect(rx-10, ry+30, 20, 14, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 7)
        c.drawCentredString(rx, ry+38, 'AG')
        # Antagonist competing
        c.setFillColor(RED)
        c.roundRect(rx+25, ry+30, 20, 14, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.drawCentredString(rx+35, ry+38, 'ANT')
        # Arrows competing
        self._arrow(c, rx, ry+30, rx, ry+18, BLUE)
        self._arrow(c, rx+35, ry+30, rx+18, ry+18, RED, dash=[2,2])
        # Label
        c.setFillColor(BLUE)
        c.setFont('Helvetica', 7.5)
        c.drawString(rx-18, ry+46, 'Agonist')
        c.setFillColor(RED)
        c.drawString(rx+22, ry+46, 'Antagonist')
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 7.5)
        c.drawString(18, h-130, '↑ Agonist dose → overcomes')
        c.drawString(18, h-141, 'Ex: Naloxone vs Morphine')
        # Panel B - Non-competitive
        c.setFillColor(WHITE)
        c.roundRect(w/2+7, h-160, panel_w, 130, 7, fill=1, stroke=0)
        c.setFillColor(CRIMSON)
        c.setFont('Helvetica-Bold', 9.5)
        c.drawString(w/2+17, h-44, 'B) NON-COMPETITIVE')
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 8)
        c.drawString(w/2+17, h-56, '(Irreversible / Insurmountable)')
        rx2 = w/2 + 80
        self._receptor(c, rx2, ry, r=18, color=PURPLE, label='R')
        # Agonist bound
        c.setFillColor(BLUE)
        c.roundRect(rx2-10, ry+30, 20, 14, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 7)
        c.drawCentredString(rx2, ry+38, 'AG')
        self._arrow(c, rx2, ry+30, rx2, ry+18, BLUE)
        # Allosteric site
        c.setFillColor(CRIMSON)
        c.circle(rx2+18, ry, 10, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 6.5)
        c.drawCentredString(rx2+18, ry-3, 'ANT\n(allost)')
        # Cross on effect
        c.setFillColor(DKGREY)
        c.roundRect(rx2-12, ry-35, 24, 14, 3, fill=1, stroke=0)
        self._cross(c, rx2, ry-28, 5)
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 7.5)
        c.drawString(w/2+17, h-130, '↑ Agonist dose CANNOT overcome')
        c.drawString(w/2+17, h-141, 'Ex: Phenoxybenzamine vs NA')
        # ── (C) Physiological ─────────────────────────────────────────
        c.setFillColor(WHITE)
        c.roundRect(8, 10, w/2-15, 120, 7, fill=1, stroke=0)
        c.setFillColor(BLUE)
        c.setFont('Helvetica-Bold', 9.5)
        c.drawString(18, 118, 'C) PHYSIOLOGICAL ANTAGONISM')
        # Two receptors with opposing effects
        r1x, r1y = 70, 80
        r2x, r2y = 160, 80
        self._receptor(c, r1x, r1y, r=15, color=TEAL, label='α')
        self._receptor(c, r2x, r2y, r=15, color=RED, label='H')
        # Adrenaline
        c.setFillColor(TEAL)
        c.roundRect(r1x-12, r1y+22, 24, 14, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 7)
        c.drawCentredString(r1x, r1y+30, 'Adr')
        self._arrow(c, r1x, r1y+22, r1x, r1y+15, TEAL)
        # Histamine
        c.setFillColor(RED)
        c.roundRect(r2x-12, r2y+22, 24, 14, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 7)
        c.drawCentredString(r2x, r2y+30, 'Hist')
        self._arrow(c, r2x, r2y+22, r2x, r2y+15, RED)
        # BP arrows
        c.setFillColor(TEAL)
        c.setFont('Helvetica-Bold', 9)
        c.drawString(r1x-12, r1y-28, '↑ BP / ↑ HR')
        c.setFillColor(RED)
        c.drawString(r2x-12, r2y-28, '↓ BP / bronchosp.')
        # Balance
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 8)
        c.drawCentredString((r1x+r2x)/2, 14, '= Balance (Anaphylaxis Rx)')
        # (D) Chemical
        c.setFillColor(WHITE)
        c.roundRect(w/2+7, 10, panel_w, 120, 7, fill=1, stroke=0)
        c.setFillColor(GOLD)
        c.setFont('Helvetica-Bold', 9.5)
        c.drawString(w/2+17, 118, 'D) CHEMICAL ANTAGONISM')
        # Protamine + Heparin
        cx1, cx2 = w/2+50, w/2+120
        cy0 = 75
        c.setFillColor(BLUE)
        c.roundRect(cx1-22, cy0, 44, 24, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 8)
        c.drawCentredString(cx1, cy0+12, 'Heparin (–)')
        c.setFillColor(ORANGE)
        c.roundRect(cx2-22, cy0, 44, 24, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.drawCentredString(cx2, cy0+12, 'Protamine (+)')
        # Arrow toward complex
        midx = (cx1+22+cx2-22)/2
        self._arrow(c, cx1+22, cy0+12, midx-5, cy0+12, BLUE)
        self._arrow(c, cx2-22, cy0+12, midx+5, cy0+12, ORANGE)
        # Complex
        c.setFillColor(PURPLE)
        c.roundRect(midx-25, cy0-30, 50, 24, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica', 7.5)
        c.drawCentredString(midx, cy0-18, 'Inactive\nComplex')
        c.setFillColor(DKGREY)
        c.setFont('Helvetica', 8)
        c.drawString(w/2+17, 14, 'Direct inactivation outside receptors')


# ── 7. CYP450 Interaction Diagram ─────────────────────────────────────────────
class CYPDiagram(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 260
    def _arrow(self, c, x1,y1,x2,y2, color=DKGREY, lw=1.5, label='', cross=False):
        angle = math.atan2(y2-y1, x2-x1)
        c.setStrokeColor(color)
        c.setLineWidth(lw)
        c.line(x1,y1,x2,y2)
        arr=8; ang=0.4
        c.setFillColor(color)
        p = c.beginPath()
        p.moveTo(x2,y2)
        p.lineTo(x2-arr*math.cos(angle-ang), y2-arr*math.sin(angle-ang))
        p.lineTo(x2-arr*math.cos(angle+ang), y2-arr*math.sin(angle+ang))
        p.close()
        c.drawPath(p, fill=1, stroke=0)
        if label:
            mx,my=(x1+x2)/2,(y1+y2)/2
            c.setFillColor(color)
            c.setFont('Helvetica-Bold',7.5)
            c.drawCentredString(mx, my+5, label)
        if cross:
            mx,my=(x1+x2)/2,(y1+y2)/2
            c.setStrokeColor(RED)
            c.setLineWidth(2)
            c.line(mx-6, my-6, mx+6, my+6)
            c.line(mx-6, my+6, mx+6, my-6)
    def _box(self, c, x,y,w,h, text, bg, fg=WHITE, fs=9, r=6):
        c.setFillColor(bg)
        c.roundRect(x,y,w,h,r, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', fs)
        lines = textwrap.wrap(text, width=max(int(w/5.3),6))
        total=len(lines)*(fs+2)
        sy=y+h/2+total/2-fs
        for i,ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy-i*(fs+2), ln)
    def draw(self):
        c = self.canv
        w, h = self._w, 260
        c.setFillColor(LBLUE)
        c.roundRect(0,0,w,h,10, fill=1, stroke=0)
        c.setFillColor(BLUE)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'CYP450-MEDIATED PHARMACOKINETIC DRUG INTERACTIONS')
        # ── Left panel: Inhibition ──────────────────────────────
        px = 10
        c.setFillColor(WHITE)
        c.roundRect(px, 10, w/2-20, h-35, 7, fill=1, stroke=0)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 10)
        c.drawCentredString(px + (w/2-20)/2, h-38, 'CYP INHIBITION  (↑ Drug Levels)')
        # Flow
        y_flow = h - 80
        self._box(c, px+10, y_flow, 80, 28, 'Drug A\n(substrate)', BLUE, fs=8)
        self._box(c, px+110, y_flow, 80, 28, 'CYP450\nInhibited', RED, fs=8)
        self._box(c, px+210, y_flow-10, 80, 48, '↑ Drug A\nPlasma Levels\n= TOXICITY', RED, fs=8)
        self._arrow(c, px+90, y_flow+14, px+110, y_flow+14, BLUE)
        self._arrow(c, px+190, y_flow+14, px+210, y_flow+24, RED, cross=False)
        # Inhibitor drug
        c.setFillColor(CRIMSON)
        c.roundRect(px+100, y_flow-35, 100, 24, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8)
        c.drawCentredString(px+150, y_flow-20, 'Drug B (Inhibitor)')
        self._arrow(c, px+150, y_flow-11, px+150, y_flow, CRIMSON)
        # Examples
        c.setFillColor(DKGREY)
        c.setFont('Helvetica-Bold', 8)
        c.drawString(px+10, y_flow-50, 'Common CYP3A4 Inhibitors:')
        examples = [
            'Ketoconazole, Erythromycin',
            'Grapefruit juice, Ritonavir',
            'Ciprofloxacin (CYP1A2)',
            '→ Raise statin, warfarin, cyclosporin levels',
        ]
        c.setFont('Helvetica', 7.5)
        for i, ex in enumerate(examples):
            c.drawString(px+10, y_flow-63 - i*11, '• '+ex)
        # ── Right panel: Induction ─────────────────────────────
        px2 = w/2 + 10
        c.setFillColor(WHITE)
        c.roundRect(px2, 10, w/2-20, h-35, 7, fill=1, stroke=0)
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 10)
        c.drawCentredString(px2 + (w/2-20)/2, h-38, 'CYP INDUCTION  (↓ Drug Levels)')
        self._box(c, px2+10, y_flow, 80, 28, 'Drug A\n(substrate)', BLUE, fs=8)
        self._box(c, px2+110, y_flow, 80, 28, 'CYP450\nUp-regulated', GREEN, fs=8)
        self._box(c, px2+210, y_flow-10, 80, 48, '↓ Drug A\nPlasma Levels\n= FAILURE', ORANGE, fs=8)
        self._arrow(c, px2+90, y_flow+14, px2+110, y_flow+14, BLUE)
        self._arrow(c, px2+190, y_flow+14, px2+210, y_flow+24, GREEN)
        c.setFillColor(GREEN)
        c.roundRect(px2+100, y_flow-35, 100, 24, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8)
        c.drawCentredString(px2+150, y_flow-20, 'Drug B (Inducer)')
        self._arrow(c, px2+150, y_flow-11, px2+150, y_flow, GREEN)
        c.setFillColor(DKGREY)
        c.setFont('Helvetica-Bold', 8)
        c.drawString(px2+10, y_flow-50, 'Common CYP3A4 Inducers:')
        examples2 = [
            'Rifampicin (strongest inducer)',
            'Carbamazepine, Phenytoin',
            'St. John\'s Wort, Barbiturates',
            '→ ↓ OCP, warfarin, HIV drugs',
        ]
        c.setFont('Helvetica', 7.5)
        for i, ex in enumerate(examples2):
            c.drawString(px2+10, y_flow-63 - i*11, '• '+ex)


# ── 8. Pharmacokinetic interaction overview flowchart ─────────────────────────
class PKFlowchart(Flowable):
    def __init__(self):
        super().__init__()
    def wrap(self, aW, aH):
        self._w = aW
        return aW, 200
    def _box(self, c, x,y,w,h, text, bg, fg=WHITE, fs=8.5, r=5):
        c.setFillColor(bg)
        c.roundRect(x,y,w,h,r, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', fs)
        lines = textwrap.wrap(text, width=max(int(w/5),6))
        total=len(lines)*(fs+1.5)
        sy=y+h/2+total/2-fs
        for i,ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy-i*(fs+1.5), ln)
    def _arrow(self, c, x1,y1,x2,y2, color=MDGREY, lw=1.4):
        angle=math.atan2(y2-y1,x2-x1)
        c.setStrokeColor(color); c.setLineWidth(lw); c.line(x1,y1,x2,y2)
        arr=7; ang=0.4; c.setFillColor(color)
        p=c.beginPath(); p.moveTo(x2,y2)
        p.lineTo(x2-arr*math.cos(angle-ang), y2-arr*math.sin(angle-ang))
        p.lineTo(x2-arr*math.cos(angle+ang), y2-arr*math.sin(angle+ang))
        p.close(); c.drawPath(p, fill=1, stroke=0)
    def draw(self):
        c = self.canv
        w, h = self._w, 200
        c.setFillColor(LGREY)
        c.roundRect(0,0,w,h,10, fill=1, stroke=0)
        c.setFillColor(NAVY)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(w/2, h-18, 'PHARMACOKINETIC DRUG INTERACTION SITES (ADME)')
        # ADME horizontal row
        stages = [
            ('ABSORPTION', TEAL,   ['Chelation (Antacid+Tetracycline)',
                                     'pH change (antacids)',
                                     'P-gp (efflux, e.g. digoxin)']),
            ('DISTRIBUTION', BLUE,  ['Protein binding displacement',
                                     'Warfarin displaced by sulfonamide',
                                     'Volume of distribution changes']),
            ('METABOLISM', RED,     ['CYP induction / inhibition',
                                     'Rifampicin (induces CYP3A4)',
                                     'Ketoconazole (inhibits CYP3A4)']),
            ('EXCRETION', PURPLE,   ['Tubular secretion block',
                                     'Probenecid blocks penicillin',
                                     'Lithium + NSAIDs: ↑Li levels']),
        ]
        box_w = (w - 20) / 4
        box_h = 32
        top_y = h - 52
        for i, (stage, col, notes) in enumerate(stages):
            bx = 10 + i * box_w
            self._box(c, bx+2, top_y, box_w-6, box_h, stage, col, fs=9)
            # Connect with arrows
            if i < 3:
                self._arrow(c, bx+box_w-4, top_y+16, bx+box_w+4, top_y+16, MDGREY)
            # Sub notes
            c.setFillColor(DKGREY)
            c.setFont('Helvetica', 7.5)
            for ni, note_txt in enumerate(notes):
                c.drawString(bx+4, top_y-18-ni*11, '• '+note_txt)
        # Drug molecule journey label
        c.setFillColor(ORANGE)
        c.roundRect(10, 10, w-20, 18, 4, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8.5)
        c.drawCentredString(w/2, 17, 'Drug molecule travels through all four ADME stages — interaction can occur at ANY stage')


# ════════════════════════════════════════════════════════════════════════════
# BUILD PDF
# ════════════════════════════════════════════════════════════════════════════
output = '/tmp/workspace/drug-interactions-pdf/Drug_Interactions_Study_Guide.pdf'
doc = SimpleDocTemplate(output, pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=MARGIN, bottomMargin=MARGIN,
    title='Drug Interactions Study Guide',
    author='Pharmacology Study Guide')

story = []
W = CONTENT_W

# ── PAGE 1: Title + Definition + Mind Map ─────────────────────────────────────
story.append(TitlePage())
story.append(spacer(14))

story.append(banner('1. DEFINITION OF DRUG INTERACTION', color=NAVY))
story.append(spacer(6))
story.append(Paragraph(
    'A <b>drug interaction</b> occurs when the pharmacological effect of one drug is altered '
    '(enhanced, diminished, or qualitatively changed) by the concurrent or sequential '
    'administration of another drug, food, herb, or endogenous substance. '
    'Drug interactions are clinically significant when they alter <b>efficacy</b> or cause <b>toxicity</b>, '
    'particularly with drugs of <b>narrow therapeutic index</b> (warfarin, digoxin, lithium, phenytoin, aminoglycosides).',
    body))
story.append(spacer(6))

story.append(sub_banner('Classification of Drug Interactions', TEAL))
story.append(spacer(6))
story.append(DefinitionMindMap())
story.append(spacer(4))
story.append(Paragraph(
    '<b>Pharmacodynamic interactions</b> alter the response at the receptor/effector level without '
    'changing drug concentrations. <b>Pharmacokinetic interactions</b> alter Absorption, Distribution, '
    'Metabolism, or Excretion (ADME), changing plasma drug levels. <b>Pharmaceutical incompatibility</b> '
    'refers to chemical or physical changes before drug reaches the body (e.g., precipitation in IV lines).',
    body))

# ── PAGE 2: Additive Effect ────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('2. ADDITIVE EFFECT', color=GREEN))
story.append(spacer(6))
story.append(Paragraph(
    'When two drugs that act on the <b>same receptor or biological system</b> are combined, '
    'their effects simply sum together arithmetically. Neither drug alters the sensitivity '
    'of the target to the other.', body))
story.append(spacer(4))

# Formula highlight
formula_data = [
    [Paragraph('<b>Formula</b>', th),
     Paragraph('<b>Expression</b>', th),
     Paragraph('<b>Meaning</b>', th)],
    [Paragraph('E(A+B) = E(A) + E(B)', tdB),
     Paragraph('1 + 1 = 2', tdB),
     Paragraph('The total effect equals the sum of each drug\'s individual effect', td)],
]
story.append(tbl(formula_data, [130, 80, W-230], hdr_color=GREEN))
story.append(spacer(8))
story.append(AdditiveBarChart())
story.append(spacer(8))

story.append(sub_banner('Additive Effect Examples', GREEN))
story.append(spacer(5))
additive_ex = [
    [Paragraph('<b>Drug A</b>', th),
     Paragraph('<b>Drug B</b>', th),
     Paragraph('<b>Combined Additive Effect</b>', th),
     Paragraph('<b>Clinical Concern</b>', th)],
    [Paragraph('Aspirin', td), Paragraph('Paracetamol', td),
     Paragraph('Additive analgesia', td), Paragraph('Useful - allows dose reduction of each', td)],
    [Paragraph('Aspirin', td), Paragraph('Ibuprofen', td),
     Paragraph('Additive GI mucosal damage', td), Paragraph('Avoid combination - peptic ulcer risk', td)],
    [Paragraph('Alcohol', td), Paragraph('Diazepam', td),
     Paragraph('Additive CNS depression', td), Paragraph('Dangerous - respiratory depression risk', td)],
    [Paragraph('Thiazide diuretic', td), Paragraph('Loop diuretic', td),
     Paragraph('Additive diuresis', td), Paragraph('Sequential nephron blockade; used in resistant oedema', td)],
    [Paragraph('Aminoglycoside', td), Paragraph('Amphotericin B', td),
     Paragraph('Additive nephrotoxicity', td), Paragraph('High risk of acute kidney injury', td)],
    [Paragraph('Two antihypertensives', td), Paragraph('(same class)', td),
     Paragraph('Additive hypotension', td), Paragraph('Dose titration needed', td)],
]
story.append(tbl(additive_ex, [95, 95, 130, W-340], hdr_color=GREEN, alt=[WHITE, LGREEN]))
story.append(spacer(6))
story.append(Paragraph(
    '<b>Key Point:</b> Additive interactions are exploited clinically to achieve efficacy at lower individual doses, '
    'reducing side effects. However, additive <i>toxicity</i> is a major cause of adverse drug reactions.',
    note))

# ── PAGE 3: Synergism ──────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('3. SYNERGISM (SUPRA-ADDITIVE EFFECT)', color=TEAL))
story.append(spacer(6))
story.append(Paragraph(
    'Synergism occurs when two drugs produce a combined effect that is <b>greater than the '
    'arithmetic sum</b> of their individual effects. This happens because the drugs act at '
    '<b>different sites or different mechanisms</b> but converge on the same physiological outcome.',
    body))
story.append(spacer(4))
formula2 = [
    [Paragraph('<b>Formula</b>', th), Paragraph('<b>Expression</b>', th), Paragraph('<b>Also called</b>', th)],
    [Paragraph('E(A+B) > E(A) + E(B)', tdB), Paragraph('1 + 1 > 2', tdB),
     Paragraph('Positive synergism / Superadditivity / Supra-additive effect', td)],
]
story.append(tbl(formula2, [130, 80, W-230], hdr_color=TEAL))
story.append(spacer(8))
story.append(IsobologramDiagram())
story.append(spacer(4))
story.append(Paragraph(
    'The <b>isobologram</b> (above) is the graphical tool used to detect synergism. The straight diagonal '
    'line joining EC₅₀-A and EC₅₀-B represents additivity. Combinations producing a 50% effect that fall '
    '<b>below this line</b> (i.e., require less of each drug than expected) indicate positive synergism. '
    'Combinations <b>above the line</b> are subadditive.',
    caption))
story.append(spacer(8))
story.append(sub_banner('Types of Synergism', TEAL))
story.append(spacer(5))
syn_types = [
    [Paragraph('<b>Type</b>', th),
     Paragraph('<b>Mechanism</b>', th),
     Paragraph('<b>Example</b>', th),
     Paragraph('<b>Clinical Use</b>', th)],
    [Paragraph('Bactericidal Synergism', tdB),
     Paragraph('Each drug alone is bacteriostatic; combination is bactericidal', td),
     Paragraph('Penicillin + Aminoglycoside', td),
     Paragraph('Enterococcal endocarditis, serious gram-positive infections', td)],
    [Paragraph('Sequential Block Synergism', tdB),
     Paragraph('Two drugs block consecutive steps in same metabolic pathway', td),
     Paragraph('Trimethoprim + Sulfamethoxazole (Co-trimoxazole)', td),
     Paragraph('UTIs, PCP, toxoplasmosis; 20-100× greater activity', td)],
    [Paragraph('Receptor-Effector Synergism', tdB),
     Paragraph('Drugs act at different receptor subtypes converging on same effect', td),
     Paragraph('Morphine + Ketamine (pain control)', td),
     Paragraph('Post-operative analgesia; allows opioid dose reduction', td)],
    [Paragraph('Pharmacokinetic Synergism', tdB),
     Paragraph('One drug increases bioavailability/distribution of another', td),
     Paragraph('Levodopa + Carbidopa', td),
     Paragraph('Carbidopa blocks peripheral decarboxylation → more levodopa reaches brain', td)],
    [Paragraph('Enzyme Protection Synergism', tdB),
     Paragraph('One drug protects the other from enzymatic destruction', td),
     Paragraph('Amoxicillin + Clavulanate', td),
     Paragraph('Clavulanate inhibits β-lactamase → protects amoxicillin', td)],
]
story.append(tbl(syn_types, [100, 130, 110, W-360], hdr_color=TEAL, alt=[WHITE, LTEAL]))

# ── PAGE 4: Potentiation ───────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('4. POTENTIATION', color=ORANGE))
story.append(spacer(6))
story.append(Paragraph(
    'Potentiation occurs when a drug that has <b>NO activity of its own</b> on a particular '
    'biological system <b>increases the effect</b> of another drug that does have activity on '
    'that system. This is the key distinction from synergism, where both drugs must be active.',
    body))
story.append(spacer(4))

formula3 = [
    [Paragraph('<b>Formula</b>', th), Paragraph('<b>Expression</b>', th), Paragraph('<b>Key Distinction</b>', th)],
    [Paragraph('E(potentiator alone) = 0\nE(A + potentiator) >> E(A)', tdB),
     Paragraph('0 + 1 = 3', tdB),
     Paragraph('One drug is INACTIVE on the target system; still amplifies the other drug\'s effect', td)],
]
story.append(tbl(formula3, [150, 70, W-240], hdr_color=ORANGE))
story.append(spacer(8))
story.append(PotentiationDiagram())
story.append(spacer(8))

story.append(sub_banner('Potentiation Examples', ORANGE))
story.append(spacer(5))
pot_ex = [
    [Paragraph('<b>Potentiator</b>', th),
     Paragraph('<b>Active Drug</b>', th),
     Paragraph('<b>Mechanism of Potentiation</b>', th),
     Paragraph('<b>Clinical Use</b>', th)],
    [Paragraph('Probenecid\n(no antibacterial activity)', td),
     Paragraph('Penicillin', td),
     Paragraph('Blocks OAT (organic anion transporter) in renal tubules → reduces penicillin excretion → prolongs t½', td),
     Paragraph('Historically used to extend penicillin action; still used with cephalosporins in gonorrhoea', td)],
    [Paragraph('Clavulanate\n(no direct antibacterial effect)', td),
     Paragraph('Amoxicillin', td),
     Paragraph('Irreversibly inhibits β-lactamase → protects amoxicillin from destruction', td),
     Paragraph('Augmentin - broadens spectrum against β-lactamase producers', td)],
    [Paragraph('Carbidopa / Benserazide\n(no antiparkinsonian effect alone)', td),
     Paragraph('Levodopa', td),
     Paragraph('Peripheral DOPA decarboxylase inhibitor → prevents conversion of L-DOPA to dopamine outside CNS', td),
     Paragraph('Sinemet / Madopar - allows 75-80% dose reduction of levodopa', td)],
    [Paragraph('CYP inhibitor\n(e.g. Ketoconazole)', td),
     Paragraph('Statins / Protease inhibitors (CYP3A4 substrates)', td),
     Paragraph('Inhibits CYP3A4 → reduces first-pass and systemic metabolism of co-administered drug', td),
     Paragraph('DANGEROUS: raises statin levels (myopathy/rhabdomyolysis)', td)],
    [Paragraph('Sulfonamide\n(anti-infective)', td),
     Paragraph('Warfarin', td),
     Paragraph('(1) Inhibits CYP2C9 → ↓ warfarin metabolism. (2) Displaces warfarin from albumin binding', td),
     Paragraph('DANGEROUS: major bleeding risk; monitor INR closely or avoid', td)],
    [Paragraph('Dantrolene\n(no NMJ blocking effect)', td),
     Paragraph('Neuromuscular blockers', td),
     Paragraph('Prevents Ca²⁺ release from SR → depresses muscle contraction → potentiates NMB-induced paralysis', td),
     Paragraph('Relevance in anaesthesia; used in malignant hyperthermia treatment', td)],
]
story.append(tbl(pot_ex, [110, 90, 150, W-370], hdr_color=ORANGE, alt=[WHITE, LORANGE]))

# ── PAGE 5: Antagonism ─────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('5. ANTAGONISM', color=RED))
story.append(spacer(6))
story.append(Paragraph(
    'Antagonism occurs when one drug <b>reduces or abolishes the effect</b> of another. '
    'The combined effect is less than that of either drug alone. Antagonism is classified '
    'by <b>mechanism</b> into four main types.',
    body))
story.append(spacer(6))
formula4 = [
    [Paragraph('<b>Formula</b>', th), Paragraph('<b>Expression</b>', th)],
    [Paragraph('E(A+B) < E(A)  or  E(A+B) < E(B)', tdB),
     Paragraph('1 + 1 < 2  or  even  1 + 1 = 0', tdB)],
]
story.append(tbl(formula4, [200, W-220], hdr_color=RED))
story.append(spacer(8))
story.append(AntagonismDiagram())
story.append(spacer(8))

story.append(sub_banner('Detailed Classification of Antagonism', RED))
story.append(spacer(5))
ant_data = [
    [Paragraph('<b>Type</b>', th),
     Paragraph('<b>Sub-type</b>', th),
     Paragraph('<b>Mechanism</b>', th),
     Paragraph('<b>Reversibility</b>', th),
     Paragraph('<b>Example</b>', th)],
    [Paragraph('Pharmacological\n(Receptor)\nAntagonism', tdB),
     Paragraph('Competitive\n(Surmountable)', td),
     Paragraph('Antagonist reversibly occupies same active site as agonist; ↑ agonist dose overcomes block; dose-response curve shifts RIGHT (parallel shift); Emax unchanged', td),
     Paragraph('Reversible', td),
     Paragraph('Naloxone vs Morphine\nAtropine vs ACh\nBeta-blockers vs Adrenaline\nAntihistamines vs Histamine', td)],
    [Paragraph('', tdB),
     Paragraph('Non-competitive\n(Insurmountable)', td),
     Paragraph('Antagonist binds irreversibly to receptor or allosteric site; increasing agonist dose CANNOT restore Emax; dose-response curve shifts RIGHT + Emax DEPRESSED', td),
     Paragraph('Irreversible', td),
     Paragraph('Phenoxybenzamine (α-blocker) vs NA\nAspirin (irreversible COX inhibition)\nOrganophosphate vs AChE', td)],
    [Paragraph('Physiological\n(Functional)\nAntagonism', tdB),
     Paragraph('Functional\nOpposition', td),
     Paragraph('Two drugs produce OPPOSITE effects on the same physiological endpoint by acting at DIFFERENT receptors or through entirely different mechanisms; effects cancel', td),
     Paragraph('Reversible', td),
     Paragraph('Adrenaline (↑BP, bronchodilation) vs Histamine (↓BP, bronchoconstriction)\nGlucagon vs Insulin (blood glucose)\nHeparin vs Protamine (anticoagulation)', td)],
    [Paragraph('Chemical\nAntagonism', tdB),
     Paragraph('Direct\nInactivation', td),
     Paragraph('The two drugs interact CHEMICALLY outside the receptor, forming an inactive complex; this occurs in plasma, GIT, or at injection site', td),
     Paragraph('Usually\nirreversible', td),
     Paragraph('Protamine + Heparin (ionic complex)\nDimercaprol + Heavy metals (chelation)\nActivated charcoal (adsorption)\nEdrophonium antidote for tubocurarine', td)],
    [Paragraph('Pharmacokinetic\nAntagonism', tdB),
     Paragraph('Altered\nPharmacokinetics', td),
     Paragraph('One drug accelerates elimination or reduces absorption of another without directly interacting at receptor; reduces plasma levels of the target drug', td),
     Paragraph('Reversible', td),
     Paragraph('Rifampicin induces CYP3A4 → ↓ OCP / warfarin levels\nCholestyramine binds digoxin/warfarin in gut\nAntacids chelate tetracyclines/quinolones', td)],
    [Paragraph('Partial Agonist\nAntagonism', tdB),
     Paragraph('Competitive\nPartial Agonism', td),
     Paragraph('Partial agonist competes with full agonist; reduces the overall effect by replacing a high-efficacy agonist with a low-efficacy partial agonist at the same receptor', td),
     Paragraph('Reversible', td),
     Paragraph('Buprenorphine (partial opioid agonist) displaces morphine → precipitates withdrawal in opioid-dependent patients', td)],
]
story.append(tbl(ant_data, [80, 80, 175, 65, W-420], hdr_color=RED, alt=[WHITE, LRED]))

# ── PAGE 6: PK Interactions ────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('6. PHARMACOKINETIC DRUG INTERACTIONS', color=BLUE))
story.append(spacer(6))
story.append(Paragraph(
    'Pharmacokinetic interactions alter the <b>plasma concentration</b> of a drug by modifying one '
    'or more stages of ADME without any direct receptor-level action. The resulting '
    'change in drug concentration then leads to changed pharmacodynamic effects.',
    body))
story.append(spacer(8))
story.append(PKFlowchart())
story.append(spacer(8))
story.append(CYPDiagram())
story.append(spacer(8))

story.append(sub_banner('Key CYP450 Drug Interactions Table', BLUE))
story.append(spacer(5))
cyp_data = [
    [Paragraph('<b>CYP Enzyme</b>', th),
     Paragraph('<b>Important Inducers</b>', th),
     Paragraph('<b>Important Inhibitors</b>', th),
     Paragraph('<b>Key Substrates (drugs affected)</b>', th)],
    [Paragraph('CYP3A4\n(~50% of drugs)', tdB),
     Paragraph('Rifampicin, Carbamazepine, Phenytoin, St. John\'s Wort, Barbiturates', td),
     Paragraph('Ketoconazole, Erythromycin, Clarithromycin, Ritonavir, Grapefruit juice', td),
     Paragraph('Statins, Cyclosporin, Tacrolimus, Midazolam, Sildenafil, Protease inhibitors, OCP, many antihistamines', td)],
    [Paragraph('CYP2C9', tdB),
     Paragraph('Rifampicin, Carbamazepine', td),
     Paragraph('Fluconazole, Amiodarone, Sulfonamides, Metronidazole', td),
     Paragraph('Warfarin (S-enantiomer), Phenytoin, NSAIDs, Glibenclamide, Losartan', td)],
    [Paragraph('CYP2C19', tdB),
     Paragraph('Rifampicin, Carbamazepine', td),
     Paragraph('Omeprazole, Fluconazole, Fluvoxamine', td),
     Paragraph('Clopidogrel (prodrug - reduced activation), PPIs, TCAs, some SSRIs', td)],
    [Paragraph('CYP2D6', tdB),
     Paragraph('(Rarely induced)', td),
     Paragraph('Fluoxetine, Paroxetine, Haloperidol, Quinidine, Amiodarone', td),
     Paragraph('Codeine (prodrug→morphine), Tramadol, TCAs, Beta-blockers, Tamoxifen, Antipsychotics', td)],
    [Paragraph('CYP1A2', tdB),
     Paragraph('Smoking, Omeprazole, Rifampicin, Cruciferous vegetables', td),
     Paragraph('Ciprofloxacin, Fluvoxamine, Amiodarone', td),
     Paragraph('Theophylline, Clozapine, Olanzapine, Warfarin (R-enantiomer), Caffeine', td)],
]
story.append(tbl(cyp_data, [75, 110, 110, W-315], hdr_color=BLUE, alt=[WHITE, LBLUE]))

# ── PAGE 7: High-Yield Clinical Examples ──────────────────────────────────────
story.append(PageBreak())
story.append(banner('7. HIGH-YIELD CLINICAL DRUG INTERACTION EXAMPLES', color=CRIMSON))
story.append(spacer(6))

clinical_data = [
    [Paragraph('<b>Interaction</b>', th),
     Paragraph('<b>Type</b>', th),
     Paragraph('<b>Mechanism</b>', th),
     Paragraph('<b>Consequence</b>', th),
     Paragraph('<b>Management</b>', th)],
    [Paragraph('Warfarin + Aspirin', td),
     Paragraph('PD + PK', td),
     Paragraph('PD: additive anticoagulation\nPK: aspirin inhibits warfarin CYP2C9 metabolism', td),
     Paragraph('Major bleeding risk (GI, intracranial)', td),
     Paragraph('Avoid; if essential, reduce warfarin dose + monitor INR', td)],
    [Paragraph('MAOIs + Pethidine / Tramadol', td),
     Paragraph('PD Potentiation', td),
     Paragraph('MAOI inhibits MAO-A → ↑ serotonin. Pethidine also releases/blocks reuptake of serotonin', td),
     Paragraph('Serotonin Syndrome: hyperthermia, rigidity, seizures, death', td),
     Paragraph('ABSOLUTE CONTRAINDICATION. Washout 14 days before switching', td)],
    [Paragraph('Rifampicin + OCP', td),
     Paragraph('PK Antagonism', td),
     Paragraph('Rifampicin induces CYP3A4 and P-gp → ↑ metabolism + ↑ first-pass of oestrogen/progestogen', td),
     Paragraph('Contraceptive failure, unwanted pregnancy', td),
     Paragraph('Use additional contraception; switch to IUD or injectable', td)],
    [Paragraph('Methotrexate + NSAIDs', td),
     Paragraph('PK (excretion)', td),
     Paragraph('NSAIDs reduce renal blood flow → ↓ GFR + inhibit tubular secretion of MTX', td),
     Paragraph('MTX accumulation → bone marrow suppression, mucositis, hepatotoxicity', td),
     Paragraph('Avoid concurrent use; if unavoidable, give folinic acid rescue', td)],
    [Paragraph('Digoxin + Amiodarone', td),
     Paragraph('PK (metabolism + excretion)', td),
     Paragraph('Amiodarone inhibits P-gp and CYP2C9 → ↓ digoxin renal and non-renal clearance', td),
     Paragraph('Digoxin toxicity: bradycardia, heart block, nausea, xanthopsia', td),
     Paragraph('Reduce digoxin dose by 50% when starting amiodarone; monitor levels', td)],
    [Paragraph('Lithium + NSAIDs/Thiazides', td),
     Paragraph('PK (excretion)', td),
     Paragraph('NSAIDs ↓ prostaglandin-mediated renal blood flow; Thiazides deplete Na → kidney compensates by ↑ Li reabsorption', td),
     Paragraph('Lithium toxicity: tremor, confusion, seizures, nephrogenic DI', td),
     Paragraph('Avoid NSAIDs; use paracetamol. Monitor Li levels when initiating diuretic', td)],
    [Paragraph('Linezolid + SSRIs', td),
     Paragraph('PD Potentiation', td),
     Paragraph('Linezolid is a reversible non-selective MAO inhibitor; SSRIs inhibit serotonin reuptake → combined serotonin excess', td),
     Paragraph('Serotonin Syndrome', td),
     Paragraph('Avoid; if essential, closely monitor for serotonin toxicity features', td)],
    [Paragraph('Co-trimoxazole\n(TMP + SMX)', td),
     Paragraph('PD Synergism', td),
     Paragraph('Sequential block of folate synthesis: SMX blocks DHPS; TMP blocks DHFR → both steps inhibited', td),
     Paragraph('20-100x greater antibacterial activity vs either alone', td),
     Paragraph('Therapeutic exploitation; used in UTI, PCP prophylaxis/treatment', td)],
    [Paragraph('Succinylcholine + Organophosphates', td),
     Paragraph('PD Potentiation', td),
     Paragraph('Organophosphates irreversibly inhibit plasma cholinesterase (pseudocholinesterase) → ↓ succinylcholine metabolism', td),
     Paragraph('Prolonged neuromuscular blockade → prolonged apnoea', td),
     Paragraph('Avoid succinylcholine; use non-depolarising NMB', td)],
]
story.append(tbl(clinical_data, [95, 60, 145, 100, W-420], hdr_color=CRIMSON, alt=[WHITE, LRED]))

# ── PAGE 8: Summary + Exam Points ─────────────────────────────────────────────
story.append(PageBreak())
story.append(banner('8. SUMMARY COMPARISON TABLE', color=NAVY))
story.append(spacer(6))
summary = [
    [Paragraph('<b>Type</b>', th),
     Paragraph('<b>Math</b>', th),
     Paragraph('<b>Both Drugs Active?</b>', th),
     Paragraph('<b>Mechanism</b>', th),
     Paragraph('<b>Classic Exam Example</b>', th)],
    [Paragraph('Additive', tdB),
     Paragraph('1+1=2', tdB),
     Paragraph('Yes (same system)', td),
     Paragraph('Same receptor/pathway; effects sum', td),
     Paragraph('Aspirin + Paracetamol', td)],
    [Paragraph('Synergism\n(Supra-additive)', tdB),
     Paragraph('1+1>2', tdB),
     Paragraph('Yes (different mechanisms)', td),
     Paragraph('Different sites, convergent outcome; isobologram bows inward', td),
     Paragraph('TMP + SMX; Penicillin + Aminoglycoside', td)],
    [Paragraph('Potentiation', tdB),
     Paragraph('0+1=3', tdB),
     Paragraph('No — one is inactive', td),
     Paragraph('Inactive drug amplifies active drug (PK or enzymatic)', td),
     Paragraph('Probenecid + Penicillin; Carbidopa + Levodopa', td)],
    [Paragraph('Competitive\nAntagonism', tdB),
     Paragraph('1+1→0\n(reversible)', tdB),
     Paragraph('Agonist active;\nantagonist blocks', td),
     Paragraph('Same receptor, reversible; parallel right-shift; Emax unchanged', td),
     Paragraph('Naloxone + Morphine; Atropine + ACh', td)],
    [Paragraph('Non-competitive\nAntagonism', tdB),
     Paragraph('1+1→0\n(irreversible)', tdB),
     Paragraph('Agonist active;\nantagonist blocks', td),
     Paragraph('Same receptor, irreversible; right-shift + ↓ Emax', td),
     Paragraph('Phenoxybenzamine + Noradrenaline', td)],
    [Paragraph('Physiological\nAntagonism', tdB),
     Paragraph('1+1→0\n(different R)', tdB),
     Paragraph('Both active (opposing)', td),
     Paragraph('Different receptors, opposing physiological effects', td),
     Paragraph('Adrenaline + Histamine (anaphylaxis)', td)],
    [Paragraph('Chemical\nAntagonism', tdB),
     Paragraph('1+1→0\n(no receptor)', tdB),
     Paragraph('Direct chemical\nreaction', td),
     Paragraph('In vitro or in vivo chemical inactivation', td),
     Paragraph('Protamine + Heparin; EDTA + heavy metals', td)],
    [Paragraph('Pharmacokinetic\nAntagonism', tdB),
     Paragraph('1+1<2\n(ADME)', tdB),
     Paragraph('Both active; one reduces the other\'s levels', td),
     Paragraph('CYP induction / ↑ excretion / ↓ absorption of co-drug', td),
     Paragraph('Rifampicin + Warfarin; Antacid + Tetracycline', td)],
]
story.append(tbl(summary, [80, 48, 75, 140, W-363], hdr_color=NAVY))
story.append(spacer(10))

story.append(banner('9. HIGH-YIELD EXAM POINTS', color=HexColor('#7B1FA2')))
story.append(spacer(6))
exam_pts = [
    ('Narrow therapeutic index drugs', 'Interactions are most dangerous with warfarin, digoxin, lithium, phenytoin, theophylline, aminoglycosides, cyclosporin — monitor plasma levels when adding/removing drugs'),
    ('Isobologram', 'Below the line of additivity = positive synergism (superadditive); above the line = subadditivity (negative synergism)'),
    ('Competitive vs Non-competitive', 'Competitive: right-shift of DRC, Emax unchanged; Non-competitive: right-shift + Emax depressed — this is the most tested distinction'),
    ('Serotonin Syndrome triad', 'Mental change + neuromuscular abnormality + autonomic instability. Caused by MAOIs + pethidine/tramadol/SSRIs/linezolid. Life-threatening.'),
    ('Rifampicin', 'Most potent CYP3A4 inducer — causes failure of warfarin, OCP, protease inhibitors, immunosuppressants. Always check interactions when starting TB therapy.'),
    ('Grapefruit juice', 'CYP3A4 inhibitor (furanocoumarins) — raises levels of statins, calcium channel blockers, immunosuppressants. Single glass can inhibit CYP for 24-72h.'),
    ('Protamine + Heparin', 'Classic chemical antagonism — protamine (cationic) neutralises heparin (anionic) 1mg per 100 units of heparin. Used post-cardiac surgery.'),
    ('TMP/SMX sequential block', 'Textbook example of synergism — two drugs blocking consecutive enzymatic steps in same pathway; 20-100x more effective than either alone.'),
    ('Probenecid + Penicillin', 'Classic potentiation — probenecid has NO antibacterial activity but prolongs penicillin half-life by blocking renal tubular secretion (OAT transporter).'),
    ('Linezolid caution', 'Reversible MAOI. Must avoid SSRIs, TCAs, pethidine — risk of serotonin syndrome. Also causes myelosuppression — additive with other bone marrow suppressants.'),
]
for bold_t, detail_t in exam_pts:
    story.append(Paragraph(f'<b>• {bold_t}:</b>  {detail_t}', bullet))
    story.append(spacer(2))

story.append(spacer(8))
story.append(hr(color=NAVY))
story.append(spacer(4))
story.append(Paragraph(
    'References: Goodman & Gilman\'s Pharmacological Basis of Therapeutics 14e  |  '
    'Goldman-Cecil Medicine  |  Lippincott Illustrated Reviews: Pharmacology  |  '
    'Katzung Basic & Clinical Pharmacology 16e  |  Miller\'s Anesthesia 10e',
    caption))

doc.build(story)
print(f"PDF generated: {output}")
Running Command

cd /tmp/workspace/drug-interactions-pdf && python build_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/drug-interactions-pdf/Drug_Interactions_Study_Guide.pdf

Your study guide PDF is ready:

Drug Interactions Study Guide

PDF Document · PDF


What's inside the 8-page PDF

Page 1 - Title Page + Definition + Mind Map
  • Professional title banner with topic tags
  • Clear definition of drug interaction
  • Visual mind map showing the 4 categories: Pharmacodynamic, Pharmacokinetic, Pharmaceutical, and Beneficial interactions
Page 2 - Additive Effect
  • Formula and concept table (E(A+B) = E(A)+E(B))
  • Colour-coded bar chart comparing Drug A alone / Drug B alone / A+B combined
  • Clinical examples table (6 examples including aspirin+paracetamol, alcohol+diazepam, additive nephrotoxicity)
Page 3 - Synergism
  • Formula and mathematical expression
  • Custom isobologram diagram showing positive synergism (green curve, bows inward), line of additivity, and subadditivity (red curve, bows outward) - with labelled zones
  • Synergism types table: bactericidal, sequential block (TMP/SMX), receptor-effector, pharmacokinetic, enzyme protection
Page 4 - Potentiation
  • Before/After mechanism diagram: Penicillin alone (rapidly excreted) vs. Penicillin + Probenecid (blocked tubular secretion = prolonged action)
  • Full potentiation examples table: Probenecid, Clavulanate, Carbidopa, Ketoconazole, Sulfonamide + Warfarin, Dantrolene
Page 5 - Antagonism
  • 4-panel mechanism diagram: (A) Competitive - receptor with competing agonist/antagonist; (B) Non-competitive - allosteric blockade; (C) Physiological - opposing receptors cancelling BP effects; (D) Chemical - Protamine + Heparin ionic complex
  • Detailed classification table with all 6 sub-types including partial agonist antagonism
Page 6 - Pharmacokinetic Interactions
  • ADME flowchart showing interaction sites at each stage with specific examples
  • Dual-panel CYP diagram: Inhibition (raises drug levels → toxicity) vs Induction (lowers drug levels → failure)
  • Full CYP450 table: CYP3A4 / 2C9 / 2C19 / 2D6 / 1A2 with inducers, inhibitors, and key substrates
Page 7 - Clinical High-Yield Examples
  • 9 dangerous/important interactions with type, mechanism, consequence, and management (Warfarin+Aspirin, MAOIs+Pethidine, Rifampicin+OCP, MTX+NSAIDs, Digoxin+Amiodarone, Lithium+NSAIDs, Linezolid+SSRIs, Co-trimoxazole, Succinylcholine+Organophosphates)
Page 8 - Summary Table + 10 Exam Points
  • Master comparison table across all interaction types with formulas
  • 10 high-yield exam bullets covering isobologram interpretation, competitive vs non-competitive DRC shifts, serotonin syndrome, Rifampicin, grapefruit juice, and the classic exam examples

Complete

Asking for Preferences

The ongoing pdf

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