Define Incidence and Prevalence. Explain attack rate and secondary attack rate, Point Prevalence and Period Prevalence. Write uses of Incidence and Prevalence.

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Reading File
Reading File
Reading File
Loading Image
I now have everything needed to write a complete, well-structured answer. Here it is:

Incidence and Prevalence - Key Epidemiological Measures

(Source: Park's Textbook of Preventive and Social Medicine)

1. INCIDENCE

Definition: Incidence rate is defined as "the number of new cases occurring in a defined population during a specified period of time."

Formula:

$$\text{Incidence Rate} = \frac{\text{Number of new cases of specific disease during a given time period}}{\text{Population at-risk during that period}} \times 1000$$
Example: 500 new cases in a population of 30,000 in a year:
  • = 500/30,000 × 1000 = 16.7 per 1,000 per year
Note: Incidence rate must always include the unit of time (e.g., per year). Writing "16.7 per 1000" alone is inadequate.

Key features of Incidence:

  • (a) Refers only to new cases
  • (b) Measured during a given period (usually one year)
  • (c) Refers to a specified population at risk
  • (d) Can also refer to new spells/episodes of disease - e.g., a person having two attacks of common cold in a year contributes 2 spells
  • Incidence measures the rate at which new cases are occurring in a population
  • Not influenced by the duration of the disease
  • Generally restricted to acute conditions

2. SPECIAL INCIDENCE RATES

a. Attack Rate

An attack rate is an incidence rate (usually expressed as a percentage), used only when the population is exposed to risk for a limited period of time, such as during an epidemic. It reflects the extent of the epidemic.
Formula:
$$\text{Attack Rate} = \frac{\text{Number of new cases of a specified disease during a specified time interval}}{\text{Total population at risk during the same interval}} \times 100$$
  • Expressed as a percentage (not per 1000)
  • Used specifically in epidemic situations
  • Reflects both the communicability of the agent and the susceptibility of the exposed population

b. Secondary Attack Rate (SAR)

Definition: SAR is defined as "the number of exposed persons developing the disease within the range of the incubation period, following exposure to the primary case."
Formula:
$$\text{SAR} = \frac{\text{Number of exposed persons developing the disease within the range of the incubation period}}{\text{Total number of exposed/"susceptible" contacts}} \times 100$$
Important points about SAR:
  • The primary case is excluded from both numerator and denominator
  • The denominator consists of all persons exposed to the case, or may be restricted to "susceptible" contacts if immune persons can be identified
Example: A family of 6 - 2 immune parents, 4 susceptible children. A primary measles case occurs, followed by 2 secondary cases among the remaining 3 susceptible children.
  • SAR = 2/3 = 66.6%
Limitations of SAR:
  • Limited to infectious diseases where the primary case is infective for a short period (e.g., measles, chickenpox)
  • When the primary case is infective over a long period (e.g., tuberculosis), duration of exposure becomes important, so a person-time denominator is used:
$$\text{SAR (TB)} = \frac{\text{Number of contacts developing tuberculosis}}{\text{Number of person-weeks (months or years) of exposure}} \times 100$$
  • Identifying "susceptibles" is difficult in diseases like influenza
  • Where numerous subclinical cases exist, SAR has limited meaning without laboratory investigations
Uses of SAR:
  • Measures spread of infection within families, households, or closed groups
  • Determines whether a disease of unknown aetiology (e.g., Hodgkin's disease) is communicable
  • Evaluates effectiveness of control measures (isolation, immunization)
  • Can pool vaccinated and unvaccinated groups from multiple families to compare overall attack rates

3. PREVALENCE

Definition: "Disease prevalence refers specifically to all current cases (old and new) existing at a given point in time, or over a period of time in a given population."
Broader definition: "The total number of all individuals who have an attribute or disease at a particular time (or during a particular period) divided by the population at risk of having the attribute or disease at this point in time or midway through the period."
Although called a "prevalence rate," it is technically a ratio, not a rate.
Prevalence is of two types:
  • (a) Point Prevalence
  • (b) Period Prevalence

(a) Point Prevalence

Definition: Point prevalence is the number of all current cases (old and new) of a disease at one point of time, in relation to a defined population.
The "point" in point prevalence may, for practical purposes, consist of a day, several days, or even a few weeks - depending on the time it takes to examine the population sample.
Formula:
$$\text{Point Prevalence} = \frac{\text{Number of all current cases (old and new) of a specified disease existing at a given point in time}}{\text{Estimated population at the same point in time}} \times 100$$
  • When the term "prevalence rate" is used without qualification, it refers to point prevalence
  • Can be made specific for age, sex, and other relevant factors

(b) Period Prevalence

Definition: Period prevalence measures the frequency of all current cases (old and new) existing during a defined period of time (e.g., annual prevalence), expressed in relation to a defined population.
It includes:
  • Cases arising before but extending into the period
  • Cases arising during the period
Formula:
$$\text{Period Prevalence} = \frac{\text{Number of existing cases (old and new) of a specified disease during a given period of time interval}}{\text{Estimated mid-interval population at-risk}} \times 100$$

Diagram: Incidence vs Prevalence (Jan 1 to Dec 31)

Diagram illustrating incidence, point prevalence, and period prevalence with 8 cases over a calendar year
Each line represents the duration of illness for a case. The open circle marks onset.
From the diagram:
MeasureCases included
Incidence (new cases Jan-Dec)Cases 3, 4, 5, 8
Point Prevalence (Jan 1)Cases 1, 2, 7
Point Prevalence (Dec 31)Cases 1, 3, 5, 8
Period Prevalence (Jan-Dec)Cases 1, 2, 3, 4, 5, 7, 8

4. RELATIONSHIP BETWEEN PREVALENCE AND INCIDENCE

Prevalence depends on 2 factors: incidence and duration of illness.
For a stable population (unchanging incidence and duration):
P = I × D (Prevalence = Incidence × Mean Duration of Disease)
Example:
  • Incidence = 10 cases per 1,000 per year
  • Mean duration = 5 years
  • Prevalence = 10 × 5 = 50 per 1,000 population
This formula explains why:
  • Acute diseases (short duration) - prevalence ≈ incidence
  • Chronic diseases (long duration) - prevalence >> incidence

5. USES OF INCIDENCE

The incidence rate as a health status indicator is useful for:
  1. Disease control - A rising incidence rate indicates failure or ineffectiveness of current control programmes and may suggest the need for a new disease control or preventive programme
  2. Aetiological research - Research into aetiology and pathogenesis of diseases
  3. Monitoring distribution - Analysis of differences in incidence rates across socio-economic groups and geographical areas provides insights into the effectiveness of health services
  4. Evaluating interventions - Assessing efficacy of preventive and therapeutic measures
  5. Detecting change - A change in incidence may signal change in the disease agent, host, or environmental characteristics
  6. Improved reporting detection - Rising incidence may also reflect improved reporting practices

6. USES OF PREVALENCE

  1. (a) Estimating disease burden - Prevalence helps estimate the magnitude of health/disease problems in the community and identifies potential high-risk populations
  2. (b) Administrative and planning purposes - Prevalence rates are especially useful for planning hospital beds, manpower needs, rehabilitation facilities, etc.
  3. Substitute for incidence - When incidence rates are not available, prevalence rates (which are more readily obtainable) may be used, though the contribution of the duration element must always be assessed
  4. Testing aetiological hypotheses - Prevalence data can be used to generate or test hypotheses about disease causation

Key Distinction - Incidence vs Prevalence:
FeatureIncidencePrevalence
Cases countedNew cases onlyAll current cases (old + new)
Time referenceOver a periodAt a point / over a period
Type of measureRate (has time unit)Ratio
Best forAcute conditionsChronic conditions
UsesAetiology, controlPlanning, resource allocation
  • Park's Textbook of Preventive and Social Medicine, pp. 73-75

Create a pd

Asking for Preferences
Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Writing File

~/epidemiology-summary/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, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
import urllib.request
import os

OUTPUT = "/home/daytona/workspace/epidemiology-summary/Incidence_Prevalence_Notes.pdf"

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm
)

# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1a3a5c")
MED_BLUE    = colors.HexColor("#2e6da4")
LIGHT_BLUE  = colors.HexColor("#dbeafe")
ACCENT      = colors.HexColor("#e67e22")
GREEN       = colors.HexColor("#27ae60")
LIGHT_GREEN = colors.HexColor("#d5f5e3")
LIGHT_GRAY  = colors.HexColor("#f4f6f8")
TEXT_DARK   = colors.HexColor("#1c1c1c")
WHITE       = colors.white

styles = getSampleStyleSheet()

# Custom styles
title_style = ParagraphStyle(
    "Title", parent=styles["Normal"],
    fontSize=20, textColor=WHITE, fontName="Helvetica-Bold",
    alignment=TA_CENTER, spaceAfter=4
)
subtitle_style = ParagraphStyle(
    "Subtitle", parent=styles["Normal"],
    fontSize=11, textColor=colors.HexColor("#bde0fe"),
    alignment=TA_CENTER, spaceAfter=0
)
h1 = ParagraphStyle(
    "H1", parent=styles["Normal"],
    fontSize=14, textColor=WHITE, fontName="Helvetica-Bold",
    alignment=TA_LEFT, spaceBefore=10, spaceAfter=4,
    leftIndent=6
)
h2 = ParagraphStyle(
    "H2", parent=styles["Normal"],
    fontSize=12, textColor=DARK_BLUE, fontName="Helvetica-Bold",
    spaceBefore=10, spaceAfter=4
)
h3 = ParagraphStyle(
    "H3", parent=styles["Normal"],
    fontSize=11, textColor=MED_BLUE, fontName="Helvetica-Bold",
    spaceBefore=8, spaceAfter=3
)
body = ParagraphStyle(
    "Body", parent=styles["Normal"],
    fontSize=10, textColor=TEXT_DARK, leading=15,
    alignment=TA_JUSTIFY, spaceAfter=5
)
bullet = ParagraphStyle(
    "Bullet", parent=styles["Normal"],
    fontSize=10, textColor=TEXT_DARK, leading=14,
    leftIndent=18, bulletIndent=6, spaceAfter=3
)
formula_style = ParagraphStyle(
    "Formula", parent=styles["Normal"],
    fontSize=10, textColor=DARK_BLUE, fontName="Helvetica-Bold",
    leading=16, alignment=TA_CENTER, spaceAfter=4, spaceBefore=4
)
note_style = ParagraphStyle(
    "Note", parent=styles["Normal"],
    fontSize=9, textColor=colors.HexColor("#7f6000"),
    leading=13, leftIndent=10, spaceAfter=4
)
source_style = ParagraphStyle(
    "Source", parent=styles["Normal"],
    fontSize=8, textColor=colors.HexColor("#888888"),
    alignment=TA_CENTER
)

def section_header(text):
    """Returns a table that looks like a coloured section banner."""
    t = Table([[Paragraph(text, h1)]], colWidths=[17*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
        ("ROUNDEDCORNERS", [6, 6, 6, 6]),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
    ]))
    return t

def formula_box(text):
    t = Table([[Paragraph(text, formula_style)]], colWidths=[17*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
        ("BOX", (0,0), (-1,-1), 1, MED_BLUE),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ]))
    return t

def highlight_box(text, bg=LIGHT_GREEN, border=GREEN):
    t = Table([[Paragraph(text, ParagraphStyle("hb", parent=body, spaceAfter=0))]],
              colWidths=[17*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("BOX", (0,0), (-1,-1), 1, border),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    return t

story = []

# ═══════════════════════════════════════════════════════════════════
# COVER / TITLE BLOCK
# ═══════════════════════════════════════════════════════════════════
cover = Table([
    [Paragraph("Epidemiology", title_style)],
    [Paragraph("Incidence, Prevalence, Attack Rate & Secondary Attack Rate", subtitle_style)],
    [Spacer(1, 5)],
    [Paragraph("Based on Park's Textbook of Preventive and Social Medicine", source_style)],
], colWidths=[17*cm])
cover.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
    ("BOX", (0,0), (-1,-1), 2, ACCENT),
    ("TOPPADDING",    (0,0), (-1,-1), 16),
    ("BOTTOMPADDING", (0,0), (-1,-1), 16),
]))
story.append(cover)
story.append(Spacer(1, 0.4*cm))

# ═══════════════════════════════════════════════════════════════════
# SECTION 1 – INCIDENCE
# ═══════════════════════════════════════════════════════════════════
story.append(section_header("1. INCIDENCE"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "<b>Definition:</b> Incidence rate is defined as <i>\"the number of NEW cases occurring in a "
    "defined population during a specified period of time.\"</i>",
    body
))

story.append(formula_box(
    "Incidence Rate = (Number of new cases of specific disease during a given time period / "
    "Population at-risk during that period) × 1000"
))

story.append(Paragraph("<b>Example:</b>", h3))
story.append(Paragraph(
    "500 new cases in a population of 30,000 in a year → 500/30,000 × 1000 = <b>16.7 per 1,000 per year</b>",
    body
))
story.append(highlight_box(
    "⚠ Note: Incidence rate MUST include the unit of time. Writing '16.7 per 1000' alone is inadequate. "
    "The correct expression is '16.7 per 1,000 per year.'",
    bg=colors.HexColor("#fff8e1"), border=colors.HexColor("#f39c12")
))

story.append(Paragraph("<b>Key Features of Incidence:</b>", h3))
features = [
    ("a)", "Refers only to <b>new cases</b>"),
    ("b)", "Measured during a <b>given period</b> (usually one year)"),
    ("c)", "Refers to a specified <b>population at risk</b>"),
    ("d)", "Can also refer to new <b>spells/episodes</b> of disease (e.g., two attacks of common cold = 2 spells)"),
    ("e)", "Measures the <b>rate at which new cases are occurring</b> — not influenced by disease duration"),
    ("f)", "Generally restricted to <b>acute conditions</b>"),
]
for marker, text in features:
    story.append(Paragraph(f"<b>{marker}</b>  {text}", bullet))

# ═══════════════════════════════════════════════════════════════════
# SECTION 2 – ATTACK RATE
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.3*cm))
story.append(section_header("2. ATTACK RATE"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "An attack rate is an <b>incidence rate (expressed as a percentage)</b>, used only when the population "
    "is exposed to risk for a <b>limited period of time</b>, such as during an <b>epidemic</b>. "
    "It reflects the extent of the epidemic.",
    body
))
story.append(formula_box(
    "Attack Rate = (Number of new cases of a specified disease during a specified time interval / "
    "Total population at risk during the same interval) × 100"
))
story.append(Paragraph("<b>Key Points:</b>", h3))
for pt in [
    "Expressed as a <b>percentage</b> (not per 1,000)",
    "Used specifically in <b>epidemic situations</b>",
    "Reflects communicability of the agent and susceptibility of the exposed population",
    "It is a type of <b>Special Incidence Rate</b>",
]:
    story.append(Paragraph(f"• {pt}", bullet))

# ═══════════════════════════════════════════════════════════════════
# SECTION 3 – SECONDARY ATTACK RATE
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.3*cm))
story.append(section_header("3. SECONDARY ATTACK RATE (SAR)"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "<b>Definition:</b> SAR is defined as <i>\"the number of exposed persons developing the disease "
    "within the range of the incubation period, following exposure to the primary case.\"</i>",
    body
))
story.append(formula_box(
    "SAR = (Number of exposed persons developing disease within incubation period / "
    "Total number of exposed / 'susceptible' contacts) × 100"
))

story.append(Paragraph("<b>Example:</b>", h3))
story.append(highlight_box(
    "A family of 6: 2 immune parents + 4 susceptible children. Primary measles case occurs. "
    "2 secondary cases develop among the remaining 3 susceptible children.\n"
    "SAR = 2/3 = <b>66.6%</b>. The primary case is excluded from both numerator and denominator.",
    bg=LIGHT_GREEN, border=GREEN
))

story.append(Paragraph("<b>Key Rules:</b>", h3))
for pt in [
    "<b>Primary case excluded</b> from both numerator and denominator",
    "Denominator = all <b>exposed contacts</b> (or only susceptible contacts if identifiable)",
    "For diseases with long infectivity (e.g., TB), a <b>person-time denominator</b> is used",
]:
    story.append(Paragraph(f"• {pt}", bullet))

story.append(Paragraph("<b>Limitations:</b>", h3))
for pt in [
    "Limited to diseases with a <b>short period of infectivity</b> (e.g., measles, chickenpox)",
    "Difficult to identify susceptibles in diseases like <b>influenza</b>",
    "Limited meaning when <b>subclinical cases</b> are numerous without laboratory investigation",
]:
    story.append(Paragraph(f"• {pt}", bullet))

story.append(Paragraph("<b>Uses of SAR:</b>", h3))
for pt in [
    "Measures <b>spread of infection</b> within families/households/closed groups",
    "Determines whether a disease of <b>unknown aetiology</b> is communicable",
    "Evaluates effectiveness of <b>control measures</b> (isolation, immunization)",
    "Compares attack rates in <b>vaccinated vs unvaccinated</b> populations",
]:
    story.append(Paragraph(f"• {pt}", bullet))

# ═══════════════════════════════════════════════════════════════════
# SECTION 4 – PREVALENCE
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.3*cm))
story.append(section_header("4. PREVALENCE"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "<b>Definition:</b> <i>\"The total number of all individuals who have an attribute or disease "
    "at a particular time (or during a particular period) divided by the population at risk of "
    "having the attribute or disease at this point in time or midway through the period.\"</i> "
    "Although called a rate, prevalence is technically a <b>ratio</b>.",
    body
))

story.append(Paragraph("<b>Prevalence is of two types:</b>", h3))
story.append(Paragraph("(a) Point Prevalence     (b) Period Prevalence", body))

# ── 4a Point Prevalence ─────────────────────────────────────────
story.append(Paragraph("(a) Point Prevalence", h2))
story.append(Paragraph(
    "The number of <b>all current cases (old and new)</b> of a disease at <b>one point of time</b>, "
    "in relation to a defined population. The 'point' may span a day, several days, or even a few "
    "weeks depending on the time required to examine the population sample.",
    body
))
story.append(formula_box(
    "Point Prevalence = (Number of all current cases at a given point in time / "
    "Estimated population at the same point in time) × 100"
))
story.append(Paragraph(
    "• When 'prevalence rate' is used without qualification, it means <b>point prevalence</b>.<br/>"
    "• Can be made specific for age, sex, and other relevant factors.",
    bullet
))

# ── 4b Period Prevalence ────────────────────────────────────────
story.append(Paragraph("(b) Period Prevalence", h2))
story.append(Paragraph(
    "Measures the frequency of all current cases (old and new) existing during a <b>defined period "
    "of time</b> (e.g., annual prevalence). Includes cases arising <b>before but extending into</b> "
    "the period, as well as cases <b>arising during</b> the period.",
    body
))
story.append(formula_box(
    "Period Prevalence = (Number of existing cases during a given period of time / "
    "Estimated mid-interval population at-risk) × 100"
))

# ── Diagram comparison table ────────────────────────────────────
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("<b>Diagram: Incidence vs Prevalence (Jan 1 – Dec 31)</b>", h3))

diag_data = [
    [Paragraph("<b>Measure</b>", body), Paragraph("<b>Cases Included</b>", body)],
    [Paragraph("Incidence (new cases Jan–Dec)", body),      Paragraph("Cases 3, 4, 5, 8", body)],
    [Paragraph("Point Prevalence (Jan 1)", body),           Paragraph("Cases 1, 2, 7", body)],
    [Paragraph("Point Prevalence (Dec 31)", body),          Paragraph("Cases 1, 3, 5, 8", body)],
    [Paragraph("Period Prevalence (Jan–Dec)", body),        Paragraph("Cases 1, 2, 3, 4, 5, 7, 8", body)],
]
diag_table = Table(diag_data, colWidths=[9.5*cm, 7.5*cm])
diag_table.setStyle(TableStyle([
    ("BACKGROUND",   (0,0), (-1,0),  DARK_BLUE),
    ("TEXTCOLOR",    (0,0), (-1,0),  WHITE),
    ("BACKGROUND",   (0,1), (-1,1),  LIGHT_BLUE),
    ("BACKGROUND",   (0,2), (-1,2),  LIGHT_GRAY),
    ("BACKGROUND",   (0,3), (-1,3),  LIGHT_BLUE),
    ("BACKGROUND",   (0,4), (-1,4),  LIGHT_GRAY),
    ("GRID",         (0,0), (-1,-1), 0.5, colors.HexColor("#aaaaaa")),
    ("TOPPADDING",   (0,0), (-1,-1), 6),
    ("BOTTOMPADDING",(0,0), (-1,-1), 6),
    ("LEFTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(diag_table)

# ═══════════════════════════════════════════════════════════════════
# SECTION 5 – RELATIONSHIP P = I × D
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.3*cm))
story.append(section_header("5. RELATIONSHIP BETWEEN PREVALENCE & INCIDENCE"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "Prevalence depends on 2 factors: <b>incidence</b> and <b>duration of illness</b>. "
    "For a stable population (unchanging incidence and duration):",
    body
))
story.append(formula_box("P = I × D     (Prevalence = Incidence × Mean Duration of Disease)"))
story.append(Paragraph(
    "<b>Example:</b> Incidence = 10/1,000/year; Mean duration = 5 years → "
    "Prevalence = 10 × 5 = <b>50 per 1,000</b>",
    body
))
story.append(Paragraph("<b>Implications:</b>", h3))
for pt in [
    "<b>Acute diseases</b> (short duration) → Prevalence ≈ Incidence",
    "<b>Chronic diseases</b> (long duration) → Prevalence &gt;&gt; Incidence",
]:
    story.append(Paragraph(f"• {pt}", bullet))

# ═══════════════════════════════════════════════════════════════════
# SECTION 6 – USES
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.3*cm))
story.append(section_header("6. USES OF INCIDENCE & PREVALENCE"))
story.append(Spacer(1, 0.2*cm))

uses_data = [
    [
        Paragraph("<b>Uses of Incidence</b>", ParagraphStyle("th", parent=body, textColor=WHITE, fontName="Helvetica-Bold")),
        Paragraph("<b>Uses of Prevalence</b>", ParagraphStyle("th", parent=body, textColor=WHITE, fontName="Helvetica-Bold")),
    ],
    [
        Paragraph(
            "1. <b>Disease control</b> – rising incidence signals failure of control programmes<br/><br/>"
            "2. <b>Aetiological research</b> – study causes and pathogenesis<br/><br/>"
            "3. <b>Monitoring distribution</b> – across socio-economic groups and geographies<br/><br/>"
            "4. <b>Evaluating interventions</b> – efficacy of preventive/therapeutic measures<br/><br/>"
            "5. <b>Detecting change</b> – in agent, host, or environment<br/><br/>"
            "6. <b>Detecting improved reporting</b> – rising incidence may reflect better reporting",
            body
        ),
        Paragraph(
            "1. <b>Estimating disease burden</b> – magnitude of health problems and identifying high-risk populations<br/><br/>"
            "2. <b>Administrative/planning purposes</b> – hospital beds, manpower, rehabilitation facilities<br/><br/>"
            "3. <b>Substitute for incidence</b> – when incidence data is unavailable (duration element must be assessed)<br/><br/>"
            "4. <b>Testing aetiological hypotheses</b> – generate/test hypotheses about disease causation",
            body
        ),
    ]
]
uses_table = Table(uses_data, colWidths=[8.5*cm, 8.5*cm])
uses_table.setStyle(TableStyle([
    ("BACKGROUND",   (0,0), (-1,0),  MED_BLUE),
    ("TEXTCOLOR",    (0,0), (-1,0),  WHITE),
    ("BACKGROUND",   (0,1), (0,1),   LIGHT_BLUE),
    ("BACKGROUND",   (1,1), (1,1),   LIGHT_GREEN),
    ("GRID",         (0,0), (-1,-1), 0.5, colors.HexColor("#aaaaaa")),
    ("TOPPADDING",   (0,0), (-1,-1), 8),
    ("BOTTOMPADDING",(0,0), (-1,-1), 8),
    ("LEFTPADDING",  (0,0), (-1,-1), 8),
    ("VALIGN",       (0,0), (-1,-1), "TOP"),
]))
story.append(uses_table)

# ═══════════════════════════════════════════════════════════════════
# SECTION 7 – QUICK COMPARISON TABLE
# ═══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(section_header("7. INCIDENCE vs PREVALENCE – QUICK COMPARISON"))
story.append(Spacer(1, 0.2*cm))

comp_data = [
    ["Feature", "Incidence", "Prevalence"],
    ["Cases counted",  "New cases only",          "All current cases (old + new)"],
    ["Time reference", "Over a period",            "At a point / over a period"],
    ["Type of measure","Rate (has time unit)",     "Ratio"],
    ["Best for",       "Acute conditions",         "Chronic conditions"],
    ["Primary uses",   "Aetiology, disease control","Planning, resource allocation"],
    ["Formula multiplier", "× 1000 (usually)",    "× 100 (usually)"],
]
col_widths = [4.5*cm, 6.2*cm, 6.3*cm]
comp_table = Table(comp_data, colWidths=col_widths)
comp_table.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0),   DARK_BLUE),
    ("TEXTCOLOR",     (0,0), (-1,0),   WHITE),
    ("FONTNAME",      (0,0), (-1,0),   "Helvetica-Bold"),
    ("BACKGROUND",    (0,1), (0,-1),   LIGHT_GRAY),
    ("FONTNAME",      (0,1), (0,-1),   "Helvetica-Bold"),
    ("BACKGROUND",    (1,1), (1,-1),   LIGHT_BLUE),
    ("BACKGROUND",    (2,1), (2,-1),   LIGHT_GREEN),
    ("ROWBACKGROUNDS",(0,1), (-1,-1),  [colors.HexColor("#f0f4ff"), colors.HexColor("#f0fff4")]),
    ("GRID",          (0,0), (-1,-1),  0.5, colors.HexColor("#aaaaaa")),
    ("TOPPADDING",    (0,0), (-1,-1),  6),
    ("BOTTOMPADDING", (0,0), (-1,-1),  6),
    ("LEFTPADDING",   (0,0), (-1,-1),  8),
    ("FONTSIZE",      (0,0), (-1,-1),  10),
]))
story.append(comp_table)

# ── Footer note ──────────────────────────────────────────────────
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1, color=MED_BLUE))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
    "Source: Park's Textbook of Preventive and Social Medicine, pp. 73–75 | "
    "Notes prepared for educational purposes",
    source_style
))

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

python /home/daytona/workspace/epidemiology-summary/create_pdf.py

Your PDF is ready! Here's the download link:

Incidence Prevalence Notes

PDF Document · PDF

What's included in the PDF:
  1. Incidence - definition, formula, example, and key features
  2. Attack Rate - definition, formula, and key points
  3. Secondary Attack Rate (SAR) - definition, formula, worked example (measles family), limitations, and uses
  4. Prevalence - full definition with both types:
    • Point Prevalence (with formula)
    • Period Prevalence (with formula)
    • Diagram table (Cases 1-8 / Jan 1 - Dec 31)
  5. Relationship P = I × D - with example
  6. Uses of Incidence vs Prevalence - side-by-side comparison table
  7. Quick comparison table - Incidence vs Prevalence at a glance
The PDF uses colour-coded sections, formula boxes, and comparison tables for easy studying.

Create a pdf

Asking for Preferences
The PDF is already generated and ready — here's your download link again:

Incidence Prevalence Notes

PDF Document · PDF

Click the link above to download the full colour-coded notes on Incidence, Prevalence, Attack Rate, Secondary Attack Rate, Point & Period Prevalence, and their Uses.

Can you make pdf look handwritten

Running Command

# Check for any handwriting fonts already on the system fc-list | grep -i -E "h…

Running Command

# Download Caveat (Google Fonts handwriting font) - clean, legible handwriting …

Running Command

# Also grab Kalam (more natural handwriting) as fallback option curl -L -o /hom…

Writing File

~/epidemiology-summary/create_handwritten_pdf.py

"""
Handwritten-style PDF – Incidence, Prevalence, Attack Rate & SAR
Uses Kalam font (Google Fonts) on a ruled notebook-paper background.
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether, Frame, PageTemplate
)
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
import os

# ── Paths ────────────────────────────────────────────────────────────────────
FONT_DIR = "/home/daytona/workspace/epidemiology-summary/fonts"
OUTPUT   = "/home/daytona/workspace/epidemiology-summary/Incidence_Prevalence_Handwritten.pdf"

# ── Register fonts ───────────────────────────────────────────────────────────
pdfmetrics.registerFont(TTFont("Kalam",     f"{FONT_DIR}/Kalam-Regular.ttf"))
pdfmetrics.registerFont(TTFont("KalamBold", f"{FONT_DIR}/Kalam-Bold.ttf"))
pdfmetrics.registerFontFamily("Kalam", normal="Kalam", bold="KalamBold")

# ── Colours ──────────────────────────────────────────────────────────────────
PAGE_BG       = colors.HexColor("#fffef5")   # warm cream
LINE_COLOR    = colors.HexColor("#b8d0e8")   # soft blue ruled lines
MARGIN_COLOR  = colors.HexColor("#f4a0a0")   # red margin line
INK           = colors.HexColor("#1a1a6e")   # dark navy "ink"
HEADING_INK   = colors.HexColor("#0d0d5c")
RED_INK       = colors.HexColor("#c0392b")
GREEN_INK     = colors.HexColor("#1a6e3c")
PENCIL        = colors.HexColor("#555555")
HIGHLIGHT_YLW = colors.HexColor("#fff176")
HIGHLIGHT_GRN = colors.HexColor("#c8f7c5")
HIGHLIGHT_BLU = colors.HexColor("#c5e8f7")
HIGHLIGHT_PNK = colors.HexColor("#ffd6d6")

PAGE_W, PAGE_H = A4
MARGIN_L = 3.2*cm   # left of margin line
MARGIN_R = 1.5*cm
MARGIN_T = 2.2*cm
MARGIN_B = 1.8*cm
LINE_SPACING = 0.72*cm   # ruled line spacing

# ── Draw notebook background on every page ───────────────────────────────────
def draw_notebook_bg(c: canvas.Canvas, doc):
    c.saveState()
    # Cream background
    c.setFillColor(PAGE_BG)
    c.rect(0, 0, PAGE_W, PAGE_H, fill=1, stroke=0)

    # Horizontal ruled lines
    c.setStrokeColor(LINE_COLOR)
    c.setLineWidth(0.5)
    y = PAGE_H - MARGIN_T
    while y > MARGIN_B:
        c.line(0, y, PAGE_W, y)
        y -= LINE_SPACING

    # Red margin line
    c.setStrokeColor(MARGIN_COLOR)
    c.setLineWidth(1.2)
    c.line(MARGIN_L - 0.2*cm, 0, MARGIN_L - 0.2*cm, PAGE_H)

    # Tiny hole punches on left
    c.setFillColor(colors.HexColor("#ddd8cc"))
    c.setStrokeColor(colors.HexColor("#ccc8be"))
    c.setLineWidth(0.5)
    for hole_y in [PAGE_H * 0.25, PAGE_H * 0.5, PAGE_H * 0.75]:
        c.circle(0.55*cm, hole_y, 0.25*cm, fill=1, stroke=1)

    # Page number (bottom right)
    c.setFont("Kalam", 9)
    c.setFillColor(PENCIL)
    c.drawRightString(PAGE_W - 1*cm, 1*cm, str(doc.page))

    c.restoreState()

# ── Styles ───────────────────────────────────────────────────────────────────
def S(name, **kw):
    base = kw.pop("parent", None)
    defaults = dict(
        fontName="Kalam",
        fontSize=12,
        textColor=INK,
        leading=20,
        spaceAfter=4,
        spaceBefore=2,
        alignment=TA_LEFT,
    )
    defaults.update(kw)
    return ParagraphStyle(name, **defaults)

title_s   = S("title",   fontSize=22, fontName="KalamBold", textColor=HEADING_INK,
               alignment=TA_CENTER, spaceAfter=2, leading=28)
sub_s     = S("sub",     fontSize=12, textColor=PENCIL, alignment=TA_CENTER, spaceAfter=6)
h1_s      = S("h1",      fontSize=17, fontName="KalamBold", textColor=RED_INK,
               spaceBefore=14, spaceAfter=4, leading=24)
h2_s      = S("h2",      fontSize=14, fontName="KalamBold", textColor=HEADING_INK,
               spaceBefore=10, spaceAfter=3, leading=20)
h3_s      = S("h3",      fontSize=12, fontName="KalamBold", textColor=GREEN_INK,
               spaceBefore=7, spaceAfter=2)
body_s    = S("body",    fontSize=11, leading=19, spaceAfter=5)
bullet_s  = S("bullet",  fontSize=11, leading=19, leftIndent=22, spaceAfter=3)
formula_s = S("formula", fontSize=11, fontName="KalamBold", textColor=RED_INK,
               leading=18, alignment=TA_CENTER, spaceAfter=4, spaceBefore=4)
note_s    = S("note",    fontSize=10, textColor=PENCIL, leftIndent=12, spaceAfter=4)
src_s     = S("src",     fontSize=9,  textColor=PENCIL, alignment=TA_CENTER)
tbl_hd_s  = S("tblhd",  fontSize=11, fontName="KalamBold", textColor=INK, leading=16)
tbl_s     = S("tblbod", fontSize=10, leading=16)

# ── Helper builders ──────────────────────────────────────────────────────────
def formula_box(text, bg=HIGHLIGHT_YLW):
    inner = Paragraph(text, formula_s)
    t = Table([[inner]], colWidths=[15.8*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("BOX",           (0,0), (-1,-1), 1.2, RED_INK),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 12),
        ("RIGHTPADDING",  (0,0), (-1,-1), 12),
    ]))
    return t

def highlight_note(text, bg=HIGHLIGHT_GRN, border=GREEN_INK):
    inner = Paragraph(text, S("hn", fontSize=10, leading=16, textColor=INK, spaceAfter=0))
    t = Table([[inner]], colWidths=[15.8*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("BOX",           (0,0), (-1,-1), 1, border),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    return t

def b(text):   return f"<font name='KalamBold'>{text}</font>"
def r(text):   return f"<font color='#c0392b'>{text}</font>"
def g(text):   return f"<font color='#1a6e3c'>{text}</font>"
def p_bullet(text):
    return Paragraph(f"  ✦  {text}", bullet_s)

# ── Story ────────────────────────────────────────────────────────────────────
story = []

# ════════════════════════════════════════════════════════════════════
# TITLE PAGE BLOCK
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph("Epidemiology Notes", title_s))
story.append(Paragraph(
    "Incidence · Prevalence · Attack Rate · Secondary Attack Rate",
    sub_s
))
story.append(HRFlowable(width="100%", thickness=1.5, color=RED_INK, spaceAfter=10))
story.append(Paragraph(
    f"{b('Source:')} Park's Textbook of Preventive &amp; Social Medicine, pp. 73–75",
    note_s
))
story.append(Spacer(1, 0.3*cm))

# ════════════════════════════════════════════════════════════════════
# SECTION 1 – INCIDENCE
# ════════════════════════════════════════════════════════════════════
story.append(Paragraph("1.  Incidence", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

story.append(Paragraph(
    f"{b('Definition:')}  The number of {r('NEW cases')} occurring in a defined "
    "population during a specified period of time.",
    body_s
))

story.append(formula_box(
    "Incidence Rate  =  New cases of disease (given period)\n"
    "                   ──────────────────────────────────  × 1000\n"
    "                      Population at-risk (same period)"
))

story.append(Paragraph(
    f"  {b('Example:')}  500 new cases in 30,000 population in 1 year\n"
    f"  → 500 ÷ 30,000 × 1000  =  {r('16.7 per 1,000 per year')}",
    body_s
))
story.append(highlight_note(
    "⚠  Always include the time unit! '16.7 per 1,000' alone is INCORRECT. "
    "Write '16.7 per 1,000 per year'.",
    bg=HIGHLIGHT_PNK, border=RED_INK
))

story.append(Paragraph(f"{b('Key Features:')}", h3_s))
for pt in [
    f"Counts {r('new cases only')}",
    "Measured over a given period (usually 1 year)",
    "Denominator = population at risk",
    "Can count spells/episodes — e.g. 2 attacks of cold = 2 spells",
    "Not influenced by duration of disease",
    "Generally used for acute conditions",
]:
    story.append(p_bullet(pt))

# ════════════════════════════════════════════════════════════════════
# SECTION 2 – ATTACK RATE
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("2.  Attack Rate", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

story.append(Paragraph(
    f"{b('Definition:')}  An incidence rate (expressed as %) used when the population "
    f"is exposed for a {r('limited period')} such as during an {r('epidemic')}.",
    body_s
))

story.append(formula_box(
    "Attack Rate  =  New cases during epidemic period\n"
    "                ─────────────────────────────────  × 100\n"
    "                  Total population at risk"
))

story.append(Paragraph(f"{b('Key Points:')}", h3_s))
for pt in [
    f"Expressed as {r('percentage (×100)')} — not per 1,000",
    "Used in epidemic/outbreak investigation",
    "Reflects communicability of agent + susceptibility of host",
    f"It is a {b('Special Incidence Rate')}",
]:
    story.append(p_bullet(pt))

# ════════════════════════════════════════════════════════════════════
# SECTION 3 – SECONDARY ATTACK RATE
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("3.  Secondary Attack Rate (SAR)", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

story.append(Paragraph(
    f"{b('Definition:')}  The number of exposed persons developing the disease "
    f"within the range of the {r('incubation period')}, following exposure to the "
    f"{r('primary case')}.",
    body_s
))

story.append(formula_box(
    "SAR  =  Exposed persons developing disease (within incubation period)\n"
    "        ─────────────────────────────────────────────────────────────  × 100\n"
    "              Total exposed / susceptible contacts"
))

story.append(Paragraph(f"{b('Worked Example (Measles):')}", h3_s))
story.append(highlight_note(
    "Family of 6:  2 immune parents + 4 susceptible children.\n"
    "Primary case occurs in 1 child.  2 secondary cases develop among remaining 3 susceptible children.\n\n"
    "SAR  =  2 / 3  =  66.6%\n\n"
    "★  Primary case is excluded from BOTH numerator and denominator.",
    bg=HIGHLIGHT_BLU, border=colors.HexColor("#2980b9")
))

story.append(Paragraph(f"{b('Rules:')}", h3_s))
for pt in [
    f"{r('Primary case excluded')} from both numerator & denominator",
    "Denominator = all exposed contacts (or susceptibles only if identifiable)",
    "For long-infectivity diseases (TB) — use person-time denominator",
]:
    story.append(p_bullet(pt))

story.append(Paragraph(f"{b('Limitations:')}", h3_s))
for pt in [
    "Limited to diseases with short infectivity (measles, chickenpox)",
    "Hard to identify susceptibles in diseases like influenza",
    "Limited meaning when subclinical cases are numerous",
]:
    story.append(p_bullet(pt))

story.append(Paragraph(f"{b('Uses of SAR:')}", h3_s))
for pt in [
    "Measure spread of infection within households/closed groups",
    "Determine if disease of unknown aetiology (e.g., Hodgkin's) is communicable",
    "Evaluate effectiveness of isolation &amp; immunization",
    "Compare attack rates: vaccinated vs unvaccinated",
]:
    story.append(p_bullet(pt))

# ════════════════════════════════════════════════════════════════════
# SECTION 4 – PREVALENCE
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("4.  Prevalence", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

story.append(Paragraph(
    f"{b('Definition:')}  All {r('current cases (old + new)')} existing at a given point "
    "in time or over a period of time, divided by the population at risk.  "
    "Although called a rate, it is technically a {b('ratio')}.".replace("{b('ratio')}", b("ratio")),
    body_s
))

# ── 4a Point Prevalence ──────────────────────────────────────────
story.append(Paragraph("(a)  Point Prevalence", h2_s))
story.append(Paragraph(
    f"All current cases at {r('one specific point in time')} "
    "(may span days–weeks while examining the population).",
    body_s
))
story.append(formula_box(
    "Point Prevalence  =  All current cases at a given point in time\n"
    "                     ─────────────────────────────────────────  × 100\n"
    "                        Estimated population at same point"
))
story.append(Paragraph(
    f"  ✦  When 'prevalence rate' is used without qualification → means {b('Point Prevalence')}",
    bullet_s
))

# ── 4b Period Prevalence ─────────────────────────────────────────
story.append(Paragraph("(b)  Period Prevalence", h2_s))
story.append(Paragraph(
    f"All cases existing during a {r('defined period')} (e.g., a full year).  "
    "Includes cases that started before and extended into the period.",
    body_s
))
story.append(formula_box(
    "Period Prevalence  =  All existing cases during a time period\n"
    "                      ────────────────────────────────────────  × 100\n"
    "                         Mid-interval population at-risk"
))

# ── Diagram table ─────────────────────────────────────────────────
story.append(Paragraph(f"{b('Diagram Summary')} (Jan 1 – Dec 31, Cases 1–8):", h3_s))
diag_data = [
    [Paragraph(b("Measure"), tbl_hd_s),           Paragraph(b("Cases Included"), tbl_hd_s)],
    [Paragraph("Incidence (new cases)", tbl_s),   Paragraph("3, 4, 5, 8", tbl_s)],
    [Paragraph("Point Prevalence — Jan 1", tbl_s),Paragraph("1, 2, 7", tbl_s)],
    [Paragraph("Point Prevalence — Dec 31",tbl_s),Paragraph("1, 3, 5, 8", tbl_s)],
    [Paragraph("Period Prevalence (Jan–Dec)",tbl_s),Paragraph("1, 2, 3, 4, 5, 7, 8", tbl_s)],
]
diag_tbl = Table(diag_data, colWidths=[9*cm, 6.8*cm])
diag_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0),  colors.HexColor("#d6eaf8")),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [PAGE_BG, colors.HexColor("#eafaf1")]),
    ("BOX",           (0,0), (-1,-1), 1, LINE_COLOR),
    ("INNERGRID",     (0,0), (-1,-1), 0.5, LINE_COLOR),
    ("TOPPADDING",    (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
]))
story.append(diag_tbl)

# ════════════════════════════════════════════════════════════════════
# SECTION 5 – P = I × D
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("5.  Relationship:  Prevalence = Incidence × Duration", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

story.append(Paragraph(
    "For a stable population (incidence and duration unchanging):",
    body_s
))
story.append(formula_box("P  =  I  ×  D"))
story.append(Paragraph(
    f"  {b('Example:')}  Incidence = 10/1,000/yr;  Mean duration = 5 yrs\n"
    f"  →  Prevalence = 10 × 5 = {r('50 per 1,000')}",
    body_s
))
for pt in [
    f"{b('Acute diseases')} (short duration)  →  Prevalence ≈ Incidence",
    f"{b('Chronic diseases')} (long duration)  →  Prevalence  &gt;&gt;  Incidence",
]:
    story.append(p_bullet(pt))

# ════════════════════════════════════════════════════════════════════
# SECTION 6 – USES
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("6.  Uses of Incidence &amp; Prevalence", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

# Two-column uses table
uses_inc = [
    "Rising rate → signals failure of control programme",
    "Aetiological research (causes, pathogenesis)",
    "Monitor disease distribution across populations",
    "Evaluate preventive / therapeutic measures",
    "Detect change in agent, host, or environment",
    "Detect improved reporting practices",
]
uses_prev = [
    "Estimate magnitude of disease in community",
    "Identify high-risk populations",
    "Administrative/planning: beds, staff, rehab",
    "Substitute when incidence data unavailable",
    "Test aetiological hypotheses",
]

def ul(items):
    return "\n".join(f"  ✦  {i}" for i in items)

uses_data = [
    [Paragraph(b("Uses of Incidence"), tbl_hd_s),
     Paragraph(b("Uses of Prevalence"), tbl_hd_s)],
    [Paragraph(ul(uses_inc),  S("ui", fontSize=10, leading=18, leftIndent=4)),
     Paragraph(ul(uses_prev), S("up", fontSize=10, leading=18, leftIndent=4))],
]
uses_tbl = Table(uses_data, colWidths=[7.9*cm, 7.9*cm])
uses_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0),  colors.HexColor("#d6eaf8")),
    ("BACKGROUND",    (0,1), (0,1),   HIGHLIGHT_BLU),
    ("BACKGROUND",    (1,1), (1,1),   HIGHLIGHT_GRN),
    ("BOX",           (0,0), (-1,-1), 1, LINE_COLOR),
    ("INNERGRID",     (0,0), (-1,-1), 0.5, LINE_COLOR),
    ("TOPPADDING",    (0,0), (-1,-1), 8),
    ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(uses_tbl)

# ════════════════════════════════════════════════════════════════════
# SECTION 7 – QUICK COMPARISON
# ════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("7.  Incidence vs Prevalence — Quick Comparison", h1_s))
story.append(HRFlowable(width="100%", thickness=0.8, color=LINE_COLOR))
story.append(Spacer(1, 0.1*cm))

comp_rows = [
    ["Feature",           "Incidence",                   "Prevalence"],
    ["Cases",             "New cases only",               "All current (old + new)"],
    ["Time",              "Over a period",                "At a point / over period"],
    ["Type",              "Rate (needs time unit)",       "Ratio"],
    ["Best for",          "Acute conditions",             "Chronic conditions"],
    ["Multiplier",        "× 1,000 (usually)",            "× 100 (usually)"],
    ["Main uses",         "Aetiology, control",           "Planning, resource allocation"],
]
comp_styles_list = [
    ("BACKGROUND",    (0,0), (-1,0),  colors.HexColor("#d6eaf8")),
    ("FONTNAME",      (0,0), (-1,0),  "KalamBold"),
    ("BACKGROUND",    (0,1), (0,-1),  colors.HexColor("#f0e6ff")),
    ("FONTNAME",      (0,1), (0,-1),  "KalamBold"),
    ("ROWBACKGROUNDS",(1,1), (-1,-1), [HIGHLIGHT_BLU, HIGHLIGHT_GRN]),
    ("BOX",           (0,0), (-1,-1), 1, LINE_COLOR),
    ("INNERGRID",     (0,0), (-1,-1), 0.5, LINE_COLOR),
    ("TOPPADDING",    (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("FONTSIZE",      (0,0), (-1,-1), 10),
    ("FONTNAME",      (1,1), (-1,-1), "Kalam"),
]
comp_tbl_data = [[Paragraph(c, S("ct", fontSize=10, fontName="KalamBold" if r==0 else "Kalam", leading=15)) for c in row] for r, row in enumerate(comp_rows)]
comp_tbl = Table(comp_tbl_data, colWidths=[4.2*cm, 5.8*cm, 5.8*cm])
comp_tbl.setStyle(TableStyle(comp_styles_list))
story.append(comp_tbl)

# ── Footer ───────────────────────────────────────────────────────────────────
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1, color=RED_INK))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
    "Source: Park's Textbook of Preventive and Social Medicine, pp. 73–75  |  "
    "Notes prepared for educational purposes",
    src_s
))

# ════════════════════════════════════════════════════════════════════
# BUILD
# ════════════════════════════════════════════════════════════════════
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=MARGIN_R,
    leftMargin=MARGIN_L,
    topMargin=MARGIN_T,
    bottomMargin=MARGIN_B,
)
doc.build(story, onFirstPage=draw_notebook_bg, onLaterPages=draw_notebook_bg)
print(f"✓  PDF written to: {OUTPUT}")
Running Command

python /home/daytona/workspace/epidemiology-summary/create_handwritten_pdf.py 2>…

Running Command

ls -lh /home/daytona/workspace/epidemiology-summary/Incidence_Prevalence_Handwri…

Your handwritten-style PDF is ready! Download it here:

Incidence Prevalence Handwritten

PDF Document · PDF

What makes it look handwritten:
  • Kalam font - a Google font designed to mimic natural handwriting
  • Cream/warm yellow page background - like real notebook paper
  • Horizontal ruled blue lines across every page
  • Red vertical margin line on the left
  • Three hole-punch marks on the left edge
  • Navy blue "ink" colour for body text
  • Red ink for headings, formulas, and key terms
  • Yellow highlight boxes for formulas (like highlighting with a marker)
  • Soft pastel highlight boxes (blue/green/pink) for examples and notes
  • Page numbers in the bottom corner in pencil-grey
attachment
attachment

Here's a sample of how I want my notes

analyse_media
Writing File

~/epidemiology-summary/create_sample_style_pdf.py

"""
Recreates the handwritten-notes style PDF matching the user's sample image exactly.
Uses ReportLab canvas (low-level) for precise placement, ruled paper background,
two-column layout, red margin line, centre divider, and full colour-coded system.
Font: Kalam (handwriting) for all text.
"""

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import math, textwrap

# ── Register fonts ────────────────────────────────────────────────
FONT_DIR = "/home/daytona/workspace/epidemiology-summary/fonts"
pdfmetrics.registerFont(TTFont("Kalam",     f"{FONT_DIR}/Kalam-Regular.ttf"))
pdfmetrics.registerFont(TTFont("KalamBold", f"{FONT_DIR}/Kalam-Bold.ttf"))

OUTPUT = "/home/daytona/workspace/epidemiology-summary/Incidence_Prevalence_SampleStyle.pdf"

# ── Page dimensions ───────────────────────────────────────────────
PW, PH = A4          # 595.3 x 841.9 pts
ML = 1.6*cm          # left margin (inside margin line)
MR = 1.2*cm          # right margin
MT = 1.6*cm          # top margin
MB = 1.4*cm          # bottom margin
MARGIN_X = 1.3*cm    # red margin line x
LINE_GAP = 0.60*cm   # ruled line spacing
COL_DIV  = PW / 2.0  # centre divider x
LC_X     = MARGIN_X + 0.4*cm   # left col text start
LC_W     = COL_DIV - LC_X - 0.3*cm
RC_X     = COL_DIV + 0.35*cm   # right col text start
RC_W     = PW - RC_X - MR

# ── Colours ───────────────────────────────────────────────────────
C_LINE   = colors.HexColor("#b8cfe8")   # ruled lines
C_MARGIN = colors.HexColor("#e05050")   # red margin line
C_DIVID  = colors.HexColor("#333333")   # centre divider
C_RED    = colors.HexColor("#c0392b")   # red ink
C_BLUE   = colors.HexColor("#1a3aab")   # blue ink
C_BLACK  = colors.HexColor("#1a1a1a")   # black ink
C_GREEN  = colors.HexColor("#1a7a3a")   # green ink
C_PAGE   = colors.HexColor("#ffffff")   # white page

# ── Canvas helpers ────────────────────────────────────────────────
def draw_page_bg(c, page_num):
    """Ruled paper background, margin line, page number."""
    c.setFillColor(C_PAGE)
    c.rect(0, 0, PW, PH, fill=1, stroke=0)
    # Ruled lines
    c.setStrokeColor(C_LINE)
    c.setLineWidth(0.4)
    y = PH - MT
    while y > MB:
        c.line(0, y, PW, y)
        y -= LINE_GAP
    # Red margin line
    c.setStrokeColor(C_MARGIN)
    c.setLineWidth(1.0)
    c.line(MARGIN_X, 0, MARGIN_X, PH)
    # Centre divider (starts below header area)
    c.setStrokeColor(C_DIVID)
    c.setLineWidth(0.6)
    c.line(COL_DIV, MB, COL_DIV, PH - 3.8*cm)
    # Page number top right
    c.setFont("Kalam", 11)
    c.setFillColor(C_BLUE)
    label = f"Page {page_num}"
    c.drawRightString(PW - MR, PH - 1.0*cm, label)
    tw = c.stringWidth(label, "Kalam", 11)
    c.setStrokeColor(C_BLUE)
    c.setLineWidth(0.7)
    c.line(PW - MR - tw, PH - 1.0*cm - 1.5, PW - MR, PH - 1.0*cm - 1.5)

def set_font(c, bold=False, size=11):
    c.setFont("KalamBold" if bold else "Kalam", size)

def text_width(text, bold=False, size=11):
    fn = "KalamBold" if bold else "Kalam"
    return pdfmetrics.stringWidth(text, fn, size)

def draw_text(c, x, y, text, color=C_BLACK, bold=False, size=11):
    c.setFillColor(color)
    c.setFont("KalamBold" if bold else "Kalam", size)
    c.drawString(x, y, text)

def draw_underline(c, x, y, text, color, bold=False, size=11):
    fn = "KalamBold" if bold else "Kalam"
    w = pdfmetrics.stringWidth(text, fn, size)
    c.setStrokeColor(color)
    c.setLineWidth(0.7)
    c.line(x, y - 1.5, x + w, y - 1.5)

def underlined_text(c, x, y, text, text_color, underline_color, bold=False, size=11):
    draw_text(c, x, y, text, text_color, bold, size)
    draw_underline(c, x, y, text, underline_color, bold, size)
    return x + text_width(text, bold, size)

def draw_centered(c, cx, y, text, color=C_BLACK, bold=False, size=13):
    c.setFillColor(color)
    c.setFont("KalamBold" if bold else "Kalam", size)
    c.drawCentredString(cx, y, text)

# ── Wrapped-text block ────────────────────────────────────────────
def wrap_and_draw(c, x, y, text, col_width, color=C_BLACK, bold=False, size=11,
                  line_height=None, return_y=True):
    """Draw wrapped text inside col_width, return new y."""
    if line_height is None:
        line_height = LINE_GAP
    fn = "KalamBold" if bold else "Kalam"
    c.setFont(fn, size)
    c.setFillColor(color)
    # Simple word-wrap
    words = text.split()
    line = ""
    for word in words:
        test = (line + " " + word).strip()
        if pdfmetrics.stringWidth(test, fn, size) <= col_width:
            line = test
        else:
            c.drawString(x, y, line)
            y -= line_height
            line = word
    if line:
        c.drawString(x, y, line)
        y -= line_height
    return y

def wrap_mixed_line(c, x, y, segments, col_width, size=11, line_height=None):
    """
    Draw a paragraph with mixed-colour/style segments, wrapping at col_width.
    segments = list of (text, color, bold, underline_color_or_None)
    Returns new y.
    """
    if line_height is None:
        line_height = LINE_GAP
    # Expand all segments into words with their attrs
    words = []
    for (text, col, bold, ucol) in segments:
        for w in text.split():
            words.append((w, col, bold, ucol))
    # Re-group into lines
    lines = []
    cur_line = []
    cur_w = 0
    sp_w = pdfmetrics.stringWidth(" ", "Kalam", size)
    for (w, col, bold, ucol) in words:
        fn = "KalamBold" if bold else "Kalam"
        ww = pdfmetrics.stringWidth(w, fn, size)
        gap = sp_w if cur_line else 0
        if cur_w + gap + ww <= col_width:
            cur_line.append((w, col, bold, ucol))
            cur_w += gap + ww
        else:
            if cur_line:
                lines.append(cur_line)
            cur_line = [(w, col, bold, ucol)]
            cur_w = ww
    if cur_line:
        lines.append(cur_line)
    for line_words in lines:
        cx = x
        for i, (w, col, bold, ucol) in enumerate(line_words):
            fn = "KalamBold" if bold else "Kalam"
            if i > 0:
                cx += sp_w
            c.setFont(fn, size)
            c.setFillColor(col)
            c.drawString(cx, y, w)
            if ucol:
                ww = pdfmetrics.stringWidth(w, fn, size)
                c.setStrokeColor(ucol)
                c.setLineWidth(0.7)
                c.line(cx, y - 1.5, cx + ww, y - 1.5)
            cx += pdfmetrics.stringWidth(w, fn, size)
        y -= line_height
    return y

# ── Formula box ───────────────────────────────────────────────────
def formula_box(c, x, y, label, numerator, denominator, multiplier, box_width, size=10):
    """Draw a green-bordered formula box with fraction. Returns new y."""
    lh = LINE_GAP * 0.9
    box_h = lh * 4.2
    pad = 6
    # Border
    c.setStrokeColor(C_GREEN)
    c.setLineWidth(1.2)
    c.rect(x, y - box_h, box_width, box_h, fill=0, stroke=1)
    # Label in green bold on left
    label_w = pdfmetrics.stringWidth(label, "KalamBold", size)
    lx = x + pad
    ly = y - box_h/2 - 3
    c.setFont("KalamBold", size)
    c.setFillColor(C_GREEN)
    c.drawString(lx, ly, label)
    # Fraction area
    frac_x = lx + label_w + 12
    frac_w = box_width - label_w - pad*2 - 14 - multiplier_w(c, multiplier, size)
    # numerator
    nw = pdfmetrics.stringWidth(numerator, "Kalam", size - 1)
    nx = frac_x + (frac_w - nw) / 2
    c.setFont("Kalam", size - 1)
    c.setFillColor(C_BLACK)
    c.drawString(nx, y - box_h/2 + lh*0.55, numerator)
    # fraction bar
    c.setStrokeColor(C_BLACK)
    c.setLineWidth(0.8)
    c.line(frac_x, y - box_h/2, frac_x + frac_w, y - box_h/2)
    # denominator
    dw = pdfmetrics.stringWidth(denominator, "Kalam", size - 1)
    dx = frac_x + (frac_w - dw) / 2
    c.setFont("Kalam", size - 1)
    c.drawString(dx, y - box_h/2 - lh*0.75, denominator)
    # multiplier
    mx = frac_x + frac_w + 6
    c.setFont("KalamBold", size)
    c.setFillColor(C_BLACK)
    c.drawString(mx, y - box_h/2 - 3, multiplier)
    return y - box_h - 4

def multiplier_w(c, text, size):
    return pdfmetrics.stringWidth(text, "KalamBold", size) + 8

# ── Wavy divider line ─────────────────────────────────────────────
def wavy_line(c, x, y, width, color=C_RED, amplitude=3, freq=8):
    c.setStrokeColor(color)
    c.setLineWidth(1.2)
    p = c.beginPath()
    steps = int(width / freq) * 2 + 2
    p.moveTo(x, y)
    for i in range(steps):
        cx1 = x + i * freq + freq/2
        cy1 = y + amplitude * (1 if i % 2 == 0 else -1)
        cx2 = x + (i+1) * freq
        cy2 = y
        p.curveTo(cx1, cy1, cx2, cy2, cx2, cy2)
    c.drawPath(p, stroke=1, fill=0)

# ── Section heading ───────────────────────────────────────────────
def section_heading(c, x, y, number, title, size=13):
    """Blue bold heading with underline. Returns new y."""
    full = f"{number}. {title}"
    c.setFont("KalamBold", size)
    c.setFillColor(C_BLUE)
    c.drawString(x, y, full)
    tw = pdfmetrics.stringWidth(full, "KalamBold", size)
    c.setStrokeColor(C_BLUE)
    c.setLineWidth(0.9)
    c.line(x, y - 2, x + tw, y - 2)
    return y - LINE_GAP * 1.1

def sub_heading(c, x, y, text, size=11):
    """Blue underlined subheading like 'Key features of Incidence :'. Returns new y."""
    c.setFont("KalamBold", size)
    c.setFillColor(C_BLUE)
    c.drawString(x, y, text)
    tw = pdfmetrics.stringWidth(text, "KalamBold", size)
    c.setStrokeColor(C_BLUE)
    c.setLineWidth(0.7)
    c.line(x, y - 1.5, x + tw, y - 1.5)
    return y - LINE_GAP * 0.95

# ── Bullet helpers ────────────────────────────────────────────────
def bullet_item(c, x, y, segments, col_width, size=11):
    """• bullet point with mixed segments. Returns new y."""
    bul = "• "
    bw = pdfmetrics.stringWidth(bul, "Kalam", size)
    c.setFont("Kalam", size)
    c.setFillColor(C_BLACK)
    c.drawString(x, y, bul)
    return wrap_mixed_line(c, x + bw, y, segments, col_width - bw, size)

def alpha_item(c, x, y, letter, segments, col_width, size=11):
    """a) b) c) list items. Returns new y."""
    lbl = f"{letter}) "
    lw = pdfmetrics.stringWidth(lbl, "KalamBold", size)
    c.setFont("KalamBold", size)
    c.setFillColor(C_BLACK)
    c.drawString(x, y, lbl)
    return wrap_mixed_line(c, x + lw, y, segments, col_width - lw, size)

def circled_item(c, x, y, number, segments, col_width, size=11):
    """① ② ③ circled-number list items. Returns new y."""
    circles = ["①","②","③","④","⑤"]
    lbl = circles[number-1] + " "
    lw = pdfmetrics.stringWidth(lbl, "Kalam", size)
    c.setFont("Kalam", size)
    c.setFillColor(C_BLUE)
    c.drawString(x, y, lbl)
    return wrap_mixed_line(c, x + lw, y, segments, col_width - lw, size)

# ═══════════════════════════════════════════════════════════════════
# Main draw routine
# ═══════════════════════════════════════════════════════════════════
c = canvas.Canvas(OUTPUT, pagesize=A4)

# ─────────────────────────────────────────
# PAGE 1
# ─────────────────────────────────────────
draw_page_bg(c, 1)

# ── MAIN TITLE ────────────────────────────
title_y = PH - 1.4*cm
cx = PW / 2
draw_centered(c, cx, title_y,       "Epidemiology – Incidence,", C_RED, bold=True, size=17)
draw_centered(c, cx, title_y - 0.72*cm, "Attack Rate & Secondary Attack Rate", C_RED, bold=True, size=17)
# Thick red underline with dots
ul_y = title_y - 0.72*cm - 3
ul_x1, ul_x2 = 1.8*cm, PW - 1.8*cm
c.setStrokeColor(C_RED)
c.setLineWidth(2.0)
c.line(ul_x1, ul_y, ul_x2, ul_y)
# end dots
c.setFillColor(C_RED)
c.circle(ul_x1, ul_y, 3, fill=1, stroke=0)
c.circle(ul_x2, ul_y, 3, fill=1, stroke=0)

# Starting y positions for columns
COL_START_Y = PH - 4.0*cm
ly = COL_START_Y   # left column current y
ry = COL_START_Y   # right column current y
lx = LC_X
rx = RC_X

# ════════════ LEFT COLUMN ════════════

# ── SECTION 1: INCIDENCE ─────────────
ly = section_heading(c, lx, ly, "1", "Incidence", size=13)
ly -= 2

# Definition line
sp = pdfmetrics.stringWidth(" ", "Kalam", 11)
def_label_w = pdfmetrics.stringWidth("Definition", "KalamBold", 11)
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(lx, ly, "Definition")
draw_underline(c, lx, ly, "Definition", C_RED, bold=True, size=11)
colon_x = lx + def_label_w
c.setFont("Kalam", 11); c.setFillColor(C_RED)
c.drawString(colon_x, ly, " : ")
colon_w = pdfmetrics.stringWidth(" : ", "Kalam", 11)
start_x = colon_x + colon_w
ly = wrap_mixed_line(c, start_x, ly, [
    ('Incidence rate is defined as \u201cthe number of ', C_BLACK, False, None),
    ('NEW', C_BLACK, True, C_BLACK),
    ('cases occurring in a defined population during a specified period of time.\u201d', C_BLACK, False, None),
], LC_W - (start_x - lx), size=11)
ly -= 4

# Formula box 1
ly = formula_box(c, lx, ly,
    "Incidence Rate =",
    "Number of new cases of specific disease during a given time period",
    "Population at-risk during that period",
    "\u00d7 1000",
    LC_W, size=10)
ly -= 4

# Example
c.setFont("KalamBold", 11); c.setFillColor(C_BLUE)
c.drawString(lx, ly, "Example")
tw = pdfmetrics.stringWidth("Example", "KalamBold", 11)
c.setStrokeColor(C_BLUE); c.setLineWidth(0.7)
c.line(lx, ly-1.5, lx+tw, ly-1.5)
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
ex_txt = " : 500 new cases in a population of 30,000 in a year."
c.drawString(lx + tw, ly, ex_txt)
ly -= LINE_GAP

# Incidence rate calculation line
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(lx + 4, ly, "Incidence Rate = ")
iw = pdfmetrics.stringWidth("Incidence Rate = ", "Kalam", 11)
# fraction
num_txt = "500"
den_txt = "30,000"
nw = pdfmetrics.stringWidth(num_txt, "Kalam", 11)
dw = pdfmetrics.stringWidth(den_txt, "Kalam", 11)
fw = max(nw, dw) + 6
fx = lx + 4 + iw
c.drawString(fx + (fw-nw)/2, ly + 5, num_txt)
c.setStrokeColor(C_BLACK); c.setLineWidth(0.8)
c.line(fx, ly, fx + fw, ly)
c.drawString(fx + (fw-dw)/2, ly - 11, den_txt)
# × 1000 = result
after_x = fx + fw + 4
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(after_x, ly, " \u00d7 1000 = ")
eq_w = pdfmetrics.stringWidth(" \u00d7 1000 = ", "Kalam", 11)
res_x = after_x + eq_w
res_txt = "16.7 per 1,000 per year."
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(res_x, ly, res_txt)
draw_underline(c, res_x, ly, res_txt, C_RED, bold=True, size=11)
ly -= LINE_GAP * 1.5

# Note with asterisk
c.setFont("KalamBold", 13); c.setFillColor(C_RED)
c.drawString(lx, ly, "\u2731 ")
sw = pdfmetrics.stringWidth("\u2731 ", "KalamBold", 13)
# "Note :" underlined in red
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(lx + sw, ly, "Note")
nw2 = pdfmetrics.stringWidth("Note", "KalamBold", 11)
draw_underline(c, lx+sw, ly, "Note", C_RED, bold=True, size=11)
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
note_after = " : Incidence rate "
c.drawString(lx+sw+nw2, ly, note_after)
naw = pdfmetrics.stringWidth(note_after, "Kalam", 11)
must_x = lx+sw+nw2+naw
c.setFont("KalamBold", 11); c.setFillColor(C_BLACK)
c.drawString(must_x, ly, "MUST")
mw = pdfmetrics.stringWidth("MUST", "KalamBold", 11)
draw_underline(c, must_x, ly, "MUST", C_BLACK, bold=True, size=11)
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(must_x+mw, ly, " include the unit of time.")
ly -= LINE_GAP
indent = lx + sw + 4
c.drawString(indent, ly, "Writing \u201c16.7 per 1000\u201d alone is inadequate.")
ly -= LINE_GAP
c.drawString(indent, ly, "The correct expression is \u201c")
pref_w = pdfmetrics.stringWidth("The correct expression is \u201c", "Kalam", 11)
corr_x = indent + pref_w
corr_txt = "16.7 per 1,000 per year."
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(corr_x, ly, corr_txt)
draw_underline(c, corr_x, ly, corr_txt, C_RED, bold=True, size=11)
cw = pdfmetrics.stringWidth(corr_txt, "KalamBold", 11)
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(corr_x+cw, ly, "\u201d")
ly -= LINE_GAP * 1.1

# Key features subheading
ly = sub_heading(c, lx, ly, "Key features of Incidence :", size=11)

alpha_items = [
    ([("Refers only to ", C_BLACK, False, None), ("new cases", C_BLACK, False, C_BLUE), (".", C_BLACK, False, None)], "a"),
    ([("Measured during a given ", C_BLACK, False, None), ("period", C_BLACK, False, C_BLUE), (" (usually one year).", C_BLACK, False, None)], "b"),
    ([("Refers to a specified ", C_BLACK, False, None), ("population at risk", C_BLACK, False, C_BLUE), (".", C_BLACK, False, None)], "c"),
    ([("Can also refer to new ", C_BLACK, False, None), ("spells/episodes", C_BLACK, False, C_BLUE), (" of disease (e.g., two attacks of common cold = 2 spells).", C_BLACK, False, None)], "d"),
    ([("Measures the rate at which new cases are occurring \u2013 ", C_BLACK, False, None), ("not influenced", C_BLACK, False, C_BLUE), (" by disease duration.", C_BLACK, False, None)], "e"),
    ([("Generally restricted to ", C_BLACK, False, None), ("acute", C_BLACK, False, C_BLUE), (" conditions.", C_BLACK, False, None)], "f"),
]
for segs, letter in alpha_items:
    ly = alpha_item(c, lx, ly, letter, segs, LC_W, size=11)

ly -= 6
# Wavy divider between section 1 and 2
wavy_line(c, lx, ly, LC_W, C_RED)
ly -= 12

# ── SECTION 2: ATTACK RATE ───────────────
ly = section_heading(c, lx, ly, "2", "Attack Rate", size=13)
ly -= 2

ly = wrap_mixed_line(c, lx, ly, [
    ("An ", C_BLACK, False, None),
    ("attack rate", C_BLACK, False, C_RED),
    (" is an incidence rate (expressed as a ", C_BLACK, False, None),
    ("percentage", C_BLACK, False, C_RED),
    ("), used only when the population is exposed to risk for a limited period of time, such as during an ", C_BLACK, False, None),
    ("epidemic", C_BLACK, False, C_BLUE),
    (". It reflects the extent of the ", C_BLACK, False, None),
    ("epidemic", C_BLACK, False, C_BLUE),
    (".", C_BLACK, False, None),
], LC_W, size=11)
ly -= 4

ly = formula_box(c, lx, ly,
    "Attack Rate =",
    "Number of new cases of a specified disease during a specified time interval",
    "Total population at risk during the same interval",
    "\u00d7 100",
    LC_W, size=10)
ly -= 4

ly = sub_heading(c, lx, ly, "Key points :", size=11)
kp_items = [
    [("Expressed as a ", C_BLACK, False, None), ("percentage", C_BLACK, False, C_RED), (" (not per 1,000).", C_BLACK, False, None)],
    [("Used specifically in ", C_BLACK, False, None), ("epidemic", C_BLACK, False, C_BLUE), (" situations.", C_BLACK, False, None)],
    [("Reflects ", C_BLACK, False, None), ("communicability", C_BLACK, False, C_GREEN), (" of the agent and ", C_BLACK, False, None), ("susceptibility", C_BLACK, False, C_GREEN), (" of the exposed population.", C_BLACK, False, None)],
    [("It is a type of ", C_BLACK, False, None), ("Special Incidence Rate", C_BLACK, False, C_RED), (".", C_BLACK, False, None)],
]
for segs in kp_items:
    ly = bullet_item(c, lx, ly, segs, LC_W, size=11)

# ════════════ RIGHT COLUMN ════════════

# ── SECTION 3: SECONDARY ATTACK RATE ─────
ry = section_heading(c, rx, ry, "3", "Secondary Attack Rate (SAR)", size=13)
ry -= 2

# Definition
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(rx, ry, "Definition")
dw2 = pdfmetrics.stringWidth("Definition", "KalamBold", 11)
draw_underline(c, rx, ry, "Definition", C_RED, bold=True, size=11)
c.setFont("Kalam", 11); c.setFillColor(C_RED)
c.drawString(rx + dw2, ry, " : ")
cw2 = pdfmetrics.stringWidth(" : ", "Kalam", 11)
sx2 = rx + dw2 + cw2
ry = wrap_mixed_line(c, sx2, ry, [
    ("SAR is defined as \u201cthe number of exposed persons developing the disease within the range of the ", C_BLACK, False, None),
    ("incubation period", C_BLACK, False, C_BLUE),
    (", following exposure to the primary case.\u201d", C_BLACK, False, None),
], RC_W - (sx2 - rx), size=11)
ry -= 4

# SAR formula box (two-line denominator)
sar_bw = RC_W
sar_lh = LINE_GAP * 0.9
sar_bh = sar_lh * 5.0
c.setStrokeColor(C_GREEN); c.setLineWidth(1.2)
c.rect(rx, ry - sar_bh, sar_bw, sar_bh, fill=0, stroke=1)
spad = 6
sar_label = "SAR ="
slw = pdfmetrics.stringWidth(sar_label, "KalamBold", 11)
c.setFont("KalamBold", 11); c.setFillColor(C_GREEN)
c.drawString(rx + spad, ry - sar_bh/2 - 4, sar_label)
frac_x2 = rx + spad + slw + 10
frac_w2 = sar_bw - slw - spad*2 - 12 - pdfmetrics.stringWidth("\u00d7 100", "KalamBold", 10) - 4
sar_num = "Number of exposed persons developing"
sar_num2 = "disease within incubation period"
sar_den = "Total number of exposed / \u2018susceptible\u2019"
sar_den2 = "contacts"
mid_y = ry - sar_bh/2
c.setFont("Kalam", 9); c.setFillColor(C_BLACK)
nw3 = pdfmetrics.stringWidth(sar_num, "Kalam", 9)
c.drawString(frac_x2 + (frac_w2 - nw3)/2, mid_y + sar_lh*0.7, sar_num)
nw3b = pdfmetrics.stringWidth(sar_num2, "Kalam", 9)
c.drawString(frac_x2 + (frac_w2 - nw3b)/2, mid_y + sar_lh*0.05, sar_num2)
c.setStrokeColor(C_BLACK); c.setLineWidth(0.8)
c.line(frac_x2, mid_y - sar_lh*0.3, frac_x2 + frac_w2, mid_y - sar_lh*0.3)
dw3 = pdfmetrics.stringWidth(sar_den, "Kalam", 9)
c.drawString(frac_x2 + (frac_w2 - dw3)/2, mid_y - sar_lh*0.9, sar_den)
dw3b = pdfmetrics.stringWidth(sar_den2, "Kalam", 9)
c.drawString(frac_x2 + (frac_w2 - dw3b)/2, mid_y - sar_lh*1.6, sar_den2)
mx2 = frac_x2 + frac_w2 + 4
c.setFont("KalamBold", 10); c.setFillColor(C_BLACK)
c.drawString(mx2, mid_y - 4, "\u00d7 100")
ry = ry - sar_bh - 4

# Example subheading
c.setFont("KalamBold", 11); c.setFillColor(C_BLUE)
c.drawString(rx, ry, "Example :")
tw2 = pdfmetrics.stringWidth("Example :", "KalamBold", 11)
c.setStrokeColor(C_BLUE); c.setLineWidth(0.7)
c.line(rx, ry-1.5, rx+tw2, ry-1.5)
ry -= LINE_GAP

ry = wrap_mixed_line(c, rx, ry, [
    ("A family of 6 : 2 immune parents + 4 susceptible children. Primary measles case occurs.", C_BLACK, False, None),
], RC_W, size=11)
ry = wrap_mixed_line(c, rx, ry, [
    ("2 secondary cases develop among the remaining 3 susceptible children.", C_BLACK, False, None),
], RC_W, size=11)
ry -= 4

# SAR calculation
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(rx + 4, ry, "SAR = ")
sw2 = pdfmetrics.stringWidth("SAR = ", "Kalam", 11)
fx3 = rx + 4 + sw2
num_s = "2"
den_s = "3"
fw3 = 18
nw4 = pdfmetrics.stringWidth(num_s, "Kalam", 13)
dw4 = pdfmetrics.stringWidth(den_s, "Kalam", 13)
c.setFont("Kalam", 13)
c.drawString(fx3 + (fw3-nw4)/2, ry + 5, num_s)
c.setStrokeColor(C_BLACK); c.setLineWidth(0.8)
c.line(fx3, ry, fx3+fw3, ry)
c.drawString(fx3 + (fw3-dw4)/2, ry - 12, den_s)
ax3 = fx3 + fw3 + 4
c.setFont("Kalam", 11)
c.drawString(ax3, ry, " \u00d7 100 = ")
eq3w = pdfmetrics.stringWidth(" \u00d7 100 = ", "Kalam", 11)
res3_x = ax3 + eq3w
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(res3_x, ry, "66.6%.")
rw3 = pdfmetrics.stringWidth("66.6%.", "KalamBold", 11)
draw_underline(c, res3_x, ry, "66.6%.", C_RED, bold=True, size=11)
ry -= LINE_GAP * 1.5

ry = wrap_mixed_line(c, rx, ry, [
    ("The primary case is ", C_BLACK, False, None),
    ("excluded", C_BLACK, False, C_BLACK),
    (" from both numerator and denominator.", C_BLACK, False, None),
], RC_W, size=11)
# underline "excluded"
excl_x = rx + pdfmetrics.stringWidth("The primary case is ", "Kalam", 11)
draw_underline(c, excl_x, ry + LINE_GAP, "excluded", C_BLACK, size=11)
ry -= 4

# Key rules
ry = sub_heading(c, rx, ry, "Key rules :", size=11)
kr_items = [
    [("Primary case ", C_BLACK, False, None), ("excluded", C_BLACK, False, C_BLACK), (" from both numerator and denominator.", C_BLACK, False, None)],
    [("Denominator = all exposed contacts (or only susceptible contacts if identifiable).", C_BLACK, False, None)],
    [("For diseases with long infectivity (e.g., TB), a ", C_BLACK, False, None), ("person-time", C_BLACK, False, C_BLUE), (" denominator is used.", C_BLACK, False, None)],
]
for segs in kr_items:
    ry = bullet_item(c, rx, ry, segs, RC_W, size=11)

# Limitations
ry = sub_heading(c, rx, ry, "Limitations :", size=11)
lim_items = [
    [("Limited to diseases with a short period of infectivity (e.g., measles, chickenpox).", C_BLACK, False, None)],
    [("Difficult to identify susceptibles in diseases like influenza.", C_BLACK, False, None)],
    [("Limited meaning when subclinical cases are numerous without laboratory investigation.", C_BLACK, False, None)],
]
for segs in lim_items:
    ry = bullet_item(c, rx, ry, segs, RC_W, size=11)

# Uses of SAR
ry = sub_heading(c, rx, ry, "Uses of SAR :", size=11)
uses_items = [
    [("Measures spread of infection within families/households/closed groups.", C_BLACK, False, None)],
    [("Determines whether a disease of unknown aetiology is communicable.", C_BLACK, False, None)],
    [("Evaluates effectiveness of control measures (isolation, immunization).", C_BLACK, False, None)],
    [("Compares attack rates in ", C_BLACK, False, None), ("vaccinated", C_BLACK, False, C_BLACK), (" vs. ", C_BLACK, False, None), ("unvaccinated", C_BLACK, False, C_BLACK), (" populations.", C_BLACK, False, None)],
]
for i, segs in enumerate(uses_items, 1):
    ry = circled_item(c, rx, ry, i, segs, RC_W, size=11)

c.showPage()

# ─────────────────────────────────────────
# PAGE 2: Prevalence
# ─────────────────────────────────────────
draw_page_bg(c, 2)

ly2 = PH - MT - 0.4*cm
ry2 = PH - MT - 0.4*cm

# ════════════ LEFT COLUMN – PAGE 2 ════════════

ly2 = section_heading(c, lx, ly2, "4", "Prevalence", size=13)
ly2 -= 2

# Definition
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(lx, ly2, "Definition")
dp_w = pdfmetrics.stringWidth("Definition", "KalamBold", 11)
draw_underline(c, lx, ly2, "Definition", C_RED, bold=True, size=11)
c.setFont("Kalam", 11); c.setFillColor(C_RED)
c.drawString(lx + dp_w, ly2, " : ")
cp_w = pdfmetrics.stringWidth(" : ", "Kalam", 11)
sp2 = lx + dp_w + cp_w
ly2 = wrap_mixed_line(c, sp2, ly2, [
    ("All ", C_BLACK, False, None),
    ("current cases (old and new)", C_BLACK, False, C_BLUE),
    (" existing at a given point in time, or over a period of time in a given population. Although called a rate, prevalence is technically a ", C_BLACK, False, None),
    ("ratio", C_BLACK, True, None),
    (".", C_BLACK, False, None),
], LC_W - (sp2-lx), size=11)
ly2 -= 6

c.setFont("KalamBold", 11); c.setFillColor(C_BLACK)
c.drawString(lx, ly2, "Prevalence is of two types :")
ly2 -= LINE_GAP
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(lx + 12, ly2, "(a) Point Prevalence")
ly2 -= LINE_GAP
c.drawString(lx + 12, ly2, "(b) Period Prevalence")
ly2 -= LINE_GAP * 1.1

# (a) Point Prevalence
c.setFont("KalamBold", 12); c.setFillColor(C_BLUE)
c.drawString(lx, ly2, "(a) Point Prevalence")
tw_pp = pdfmetrics.stringWidth("(a) Point Prevalence", "KalamBold", 12)
c.setStrokeColor(C_BLUE); c.setLineWidth(0.8)
c.line(lx, ly2-2, lx+tw_pp, ly2-2)
ly2 -= LINE_GAP * 1.1

ly2 = wrap_mixed_line(c, lx, ly2, [
    ("The number of all current cases (old and new) of a disease at ", C_BLACK, False, None),
    ("one point of time", C_BLACK, False, C_BLUE),
    (", in relation to a defined population.", C_BLACK, False, None),
], LC_W, size=11)
ly2 -= 4

ly2 = formula_box(c, lx, ly2,
    "Point Prevalence =",
    "All current cases at a given point in time",
    "Estimated population at same point in time",
    "\u00d7 100",
    LC_W, size=10)
ly2 -= 4

ly2 = bullet_item(c, lx, ly2, [
    ("When 'prevalence rate' is used without qualification, it means ", C_BLACK, False, None),
    ("point prevalence", C_BLACK, True, None),
    (".", C_BLACK, False, None),
], LC_W, size=11)
ly2 = bullet_item(c, lx, ly2, [
    ("Can be made specific for age, sex, and other relevant factors.", C_BLACK, False, None),
], LC_W, size=11)
ly2 -= 8

# (b) Period Prevalence
c.setFont("KalamBold", 12); c.setFillColor(C_BLUE)
c.drawString(lx, ly2, "(b) Period Prevalence")
tw_per = pdfmetrics.stringWidth("(b) Period Prevalence", "KalamBold", 12)
c.setStrokeColor(C_BLUE); c.setLineWidth(0.8)
c.line(lx, ly2-2, lx+tw_per, ly2-2)
ly2 -= LINE_GAP * 1.1

ly2 = wrap_mixed_line(c, lx, ly2, [
    ("Measures the frequency of all cases (old and new) existing during a ", C_BLACK, False, None),
    ("defined period", C_BLACK, False, C_BLUE),
    (" (e.g., annual prevalence). Includes cases arising ", C_BLACK, False, None),
    ("before but extending into", C_BLACK, False, C_BLUE),
    (" the period, as well as cases arising during the period.", C_BLACK, False, None),
], LC_W, size=11)
ly2 -= 4

ly2 = formula_box(c, lx, ly2,
    "Period Prevalence =",
    "All existing cases during a given period of time",
    "Estimated mid-interval population at-risk",
    "\u00d7 100",
    LC_W, size=10)
ly2 -= 8

# Diagram table
ly2 = sub_heading(c, lx, ly2, "Diagram Summary (Jan 1 \u2013 Dec 31) :", size=11)
diag_rows = [
    ("Measure", "Cases Included", True),
    ("Incidence (new cases)", "3, 4, 5, 8", False),
    ("Point Prevalence \u2013 Jan 1", "1, 2, 7", False),
    ("Point Prevalence \u2013 Dec 31", "1, 3, 5, 8", False),
    ("Period Prevalence (Jan\u2013Dec)", "1, 2, 3, 4, 5, 7, 8", False),
]
col1w = 8.5*cm; col2w = LC_W - col1w
rh = LINE_GAP
for row in diag_rows:
    r_y_top = ly2 + rh * 0.85
    r_y_bot = ly2 - rh * 0.25
    if row[2]:  # header
        c.setFillColor(colors.HexColor("#d6eaf8"))
        c.rect(lx, r_y_bot, LC_W, rh * 1.1, fill=1, stroke=0)
    c.setStrokeColor(C_LINE); c.setLineWidth(0.5)
    c.rect(lx, r_y_bot, col1w, rh * 1.1, fill=0, stroke=1)
    c.rect(lx + col1w, r_y_bot, col2w, rh * 1.1, fill=0, stroke=1)
    bold = row[2]
    c.setFont("KalamBold" if bold else "Kalam", 10)
    c.setFillColor(C_BLUE if bold else C_BLACK)
    c.drawString(lx + 4, ly2, row[0])
    c.drawString(lx + col1w + 4, ly2, row[1])
    ly2 -= rh * 1.1

# ════════════ RIGHT COLUMN – PAGE 2 ════════════

# Section 5: P = I x D
ry2 = section_heading(c, rx, ry2, "5", "Relationship:  P = I \u00d7 D", size=13)
ry2 -= 2

ry2 = wrap_mixed_line(c, rx, ry2, [
    ("Prevalence depends on 2 factors: ", C_BLACK, False, None),
    ("incidence", C_BLACK, True, None),
    (" and ", C_BLACK, False, None),
    ("duration of illness", C_BLACK, True, None),
    (". For a stable population:", C_BLACK, False, None),
], RC_W, size=11)
ry2 -= 4

# Big P = I × D box
pid_box_h = LINE_GAP * 2.0
c.setStrokeColor(C_GREEN); c.setLineWidth(1.2)
c.rect(rx, ry2 - pid_box_h, RC_W, pid_box_h, fill=0, stroke=1)
c.setFont("KalamBold", 14); c.setFillColor(C_GREEN)
pid_txt = "P  =  I  \u00d7  D"
ptw = pdfmetrics.stringWidth(pid_txt, "KalamBold", 14)
c.drawString(rx + (RC_W - ptw)/2, ry2 - pid_box_h/2 - 5, pid_txt)
ry2 -= pid_box_h + 4

ry2 = wrap_mixed_line(c, rx, ry2, [
    ("(Prevalence = Incidence \u00d7 Mean Duration of Disease)", C_BLACK, False, None),
], RC_W, size=10)
ry2 -= 4

# Example
c.setFont("KalamBold", 11); c.setFillColor(C_BLUE)
c.drawString(rx, ry2, "Example :")
tw_ex = pdfmetrics.stringWidth("Example :", "KalamBold", 11)
c.setStrokeColor(C_BLUE); c.setLineWidth(0.7)
c.line(rx, ry2-1.5, rx+tw_ex, ry2-1.5)
ry2 -= LINE_GAP
c.setFont("Kalam", 11); c.setFillColor(C_BLACK)
c.drawString(rx + 4, ry2, "Incidence = 10/1,000/yr;  Mean duration = 5 years")
ry2 -= LINE_GAP
c.drawString(rx + 4, ry2, "\u2192  Prevalence = 10 \u00d7 5 = ")
arw = pdfmetrics.stringWidth("\u2192  Prevalence = 10 \u00d7 5 = ", "Kalam", 11)
c.setFont("KalamBold", 11); c.setFillColor(C_RED)
c.drawString(rx + 4 + arw, ry2, "50 per 1,000")
draw_underline(c, rx + 4 + arw, ry2, "50 per 1,000", C_RED, bold=True, size=11)
ry2 -= LINE_GAP * 1.2

for pt in [
    [("Acute diseases", C_BLACK, True, None), (" (short duration) \u2192 Prevalence \u2248 Incidence", C_BLACK, False, None)],
    [("Chronic diseases", C_BLACK, True, None), (" (long duration) \u2192 Prevalence >> Incidence", C_BLACK, False, None)],
]:
    ry2 = bullet_item(c, rx, ry2, pt, RC_W, size=11)

ry2 -= 10
wavy_line(c, rx, ry2, RC_W, C_RED)
ry2 -= 12

# Section 6: Uses of Incidence
ry2 = section_heading(c, rx, ry2, "6", "Uses of Incidence Rate", size=13)
ry2 -= 2

ry2 = wrap_mixed_line(c, rx, ry2, [
    ("The incidence rate is useful for: (a) to ", C_BLACK, False, None),
    ("control disease", C_BLACK, True, None),
    (", and (b) for research into ", C_BLACK, False, None),
    ("aetiology", C_BLACK, True, None),
    (", distribution of diseases, and efficacy of preventive and therapeutic measures.", C_BLACK, False, None),
], RC_W, size=11)
ry2 -= 4

ry2 = sub_heading(c, rx, ry2, "Key uses :", size=11)
uses_inc = [
    [("Rising rate \u2192 signals ", C_BLACK, False, None), ("failure of control programme", C_BLACK, False, C_BLUE), (".", C_BLACK, False, None)],
    [("Aetiological research: causes, pathogenesis of diseases.", C_BLACK, False, None)],
    [("Monitor disease distribution across socio-economic groups and geographies.", C_BLACK, False, None)],
    [("Evaluate efficacy of preventive / therapeutic measures.", C_BLACK, False, None)],
    [("Detect change in agent, host, or environmental characteristics.", C_BLACK, False, None)],
    [("Rising rates may also indicate improved reporting practices.", C_BLACK, False, None)],
]
for i, segs in enumerate(uses_inc, 1):
    ry2 = circled_item(c, rx, ry2, i, segs, RC_W, size=11)

ry2 -= 8

# Section 7: Uses of Prevalence
ry2 = section_heading(c, rx, ry2, "7", "Uses of Prevalence", size=13)
ry2 -= 2

uses_prev = [
    [("Estimate ", C_BLACK, False, None), ("magnitude of disease burden", C_BLACK, False, C_BLUE), (" in the community.", C_BLACK, False, None)],
    [("Identify potential ", C_BLACK, False, None), ("high-risk populations", C_BLACK, False, C_BLUE), (".", C_BLACK, False, None)],
    [("Administrative/planning purposes: hospital beds, ", C_BLACK, False, None), ("manpower", C_BLACK, False, C_BLUE), (", rehabilitation facilities.", C_BLACK, False, None)],
    [("Substitute when ", C_BLACK, False, None), ("incidence data unavailable", C_BLACK, False, C_BLUE), (" (duration element must be assessed).", C_BLACK, False, None)],
    [("Testing aetiological hypotheses about disease causation.", C_BLACK, False, None)],
]
for i, segs in enumerate(uses_prev, 1):
    ry2 = circled_item(c, rx, ry2, i, segs, RC_W, size=11)

ry2 -= 10

# Source note at bottom
c.setFont("Kalam", 9); c.setFillColor(colors.HexColor("#888888"))
src = "Source: Park\u2019s Textbook of Preventive and Social Medicine, pp. 73\u201375"
c.drawCentredString(PW/2, MB + 2, src)

c.showPage()
c.save()
print(f"\u2713 PDF written to: {OUTPUT}")
Running Command

python /home/daytona/workspace/epidemiology-summary/create_sample_style_pdf.py 2…

Editing File

~/epidemiology-summary/create_sample_style_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/epidemiology-summary/create_sample_style_pdf.py'
Running Command

python /home/daytona/workspace/epidemiology-summary/create_sample_style_pdf.py 2…

Running Command

ls -lh /home/daytona/workspace/epidemiology-summary/Incidence_Prevalence_SampleS…

Your notes-style PDF is ready! Download it here:

Incidence Prevalence SampleStyle

PDF Document · PDF

Exactly matching your sample style:
FeatureImplementation
Ruled paperLight blue horizontal lines across every page
Red margin lineVertical red line on the left
Two-column layoutThin black centre divider, same as sample
Page numberTop-right, blue, underlined ("Page 1")
Handwriting fontKalam (clean print-style, just like your sample)
Red inkTitle, "Definition" labels, key emphasis, asterisk notes
Blue inkSection headings (underlined), subheadings, page number
Green inkFormula box labels and borders
Black inkBody text
UnderlinesBlue for key terms, red for answers/results, black for excluded/specific
Formula boxesGreen-bordered, fraction with dividing line, multiplier
a) b) c) listsAlphabetical for Key Features
• bullet pointsFor Key Rules, Limitations, Key Points
① ② ③ circlesBlue circled numbers for Uses sections
Wavy red dividerBetween sections (like in your sample)
attachment
attachment

Create a notes for these topics from park's psm textbook

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
This is a shared conversation. Sign in to Orris to start your own chat.