To prepare and standrize 100 ml of 0.1 naoh solution using oxalic acid as primary standard........
Procedure in easy and simple way to learn in few minutes
standardization of NaOH using oxalic acid primary standard procedure
https://courseware.cutm.ac.in/wp-content/uploads/2020/06/Sod…
Note: This is an approximate (rough) solution. Its exact concentration is determined by standardization.
| Item | Purpose |
|---|---|
| Burette (50 mL) | To hold NaOH solution |
| Pipette (10 mL) | To measure oxalic acid |
| Conical flask (250 mL) | Titration vessel |
| Phenolphthalein indicator | To detect endpoint |
| White tile | To see color change clearly |
| Step | Action |
|---|---|
| 1 | Weigh 0.4 g NaOH, dissolve, make up to 100 mL |
| 2 | Weigh 0.63 g oxalic acid, dissolve, make up to 100 mL |
| 3 | Pipette 10 mL oxalic acid into flask |
| 4 | Add 2 drops phenolphthalein |
| 5 | Titrate with NaOH from burette |
| 6 | Endpoint = faint permanent pink |
| 7 | Calculate: N(NaOH) = (0.1 × 10) / V(NaOH used) |
Create a printable quick reference card for this procedure
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not found"
mkdir -p /home/daytona/workspace/naoh-card && python3 -c "from reportlab.lib import colors; print('reportlab ok')"
~/naoh-card/generate_card.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import Paragraph
from reportlab.lib.enums import TA_CENTER, TA_LEFT
W, H = A4 # 595.27 x 841.89 pts
# ── color palette ──────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MID_BLUE = colors.HexColor("#2e6da4")
LIGHT_BLUE = colors.HexColor("#d6e8f7")
ACCENT = colors.HexColor("#e74c3c")
GREEN = colors.HexColor("#27ae60")
LIGHT_GREEN = colors.HexColor("#eafaf1")
YELLOW_BG = colors.HexColor("#fef9e7")
ORANGE = colors.HexColor("#e67e22")
GRAY_BG = colors.HexColor("#f4f6f8")
WHITE = colors.white
BLACK = colors.black
def draw_rounded_rect(c, x, y, w, h, r=6, fill_color=WHITE, stroke_color=MID_BLUE, line_width=0.8):
c.setFillColor(fill_color)
c.setStrokeColor(stroke_color)
c.setLineWidth(line_width)
c.roundRect(x, y, w, h, r, stroke=1, fill=1)
def section_header(c, x, y, w, h, title, bg=DARK_BLUE, text_color=WHITE, fontsize=9.5):
c.setFillColor(bg)
c.rect(x, y, w, h, stroke=0, fill=1)
c.setFillColor(text_color)
c.setFont("Helvetica-Bold", fontsize)
c.drawString(x + 6, y + h/2 - fontsize/3, title)
def bullet_row(c, x, y, bullet, text, bullet_color=MID_BLUE, font="Helvetica", fontsize=8, indent=12):
c.setFillColor(bullet_color)
c.setFont("Helvetica-Bold", fontsize + 1)
c.drawString(x + 3, y, bullet)
c.setFillColor(BLACK)
c.setFont(font, fontsize)
c.drawString(x + indent, y, text)
def step_box(c, x, y, w, h, num, title, detail, num_bg=MID_BLUE):
draw_rounded_rect(c, x, y, w, h, r=5, fill_color=GRAY_BG, stroke_color=MID_BLUE, line_width=0.6)
# number circle
c.setFillColor(num_bg)
c.circle(x + 13, y + h/2, 9, stroke=0, fill=1)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(x + 13, y + h/2 - 3, str(num))
# title
c.setFillColor(DARK_BLUE)
c.setFont("Helvetica-Bold", 8)
c.drawString(x + 27, y + h - 11, title)
# detail
c.setFillColor(colors.HexColor("#444444"))
c.setFont("Helvetica", 7.5)
c.drawString(x + 27, y + 3, detail)
def table_row(c, x, y, w, cols, values, fontsize=8, bg=WHITE, bold_first=False):
c.setFillColor(bg)
c.rect(x, y, w, 14, stroke=0, fill=1)
col_x = x + 4
for i, (cw, val) in enumerate(zip(cols, values)):
c.setFillColor(BLACK)
font = "Helvetica-Bold" if (bold_first and i == 0) else "Helvetica"
c.setFont(font, fontsize)
c.drawString(col_x + 2, y + 3, str(val))
col_x += cw
def draw_card(output_path):
c = canvas.Canvas(output_path, pagesize=A4)
margin = 1.5 * cm
usable_w = W - 2 * margin
mid_x = margin + usable_w / 2
# ══════════════════════════════════════════════════════
# HEADER BANNER
# ══════════════════════════════════════════════════════
banner_h = 58
banner_y = H - margin - banner_h
c.setFillColor(DARK_BLUE)
c.rect(margin, banner_y, usable_w, banner_h, stroke=0, fill=1)
# accent stripe
c.setFillColor(MID_BLUE)
c.rect(margin, banner_y, 6, banner_h, stroke=0, fill=1)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 16)
c.drawString(margin + 16, banner_y + 33, "NaOH Preparation & Standardization")
c.setFont("Helvetica", 9)
c.drawString(margin + 16, banner_y + 17, "0.1 M NaOH | 100 mL | Primary Standard: Oxalic Acid Dihydrate")
# badge
c.setFillColor(ACCENT)
c.roundRect(W - margin - 82, banner_y + 12, 76, 22, 4, stroke=0, fill=1)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(W - margin - 44, banner_y + 20, "QUICK REFERENCE CARD")
# ══════════════════════════════════════════════════════
# ROW 1 — two top boxes side by side
# ══════════════════════════════════════════════════════
box_y1 = banner_y - 10 - 155
col_w = usable_w / 2 - 4
# ── LEFT: Chemicals & Apparatus ──────────────────────
draw_rounded_rect(c, margin, box_y1, col_w, 155, fill_color=WHITE, stroke_color=MID_BLUE)
section_header(c, margin, box_y1 + 135, col_w, 20, " CHEMICALS & QUANTITIES")
chem_data = [
("NaOH pellets", "0.40 g", MID_BLUE),
("Oxalic acid·2H₂O", "0.63 g", GREEN),
("Distilled water", "~200 mL", MID_BLUE),
("Phenolphthalein (ind.)", "2–3 drops",ORANGE),
]
ry = box_y1 + 123
for name, qty, col in chem_data:
c.setFillColor(col)
c.setFont("Helvetica-Bold", 8)
c.drawString(margin + 6, ry, qty)
c.setFillColor(BLACK)
c.setFont("Helvetica", 8)
c.drawString(margin + 58, ry, name)
ry -= 13
c.setStrokeColor(LIGHT_BLUE)
c.setLineWidth(0.5)
c.line(margin + 6, ry + 7, margin + col_w - 6, ry + 7)
c.setFillColor(DARK_BLUE)
c.setFont("Helvetica-Bold", 7.5)
c.drawString(margin + 6, ry - 5, "KEY APPARATUS:")
apparatus = ["100 mL volumetric flask", "50 mL burette", "10 mL pipette",
"250 mL conical flask", "White tile", "Analytical balance"]
ax, ay = margin + 6, ry - 17
for i, ap in enumerate(apparatus):
col_offset = 0 if i % 2 == 0 else col_w // 2
row_y = ay - (i // 2) * 11
c.setFillColor(MID_BLUE)
c.circle(margin + 6 + col_offset + 3, row_y + 3, 2, stroke=0, fill=1)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(margin + 6 + col_offset + 8, row_y, ap)
# ── RIGHT: Chemical Reaction ──────────────────────────
rx0 = margin + col_w + 8
draw_rounded_rect(c, rx0, box_y1, col_w, 155, fill_color=WHITE, stroke_color=GREEN)
section_header(c, rx0, box_y1 + 135, col_w, 20, " CHEMICAL REACTION", bg=GREEN)
c.setFillColor(LIGHT_GREEN)
c.roundRect(rx0 + 6, box_y1 + 95, col_w - 12, 34, 4, stroke=0, fill=1)
c.setFillColor(DARK_BLUE)
c.setFont("Helvetica-Bold", 8.5)
c.drawCentredString(rx0 + col_w/2, box_y1 + 117, "H\u2082C\u2082O\u2084 + 2 NaOH")
c.setFillColor(ACCENT)
c.setFont("Helvetica-Bold", 10)
c.drawCentredString(rx0 + col_w/2, box_y1 + 104, "\u2192 Na\u2082C\u2082O\u2084 + 2 H\u2082O")
facts = [
("Molar mass NaOH", "40.00 g/mol"),
("Molar mass Oxalic·2H\u2082O", "126.07 g/mol"),
("Reaction ratio", "1 mol acid : 2 mol NaOH"),
("Equivalent factor (n)", "2 (diprotic acid)"),
("Indicator", "Phenolphthalein"),
]
fy = box_y1 + 86
for label, val in facts:
c.setFillColor(colors.HexColor("#555555"))
c.setFont("Helvetica", 7.5)
c.drawString(rx0 + 6, fy, label + ":")
c.setFillColor(DARK_BLUE)
c.setFont("Helvetica-Bold", 7.5)
c.drawRightString(rx0 + col_w - 6, fy, val)
fy -= 12
# endpoint note
c.setFillColor(YELLOW_BG)
c.roundRect(rx0 + 6, box_y1 + 4, col_w - 12, 20, 3, stroke=0, fill=1)
c.setFillColor(ORANGE)
c.setFont("Helvetica-Bold", 8)
c.drawString(rx0 + 10, box_y1 + 11, "ENDPOINT: Faint permanent PINK (30 sec stable)")
# ══════════════════════════════════════════════════════
# ROW 2 — PART A steps
# ══════════════════════════════════════════════════════
row2_y = box_y1 - 12 - 125
draw_rounded_rect(c, margin, row2_y, usable_w, 125, fill_color=WHITE, stroke_color=MID_BLUE)
section_header(c, margin, row2_y + 105, usable_w, 20, " PART A — PREPARATION OF 0.1 M NaOH (100 mL)")
steps_a = [
("Weigh", "Weigh 0.40 g NaOH pellets quickly (hygroscopic!)"),
("Dissolve", "Dissolve in ~30 mL distilled water in a beaker; stir"),
("Cool", "Let solution cool to room temperature"),
("Transfer", "Pour into 100 mL volumetric flask; rinse beaker 2-3×"),
("Make up", "Add distilled water to the 100 mL mark (bottom meniscus)"),
("Mix", "Stopper the flask; invert 10× to homogenize"),
]
sw = usable_w / 3 - 4
sx, sy = margin + 4, row2_y + 92
for i, (title, detail) in enumerate(steps_a):
col = i % 3
row = i // 3
bx = margin + 4 + col * (sw + 4)
by = sy - row * 38 - 34
step_box(c, bx, by, sw, 33, i + 1, title, detail, num_bg=MID_BLUE)
# ══════════════════════════════════════════════════════
# ROW 3 — PART B steps
# ══════════════════════════════════════════════════════
row3_y = row2_y - 12 - 125
draw_rounded_rect(c, margin, row3_y, usable_w, 125, fill_color=WHITE, stroke_color=GREEN)
section_header(c, margin, row3_y + 105, usable_w, 20, " PART B — STANDARDIZATION (TITRATION)", bg=GREEN)
steps_b = [
("Prepare std", "Dissolve 0.63 g oxalic acid in water → 100 mL flask"),
("Fill burette", "Rinse burette with NaOH; fill; note initial reading"),
("Pipette", "Pipette 10 mL oxalic acid into conical flask"),
("Indicator", "Add 2-3 drops phenolphthalein (solution = colorless)"),
("Titrate", "Run NaOH slowly; swirl; add drop-by-drop near end"),
("Repeat", "Repeat 3× for concordant readings (within 0.1 mL)"),
]
for i, (title, detail) in enumerate(steps_b):
col = i % 3
row = i // 3
bx = margin + 4 + col * (sw + 4)
by = row3_y + 92 - row * 38 - 34
step_box(c, bx, by, sw, 33, i + 1, title, detail, num_bg=GREEN)
# ══════════════════════════════════════════════════════
# ROW 4 — Calculation box + Key reminders side by side
# ══════════════════════════════════════════════════════
row4_y = row3_y - 12 - 110
calc_w = usable_w * 0.54
tip_w = usable_w - calc_w - 8
# Calculation box
draw_rounded_rect(c, margin, row4_y, calc_w, 110, fill_color=WHITE, stroke_color=DARK_BLUE, line_width=1.2)
section_header(c, margin, row4_y + 90, calc_w, 20, " CALCULATION FORMULA", bg=DARK_BLUE)
c.setFillColor(LIGHT_BLUE)
c.roundRect(margin + 6, row4_y + 56, calc_w - 12, 28, 4, stroke=0, fill=1)
c.setFillColor(DARK_BLUE)
c.setFont("Helvetica-Bold", 10)
c.drawCentredString(margin + calc_w/2, row4_y + 71, "N\u2081V\u2081 = N\u2082V\u2082")
c.setFont("Helvetica", 8)
c.setFillColor(colors.HexColor("#333333"))
c.drawCentredString(margin + calc_w/2, row4_y + 59, "N(NaOH) = (0.1 \u00d7 10) / V(NaOH used)")
c.setFillColor(BLACK)
c.setFont("Helvetica-Bold", 8)
c.drawString(margin + 8, row4_y + 48, "Where:")
vars_data = [
("N\u2081", "Normality of oxalic acid = 0.1 N"),
("V\u2081", "Volume of oxalic acid = 10 mL"),
("N\u2082", "Normality of NaOH = ? (to find)"),
("V\u2082", "Volume of NaOH used from burette (mL)"),
]
vy = row4_y + 37
for sym, meaning in vars_data:
c.setFillColor(MID_BLUE)
c.setFont("Helvetica-Bold", 8)
c.drawString(margin + 10, vy, sym)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(margin + 26, vy, "= " + meaning)
vy -= 10
c.setFillColor(YELLOW_BG)
c.roundRect(margin + 6, row4_y + 4, calc_w - 12, 14, 3, stroke=0, fill=1)
c.setFillColor(ORANGE)
c.setFont("Helvetica-Bold", 7.5)
c.drawCentredString(margin + calc_w/2, row4_y + 9, "Example: V(NaOH) = 9.8 mL → N(NaOH) = (0.1×10)/9.8 = 0.102 N")
# Key reminders box
tip_x = margin + calc_w + 8
draw_rounded_rect(c, tip_x, row4_y, tip_w, 110, fill_color=WHITE, stroke_color=ORANGE, line_width=1.2)
section_header(c, tip_x, row4_y + 90, tip_w, 20, " KEY REMINDERS", bg=ORANGE, text_color=WHITE)
tips = [
("\u26a0", "NaOH is hygroscopic - weigh fast!"),
("\u26a0", "Use CO\u2082-free distilled water"),
("\u2714", "Read burette at bottom of meniscus"),
("\u2714", "3 concordant readings (within 0.1 mL)"),
("\u2714", "Endpoint = faint pink, stable 30 s"),
("\u2714", "Standardized molarity may differ from 0.1"),
]
ty = row4_y + 80
for icon, tip in tips:
ico_col = ACCENT if icon == "\u26a0" else GREEN
c.setFillColor(ico_col)
c.setFont("Helvetica-Bold", 9)
c.drawString(tip_x + 6, ty, icon)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(tip_x + 18, ty, tip)
ty -= 12
# ══════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════
footer_y = row4_y - 10
c.setStrokeColor(DARK_BLUE)
c.setLineWidth(0.5)
c.line(margin, footer_y, W - margin, footer_y)
c.setFillColor(colors.HexColor("#888888"))
c.setFont("Helvetica", 7)
c.drawString(margin, footer_y - 10, "Preparation & Standardization of 0.1 M NaOH using Oxalic Acid Dihydrate as Primary Standard")
c.drawRightString(W - margin, footer_y - 10, "Analytical Chemistry Quick Reference")
c.save()
print(f"PDF saved to {output_path}")
draw_card("/home/daytona/workspace/naoh-card/NaOH_Quick_Reference_Card.pdf")
python3 /home/daytona/workspace/naoh-card/generate_card.py
NaOH Quick Reference Card
PDF Document · PDF
| Section | What's inside |
|---|---|
| Header banner | Title, concentration, primary standard at a glance |
| Chemicals & Apparatus | Exact weights/volumes + all glassware needed |
| Chemical Reaction | Balanced equation, molar masses, n-factor, indicator |
| Part A - Preparation | 6 numbered steps with titles and details |
| Part B - Standardization | 6 numbered titration steps |
| Calculation formula | N₁V₁ = N₂V₂ with worked example + key reminders |
To estimation of barium sulfate...... procedure flash card chemical with h2so4 and bacl2
~/naoh-card/baso4_flashcard.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.pdfgen import canvas
W, H = A4
# ── Palette ────────────────────────────────────────────────────
DARK_PURPLE = colors.HexColor("#3b1f5e")
MID_PURPLE = colors.HexColor("#6c3fc5")
LIGHT_PURPLE = colors.HexColor("#ede7f6")
TEAL = colors.HexColor("#00796b")
LIGHT_TEAL = colors.HexColor("#e0f2f1")
AMBER = colors.HexColor("#e65100")
AMBER_LIGHT = colors.HexColor("#fff3e0")
RED = colors.HexColor("#c0392b")
GREEN = colors.HexColor("#1b5e20")
LIGHT_GREEN = colors.HexColor("#e8f5e9")
BLUE = colors.HexColor("#1565c0")
LIGHT_BLUE = colors.HexColor("#e3f2fd")
GRAY_BG = colors.HexColor("#f5f5f5")
DARK_GRAY = colors.HexColor("#37474f")
WHITE = colors.white
BLACK = colors.black
def rrect(c, x, y, w, h, r=6, fill=WHITE, stroke=MID_PURPLE, lw=0.8):
c.setFillColor(fill)
c.setStrokeColor(stroke)
c.setLineWidth(lw)
c.roundRect(x, y, w, h, r, stroke=1, fill=1)
def sec_hdr(c, x, y, w, h, txt, bg=DARK_PURPLE, fg=WHITE, fs=9.5):
c.setFillColor(bg)
c.rect(x, y, w, h, stroke=0, fill=1)
c.setFillColor(fg)
c.setFont("Helvetica-Bold", fs)
c.drawString(x + 7, y + h/2 - fs/3, txt)
def step_pill(c, x, y, num, title, detail, num_bg=MID_PURPLE, bw=None, bh=36):
if bw is None:
bw = (W - 2*1.5*cm) / 3 - 4
rrect(c, x, y, bw, bh, r=5, fill=GRAY_BG, stroke=MID_PURPLE, lw=0.6)
c.setFillColor(num_bg)
c.circle(x + 13, y + bh/2, 10, stroke=0, fill=1)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 9)
c.drawCentredString(x + 13, y + bh/2 - 3, str(num))
c.setFillColor(DARK_PURPLE)
c.setFont("Helvetica-Bold", 8)
c.drawString(x + 28, y + bh - 12, title)
c.setFillColor(DARK_GRAY)
c.setFont("Helvetica", 7.5)
c.drawString(x + 28, y + 4, detail)
def draw_baso4_card(out):
c = canvas.Canvas(out, pagesize=A4)
mg = 1.5 * cm
uw = W - 2 * mg # usable width
half = uw / 2 - 4
# ══════════════════════════════════════════════════════════
# HEADER
# ══════════════════════════════════════════════════════════
bh = 64
by = H - mg - bh
c.setFillColor(DARK_PURPLE)
c.rect(mg, by, uw, bh, stroke=0, fill=1)
c.setFillColor(AMBER)
c.rect(mg, by, 7, bh, stroke=0, fill=1) # accent stripe
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 17)
c.drawString(mg + 18, by + 39, "Estimation of Barium as BaSO\u2084")
c.setFont("Helvetica", 9)
c.drawString(mg + 18, by + 23, "Gravimetric Analysis | BaCl\u2082 + H\u2082SO\u2084 \u2192 BaSO\u2084\u2193 + 2 HCl")
c.setFillColor(AMBER)
c.roundRect(W - mg - 90, by + 14, 84, 22, 4, stroke=0, fill=1)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 7.5)
c.drawCentredString(W - mg - 48, by + 22, "GRAVIMETRIC FLASHCARD")
# ══════════════════════════════════════════════════════════
# ROW 1 — Principle + Chemicals side by side
# ══════════════════════════════════════════════════════════
r1y = by - 10 - 115
# LEFT – Principle
rrect(c, mg, r1y, half, 115, fill=LIGHT_PURPLE, stroke=MID_PURPLE)
sec_hdr(c, mg, r1y + 95, half, 20, " PRINCIPLE", bg=MID_PURPLE)
lines = [
"Ba\u00b2\u207a ions in BaCl\u2082 are precipitated by H\u2082SO\u2084",
"as insoluble BaSO\u2084 (white precipitate).",
"Precipitate is filtered, washed, dried,",
"ignited, and weighed accurately.",
"Barium % is calculated from precipitate mass.",
]
py = r1y + 82
for ln in lines:
c.setFillColor(DARK_PURPLE)
c.circle(mg + 8, py + 3, 2.2, stroke=0, fill=1)
c.setFillColor(BLACK)
c.setFont("Helvetica", 8)
c.drawString(mg + 14, py, ln)
py -= 12
# RIGHT – Chemicals
rx0 = mg + half + 8
rrect(c, rx0, r1y, half, 115, fill=WHITE, stroke=TEAL)
sec_hdr(c, rx0, r1y + 95, half, 20, " CHEMICALS & APPARATUS", bg=TEAL)
chems = [
("BaCl\u2082 solution", "~0.5 g/100 mL", BLUE),
("H\u2082SO\u2084 (dil.)", "1:10 v/v, 5 mL", RED),
("Distilled water", "for washing", TEAL),
("Whatman No. 42 filter paper", "ashless", DARK_GRAY),
("Crucible (porcelain)", "pre-ignited", AMBER),
]
cy = r1y + 83
for name, qty, col in chems:
c.setFillColor(col)
c.setFont("Helvetica-Bold", 7.5)
c.drawString(rx0 + 6, cy, qty)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(rx0 + 80, cy, name)
cy -= 12
c.setFillColor(AMBER_LIGHT)
c.roundRect(rx0 + 6, r1y + 4, half - 12, 14, 3, stroke=0, fill=1)
c.setFillColor(AMBER)
c.setFont("Helvetica-Bold", 7.5)
c.drawCentredString(rx0 + half/2, r1y + 9, "Also: Muffle furnace, analytical balance, desiccator")
# ══════════════════════════════════════════════════════════
# ROW 2 — Balanced Equation + MW data
# ══════════════════════════════════════════════════════════
r2y = r1y - 10 - 58
rrect(c, mg, r2y, uw, 58, fill=LIGHT_BLUE, stroke=BLUE, lw=1.2)
sec_hdr(c, mg, r2y + 38, uw, 20, " BALANCED EQUATION & MOLAR MASSES", bg=BLUE)
c.setFillColor(DARK_PURPLE)
c.setFont("Helvetica-Bold", 12)
c.drawCentredString(W/2, r2y + 24, "BaCl\u2082 + H\u2082SO\u2084 \u27f6 BaSO\u2084\u2193 + 2 HCl")
c.setFillColor(BLUE)
c.setFont("Helvetica", 8)
c.drawCentredString(W/2 - 90, r2y + 11, "208.23 g/mol")
c.drawCentredString(W/2 - 10, r2y + 11, "98.08 g/mol")
c.drawCentredString(W/2 + 80, r2y + 11, "233.39 g/mol \u2190 weighed")
# ══════════════════════════════════════════════════════════
# ROW 3 — Procedure steps (6 steps, 2 rows × 3 cols)
# ══════════════════════════════════════════════════════════
r3y = r2y - 10 - 90
rrect(c, mg, r3y, uw, 90, fill=WHITE, stroke=DARK_PURPLE, lw=1)
sec_hdr(c, mg, r3y + 70, uw, 20, " STEP-BY-STEP PROCEDURE")
sw = uw / 3 - 4
steps = [
("Dissolve", "Dissolve BaCl\u2082 sample in ~100 mL distilled water"),
("Acidify", "Add 5 mL dil. H\u2082SO\u2084; heat solution to near boiling"),
("Precipitate","White BaSO\u2084 ppt forms; stir; let digest 1 hour"),
("Filter", "Filter hot thro Whatman 42; wash ppt with hot water"),
("Dry & Ignite","Dry paper+ppt; ignite at 800\u2013900\u00b0C in muffle furnace"),
("Weigh", "Cool in desiccator; weigh crucible+BaSO\u2084 to 0.0001 g"),
]
for i, (title, detail) in enumerate(steps):
col = i % 3
row = i // 3
bx = mg + 2 + col * (sw + 6)
bby = r3y + 58 - row * 40
step_pill(c, bx, bby, i+1, title, detail, num_bg=DARK_PURPLE, bw=sw, bh=34)
# ══════════════════════════════════════════════════════════
# ROW 4 — Calculation + Observations side by side
# ══════════════════════════════════════════════════════════
r4y = r3y - 10 - 118
cw = uw * 0.52
ow = uw - cw - 8
# Calculation
rrect(c, mg, r4y, cw, 118, fill=WHITE, stroke=BLUE, lw=1.2)
sec_hdr(c, mg, r4y + 98, cw, 20, " CALCULATIONS", bg=BLUE)
c.setFillColor(LIGHT_BLUE)
c.roundRect(mg + 6, r4y + 66, cw - 12, 26, 4, stroke=0, fill=1)
c.setFillColor(BLUE)
c.setFont("Helvetica-Bold", 9.5)
c.drawCentredString(mg + cw/2, r4y + 79, "Wt of BaSO\u2084 = W\u2082 \u2212 W\u2081 (g)")
c.setFillColor(DARK_GRAY)
c.setFont("Helvetica", 7.5)
c.drawCentredString(mg + cw/2, r4y + 68, "W\u2081 = empty crucible wt | W\u2082 = crucible + ppt wt")
c.setFillColor(LIGHT_GREEN)
c.roundRect(mg + 6, r4y + 38, cw - 12, 24, 4, stroke=0, fill=1)
c.setFillColor(GREEN)
c.setFont("Helvetica-Bold", 9.5)
c.drawCentredString(mg + cw/2, r4y + 50, "% Ba = (Wt BaSO\u2084 \u00d7 137.33 / 233.39) \u00d7 (100 / W\u209b)")
c.setFillColor(DARK_GRAY)
c.setFont("Helvetica", 7.5)
c.drawCentredString(mg + cw/2, r4y + 39, "W\u209b = weight of sample taken")
c.setFillColor(AMBER_LIGHT)
c.roundRect(mg + 6, r4y + 16, cw - 12, 18, 3, stroke=0, fill=1)
c.setFillColor(AMBER)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(mg + cw/2, r4y + 22, "Gravimetric Factor = Ba / BaSO\u2084 = 137.33 / 233.39 = 0.5885")
c.setFillColor(DARK_GRAY)
c.setFont("Helvetica", 7.5)
c.drawCentredString(mg + cw/2, r4y + 7, "Molar mass: Ba = 137.33 | BaSO\u2084 = 233.39 | BaCl\u2082 = 208.23")
# Observations / Key Points
ox = mg + cw + 8
rrect(c, ox, r4y, ow, 118, fill=WHITE, stroke=AMBER, lw=1.2)
sec_hdr(c, ox, r4y + 98, ow, 20, " OBSERVATIONS & KEY POINTS", bg=AMBER, fg=WHITE)
obs = [
("\u2714", "White crystalline precipitate forms", GREEN),
("\u2714", "BaSO\u2084 is insoluble in hot/cold water", GREEN),
("\u2714", "Precipitate must be digested (aged)", GREEN),
("\u26a0", "Avoid excess H\u2082SO\u2084 (co-precipitation)", RED),
("\u26a0", "Wash until filtrate is chloride-free", RED),
("\u26a0", "Ignite at 800-900\u00b0C; NOT above 1000\u00b0C", RED),
("\u2139", "BaSO\u2084 is stable, non-hygroscopic", BLUE),
("\u2139", "Cool in desiccator before each weighing", BLUE),
]
ty = r4y + 87
for icon, tip, col in obs:
c.setFillColor(col)
c.setFont("Helvetica-Bold", 9)
c.drawString(ox + 5, ty, icon)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(ox + 18, ty, tip)
ty -= 11
# ══════════════════════════════════════════════════════════
# ROW 5 — Sources of error flash strip
# ══════════════════════════════════════════════════════════
r5y = r4y - 8 - 34
rrect(c, mg, r5y, uw, 34, fill=colors.HexColor("#fce4ec"), stroke=RED, lw=1)
sec_hdr(c, mg, r5y + 14, uw, 20, " COMMON SOURCES OF ERROR", bg=RED)
errors = [
"Co-precipitation of Cl\u207b",
"Incomplete washing",
"Incomplete ignition",
"Hygroscopic gain if not cooled properly",
"Crucible not pre-ignited / tared",
]
ex = mg + 6
for err in errors:
c.setFillColor(RED)
c.circle(ex + 3, r5y + 6, 2.2, stroke=0, fill=1)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
tw = c.stringWidth(err, "Helvetica", 7.5)
c.drawString(ex + 8, r5y + 2, err)
ex += tw + 20
# ══════════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════════
fy = r5y - 10
c.setStrokeColor(DARK_PURPLE)
c.setLineWidth(0.5)
c.line(mg, fy, W - mg, fy)
c.setFillColor(colors.HexColor("#888888"))
c.setFont("Helvetica", 7)
c.drawString(mg, fy - 10, "Estimation of Barium as BaSO\u2084 | Gravimetric Analysis | BaCl\u2082 + H\u2082SO\u2084 \u2192 BaSO\u2084\u2193 + 2HCl")
c.drawRightString(W - mg, fy - 10, "Analytical Chemistry Quick Reference Card")
c.save()
print(f"Saved: {out}")
draw_baso4_card("/home/daytona/workspace/naoh-card/BaSO4_Estimation_Flashcard.pdf")
python3 /home/daytona/workspace/naoh-card/baso4_flashcard.py
BaSO4 Estimation Flashcard
PDF Document · PDF
| Section | Content |
|---|---|
| Principle | How Ba²⁺ precipitates as BaSO₄ - 5 bullet points |
| Chemicals & Apparatus | BaCl₂, H₂SO₄, filter paper, crucible, furnace |
| Balanced Equation | BaCl₂ + H₂SO₄ → BaSO₄↓ + 2HCl with molar masses |
| 6 Procedure Steps | Dissolve → Acidify → Precipitate → Filter → Ignite → Weigh |
| Calculations | Wt BaSO₄ = W₂ - W₁, % Ba formula, gravimetric factor 0.5885 |
| Observations & Key Points | 8 tips with green/red/blue color coding |
| Sources of Error | 5 common mistakes to avoid (co-precipitation, incomplete washing, etc.) |