Act like a topper Make a perfect answer for 10 marks on both cardiac cycle and cardiac output for uni exam in simple point wise manner extract every definition, strategies and approach and strictly from the above pages mentioned only add flow chart or easy mnemonic if required only in pdf format don't add tables please
mkdir -p /tmp/workspace/physiology-notes && ls /tmp/workspace/
~/physiology-notes/create_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, HRFlowable,
KeepTogether, ListFlowable, ListItem
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus.flowables import Flowable
OUTPUT = "/tmp/workspace/physiology-notes/Cardiac_Cycle_and_Output.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm,
leftMargin=2*cm,
topMargin=2*cm,
bottomMargin=2*cm,
)
# ─── colour palette ───────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1a3a5c")
TEAL = colors.HexColor("#0077b6")
GOLD = colors.HexColor("#f4a921")
LIGHT = colors.HexColor("#e8f4fd")
WHITE = colors.white
LGRAY = colors.HexColor("#f7f7f7")
DKGRAY = colors.HexColor("#333333")
GREEN = colors.HexColor("#1a7a4a")
RED = colors.HexColor("#c0392b")
# ─── styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
cover_title = ParagraphStyle(
"cover_title",
fontName="Helvetica-Bold",
fontSize=26,
textColor=WHITE,
alignment=TA_CENTER,
spaceAfter=6,
leading=32,
)
cover_sub = ParagraphStyle(
"cover_sub",
fontName="Helvetica",
fontSize=13,
textColor=colors.HexColor("#cce5ff"),
alignment=TA_CENTER,
leading=18,
)
part_header = ParagraphStyle(
"part_header",
fontName="Helvetica-Bold",
fontSize=16,
textColor=WHITE,
alignment=TA_CENTER,
spaceAfter=4,
leading=20,
)
h1 = ParagraphStyle(
"h1",
fontName="Helvetica-Bold",
fontSize=13,
textColor=NAVY,
spaceBefore=10,
spaceAfter=3,
leading=17,
borderPad=4,
)
h2 = ParagraphStyle(
"h2",
fontName="Helvetica-Bold",
fontSize=11,
textColor=TEAL,
spaceBefore=7,
spaceAfter=2,
leading=15,
)
body = ParagraphStyle(
"body",
fontName="Helvetica",
fontSize=10,
textColor=DKGRAY,
leading=15,
spaceAfter=3,
alignment=TA_JUSTIFY,
)
bullet_style = ParagraphStyle(
"bullet_style",
fontName="Helvetica",
fontSize=10,
textColor=DKGRAY,
leading=15,
leftIndent=12,
spaceAfter=2,
)
numbered_style = ParagraphStyle(
"numbered_style",
fontName="Helvetica",
fontSize=10,
textColor=DKGRAY,
leading=15,
leftIndent=20,
spaceAfter=2,
)
bold_label = ParagraphStyle(
"bold_label",
fontName="Helvetica-Bold",
fontSize=10,
textColor=NAVY,
leading=15,
spaceAfter=2,
)
def_box = ParagraphStyle(
"def_box",
fontName="Helvetica-Oblique",
fontSize=10.5,
textColor=NAVY,
leading=16,
spaceAfter=4,
leftIndent=8,
rightIndent=8,
backColor=LIGHT,
borderPad=6,
borderColor=TEAL,
borderWidth=1,
borderRadius=4,
)
mnemonic_style = ParagraphStyle(
"mnemonic_style",
fontName="Helvetica-Bold",
fontSize=10,
textColor=GREEN,
leading=15,
leftIndent=8,
spaceAfter=2,
)
note_style = ParagraphStyle(
"note_style",
fontName="Helvetica-Oblique",
fontSize=9,
textColor=colors.HexColor("#555555"),
leading=13,
spaceAfter=2,
leftIndent=8,
)
footer_style = ParagraphStyle(
"footer_style",
fontName="Helvetica",
fontSize=8,
textColor=colors.HexColor("#999999"),
alignment=TA_CENTER,
)
# ─── helper: coloured banner ─────────────────────────────────────────────────
class ColorBanner(Flowable):
def __init__(self, text, bg=NAVY, fg=WHITE, height=1.2*cm, font_size=14, radius=6):
Flowable.__init__(self)
self.text = text
self.bg = bg
self.fg = fg
self.height = height
self.font_size = font_size
self.radius = radius
self.width = 0 # set by wrap
def wrap(self, avail_width, avail_height):
self.width = avail_width
return avail_width, self.height
def draw(self):
c = self.canv
c.saveState()
c.setFillColor(self.bg)
c.roundRect(0, 0, self.width, self.height, self.radius, fill=1, stroke=0)
c.setFillColor(self.fg)
c.setFont("Helvetica-Bold", self.font_size)
c.drawCentredString(self.width / 2, self.height * 0.28, self.text)
c.restoreState()
class GoldLine(Flowable):
def wrap(self, avail_width, avail_height):
self.width = avail_width
return avail_width, 4
def draw(self):
c = self.canv
c.setStrokeColor(GOLD)
c.setLineWidth(2)
c.line(0, 2, self.width, 2)
class CoverPage(Flowable):
def wrap(self, avail_width, avail_height):
self.width = avail_width
self.avail_height = avail_height
return avail_width, 340
def draw(self):
c = self.canv
c.saveState()
# background rect
c.setFillColor(NAVY)
c.roundRect(0, 0, self.width, 340, 12, fill=1, stroke=0)
# gold accent bar
c.setFillColor(GOLD)
c.rect(0, 295, self.width, 8, fill=1, stroke=0)
# title
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 28)
c.drawCentredString(self.width/2, 250, "CARDIAC CYCLE")
c.setFont("Helvetica-Bold", 22)
c.drawCentredString(self.width/2, 215, "& CARDIAC OUTPUT")
# gold underline
c.setStrokeColor(GOLD)
c.setLineWidth(2)
c.line(self.width*0.25, 205, self.width*0.75, 205)
# subtitle
c.setFont("Helvetica", 12)
c.setFillColor(colors.HexColor("#cce5ff"))
c.drawCentredString(self.width/2, 180, "Perfect 10-Mark University Exam Answers")
c.drawCentredString(self.width/2, 163, "Strictly from Textbook | Point-wise Format")
# marks badge
c.setFillColor(GOLD)
c.roundRect(self.width/2 - 60, 115, 120, 35, 8, fill=1, stroke=0)
c.setFillColor(NAVY)
c.setFont("Helvetica-Bold", 14)
c.drawCentredString(self.width/2, 126, "10 MARKS EACH")
# bottom note
c.setFillColor(colors.HexColor("#aaaacc"))
c.setFont("Helvetica", 9)
c.drawCentredString(self.width/2, 70, "Chapter 60 · Cardiac Cycle | Chapter 63 · Cardiac Output")
c.drawCentredString(self.width/2, 55, "Cardiovascular System · Human Physiology")
c.restoreState()
# ─── flowchart helper using text ─────────────────────────────────────────────
class FlowchartBox(Flowable):
"""Simple vertical flowchart of steps."""
def __init__(self, steps, box_color=TEAL, text_color=WHITE, w=None):
Flowable.__init__(self)
self.steps = steps
self.box_color = box_color
self.text_color = text_color
self._w = w
self.box_h = 22
self.gap = 12
def wrap(self, avail_width, avail_height):
self.width = self._w if self._w else avail_width
total = len(self.steps) * (self.box_h + self.gap) - self.gap
return self.width, total
def draw(self):
c = self.canv
c.saveState()
n = len(self.steps)
total_h = n * (self.box_h + self.gap) - self.gap
y = total_h - self.box_h
box_w = self.width * 0.78
x = (self.width - box_w) / 2
for i, step in enumerate(self.steps):
# box
c.setFillColor(self.box_color)
c.roundRect(x, y, box_w, self.box_h, 4, fill=1, stroke=0)
# step number circle
c.setFillColor(GOLD)
c.circle(x + 14, y + self.box_h/2, 8, fill=1, stroke=0)
c.setFillColor(NAVY)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(x + 14, y + self.box_h/2 - 3, str(i+1))
# text
c.setFillColor(self.text_color)
c.setFont("Helvetica-Bold", 9)
c.drawString(x + 28, y + self.box_h/2 - 3, step)
# arrow (except last)
if i < n - 1:
ax = self.width / 2
ay = y - self.gap / 2
c.setFillColor(GOLD)
c.setStrokeColor(GOLD)
c.setLineWidth(1.5)
c.line(ax, y, ax, y - self.gap + 4)
# arrowhead
c.polygon([ax-5, y-self.gap+8, ax+5, y-self.gap+8, ax, y-self.gap+2], fill=1, stroke=0)
y -= self.box_h + self.gap
c.restoreState()
class SideBySideBoxes(Flowable):
"""Two coloured boxes side by side."""
def __init__(self, left_title, left_items, right_title, right_items):
Flowable.__init__(self)
self.left_title = left_title
self.left_items = left_items
self.right_title = right_title
self.right_items = right_items
def wrap(self, avail_width, avail_height):
self.width = avail_width
rows = max(len(self.left_items), len(self.right_items))
self.height = 26 + rows * 17 + 14
return avail_width, self.height
def draw(self):
c = self.canv
c.saveState()
half = self.width / 2 - 4
h = self.height
# left box
c.setFillColor(colors.HexColor("#d0eaf7"))
c.roundRect(0, 0, half, h, 5, fill=1, stroke=0)
c.setFillColor(TEAL)
c.roundRect(0, h - 22, half, 22, 5, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 9)
c.drawCentredString(half/2, h - 15, self.left_title)
c.setFillColor(NAVY)
c.setFont("Helvetica-Bold", 8.5)
for i, item in enumerate(self.left_items):
c.drawString(8, h - 38 - i*17, f"• {item}")
# right box
rx = half + 8
c.setFillColor(colors.HexColor("#d5f0e0"))
c.roundRect(rx, 0, half, h, 5, fill=1, stroke=0)
c.setFillColor(GREEN)
c.roundRect(rx, h - 22, half, 22, 5, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 9)
c.drawCentredString(rx + half/2, h - 15, self.right_title)
c.setFillColor(colors.HexColor("#1a4a2a"))
c.setFont("Helvetica-Bold", 8.5)
for i, item in enumerate(self.right_items):
c.drawString(rx + 8, h - 38 - i*17, f"• {item}")
c.restoreState()
# ─── build story ─────────────────────────────────────────────────────────────
story = []
# COVER
story.append(CoverPage())
story.append(Spacer(1, 0.5*cm))
# Quick-reference strip
story.append(ColorBanner(
"QUICK REFERENCE · Duration at HR 72/min: Total Cycle = 0.8 sec",
bg=GOLD, fg=NAVY, height=0.9*cm, font_size=10
))
story.append(Spacer(1, 0.6*cm))
# ═══════════════════════════════════════════════════════
# PART 1 – CARDIAC CYCLE
# ═══════════════════════════════════════════════════════
story.append(ColorBanner("PART 1 · CARDIAC CYCLE (Chapter 60)", bg=NAVY, height=1.2*cm, font_size=15))
story.append(GoldLine())
story.append(Spacer(1, 0.3*cm))
# ── 1. Definition ────────────────────────────────────────────────────────────
story.append(Paragraph("1. DEFINITION", h1))
story.append(Paragraph(
"Cardiac cycle is defined as the <b>sequence of coordinated events in the heart</b> "
"which are repeated during every heartbeat in a cyclic manner.",
def_box
))
story.append(Paragraph("• Each heartbeat = two major periods: <b>Systole</b> + <b>Diastole</b>.", bullet_style))
story.append(Paragraph("• <b>Systole</b> – contraction of cardiac muscle.", bullet_style))
story.append(Paragraph("• <b>Diastole</b> – relaxation of cardiac muscle.", bullet_style))
story.append(Paragraph(
"<i>Clinical note: In clinical practice, 'systole' = ventricular systole; 'diastole' = ventricular diastole.</i>",
note_style
))
story.append(Spacer(1, 0.2*cm))
# ── 2. Events ────────────────────────────────────────────────────────────────
story.append(Paragraph("2. EVENTS OF CARDIAC CYCLE", h1))
story.append(Paragraph("Events are classified into two divisions:", body))
story.append(Paragraph("1. <b>Atrial events</b> → constitute atrial systole and atrial diastole.", numbered_style))
story.append(Paragraph("2. <b>Ventricular events</b> → constitute ventricular systole and ventricular diastole.", numbered_style))
story.append(Spacer(1, 0.2*cm))
# ── 3. Subdivisions & Duration ───────────────────────────────────────────────
story.append(Paragraph("3. SUBDIVISIONS AND DURATION (HR = 72/min → cycle = 0.8 sec)", h1))
story.append(ColorBanner("ATRIAL EVENTS", bg=TEAL, height=0.8*cm, font_size=11))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("• <b>Atrial Systole</b> = 0.11 sec (0.1 sec)", bullet_style))
story.append(Paragraph("• <b>Atrial Diastole</b> = 0.69 sec (0.7 sec)", bullet_style))
story.append(Spacer(1, 0.2*cm))
story.append(ColorBanner("VENTRICULAR EVENTS", bg=NAVY, height=0.8*cm, font_size=11))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("<b>Ventricular Systole (Total = 0.27 sec) — 2 subdivisions:</b>", bold_label))
story.append(Paragraph(" 1. Isometric Contraction → <b>0.05 sec</b>", numbered_style))
story.append(Paragraph(" 2. Ejection Period → <b>0.22 sec</b>", numbered_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("<b>Ventricular Diastole (Total = 0.53 sec) — 5 subdivisions:</b>", bold_label))
story.append(Paragraph(" 1. Protodiastole → <b>0.04 sec</b>", numbered_style))
story.append(Paragraph(" 2. Isometric Relaxation → <b>0.08 sec</b>", numbered_style))
story.append(Paragraph(" 3. Rapid Filling → <b>0.11 sec</b>", numbered_style))
story.append(Paragraph(" 4. Slow Filling → <b>0.19 sec</b>", numbered_style))
story.append(Paragraph(" 5. Last Rapid Filling / Atrial Systole → <b>0.11 sec</b>", numbered_style))
story.append(Spacer(1, 0.2*cm))
# Mnemonic
story.append(ColorBanner("MNEMONIC — Ventricular Diastole (5 phases)", bg=colors.HexColor("#1a7a4a"), height=0.8*cm, font_size=10))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
'<b>"<font color="#c0392b">P</font>IG '
'<font color="#c0392b">R</font>uns '
'<font color="#c0392b">S</font>lowly '
'<font color="#c0392b">L</font>ast"</b>',
mnemonic_style
))
story.append(Paragraph(
'<b>P</b>rotodiastole · <b>I</b>sometric Relaxation · <b>R</b>apid Filling · <b>S</b>low Filling · <b>L</b>ast Rapid Filling',
bullet_style
))
story.append(Spacer(1, 0.3*cm))
# FLOWCHART of cardiac cycle
story.append(Paragraph("4. FLOWCHART — SEQUENCE OF CARDIAC CYCLE", h1))
story.append(Spacer(1, 0.15*cm))
cycle_steps = [
"Atrial Systole (0.11 sec) — atria contract, blood → ventricles",
"Isometric Contraction (0.05 sec) — AV valves close; ventricular P↑",
"Ejection Period (0.22 sec) — semilunar valves open; blood ejected",
"Protodiastole (0.04 sec) — ventricles relax; semilunar valves close",
"Isometric Relaxation (0.08 sec) — all valves closed; ventricular P↓",
"Rapid Filling (0.11 sec) — AV valves open; 70% ventricular filling",
"Slow Filling (Diastasis) (0.19 sec) — slow passive filling continues",
"Last Rapid Filling / Atrial Systole (0.11 sec) — atrial kick (10%)",
]
story.append(FlowchartBox(cycle_steps, box_color=TEAL))
story.append(Spacer(1, 0.3*cm))
# ── 5. Description of Atrial Events ──────────────────────────────────────────
story.append(Paragraph("5. DESCRIPTION OF ATRIAL EVENTS", h1))
story.append(Paragraph("A. Atrial Systole", h2))
story.append(Paragraph("• Also known as: <b>second/last rapid filling phase</b> or <b>presystole</b>.", bullet_style))
story.append(Paragraph("• Considered the <b>last phase of ventricular diastole</b>.", bullet_style))
story.append(Paragraph("• Duration: <b>0.11 sec</b>.", bullet_style))
story.append(Paragraph("• Only <b>10% of blood</b> is forced from atria into ventricles during this phase.", bullet_style))
story.append(Paragraph("• Atrial systole is <b>not essential</b> for circulation — persons with atrial fibrillation "
"survive without it, though they struggle with physical stress.", bullet_style))
story.append(Paragraph("• During atrial systole: <b>intra-atrial pressure increases</b>; intraventricular pressure "
"and ventricular volume also increase slightly.", bullet_style))
story.append(Paragraph("• Produces the <b>fourth heart sound</b> (normally inaudible).", bullet_style))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("B. Atrial Diastole", h2))
story.append(Paragraph("• Duration: <b>0.69 sec (approx. 0.7 sec)</b> — the longest phase in atrial events.", bullet_style))
story.append(Paragraph("• This long diastole is necessary for <b>atrial filling</b>.", bullet_style))
story.append(Paragraph("• <b>Right atrium</b>: receives deoxygenated blood from SVC + IVC.", bullet_style))
story.append(Paragraph("• <b>Left atrium</b>: receives oxygenated blood from lungs via pulmonary veins.", bullet_style))
story.append(Paragraph("• Contraction of atrial musculature causes increase in intra-atrial pressure.", bullet_style))
story.append(Spacer(1, 0.3*cm))
# ── 6. Description of Ventricular Events ─────────────────────────────────────
story.append(Paragraph("6. DESCRIPTION OF VENTRICULAR EVENTS", h1))
# Ventricular Systole
story.append(ColorBanner("A. VENTRICULAR SYSTOLE (0.27 sec)", bg=TEAL, height=0.8*cm, font_size=11))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("Phase 1: Isometric Contraction (0.05 sec)", h2))
story.append(Paragraph(
"<b>Definition:</b> Muscular contraction characterized by <b>increase in tension WITHOUT any change in "
"the length of muscle fibers</b>. Also called <b>isovolumetric contraction</b>.",
def_box
))
story.append(Paragraph("• Occurs immediately after atrial systole.", bullet_style))
story.append(Paragraph("• AV valves close (due to rise in ventricular pressure). Semilunar valves are already closed.", bullet_style))
story.append(Paragraph("• Ventricles contract as <b>closed cavities</b> — no change in volume or fiber length.", bullet_style))
story.append(Paragraph("• Tension ↑ in ventricular musculature → <b>sharp rise in intraventricular pressure</b>.", bullet_style))
story.append(Paragraph("• <b>Significance:</b> The pressure rise opens the semilunar valves when it exceeds "
"aortic/pulmonary artery pressure → blood ejection begins.", bullet_style))
story.append(Paragraph("• Produces the <b>first heart sound (S1)</b>.", bullet_style))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("Phase 2: Ejection Period (0.22 sec)", h2))
story.append(Paragraph("• Semilunar valves open → blood ejected from both ventricles.", bullet_style))
story.append(Paragraph("• Two sub-stages:", bullet_style))
story.append(Paragraph(" a. <b>Rapid Ejection</b> (0.13 sec) — large amount of blood ejected rapidly.", numbered_style))
story.append(Paragraph(" b. <b>Slow Ejection</b> (0.09 sec) — slow ejection; called the 'slope ejection'.", numbered_style))
story.append(Spacer(1, 0.2*cm))
# Ventricular Diastole
story.append(ColorBanner("B. VENTRICULAR DIASTOLE (0.53 sec)", bg=NAVY, height=0.8*cm, font_size=11))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("Phase 1: Protodiastole (0.04 sec)", h2))
story.append(Paragraph("• The very first part of ventricular diastole.", bullet_style))
story.append(Paragraph("• Semilunar valves close at the end of this phase (produces <b>second heart sound S2</b>).", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("Phase 2: Isometric Relaxation (0.08 sec)", h2))
story.append(Paragraph(
"<b>Definition:</b> Relaxation of ventricles WITHOUT any change in their volume "
"(also called <b>isovolumetric relaxation</b>).",
def_box
))
story.append(Paragraph("• All valves are closed; intraventricular pressure falls rapidly.", bullet_style))
story.append(Paragraph("• No change in ventricular volume during this period.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("Phase 3: Rapid Filling (0.11 sec)", h2))
story.append(Paragraph("• AV valves open when ventricular pressure falls below atrial pressure.", bullet_style))
story.append(Paragraph("• About <b>70% of ventricular filling</b> occurs during this phase.", bullet_style))
story.append(Paragraph("• Produces the <b>third heart sound (S3)</b>.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("Phase 4: Slow Filling / Diastasis (0.19 sec)", h2))
story.append(Paragraph("• Blood flow from atria to ventricles becomes slow.", bullet_style))
story.append(Paragraph("• Also called <b>diastasis</b>.", bullet_style))
story.append(Paragraph("• About 20% of ventricular filling occurs during this phase.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("Phase 5: Last Rapid Filling / Atrial Systole (0.11 sec)", h2))
story.append(Paragraph("• Final 10% of blood enters ventricles via atrial contraction.", bullet_style))
story.append(Paragraph("• = Atrial Systole / Presystole / Second rapid filling phase.", bullet_style))
story.append(Spacer(1, 0.3*cm))
# Heart sounds summary
story.append(Paragraph("7. HEART SOUNDS — QUICK SUMMARY", h1))
story.append(SideBySideBoxes(
"SYSTOLIC SOUNDS",
["S1 — Isometric contraction", "(AV valves close)", "S4 — Atrial systole", "(normally inaudible)"],
"DIASTOLIC SOUNDS",
["S2 — Protodiastole", "(Semilunar valves close)", "S3 — Rapid filling", "(3rd heart sound)"]
))
story.append(Spacer(1, 0.5*cm))
# ═══════════════════════════════════════════════════════
# PART 2 – CARDIAC OUTPUT
# ═══════════════════════════════════════════════════════
story.append(ColorBanner("PART 2 · CARDIAC OUTPUT (Chapter 63)", bg=NAVY, height=1.2*cm, font_size=15))
story.append(GoldLine())
story.append(Spacer(1, 0.3*cm))
# ── 1. Definition ────────────────────────────────────────────────────────────
story.append(Paragraph("1. DEFINITION", h1))
story.append(Paragraph(
"Cardiac output is defined as the <b>amount of blood pumped from each ventricle per minute</b>. "
"Usually it refers to the left ventricular output through the aorta.",
def_box
))
story.append(Paragraph("• It is the <b>most important factor</b> in cardiovascular physiology.", bullet_style))
story.append(Paragraph("• Cardiac output is expressed in <b>three ways</b>:", bullet_style))
story.append(Spacer(1, 0.15*cm))
# ── 2. Definitions & Normal Values ───────────────────────────────────────────
story.append(Paragraph("2. DEFINITIONS AND NORMAL VALUES", h1))
story.append(Paragraph("A. Stroke Volume (SV)", h2))
story.append(Paragraph(
"<b>Definition:</b> Amount of blood pumped out by each ventricle per beat.",
def_box
))
story.append(Paragraph("• Normal SV = <b>70 mL</b> (range: 60–80 mL)", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("B. Minute Volume (Cardiac Output)", h2))
story.append(Paragraph(
"<b>Definition:</b> Amount of blood pumped out by each ventricle per minute.",
def_box
))
story.append(Paragraph("• CO = Stroke Volume × Heart Rate", bullet_style))
story.append(Paragraph("• CO = 70 mL × 72/min = <b>5040 mL/min ≈ 5 L/min</b>", bullet_style))
story.append(Paragraph("• Normal range: <b>4.5 – 5 L/min</b> (average 5 L/min)", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("C. Cardiac Index (CI)", h2))
story.append(Paragraph(
"<b>Definition:</b> Cardiac output per unit body surface area per minute.",
def_box
))
story.append(Paragraph("• CI = CO ÷ Body Surface Area (BSA)", bullet_style))
story.append(Paragraph("• BSA in adults = 1.7 m²", bullet_style))
story.append(Paragraph("• Normal CI = <b>2.8 – 3.0 L/min/m²</b> (average 3 L/min/m²)", bullet_style))
story.append(Spacer(1, 0.2*cm))
# Mnemonic for CO
story.append(ColorBanner("MNEMONIC — Factors Affecting Cardiac Output", bg=colors.HexColor("#1a7a4a"), height=0.8*cm, font_size=10))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
'<b>"<font color="#c0392b">V</font>ery '
'<font color="#c0392b">F</font>it '
'<font color="#c0392b">H</font>earts '
'<font color="#c0392b">P</font>ump"</b>',
mnemonic_style
))
story.append(Paragraph(
'<b>V</b>enous Return · <b>F</b>orce of Contraction · <b>H</b>eart Rate · <b>P</b>eripheral Resistance',
bullet_style
))
story.append(Spacer(1, 0.3*cm))
# ── 3. Factors Maintaining CO ────────────────────────────────────────────────
story.append(Paragraph("3. FACTORS MAINTAINING CARDIAC OUTPUT", h1))
story.append(Paragraph("A. Venous Return", h2))
story.append(Paragraph("• Amount of blood returning to heart via veins.", bullet_style))
story.append(Paragraph("• CO is <b>directly proportional</b> to venous return (Frank-Starling Law).", bullet_style))
story.append(Paragraph("• Mechanisms promoting venous return:", bullet_style))
story.append(Paragraph(" i. <b>Vis a tergo</b> — residual pressure from left heart contraction.", numbered_style))
story.append(Paragraph(" ii. <b>Respiratory pump</b> — inspiration ↓ intrathoracic pressure → blood pushed to heart.", numbered_style))
story.append(Paragraph(" iii. <b>Muscle pump</b> — skeletal muscle contraction compresses veins → blood flows to heart.", numbered_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("B. Force of Contraction", h2))
story.append(Paragraph("• CO is proportional to <b>force of contraction</b>.", bullet_style))
story.append(Paragraph("• Governed by <b>Frank-Starling Law of the Heart</b>:", bullet_style))
story.append(Paragraph(
"<b>\"The force of contraction is proportional to the initial length of muscle fibers (preload). "
"Force of contraction also increases with stretch, up to a point.\"</b>",
def_box
))
story.append(Paragraph("• <b>Preload</b>: Stretching of the cardiac muscle fibers at end of diastole (end-diastolic volume).", bullet_style))
story.append(Paragraph("• <b>Afterload</b>: Force against which ventricles contract; directly proportional to arterial pressure.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("C. Heart Rate", h2))
story.append(Paragraph("• CO = SV × HR → heart rate is directly proportional to CO.", bullet_style))
story.append(Paragraph("• <b>Normal HR</b> = 72/min. CO increases proportionally when HR increases.", bullet_style))
story.append(Paragraph("• However, at <b>very high HR</b>, diastolic filling time decreases → CO may fall.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("D. Peripheral Resistance", h2))
story.append(Paragraph("• <b>Peripheral resistance</b> is the resistance offered by blood vessels to blood flow.", bullet_style))
story.append(Paragraph("• CO is <b>inversely proportional</b> to peripheral resistance.", bullet_style))
story.append(Paragraph("• When peripheral resistance increases, cardiac output decreases (and vice versa).", bullet_style))
story.append(Spacer(1, 0.3*cm))
# ── 4. Physiological Variations ──────────────────────────────────────────────
story.append(Paragraph("4. PHYSIOLOGICAL VARIATIONS IN CARDIAC OUTPUT", h1))
story.append(Paragraph("<b>CO decreases:</b>", bold_label))
story.append(Paragraph("• Sleep — CO decreases.", bullet_style))
story.append(Paragraph("• Rising to upright position.", bullet_style))
story.append(Paragraph("<b>CO increases:</b>", bold_label))
story.append(Paragraph("• Eating — cardiac output increases.", bullet_style))
story.append(Paragraph("• Exercise — moderate exercise ↑ CO up to 20–25 L/min.", bullet_style))
story.append(Paragraph("• Anxiety / Excitement.", bullet_style))
story.append(Paragraph("• Pregnancy — CO increases in later months.", bullet_style))
story.append(Paragraph("• High altitude — CO increases as body temperature increases.", bullet_style))
story.append(Paragraph("• CO does not affect changes in temperature alone — Moderate ↑ temperature → ↑ CO.", bullet_style))
story.append(Spacer(1, 0.2*cm))
# ── 5. Pathological Variations ───────────────────────────────────────────────
story.append(Paragraph("5. PATHOLOGICAL VARIATIONS IN CARDIAC OUTPUT", h1))
story.append(SideBySideBoxes(
"CONDITIONS → CO INCREASES",
["Fever", "Hyperthyroidism", "Anaemia", "Arteriovenous fistula", "Beriberi"],
"CONDITIONS → CO DECREASES",
["Hypothyroidism", "Congestive cardiac failure", "Haemorrhage", "Shock", "Myocardial infarction"]
))
story.append(Spacer(1, 0.3*cm))
# ── 6. Distribution ──────────────────────────────────────────────────────────
story.append(Paragraph("6. DISTRIBUTION OF CARDIAC OUTPUT (at 5000 mL/min)", h1))
story.append(Paragraph("The focus amount of blood pumped is distributed by region/organ:", body))
story.append(Paragraph("• Liver (portal + hepatic artery) → <b>1500 mL → 30%</b>", bullet_style))
story.append(Paragraph("• Kidneys → <b>1100 mL → 22%</b>", bullet_style))
story.append(Paragraph("• Brain → <b>700 mL → 14%</b>", bullet_style))
story.append(Paragraph("• Heart (coronary) → <b>200 mL → 4%</b>", bullet_style))
story.append(Paragraph("• Skin, bone and other muscles → rest", bullet_style))
story.append(Spacer(1, 0.3*cm))
# ── 7. Measurement of CO ─────────────────────────────────────────────────────
story.append(Paragraph("7. MEASUREMENT OF CARDIAC OUTPUT", h1))
story.append(Paragraph("A. Fick's Principle (Oxygen Consumption Method)", h2))
story.append(Paragraph(
"<b>Fick's Principle:</b> The amount of a substance taken up by an organ per unit time equals "
"the arteriovenous difference of that substance multiplied by the blood flow.",
def_box
))
story.append(Paragraph("• Cardiac output is measured by determining the amount of O₂ consumed per minute "
"and the arteriovenous O₂ difference.", bullet_style))
story.append(Paragraph("<b>Formula:</b>", bold_label))
story.append(Paragraph(
"CO = O₂ consumed per minute ÷ Arteriovenous O₂ difference",
ParagraphStyle("formula", fontName="Helvetica-Bold", fontSize=11, textColor=TEAL,
alignment=TA_CENTER, spaceAfter=4, leading=16)
))
story.append(Paragraph("<b>Example Calculation:</b>", bold_label))
story.append(Paragraph("• O₂ consumption = 250 mL/min", bullet_style))
story.append(Paragraph("• O₂ in arterial blood = 19 mL/100 mL (or 20 mL/100 mL)", bullet_style))
story.append(Paragraph("• O₂ in venous blood = 14 mL/100 mL", bullet_style))
story.append(Paragraph("• AV O₂ difference = 5 mL/100 mL", bullet_style))
story.append(Paragraph("• CO = 250 ÷ 5 × 100 = <b>5000 mL/min = 5 L/min</b>", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("B. Indicator Dye Dilution Method", h2))
story.append(Paragraph("• A known quantity of indicator (dye) is injected into a peripheral vein.", bullet_style))
story.append(Paragraph("• Blood passing through heart is equal to the amount passing through lungs (closed circuit).", bullet_style))
story.append(Paragraph("• CO calculated by measuring the dye concentration at an artery over time.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("C. Thermodilution Technique", h2))
story.append(Paragraph("• Cold saline injected into the right atrium via Swan-Ganz catheter.", bullet_style))
story.append(Paragraph("• Temperature change detected at pulmonary artery.", bullet_style))
story.append(Paragraph("• <b>Most popular method</b> to measure CO clinically.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("D. Doppler Echocardiography", h2))
story.append(Paragraph("• Uses high-frequency sound waves to detect velocity of blood flow.", bullet_style))
story.append(Paragraph("• Transducer placed on chest wall; measures velocity of flow in aorta.", bullet_style))
story.append(Paragraph("• CO = Stroke volume × Heart rate, with SV calculated from aortic cross-section × velocity.", bullet_style))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph("E. Ballistocardiographic Method", h2))
story.append(Paragraph("• Subject lies on a balanced table that records body movements with each heartbeat.", bullet_style))
story.append(Paragraph("• Each heartbeat causes the body to recoil; CO is determined by analysing the graph.", bullet_style))
story.append(Spacer(1, 0.3*cm))
# FLOWCHART — CO Measurement
story.append(Paragraph("8. FLOWCHART — METHODS TO MEASURE CARDIAC OUTPUT", h1))
story.append(Spacer(1, 0.15*cm))
method_steps = [
"Fick's Principle — O₂ consumption / AV difference × 100",
"Indicator Dye Dilution — inject dye → measure concentration",
"Thermodilution — cold saline → temperature change at PA",
"Doppler Echocardiography — velocity of blood in aorta",
"Ballistocardiography — body recoil with each heartbeat",
]
story.append(FlowchartBox(method_steps, box_color=NAVY))
story.append(Spacer(1, 0.5*cm))
# FINAL SUMMARY BOX
story.append(ColorBanner("EXAM QUICK-RECALL SUMMARY", bg=GOLD, fg=NAVY, height=0.9*cm, font_size=12))
story.append(Spacer(1, 0.2*cm))
summary_lines = [
("Cardiac Cycle Definition", "Sequence of coordinated events in heart, repeated every heartbeat"),
("Total Cycle Duration", "0.8 sec at HR 72/min"),
("Ventricular Systole", "0.27 sec (Isometric contraction 0.05 + Ejection 0.22)"),
("Ventricular Diastole", "0.53 sec (5 phases: Prot 0.04 + IR 0.08 + RF 0.11 + SF 0.19 + LRF 0.11)"),
("Atrial Systole", "0.11 sec — last phase of VD; contributes 10% filling"),
("Cardiac Output Definition", "Volume of blood pumped per ventricle per minute"),
("Normal CO", "5 L/min (70 mL SV × 72 HR)"),
("Cardiac Index", "3 L/min/m² (normal 2.8–3.0)"),
("CO Formula", "CO = SV × HR"),
("Fick's Formula", "CO = O₂ consumed ÷ AV O₂ diff × 100"),
("Best Clinical Method", "Thermodilution (Swan-Ganz catheter)"),
("Mnemonic VFHP", "Venous Return, Force of contraction, Heart rate, Peripheral resistance"),
]
for label, value in summary_lines:
story.append(Paragraph(
f'<b><font color="#1a3a5c">{label}:</font></b> {value}',
bullet_style
))
story.append(Spacer(1, 0.3*cm))
# Footer note
story.append(HRFlowable(width="100%", thickness=1, color=GOLD))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
"All content strictly from Textbook Chapter 60 (Cardiac Cycle) and Chapter 63 (Cardiac Output) · "
"Cardiovascular System · Human Physiology",
footer_style
))
# ─── build ────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF created:", OUTPUT)
cd /tmp/workspace/physiology-notes && python create_pdf.py 2>&1
~/physiology-notes/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/physiology-notes/create_pdf.py'
cd /tmp/workspace/physiology-notes && python create_pdf.py 2>&1
ls -lh /tmp/workspace/physiology-notes/Cardiac_Cycle_and_Output.pdf
Cardiac Cycle and Output
PDF Document · PDF