Explain every theorical basis behind these as a story
cd /tmp/workspace/attachments/dd73a482-ef59-4f8f-ac8e-70173d14a669/ && python3 -c " import pdfplumber with pdfplumber.open('LMS questions GI_572fbceeebc657b4b0e58c79d0474960.pdf') as pdf: print(f'Pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages): text = page.extract_text() print(f'--- PAGE {i+1} ---') print(text) print() "
Generate some images to clearly understand the above
Medical physiology diagram showing the neural control of swallowing (deglutition). Show a sagittal cross-section of the head and neck with labeled structures: tonsillar pillars (sensory trigger zone), trigeminal nerve (CN V) and glossopharyngeal nerve (CN IX) carrying signals up to the medulla oblongata, the swallowing center in the reticular formation of the medulla and lower pons, and motor output via CN V, IX, X, XII down to the pharyngeal muscles, upper esophageal sphincter, and larynx. Include arrows showing the reflex arc. Add a box showing the 5 sequential steps of the pharyngeal stage. Clean educational diagram style with blue and gray color scheme, white background, clearly labeled anatomical structures.
Medical physiology diagram explaining fecal continence and how a stroke causes fecal incontinence. Show two side-by-side panels. Left panel (NORMAL): a cross-section of the rectum and anal canal showing the internal anal sphincter (smooth muscle, autonomic control, labeled IAS) and external anal sphincter (striated muscle, voluntary, labeled EAS), with arrows showing the upper motor neuron pathway descending from the cerebral cortex through the corticospinal tract to S2-S4 spinal segments and pudendal nerve to EAS. Show the voluntary 'hold it' signal pathway. Right panel (AFTER STROKE): same diagram but with a red X on the corticospinal tract showing the pathway is severed, EAS is disconnected from cortical control, and a red 'involuntary stool passage' arrow. Use clean educational style, labeled anatomical structures, blue/red color scheme.
Medical biochemistry flowchart diagram of bilirubin metabolism and why jaundice occurs in liver disease. Show a step-by-step pathway: (1) Old red blood cells destroyed in spleen → heme released → (2) converted to unconjugated bilirubin (indirect, insoluble, bound to albumin) → (3) travels in blood to liver → (4) hepatocytes conjugate it with glucuronic acid → conjugated bilirubin (direct, water-soluble) → (5) excreted into bile ducts → gut → bacteria convert to urobilinogen → stercobilin in stool (brown color). Show a 'DISEASED LIVER' block where step 4 fails, causing backup of conjugated bilirubin into blood → deposits in sclera → yellow eyes (jaundice). Use yellow and orange color highlights for bilirubin, red for diseased pathway, clean infographic style on white background.
Medical physiology diagram showing three mechanisms causing ascites in chronic liver disease. Use a central figure of a person with a distended abdomen. Show three labeled mechanism panels pointing to the abdomen: Panel 1 - PORTAL HYPERTENSION: illustration of fibrotic liver blocking portal vein blood flow, increased hydrostatic pressure pushing fluid out of splanchnic capillaries into peritoneal cavity; Panel 2 - HYPOALBUMINEMIA: show normal vs diseased liver albumin production, Starling forces diagram with reduced oncotic pressure allowing fluid to leak out of capillaries; Panel 3 - RAAS ACTIVATION: kidney activating renin-angiotensin-aldosterone system, aldosterone causing sodium and water retention that pools in abdomen. Use red for pathological changes, blue for normal physiology, clean educational infographic style, clearly labeled.
Medical physiology diagram showing why chronic liver disease causes easy bruising (coagulopathy) and hypoglycemia. Split into two panels. Top panel - COAGULOPATHY: show the coagulation cascade waterfall diagram with factors made by the liver highlighted (fibrinogen, prothrombin, factors V, VII, IX, X, XI) in red labeled 'synthesized by liver'. Show a diseased/fibrotic liver unable to produce these, leading to prolonged PT/INR and bruising. Also show splenomegaly trapping platelets (thrombocytopenia). Bottom panel - HYPOGLYCEMIA: show the liver's role in glucose homeostasis: glycogen storage and glycogenolysis (short-term fasting) and gluconeogenesis from amino acids/lactate/glycerol (prolonged fasting). Show diseased liver with depleted glycogen stores and impaired gluconeogenesis enzymes, leading to blood glucose drop. Use clear arrows, labeled molecules, educational style, blue and red color scheme.
404 Not Found. {'message': '{\n "error": {\n "code": 404,\n "message": "Publisher model `projects/engaged-beaker-474810-u2/locations/global/publishers/google/models/gemini-3-pro-image-preview` was not found or your project does not have access to it. Ensure you are using a valid model name and that the model is available in the specified region. For more information, see: https://docs.cloud.google.com/gemini-enterprise-agent-platform/resources/locations.",\n "status": "NOT_FOUND"\n }\n}\n', 'status': 'Not Found'}
We encountered an error while processing your request. Please try again or reach out to us for help.
?
Generate a PDF document with labeled diagrams and the story explanations together
mkdir -p /tmp/workspace/gi-physiology-pdf && ls /tmp/workspace/gi-physiology-pdf/
~/gi-physiology-pdf/build_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer,
HRFlowable, PageBreak, Table, TableStyle,
KeepTogether)
from reportlab.graphics.shapes import (Drawing, Rect, String, Line, Arrow,
Circle, Polygon, PolyLine, Group)
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Circle, Polygon, Group, PolyLine
from reportlab.lib.colors import (HexColor, white, black, grey, lightgrey,
Color, red, blue, green, orange, yellow)
from reportlab.graphics.charts.flowchart import *
import math
# ── Color palette ──────────────────────────────────────────────────────────────
NAVY = HexColor('#1a3a5c')
TEAL = HexColor('#0e7c7b')
SKY = HexColor('#d0eaf8')
AMBER = HexColor('#f4a261')
AMBER_LT = HexColor('#fde8cc')
RED_D = HexColor('#c0392b')
RED_LT = HexColor('#fde8e8')
GREEN_D = HexColor('#196f3d')
GREEN_LT = HexColor('#d5f5e3')
YELLOW_D = HexColor('#b7950b')
YELLOW_LT = HexColor('#fef9c3')
GREY_LT = HexColor('#f4f4f4')
GREY_MED = HexColor('#cccccc')
PURPLE = HexColor('#7d3c98')
PURPLE_LT = HexColor('#f0e6f6')
W = white
B = black
PAGE_W, PAGE_H = A4
MARGIN = 2*cm
# ── Document setup ─────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
'/tmp/workspace/gi-physiology-pdf/GI_Physiology_Story.pdf',
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=MARGIN, bottomMargin=MARGIN,
title='GI Physiology – Story & Diagrams',
author='Physiology SGD 2024'
)
styles = getSampleStyleSheet()
# Custom paragraph styles
def S(name, **kw):
base = kw.pop('parent', 'Normal')
s = ParagraphStyle(name, parent=styles[base], **kw)
return s
H1 = S('H1', parent='Heading1', fontSize=22, textColor=NAVY,
spaceAfter=6, spaceBefore=16, fontName='Helvetica-Bold')
H2 = S('H2', parent='Heading2', fontSize=15, textColor=TEAL,
spaceAfter=4, spaceBefore=14, fontName='Helvetica-Bold')
H3 = S('H3', parent='Heading3', fontSize=12, textColor=NAVY,
spaceAfter=3, spaceBefore=10, fontName='Helvetica-Bold')
BODY= S('BODY',fontSize=10, leading=15, spaceAfter=6, textColor=HexColor('#222222'))
CITE= S('CITE',fontSize=8.5, leading=12, textColor=HexColor('#555555'),
leftIndent=12, spaceAfter=4, fontName='Helvetica-Oblique')
BOX = S('BOX', fontSize=9.5, leading=14, textColor=NAVY,
leftIndent=8, rightIndent=8, spaceAfter=4)
def hr(): return HRFlowable(width='100%', thickness=1, color=GREY_MED, spaceAfter=6)
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM HELPERS
# ══════════════════════════════════════════════════════════════════════════════
def arrow(x1,y1,x2,y2,color=NAVY,width=1.5):
"""Draw a line with arrowhead at (x2,y2)."""
g = Group()
g.add(Line(x1,y1,x2,y2,strokeColor=color,strokeWidth=width))
# arrowhead
dx,dy = x2-x1, y2-y1
L = math.hypot(dx,dy)
if L==0: return g
ux,uy = dx/L, dy/L
px,py = -uy, ux
ah = 7
aw = 4
pts = [x2,y2,
x2-ah*ux+aw*px, y2-ah*uy+aw*py,
x2-ah*ux-aw*px, y2-ah*uy-aw*py]
g.add(Polygon(pts, fillColor=color, strokeColor=color, strokeWidth=0))
return g
def box(x,y,w,h,fill=SKY,stroke=NAVY,radius=5,strokeWidth=1):
return Rect(x,y,w,h,rx=radius,ry=radius,
fillColor=fill,strokeColor=stroke,strokeWidth=strokeWidth)
def label(x,y,text,size=9,color=B,bold=False,anchor='middle'):
fn = 'Helvetica-Bold' if bold else 'Helvetica'
return String(x,y,text,fontSize=size,fillColor=color,
textAnchor=anchor,fontName=fn)
def circle_node(cx,cy,r,fill,stroke=NAVY,sw=1.5):
return Circle(cx,cy,r,fillColor=fill,strokeColor=stroke,strokeWidth=sw)
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 1 – Swallowing Neural Control
# ══════════════════════════════════════════════════════════════════════════════
def make_swallowing_diagram():
W_d, H_d = 480, 340
d = Drawing(W_d, H_d)
d.add(Rect(0,0,W_d,H_d,fillColor=GREY_LT,strokeColor=GREY_MED,strokeWidth=0.5))
d.add(label(W_d/2, H_d-14, 'Neural Control of Swallowing (Deglutition Reflex)',
size=11, bold=True, color=NAVY))
# ── Nodes (x, y, label, fill) ──────────────────────────────────────────
nodes = {
'trigger': (80, 230, 'Tonsillar Pillars\n(Sensory Trigger)', SKY, TEAL),
'afferent':(80, 155, 'CN V & IX\n(Afferent limb)', AMBER_LT, AMBER),
'center': (240,155, 'Swallowing Center\n(Medulla + Lower Pons)', GREEN_LT, GREEN_D),
'efferent':(400,155, 'CN V,IX,X,XII\n(Efferent limb)', AMBER_LT, AMBER),
'pharynx': (400, 80, 'Pharyngeal Muscles\n+ UES Relaxes', SKY, TEAL),
'resp': (240, 60, 'Respiratory Center\nINHIBITED', RED_LT, RED_D),
}
BW, BH = 110, 44
coords = {}
for key,(bx,by,txt,fill,strok) in nodes.items():
d.add(box(bx-BW/2, by-BH/2, BW, BH, fill=fill, stroke=strok, radius=7))
for i,line in enumerate(txt.split('\n')):
off = 6 if '\n' in txt else 0
d.add(label(bx, by+off - i*12, line, size=8, color=B))
coords[key] = (bx, by)
# ── Arrows ────────────────────────────────────────────────────────────
def conn(a,b,col=NAVY):
ax,ay = coords[a]; bx,by = coords[b]
d.add(arrow(ax,ay,bx,by,color=col))
conn('trigger','afferent',TEAL)
conn('afferent','center',AMBER)
conn('center','efferent',GREEN_D)
conn('efferent','pharynx',TEAL)
conn('center','resp',RED_D)
# legend note
d.add(label(W_d/2, 18,
'Swallowing is a REFLEX – voluntarily initiated but automatically executed by the brainstem',
size=7.5, color=HexColor('#444444')))
# Step labels
steps = ['① Bolus touches\ntonsillar pillars',
'② CN V/IX fire →\nmedulla',
'③ Swallowing center\ntakes over',
'④ Motor cranial nerves\nactivate sequence',
'⑤ Pharynx contracts,\nairway protected']
for i,s in enumerate(steps):
sx = 15 + i*93
d.add(Rect(sx, 290, 88, 36, fillColor=W, strokeColor=TEAL, strokeWidth=0.8, rx=4,ry=4))
for j,ln in enumerate(s.split('\n')):
d.add(label(sx+44, 318-j*11, ln, size=7, color=NAVY))
if i < 4:
d.add(arrow(sx+90,308,sx+93,308,color=TEAL,width=1))
return d
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 2 – Fecal Continence & Incontinence after Stroke
# ══════════════════════════════════════════════════════════════════════════════
def make_continence_diagram():
W_d, H_d = 480, 310
d = Drawing(W_d, H_d)
d.add(Rect(0,0,W_d,H_d,fillColor=GREY_LT,strokeColor=GREY_MED,strokeWidth=0.5))
d.add(label(W_d/2, H_d-14, 'Fecal Continence – Normal vs After Stroke',
size=11, bold=True, color=NAVY))
mid = W_d/2
# Divider
d.add(Line(mid,30,mid,H_d-25,strokeColor=GREY_MED,strokeWidth=1,strokeDashArray=[4,3]))
d.add(label(mid/2, H_d-28, 'NORMAL', size=10, bold=True, color=GREEN_D))
d.add(label(mid+mid/2, H_d-28, 'AFTER STROKE', size=10, bold=True, color=RED_D))
# ── NORMAL side ──────────────────────────────────────────────────────
# Cortex
d.add(box(30,205,100,34,fill=GREEN_LT,stroke=GREEN_D))
d.add(label(80,225,'Cerebral Cortex',size=8,bold=True,color=GREEN_D))
d.add(label(80,215,'"Hold it" signal',size=7.5,color=B))
# Spinal cord
d.add(box(30,145,100,34,fill=SKY,stroke=TEAL))
d.add(label(80,165,'Corticospinal Tract',size=8,color=B))
d.add(label(80,155,'S2–S4 segments',size=7.5,color=B))
# Pudendal nerve
d.add(box(30,88,100,34,fill=AMBER_LT,stroke=AMBER))
d.add(label(80,108,'Pudendal Nerve',size=8,color=B))
d.add(label(80,98,'(voluntary)',size=7.5,color=B))
# Sphincters
d.add(box(30,38,100,36,fill=GREEN_LT,stroke=GREEN_D))
d.add(label(80,60,'EAS contracts',size=8,bold=True,color=GREEN_D))
d.add(label(80,50,'Continence ✓',size=7.5,color=GREEN_D))
d.add(arrow(80,205,80,181,color=GREEN_D))
d.add(arrow(80,145,80,124,color=TEAL))
d.add(arrow(80,88, 80,76, color=AMBER))
# IAS label
d.add(label(185,60,'IAS = smooth muscle,\nautonomic, always contracted',size=7,color=HexColor('#444')))
# ── AFTER STROKE side ──────────────────────────────────────────────
ox = mid + 10
# Cortex
d.add(box(ox+10,205,100,34,fill=RED_LT,stroke=RED_D))
d.add(label(ox+60,225,'Cerebral Cortex',size=8,bold=True,color=RED_D))
d.add(label(ox+60,215,'DAMAGED',size=7.5,color=RED_D))
# Red X on tract
d.add(box(ox+10,145,100,34,fill=GREY_LT,stroke=GREY_MED))
d.add(label(ox+60,165,'Corticospinal Tract',size=8,color=B))
d.add(label(ox+60,155,'SEVERED',size=7.5,color=RED_D))
# Big X
d.add(Line(ox+25,200,ox+95,155,strokeColor=RED_D,strokeWidth=3))
d.add(Line(ox+95,200,ox+25,155,strokeColor=RED_D,strokeWidth=3))
# Sphincter
d.add(box(ox+10,38,100,36,fill=RED_LT,stroke=RED_D))
d.add(label(ox+60,60,'EAS fails to contract',size=8,bold=True,color=RED_D))
d.add(label(ox+60,50,'Fecal Incontinence ✗',size=7.5,color=RED_D))
d.add(label(W_d/2, 18,
'High spinal/brain lesions → voluntary sphincter control lost → urgent, precipitous defecation',
size=7.5, color=HexColor('#444444')))
return d
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 3 – Bilirubin Metabolism & Jaundice
# ══════════════════════════════════════════════════════════════════════════════
def make_bilirubin_diagram():
W_d, H_d = 480, 330
d = Drawing(W_d, H_d)
d.add(Rect(0,0,W_d,H_d,fillColor=GREY_LT,strokeColor=GREY_MED,strokeWidth=0.5))
d.add(label(W_d/2, H_d-14, 'Bilirubin Metabolism & Why Jaundice Occurs',
size=11, bold=True, color=NAVY))
# Step boxes (normal pathway) left to right, y=190 level
steps = [
('RBC destroyed\n(Spleen)', 40, 215, SKY, TEAL),
('Unconjugated\nBilirubin\n(insoluble,\nalbumin-bound)', 140, 215, YELLOW_LT, YELLOW_D),
('Liver\nHepatocytes\n(conjugation\nwith glucuronate)', 265, 215, GREEN_LT, GREEN_D),
('Conjugated\nBilirubin\n(water-soluble)', 390, 215, GREEN_LT, GREEN_D),
]
BW2, BH2 = 80, 64
sx_list = []
for txt,cx,cy,fill,strok in steps:
d.add(box(cx-BW2/2, cy-BH2/2, BW2, BH2, fill=fill, stroke=strok))
lines = txt.split('\n')
for i,ln in enumerate(lines):
d.add(label(cx, cy+18 - i*12, ln, size=7.5, color=B))
sx_list.append((cx,cy))
# Arrows between normal steps
for i in range(len(sx_list)-1):
ax,ay = sx_list[i][0]+BW2/2, sx_list[i][1]
bx,by = sx_list[i+1][0]-BW2/2, sx_list[i+1][1]
d.add(arrow(ax,ay,bx,by,color=GREEN_D))
# Normal continuation downward from Conjugated Bilirubin
cx4,cy4 = sx_list[3]
# Bile → Gut
d.add(box(350, 110, 90, 36, fill=AMBER_LT, stroke=AMBER))
d.add(label(395, 131, 'Bile → Gut', size=8, bold=True, color=B))
d.add(label(395, 121, 'Bacteria→Urobilinogen', size=7, color=B))
d.add(label(395, 111, '→ Stercobilin (brown stool)', size=7, color=B))
d.add(arrow(cx4, cy4-BH2/2, 395, 146, color=AMBER))
# Diseased liver branch
d.add(Rect(185, 95, 100, 50, fillColor=RED_LT, strokeColor=RED_D, strokeWidth=2, rx=6, ry=6))
d.add(label(235, 138, 'DISEASED LIVER', size=8, bold=True, color=RED_D))
d.add(label(235, 127, 'Hepatocytes fail', size=7.5, color=RED_D))
d.add(label(235, 116, 'Conjugation impaired', size=7.5, color=RED_D))
d.add(label(235, 105, '→ Bilirubin backs up', size=7.5, color=RED_D))
# Arrow from normal liver box down to diseased
d.add(arrow(265, 215-BH2/2, 235, 147, color=RED_D, width=2))
# Backup into blood → Sclera
d.add(box(50, 88, 115, 36, fill=YELLOW_LT, stroke=YELLOW_D, strokeWidth=2))
d.add(label(107, 110, 'Bilirubin in blood ↑', size=8, bold=True, color=YELLOW_D))
d.add(label(107, 99, 'Deposits in sclera/skin', size=7.5, color=B))
d.add(arrow(185, 120, 167, 110, color=YELLOW_D, width=2))
# Jaundice result
d.add(Circle(65, 50, 22, fillColor=HexColor('#fff176'), strokeColor=YELLOW_D, strokeWidth=2))
d.add(label(65, 54, 'YELLOW', size=8, bold=True, color=YELLOW_D))
d.add(label(65, 43, 'EYES', size=8, bold=True, color=YELLOW_D))
d.add(arrow(95, 88, 80, 74, color=YELLOW_D))
d.add(label(W_d/2, 18,
'CLD: hepatocytes fail → bilirubin conjugation blocked → conjugated bilirubin regurgitates into blood → scleral icterus',
size=7.5, color=HexColor('#444444')))
return d
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 4 – Coagulopathy & Hypoglycemia
# ══════════════════════════════════════════════════════════════════════════════
def make_coag_glucose_diagram():
W_d, H_d = 480, 370
d = Drawing(W_d, H_d)
d.add(Rect(0,0,W_d,H_d,fillColor=GREY_LT,strokeColor=GREY_MED,strokeWidth=0.5))
d.add(label(W_d/2, H_d-14, 'Coagulopathy & Hypoglycemia in Chronic Liver Disease',
size=11, bold=True, color=NAVY))
mid = W_d/2
d.add(Line(mid,25,mid,H_d-26,strokeColor=GREY_MED,strokeWidth=1,strokeDashArray=[4,3]))
# ── LEFT: Coagulopathy ────────────────────────────────────────────────
d.add(label(mid/2, H_d-28, 'EASY BRUISING / COAGULOPATHY', size=9, bold=True, color=RED_D))
# Healthy liver → makes clotting factors
d.add(box(20, 265, 100, 40, fill=GREEN_LT, stroke=GREEN_D))
d.add(label(70, 289, 'Normal Liver', size=8, bold=True, color=GREEN_D))
d.add(label(70, 279, 'Synthesizes:', size=7.5, color=B))
factors = ['Fibrinogen (I)', 'Prothrombin (II)', 'Factors V,VII,IX,X,XI',
'Protein C & S']
for i,f in enumerate(factors):
d.add(label(70, 258-i*12, '• '+f, size=7, color=GREEN_D))
d.add(arrow(70,265,70,232,color=GREEN_D))
# Clotting cascade box
d.add(box(20, 195, 100, 36, fill=SKY, stroke=TEAL))
d.add(label(70,217,'Coagulation', size=8, bold=True, color=TEAL))
d.add(label(70,206,'Cascade intact', size=7.5, color=B))
d.add(arrow(70,195,70,180,color=TEAL))
d.add(box(20, 148, 100, 30, fill=GREEN_LT, stroke=GREEN_D))
d.add(label(70,167,'Normal clotting', size=8, bold=True, color=GREEN_D))
d.add(label(70,157,'No bruising', size=7.5, color=B))
# Diseased liver side
d.add(box(130, 265, 100, 40, fill=RED_LT, stroke=RED_D))
d.add(label(180, 289, 'Diseased Liver', size=8, bold=True, color=RED_D))
d.add(label(180, 279, 'REDUCED synthesis', size=7.5, color=RED_D))
d.add(label(180, 268, 'PT/INR prolonged ↑', size=7.5, color=B))
# Splenomegaly
d.add(box(130, 215, 100, 36, fill=PURPLE_LT, stroke=PURPLE))
d.add(label(180,237,'Portal HTN →', size=7.5, color=PURPLE))
d.add(label(180,226,'Splenomegaly', size=7.5, color=PURPLE))
d.add(label(180,215,'Platelets trapped ↓', size=7, color=B))
d.add(arrow(130,265,180,253,color=RED_D))
d.add(arrow(180,215,180,202,color=PURPLE))
d.add(box(130, 148, 100, 36, fill=RED_LT, stroke=RED_D))
d.add(label(180,170,'EASY BRUISING', size=8, bold=True, color=RED_D))
d.add(label(180,159,'Spontaneous bleeding', size=7.5, color=B))
d.add(arrow(180,215,180,186,color=RED_D))
# ── RIGHT: Hypoglycemia ───────────────────────────────────────────────
d.add(label(mid+mid/2, H_d-28, 'HYPOGLYCEMIA', size=9, bold=True, color=AMBER))
ox = mid + 10
# Two pathways
# Glycogenolysis
d.add(box(ox, 280, 105, 48, fill=GREEN_LT, stroke=GREEN_D))
d.add(label(ox+52, 314, '① Glycogenolysis', size=8, bold=True, color=GREEN_D))
d.add(label(ox+52, 303, 'Liver breaks down', size=7.5, color=B))
d.add(label(ox+52, 292, 'stored glycogen → glucose', size=7.5, color=B))
d.add(label(ox+52, 281, '(short-term fasting)', size=7, color=HexColor('#555')))
# Gluconeogenesis
d.add(box(ox, 215, 105, 48, fill=SKY, stroke=TEAL))
d.add(label(ox+52, 249, '② Gluconeogenesis', size=8, bold=True, color=TEAL))
d.add(label(ox+52, 238, 'Amino acids, lactate,', size=7.5, color=B))
d.add(label(ox+52, 227, 'glycerol → glucose', size=7.5, color=B))
d.add(label(ox+52, 216, '(prolonged fasting)', size=7, color=HexColor('#555')))
d.add(arrow(ox+52, 280, ox+52, 265, color=GREEN_D))
# Normal result
d.add(box(ox, 168, 105, 36, fill=GREEN_LT, stroke=GREEN_D))
d.add(label(ox+52, 190, 'Blood glucose maintained', size=8, bold=True, color=GREEN_D))
d.add(label(ox+52, 179, '70–100 mg/dL ✓', size=7.5, color=B))
d.add(arrow(ox+52, 215, ox+52, 206, color=TEAL))
# Diseased liver
d.add(Rect(ox, 100, 105, 56, fillColor=RED_LT, strokeColor=RED_D, strokeWidth=2, rx=5,ry=5))
d.add(label(ox+52, 149, 'DISEASED LIVER', size=8, bold=True, color=RED_D))
d.add(label(ox+52, 138, '• Glycogen stores ↓↓', size=7.5, color=B))
d.add(label(ox+52, 127, '• Gluconeogenic', size=7.5, color=B))
d.add(label(ox+52, 116, ' enzymes impaired', size=7.5, color=B))
d.add(label(ox+52, 105, '• Insulin first-pass↓', size=7.5, color=B))
d.add(arrow(ox+52, 168, ox+52, 158, color=RED_D, width=2))
# Result
d.add(box(ox, 50, 105, 38, fill=AMBER_LT, stroke=AMBER, strokeWidth=2))
d.add(label(ox+52, 78, 'HYPOGLYCEMIA', size=9, bold=True, color=AMBER))
d.add(label(ox+52, 67, 'Fasting / overnight', size=7.5, color=B))
d.add(label(ox+52, 56, 'Sweating, confusion', size=7.5, color=B))
d.add(arrow(ox+52, 100, ox+52, 90, color=AMBER, width=2))
d.add(label(W_d/2, 18,
'Both coagulopathy and hypoglycemia reflect loss of hepatic synthetic & metabolic function',
size=7.5, color=HexColor('#444444')))
return d
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 5 – Ascites Triple Mechanism
# ══════════════════════════════════════════════════════════════════════════════
def make_ascites_diagram():
W_d, H_d = 480, 370
d = Drawing(W_d, H_d)
d.add(Rect(0,0,W_d,H_d,fillColor=GREY_LT,strokeColor=GREY_MED,strokeWidth=0.5))
d.add(label(W_d/2, H_d-14, 'Three Mechanisms of Ascites in Chronic Liver Disease',
size=11, bold=True, color=NAVY))
# Central circle – ASCITES
cx,cy,cr = 240, 155, 38
d.add(Circle(cx,cy,cr, fillColor=SKY, strokeColor=NAVY, strokeWidth=2))
d.add(label(cx, cy+8, 'ASCITES', size=10, bold=True, color=NAVY))
d.add(label(cx, cy-4, 'Fluid in', size=8, color=NAVY))
d.add(label(cx, cy-14, 'Peritoneum', size=8, color=NAVY))
# ── Mechanism 1: Portal Hypertension (left) ───────────────────────────
d.add(Rect(10, 230, 140, 90, fillColor=RED_LT, strokeColor=RED_D, strokeWidth=1.5, rx=7,ry=7))
d.add(label(80, 313, '① Portal Hypertension', size=9, bold=True, color=RED_D))
d.add(label(80, 301, 'Fibrosis ↑ resistance in liver', size=7.5, color=B))
d.add(label(80, 290, 'Portal vein pressure ↑', size=7.5, color=B))
d.add(label(80, 279, '(>12 mmHg)', size=7.5, color=B))
d.add(label(80, 268, 'Hydrostatic pressure ↑', size=7.5, color=B))
d.add(label(80, 257, 'Fluid pushed into peritoneum', size=7.5, color=B))
d.add(label(80, 246, '(Starling forces imbalanced)', size=7.5, color=B))
d.add(arrow(150,275, cx-cr, 175, color=RED_D, width=2))
# ── Mechanism 2: Hypoalbuminemia (top) ───────────────────────────────
d.add(Rect(160, 295, 160, 65, fillColor=YELLOW_LT, strokeColor=YELLOW_D, strokeWidth=1.5, rx=7,ry=7))
d.add(label(240, 352, '② Hypoalbuminemia', size=9, bold=True, color=YELLOW_D))
d.add(label(240, 340, 'Liver fails to make albumin', size=7.5, color=B))
d.add(label(240, 329, 'Serum albumin ↓ (<3.5 g/dL)', size=7.5, color=B))
d.add(label(240, 318, 'Oncotic pressure ↓', size=7.5, color=B))
d.add(label(240, 307, 'Fluid leaks out, not pulled back', size=7.5, color=B))
d.add(label(240, 296, 'into capillaries', size=7.5, color=B))
d.add(arrow(240, 295, 240, cy+cr+2, color=YELLOW_D, width=2))
# ── Mechanism 3: RAAS Activation (right) ─────────────────────────────
d.add(Rect(330, 230, 140, 90, fillColor=PURPLE_LT, strokeColor=PURPLE, strokeWidth=1.5, rx=7,ry=7))
d.add(label(400, 313, '③ RAAS Activation', size=9, bold=True, color=PURPLE))
d.add(label(400, 301, 'Splanchnic vasodilation', size=7.5, color=B))
d.add(label(400, 290, '→ "effective" low vol.', size=7.5, color=B))
d.add(label(400, 279, 'Kidney activates RAAS+ADH', size=7.5, color=B))
d.add(label(400, 268, 'Na⁺ & H₂O retained', size=7.5, color=B))
d.add(label(400, 257, 'Cannot correct portal HTN', size=7.5, color=B))
d.add(label(400, 246, '→ fluid pours into abdomen', size=7.5, color=B))
d.add(arrow(330,275, cx+cr, 175, color=PURPLE, width=2))
# Result box
d.add(Rect(130, 50, 220, 55, fillColor=SKY, strokeColor=NAVY, strokeWidth=2, rx=8,ry=8))
d.add(label(240, 97, 'RESULT: Tense, distended abdomen', size=9, bold=True, color=NAVY))
d.add(label(240, 85, 'Risk of SBP (spontaneous bacterial peritonitis)', size=8, color=B))
d.add(label(240, 74, 'Diaphragm elevation → breathing difficulty', size=8, color=B))
d.add(label(240, 63, 'Hepatorenal syndrome if untreated', size=8, color=B))
d.add(arrow(cx,cy-cr,cx,107,color=NAVY))
d.add(label(W_d/2, 18,
'All three mechanisms act simultaneously and amplify each other in cirrhosis',
size=7.5, color=HexColor('#444444')))
return d
# ══════════════════════════════════════════════════════════════════════════════
# BUILD STORY TEXT
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ─── COVER ────────────────────────────────────────────────────────────────────
story.append(Spacer(1, 1.8*cm))
story.append(Paragraph('GI Physiology', H1))
story.append(Paragraph('Story-Based Explanations with Diagrams', H2))
story.append(Paragraph('Physiology SGD – 2024 Batch', CITE))
story.append(hr())
story.append(Spacer(1, 0.4*cm))
toc_data = [
['Case 1', "Mr. Robert – Stroke, Dysphagia & Fecal Incontinence"],
['Case 2', "Chronic Liver Disease – Jaundice, Coagulopathy, Hypoglycemia & Ascites"],
]
toc = Table(toc_data, colWidths=[2.5*cm, 13*cm])
toc.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), SKY),
('TEXTCOLOR', (0,0), (0,-1), NAVY),
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 10),
('ROWBACKGROUNDS', (0,0), (-1,-1), [GREY_LT, W]),
('GRID', (0,0), (-1,-1), 0.5, GREY_MED),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('PADDING', (0,0), (-1,-1), 7),
]))
story.append(toc)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# CASE 1
# ═══════════════════════════════════════════════════════════════════════════════
story.append(Paragraph('Case 1 – The Day Robert\'s Brain Stopped Talking to His Gut', H1))
story.append(Paragraph(
'Mr. Robert, 70, has a massive stroke. He can no longer swallow safely and has lost control '
'of his bowels. Both problems share the same root cause: the brain can no longer send the '
'right signals at the right time.', BODY))
story.append(hr())
# --- Swallowing ---
story.append(Paragraph('Part A – Dysphagia (Difficulty Swallowing)', H2))
story.append(Paragraph(
'Every time you push food toward the back of your throat, a precisely timed reflex takes '
'over. Touch receptors on the <b>tonsillar pillars</b> detect the bolus and fire signals '
'up cranial nerves V (trigeminal) and IX (glossopharyngeal) to the <b>swallowing center</b> '
'in the reticular formation of the medulla oblongata and lower pons.', BODY))
story.append(Paragraph(
'The swallowing center then orchestrates an irreversible, automatic sequence in under '
'2 seconds: the soft palate rises (blocks the nasopharynx), the larynx lifts (protecting '
'the airway), the upper esophageal sphincter relaxes, and pharyngeal muscles contract '
'top-to-bottom, driving the bolus into the esophagus. Motor commands exit via '
'<b>CN V, IX, X, and XII</b>. Simultaneously, the swallowing center suppresses the '
'respiratory center so the patient does not inhale mid-swallow.', BODY))
story.append(Paragraph(
'Robert\'s stroke damaged the cortical pathways or brainstem structures that feed this '
'center. The voluntary "initiate swallow" signal never arrives, or the reflex arc itself '
'is disrupted. The larynx fails to lift cleanly, and food spills into the trachea. '
'A nasogastric tube bypasses the broken system entirely.', BODY))
story.append(Paragraph(
'Source: Guyton and Hall Textbook of Medical Physiology – '
'"The areas in the medulla and lower pons that control swallowing are collectively '
'called the deglutition or swallowing center." (p. 789)', CITE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Diagram 1 – Neural Control of Swallowing', H3))
story.append(make_swallowing_diagram())
story.append(Spacer(1, 0.4*cm))
# --- Fecal incontinence ---
story.append(Paragraph('Part B – Fecal Incontinence', H2))
story.append(Paragraph(
'Staying continent requires two sphincters working together. The <b>internal anal '
'sphincter (IAS)</b> is smooth muscle under tonic autonomic (involuntary) control – '
'it stays contracted without effort. The <b>external anal sphincter (EAS)</b> is '
'striated (voluntary) muscle innervated by the <b>pudendal nerve (S2–S4)</b>.', BODY))
story.append(Paragraph(
'When stool enters the rectum, the IAS briefly relaxes (rectoanal inhibitory reflex). '
'Cortical awareness arrives, and you voluntarily squeeze the EAS until an appropriate '
'time. Upper motor neuron pathways – the corticospinal tract descending from the '
'cerebral cortex – carry the "hold it" command to S2–S4.', BODY))
story.append(Paragraph(
'Robert\'s stroke severs this pathway. The EAS receives no voluntary "contract" signal. '
'With high spinal or brain lesions, defecation becomes urgent and precipitous. '
'Because the bowel and bladder share the same spinal segments (S2–S4), strokes often '
'cause "double incontinence."', BODY))
story.append(Paragraph(
'Source: Localization in Clinical Neurology, 8e – '
'"With spinal cord lesions above the conus medullaris, defecation may become urgent '
'and precipitous. High spinal cord lesions may also cause fecal incontinence."', CITE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Diagram 2 – Fecal Continence: Normal vs After Stroke', H3))
story.append(make_continence_diagram())
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# CASE 2
# ═══════════════════════════════════════════════════════════════════════════════
story.append(Paragraph('Case 2 – The Liver That Could No Longer Keep Its Promises', H1))
story.append(Paragraph(
'The liver performs over 500 distinct functions. Chronic liver disease (CLD) – from '
'cirrhosis, alcohol, or viral hepatitis – progressively destroys hepatocytes and '
'replaces them with scar. Every broken function produces a predictable clinical sign.', BODY))
story.append(hr())
# --- Jaundice ---
story.append(Paragraph('① Yellow Eyes – The Broken Excretory Promise', H2))
story.append(Paragraph(
'Old red blood cells are dismantled in the spleen. Hemoglobin releases heme, which is '
'converted to <b>unconjugated (indirect) bilirubin</b> – insoluble in water, tightly '
'bound to albumin in the blood. It travels to the liver where hepatocytes attach two '
'glucuronic acid molecules (<i>UDP-glucuronosyltransferase</i>), producing '
'<b>conjugated (direct) bilirubin</b> – now water-soluble and ready for bile excretion.', BODY))
story.append(Paragraph(
'From bile it enters the gut; bacteria convert it to urobilinogen, most becomes '
'stercobilin (the brown color of stool), and a small fraction is reabsorbed and excreted '
'in urine. In CLD, surviving hepatocytes cannot keep up with uptake and excretion. '
'Conjugated bilirubin backs up into the blood and deposits in tissues – especially the '
'<b>sclera</b>, which is rich in elastin that binds bilirubin avidly – causing the '
'characteristic yellow discoloration.', BODY))
story.append(Paragraph(
'Source: Guyton and Hall Textbook of Medical Physiology (p. 864) – '
'"In obstructive jaundice caused by damage to the hepatic cells, bilirubin formed '
'cannot pass from the blood into the intestines... most of the bilirubin in the plasma '
'becomes the conjugated type."', CITE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Diagram 3 – Bilirubin Metabolism & Jaundice', H3))
story.append(make_bilirubin_diagram())
story.append(Spacer(1, 0.5*cm))
# --- Coagulopathy & Hypoglycemia ---
story.append(Paragraph('② Easy Bruising – The Broken Synthetic Promise', H2))
story.append(Paragraph(
'The liver synthesizes <b>almost all coagulation factors</b>: fibrinogen (I), prothrombin '
'(II), and factors V, VII, IX, X, and XI – as well as the natural anticoagulants '
'Protein C, Protein S, and antithrombin. Factor VII has the shortest half-life, so it '
'falls first, and the PT/INR rises early in CLD – making it a sensitive marker of '
'hepatic synthetic function.', BODY))
story.append(Paragraph(
'Portal hypertension causes congestive splenomegaly, trapping platelets '
'(thrombocytopenia). This undermines primary hemostasis even before the coagulation '
'cascade is impaired. The combined result: minor bumps leave spreading bruises, '
'and mucosal bleeding is common.', BODY))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph('③ Intermittent Hypoglycemia – The Broken Metabolic Promise', H2))
story.append(Paragraph(
'Between meals, blood glucose is maintained by two hepatic processes: '
'<b>glycogenolysis</b> (breaking down stored glycogen – the short-term buffer) and '
'<b>gluconeogenesis</b> (synthesizing new glucose from amino acids, lactate, and '
'glycerol – the long-term reserve). Both require functional hepatocytes and their '
'enzymes (glucose-6-phosphatase, PEPCK).', BODY))
story.append(Paragraph(
'In CLD, hepatocyte mass shrinks, glycogen stores deplete, and gluconeogenic enzyme '
'expression falls. Additionally, insulin is normally degraded 50% on its first pass '
'through the portal circulation ("first-pass effect"). A diseased liver lets more '
'insulin escape into systemic circulation, prolonging hypoglycemic effect. Episodes '
'cluster in the early morning and after prolonged fasting.', BODY))
story.append(Paragraph(
'Source: Tietz Textbook of Laboratory Medicine – '
'"Decreased glucose production in hepatic failure caused by impaired gluconeogenesis '
'or glycogen storage may result in hypoglycemia. Because dysfunction of more than 80% '
'of the liver is necessary for hypoglycemia to develop..."', CITE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Diagram 4 – Coagulopathy & Hypoglycemia', H3))
story.append(make_coag_glucose_diagram())
story.append(PageBreak())
# --- Ascites ---
story.append(Paragraph('④ Ascites – The Broken Pressure & Protein Promise', H2))
story.append(Paragraph(
'Ascites is the accumulation of fluid in the peritoneal cavity. It results from three '
'interacting mechanisms that all amplify each other:', BODY))
box_data = [
['Mechanism', 'Pathophysiology', 'Result'],
['① Portal\nHypertension',
'Cirrhotic fibrosis ↑ resistance in hepatic sinusoids. Portal vein pressure exceeds '
'12 mmHg. Splanchnic capillary hydrostatic pressure ↑. Starling forces shift – '
'fluid is pushed out of capillaries into the peritoneal space.',
'Fluid extravasation\ninto abdomen'],
['② Hypo-\nalbuminemia',
'The liver is the sole producer of albumin (the main oncotic protein). In CLD, '
'albumin synthesis collapses (serum albumin < 3.5 g/dL). Oncotic pressure ↓. '
'Fluid can no longer be pulled back into capillaries.',
'Leakage from\ncapillaries'],
['③ RAAS\nActivation',
'Splanchnic vasodilation from portal HTN is sensed by the kidney as "low blood volume." '
'RAAS and ADH activate. The kidney retains Na⁺ and H₂O aggressively – but the retained '
'fluid cannot correct portal pressure; it simply pours into the abdomen.',
'Na⁺/H₂O retention\n→ ascites worsens'],
]
bt = Table(box_data, colWidths=[2.5*cm, 10*cm, 3*cm])
bt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('TEXTCOLOR', (0,0), (-1,0), W),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS',(0,1),(-1,-1),[RED_LT, YELLOW_LT, PURPLE_LT]),
('GRID', (0,0), (-1,-1), 0.5, GREY_MED),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('PADDING', (0,0), (-1,-1), 6),
]))
story.append(bt)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
'Source: Robbins & Kumar Basic Pathology – '
'"Potentially fatal sequelae of liver failure include coagulopathy, encephalopathy, '
'portal hypertension and ascites, hepatorenal syndrome."', CITE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Diagram 5 – Three Mechanisms of Ascites', H3))
story.append(make_ascites_diagram())
story.append(Spacer(1, 0.5*cm))
# ─── Summary Table ────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(Paragraph('Summary – The Big Picture', H1))
story.append(Paragraph(
'Both cases illustrate the same underlying principle: physiology depends on specific '
'anatomical pathways and specific proteins. Destroy the pathway or the factory, '
'and every downstream function collapses in a predictable, explainable way.', BODY))
story.append(Spacer(1, 0.3*cm))
summary = [
['Sign / Symptom', 'Mechanism', 'Key Structure Lost'],
['Dysphagia\n(Case 1)', 'Swallowing center in medulla cannot receive/execute voluntary\nswallowing signal', 'Cortex → brainstem pathway\n+ CN V, IX, X, XII'],
['Fecal Incontinence\n(Case 1)', 'Voluntary EAS control lost; defecation becomes urgent/precipitous', 'Corticospinal tract to S2–S4\n+ Pudendal nerve'],
['Jaundice\n(Case 2)', 'Bilirubin conjugation fails; conjugated bilirubin regurgitates\ninto blood, deposits in sclera', 'Hepatocyte UDP-\nglucuronosyltransferase'],
['Easy Bruising\n(Case 2)', 'Reduced clotting factor synthesis + thrombocytopenia\nfrom splenomegaly', 'Liver synthetic function\n(Factors I, II, V, VII, IX, X, XI)'],
['Hypoglycemia\n(Case 2)', 'Glycogenolysis and gluconeogenesis impaired; excess\ninsulin escapes portal first-pass', 'Hepatocyte metabolic\nenzymes + glycogen stores'],
['Ascites\n(Case 2)', 'Portal HTN + ↓ albumin (↓ oncotic P) + RAAS activation\n→ fluid pours into peritoneum', 'Portal vascular architecture\n+ albumin synthesis'],
]
st = Table(summary, colWidths=[3.2*cm, 8.5*cm, 4*cm])
st.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('TEXTCOLOR', (0,0), (-1,0), W),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS',(0,1), (-1,-1), [SKY, W]),
('GRID', (0,0), (-1,-1), 0.5, GREY_MED),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('PADDING', (0,0), (-1,-1), 7),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), NAVY),
]))
story.append(st)
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph(
'References: Guyton & Hall Textbook of Medical Physiology | '
'Localization in Clinical Neurology 8e | '
'Robbins & Kumar Basic Pathology | '
'Sleisenger & Fordtran\'s GI & Liver Disease | '
'Tietz Textbook of Laboratory Medicine',
CITE))
# ─── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF built successfully.")
cd /tmp/workspace/gi-physiology-pdf && python3 build_pdf.py 2>&1
~/gi-physiology-pdf/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/gi-physiology-pdf/build_pdf.py'
cd /tmp/workspace/gi-physiology-pdf && python3 build_pdf.py 2>&1
GI Physiology Story
PDF Document · PDF
| Page | What's in it |
|---|---|
| 1 | Cover + table of contents |
| 2 | Case 1 story (Robert) + Diagram 1 (swallowing neural reflex arc with 5 sequential steps) + Diagram 2 (fecal continence: normal vs stroke, side-by-side) |
| 3 | Case 2 story (CLD) - jaundice section + Diagram 3 (bilirubin metabolism flowchart with diseased liver branch) |
| 4 | Coagulopathy + hypoglycemia story sections + Diagram 4 (split panel: clotting factors & glucose pathways, both normal vs diseased) |
| 5 | Ascites story + summary table + Diagram 5 (three-mechanism ascites wheel: portal HTN, hypoalbuminemia, RAAS) |