Be my teacher and teach me the drug calculation from complete zero to hero, I am weak in maths, i don't the percentage like 1/8 like that at, and in stores they are telling the drug is 15 percent offer, 50 percent offer, even i don't know how much cost it is in offer, so help me to learn all these calculations, along with drug calculation, Start
Top number β called NUMERATOR (how many parts you have)
βββββββββββββ
Bottom number β called DENOMINATOR (total parts in the whole)
1 = numerator (you ate 1 slice) 8 = denominator (total 8 slices)
| Fraction | Say it as |
|---|---|
| 1/2 | "one half" |
| 1/4 | "one quarter" |
| 1/8 | "one eighth" |
| 3/4 | "three quarters" |
| 2/5 | "two fifths" |
A fraction = the top number DIVIDED by the bottom number
1/8 = 1 Γ· 8 = 0.125
1/4 = 1 Γ· 4 = 0.25
1/2 = 1 Γ· 2 = 0.5
3/4 = 3 Γ· 4 = 0.75
1/2 Γ 3/4 = (1Γ3) / (2Γ4) = 3/8
1/2 Γ· 1/4 = 1/2 Γ 4/1 = 4/2 = 2
% of something = (Percentage Γ· 100) Γ Total amount
% of something = (Percentage Γ Total) Γ· 100
= (15 Γ 200) Γ· 100
= 3000 Γ· 100
= βΉ30
βΉ200 - βΉ30 = βΉ170
50% of 500 = (50 Γ 500) Γ· 100 = 25000 Γ· 100 = βΉ250
50% off always means you pay HALF the price. Easy!
30% of 840 = (30 Γ 840) Γ· 100 = 25200 Γ· 100 = βΉ252
Final price = 840 - 252 = βΉ588
| Offer | Meaning | You Pay |
|---|---|---|
| 10% off | Pay 90% | Price Γ 0.90 |
| 20% off | Pay 80% | Price Γ 0.80 |
| 25% off | Pay 75% | Price Γ 0.75 |
| 50% off | Pay 50% | Price Γ 0.50 |
| Unit | Meaning | Relation |
|---|---|---|
| kg | kilogram | 1 kg = 1000 g |
| g | gram | 1 g = 1000 mg |
| mg | milligram | 1 mg = 1000 mcg |
| mcg (Β΅g) | microgram | smallest common unit |
1 kg β 1000 g β 1,000,000 mg β 1,000,000,000 mcg
| Unit | Meaning |
|---|---|
| L | litre |
| mL | millilitre (1 L = 1000 mL) |
Every 1 mL of the liquid contains 10 mg of drug.
What you WANT (dose ordered)
Volume to give = ββββββββββββββββββββββββββββββ Γ Volume it comes IN
What you HAVE (stock concentration)
W
Volume = β Γ V
H
Want 1000 mg
ββββ Γ 1 = ββββββββ Γ 1 = 2 tablets
Have 500 mg
500 mg
ββββββββ Γ 1 = 2 tablets
250 mg
Want 8 mg
ββββ Γ V = ββββββ Γ 1 mL = 0.8 mL
Have 10 mg
120 mg
ββββββββ Γ 2 mL = (120 Γ 2) Γ· 80 = 240 Γ· 80 = 3 mL
80 mg
Total dose = Dose (mg/kg) Γ Patient's weight (kg)
Total dose = 25 Γ 20 = 500 mg
Total dose = 15 Γ 12 = 180 mg
50 Γ 8 = 400 mg
(Want Γ· Have) Γ Volume = (400 Γ· 125) Γ 5 = 3.2 Γ 5 = 16 mL
| Term | Meaning |
|---|---|
| mL/hr | millilitres per hour |
| drops/min | drops per minute |
| Drop factor | how many drops = 1 mL (printed on the IV set package) |
| Common drop factors | 20 drops/mL (adult set), 60 drops/mL (micro-drip/paediatric) |
Total volume (mL)
Rate (mL/hr) = ββββββββββββββββββββββ
Time (hours)
Rate = 1000 Γ· 8 = 125 mL/hr
Total volume (mL) Γ Drop factor
Drops/min = βββββββββββββββββββββββββββββββββββββββ
Time (minutes)
Time in minutes = 4 Γ 60 = 240 minutes
Drops/min = (500 Γ 20) Γ· 240 = 10000 Γ· 240 = 41.6 β 42 drops/min
5 mcg/kg/min Γ 60 kg = 300 mcg/min
300 Γ· 1000 = 0.3 mg/min
200 mg Γ· 250 mL = 0.8 mg/mL
0.3 mg/min Γ· 0.8 mg/mL = 0.375 mL/min
0.375 Γ 60 = 22.5 mL/hr
If 100 mL = 5 g
Then 500 mL = 5 Γ 5 = 25 g
UNIT 1: Fractions β You start here
UNIT 2: Percentages + Shopping
UNIT 3: Medical units (g, mg, mL)
UNIT 4: Tablet & injection formula β Most important!
UNIT 5: Weight-based dosing (mg/kg)
UNIT 6: IV drip rates
UNIT 7: Percentage concentrations
UNIT 8: Practice problems β Test yourself here
| Rule | What it means |
|---|---|
| Always match units | mg with mg, mL with mL - never mix! |
| Convert first, calculate second | If units don't match, convert BEFORE using the formula |
| Double check | Always re-read what the doctor ordered vs what you have |
| Round safely | For injections, round to 1 decimal place (e.g., 2.4 mL not 2.38 mL) |
| % = per 100 | 15% = 15/100. Always. |
Create a PDF quick-reference guide for drug calculations
mkdir -p /tmp/workspace/drug-calc-guide && ls /tmp/workspace/drug-calc-guide/
~/drug-calc-guide/build_guide.py
from reportlab.platypus import (
SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer,
HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import PageBreak
from reportlab.pdfbase import pdfmetrics
# ββ Colour palette ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NAVY = colors.HexColor("#1A3557")
TEAL = colors.HexColor("#2196A8")
MINT = colors.HexColor("#E8F6F7")
AMBER = colors.HexColor("#F59E0B")
AMBER_LT = colors.HexColor("#FEF3C7")
RED = colors.HexColor("#DC2626")
RED_LT = colors.HexColor("#FEE2E2")
GREEN = colors.HexColor("#16A34A")
GREEN_LT = colors.HexColor("#DCFCE7")
GREY_LT = colors.HexColor("#F3F4F6")
GREY_MID = colors.HexColor("#9CA3AF")
WHITE = colors.white
BLACK = colors.HexColor("#111827")
# ββ Document setup βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
OUTPUT = "/tmp/workspace/drug-calc-guide/Drug_Calculation_Quick_Reference.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.5*cm, rightMargin=1.5*cm,
topMargin=2*cm, bottomMargin=2*cm,
title="Drug Calculation Quick Reference Guide",
author="Orris Medical Education",
subject="Drug Calculations β Nursing & Pharmacy Reference",
)
W, H = A4
CONTENT_W = W - 3*cm # usable width
# ββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
base = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
sTitle = S("sTitle",
fontName="Helvetica-Bold", fontSize=22, textColor=WHITE,
alignment=TA_CENTER, leading=28)
sSubtitle = S("sSubtitle",
fontName="Helvetica", fontSize=11, textColor=WHITE,
alignment=TA_CENTER, leading=16)
sSectionHeader = S("sSectionHeader",
fontName="Helvetica-Bold", fontSize=13, textColor=WHITE,
alignment=TA_LEFT, leading=18,
leftPadding=8, rightPadding=8, topPadding=5, bottomPadding=5)
sBodyBold = S("sBodyBold",
fontName="Helvetica-Bold", fontSize=9, textColor=BLACK, leading=13)
sBody = S("sBody",
fontName="Helvetica", fontSize=9, textColor=BLACK, leading=13)
sBodySmall = S("sBodySmall",
fontName="Helvetica", fontSize=8, textColor=BLACK, leading=12)
sFormulaLabel = S("sFormulaLabel",
fontName="Helvetica-Bold", fontSize=9, textColor=NAVY, leading=13,
alignment=TA_CENTER)
sFormula = S("sFormula",
fontName="Helvetica-Bold", fontSize=11, textColor=NAVY, leading=16,
alignment=TA_CENTER)
sNote = S("sNote",
fontName="Helvetica-Oblique", fontSize=8, textColor=GREY_MID, leading=12)
sFooter = S("sFooter",
fontName="Helvetica", fontSize=7.5, textColor=GREY_MID, alignment=TA_CENTER)
sTableHead = S("sTableHead",
fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE, leading=12,
alignment=TA_CENTER)
sTableCell = S("sTableCell",
fontName="Helvetica", fontSize=8.5, textColor=BLACK, leading=12,
alignment=TA_CENTER)
sTableCellL = S("sTableCellL",
fontName="Helvetica", fontSize=8.5, textColor=BLACK, leading=12,
alignment=TA_LEFT)
sTableCellBold = S("sTableCellBold",
fontName="Helvetica-Bold", fontSize=8.5, textColor=NAVY, leading=12,
alignment=TA_LEFT)
sWarning = S("sWarning",
fontName="Helvetica-Bold", fontSize=8.5, textColor=RED, leading=13)
sGolden = S("sGolden",
fontName="Helvetica-Bold", fontSize=9, textColor=colors.HexColor("#92400E"),
leading=13)
# ββ Helper: coloured section header βββββββββββββββββββββββββββββββββββββββββββ
def section_header(text, bg=NAVY):
tbl = Table([[Paragraph(text, sSectionHeader)]], colWidths=[CONTENT_W])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return tbl
# ββ Helper: coloured box βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def coloured_box(paragraphs, bg=MINT, radius=4):
rows = [[p] for p in paragraphs]
t = Table(rows, colWidths=[CONTENT_W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return t
# ββ Helper: two-column layout βββββββββββββββββββββββββββββββββββββββββββββββββ
def two_col(left_items, right_items, lw=None, rw=None):
lw = lw or CONTENT_W * 0.49
rw = rw or CONTENT_W * 0.49
gap = CONTENT_W - lw - rw
def wrap(items):
rows = []
for item in items:
if isinstance(item, str):
rows.append([Paragraph(item, sBody)])
else:
rows.append([item])
t = Table(rows, colWidths=[lw])
t.setStyle(TableStyle([
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING",(0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
return t
outer = Table([[wrap(left_items), Spacer(gap, 1), wrap(right_items)]],
colWidths=[lw, gap, rw])
outer.setStyle(TableStyle([
("VALIGN", (0,0),(-1,-1), "TOP"),
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING",(0,0),(-1,-1), 0),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
return outer
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CONTENT BUILD
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story = []
# ββ COVER BANNER ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
banner_data = [[
Paragraph("π Drug Calculation", sTitle),
Paragraph("Quick Reference Guide", sTitle),
Paragraph("Fractions β’ Percentages β’ Tablets β’ Injections β’ IV Drips β’ Weight-Based Dosing", sSubtitle),
]]
# flatten into rows
banner = Table(
[
[Paragraph("π Drug Calculation Quick Reference Guide", sTitle)],
[Paragraph("Fractions β’ Percentages β’ Tablets β’ Injections β’ IV Drips β’ Weight-Based Dosing", sSubtitle)],
[Paragraph("For Nurses, Pharmacists & Healthcare Students", sNote)],
],
colWidths=[CONTENT_W]
)
banner.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), NAVY),
("TOPPADDING", (0,0),(-1,-1), 10),
("BOTTOMPADDING",(0,0),(-1,-1), 10),
("LEFTPADDING", (0,0),(-1,-1), 10),
("ROUNDEDCORNERS",[6,6,6,6]),
]))
story.append(banner)
story.append(Spacer(1, 8*mm))
# ββ SECTION 1: FRACTIONS ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(KeepTogether([
section_header("SECTION 1 β Fractions"),
Spacer(1, 3*mm),
]))
frac_box = coloured_box([
Paragraph("<b>What is a fraction?</b> A fraction shows a PART of a whole thing.", sBody),
Paragraph("Written as: <b>Numerator (top)</b> Γ· <b>Denominator (bottom)</b>", sBody),
Paragraph("Example: 1/8 means 1 out of 8 equal parts β 1 Γ· 8 = <b>0.125</b>", sBody),
], bg=MINT)
story.append(frac_box)
story.append(Spacer(1, 3*mm))
frac_table_data = [
[Paragraph("Fraction", sTableHead), Paragraph("Say it as", sTableHead),
Paragraph("Decimal value", sTableHead), Paragraph("Quick meaning", sTableHead)],
["1/2", "One half", "0.5", "Half of something"],
["1/4", "One quarter", "0.25", "Quarter of something"],
["1/8", "One eighth", "0.125", "An eighth of something"],
["3/4", "Three quarters","0.75", "Three parts out of four"],
["2/5", "Two fifths", "0.4", "Two parts out of five"],
["1/3", "One third", "0.333", "One part out of three"],
]
ft = Table(frac_table_data, colWidths=[CONTENT_W*0.13, CONTENT_W*0.22, CONTENT_W*0.2, CONTENT_W*0.45])
ft.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), TEAL),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, GREY_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
]))
story.append(ft)
story.append(Spacer(1, 6*mm))
# ββ SECTION 2: PERCENTAGES ββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(KeepTogether([
section_header("SECTION 2 β Percentages"),
Spacer(1, 3*mm),
]))
pct_box = coloured_box([
Paragraph("<b>Per cent = Per hundred.</b> So 15% means 15 out of every 100.", sBody),
Paragraph("<b>Golden rule:</b> % of an amount = (Percentage Γ Amount) Γ· 100", sBodyBold),
Paragraph("<b>Shortcut decimal:</b> Multiply amount by the decimal form of the %", sBody),
], bg=AMBER_LT)
story.append(pct_box)
story.append(Spacer(1, 3*mm))
pct_data = [
[Paragraph("Offer", sTableHead), Paragraph("Formula", sTableHead),
Paragraph("Example (βΉ500 item)", sTableHead), Paragraph("You Pay", sTableHead)],
["10% off", "Price Γ 0.90", "500 Γ 0.90", "βΉ450"],
["15% off", "Price Γ 0.85", "500 Γ 0.85", "βΉ425"],
["20% off", "Price Γ 0.80", "500 Γ 0.80", "βΉ400"],
["25% off", "Price Γ 0.75", "500 Γ 0.75", "βΉ375"],
["30% off", "Price Γ 0.70", "500 Γ 0.70", "βΉ350"],
["50% off", "Price Γ 0.50", "500 Γ 0.50", "βΉ250"],
]
pt = Table(pct_data, colWidths=[CONTENT_W*0.15, CONTENT_W*0.25, CONTENT_W*0.3, CONTENT_W*0.3])
pt.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), AMBER),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, AMBER_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("FONTNAME", (0,-1),(-1,-1),"Helvetica"),
]))
story.append(pt)
story.append(Spacer(1, 6*mm))
# ββ SECTION 3: UNITS OF MEASUREMENT ββββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 3 β Units of Measurement"))
story.append(Spacer(1, 3*mm))
left_units = [
coloured_box([
Paragraph("<b>WEIGHT UNITS</b>", sBodyBold),
Paragraph("kg β g β mg β mcg", sBody),
Paragraph("1 kg = 1,000 g", sBodySmall),
Paragraph("1 g = 1,000 mg", sBodySmall),
Paragraph("1 mg = 1,000 mcg", sBodySmall),
Paragraph("<b>Convert DOWN (biggerβsmaller):</b> Γ 1000", sBodyBold),
Paragraph("<b>Convert UP (smallerβbigger):</b> Γ· 1000", sBodyBold),
], bg=GREEN_LT),
]
right_units = [
coloured_box([
Paragraph("<b>VOLUME UNITS</b>", sBodyBold),
Paragraph("1 L = 1,000 mL", sBodySmall),
Spacer(1, 5),
Paragraph("<b>CONCENTRATION (mg/mL)</b>", sBodyBold),
Paragraph("= milligrams PER millilitre", sBodySmall),
Paragraph("If drug is 10 mg/mL:", sBodySmall),
Paragraph(" 2 mL contains 20 mg", sBodySmall),
Paragraph(" 5 mL contains 50 mg", sBodySmall),
], bg=GREEN_LT),
]
story.append(two_col(left_units, right_units))
story.append(Spacer(1, 3*mm))
conv_data = [
[Paragraph("Convert FROM", sTableHead), Paragraph("Convert TO", sTableHead),
Paragraph("Operation", sTableHead), Paragraph("Example", sTableHead)],
["g", "mg", "Γ 1000", "2 g β 2000 mg"],
["mg", "mcg", "Γ 1000", "0.5 mg β 500 mcg"],
["mg", "g", "Γ· 1000", "500 mg β 0.5 g"],
["mcg", "mg", "Γ· 1000", "250 mcg β 0.25 mg"],
["L", "mL", "Γ 1000", "1.5 L β 1500 mL"],
["mL", "L", "Γ· 1000", "750 mL β 0.75 L"],
]
ct = Table(conv_data, colWidths=[CONTENT_W*0.18, CONTENT_W*0.18, CONTENT_W*0.22, CONTENT_W*0.42])
ct.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), colors.HexColor("#16A34A")),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1),8.5),
("ALIGN", (0,0),(-1,-1),"CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, GREEN_LT]),
("GRID", (0,0),(-1,-1),0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
]))
story.append(ct)
story.append(Spacer(1, 6*mm))
# ββ SECTION 4: MASTER FORMULA βββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 4 β The Master Drug Formula (Tablets & Injections)"))
story.append(Spacer(1, 3*mm))
formula_box = Table(
[
[Paragraph("THE FORMULA", sFormulaLabel)],
[Paragraph("Volume / Tablets to Give = (Want Γ· Have) Γ Volume it comes in", sFormula)],
[Paragraph("W = What you Want (dose ordered by doctor)", sBody)],
[Paragraph("H = What you Have (strength on the drug label)", sBody)],
[Paragraph("V = Volume the drug comes in (usually 1 tablet or 1 mL)", sBody)],
],
colWidths=[CONTENT_W]
)
formula_box.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), MINT),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("LEFTPADDING", (0,0),(-1,-1), 14),
("RIGHTPADDING", (0,0),(-1,-1), 14),
("LINEABOVE", (0,0),(-1,0), 2, TEAL),
("LINEBELOW", (0,-1),(-1,-1),2, TEAL),
]))
story.append(formula_box)
story.append(Spacer(1, 3*mm))
ex_data = [
[Paragraph("Example", sTableHead), Paragraph("Ordered", sTableHead),
Paragraph("Available", sTableHead), Paragraph("Calculation", sTableHead),
Paragraph("Answer", sTableHead)],
["Tablet", "Paracetamol 1000 mg", "500 mg tablets", "(1000Γ·500) Γ 1", "2 tablets"],
["Tablet", "Metformin 500 mg", "250 mg tablets", "(500Γ·250) Γ 1", "2 tablets"],
["Injection", "Morphine 8 mg", "10 mg in 1 mL", "(8Γ·10) Γ 1 mL", "0.8 mL"],
["Injection", "Gentamicin 120 mg", "80 mg in 2 mL", "(120Γ·80) Γ 2 mL", "3 mL"],
["Injection", "Furosemide 60 mg", "20 mg in 2 mL", "(60Γ·20) Γ 2 mL", "6 mL"],
["Syrup", "Amoxicillin 375 mg", "250 mg in 5 mL", "(375Γ·250) Γ 5 mL", "7.5 mL"],
]
et = Table(ex_data, colWidths=[CONTENT_W*0.11,CONTENT_W*0.22,CONTENT_W*0.22,CONTENT_W*0.24,CONTENT_W*0.21])
et.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), TEAL),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, MINT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("FONTNAME", (-1,1),(-1,-1),"Helvetica-Bold"),
("TEXTCOLOR", (-1,1),(-1,-1), NAVY),
]))
story.append(et)
story.append(Spacer(1, 6*mm))
# ββ SECTION 5: WEIGHT-BASED DOSING ββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 5 β Weight-Based Dosing (mg/kg)"))
story.append(Spacer(1, 3*mm))
wb_formula = coloured_box([
Paragraph("<b>Step 1:</b> Total dose (mg) = Dose per kg Γ Patient weight (kg)", sBodyBold),
Paragraph("<b>Step 2:</b> Volume = (Total dose Γ· Have) Γ Volume it comes in", sBodyBold),
], bg=AMBER_LT)
story.append(wb_formula)
story.append(Spacer(1, 3*mm))
wb_data = [
[Paragraph("Drug", sTableHead), Paragraph("Ordered", sTableHead),
Paragraph("Weight", sTableHead), Paragraph("Step 1: Total Dose", sTableHead),
Paragraph("Available", sTableHead), Paragraph("Step 2: Volume", sTableHead)],
["Paracetamol", "15 mg/kg", "12 kg", "15Γ12 = 180 mg", "120 mg/5 mL", "(180Γ·120)Γ5 = 7.5 mL"],
["Amoxicillin", "25 mg/kg", "20 kg", "25Γ20 = 500 mg", "250 mg/5 mL", "(500Γ·250)Γ5 = 10 mL"],
["Ampicillin", "50 mg/kg", "8 kg", "50Γ8 = 400 mg", "125 mg/5 mL", "(400Γ·125)Γ5 = 16 mL"],
["Gentamicin", "7 mg/kg", "60 kg", "7Γ60 = 420 mg", "80 mg/2 mL", "(420Γ·80)Γ2 = 10.5 mL"],
]
wt = Table(wb_data, colWidths=[
CONTENT_W*0.14, CONTENT_W*0.13, CONTENT_W*0.1,
CONTENT_W*0.2, CONTENT_W*0.17, CONTENT_W*0.26
])
wt.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), AMBER),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, AMBER_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("FONTNAME", (-1,1),(-1,-1),"Helvetica-Bold"),
("TEXTCOLOR", (-1,1),(-1,-1), colors.HexColor("#92400E")),
]))
story.append(wt)
story.append(Spacer(1, 6*mm))
# ββ SECTION 6: IV DRIP RATES ββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 6 β IV Drip Rate Calculations"))
story.append(Spacer(1, 3*mm))
iv_left = [
coloured_box([
Paragraph("<b>mL/hr Formula</b>", sBodyBold),
Paragraph("Rate (mL/hr) = Total volume (mL) Γ· Time (hrs)", sBody),
Spacer(1, 3),
Paragraph("<b>Example:</b> 1000 mL over 8 hrs", sBody),
Paragraph("= 1000 Γ· 8 = <b>125 mL/hr</b>", sBodyBold),
], bg=colors.HexColor("#EDE9FE")),
]
iv_right = [
coloured_box([
Paragraph("<b>Drops/min Formula</b>", sBodyBold),
Paragraph("Drops/min = (Vol Γ Drop factor) Γ· Time (min)", sBody),
Spacer(1, 3),
Paragraph("<b>Drop factors:</b> 20 drops/mL (adult) | 60 drops/mL (paediatric)", sBodySmall),
Paragraph("<b>Example:</b> 500 mL, 4 hrs, df=20", sBody),
Paragraph("= (500Γ20)Γ·240 = <b>42 drops/min</b>", sBodyBold),
], bg=colors.HexColor("#EDE9FE")),
]
story.append(two_col(iv_left, iv_right))
story.append(Spacer(1, 3*mm))
iv_data = [
[Paragraph("Volume", sTableHead), Paragraph("Time", sTableHead),
Paragraph("Rate (mL/hr)", sTableHead), Paragraph("Drop Factor", sTableHead),
Paragraph("Drops/min", sTableHead)],
["500 mL", "4 hours", "125 mL/hr", "20", "42 drops/min"],
["1000 mL", "6 hours", "167 mL/hr", "20", "56 drops/min"],
["1000 mL", "8 hours", "125 mL/hr", "20", "42 drops/min"],
["250 mL", "2 hours", "125 mL/hr", "60", "125 drops/min"],
["500 mL", "12 hours", "42 mL/hr", "20", "14 drops/min"],
]
ivt = Table(iv_data, colWidths=[CONTENT_W*0.16,CONTENT_W*0.16,CONTENT_W*0.22,CONTENT_W*0.2,CONTENT_W*0.26])
ivt.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), colors.HexColor("#7C3AED")),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, colors.HexColor("#EDE9FE")]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("FONTNAME", (-1,1),(-1,-1),"Helvetica-Bold"),
("TEXTCOLOR", (-1,1),(-1,-1), colors.HexColor("#5B21B6")),
]))
story.append(ivt)
story.append(Spacer(1, 6*mm))
# ββ SECTION 7: PERCENTAGE CONCENTRATIONS βββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 7 β Percentage Concentrations in Drug Solutions"))
story.append(Spacer(1, 3*mm))
conc_box = coloured_box([
Paragraph("<b>%w/v</b> = grams of drug per 100 mL of solution", sBodyBold),
Paragraph("So 5% means 5 g of drug in every 100 mL", sBody),
Paragraph("<b>Formula:</b> Amount of drug (g) = (% Γ Volume in mL) Γ· 100", sBodyBold),
], bg=RED_LT)
story.append(conc_box)
story.append(Spacer(1, 3*mm))
conc_data = [
[Paragraph("Solution", sTableHead), Paragraph("Concentration", sTableHead),
Paragraph("Meaning", sTableHead), Paragraph("Drug in 500 mL", sTableHead)],
["Normal Saline", "0.9% NaCl", "0.9 g NaCl per 100 mL", "4.5 g NaCl"],
["5% Dextrose", "5% Glucose", "5 g glucose per 100 mL", "25 g glucose"],
["HβOβ antiseptic", "3% HβOβ", "3 g HβOβ per 100 mL", "15 g HβOβ"],
["Dextrose saline", "4% Glucose +\n0.18% NaCl", "4g + 0.18g per 100 mL","20g + 0.9g"],
]
cnct = Table(conc_data, colWidths=[CONTENT_W*0.22,CONTENT_W*0.2,CONTENT_W*0.3,CONTENT_W*0.28])
cnct.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RED),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(-1,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, RED_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
]))
story.append(cnct)
story.append(Spacer(1, 6*mm))
# ββ SECTION 8: GOLDEN RULES βββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 8 β Golden Rules & Safety Tips", bg=colors.HexColor("#92400E")))
story.append(Spacer(1, 3*mm))
rules_data = [
["β
", "Always check units FIRST", "mg with mg, mL with mL. Never mix different units in the formula."],
["β
", "Convert BEFORE you calculate", "If units don't match, convert them first, THEN use the formula."],
["β
", "Double-check your answer", "Does the answer make sense? More than 3 tablets = check again."],
["β
", "Round safely", "Round injections to 1 decimal place (e.g., 2.4 mL, not 2.38 mL)."],
["β
", "Re-read the order", "Confirm dose, route, frequency, and patient name before giving."],
["β οΈ", "Never guess a dose", "If unsure, ask a senior. Never estimate or assume."],
["β οΈ", "High-alert drugs", "Insulin, heparin, morphine, digoxin β always double-check with a colleague."],
["β οΈ", "Check expiry and label", "Verify drug name, strength, and expiry date before preparation."],
]
rt = Table(rules_data, colWidths=[CONTENT_W*0.06, CONTENT_W*0.28, CONTENT_W*0.66])
rt.setStyle(TableStyle([
("FONTSIZE", (0,0),(-1,-1), 8.5),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("FONTNAME", (1,0),(1,-1), "Helvetica-Bold"),
("TEXTCOLOR", (1,0),(1,4), GREEN),
("TEXTCOLOR", (1,5),(1,-1), RED),
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, GREY_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("LEFTPADDING", (0,0),(0,-1), 8),
("LEFTPADDING", (1,0),(-1,-1), 8),
]))
story.append(rt)
story.append(Spacer(1, 6*mm))
# ββ SECTION 9: QUICK PRACTICE PROBLEMS ββββββββββββββββββββββββββββββββββββββββ
story.append(section_header("SECTION 9 β Quick Practice Problems"))
story.append(Spacer(1, 3*mm))
qp_data = [
[Paragraph("Q#", sTableHead), Paragraph("Question", sTableHead),
Paragraph("Answer", sTableHead)],
["Q1", "Aspirin 300 mg ordered. Available: 75 mg tablets. How many?", "4 tablets"],
["Q2", "Codeine 60 mg ordered. Available: 30 mg/mL. How many mL?", "2 mL"],
["Q3", "Child 10 kg. Paracetamol 15 mg/kg. Total dose?", "150 mg"],
["Q4", "1000 mL over 10 hrs. Rate in mL/hr?", "100 mL/hr"],
["Q5", "500 mL, 5 hrs, drop factor 20. Drops/min?", "33 drops/min"],
["Q6", "Shop: βΉ480 with 25% off. What do you pay?", "βΉ360"],
["Q7", "Gentamicin 80 mg in 2 mL. Order: 120 mg. Volume?", "3 mL"],
["Q8", "Amoxicillin 40 mg/kg, child 15 kg. Available 250 mg/5 mL.", "12 mL"],
]
qt = Table(qp_data, colWidths=[CONTENT_W*0.07, CONTENT_W*0.65, CONTENT_W*0.28])
qt.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), NAVY),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 8.5),
("ALIGN", (0,0),(0,-1), "CENTER"),
("ALIGN", (1,0),(1,-1), "LEFT"),
("ALIGN", (2,0),(2,-1), "CENTER"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, GREY_LT]),
("GRID", (0,0),(-1,-1), 0.3, GREY_MID),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("LEFTPADDING", (1,0),(1,-1), 8),
("FONTNAME", (-1,1),(-1,-1),"Helvetica-Bold"),
("TEXTCOLOR", (-1,1),(-1,-1), TEAL),
]))
story.append(qt)
story.append(Spacer(1, 6*mm))
# ββ CHEAT-SHEET SUMMARY BOX βββββββββββββββββββββββββββββββββββββββββββββββββββ
summary = Table([
[Paragraph("π FORMULA CHEAT SHEET", S("ch", fontName="Helvetica-Bold",
fontSize=10, textColor=NAVY, alignment=TA_CENTER, leading=14))],
[Table([
[
Paragraph("<b>Tablets / Injections</b><br/>(Want Γ· Have) Γ Volume", sBody),
Paragraph("<b>Weight-based</b><br/>Dose/kg Γ Weight (kg)", sBody),
Paragraph("<b>mL/hr</b><br/>Volume Γ· Time (hrs)", sBody),
Paragraph("<b>Drops/min</b><br/>(Vol Γ df) Γ· Time (min)", sBody),
Paragraph("<b>Discount</b><br/>Price Γ (1 - %/100)", sBody),
]
], colWidths=[CONTENT_W/5]*5,
style=TableStyle([
("ALIGN", (0,0),(-1,-1),"CENTER"),
("FONTSIZE", (0,0),(-1,-1), 8),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1), 3),
("LINEBEFORE", (1,0),(-1,-1), 0.5, GREY_MID),
]))],
], colWidths=[CONTENT_W])
summary.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), MINT),
("TOPPADDING", (0,0),(-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LINEABOVE", (0,0),(-1,0), 2, TEAL),
("LINEBELOW", (0,-1),(-1,-1),2, TEAL),
]))
story.append(summary)
story.append(Spacer(1, 5*mm))
# ββ FOOTER NOTE βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(HRFlowable(width=CONTENT_W, thickness=0.5, color=GREY_MID))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
"This guide is for educational purposes only. Always verify drug calculations with a licensed healthcare professional before administration.",
sFooter
))
# ββ BUILD ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /tmp/workspace/drug-calc-guide && python build_guide.py 2>&1
ls -lh /tmp/workspace/drug-calc-guide/Drug_Calculation_Quick_Reference.pdf
Drug Calculation Quick Reference
PDF Document Β· PDF
| Section | What it covers |
|---|---|
| Section 1 | Fractions - what they are, decimal values, table of common fractions |
| Section 2 | Percentages - golden rule, shop discount table (10% to 50% off) |
| Section 3 | Units of measurement - kg/g/mg/mcg conversions, mL/L, concentration |
| Section 4 | The master drug formula - tablets & injections, with 6 worked examples |
| Section 5 | Weight-based dosing (mg/kg) - 2-step method with 4 examples |
| Section 6 | IV drip rates - mL/hr and drops/min formulas with a ready-reference table |
| Section 7 | Percentage concentrations - Normal Saline, 5% Dextrose, etc. |
| Section 8 | Golden rules & safety tips - 8 rules including high-alert drugs |
| Section 9 | 8 practice problems with answers |
| Cheat sheet | All 5 formulas in one summary box at the bottom |