~/physiology-viva/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import ListFlowable, ListItem
OUTPUT = "/tmp/workspace/physiology-viva/Physiology_Viva_Guide.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm,
title="Physiology Viva Preparation Guide",
author="Orris Medical AI"
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle('TitleStyle', parent=styles['Title'],
fontSize=22, textColor=colors.HexColor('#1a237e'),
spaceAfter=6, alignment=TA_CENTER, fontName='Helvetica-Bold')
subtitle_style = ParagraphStyle('SubtitleStyle', parent=styles['Normal'],
fontSize=11, textColor=colors.HexColor('#5c6bc0'),
spaceAfter=4, alignment=TA_CENTER)
section_style = ParagraphStyle('SectionStyle', parent=styles['Heading1'],
fontSize=14, textColor=colors.white,
backColor=colors.HexColor('#1a237e'),
spaceBefore=12, spaceAfter=6,
borderPad=6, fontName='Helvetica-Bold',
leftIndent=-0.5*cm, rightIndent=-0.5*cm)
subsection_style = ParagraphStyle('SubsectionStyle', parent=styles['Heading2'],
fontSize=12, textColor=colors.HexColor('#283593'),
spaceBefore=10, spaceAfter=4,
fontName='Helvetica-Bold',
borderPad=3)
q_style = ParagraphStyle('QStyle', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#b71c1c'),
spaceBefore=8, spaceAfter=2,
fontName='Helvetica-Bold',
leftIndent=0.3*cm)
a_style = ParagraphStyle('AStyle', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#1b1b1b'),
spaceBefore=2, spaceAfter=4,
fontName='Helvetica',
leftIndent=0.6*cm,
leading=14)
bullet_style = ParagraphStyle('BulletStyle', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#1b1b1b'),
spaceBefore=1, spaceAfter=1,
fontName='Helvetica',
leftIndent=1.2*cm,
bulletIndent=0.8*cm,
leading=14)
highlight_style = ParagraphStyle('HighlightStyle', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#1b1b1b'),
spaceBefore=3, spaceAfter=3,
fontName='Helvetica',
leftIndent=0.6*cm,
backColor=colors.HexColor('#fff9c4'),
borderPad=4, leading=14)
normal_style = ParagraphStyle('NormalStyle', parent=styles['Normal'],
fontSize=10, leading=14, spaceAfter=4,
fontName='Helvetica')
def Q(text):
return Paragraph(f"Q: {text}", q_style)
def A(text):
return Paragraph(text, a_style)
def Bullet(text):
return Paragraph(f"• {text}", bullet_style)
def SectionHeader(text):
return Paragraph(f" {text}", section_style)
def SubSection(text):
return Paragraph(f"🔹 {text}", subsection_style)
def Highlight(text):
return Paragraph(text, highlight_style)
def make_table(headers, rows, col_widths=None):
data = [headers] + rows
if col_widths is None:
col_widths = [4*cm] * len(headers)
t = Table(data, colWidths=col_widths)
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#3949ab')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
]))
return t
story = []
# ===================== TITLE PAGE =====================
story.append(Spacer(1, 1.5*cm))
story.append(Paragraph("PHYSIOLOGY VIVA", title_style))
story.append(Paragraph("PREPARATION GUIDE", title_style))
story.append(Spacer(1, 0.3*cm))
story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor('#5c6bc0')))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("General Physiology · Hematology · Biophysics · Endocrine System", subtitle_style))
story.append(Paragraph("Thyroid · Parathyroid · Anterior Pituitary", subtitle_style))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Source: Ganong's Review of Medical Physiology | Guyton & Hall Textbook of Medical Physiology", subtitle_style))
story.append(Spacer(1, 0.5*cm))
# ===================== SECTION 1: GENERAL PHYSIOLOGY =====================
story.append(SectionHeader("SECTION 1: GENERAL PHYSIOLOGY"))
story.append(Spacer(1, 0.2*cm))
story.append(SubSection("Cell Membrane & Transport"))
story.append(Q("What is the composition of the cell membrane?"))
story.append(A("The cell membrane is a <b>lipid bilayer</b> embedded with proteins. Phospholipids have hydrophilic heads facing outward and hydrophobic tails facing inward. Cholesterol stabilizes fluidity, and membrane proteins serve as channels, carriers, receptors, and enzymes."))
story.append(Q("What are the types of membrane transport?"))
t = make_table(
['Type', 'Energy Needed', 'Examples'],
[
['Simple diffusion', 'No', 'O2, CO2, fat-soluble substances'],
['Facilitated diffusion', 'No', 'Glucose (GLUT), amino acids'],
['Primary active transport', 'Yes (ATP)', 'Na+/K+-ATPase pump'],
['Secondary active transport', 'Yes (gradient)', 'Na+-glucose co-transport'],
['Osmosis', 'No', 'Water movement'],
['Endocytosis/Exocytosis', 'Yes', 'Large molecules, hormones'],
],
col_widths=[5.5*cm, 4*cm, 6.5*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("Explain the Na+/K+ ATPase pump."))
story.append(A("Pumps <b>3 Na+ out</b> and <b>2 K+ in</b> per cycle using 1 ATP. This maintains the resting membrane potential, keeps cells from swelling, and generates the electrochemical gradient used for secondary active transport."))
story.append(Q("What is the resting membrane potential (RMP) and what determines it?"))
story.append(A("RMP is approximately <b>-70 mV</b> in neurons and <b>-90 mV</b> in skeletal muscle. Determined by: high K+ permeability at rest (K+ leaks out), low Na+ permeability, and the electrogenic Na+/K+ pump (minor contribution)."))
story.append(Q("What is an action potential? Describe its phases."))
for item in [
"1. <b>Resting phase</b> (-70 mV) - Na+ channels closed",
"2. <b>Depolarization</b> - rapid Na+ influx, membrane reaches +30 mV",
"3. <b>Repolarization</b> - Na+ channels inactivate, K+ channels open",
"4. <b>Hyperpolarization</b> - membrane briefly more negative than RMP",
"5. <b>Return to RMP</b> - K+ channels close"
]:
story.append(Bullet(item))
story.append(Q("What is the All-or-None law?"))
story.append(A("An action potential either fires completely or not at all. Once threshold (~-55 mV) is reached, the full action potential fires regardless of stimulus strength."))
story.append(Q("What is osmosis vs. diffusion?"))
story.append(Bullet("<b>Diffusion</b>: movement of solutes from high to low concentration across a permeable membrane"))
story.append(Bullet("<b>Osmosis</b>: movement of <b>water</b> from low solute concentration to high solute concentration across a semi-permeable membrane"))
story.append(Q("Define tonicity and give examples."))
story.append(Bullet("<b>Isotonic</b>: 0.9% NaCl or 5% dextrose - no change in cell size"))
story.append(Bullet("<b>Hypotonic</b>: < 0.9% NaCl - cell swells (lysis possible)"))
story.append(Bullet("<b>Hypertonic</b>: > 0.9% NaCl - cell shrinks (crenation)"))
# ===================== BIOPHYSICS =====================
story.append(Spacer(1, 0.3*cm))
story.append(SubSection("Biophysics"))
story.append(Q("What is Fick's law of diffusion?"))
story.append(Highlight("Rate of diffusion ∝ (Surface area × Concentration gradient × Diffusion coefficient) / Membrane thickness"))
story.append(A("Clinically important for gas exchange in lungs. Diffusion decreases with thickened membranes (pulmonary fibrosis)."))
story.append(Q("What is the Nernst equation?"))
story.append(Highlight("E = (RT/zF) × ln([ion]outside / [ion]inside)"))
story.append(A("Calculates equilibrium potential for a single ion. K+ equilibrium potential ≈ -94 mV; Na+ ≈ +61 mV."))
story.append(Q("What is the Goldman equation?"))
story.append(A("The Goldman-Hodgkin-Katz equation calculates the actual membrane potential considering the permeability of <b>all ions simultaneously</b> (Na+, K+, Cl-)."))
story.append(Q("Define compliance. Where is it clinically relevant?"))
story.append(Highlight("Compliance = Change in volume / Change in pressure (ΔV/ΔP)"))
story.append(Bullet("Lungs: reduced in fibrosis, increased in emphysema"))
story.append(Bullet("Blood vessels, bladder, cardiac ventricles"))
story.append(Q("What is Starling's hypothesis regarding capillary exchange?"))
story.append(Highlight("Net filtration = (Pc - Pi) - (πc - πi)"))
story.append(Bullet("<b>Hydrostatic pressure</b>: pushes fluid OUT of capillaries"))
story.append(Bullet("<b>Oncotic (colloid osmotic) pressure</b>: pulls fluid INTO capillaries"))
story.append(Q("What is surface tension and what is surfactant?"))
story.append(A("Surface tension tends to collapse alveoli. <b>Surfactant</b> (dipalmitoyl phosphatidylcholine) produced by type II pneumocytes reduces surface tension. Deficiency causes <b>Respiratory Distress Syndrome</b> in premature neonates."))
# ===================== SECTION 2: HEMATOLOGY =====================
story.append(PageBreak())
story.append(SectionHeader("SECTION 2: HEMATOLOGY"))
story.append(Spacer(1, 0.2*cm))
story.append(Q("What are the normal values for blood components?"))
t = make_table(
['Parameter', 'Normal Value'],
[
['RBC (male)', '4.5 - 5.5 million/μL'],
['RBC (female)', '3.8 - 5.0 million/μL'],
['Hemoglobin (male)', '13.5 - 17.5 g/dL'],
['Hemoglobin (female)', '11.5 - 15.5 g/dL'],
['Hematocrit (male)', '40 - 54%'],
['WBC', '4,000 - 11,000/μL'],
['Platelets', '1.5 - 4 lakh/μL'],
['MCV', '80 - 100 fL'],
],
col_widths=[8*cm, 8*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("Describe the structure of hemoglobin."))
story.append(A("Hemoglobin A (HbA): <b>2 alpha + 2 beta chains</b>. Each chain carries one <b>heme group</b> (porphyrin ring + Fe2+). Each molecule can carry 4 O2 molecules."))
story.append(Bullet("<b>HbA</b> (alpha2beta2) - 97% in adults"))
story.append(Bullet("<b>HbA2</b> (alpha2delta2) - 2.5%"))
story.append(Bullet("<b>HbF</b> (alpha2gamma2) - fetal hemoglobin, higher O2 affinity"))
story.append(Q("What is the oxygen-hemoglobin dissociation curve? What shifts it?"))
t = make_table(
['Shift', 'Factors', 'Effect'],
[
['RIGHT (decreased affinity)', 'Increased CO2, H+, temperature, 2,3-DPG', 'O2 released to tissues easily'],
['LEFT (increased affinity)', 'Decreased CO2, H+, temperature; HbF; CO', 'O2 held tightly by Hb'],
],
col_widths=[5*cm, 7*cm, 4*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("What is the Bohr effect vs. Haldane effect?"))
story.append(Bullet("<b>Bohr effect</b>: CO2/H+ decreases Hb affinity for O2, aiding O2 release in tissues"))
story.append(Bullet("<b>Haldane effect</b>: O2 decreases Hb affinity for CO2, aiding CO2 release in lungs"))
story.append(Q("What are the ABO and Rh blood group systems?"))
t = make_table(
['Blood Group', 'Antigen on RBC', 'Antibody in Plasma'],
[
['A', 'A antigen', 'Anti-B'],
['B', 'B antigen', 'Anti-A'],
['AB', 'A and B', 'None (Universal Recipient)'],
['O', 'None', 'Anti-A and Anti-B (Universal Donor)'],
],
col_widths=[4*cm, 5.5*cm, 6.5*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(A("<b>Rh system</b>: Rh+ individuals have D antigen. Rh- mother + Rh+ fetus -> Hemolytic Disease of the Newborn (HDN). Prevented with anti-D immunoglobulin (Rho-GAM)."))
story.append(Q("What is erythropoiesis? Where does it occur?"))
story.append(Bullet("Yolk sac (0-2 months) -> Liver, spleen (2-7 months) -> Bone marrow (5 months+)"))
story.append(Bullet("Regulated by <b>erythropoietin (EPO)</b> from kidneys, stimulated by hypoxia"))
story.append(Q("What are the life spans of blood cells?"))
t = make_table(
['Cell', 'Life Span'],
[
['RBC', '120 days'],
['Platelets', '8-10 days'],
['Neutrophils', '6-8 hours in blood'],
['Lymphocytes', 'Days to years'],
],
col_widths=[8*cm, 8*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("What is coagulation? Name the pathways."))
story.append(Bullet("<b>Extrinsic pathway</b> (tissue factor/Factor III): faster, triggered by tissue injury (Factor VII)"))
story.append(Bullet("<b>Intrinsic pathway</b> (contact activation): slower, triggered by Factor XII"))
story.append(Bullet("Both converge at <b>Factor X</b> -> Common pathway -> Prothrombin -> Thrombin -> Fibrinogen -> Fibrin"))
story.append(Q("What are the functions of WBCs (leukocytes)?"))
t = make_table(
['WBC', '%', 'Function'],
[
['Neutrophils', '50-70%', 'First-line defense, phagocytosis of bacteria'],
['Eosinophils', '1-4%', 'Allergy, parasitic infections'],
['Basophils', '<1%', 'Histamine release, allergy'],
['Monocytes', '2-8%', 'Become macrophages, phagocytosis'],
['Lymphocytes', '20-40%', 'B cells (antibodies), T cells (cell-mediated immunity)'],
],
col_widths=[4*cm, 3*cm, 9*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("What is the difference between plasma and serum?"))
story.append(Bullet("<b>Plasma</b>: blood minus cells - contains fibrinogen and clotting factors"))
story.append(Bullet("<b>Serum</b>: plasma minus clotting factors - after blood has clotted"))
# ===================== SECTION 3: ENDOCRINE =====================
story.append(PageBreak())
story.append(SectionHeader("SECTION 3: ENDOCRINE SYSTEM"))
story.append(Spacer(1, 0.2*cm))
story.append(Q("What is the difference between endocrine, paracrine, and autocrine signaling?"))
story.append(Bullet("<b>Endocrine</b>: hormone secreted into blood, acts on distant target"))
story.append(Bullet("<b>Paracrine</b>: acts on neighboring cells"))
story.append(Bullet("<b>Autocrine</b>: acts on the same cell that secreted it"))
story.append(Q("Classify hormones by chemical nature."))
t = make_table(
['Type', 'Examples'],
[
['Peptide/Protein', 'Insulin, GH, PTH, ADH, Oxytocin'],
['Steroid', 'Cortisol, Aldosterone, Estrogen, Testosterone'],
['Amino acid derivatives', 'Thyroid hormones (T3/T4), Catecholamines (Adrenaline)'],
],
col_widths=[6*cm, 10*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
# Thyroid
story.append(SubSection("Thyroid Gland"))
story.append(Q("What hormones does the thyroid secrete?"))
story.append(Bullet("<b>T4 (thyroxine)</b>: 80 μg/day - major secretory product, prohormone"))
story.append(Bullet("<b>T3 (triiodothyronine)</b>: 4 μg/day - more active form (3-5x more potent)"))
story.append(Bullet("<b>Reverse T3 (rT3)</b>: 2 μg/day - inactive"))
story.append(Bullet("<b>Calcitonin</b>: from parafollicular C cells, lowers blood calcium"))
story.append(Q("Describe the steps of thyroid hormone synthesis."))
for step in [
"<b>1. Iodide trapping</b>: I- actively transported via NIS (sodium-iodide symporter)",
"<b>2. Oxidation</b>: I- -> I2 by thyroid peroxidase (TPO) at apical membrane",
"<b>3. Organification</b>: I2 incorporated into tyrosine residues of thyroglobulin in colloid",
"<b>4. MIT + DIT formation</b>: Monoiodotyrosine and Diiodotyrosine",
"<b>5. Coupling</b>: DIT + DIT = T4; MIT + DIT = T3 (by TPO)",
"<b>6. Storage</b>: As thyroglobulin in colloid (reservoir for up to 2 months)",
"<b>7. Secretion</b>: Colloid endocytosed -> lysosomes -> T3/T4 released into blood",
]:
story.append(Bullet(step))
story.append(Q("What drugs block thyroid hormone synthesis?"))
t = make_table(
['Drug', 'Mechanism'],
[
['Propylthiouracil (PTU)', 'Blocks TPO + blocks T4->T3 peripheral conversion'],
['Methimazole/Carbimazole', 'Blocks TPO (organification + coupling)'],
['Perchlorate', 'Blocks NIS (iodide trapping)'],
['High iodide (Wolff-Chaikoff)', 'Transiently inhibits organification'],
],
col_widths=[7*cm, 9*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("How is thyroid hormone transported in blood?"))
story.append(Bullet("<b>TBG (thyroxine-binding globulin)</b>: highest affinity, binds most T4/T3"))
story.append(Bullet("<b>Transthyretin (TTR/prealbumin)</b>: intermediate affinity"))
story.append(Bullet("<b>Albumin</b>: lowest affinity, highest capacity"))
story.append(A("<b>Only free T4 and free T3</b> are biologically active and feed back to inhibit TSH."))
story.append(Q("What is the HPT axis (feedback regulation)?"))
story.append(Highlight("Hypothalamus (TRH) -> Anterior Pituitary (TSH) -> Thyroid (T3/T4) -> Negative feedback inhibits TRH and TSH"))
story.append(Q("What are the actions of thyroid hormones?"))
story.append(Bullet("<b>Metabolic</b>: Increase BMR, O2 consumption (calorigenic - via Na+/K+ ATPase upregulation)"))
story.append(Bullet("<b>Cardiovascular</b>: Increase HR, stroke volume, cardiac output"))
story.append(Bullet("<b>Growth</b>: Essential for normal brain development (fetus/neonate), bone growth"))
story.append(Bullet("<b>Permissive</b>: Potentiates catecholamine effects"))
story.append(Bullet("<b>GI</b>: Increases gut motility (diarrhea in hyperthyroidism, constipation in hypothyroidism)"))
story.append(Q("Compare hypothyroidism vs. hyperthyroidism."))
t = make_table(
['Feature', 'Hypothyroidism', 'Hyperthyroidism'],
[
['BMR', 'Decreased', 'Increased'],
['Weight', 'Gain', 'Loss'],
['Heart Rate', 'Bradycardia', 'Tachycardia'],
['Reflexes', 'Slow (delayed relaxation)', 'Brisk'],
['Skin/Hair', 'Dry, coarse, hair loss', 'Moist, warm, fine hair'],
['TSH', 'High (primary)', 'Low (primary)'],
['Myxedema', 'Yes', 'No'],
['Exophthalmos', 'No', 'Yes (Graves disease only)'],
],
col_widths=[4.5*cm, 5.5*cm, 6*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
# Parathyroid
story.append(PageBreak())
story.append(SubSection("Parathyroid Gland"))
story.append(Q("What is PTH? Where is it secreted?"))
story.append(A("<b>Parathyroid hormone (PTH)</b> is an 84 amino acid peptide secreted by the <b>chief cells</b> of the 4 parathyroid glands (posterior surface of the thyroid). Oxyphil cells are the other cell type but their function is unknown."))
story.append(Q("What regulates PTH secretion?"))
story.append(Bullet("<b>Low Ca2+</b>: stimulates PTH (via CaSR - calcium-sensing receptor)"))
story.append(Bullet("<b>High Ca2+</b>: inhibits PTH"))
story.append(Bullet("<b>Low Mg2+</b>: stimulates PTH"))
story.append(Bullet("<b>Vitamin D (calcitriol)</b>: inhibits PTH gene expression"))
story.append(Q("What are the actions of PTH? (Three target organs)"))
t = make_table(
['Target', 'Action', 'Net Effect'],
[
['Bone', 'Osteolysis (rapid); Osteoclast activation via RANK-L (slow)', 'Ca2+ and PO43- released'],
['Kidney', 'Increases Ca2+ reabsorption (DCT); Decreases PO43- reabsorption; Stimulates 1alpha-hydroxylase', 'Ca2+ up, PO43- down in blood'],
['Intestine', 'Indirect via Vitamin D (calcitriol production)', 'Increased Ca2+ absorption'],
],
col_widths=[3.5*cm, 7.5*cm, 5*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Highlight("NET RESULT: PTH raises blood Ca2+ and lowers blood PO43-"))
story.append(Q("How does PTH act on bone - rapid vs. slow phase?"))
story.append(Bullet("<b>Rapid (minutes)</b>: Activates osteocytic membrane pump (osteolysis) - Ca2+ extracted from amorphous bone crystals without matrix resorption"))
story.append(Bullet("<b>Slow (days-weeks)</b>: Activates osteoclasts via osteoblast RANK-L/RANK signaling - full bone resorption"))
story.append(Q("What is calcitonin? How does it differ from PTH?"))
t = make_table(
['Feature', 'PTH', 'Calcitonin'],
[
['Source', 'Parathyroid chief cells', 'Thyroid C cells (parafollicular)'],
['Stimulus', 'Low Ca2+', 'High Ca2+'],
['Effect on Ca2+', 'RAISES blood Ca2+', 'LOWERS blood Ca2+'],
['Main action', 'Bone resorption + renal reabsorption', 'Inhibits osteoclasts'],
],
col_widths=[4*cm, 6*cm, 6*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("Hyperparathyroidism vs. hypoparathyroidism."))
t = make_table(
['Feature', 'Hyperparathyroidism', 'Hypoparathyroidism'],
[
['Ca2+', 'HIGH (hypercalcemia)', 'LOW (hypocalcemia)'],
['PO43-', 'Low', 'High'],
['Symptoms', '"Bones, Stones, Groans, Psychic moans"', 'Tetany, Chvostek sign, Trousseau sign'],
['Common cause', 'Adenoma', 'Post-thyroid surgery'],
],
col_widths=[4.5*cm, 5.5*cm, 6*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
# Anterior Pituitary
story.append(SubSection("Anterior Pituitary Gland"))
story.append(Q("What are the 6 hormones of the anterior pituitary?"))
story.append(Highlight("Memory: 'FLAGTAP' - FSH, LH, ACTH, GH, TSH, And Prolactin"))
for h in [
"<b>GH</b> - Growth hormone / Somatotropin",
"<b>TSH</b> - Thyroid-stimulating hormone / Thyrotropin",
"<b>ACTH</b> - Adrenocorticotropic hormone / Corticotropin",
"<b>FSH</b> - Follicle-stimulating hormone",
"<b>LH</b> - Luteinizing hormone",
"<b>PRL</b> - Prolactin",
]:
story.append(Bullet(h))
story.append(Q("What are the hypothalamic hormones controlling anterior pituitary?"))
t = make_table(
['Hypothalamic Hormone', 'Effect on Anterior Pituitary'],
[
['TRH (Thyrotropin-releasing hormone)', 'Stimulates TSH and PRL'],
['CRH (Corticotropin-releasing hormone)', 'Stimulates ACTH'],
['GnRH (Gonadotropin-releasing hormone)', 'Stimulates FSH and LH'],
['GHRH (GH-releasing hormone)', 'Stimulates GH'],
['Somatostatin (GHIH)', 'Inhibits GH (and TSH)'],
['Dopamine (PIH)', 'Inhibits PRL (primary inhibitor)'],
],
col_widths=[9*cm, 7*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("How does the hypothalamo-pituitary portal system work?"))
story.append(A("The hypothalamus releases <b>hypophysiotropic hormones</b> into the <b>portal hypophyseal vessels</b> (primary capillary plexus in median eminence -> portal veins -> secondary capillary plexus in anterior pituitary). This ensures high local concentrations reach the pituitary before diluting into systemic circulation."))
story.append(Q("What are the actions of Growth Hormone (GH)?"))
story.append(Bullet("<b>Direct effects</b>: Anti-insulin (diabetogenic), lipolysis, protein synthesis"))
story.append(Bullet("<b>Indirect (via IGF-1/Somatomedin C from liver)</b>: bone growth at epiphyseal plates, cartilage, muscle proliferation"))
t = make_table(
['Condition', 'Cause', 'Features'],
[
['Gigantism', 'GH excess BEFORE epiphyseal fusion', 'Increased height, large features'],
['Acromegaly', 'GH excess AFTER epiphyseal fusion', 'Enlarged hands, feet, jaw, brow'],
['Dwarfism', 'GH deficiency in childhood', 'Proportionate short stature, normal intelligence'],
],
col_widths=[4*cm, 6*cm, 6*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("What regulates GH secretion?"))
story.append(Bullet("<b>Stimulates GH</b>: Deep sleep (peak secretion), exercise, hypoglycemia, stress, amino acids, GHRH"))
story.append(Bullet("<b>Inhibits GH</b>: Somatostatin, hyperglycemia, IGF-1 (negative feedback), obesity"))
story.append(Q("What are the actions of prolactin?"))
story.append(Bullet("Initiates and maintains <b>lactation</b> (milk production)"))
story.append(Bullet("Inhibits GnRH -> suppresses ovulation (contraceptive effect of breastfeeding)"))
story.append(Bullet("<b>Hyperprolactinemia</b>: amenorrhea, galactorrhea, infertility. Treat with dopamine agonists (bromocriptine)"))
story.append(Q("What cells make up the anterior pituitary?"))
t = make_table(
['Cell Type', 'Hormone Produced'],
[
['Somatotrophs (50%)', 'GH'],
['Corticotrophs', 'ACTH'],
['Thyrotrophs', 'TSH'],
['Gonadotrophs', 'FSH and LH'],
['Lactotrophs', 'Prolactin'],
],
col_widths=[8*cm, 8*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
story.append(Q("Difference between anterior and posterior pituitary?"))
t = make_table(
['Feature', 'Anterior Pituitary', 'Posterior Pituitary'],
[
['Embryological origin', "Rathke's pouch (oral ectoderm)", 'Downgrowth of hypothalamus (neural)'],
['Other name', 'Adenohypophysis', 'Neurohypophysis'],
['Hormones', 'GH, TSH, ACTH, FSH, LH, PRL', 'ADH (vasopressin) + Oxytocin'],
['Synthesis site', 'Pituitary itself', 'Hypothalamus (stored in post. pituitary)'],
['Blood supply', 'Portal vessels', 'Systemic + axon terminals'],
],
col_widths=[4.5*cm, 5.5*cm, 6*cm]
)
story.append(Spacer(1, 0.2*cm))
story.append(t)
story.append(Spacer(1, 0.2*cm))
# ===================== HIGH-YIELD POINTS =====================
story.append(PageBreak())
story.append(SectionHeader("QUICK HIGH-YIELD POINTS FOR VIVA"))
story.append(Spacer(1, 0.3*cm))
high_yield = [
"<b>Wolff-Chaikoff effect</b>: Excess iodide transiently inhibits thyroid hormone synthesis (used with Lugol's iodine before thyroid surgery)",
"<b>Most active thyroid hormone</b>: T3 (3-5x more potent than T4); T4 is mainly converted to T3 in peripheral tissues",
"<b>Most thyroid hormone in blood is T4</b> - but T3 is biologically more active",
"<b>PTH does NOT directly stimulate osteoclasts</b> - it acts via osteoblasts (RANK-L -> RANK on osteoclast precursors)",
"<b>GH is highest during slow-wave sleep</b> (stage 3-4 NREM)",
"<b>Dopamine is the main prolactin inhibitor</b> - hence dopamine agonists (bromocriptine) treat hyperprolactinemia",
"<b>CaSR (calcium-sensing receptor)</b>: G-protein coupled receptor on parathyroid chief cells - key regulator of PTH",
"<b>Universal donor</b>: O negative; <b>Universal recipient</b>: AB positive",
"<b>Rh disease prevention</b>: Sensitization in 1st pregnancy, disease in subsequent ones - prevent with anti-D immunoglobulin (Rho-GAM)",
"<b>Cretinism</b>: Congenital hypothyroidism - irreversible if not treated within 2 weeks - causes deaf-mutism, intellectual disability, growth retardation",
"<b>2,3-DPG</b>: Increases in chronic anemia and high altitude - shifts O2 curve right to release more O2 to tissues",
"<b>Most common cause of hyperparathyroidism</b>: Parathyroid adenoma (single gland)",
"<b>Surfactant</b>: Produced by Type II pneumocytes from 24 weeks gestation - Deficiency causes Neonatal RDS",
"<b>EPO source</b>: Peritubular cells of kidney (90%) + hepatocytes (10%) - stimulated by hypoxia via HIF-1alpha",
"<b>Refractory period</b>: Absolute (no AP possible) during depolarization; Relative (stronger stimulus needed) during repolarization",
]
for i, point in enumerate(high_yield, 1):
row_color = colors.HexColor('#e8f5e9') if i % 2 == 0 else colors.HexColor('#fff9c4')
p = ParagraphStyle(f'HY{i}', parent=styles['Normal'],
fontSize=10, leading=14, spaceBefore=4, spaceAfter=4,
leftIndent=0.5*cm, fontName='Helvetica',
backColor=row_color, borderPad=5)
story.append(Paragraph(f"<b>{i}.</b> {point}", p))
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1.5, color=colors.HexColor('#3949ab')))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Best of luck for your viva tomorrow! Focus on mechanisms, not just names.",
ParagraphStyle('Footer', parent=styles['Normal'], fontSize=11,
alignment=TA_CENTER, textColor=colors.HexColor('#1a237e'), fontName='Helvetica-Bold')))
story.append(Paragraph("Sources: Ganong's Review of Medical Physiology (26th Ed.) | Guyton & Hall Textbook of Medical Physiology",
ParagraphStyle('Source', parent=styles['Normal'], fontSize=8,
alignment=TA_CENTER, textColor=colors.grey, fontName='Helvetica')))
doc.build(story)
print(f"PDF saved to: {OUTPUT}")