List of all the drug calculation formulas for adults and paediatric with examples
drug calculation formulas adults paediatric nursing complete list with examples
https://nurseslabs.com/pediatric-dosage-calculations
| Metric | Equivalent |
|---|---|
| 1 microgram (mcg) | 0.000001 g (1/1000 mg) |
| 1 milligram (mg) | 0.001 g / 1000 mcg |
| 1 gram (g) | 1000 mg |
| 1 kilogram (kg) | 1000 g / 2.2 lbs |
| 1 milliliter (mL) | 0.001 L |
| 1 teaspoon | 5 mL |
| 1 tablespoon | 15 mL / 3 tsp |
| 1 fluid ounce | 30 mL |
Dose to give = (Desired dose / Have on hand) x Vehicle
= (500 / 250) x 5 mL = 2 x 5 = 10 mL
= (0.25 / 0.125) x 1 = 2 tablets
H : V = D : X
(cross-multiply to solve for X)
250 : 1 = 750 : X
250X = 750
X = 3 capsules
Drip rate (gtt/min) = (Volume to infuse in mL x Drop factor) / Time in minutes
Time = 8 x 60 = 480 minutes
Drip rate = (1000 x 20) / 480 = 20,000 / 480 = 41.7 ≈ 42 gtt/min
Flow rate (mL/hr) = Total volume (mL) / Total time (hours)
Flow rate = 500 / 4 = 125 mL/hr
Infusion time (hours) = Total volume (mL) / Flow rate (mL/hr)
Time = 1000 / 125 = 8 hours
Dose = Ordered dose (mg/kg) x Patient weight (kg)
Dose = 25 x 70 = 1750 mg per dose
mL/hr = (Dose in mcg/kg/min x Weight in kg x 60) / Concentration in mcg/mL
mL/hr = (5 x 80 x 60) / 1600 = 24,000 / 1600 = 15 mL/hr
Amount to administer = (Desired dose / Available dose) x Volume after reconstitution
= (500 mg / 100 mg) x 1 mL = 5 mL
% Solution = (Amount of drug in g / Total volume in mL) x 100
Volume to give (mL) = Units ordered / Units per mL available
= 5000 / 10,000 = 0.5 mL
BSA (m²) = √[ Height (cm) x Weight (kg) / 3600 ]
BSA = √(170 x 70 / 3600) = √(11900/3600) = √3.306 = 1.82 m²
Dose = BSA (m²) x Dose per m²
Dose = 1.82 x 50 = 91 mg
CrCl (mL/min) = [ (140 - Age) x Weight (kg) ] / [ 72 x Serum Creatinine (mg/dL) ]
(Multiply by 0.85 for females)
CrCl = (140 - 65) x 70 / (72 x 1.2) = 75 x 70 / 86.4 = 5250 / 86.4 = 60.8 mL/min
Paediatric doses are almost always based on weight (mg/kg), but several age-based rules are also used to estimate doses when only the adult dose is known.
Child's dose = Ordered dose (mg/kg) x Child's weight (kg)
Dose = 15 x 20 = 300 mg
Child's dose = [ Age (years) / (Age + 12) ] x Adult dose
= [10 / (10 + 12)] x 500
= [10 / 22] x 500
= 0.455 x 500 = 227.5 mg ≈ 225 mg
Child's dose = [ Age (months) / 150 ] x Adult dose
= [24 / 150] x 500
= 0.16 x 500 = 80 mg
Child's dose = [ Weight of child (lb) / 150 lb ] x Adult dose
Note: Use weight in pounds only, never kilograms, for this formula. Average adult weight = 150 lbs.
= [60 / 150] x 500
= 0.4 x 500 = 200 mg
Child's dose = (Child's BSA in m² / 1.7 m²) x Adult dose
= (0.64 / 1.7) x 500
= 0.38 x 500 = 190 mg
BSA = √[ Height (cm) x Weight (kg) / 3600 ]
BSA = √(100 x 16.4 / 3600) = √(1640/3600) = √0.456 = 0.675 m²
Drip rate (gtt/min) = (Volume x Drop factor) / Time in minutes
Paediatric IV sets typically use 60 gtt/mL (micro-drip) for accuracy with small volumes.
Time = 4 x 60 = 240 min
Drip rate = (100 x 60) / 240 = 6000 / 240 = 25 gtt/min
Low safe dose = Low mg/kg x Child's weight (kg)
High safe dose = High mg/kg x Child's weight (kg)
Low = 10 x 20 = 200 mg
High = 30 x 20 = 600 mg
→ Prescribed dose must fall between 200-600 mg to be safe
| Formula | Used For | Key Variable |
|---|---|---|
| D/H x V | Any oral/parenteral dose | Desired, Have, Vehicle |
| Ratio & Proportion | Dose calculation | Cross multiply |
| Drip rate (gtt/min) | IV gravity infusion | Drop factor, time |
| mL/hr | IV pump rate | Volume, time |
| mg/kg | Weight-based dosing (all ages) | Patient weight |
| mcg/kg/min | Vasoactive drips | Concentration, weight |
| Reconstitution | Powder vials | Post-reconstitution conc. |
| BSA (Mosteller) | Chemo, high-risk drugs | Height, weight |
| Cockcroft-Gault | Renal dose adjustment | Age, weight, creatinine |
| Young's Rule | Paediatric (2-12 yrs) | Age in years |
| Fried's Rule | Infants (<2 yrs) | Age in months |
| Clark's Rule | Paediatric (weight-based) | Weight in lbs |
| BSA Paediatric | Paediatric/chemo doses | BSA vs 1.7 m² |
| Safe Dose Range | Paediatric safety check | mg/kg range x weight |
Create a quick reference PDF or pocket guide for drug calculation formulas
ls /home/daytona/workspace/
mkdir -p /home/daytona/workspace/drug-calc-guide
~/drug-calc-guide/generate_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfgen import canvas
from reportlab.platypus.flowables import Flowable
# ── Colour Palette ────────────────────────────────────────────────
NAVY = colors.HexColor("#0D2B55")
TEAL = colors.HexColor("#0B7FA0")
TEAL_LIGHT = colors.HexColor("#D6F0F7")
GREEN = colors.HexColor("#0A6E44")
GREEN_LIGHT= colors.HexColor("#D4EDDA")
AMBER = colors.HexColor("#B45309")
AMBER_LIGHT= colors.HexColor("#FEF3C7")
RED = colors.HexColor("#9B1C1C")
RED_LIGHT = colors.HexColor("#FEE2E2")
PURPLE = colors.HexColor("#5B21B6")
PURPLE_LIGHT=colors.HexColor("#EDE9FE")
GREY_DARK = colors.HexColor("#374151")
GREY_MID = colors.HexColor("#6B7280")
GREY_LIGHT = colors.HexColor("#F3F4F6")
WHITE = colors.white
BLACK = colors.black
PAGE_W, PAGE_H = A4
MARGIN = 1.6 * cm
# ── Styles ─────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
TITLE_STYLE = S("MainTitle",
fontName="Helvetica-Bold", fontSize=22, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=4)
SUBTITLE_STYLE = S("SubTitle",
fontName="Helvetica", fontSize=10, textColor=colors.HexColor("#B0D9F0"),
alignment=TA_CENTER, spaceAfter=2)
SECTION_HEADER = S("SectionH",
fontName="Helvetica-Bold", fontSize=11, textColor=WHITE,
alignment=TA_LEFT, leftIndent=6, spaceBefore=4, spaceAfter=2)
FORMULA_NAME = S("FormName",
fontName="Helvetica-Bold", fontSize=9.5, textColor=NAVY,
spaceBefore=2, spaceAfter=1)
FORMULA_BOX = S("FormBox",
fontName="Helvetica-Bold", fontSize=9, textColor=NAVY,
leftIndent=8, spaceBefore=1, spaceAfter=1)
BODY = S("Body",
fontName="Helvetica", fontSize=8.5, textColor=GREY_DARK,
leftIndent=8, spaceBefore=1, spaceAfter=1)
EXAMPLE_LABEL = S("ExLabel",
fontName="Helvetica-BoldOblique", fontSize=8, textColor=TEAL,
leftIndent=8, spaceBefore=1)
EXAMPLE_TEXT = S("ExText",
fontName="Helvetica-Oblique", fontSize=8, textColor=GREY_DARK,
leftIndent=16, spaceAfter=2)
NOTE = S("Note",
fontName="Helvetica-Oblique", fontSize=7.5, textColor=GREY_MID,
leftIndent=8, spaceAfter=2)
TABLE_HEADER = S("TH",
fontName="Helvetica-Bold", fontSize=8, textColor=WHITE,
alignment=TA_CENTER)
TABLE_CELL = S("TC",
fontName="Helvetica", fontSize=7.5, textColor=GREY_DARK,
alignment=TA_LEFT)
FOOTER_STYLE = S("Footer",
fontName="Helvetica-Oblique", fontSize=7, textColor=GREY_MID,
alignment=TA_CENTER)
WARNING = S("Warn",
fontName="Helvetica-Bold", fontSize=8, textColor=RED,
leftIndent=8, spaceAfter=2)
# ── Helper Flowables ───────────────────────────────────────────────
def section_bar(title, color=TEAL):
"""Coloured section header bar."""
data = [[Paragraph(title, SECTION_HEADER)]]
t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4, 4, 4, 4]),
]))
return t
def formula_card(name, formula_lines, example_steps, note=None,
bg_color=TEAL_LIGHT, accent=TEAL):
"""A single formula card."""
col_w = PAGE_W - 2*MARGIN
content = []
content.append(Paragraph(name, FORMULA_NAME))
for fl in formula_lines:
content.append(Paragraph(fl, FORMULA_BOX))
content.append(Paragraph("Example:", EXAMPLE_LABEL))
for es in example_steps:
content.append(Paragraph(es, EXAMPLE_TEXT))
if note:
content.append(Paragraph(f"ⓘ {note}", NOTE))
data = [[content]]
t = Table(data, colWidths=[col_w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("LINECOLOR", (0,0), (-1,-1), accent),
("LINEBEFORE", (0,0), (0,-1), 3, accent),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
def two_col_cards(left_items, right_items, bg=TEAL_LIGHT, accent=TEAL):
"""Two formula cards side by side."""
col_w = (PAGE_W - 2*MARGIN - 4*mm) / 2
def make_cell(items):
content = []
for item in items:
content.append(item)
return content
data = [[make_cell(left_items), make_cell(right_items)]]
t = Table(data, colWidths=[col_w, col_w], hAlign="LEFT")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LINEBEFORE", (0,0), (0,-1), 3, accent),
("LINEBEFORE", (1,0), (1,-1), 3, accent),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
# ── Page Template with header/footer ──────────────────────────────
class DrugCalcDoc(SimpleDocTemplate):
def __init__(self, filename):
super().__init__(
filename,
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=MARGIN + 0.2*cm, bottomMargin=MARGIN,
title="Drug Calculation Pocket Guide",
author="Clinical Reference",
subject="Drug Dosage Formulas - Adults & Paediatrics"
)
self.page_num = 0
def handle_pageBegin(self):
self.page_num += 1
super().handle_pageBegin()
def afterPage(self):
c = self.canv
w, h = A4
c.saveState()
# Footer line
c.setStrokeColor(TEAL)
c.setLineWidth(0.5)
c.line(MARGIN, 1.0*cm, w - MARGIN, 1.0*cm)
# Footer text
c.setFont("Helvetica-Oblique", 7)
c.setFillColor(GREY_MID)
c.drawString(MARGIN, 0.65*cm,
"Drug Calculation Pocket Guide | For educational use only | Always verify doses with current formulary")
c.drawRightString(w - MARGIN, 0.65*cm, f"Page {self._pagenum}")
c.restoreState()
# ── Build Content ─────────────────────────────────────────────────
def build_title_block():
"""Hero banner drawn directly - returns a Table that looks like a banner."""
col_w = PAGE_W - 2*MARGIN
title_para = Paragraph("Drug Calculation<br/>Pocket Guide", TITLE_STYLE)
sub_para = Paragraph(
"Adults & Paediatrics | Quick Reference for Nurses & Clinicians",
SUBTITLE_STYLE)
note_para = Paragraph(
"Covers oral doses, IV infusions, weight-based & paediatric rules, "
"BSA, renal adjustment, and safe dose checks",
S("BannerNote", fontName="Helvetica", fontSize=8.5,
textColor=colors.HexColor("#93C5FD"), alignment=TA_CENTER))
data = [[ [title_para, Spacer(1, 4), sub_para, Spacer(1, 6), note_para] ]]
t = Table(data, colWidths=[col_w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 16),
("BOTTOMPADDING", (0,0), (-1,-1), 16),
("LEFTPADDING", (0,0), (-1,-1), 16),
("RIGHTPADDING", (0,0), (-1,-1), 16),
("ROUNDEDCORNERS", [6, 6, 6, 6]),
]))
return t
def build_units_table():
"""Metric conversion quick-ref table."""
headers = ["Unit", "Equivalent", "Unit", "Equivalent"]
rows = [
["1 microgram (mcg)", "0.001 mg", "1 teaspoon (tsp)", "5 mL"],
["1 milligram (mg)", "1,000 mcg / 0.001 g", "1 tablespoon (tbsp)", "15 mL"],
["1 gram (g)", "1,000 mg", "1 fluid ounce", "30 mL"],
["1 kilogram (kg)", "1,000 g / 2.2 lbs", "1 cup", "240 mL"],
]
table_data = [
[Paragraph(h, TABLE_HEADER) for h in headers]
] + [
[Paragraph(cell, TABLE_CELL) for cell in row] for row in rows
]
col_widths = [(PAGE_W - 2*MARGIN)/4] * 4
t = Table(table_data, colWidths=col_widths)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("BACKGROUND", (0,1), (-1,-1), GREY_LIGHT),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#D1D5DB")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
return t
def build_summary_table():
"""Quick summary table of all formulas."""
headers = ["Formula", "Used For", "Key Variables"]
rows = [
["D/H × V", "Oral & parenteral dose", "Desired, Have, Vehicle"],
["Ratio & Proportion", "Tablet/capsule dose", "Cross-multiply for X"],
["Drip rate (gtt/min)", "IV gravity infusion", "Volume, Drop factor, Time"],
["Flow rate (mL/hr)", "IV pump programming", "Volume ÷ Time"],
["mg/kg", "Weight-based dosing", "Dose × Weight (kg)"],
["mcg/kg/min", "Vasoactive IV drips", "Conc., Weight, Dose"],
["Reconstitution", "Powder vials", "Desired ÷ Reconst. conc."],
["BSA (Mosteller)", "Chemo & high-risk drugs", "Height (cm) × Weight (kg)"],
["Cockcroft-Gault", "Renal dose adjustment", "Age, Weight, Creatinine"],
["Young's Rule", "Paediatric 2-12 yrs", "Age ÷ (Age + 12) × Adult"],
["Fried's Rule", "Infants < 2 yrs", "Months ÷ 150 × Adult"],
["Clark's Rule", "Paediatric (lbs)", "Weight(lb) ÷ 150 × Adult"],
["BSA Paediatric", "Paediatric chemo doses", "Child BSA ÷ 1.7 × Adult"],
["Safe Dose Range", "Paediatric safety check", "mg/kg range × Weight"],
]
col_widths = [
(PAGE_W - 2*MARGIN) * 0.27,
(PAGE_W - 2*MARGIN) * 0.38,
(PAGE_W - 2*MARGIN) * 0.35,
]
table_data = [
[Paragraph(h, TABLE_HEADER) for h in headers]
] + [
[Paragraph(cell, TABLE_CELL) for cell in row] for row in rows
]
t = Table(table_data, colWidths=col_widths, repeatRows=1)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#D1D5DB")),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
]))
return t
def P(text, style=None):
if style is None:
style = BODY
return Paragraph(text, style)
def build_story():
story = []
SP = lambda h=4: Spacer(1, h)
HR = lambda: HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#E5E7EB"), spaceAfter=3, spaceBefore=3)
# ── Title Banner ───────────────────────────────────────────────
story.append(build_title_block())
story.append(SP(10))
# ── Unit Conversions ───────────────────────────────────────────
story.append(section_bar(" UNIT CONVERSIONS (Essential Foundation)", color=GREY_DARK))
story.append(SP(4))
story.append(build_units_table())
story.append(SP(10))
# ════════════════════════════════════════════════════════════════
# SECTION A: ADULT / GENERAL FORMULAS
# ════════════════════════════════════════════════════════════════
story.append(section_bar(" SECTION A: GENERAL / ADULT DRUG CALCULATION FORMULAS", color=TEAL))
story.append(SP(5))
# 1. D/H x V
story.append(KeepTogether([
formula_card(
"1. Basic Dose Formula (D / H × V)",
[
"Dose to give = (Desired dose ÷ Have on hand) × Vehicle",
"D = Desired (ordered) | H = Have (on hand) | V = Vehicle (mL, tablet)",
],
[
"<b>Ex 1 – Oral liquid:</b> Order: Paracetamol 500 mg | On hand: 250 mg / 5 mL",
"= (500 ÷ 250) × 5 mL = 2 × 5 = <b>10 mL</b>",
"<b>Ex 2 – Tablets:</b> Order: Digoxin 0.25 mg | On hand: 0.125 mg / tablet",
"= (0.25 ÷ 0.125) × 1 = <b>2 tablets</b>",
],
bg_color=TEAL_LIGHT, accent=TEAL
),
SP(5),
]))
# 2. Ratio & Proportion
story.append(KeepTogether([
formula_card(
"2. Ratio & Proportion Method",
[
"H : V = D : X → X = (D × V) ÷ H",
],
[
"<b>Ex:</b> Order: Erythromycin 750 mg | On hand: 250 mg capsules",
"250 : 1 = 750 : X → 250X = 750 → <b>X = 3 capsules</b>",
],
bg_color=TEAL_LIGHT, accent=TEAL
),
SP(5),
]))
# 3 & 4 side by side – IV Drip Rate & Flow Rate
left_3 = [
P("3. IV Drip Rate (gtt/min)", FORMULA_NAME),
P("gtt/min = (Volume mL × Drop factor) ÷ Time (min)", FORMULA_BOX),
P("Drop factors: Macro = 10/15/20 gtt/mL | Micro = 60 gtt/mL", NOTE),
P("Example:", EXAMPLE_LABEL),
P("1000 mL NS over 8 h, tubing 20 gtt/mL", EXAMPLE_TEXT),
P("= (1000 × 20) ÷ (8 × 60) = 20,000 ÷ 480 = <b>42 gtt/min</b>", EXAMPLE_TEXT),
]
right_4 = [
P("4. IV Flow Rate (mL/hr)", FORMULA_NAME),
P("Flow rate (mL/hr) = Total volume (mL) ÷ Time (hr)", FORMULA_BOX),
P("​", NOTE), # spacer note
P("Example:", EXAMPLE_LABEL),
P("500 mL D5W over 4 hours", EXAMPLE_TEXT),
P("= 500 ÷ 4 = <b>125 mL/hr</b>", EXAMPLE_TEXT),
]
story.append(KeepTogether([two_col_cards(left_3, right_4), SP(5)]))
# 5. Infusion Time
story.append(KeepTogether([
formula_card(
"5. Infusion Time",
["Infusion time (hr) = Total volume (mL) ÷ Flow rate (mL/hr)"],
[
"<b>Ex:</b> 1000 mL infusing at 125 mL/hr",
"= 1000 ÷ 125 = <b>8 hours</b>",
],
bg_color=TEAL_LIGHT, accent=TEAL
),
SP(5),
]))
# 6. Weight-based mg/kg
story.append(KeepTogether([
formula_card(
"6. Weight-Based Dosing (mg/kg)",
["Dose = Ordered dose (mg/kg) × Patient weight (kg)"],
[
"<b>Ex:</b> Amoxicillin 25 mg/kg | Patient: 70 kg",
"= 25 × 70 = <b>1,750 mg per dose</b>",
],
bg_color=TEAL_LIGHT, accent=TEAL
),
SP(5),
]))
# 7. Weight-based IV (mcg/kg/min)
story.append(KeepTogether([
formula_card(
"7. Weight-Based IV Infusion Rate (mcg/kg/min)",
[
"mL/hr = (Dose mcg/kg/min × Weight kg × 60) ÷ Concentration mcg/mL",
],
[
"<b>Ex:</b> Dopamine 5 mcg/kg/min | Patient: 80 kg | Bag: 400 mg in 250 mL",
"Concentration = 400,000 mcg ÷ 250 mL = 1,600 mcg/mL",
"= (5 × 80 × 60) ÷ 1,600 = 24,000 ÷ 1,600 = <b>15 mL/hr</b>",
],
note="Always double-check concentration of bag before calculating.",
bg_color=AMBER_LIGHT, accent=AMBER
),
SP(5),
]))
# 8. Reconstitution
story.append(KeepTogether([
formula_card(
"8. Reconstitution Formula",
[
"Amount to give (mL) = Desired dose ÷ Concentration after reconstitution",
"Concentration after reconstitution = Total drug (mg) ÷ Total volume (mL)",
],
[
"<b>Ex:</b> Order: Ampicillin 500 mg IV | Vial: 1 g powder + 10 mL diluent = 100 mg/mL",
"= 500 ÷ 100 = <b>5 mL</b>",
],
bg_color=TEAL_LIGHT, accent=TEAL
),
SP(5),
]))
# 9 & 10 side by side – Percent solution & Units
left_9 = [
P("9. Percent Solution", FORMULA_NAME),
P("% = (Drug in g ÷ Total volume in mL) × 100", FORMULA_BOX),
P("Example:", EXAMPLE_LABEL),
P("10 g glucose in 100 mL → <b>10% solution</b>", EXAMPLE_TEXT),
]
right_10 = [
P("10. Units-Based Dosing (Insulin / Heparin)", FORMULA_NAME),
P("Volume (mL) = Units ordered ÷ Units per mL", FORMULA_BOX),
P("Example:", EXAMPLE_LABEL),
P("Heparin 5,000 units SC | Available: 10,000 units/mL", EXAMPLE_TEXT),
P("= 5,000 ÷ 10,000 = <b>0.5 mL</b>", EXAMPLE_TEXT),
]
story.append(KeepTogether([two_col_cards(left_9, right_10), SP(5)]))
# 11. BSA Mosteller
story.append(KeepTogether([
formula_card(
"11. Body Surface Area – Mosteller Formula",
[
"BSA (m²) = √ [ Height (cm) × Weight (kg) ÷ 3,600 ]",
],
[
"<b>Ex:</b> Patient: 170 cm, 70 kg",
"= √ (170 × 70 ÷ 3,600) = √ 3.306 = <b>1.82 m²</b>",
],
note="Valid for both adults and children. Use on any calculator with a √ function.",
bg_color=PURPLE_LIGHT, accent=PURPLE
),
SP(5),
]))
# 12. BSA-based dose
story.append(KeepTogether([
formula_card(
"12. BSA-Based Dose (Chemotherapy / High-Risk Drugs)",
["Dose = BSA (m²) × Prescribed dose per m²"],
[
"<b>Ex:</b> Chemo drug 50 mg/m² | BSA: 1.82 m²",
"= 1.82 × 50 = <b>91 mg</b>",
],
bg_color=PURPLE_LIGHT, accent=PURPLE
),
SP(5),
]))
# 13. Cockcroft-Gault
story.append(KeepTogether([
formula_card(
"13. Creatinine Clearance – Cockcroft-Gault (Renal Dose Adjustment)",
[
"CrCl (mL/min) = [ (140 − Age) × Weight (kg) ] ÷ [ 72 × Serum Creatinine (mg/dL) ]",
"Multiply result by <b>0.85 for females</b>",
],
[
"<b>Ex:</b> 65-year-old male, 70 kg, Cr 1.2 mg/dL",
"= (140 − 65) × 70 ÷ (72 × 1.2) = 75 × 70 ÷ 86.4 = 5,250 ÷ 86.4 = <b>60.8 mL/min</b>",
],
note="Use actual body weight unless patient is obese — then use ideal body weight.",
bg_color=AMBER_LIGHT, accent=AMBER
),
SP(8),
]))
# ════════════════════════════════════════════════════════════════
# SECTION B: PAEDIATRIC
# ════════════════════════════════════════════════════════════════
story.append(section_bar(" SECTION B: PAEDIATRIC DRUG CALCULATION FORMULAS", color=GREEN))
story.append(SP(4))
story.append(P(
"▶ Weight-based dosing (mg/kg) is the gold standard for paediatrics. "
"Age-based rules (Young's, Fried's, Clark's) are <b>estimates only</b> and should be used "
"only when the mg/kg dose is not known.",
S("PaedNote", fontName="Helvetica-Oblique", fontSize=8.5,
textColor=GREEN, leftIndent=4, spaceAfter=6, spaceBefore=2)
))
# 14. mg/kg paediatric
story.append(KeepTogether([
formula_card(
"14. Weight-Based Dose (mg/kg) — Preferred Paediatric Method",
["Child's dose = Ordered dose (mg/kg) × Child's weight (kg)"],
[
"<b>Ex:</b> Order: Paracetamol 15 mg/kg | Child: 20 kg",
"= 15 × 20 = <b>300 mg</b>",
],
note="Always verify the calculated dose against the published safe dose range.",
bg_color=GREEN_LIGHT, accent=GREEN
),
SP(5),
]))
# 15. Young's Rule
story.append(KeepTogether([
formula_card(
"15. Young's Rule (Children 2 – 12 years)",
["Child's dose = [ Age (years) ÷ (Age + 12) ] × Adult dose"],
[
"<b>Ex:</b> 10-year-old child | Adult Paracetamol dose: 500 mg",
"= [ 10 ÷ (10 + 12) ] × 500 = (10 ÷ 22) × 500 = 0.455 × 500 = <b>227.5 mg</b>",
],
bg_color=GREEN_LIGHT, accent=GREEN
),
SP(5),
]))
# 16 & 17 side by side – Fried's & Clark's
left_16 = [
P("16. Fried's Rule (Infants < 2 years)", FORMULA_NAME),
P("Child's dose = (Age in months ÷ 150) × Adult dose", FORMULA_BOX),
P("Example:", EXAMPLE_LABEL),
P("2-year-old (24 months) | Adult dose: 500 mg", EXAMPLE_TEXT),
P("= (24 ÷ 150) × 500 = 0.16 × 500 = <b>80 mg</b>", EXAMPLE_TEXT),
]
right_17 = [
P("17. Clark's Rule (Weight in POUNDS)", FORMULA_NAME),
P("Child's dose = (Weight lb ÷ 150) × Adult dose", FORMULA_BOX),
P("⚠ Use lbs ONLY — never kg for this rule.", NOTE),
P("Example:", EXAMPLE_LABEL),
P("Child: 60 lbs | Adult Amoxicillin dose: 500 mg", EXAMPLE_TEXT),
P("= (60 ÷ 150) × 500 = 0.4 × 500 = <b>200 mg</b>", EXAMPLE_TEXT),
]
story.append(KeepTogether([two_col_cards(left_16, right_17, bg=GREEN_LIGHT, accent=GREEN), SP(5)]))
# 18. BSA Paediatric
story.append(KeepTogether([
formula_card(
"18. BSA-Based Paediatric Dose (West Nomogram / Mosteller)",
[
"Child's dose = (Child's BSA m² ÷ 1.7 m²) × Adult dose",
"BSA (m²) = √ [ Height (cm) × Weight (kg) ÷ 3,600 ] ← Mosteller",
"Average adult BSA = 1.7 m²",
],
[
"<b>Ex:</b> Child: 100 cm, 16.4 kg → BSA = √(100 × 16.4 ÷ 3,600) = √0.456 = <b>0.675 m²</b>",
"Adult dose: 500 mg → Child's dose = (0.675 ÷ 1.7) × 500 = 0.397 × 500 = <b>198.5 mg</b>",
],
note="West Nomogram: plot height (left) and weight (right) — read BSA from SA column.",
bg_color=GREEN_LIGHT, accent=GREEN
),
SP(5),
]))
# 19. Paediatric IV drip
story.append(KeepTogether([
formula_card(
"19. Paediatric IV Drip Rate",
[
"gtt/min = (Volume mL × Drop factor) ÷ Time (min)",
"Paediatric sets typically use micro-drip: 60 gtt/mL",
],
[
"<b>Ex:</b> 100 mL over 4 hours, micro-drip (60 gtt/mL)",
"= (100 × 60) ÷ (4 × 60) = 6,000 ÷ 240 = <b>25 gtt/min</b>",
],
bg_color=GREEN_LIGHT, accent=GREEN
),
SP(5),
]))
# 20. Safe Dose Range
story.append(KeepTogether([
formula_card(
"20. Safe Dose Range Check (Paediatric Safety — ALWAYS Perform)",
[
"Low safe dose = Low mg/kg × Child's weight (kg)",
"High safe dose = High mg/kg × Child's weight (kg)",
"Prescribed dose MUST fall within this range before administration",
],
[
"<b>Ex:</b> Safe range: 10–30 mg/kg | Child: 20 kg",
"Low = 10 × 20 = 200 mg | High = 30 × 20 = 600 mg",
"Prescribed dose must be between <b>200 mg and 600 mg</b> ✓",
],
note="If the prescribed dose is outside the safe range, clarify with the prescriber before administering.",
bg_color=RED_LIGHT, accent=RED
),
SP(8),
]))
# ── Quick Summary Table ────────────────────────────────────────
story.append(section_bar(" QUICK SUMMARY: ALL FORMULAS AT A GLANCE", color=NAVY))
story.append(SP(5))
story.append(build_summary_table())
story.append(SP(8))
# ── Clinical Reminders ─────────────────────────────────────────
story.append(section_bar(" KEY CLINICAL REMINDERS", color=RED))
story.append(SP(4))
reminders = [
("⚠ Units first", "Always confirm mg vs mcg vs g before calculating. A ×1000 error is fatal."),
("⚠ Double-check", "High-alert drugs (insulin, heparin, opioids, chemo) must have a second nurse verify independently."),
("▸ Paediatric", "mg/kg is the gold standard. Age-based rules (Young's, Fried's, Clark's) are estimates only."),
("▸ Renal patients","Use Cockcroft-Gault CrCl to adjust renally-cleared drugs. Elderly patients require extra caution."),
("▸ Weight", "1 kg = 2.2 lbs. Convert lbs → kg by dividing by 2.2. Never mix units."),
("▸ IV bags", "Always recalculate concentration when a different bag size is dispensed."),
("▸ BSA drugs", "Recalculate BSA if patient's weight changes significantly during treatment."),
]
for icon_label, text in reminders:
data = [[
Paragraph(icon_label, S("RL", fontName="Helvetica-Bold", fontSize=8.5, textColor=RED)),
Paragraph(text, S("RT", fontName="Helvetica", fontSize=8.5, textColor=GREY_DARK)),
]]
t = Table(data, colWidths=[3.5*cm, PAGE_W - 2*MARGIN - 3.5*cm])
t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (0,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(t)
story.append(SP(6))
story.append(HR())
story.append(P(
"This pocket guide is for educational and clinical reference only. "
"Always verify drug doses against current national formularies, "
"local protocols, and prescriber orders. Clinical judgment is essential.",
S("Disc", fontName="Helvetica-Oblique", fontSize=7.5,
textColor=GREY_MID, alignment=TA_CENTER, spaceAfter=4)
))
return story
# ── Generate PDF ───────────────────────────────────────────────────
output_path = "/home/daytona/workspace/drug-calc-guide/Drug_Calculation_Pocket_Guide.pdf"
doc = DrugCalcDoc(output_path)
story = build_story()
doc.build(story)
print(f"PDF generated: {output_path}")
cd /home/daytona/workspace/drug-calc-guide && python generate_guide.py 2>&1
~/drug-calc-guide/generate_guide.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/drug-calc-guide/generate_guide.py'
cd /home/daytona/workspace/drug-calc-guide && python generate_guide.py 2>&1
ls -lh /home/daytona/workspace/drug-calc-guide/Drug_Calculation_Pocket_Guide.pdf
Drug Calculation Pocket Guide
PDF Document · PDF