analyze and give suitable answers for 1st year mbbs student
cd /home/daytona/workspace/attachments/ea69af15-637b-4be7-adf1-5509f728b1a7/ && …
| # | Case Label | Diagnosis | Key Clues |
|---|---|---|---|
| 1 | Major | Myocardial Infarction | CK-MB 40%, ST elevation, chest pain |
| 2 | Major | Acute Pancreatitis | Amylase/Lipase >3x, hypocalcemia, hyperglycemia, alcohol |
| 3 | Major | Metabolic Syndrome | Obesity + HTN + hyperglycemia + acanthosis nigricans |
| 4 | Major | Von Gierke's Disease | Hypoglycemia + hepatomegaly + hyperuricemia + lactic acidosis + G6Pase deficiency |
| 5 | Major | Starvation Ketoacidosis | Pregnant + vomiting + hypoglycemia + Rothera+, Benedict- |
| 6 | Major | Gout | Uric acid 17.2, sodium urate crystals, after alcohol/purine meal |
| 7 | Major | Hemolytic Jaundice | Indirect bili dominant, post-transfusion, dark stools, acholuric |
| 8 | Major | Obstructive Jaundice (Cholelithiasis) | Direct bili dominant, ALP >>>, clay stools, absent urobilinogen |
| 9 | Major | Hepatic Jaundice | Both bili elevated, SGOT/SGPT very high, bile salts in urine |
| 10 | Major | Nephrotic Syndrome | Proteinuria >3.5g, hypoalbuminemia, hypercholesterolemia, edema |
| 11 | Major | Acute Glomerulonephritis | Post-streptococcal, hematuria, mild proteinuria, elevated urea/creatinine |
| 12 | Major | Hyperthyroidism (Graves') | Exophthalmos, weight loss, tachycardia, goitre, elevated T3/T4, low TSH |
| 13 | Major | Euthyroid | All TFTs normal |
| 14 | Major | Prostate Carcinoma | PSA 42, hard nodular prostate, elderly male |
| 15 | Major | Breast Carcinoma | Firm immobile mass, nipple retraction, postmenopausal |
| 16 | Major | DKA | Hyperglycemia + acidosis + Rothera+ + Benedict+, no insulin |
| 17 | Major | Respiratory Acidosis | Asthmatic, pH low, pCO2 high, HCO3 compensatorily high |
| 18 | Major | Respiratory Alkalosis | Anxiety, hyperventilation, pH high, pCO2 low, ionized Ca low |
| 19 | Major | NAFLD | Obese, T2DM, no alcohol, ALT>AST, Grade II fatty liver |
| 20 | Major | Phenylketonuria | High phenylalanine, urine keto acids, mental retardation, pale skin |
| 21/22 | Major | Kwashiorkor | Protein deficiency, edema, fatty liver, hair/skin changes, weaned child |
| 23 | Major | Starvation Ketoacidosis | Same as Case 5 |
| M1 | Minor | Galactosemia | GALT deficiency, cataract, mucic acid+, Benedict+, glucose- |
| M2 | Minor | Alkaptonuria | Homogentisate oxidase deficiency, darkening urine, ferric chloride+ |
| M3 | Minor | Homocystinuria | CBS deficiency, ectopia lentis, marfanoid, nitroprusside+, B6 non-responsive |
| M4 | Minor | MSUD | BCKDH deficiency, maple syrup urine, elevated LIV amino acids |
| M5 | Minor | Albinism | Tyrosinase deficiency, no melanin, pale skin/hair/eyes, AR |
| M6/7 | Minor | Vitamin A Deficiency | Night blindness, Bitot's spots, low retinol, low RBP |
| M8 | Minor | Rickets | Low calcitriol, high ALP, low Ca/PO4, bone deformities |
| M9/10 | Minor | Scurvy | Vitamin C deficiency, bleeding gums, petechiae, defective collagen |
| M11 | Minor | Beriberi (Wet) | Thiamine deficiency, polished rice, edema, cardiac failure |
| M12-14 | Minor | Pellagra | Niacin deficiency, corn diet, 4 D's: Dermatitis, Diarrhea, Dementia, Death |
| M15 | Minor | Megaloblastic Anemia | B12 + Folate deficiency, high MCV, hypersegmented neutrophils |
| M16 | Minor | Iron Deficiency Anemia | Low ferritin + low serum iron, microcytic, pica, brittle nails |
| M17 | Minor | Tetany | Post-thyroidectomy, hypoparathyroidism, hypocalcemia, carpopedal spasms |
| M18 | Minor | Goitre | Iodine deficiency/Hashimoto's, diffuse neck swelling, hypothyroid symptoms |
| M19 | Minor | Fluorosis | Excess fluoride, mottled teeth, skeletal stiffness, high serum F |
| M20 | Minor | Cystinuria | Renal COLA transporter defect, hexagonal crystals, nitroprusside+, kidney stones |
Create a study summary PDF with flow charts for case diagnosis
mkdir -p /home/daytona/workspace/mbbs-study-pdf && ls /home/daytona/workspace/mb…
~/mbbs-study-pdf/generate_pdf.py
#!/usr/bin/env python3
"""
MBBS 1st Year Biochemistry Case Study Summary PDF
with Diagnosis Flowcharts
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import (
HexColor, white, black, Color
)
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.graphics.shapes import (
Drawing, Rect, String, Line, Polygon, Arrow,
Group, Circle
)
from reportlab.graphics import renderPDF
import textwrap
# ─── COLOUR PALETTE ──────────────────────────────────────────────────────────
C_NAVY = HexColor('#1a2a4a')
C_BLUE = HexColor('#2563EB')
C_LIGHT_BLU = HexColor('#DBEAFE')
C_TEAL = HexColor('#0F766E')
C_TEAL_LT = HexColor('#CCFBF1')
C_RED = HexColor('#DC2626')
C_RED_LT = HexColor('#FEE2E2')
C_GREEN = HexColor('#16A34A')
C_GREEN_LT = HexColor('#DCFCE7')
C_ORANGE = HexColor('#D97706')
C_ORANGE_LT = HexColor('#FEF3C7')
C_PURPLE = HexColor('#7C3AED')
C_PURPLE_LT = HexColor('#EDE9FE')
C_GRAY = HexColor('#6B7280')
C_GRAY_LT = HexColor('#F3F4F6')
C_DARK = HexColor('#111827')
C_WHITE = white
PAGE_W, PAGE_H = A4
# ─── STYLES ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def make_style(name, **kw):
base = kw.pop('parent', 'Normal')
s = ParagraphStyle(name, parent=styles[base], **kw)
styles.add(s)
return s
TITLE_STYLE = make_style('MyTitle',
fontSize=26, leading=32, textColor=C_WHITE,
fontName='Helvetica-Bold', alignment=TA_CENTER, spaceAfter=6)
SUBTITLE_STYLE = make_style('MySubtitle',
fontSize=13, leading=18, textColor=HexColor('#BFDBFE'),
fontName='Helvetica', alignment=TA_CENTER, spaceAfter=4)
H1 = make_style('MyH1',
fontSize=16, leading=20, textColor=C_WHITE,
fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=2, spaceAfter=2)
H2 = make_style('MyH2',
fontSize=12, leading=16, textColor=C_NAVY,
fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=6, spaceAfter=3)
H3 = make_style('MyH3',
fontSize=10, leading=14, textColor=C_TEAL,
fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=4, spaceAfter=2)
BODY = make_style('MyBody',
fontSize=9, leading=13, textColor=C_DARK,
fontName='Helvetica', alignment=TA_LEFT,
spaceBefore=2, spaceAfter=2)
BODY_BOLD = make_style('MyBodyBold',
fontSize=9, leading=13, textColor=C_DARK,
fontName='Helvetica-Bold', alignment=TA_LEFT)
SMALL = make_style('MySmall',
fontSize=8, leading=11, textColor=C_GRAY,
fontName='Helvetica', alignment=TA_LEFT)
BULLET = make_style('MyBullet',
fontSize=9, leading=13, textColor=C_DARK,
fontName='Helvetica', leftIndent=14, bulletIndent=4,
bulletFontName='Helvetica', spaceAfter=1)
CENTER = make_style('MyCenter',
fontSize=9, leading=13, textColor=C_DARK,
fontName='Helvetica', alignment=TA_CENTER)
DIAG_LABEL = make_style('MyDiag',
fontSize=10, leading=13, textColor=C_WHITE,
fontName='Helvetica-Bold', alignment=TA_CENTER)
# ─── FLOWCHART HELPER ────────────────────────────────────────────────────────
class FlowChart(Flowable):
"""
Draws a linear diagnostic flowchart:
steps = list of dicts:
type: 'box' | 'diamond' | 'oval'
text: string
color: HexColor (fill)
tcolor: HexColor (text)
arrows between each step.
Fits into given width; height computed automatically.
"""
BOX_H = 34
DIAM_H = 38
OVAL_H = 32
ARROW_H = 18
PAD_X = 10
PAD_Y = 6
def __init__(self, steps, width=None, font_size=8):
super().__init__()
self.steps = steps
self._w = width or (PAGE_W - 4*cm)
self.font_size = font_size
# compute height
h = 6
for s in steps:
t = s.get('type', 'box')
if t == 'diamond': h += self.DIAM_H
elif t == 'oval': h += self.OVAL_H
else: h += self.BOX_H
h += self.ARROW_H
h -= self.ARROW_H
h += 6
self.height = h
self.width = self._w
def wrap(self, availW, availH):
return (self.width, self.height)
def draw(self):
c = self.canv
x0 = 0
cx = self._w / 2
y = self.height - 6
box_w = self._w * 0.72
bx = cx - box_w/2
for i, step in enumerate(self.steps):
t = step.get('type', 'box')
text = step.get('text', '')
fill = step.get('color', C_BLUE)
tcolor = step.get('tcolor', C_WHITE)
if t == 'oval':
sh = self.OVAL_H
elif t == 'diamond':
sh = self.DIAM_H
else:
sh = self.BOX_H
top = y
bot = y - sh
midY = (top + bot) / 2
if t == 'box':
c.setFillColor(fill)
c.setStrokeColor(C_NAVY)
c.setLineWidth(0.8)
c.roundRect(bx, bot, box_w, sh, 5, fill=1, stroke=1)
elif t == 'oval':
c.setFillColor(fill)
c.setStrokeColor(C_NAVY)
c.setLineWidth(0.8)
c.ellipse(bx, bot, bx+box_w, top, fill=1, stroke=1)
elif t == 'diamond':
mx = cx
pts = [mx, top, bx+box_w, midY, mx, bot, bx, midY]
p = c.beginPath()
p.moveTo(pts[0], pts[1])
p.lineTo(pts[2], pts[3])
p.lineTo(pts[4], pts[5])
p.lineTo(pts[6], pts[7])
p.close()
c.setFillColor(fill)
c.setStrokeColor(C_NAVY)
c.setLineWidth(0.8)
c.drawPath(p, fill=1, stroke=1)
# text
c.setFillColor(tcolor)
c.setFont('Helvetica-Bold', self.font_size)
lines = self._wrap_text(text, box_w - 2*self.PAD_X, self.font_size)
total_th = len(lines) * (self.font_size + 2)
ty = midY + total_th/2 - self.font_size
for ln in lines:
c.drawCentredString(cx, ty, ln)
ty -= (self.font_size + 2)
y = bot
# arrow
if i < len(self.steps) - 1:
ay_top = y
ay_bot = y - self.ARROW_H
c.setStrokeColor(C_GRAY)
c.setFillColor(C_GRAY)
c.setLineWidth(1.2)
c.line(cx, ay_top, cx, ay_bot + 5)
# arrowhead
aw = 5
p2 = c.beginPath()
p2.moveTo(cx, ay_bot)
p2.lineTo(cx - aw, ay_bot + 7)
p2.lineTo(cx + aw, ay_bot + 7)
p2.close()
c.drawPath(p2, fill=1, stroke=0)
y = ay_bot
def _wrap_text(self, text, max_w, fsize):
# estimate chars per line
char_w = fsize * 0.52
cpl = max(1, int(max_w / char_w))
return textwrap.wrap(text, width=cpl) or [text]
class SideBySideFlowChart(Flowable):
"""Two-column flowchart for comparison."""
STEP_H = 28
GAP_H = 16
PAD = 6
def __init__(self, left_steps, right_steps, left_title, right_title,
width=None, font_size=8):
super().__init__()
self._w = width or (PAGE_W - 4*cm)
self.font_size = font_size
self.left_steps = left_steps
self.right_steps = right_steps
self.left_title = left_title
self.right_title = right_title
n = max(len(left_steps), len(right_steps))
self.height = 28 + n*(self.STEP_H + self.GAP_H) + 10
self.width = self._w
def wrap(self, aw, ah):
return (self.width, self.height)
def draw(self):
c = self.canv
col_w = (self._w - 10) / 2
lx = 0
rx = col_w + 10
# headers
for x, title, color in [(lx, self.left_title, C_BLUE),
(rx, self.right_title, C_TEAL)]:
c.setFillColor(color)
c.setStrokeColor(color)
c.roundRect(x, self.height-24, col_w, 20, 4, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 9)
c.drawCentredString(x + col_w/2, self.height-17, title)
y = self.height - 30
for i in range(max(len(self.left_steps), len(self.right_steps))):
for steps, x, color in [(self.left_steps, lx, C_BLUE),
(self.right_steps, rx, C_TEAL)]:
if i < len(steps):
s = steps[i]
fill = s.get('color', color)
text = s.get('text', '')
c.setFillColor(fill)
c.setStrokeColor(HexColor('#94A3B8'))
c.setLineWidth(0.5)
c.roundRect(x, y-self.STEP_H, col_w, self.STEP_H, 4, fill=1, stroke=1)
c.setFillColor(s.get('tcolor', C_WHITE))
c.setFont('Helvetica-Bold', self.font_size)
lines = textwrap.wrap(text, width=int(col_w*0.17))
total_th = len(lines)*(self.font_size+2)
ty = (y - self.STEP_H/2) + total_th/2 - self.font_size
for ln in lines:
c.drawCentredString(x + col_w/2, ty, ln)
ty -= (self.font_size+2)
# downward arrow
if i < max(len(self.left_steps), len(self.right_steps))-1 and i < len(steps)-1:
ax = x + col_w/2
ay_t = y - self.STEP_H
ay_b = ay_t - self.GAP_H + 4
c.setStrokeColor(C_GRAY)
c.setFillColor(C_GRAY)
c.setLineWidth(1)
c.line(ax, ay_t, ax, ay_b+4)
aw2 = 4
p = c.beginPath()
p.moveTo(ax, ay_b)
p.lineTo(ax-aw2, ay_b+6)
p.lineTo(ax+aw2, ay_b+6)
p.close()
c.drawPath(p, fill=1, stroke=0)
y -= (self.STEP_H + self.GAP_H)
# ─── SECTION HEADER FLOWABLE ─────────────────────────────────────────────────
class SectionHeader(Flowable):
def __init__(self, title, subtitle='', color=C_NAVY, width=None):
super().__init__()
self.title = title
self.subtitle = subtitle
self.color = color
self._w = width or (PAGE_W - 4*cm)
self.height = 46 if subtitle else 36
def wrap(self, aw, ah):
return (self._w, self.height)
def draw(self):
c = self.canv
c.setFillColor(self.color)
c.roundRect(0, 0, self._w, self.height, 6, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 13)
ty = self.height - 18 if self.subtitle else (self.height-13)/2
c.drawString(12, ty, self.title)
if self.subtitle:
c.setFont('Helvetica', 8)
c.setFillColor(HexColor('#CBD5E1'))
c.drawString(12, 8, self.subtitle)
# ─── KEY BOX FLOWABLE ────────────────────────────────────────────────────────
def key_box(label, value, bg=C_LIGHT_BLU, fg=C_NAVY):
data = [[Paragraph(f'<b>{label}</b>', BODY_BOLD),
Paragraph(value, BODY)]]
t = Table(data, colWidths=['30%', '70%'])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), bg),
('BACKGROUND', (1,0), (1,-1), C_WHITE),
('TEXTCOLOR', (0,0), (-1,-1), fg),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('ROUNDEDCORNERS', [4]),
]))
return t
def info_table(rows, col_ratio=None, header_color=C_NAVY):
col_ratio = col_ratio or [35, 65]
cw = [(PAGE_W - 4*cm) * r/100 for r in col_ratio]
data = []
for i, row in enumerate(rows):
data.append([Paragraph(str(row[0]), BODY_BOLD if i==0 else BODY),
Paragraph(str(row[1]), BODY)])
t = Table(data, colWidths=cw)
ts = [
('BACKGROUND', (0,0), (-1,0), header_color),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]
t.setStyle(TableStyle(ts))
return t
def colored_box_para(text, bg=C_LIGHT_BLU, fg=C_NAVY, font_size=9):
data = [[Paragraph(text, ParagraphStyle('_tmp', fontSize=font_size,
fontName='Helvetica', textColor=fg,
leading=font_size+3))]]
t = Table(data, colWidths=[PAGE_W - 4*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 0.5, fg),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
('ROUNDEDCORNERS', [4]),
]))
return t
# ─── COVER PAGE ──────────────────────────────────────────────────────────────
def cover_page(story):
# gradient-like cover using a drawing
d = Drawing(PAGE_W - 4*cm, 160)
d.add(Rect(0, 0, PAGE_W-4*cm, 160,
fillColor=C_NAVY, strokeColor=None))
d.add(Rect(0, 120, PAGE_W-4*cm, 40,
fillColor=C_BLUE, strokeColor=None))
d.add(Rect(0, 0, 8, 160,
fillColor=C_TEAL, strokeColor=None))
story.append(Spacer(1, 0.3*cm))
story.append(d)
# overlay text as paragraphs AFTER the drawing
title_data = [[Paragraph(
'<font color="#FFFFFF"><b>1st Year MBBS Biochemistry</b></font>',
ParagraphStyle('ct', fontSize=20, fontName='Helvetica-Bold',
alignment=TA_CENTER, leading=26,
textColor=C_WHITE))]]
tt = Table(title_data, colWidths=[PAGE_W-4*cm])
tt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), C_NAVY),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
story.append(tt)
sub_data = [[Paragraph(
'<font color="#93C5FD"><b>Case Study Summary with Diagnosis Flowcharts</b></font>',
ParagraphStyle('cs', fontSize=12, fontName='Helvetica',
alignment=TA_CENTER, leading=16, textColor=HexColor('#93C5FD')))]]
st = Table(sub_data, colWidths=[PAGE_W-4*cm])
st.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), C_NAVY),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
]))
story.append(st)
# accent bar
story.append(HRFlowable(width='100%', thickness=3, color=C_TEAL))
story.append(Spacer(1, 0.4*cm))
# Quick guide table
story.append(Paragraph('📋 Cases Covered in This Summary', H2))
story.append(Spacer(1, 0.2*cm))
toc_data = [
['#', 'Case / Diagnosis', 'System', 'Page'],
['1', 'Myocardial Infarction', 'Cardiology', '2'],
['2', 'Acute Pancreatitis', 'GI / Pancreas', '3'],
['3', 'Metabolic Syndrome', 'Metabolism', '4'],
['4', "Von Gierke's Disease", 'Glycogen Metabolism','5'],
['5', 'Starvation Ketoacidosis', 'Metabolism', '6'],
['6', 'Gout', 'Purine Metabolism', '7'],
['7', 'Hemolytic Jaundice', 'Hepatology', '8'],
['8', 'Obstructive Jaundice', 'Hepatology', '9'],
['9', 'Hepatic Jaundice', 'Hepatology', '10'],
['10', 'Nephrotic Syndrome', 'Nephrology', '11'],
['11', 'Acute Glomerulonephritis', 'Nephrology', '12'],
['12', 'Hyperthyroidism', 'Endocrinology', '13'],
['13', 'DKA & Metabolic Acidosis', 'Metabolism', '14'],
['14', 'Respiratory Acidosis/Alkalosis', 'Acid-Base', '15'],
['15', 'NAFLD', 'Hepatology', '16'],
['16', 'Phenylketonuria', 'Amino Acid Metab', '17'],
['17', 'Kwashiorkor', 'Nutrition', '18'],
['M1', 'Galactosemia', 'Carb Metabolism', '19'],
['M2', 'Alkaptonuria', 'Amino Acid Metab', '19'],
['M3', 'Homocystinuria / MSUD', 'Amino Acid Metab', '20'],
['M4', 'Albinism', 'Amino Acid Metab', '20'],
['M5', 'Vitamin Deficiencies', 'Nutrition', '21'],
['M6', 'Anemias (IDA, Megaloblastic)', 'Hematology', '22'],
['M7', 'Tetany / Goitre / Fluorosis', 'Minerals', '22'],
['M8', 'Cystinuria', 'Amino Acid Metab', '23'],
]
cw = [1.0*cm, 7.5*cm, 4.5*cm, 1.5*cm]
toc_t = Table(toc_data, colWidths=cw)
toc_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_NAVY),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.2, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('ALIGN', (0,0), (0,-1), 'CENTER'),
('ALIGN', (3,0), (3,-1), 'CENTER'),
]))
story.append(toc_t)
story.append(PageBreak())
# ─── CASE BUILDERS ───────────────────────────────────────────────────────────
def add_case(story, number, title, system, color, flowchart_steps,
labs_rows, key_points, mnemonics=None, note=None):
"""Generic case adder."""
story.append(SectionHeader(
f'Case {number}: {title}',
subtitle=f'System: {system}',
color=color,
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
# flowchart
story.append(Paragraph('Diagnostic Flowchart', H3))
story.append(Spacer(1, 0.15*cm))
fc = FlowChart(flowchart_steps, width=PAGE_W-4*cm, font_size=8)
story.append(fc)
story.append(Spacer(1, 0.3*cm))
# labs
if labs_rows:
story.append(Paragraph('Key Lab Findings', H3))
story.append(Spacer(1, 0.1*cm))
story.append(info_table(labs_rows, header_color=color))
story.append(Spacer(1, 0.3*cm))
# key points
story.append(Paragraph('Key Points to Remember', H3))
for kp in key_points:
story.append(Paragraph(f'• {kp}', BULLET))
story.append(Spacer(1, 0.2*cm))
if mnemonics:
story.append(colored_box_para(f'<b>Mnemonic:</b> {mnemonics}',
bg=C_ORANGE_LT, fg=C_ORANGE))
story.append(Spacer(1, 0.2*cm))
if note:
story.append(colored_box_para(f'<b>Exam Tip:</b> {note}',
bg=C_PURPLE_LT, fg=C_PURPLE))
story.append(Spacer(1, 0.2*cm))
story.append(HRFlowable(width='100%', thickness=0.5, color=HexColor('#E5E7EB')))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD THE PDF
# ═══════════════════════════════════════════════════════════════════════════════
def build():
doc = SimpleDocTemplate(
'/home/daytona/workspace/mbbs-study-pdf/MBBS_Case_Study_Summary.pdf',
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm,
title='MBBS 1st Year Biochemistry Case Study Summary',
author='Orris AI',
subject='Case Studies with Diagnosis Flowcharts',
)
story = []
# ── COVER ────────────────────────────────────────────────────────────────
cover_page(story)
# ── CASE 1: MI ────────────────────────────────────────────────────────────
add_case(
story, '1', 'Myocardial Infarction', 'Cardiology / Cardiac Enzymes',
color=C_RED,
flowchart_steps=[
{'text': 'Severe retrosternal chest pain + Sweating + Hypertension', 'color': C_RED, 'type': 'oval'},
{'text': 'ECG: ST-segment elevation (STEMI)', 'color': HexColor('#B91C1C')},
{'text': 'Serum CK-MB elevated (>5% of Total CK)\nTotal CK elevated', 'color': HexColor('#991B1B')},
{'text': 'LDH elevated + Flipped LDH pattern (LDH1 > LDH2)', 'color': C_ORANGE},
{'text': 'SGOT elevated; SGPT normal/mildly elevated\n(rules out primary liver pathology)', 'color': HexColor('#92400E')},
{'text': 'DIAGNOSIS: ACUTE MYOCARDIAL INFARCTION', 'color': C_NAVY, 'type': 'oval', 'tcolor': C_WHITE},
],
labs_rows=[
['Parameter', 'Result', 'Normal', 'Interpretation'],
['Serum CK', '1150 IU/L', '30-200 IU/L', '↑↑ Elevated'],
['Serum CK-MB', '455 IU/L', '<5% total CK', '↑↑↑ ~40% - CARDIAC SOURCE'],
['LDH', '296 IU/L', '100-225 IU/L', '↑ Elevated'],
['SGOT (AST)', '106 IU/L', '10-40 IU/L', '↑ Elevated'],
['SGPT (ALT)', '25 IU/L', '7-40 IU/L', 'Normal'],
],
key_points=[
'CK isoenzymes: CK-MM (skeletal), CK-MB (cardiac), CK-BB (brain)',
'CK-MB rises 3-6h, peaks 12-24h, normalizes 48-72h after MI',
'CK-MB index (CK-MB/Total CK × 100) >5-6% = diagnostic of MI',
'Flipped LDH = LDH1 > LDH2 (normal: LDH2 > LDH1); appears day 2-3, persists 7-14 days',
'Most specific cardiac markers: Troponin I and Troponin T',
'SGOT elevated in MI (not liver); SGPT is more liver-specific',
],
mnemonics='CK-MB = Cardiac Killer MB | Troponin = GOLD STANDARD for MI',
note='In exam: Always mention CK-MB index (%) not just absolute value. Troponins are the gold standard - but CK-MB is still asked for 1st year.'
)
# ── CASE 2: PANCREATITIS ──────────────────────────────────────────────────
add_case(
story, '2', 'Acute Pancreatitis', 'GI / Pancreatic Enzymes',
color=C_ORANGE,
flowchart_steps=[
{'text': 'Severe epigastric pain radiating to BACK + Alcohol history', 'color': C_ORANGE, 'type': 'oval'},
{'text': 'Shock (BP 90/60), Epigastric tenderness + guarding', 'color': HexColor('#B45309')},
{'text': 'Serum Amylase >3× normal (1500 U/L)\nSerum Lipase >3× normal (3000 U/L)', 'color': HexColor('#92400E')},
{'text': 'Hyperglycemia (380 mg/dL)\nIslets of Langerhans destruction', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'Hypocalcemia (6.0 mg/dL)\nFat saponification by released lipases', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: ACUTE PANCREATITIS', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Parameter', 'Result', 'Normal', 'Significance'],
['Serum Amylase', '1500 U/L', '40-140 U/L', '↑↑↑ (10×) - Pancreatitis marker'],
['Serum Lipase', '3000 U/L', '10-140 U/L', '↑↑↑ More specific; persists longer'],
['Plasma Glucose', '380 mg/dL', '70-100 mg/dL', '↑↑ Islet cell destruction'],
['Serum Calcium', '6.0 mg/dL', '8.5-10.5 mg/dL', '↓↓ Fat saponification = poor prognosis'],
['Urine Sugar', '+++', 'Negative', 'Glucosuria (exceeds renal threshold)'],
],
key_points=[
'Lipase is more specific than amylase; rises later but persists longer (7-14 days vs 2-4 days)',
'Hypocalcemia mechanism: Lipases → fatty acids + glycerol → FA binds Ca²+ → calcium soaps',
'Hypocalcemia in pancreatitis = poor prognosis (Ranson\'s criteria)',
'Hyperglycemia: destruction of beta cells (insulin↓) + increased glucagon',
'Both amylase and lipase >3× normal = diagnostic of acute pancreatitis',
],
note='Exam favorite: WHY is calcium low in pancreatitis? Answer = Saponification of fat (Ca²+ chelation by fatty acids released by lipase activity on peripancreatic fat).'
)
# ── CASE 3: METABOLIC SYNDROME ────────────────────────────────────────────
add_case(
story, '3', 'Metabolic Syndrome', 'Endocrine / Metabolism',
color=C_PURPLE,
flowchart_steps=[
{'text': 'Obese woman (BMI 32) + Hypertension (160/110)', 'color': C_PURPLE, 'type': 'oval'},
{'text': 'Acanthosis nigricans (dark velvety skin)\n→ Sign of hyperinsulinemia', 'color': HexColor('#6D28D9')},
{'text': 'Random blood sugar 210 mg/dL\n→ Hyperglycemia', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'Sedentary lifestyle + Postmenopausal\nFatigue, polyuria, chest heaviness', 'color': HexColor('#7C3AED')},
{'text': 'NCEP-ATP III: ≥3 of 5 criteria met\n(Obesity, HTN, Hyperglycemia + likely ↑TG + ↓HDL)', 'color': HexColor('#4C1D95')},
{'text': 'DIAGNOSIS: METABOLIC SYNDROME', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Component', 'Criterion', 'This Patient'],
['Central Obesity', 'BMI >30 or WC >88cm (F)', 'BMI 32 ✓'],
['Hypertension', '≥130/85 mmHg', '160/110 ✓'],
['Fasting Hyperglycemia', '≥100 mg/dL', 'RBS 210 ✓'],
['Hypertriglyceridemia', '≥150 mg/dL', 'Likely ✓'],
['Low HDL', '<50 mg/dL (women)', 'Likely ✓'],
],
key_points=[
'Metabolic Syndrome = Syndrome X = Insulin Resistance Syndrome',
'Diagnosed when ≥3 of 5 NCEP-ATP III criteria are met',
'Insulin resistance: target cells fail to respond to insulin despite normal/high levels',
'Acanthosis nigricans = skin sign of hyperinsulinemia',
'Risks: T2DM (5×), CVD, NAFLD, PCOS, gout, sleep apnea',
'GLUT-4 translocation is impaired in insulin resistance (skeletal muscle, adipose)',
],
mnemonics='5 criteria: OHHFG - Obesity, Hypertension, Hyperglycemia, hyperlipidemia (↑TG), low HDL',
)
# ── CASE 4: VON GIERKE'S ──────────────────────────────────────────────────
add_case(
story, '4', "Von Gierke's Disease (GSD Type I)", 'Glycogen Storage / Carbohydrate Metabolism',
color=C_TEAL,
flowchart_steps=[
{'text': 'Infant: doll-like face, fat cheeks, massive hepatomegaly + enlarged kidneys', 'color': C_TEAL, 'type': 'oval'},
{'text': 'Severe fasting hypoglycemia (35 mg/dL)\nNo glucose release from liver', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'Lactic acidosis (90 mg/dL)\nG6P → glycolysis → excess lactate', 'color': HexColor('#0F766E')},
{'text': 'Hyperuricemia (10 mg/dL)\nPentose-P pathway ↑ + Lactate competes with urate excretion', 'color': HexColor('#B45309'), 'tcolor': C_WHITE},
{'text': 'Hypertriglyceridemia (400 mg/dL)\nExcess G6P → lipogenesis', 'color': HexColor('#7C3AED'), 'tcolor': C_WHITE},
{'text': 'Enzyme deficient: GLUCOSE-6-PHOSPHATASE\nGSD Type Ia', 'color': HexColor('#065F46')},
{'text': 'DIAGNOSIS: VON GIERKE\'S DISEASE', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Parameter', 'Result', 'Normal', 'Significance'],
['Fasting Glucose', '35 mg/dL', '70-110 mg/dL', '↓↓↓ Severe hypoglycemia'],
['Lactate', '90 mg/dL', '4.5-14.4 mg/dL', '↑↑↑ Lactic acidosis'],
['Uric Acid', '10 mg/dL', '<7 mg/dL', '↑ Hyperuricemia'],
['Triglycerides', '400 mg/dL', '<150 mg/dL', '↑↑ Hyperlipidemia'],
['ALT', '140 IU/L', '7-40 IU/L', '↑ Liver cell damage'],
['Urine Glucose', 'Negative', 'Negative', 'Normal (NOT hyperglycemic)'],
],
key_points=[
'Enzyme: Glucose-6-phosphatase (G6Pase) in liver/kidney ER',
'G6P cannot be dephosphorylated → no free glucose released → severe fasting hypoglycemia',
'Both glycogenolysis AND gluconeogenesis are blocked (both produce G6P)',
'Hypoglycemia + Lactic acidosis + Hyperuricemia + Hypertriglyceridemia = classic tetrad',
'Doll-like face = fat redistribution + hepatomegaly',
'Treatment: frequent feeds, raw cornstarch (slow glucose release)',
],
mnemonics='Von Gierke = No G6Pase = Glucose-6-P piles up = "Got 6 Problems": Hypoglycemia, Lactic acidosis, Hyperuricemia, Hypertriglyceridemia, Hepatomegaly, Renal enlargement',
note='Urine glucose is NEGATIVE - key differentiator from diabetes. Glucose is low (not high) so nothing crosses renal threshold.'
)
# ── CASE 5: STARVATION KETOACIDOSIS ──────────────────────────────────────
add_case(
story, '5', 'Starvation Ketoacidosis', 'Metabolism / Acid-Base',
color=HexColor('#D97706'),
flowchart_steps=[
{'text': 'Pregnant + prolonged vomiting (4 days) → Starvation state', 'color': HexColor('#D97706'), 'type': 'oval'},
{'text': 'No food intake → ↓Insulin → ↑Glucagon\nFat mobilization from adipose', 'color': HexColor('#B45309')},
{'text': 'Fatty acid β-oxidation → Excess Acetyl-CoA\nOxaloacetate depleted → Ketogenesis', 'color': HexColor('#92400E')},
{'text': 'Serum glucose LOW (40 mg/dL) - starvation\nBenedict\'s NEGATIVE (no glucosuria)', 'color': C_GREEN, 'tcolor': C_WHITE},
{'text': 'Rothera\'s POSITIVE (ketone bodies in urine)\npH 7.2, HCO₃ 15 mEq/L → Metabolic acidosis', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: STARVATION KETOACIDOSIS\n(Hyperemesis Gravidarum)', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Test', 'Result', 'Interpretation'],
['Serum Glucose', '40 mg/dL', '↓↓ Hypoglycemia (starvation)'],
['Blood pH', '7.2', '↓ Acidosis (normal 7.35-7.45)'],
['Serum HCO₃', '15 mEq/L', '↓ Metabolic acidosis'],
['Benedict\'s (urine)', 'Negative', 'No glucosuria = distinguishes from DKA'],
['Rothera\'s (urine)', 'Positive', 'Ketone bodies present'],
['Anion Gap', 'Elevated', 'Unmeasured ketoanions ↑'],
],
key_points=[
'KEY DIFFERENCE from DKA: Starvation ketosis has HYPOGLYCEMIA; DKA has HYPERGLYCEMIA',
'Benedict\'s negative in starvation (no glucose) vs positive in DKA',
'Rothera\'s test: sodium nitroprusside + ammonia → purple = acetoacetate/acetone',
'Anion Gap = Na - (Cl + HCO₃); elevated in ketoacidosis due to ketoanions',
'High Anion Gap Metabolic Acidosis: MUDPILES - Methanol, Uremia, DKA, Paraldehyde, Isoniazid, Lactic acidosis, Ethylene glycol, Salicylates',
],
mnemonics='Starvation vs DKA: "Starvation = Sugar Low; DKA = Sugar HIGH - both have ketones"',
note='Anion gap is ELEVATED in both starvation ketosis and DKA because both generate unmeasured ketoanions.'
)
# ── CASE 6: GOUT ──────────────────────────────────────────────────────────
add_case(
story, '6', 'Gout (Hyperuricemia)', 'Purine Metabolism',
color=HexColor('#7C3AED'),
flowchart_steps=[
{'text': 'Heavy alcohol + purine-rich meal → Acute joint pain\nRight great toe (1st MTP joint) - Podagra', 'color': HexColor('#7C3AED'), 'type': 'oval'},
{'text': 'Serum Uric Acid 17.2 mg/dL\n(Normal: <7.0 mg/dL in males) - VERY HIGH', 'color': HexColor('#6D28D9')},
{'text': 'Synovial fluid: SODIUM URATE CRYSTALS\n(negatively birefringent, needle-shaped)', 'color': HexColor('#4C1D95')},
{'text': 'Alcohol → ↑Lactate → Competes with urate for renal tubular secretion\n→ ↓Uric acid excretion', 'color': HexColor('#5B21B6')},
{'text': 'Other labs: FBS, Urea, Creatinine normal\n→ Primary Gout', 'color': C_GREEN, 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: ACUTE GOUTY ARTHRITIS', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Investigation', 'Result', 'Normal', 'Interpretation'],
['Fasting Blood Sugar','97 mg/dL', '70-100 mg/dL', 'Normal'],
['Blood Urea', '30 mg/dL', '10-40 mg/dL', 'Normal'],
['Serum Creatinine', '0.9 mg/dL', '0.6-1.2 mg/dL', 'Normal - No renal failure'],
['Serum Uric Acid', '17.2 mg/dL', '<7.0 mg/dL (M)','↑↑↑ Severe hyperuricemia'],
['Synovial fluid', 'Urate crystals','Absent', 'GOLD STANDARD - confirms gout'],
],
key_points=[
'Gout = crystal arthropathy due to monosodium urate deposition in joints',
'Most common site: 1st metatarsophalangeal joint (podagra)',
'Alcohol raises uric acid via: 1) Lactate competes with urate at renal tubule, 2) Beer contains purines',
'Treatment - Acute: NSAIDs, Colchicine (inhibits microtubules → blocks neutrophil migration)',
'Treatment - Long-term: Allopurinol (xanthine oxidase inhibitor) → blocks uric acid synthesis',
'Tophus = urate crystal deposits in soft tissue (ear, elbow, Achilles tendon)',
],
mnemonics='Allopurinol = ALL-O-PURINOL = blocks ALL purine → uric acid conversion (xanthine oxidase inhibitor)',
note='Colchicine mechanism: inhibits tubulin polymerization → prevents neutrophil chemotaxis to urate crystals → anti-inflammatory. NOT an analgesic.'
)
# ── JAUNDICE COMPARISON PAGE ───────────────────────────────────────────────
story.append(SectionHeader(
'Cases 7-9: Jaundice - Comparative Analysis',
subtitle='Hemolytic vs Hepatic vs Obstructive',
color=HexColor('#B45309'),
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph('Jaundice Diagnosis Flowchart', H3))
story.append(Spacer(1, 0.1*cm))
jaundice_fc = FlowChart([
{'text': 'Patient with Jaundice (yellow skin/sclera)', 'color': HexColor('#B45309'), 'type': 'oval'},
{'text': 'Measure: Total Bilirubin, Direct (Conjugated), Indirect (Unconjugated)\n+ ALP, SGOT, SGPT + Urine & Stool examination', 'color': HexColor('#92400E')},
{'text': 'Which bilirubin is predominantly elevated?', 'color': HexColor('#78350F'), 'type': 'diamond'},
{'text': 'INDIRECT >> DIRECT\n→ Hemolytic Jaundice\n• Normal ALP/SGOT/SGPT\n• Urine: No bile pigments (acholuric)\n• Stool: Dark (↑stercobilin)\n• Urobilinogen: ↑↑', 'color': HexColor('#B91C1C'), 'tcolor': C_WHITE},
{'text': 'BOTH elevated (Mixed)\n→ Hepatic Jaundice\n• ↑↑↑ SGOT/SGPT (>10× normal)\n• Urine: Bile pigments +\n• Stool: Normal colour\n• Urobilinogen: Present', 'color': HexColor('#15803D'), 'tcolor': C_WHITE},
{'text': 'DIRECT >> INDIRECT\n→ Obstructive Jaundice\n• ↑↑↑ ALP (>3×)\n• Urine: Dark (bile pigments +)\n• Stool: Clay/pale (no stercobilin)\n• Urobilinogen: ABSENT', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(jaundice_fc)
story.append(Spacer(1, 0.3*cm))
# comparison table
story.append(Paragraph('Quick Comparison Table', H3))
story.append(Spacer(1, 0.1*cm))
comp_data = [
['Parameter', 'Hemolytic', 'Hepatic', 'Obstructive'],
['Direct Bilirubin', '↑ (mild)', '↑↑', '↑↑↑'],
['Indirect Bilirubin', '↑↑↑', '↑↑', '↑ (mild)'],
['ALP', 'Normal', 'Mild ↑', '↑↑↑ (>>3×)'],
['SGOT/SGPT', 'Normal', '↑↑↑ (>>10×)', 'Mild ↑'],
['Urine Bile pigments','ABSENT', 'Present', 'Present'],
['Urine Urobilinogen', '↑↑↑', 'Present', 'ABSENT'],
['Stool colour', 'Dark', 'Normal', 'Clay/Pale'],
['Van den Bergh', 'Indirect +ve', 'Biphasic', 'Direct +ve'],
['Example', 'Mismatch transfusion', 'Viral hepatitis', 'Gallstones'],
]
cw2 = [3.5*cm, 3.5*cm, 3.5*cm, 3.5*cm]
ct = Table(comp_data, colWidths=cw2)
ct.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_NAVY),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('BACKGROUND', (0,1), (0,-1), HexColor('#F1F5F9')),
('TEXTCOLOR', (0,1), (0,-1), C_NAVY),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS',(1,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
]))
story.append(ct)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>Acholuric Jaundice:</b> Jaundice WITHOUT bile pigments in urine. Seen in hemolytic jaundice. '
'Unconjugated bilirubin is bound to albumin (water-insoluble) → cannot be filtered → urine remains pale despite jaundice.',
bg=C_RED_LT, fg=C_RED))
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>Biphasic Jaundice (Hepatic):</b> Both direct AND indirect bilirubin elevated. '
'Van den Bergh: both direct and indirect positive = "biphasic/prompt direct." SGOT:SGPT ratio <1 in viral hepatitis.',
bg=C_GREEN_LT, fg=C_GREEN))
story.append(PageBreak())
# ── CASE 10-11: RENAL ────────────────────────────────────────────────────
story.append(SectionHeader(
'Cases 10-11: Renal Diseases',
subtitle='Nephrotic Syndrome vs Nephritic Syndrome (Glomerulonephritis)',
color=HexColor('#1D4ED8'),
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Nephrotic vs Nephritic - Diagnosis Flowchart', H3))
renal_fc = FlowChart([
{'text': 'Child with oedema + urinary abnormalities', 'color': HexColor('#1D4ED8'), 'type': 'oval'},
{'text': 'Check: Urine protein, Blood urea/creatinine,\nSerum albumin, Cholesterol, Urine RBC', 'color': HexColor('#1E40AF')},
{'text': 'Massive proteinuria >3.5 g/day?\nHypoalbuminaemia? Hypercholesterolaemia?', 'color': HexColor('#1D4ED8'), 'type': 'diamond'},
{'text': 'YES → NEPHROTIC SYNDROME\n• Albumin <2.5 g/dL (very low)\n• Cholesterol >300 mg/dL\n• Urea/Creatinine: Normal initially\n• No hematuria\n• 8-year-old boy: Minimal Change Disease', 'color': HexColor('#1E40AF'), 'tcolor': C_WHITE},
{'text': 'NO → Check hematuria, azotemia, history of infection', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
{'text': 'NEPHRITIC SYNDROME (APSGN)\n• Dark brown urine (hematuria)\n• Proteinuria mild (not massive)\n• Albumin near normal (3.2 g/dL)\n• ↑↑ Urea/Creatinine (azotemia)\n• History of strep skin infection\n• Benzidine test POSITIVE', 'color': HexColor('#B91C1C'), 'tcolor': C_WHITE},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(renal_fc)
story.append(Spacer(1, 0.3*cm))
neph_comp = [
['Feature', 'Nephrotic Syndrome', 'Nephritic Syndrome (APSGN)'],
['Proteinuria', '>3.5 g/day (massive)', 'Mild (1-3 g/day)'],
['Serum Albumin', '<2.5 g/dL (very low)', 'Near normal (3.2)'],
['Cholesterol', '>300 mg/dL ↑↑', 'Normal (~200)'],
['Hematuria', 'Absent', 'Dark brown urine ✓'],
['Azotemia', 'Initially normal', 'Urea 90, Creat 2.5 ↑↑'],
['Hypertension', 'Can occur', 'Yes (160/110)'],
['Pathology', 'GBM permeability ↑', 'Immune complex deposition'],
['Typical age', '8-year-old boy', '10-year-old girl'],
['Cause', 'Minimal change disease', 'Post-streptococcal'],
['Benzidine test', 'Negative', 'POSITIVE (blood)'],
]
cn = [4*cm, 5.5*cm, 5.5*cm]
nct = Table(neph_comp, colWidths=cn)
nct.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), HexColor('#1D4ED8')),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('BACKGROUND', (0,1), (0,-1), HexColor('#F1F5F9')),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS',(1,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('ALIGN', (1,0), (-1,-1), 'CENTER'),
]))
story.append(neph_comp[0:0])
story.append(nct)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>Hypercholesterolemia in Nephrotic Syndrome:</b> Low albumin → low oncotic pressure → liver overcompensates '
'by synthesizing all proteins including VLDL/LDL → hyperlipidemia. Also: loss of LPL cofactors → impaired clearance.',
bg=C_LIGHT_BLU, fg=C_BLUE))
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>Benzidine Test Principle:</b> Hemoglobin has pseudoperoxidase activity. In presence of H₂O₂, hemoglobin '
'oxidizes benzidine (colorless) → blue-green color. Confirms hematuria.',
bg=C_RED_LT, fg=C_RED))
story.append(PageBreak())
# ── CASE 12: THYROID ─────────────────────────────────────────────────────
add_case(
story, '12', 'Hyperthyroidism (Graves\' Disease)', 'Endocrinology / Thyroid',
color=HexColor('#D97706'),
flowchart_steps=[
{'text': 'Weight loss + Increased appetite + Palpitations + Sweating + Exophthalmos', 'color': HexColor('#D97706'), 'type': 'oval'},
{'text': 'Pulse 100/min (tachycardia) + Enlarged thyroid (goiter)', 'color': HexColor('#B45309')},
{'text': 'TFT: Free T3 ↑↑, Free T4 ↑↑\nTSH ↓↓ (suppressed by negative feedback)', 'color': HexColor('#92400E')},
{'text': 'TSH Receptor Antibodies (TSI)\nAutoimmune stimulation of thyroid = Graves\'', 'color': HexColor('#78350F')},
{'text': 'Exophthalmos: TSI cross-react with retro-orbital fibroblasts\n→ GAG accumulation → proptosis', 'color': C_BLUE, 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: HYPERTHYROIDISM (GRAVES\')', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Parameter', 'Hyperthyroid', 'Hypothyroid', 'Normal'],
['TSH', '↓↓ (low)', '↑↑ (high)', '0.4-4.0 mIU/L'],
['Free T3', '↑↑', '↓', '2.3-4.2 pg/mL'],
['Free T4', '↑↑', '↓', '0.8-1.8 ng/dL'],
['Total T4', '↑', '↓', '4.5-12.5 µg/dL'],
['BMR', '↑↑ (elevated)', '↓ (reduced)', 'Baseline'],
],
key_points=[
'TSH is the BEST screening test for thyroid disease; most sensitive indicator',
'Free T3/T4 more accurate than total (not affected by TBG changes - pregnancy, OCP)',
'T3 stimulates Na+/K+-ATPase → ↑ BMR → weight loss, heat intolerance, sweating',
'Tachycardia: T3 upregulates β-adrenergic receptors + directly stimulates SA node',
'Exophthalmos unique to Graves\' (autoimmune); separate from thyroid hormone levels',
'Weight loss despite normal/increased appetite = hallmark of hyperthyroidism',
],
mnemonics='Hyper thyroid: SWEATING - Sweating, Weight loss, Eyes (proptosis), Agitation, Tachycardia, Irritability, ↑appetite, Nervousness, Goitre',
note='Free T3/T4 advantage: NOT affected by TBG levels. Pregnancy/OCP increase TBG → Total T4 appears high even in euthyroid. Free T4 stays normal = true status.'
)
# ── CASE 13: DKA + ACID BASE ─────────────────────────────────────────────
story.append(SectionHeader(
'Cases 13-14: DKA and Acid-Base Disorders',
subtitle='Metabolic Acidosis | Respiratory Acidosis | Respiratory Alkalosis',
color=C_RED,
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Acid-Base Diagnosis Flowchart', H3))
ab_fc = FlowChart([
{'text': 'Measure: Blood pH, pCO₂, HCO₃', 'color': C_RED, 'type': 'oval'},
{'text': 'pH < 7.35 = ACIDOSIS\npH > 7.45 = ALKALOSIS', 'color': HexColor('#B91C1C'), 'type': 'diamond'},
{'text': 'Acidosis: Is pCO₂ HIGH or HCO₃ LOW?', 'color': HexColor('#991B1B'), 'type': 'diamond'},
{'text': 'pCO₂ ↑↑ (>45) = RESPIRATORY ACIDOSIS\n(e.g., Asthma, COPD, pCO₂=82)\nKidney compensates: ↑HCO₃ reabsorption\nTreat: Bronchodilators, assisted ventilation', 'color': HexColor('#7F1D1D'), 'tcolor': C_WHITE},
{'text': 'HCO₃ ↓↓ (<22) = METABOLIC ACIDOSIS\n(e.g., DKA: pH 7.25, HCO₃ 15)\nLung compensates: Kussmaul\'s breathing ↓pCO₂\nHigh Anion Gap: DKA, Lactic acidosis, Uremia', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
{'text': 'Alkalosis: pCO₂ LOW = RESPIRATORY ALKALOSIS\n(e.g., Anxiety/hyperventilation: pH 7.6, pCO₂ 20)\n↓Ionized Ca²+ → Tetany/tingling\nKidney compensates: ↓HCO₃', 'color': C_GREEN, 'tcolor': C_WHITE},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(ab_fc)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Quick Acid-Base Summary Table', H3))
ab_data = [
['Disorder', 'pH', 'pCO₂', 'HCO₃', 'Cause', 'Compensation'],
['Resp. Acidosis', '↓', '↑↑', '↑', 'Asthma, COPD', 'Renal: ↑HCO₃ retain'],
['Resp. Alkalosis', '↑', '↓↓', '↓', 'Anxiety, altitude', 'Renal: ↓HCO₃ retain'],
['Metab. Acidosis', '↓', '↓', '↓↓', 'DKA, lactic acid', 'Lung: Kussmaul\'s ↓pCO₂'],
['Metab. Alkalosis', '↑', '↑', '↑↑', 'Vomiting, diuretics', 'Lung: ↓ventilation ↑pCO₂'],
]
ab_t = Table(ab_data, colWidths=[3*cm, 1.2*cm, 1.3*cm, 1.3*cm, 4*cm, 4.2*cm])
ab_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_NAVY),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('ALIGN', (1,0), (4,-1), 'CENTER'),
]))
story.append(ab_t)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>Kussmaul\'s Breathing (DKA):</b> Deep rapid respiration = respiratory compensation for metabolic acidosis. '
'Blows off CO₂ → reduces pCO₂ → raises pH toward normal. Patients have fruity/acetone breath (exhaled acetone).',
bg=C_RED_LT, fg=C_RED))
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>Why ionized Ca²+ falls in respiratory alkalosis:</b> Alkalosis → Albumin loses H⁺ → albumin becomes more '
'negatively charged → binds more Ca²+ → ionized Ca²+ decreases → tetany, tingling.',
bg=C_ORANGE_LT, fg=C_ORANGE))
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>Anion Gap = Na⁺ - (Cl⁻ + HCO₃⁻). Normal: 8-16 mEq/L.</b> HIGH in: DKA, Lactic acidosis, Uremia, '
'Methanol, Salicylates (MUDPILES). NORMAL in: Diarrhea, RTA (hyperchloremic acidosis).',
bg=C_LIGHT_BLU, fg=C_BLUE))
story.append(PageBreak())
# ── CASE 15: NAFLD ───────────────────────────────────────────────────────
add_case(
story, '15', 'NAFLD (Non-Alcoholic Fatty Liver Disease)', 'Hepatology / Lipid Metabolism',
color=C_TEAL,
flowchart_steps=[
{'text': 'Obese (BMI >30) + T2DM + Hypertension + NO ALCOHOL\nMetabolic Syndrome background', 'color': C_TEAL, 'type': 'oval'},
{'text': 'Insulin resistance → Hyperinsulinemia\n↑ De novo lipogenesis in liver + ↓ β-oxidation', 'color': HexColor('#0F766E')},
{'text': 'Excess TG accumulates in hepatocytes → STEATOSIS\nSimple fatty liver = Grade I-II on ultrasound', 'color': HexColor('#065F46')},
{'text': 'Oxidative stress + TNF-α, IL-6 → hepatocyte apoptosis\nNASH = Steatosis + INFLAMMATION', 'color': C_ORANGE, 'tcolor': C_WHITE},
{'text': 'ALT 108, AST 95 (ALT > AST)\nHbA1c 8.4%, Hypertriglyceridemia\nUSG: Grade II echogenic (fatty) liver', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: NAFLD / NASH', 'color': C_NAVY, 'type': 'oval'},
],
labs_rows=[
['Parameter', 'Result', 'Significance'],
['ALT', '108 U/L', '↑ Cytoplasmic enzyme - hepatocellular damage'],
['AST', '95 U/L', '↑ Mitochondrial enzyme - hepatocellular damage'],
['ALT:AST', '>1 (1.13)', 'ALT > AST in NAFLD (vs AST > ALT in alcohol)'],
['HbA1c', '8.4%', 'Poor glycemic control → drives lipogenesis'],
['TG', 'Elevated', 'Dyslipidemia of insulin resistance'],
['USG', 'Grade II', 'Echogenic liver = fat infiltration'],
],
key_points=[
'NAFLD requires ABSENCE of significant alcohol consumption (<20g/day women, <30g/day men)',
'ALT > AST in NAFLD; AST:ALT >2:1 in ALCOHOLIC liver disease',
'Mechanism: Insulin resistance → ↑fatty acids → hepatic steatosis → NASH → cirrhosis → HCC',
'HbA1c reflects 3-month average blood glucose; 8.4% = prolonged poor control',
'Treatment: Weight loss (10%+ reduces liver fat), diabetes control, exercise',
],
note='Key differentiator: In NAFLD ALT>AST. In ALCOHOLIC liver disease AST>ALT (ratio >2:1). No alcohol history is essential for NAFLD diagnosis.'
)
# ── AMINO ACIDOPATHIES ────────────────────────────────────────────────────
story.append(SectionHeader(
'Case 16: Amino Acid Disorders - PKU, Alkaptonuria, Homocystinuria, MSUD',
subtitle='Inborn Errors of Amino Acid Metabolism',
color=HexColor('#4F46E5'),
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('PKU Diagnosis Flowchart', H3))
pku_fc = FlowChart([
{'text': 'Infant: Mental retardation + Seizures + Delayed milestones + Pale skin', 'color': HexColor('#4F46E5'), 'type': 'oval'},
{'text': 'Serum phenylalanine >> 50 mg/dL (normal <1.2)\nUrine: phenylpyruvate +++ , phenylacetate +++', 'color': HexColor('#4338CA')},
{'text': 'ENZYME DEFICIENT: Phenylalanine Hydroxylase (PAH)\n+ cofactor Tetrahydrobiopterin (BH4)', 'color': HexColor('#3730A3')},
{'text': 'Phenylalanine → Phenylpyruvate (toxic)\n→ Brain damage, seizures', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'Hypopigmentation: Tyr deficient → ↓Melanin\n(Phenylalanine → Tyrosine is blocked)', 'color': HexColor('#6D28D9'), 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: PHENYLKETONURIA (PKU)\nTreatment: Phenylalanine-restricted diet', 'color': C_NAVY, 'type': 'oval'},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(pku_fc)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Comparison: Major Amino Acid Disorders', H3))
aa_data = [
['Disorder', 'Enzyme Deficient', 'Urine Test', 'Key Feature'],
['PKU', 'Phenylalanine Hydroxylase', 'Ferric chloride (green/blue)\nPhenylpyruvate +++', 'Mental retardation\nPale skin'],
['Alkaptonuria', 'Homogentisate Oxidase', 'Ferric chloride +ve\nDarkens on standing', 'Dark urine\nOchronosis (adults)'],
['Homocystinuria', 'Cystathionine β-Synthase', 'Cyanide nitroprusside +', 'Ectopia lentis\nThromboembolism'],
['MSUD', 'BCKDH complex', 'DNPH test (keto acids)', 'Maple syrup urine\nBCCA elevated'],
['Albinism', 'Tyrosinase', 'None', 'No melanin\nPhotosensitivity'],
['Cystinuria', 'Renal COLA transporter', 'Cyanide nitroprusside +\nHexagonal crystals', 'Kidney stones\nCOLA amino acids ↑'],
]
aa_t = Table(aa_data, colWidths=[3.2*cm, 3.8*cm, 3.8*cm, 4.2*cm])
aa_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), HexColor('#4F46E5')),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(aa_t)
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>COLA in Cystinuria:</b> Cystine, Ornithine, Lysine, Arginine - dibasic amino acids. Renal transporter defect → all 4 in urine. '
'Only cystine precipitates (least soluble) → hexagonal crystals → kidney stones.',
bg=C_LIGHT_BLU, fg=C_BLUE))
story.append(PageBreak())
# ── CASE 17: KWASHIORKOR ──────────────────────────────────────────────────
story.append(SectionHeader(
'Case 17: Protein Energy Malnutrition',
subtitle='Kwashiorkor vs Marasmus',
color=HexColor('#B45309'),
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Kwashiorkor Diagnosis Flowchart', H3))
kw_fc = FlowChart([
{'text': '2-3 year old child, abruptly weaned, diet = mainly carbohydrates\n(rice gruel, boiled potatoes)', 'color': HexColor('#B45309'), 'type': 'oval'},
{'text': 'Pitting edema (legs/hands/face)\nDistended abdomen, hepatomegaly', 'color': HexColor('#92400E')},
{'text': 'Serum albumin ↓↓ (1.8 g/dL)\nSerum protein ↓ (4 g/dL)', 'color': HexColor('#78350F')},
{'text': 'Low albumin → Low oncotic pressure\n→ Fluid leaks to interstitium → EDEMA', 'color': C_BLUE, 'tcolor': C_WHITE},
{'text': 'Fatty liver: ↓Apolipoprotein B → VLDL not formed\n→ TG accumulates in hepatocytes', 'color': C_RED, 'tcolor': C_WHITE},
{'text': 'Hair: depigmented (flag sign), easily pluckable\nSkin: flaky paint dermatosis\nAnemia: Hb 6.5 g/dL', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: KWASHIORKOR\nTreat: F-75 → F-100 → RUTF', 'color': C_NAVY, 'type': 'oval'},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(kw_fc)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Kwashiorkor vs Marasmus Comparison', H3))
pem_data = [
['Feature', 'Kwashiorkor', 'Marasmus'],
['Definition', 'Protein deficiency', 'Total calorie deficiency'],
['Edema', 'YES (hallmark)', 'NO'],
['Body weight', 'Near normal/slightly low', 'Very low (<60% expected)'],
['Serum albumin', 'Very low (<2.5 g/dL)', 'Low but less severe'],
['Fatty liver', 'YES (↓ApoB)', 'NO'],
['Appearance', 'Moon face, pot belly', 'Skin and bones, wasted'],
['Hair changes', 'Depigmented, flag sign', 'Sparse, dull'],
['Skin', 'Flaky paint dermatosis', 'Loose, wrinkled'],
['Age', '6 months-3 years', '< 1 year'],
['Treatment', 'F-75, F-100, RUTF', 'F-75, F-100, RUTF'],
]
pem_t = Table(pem_data, colWidths=[4.5*cm, 5.5*cm, 5*cm])
pem_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), HexColor('#B45309')),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(pem_t)
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>Protein Sparing Effect:</b> Adequate carbohydrates/fats spare protein from being used as energy → proteins used for synthesis. '
'In Kwashiorkor: despite adequate calories (carbs), protein is absent → no protein available for synthesis → edema, fatty liver.',
bg=C_ORANGE_LT, fg=C_ORANGE))
story.append(PageBreak())
# ── MINOR CASES VITAMIN DEFICIENCIES ─────────────────────────────────────
story.append(SectionHeader(
'Minor Cases: Vitamin Deficiencies',
subtitle='Vitamins A, D, C, B1, B3, B12/Folate',
color=C_GREEN,
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
vit_data = [
['Vitamin', 'Deficiency Disease', 'Key Biochemistry', 'Clinical Features', 'Diagnosis'],
['A\n(Retinol)', 'Xerophthalmia\nNight blindness', '11-cis-retinal needed for rhodopsin (rod cells)', 'Night blindness (first sign)\nBitot\'s spots\nKeratomalacia\nDry rough skin', 'Low serum retinol\nLow RBP'],
['D\n(Calcitriol)', 'Rickets (children)\nOsteomalacia (adults)', 'Calcitriol regulates Ca²+/PO₄ absorption\n↓Ca, ↓PO₄ → ↓bone mineralization', 'Bow legs, pigeon chest\nRachitic rosary\nDelayed dentition\nHarrison\'s sulcus', 'Low calcitriol\nLow Ca/PO₄\n↑ALP (osteoblast)'],
['C\n(Ascorbic acid)', 'Scurvy', 'Cofactor for prolyl/lysyl hydroxylase\n→ Defective collagen synthesis', 'Bleeding gums\nPerifollicular hemorrhages\nCorkscrew hairs\nPoor wound healing\nAnemia', 'Low blood vit. C\n<0.2 mg/dL'],
['B1\n(Thiamine)', 'Beriberi\nWernicke-Korsakoff', 'TPP coenzyme for:\nPyruvate DH\nα-KG DH\nTransketolase', 'Wet: edema, cardiac failure\nDry: peripheral neuropathy\nWK: ophthalmoplegia, ataxia, confusion', 'Low RBC transketolase\nPolished rice diet'],
['B3\n(Niacin)', 'Pellagra', 'NAD+/NADP+ synthesis\n60mg Trp = 1mg Niacin', '4 Ds: Dermatitis (sun-exposed)\nDiarrhea, Dementia, Death\nCasal\'s necklace', 'Maize/corn diet\nLow urine N-methyl nicotinamide'],
['B12 + Folate', 'Megaloblastic Anemia', 'DNA synthesis: dUMP → dTMP\nB12: methylmalonyl-CoA mutase\nMethyl THF trap', 'High MCV\nHypersegmented neutrophils\nGlossitis, fatigue\nB12: subacute combined degeneration', 'Low B12 (<200 pg/mL)\nLow folate\n↑MCV, ↑homocysteine'],
]
vit_t = Table(vit_data, colWidths=[1.5*cm, 2.3*cm, 3.8*cm, 4*cm, 3.4*cm])
vit_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_GREEN),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GREEN_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(vit_t)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>B12 vs Folate Deficiency:</b> Both cause megaloblastic anemia (high MCV). '
'ONLY B12 deficiency causes neurological damage (subacute combined degeneration of spinal cord). '
'Folate deficiency in pregnancy → neural tube defects. Never give folate alone without ruling out B12 deficiency.',
bg=C_GREEN_LT, fg=C_GREEN))
story.append(PageBreak())
# ── MINOR CASES - ANEMIAS + MINERALS ─────────────────────────────────────
story.append(SectionHeader(
'Minor Cases: Anemias, Minerals & Miscellaneous',
subtitle='Iron Deficiency | Tetany | Goitre | Fluorosis | Galactosemia',
color=HexColor('#1D4ED8'),
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Iron Deficiency Anemia - Diagnosis Flowchart', H3))
ida_fc = FlowChart([
{'text': 'Young female: fatigue, breathlessness, brittle nails, hair fall, pica (ice chewing)', 'color': HexColor('#1D4ED8'), 'type': 'oval'},
{'text': 'CBC: Low Hb, Low MCV (microcytic), Low MCH (hypochromic)', 'color': HexColor('#1E40AF')},
{'text': 'Serum Ferritin LOW (8 ng/mL)\n= MOST SPECIFIC test for iron stores', 'color': HexColor('#1D4ED8')},
{'text': 'Serum Iron LOW (25 mcg/dL)\nTIBC HIGH (iron binding sites unfilled)', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
{'text': 'DIAGNOSIS: IRON DEFICIENCY ANEMIA\nStages: 1) Depleted stores (↓ferritin)\n2) Latent IDA (↓iron, ↑TIBC)\n3) Frank IDA (↓Hb)', 'color': C_NAVY, 'type': 'oval'},
], width=PAGE_W-4*cm, font_size=7.5)
story.append(ida_fc)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Minerals Summary: Tetany / Goitre / Fluorosis', H3))
story.append(Spacer(1, 0.1*cm))
min_data = [
['Condition', 'Cause', 'Key Biochemistry', 'Clinical', 'Treatment'],
['Tetany\n(Post-thyroidectomy)', 'Accidental parathyroid removal → ↓PTH → ↓Ca²+', '↓Ionized Ca²+ → nerve hyperexcitability', 'Chvostek\'s sign\nTrousseau\'s sign\nCarpopedal spasm\nParesthesias', 'IV Ca gluconate (emergency)\nOral Ca + Calcitriol'],
['Goitre', 'Iodine deficiency (or Hashimoto\'s)', '↓Iodine → ↓T3/T4 → ↑TSH → thyroid hypertrophy', 'Neck swelling (moves on swallowing)\nHypothyroid symptoms\nCold intolerance, menstrual irregularity', 'Iodized salt\nLevothyroxine\nAnti-TPO for Hashimoto'],
['Fluorosis', 'Excess fluoride (drinking water >1.5 mg/L)', 'Fluoride inhibits ameloblasts\nF replaces OH in hydroxyapatite → fluorapatite', 'Mottled brown-black teeth\nSkeletal stiffness\n↑ALP (osteoblast)', 'Remove from fluoride source\nCa supplementation'],
]
min_t = Table(min_data, colWidths=[2*cm, 3.2*cm, 3.5*cm, 3.5*cm, 2.8*cm])
min_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), HexColor('#1D4ED8')),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_LIGHT_BLU]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(min_t)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Galactosemia & Other Carbohydrate Disorders', H3))
gal_data = [
['Disorder', 'Enzyme Defect', 'Urine Test', 'Key Feature', 'Treatment'],
['Galactosemia', 'Galactose-1-P Uridylyltransferase (GALT)', 'Benedict\'s +ve\nMucic acid +ve\nGlucose -ve', 'Cataract\n(galactitol in lens)\nLiver damage', 'Lactose-free diet'],
['Von Gierke\'s', 'Glucose-6-Phosphatase', 'Urine glucose NEGATIVE', 'Severe hypoglycemia\nHepatomegaly', 'Frequent feeds\nCornstarch'],
]
gal_t = Table(gal_data, colWidths=[2.5*cm, 3.5*cm, 3*cm, 3*cm, 3*cm])
gal_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_TEAL),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_TEAL_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(gal_t)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>Cataract in Galactosemia:</b> Galactose accumulates → aldose reductase converts galactose → galactitol in the lens. '
'Galactitol is osmotically active and cannot leave the lens → lens swells → cataract. Treatment: remove galactose from diet immediately.',
bg=C_TEAL_LT, fg=C_TEAL))
story.append(PageBreak())
# ── PROSTATE + BREAST CARCINOMA ───────────────────────────────────────────
story.append(SectionHeader(
'Tumour Markers: Prostate & Breast Carcinoma',
subtitle='PSA, CA 15-3, CEA, HER-2',
color=C_NAVY,
width=PAGE_W - 4*cm
))
story.append(Spacer(1, 0.3*cm))
tm_data = [
['Cancer', 'Primary Marker', 'Other Markers', 'Normal Value', 'Uses'],
['Prostate Ca', 'PSA', 'Free PSA/Total PSA ratio\nProstatic Acid Phosphatase (PAP)\nALP (bone mets)', '<4 ng/mL\n(>10 = malignancy likely)', 'Screening, staging\nMonitoring treatment\nDetect recurrence'],
['Breast Ca', 'CA 15-3', 'CA 27.29\nCEA\nHER-2/neu (ErbB2)\nER/PR receptors\nBRCA1/BRCA2', '<30 U/mL', 'Monitoring metastatic\nTreatment response\nHER-2 = trastuzumab target'],
]
tm_t = Table(tm_data, colWidths=[2.5*cm, 3*cm, 4.5*cm, 2.5*cm, 2.5*cm])
tm_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_NAVY),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(tm_t)
story.append(Spacer(1, 0.3*cm))
story.append(colored_box_para(
'<b>Definition of Tumour Marker:</b> A substance produced by tumour cells or by the body in response to cancer, '
'detectable in blood/urine/tissue. Used for: Screening | Diagnosis | Monitoring treatment | Detecting recurrence | Prognosis. '
'No marker is 100% specific - must be interpreted with clinical context.',
bg=C_GRAY_LT, fg=C_NAVY))
story.append(Spacer(1, 0.2*cm))
story.append(colored_box_para(
'<b>PSA:</b> Prostate Specific Antigen = serine protease produced by prostate epithelium. '
'PSA <4 normal; 4-10 = "grey zone"; >10 = high malignancy risk. '
'Low free/total PSA ratio (<10%) suggests malignancy. Can also be elevated in BPH, prostatitis.',
bg=C_LIGHT_BLU, fg=C_BLUE))
story.append(Spacer(1, 0.3*cm))
# Final summary mnemonics page
story.append(Paragraph('Master Mnemonic Summary', H2))
story.append(Spacer(1, 0.1*cm))
mnemo_data = [
['Topic', 'Mnemonic / Key Point'],
['Essential Amino Acids (9)', 'PVT TIM HaLL: Phe, Val, Thr, Trp, Ile, Met, His, Arg(semi), Leu, Lys'],
['MUDPILES (High AG acidosis)', 'Methanol, Uremia, DKA, Propylene glycol, Isoniazid/Iron, Lactic acidosis, Ethylene glycol, Salicylates'],
['Metabolic Syndrome (5 criteria)', 'OHHFL: Obesity, Hypertension, Hyperglycemia, Fat (↑TG), Low HDL'],
['Pellagra 4 Ds', 'Dermatitis (sun-exposed), Diarrhea, Dementia, Death'],
['Gout treatment', 'ANCP: Acute=NSAIDs/Colchicine; Chronic=allopurinol (xanthine oxidase inhibitor)'],
['Jaundice differentials', 'H-H-O: Hemolytic(↑indirect, no bile in urine), Hepatic(both, ↑SGPT), Obstructive(↑direct, ↑ALP, clay stool)'],
['Von Gierke\'s tetrad', 'HLLU: Hypoglycemia, Lactic acidosis, ↑Lipids, Uric acid ↑'],
['COLA amino acids (Cystinuria)','Cystine, Ornithine, Lysine, Arginine'],
['Kwashiorkor vs Marasmus', 'K=edema(+), Protein deficient. M=wasted, Total calorie deficient'],
['DKA vs Starvation ketosis', 'DKA: HIGH glucose + ketones. Starvation: LOW glucose + ketones'],
['Acid-base primary changes', 'pH and pCO2 move OPPOSITE in respiratory; pH and HCO3 move SAME in metabolic'],
]
mn_t = Table(mnemo_data, colWidths=[5*cm, 10*cm])
mn_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_NAVY),
('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_ORANGE_LT]),
('BOX', (0,0), (-1,-1), 0.5, C_GRAY),
('INNERGRID', (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(mn_t)
doc.build(story)
print("PDF generated successfully!")
if __name__ == '__main__':
build()
cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1
~/mbbs-study-pdf/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mbbs-study-pdf/generate_pdf.py'
cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1
"story.append(neph_comp[0:0])" in ~/mbbs-study-pdf
~/mbbs-study-pdf/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mbbs-study-pdf/generate_pdf.py'
cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1
ls -lh /home/daytona/workspace/mbbs-study-pdf/MBBS_Case_Study_Summary.pdf
MBBS Case Study Summary
PDF Document · PDF
| Section | Content |
|---|---|
| Cover Page | Full index/table of contents with all 26 cases |
| Case 1 - MI | Flowchart: Chest pain → CK-MB index → Flipped LDH → Diagnosis. CK isoenzyme table. |
| Case 2 - Pancreatitis | Flowchart: Epigastric pain → Amylase/Lipase → Hypocalcemia mechanism |
| Case 3 - Metabolic Syndrome | NCEP-ATP III criteria table, insulin resistance |
| Case 4 - Von Gierke's | Flowchart: Doll-face infant → G6Pase deficiency → HLLU tetrad |
| Case 5 - Starvation Ketoacidosis | Starvation vs DKA comparison flowchart |
| Case 6 - Gout | Uric acid pathway, Allopurinol mechanism |
| Cases 7-9 - Jaundice | 3-way comparison flowchart + full comparison table (Hemolytic / Hepatic / Obstructive) |
| Cases 10-11 - Renal | Nephrotic vs Nephritic side-by-side diagnosis flowchart + comparison table |
| Case 12 - Hyperthyroidism | TFT interpretation table, Graves' mechanism |
| Cases 13-14 - Acid-Base | Master flowchart: pH → pCO₂/HCO₃ → diagnosis + all 4 disorders table |
| Case 15 - NAFLD | ALT vs AST pattern table |
| Case 16 - Amino Acidopathies | PKU flowchart + comparison table (PKU, Alkaptonuria, Homocystinuria, MSUD, Albinism, Cystinuria) |
| Case 17 - Kwashiorkor | Kwashiorkor vs Marasmus comparison table |
| Minor Cases | Vitamins A/D/C/B1/B3/B12 summary table; IDA flowchart; Tetany/Goitre/Fluorosis; Galactosemia |
| Tumour Markers | PSA, CA 15-3, HER-2 table |
| Master Mnemonics | All key mnemonics in one table (PVT TIM HaLL, MUDPILES, HLLU, COLA, 4D's, etc.) |
i'm unable to download
ls -lh /home/daytona/workspace/mbbs-study-pdf/ && file /home/daytona/workspace/m…
# Copy to workspace root for easier access, also try base64 encoding for direct …
MBBS Case Study Summary
PDF Document · PDF
/home/daytona/workspace/MBBS_Case_Study_Summary.pdf