I need chemistry atomic structure important detailed points
chemistry atomic structure important points detailed notes
| Particle | Symbol | Relative Mass | Relative Charge | Location |
|---|---|---|---|---|
| Proton | p⁺ | 1 | +1 | Nucleus |
| Neutron | n⁰ | 1 | 0 | Nucleus |
| Electron | e⁻ | 1/1836 (~negligible) | -1 | Shells/Orbitals around nucleus |
| Quantum Number | Symbol | What it Describes | Allowed Values |
|---|---|---|---|
| Principal | n | Shell/energy level | 1, 2, 3, 4... |
| Azimuthal (Angular Momentum) | l | Shape of orbital (subshell) | 0 to (n-1) |
| Magnetic | mₗ | Orientation of orbital | -l to +l |
| Spin | mₛ | Spin of electron | +½ or -½ |
| Series | Transition to Shell | Region |
|---|---|---|
| Lyman | n=1 | Ultraviolet |
| Balmer | n=2 | Visible |
| Paschen | n=3 | Infrared |
| Brackett | n=4 | Infrared |
| Pfund | n=5 | Far-infrared |
| Formula | Description |
|---|---|
| A = Z + N | Mass number = protons + neutrons |
| E = hν | Energy of photon |
| E = hc/λ | Energy using wavelength |
| Max e⁻ per shell = 2n² | Shell capacity |
| Number of orbitals in shell = n² | Total orbitals |
| Wavenumber: ν̄ = 1/λ | Spectroscopy |
| Rydberg: 1/λ = R(1/n₁² - 1/n₂²) | Hydrogen spectral lines |
| Property | Across Period (L→R) | Down a Group |
|---|---|---|
| Atomic radius | Decreases | Increases |
| Ionisation energy | Increases | Decreases |
| Electron affinity | Generally increases | Decreases |
| Electronegativity | Increases | Decreases |
| Nuclear charge (Z) | Increases | Increases |
| Shielding | Roughly constant | Increases |
Create a comprehensive study guide PDF on atomic structure
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "workspace ready"
mkdir -p /tmp/workspace/atomic-structure-guide && echo "dir created"
~/atomic-structure-guide/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import Flowable
import reportlab.rl_config
OUTPUT = "/tmp/workspace/atomic-structure-guide/Atomic_Structure_Study_Guide.pdf"
# ─── Color Palette ───────────────────────────────────────────────────────────
C_DARK_BLUE = colors.HexColor("#1A237E")
C_MED_BLUE = colors.HexColor("#1565C0")
C_LIGHT_BLUE = colors.HexColor("#E3F2FD")
C_ACCENT = colors.HexColor("#FF6F00")
C_ACCENT2 = colors.HexColor("#00838F")
C_YELLOW = colors.HexColor("#FFF9C4")
C_GREEN_BG = colors.HexColor("#E8F5E9")
C_GREEN = colors.HexColor("#2E7D32")
C_PURPLE_BG = colors.HexColor("#F3E5F5")
C_PURPLE = colors.HexColor("#6A1B9A")
C_RED_BG = colors.HexColor("#FFEBEE")
C_RED = colors.HexColor("#B71C1C")
C_ORANGE_BG = colors.HexColor("#FFF3E0")
C_ORANGE = colors.HexColor("#E65100")
C_GRAY_BG = colors.HexColor("#F5F5F5")
C_GRAY = colors.HexColor("#616161")
C_WHITE = colors.white
C_BLACK = colors.black
# ─── Page geometry ───────────────────────────────────────────────────────────
PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm
# ─── Styles ──────────────────────────────────────────────────────────────────
base_styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
sTitle = S("sTitle",
fontName="Helvetica-Bold", fontSize=28, textColor=C_WHITE,
alignment=TA_CENTER, leading=36)
sSubtitle = S("sSubtitle",
fontName="Helvetica", fontSize=13, textColor=colors.HexColor("#BBDEFB"),
alignment=TA_CENTER, leading=18)
sSectionNum = S("sSectionNum",
fontName="Helvetica-Bold", fontSize=18, textColor=C_WHITE,
alignment=TA_LEFT, leading=24)
sH1 = S("sH1",
fontName="Helvetica-Bold", fontSize=15, textColor=C_WHITE,
alignment=TA_LEFT, leading=20)
sH2 = S("sH2",
fontName="Helvetica-Bold", fontSize=12, textColor=C_MED_BLUE,
alignment=TA_LEFT, leading=16, spaceBefore=8, spaceAfter=4)
sH3 = S("sH3",
fontName="Helvetica-Bold", fontSize=10, textColor=C_ACCENT2,
alignment=TA_LEFT, leading=14, spaceBefore=6, spaceAfter=2)
sBody = S("sBody",
fontName="Helvetica", fontSize=9.5, textColor=colors.HexColor("#212121"),
alignment=TA_JUSTIFY, leading=15, spaceAfter=4)
sBullet = S("sBullet",
fontName="Helvetica", fontSize=9.5, textColor=colors.HexColor("#212121"),
alignment=TA_LEFT, leading=15, leftIndent=14, spaceAfter=2,
bulletIndent=4)
sBulletBold = S("sBulletBold",
fontName="Helvetica-Bold", fontSize=9.5, textColor=C_DARK_BLUE,
alignment=TA_LEFT, leading=15, leftIndent=14, spaceAfter=2,
bulletIndent=4)
sFormula = S("sFormula",
fontName="Helvetica-Bold", fontSize=10, textColor=C_ACCENT,
alignment=TA_CENTER, leading=16, spaceBefore=4, spaceAfter=4)
sNote = S("sNote",
fontName="Helvetica-Oblique", fontSize=8.8, textColor=C_GREEN,
alignment=TA_LEFT, leading=14, leftIndent=10)
sSmall = S("sSmall",
fontName="Helvetica", fontSize=8.5, textColor=C_GRAY,
alignment=TA_CENTER, leading=12)
sTableHead = S("sTableHead",
fontName="Helvetica-Bold", fontSize=9, textColor=C_WHITE,
alignment=TA_CENTER, leading=13)
sTableCell = S("sTableCell",
fontName="Helvetica", fontSize=9, textColor=C_BLACK,
alignment=TA_CENTER, leading=13)
sTableCellL = S("sTableCellL",
fontName="Helvetica", fontSize=9, textColor=C_BLACK,
alignment=TA_LEFT, leading=13)
sWarning = S("sWarning",
fontName="Helvetica-Bold", fontSize=9.5, textColor=C_RED,
alignment=TA_LEFT, leading=14, leftIndent=10)
sPageNum = S("sPageNum",
fontName="Helvetica", fontSize=8, textColor=C_GRAY,
alignment=TA_CENTER, leading=10)
# ─── Custom Flowables ────────────────────────────────────────────────────────
class ColorBand(Flowable):
"""A full-width colored band (used for section headers)."""
def __init__(self, height, color, radius=4):
super().__init__()
self.band_h = height
self.color = color
self.radius = radius
self.width = PAGE_W - 2 * MARGIN
self.height = height
def draw(self):
self.canv.setFillColor(self.color)
self.canv.roundRect(0, 0, self.width, self.band_h,
self.radius, stroke=0, fill=1)
class SectionHeader(Flowable):
"""Gradient-style section header block."""
def __init__(self, number, title, color1=C_DARK_BLUE, color2=C_MED_BLUE, h=42):
super().__init__()
self.number = number
self.title = title
self.color1 = color1
self.color2 = color2
self.band_h = h
self.width = PAGE_W - 2 * MARGIN
self.height = h + 6
def draw(self):
c = self.canv
w, h = self.width, self.band_h
# Background rect
c.setFillColor(self.color1)
c.roundRect(0, 0, w, h, 5, stroke=0, fill=1)
# Accent stripe on left
c.setFillColor(self.color2)
c.roundRect(0, 0, 8, h, 3, stroke=0, fill=1)
# Number circle
cx, cy, r = 26, h/2, 13
c.setFillColor(C_ACCENT)
c.circle(cx, cy, r, stroke=0, fill=1)
c.setFont("Helvetica-Bold", 12)
c.setFillColor(C_WHITE)
txt = str(self.number)
c.drawCentredString(cx, cy - 4, txt)
# Title text
c.setFont("Helvetica-Bold", 14)
c.setFillColor(C_WHITE)
c.drawString(48, h/2 - 5, self.title.upper())
class InfoBox(Flowable):
"""A colored info box with a label."""
def __init__(self, label, content_lines, bg=C_LIGHT_BLUE, border=C_MED_BLUE,
label_color=C_MED_BLUE, text_color=C_BLACK, w=None, padding=8):
super().__init__()
self.label = label
self.lines = content_lines
self.bg = bg
self.border = border
self.label_color = label_color
self.text_color = text_color
self.box_w = w or (PAGE_W - 2 * MARGIN)
self.pad = padding
line_h = 14
self.height = self.pad * 2 + (len(self.lines) + (1 if label else 0)) * line_h + 4
self.width = self.box_w
def draw(self):
c = self.canv
h = self.height
c.setFillColor(self.bg)
c.setStrokeColor(self.border)
c.setLineWidth(1.2)
c.roundRect(0, 0, self.box_w, h, 5, stroke=1, fill=1)
# Left accent bar
c.setFillColor(self.border)
c.roundRect(0, 0, 5, h, 3, stroke=0, fill=1)
y = h - self.pad - 12
if self.label:
c.setFont("Helvetica-Bold", 9.5)
c.setFillColor(self.label_color)
c.drawString(14, y, self.label)
y -= 14
c.setFont("Helvetica", 9)
c.setFillColor(self.text_color)
for line in self.lines:
c.drawString(14, y, line)
y -= 14
# ─── Helper builders ─────────────────────────────────────────────────────────
def make_table(data, col_widths, header_bg=C_DARK_BLUE, alt_bg=C_LIGHT_BLUE,
header_text_color=C_WHITE):
"""Build a styled Table."""
style = [
("BACKGROUND", (0,0), (-1,0), header_bg),
("TEXTCOLOR", (0,0), (-1,0), header_text_color),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, alt_bg]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING",(0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [4]),
]
t = Table(data, colWidths=col_widths)
t.setStyle(TableStyle(style))
return t
def hr(color=C_MED_BLUE, thickness=1):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=6, spaceBefore=6)
def sp(h=6):
return Spacer(1, h)
def bullet(text, style=sBullet):
return Paragraph(f"<bullet>\u2022</bullet> {text}", style)
def subbullet(text):
return Paragraph(f"<bullet> \u25e6</bullet> {text}",
S("sub", parent=sBullet, leftIndent=28, bulletIndent=18,
fontSize=9))
# ─── Cover Page ──────────────────────────────────────────────────────────────
def cover_page(story):
# Full-page dark blue background via a large table
cover_data = [[""]]
cover_table = Table(cover_data, colWidths=[PAGE_W - 2*MARGIN], rowHeights=[260])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 80),
("BOTTOMPADDING",(0,0), (-1,-1), 80),
("ROUNDEDCORNERS", [8]),
]))
story.append(cover_table)
story.append(sp(8))
# Top accent line
story.append(HRFlowable(width="100%", thickness=4, color=C_ACCENT, spaceAfter=0, spaceBefore=0))
story.append(sp(8))
# Title block
title_data = [[Paragraph("⚛ ATOMIC STRUCTURE", sTitle)]]
title_table = Table(title_data, colWidths=[PAGE_W - 2*MARGIN], rowHeights=[60])
title_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING",(0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [6]),
]))
story.append(title_table)
story.append(sp(6))
sub_data = [[Paragraph("COMPREHENSIVE STUDY GUIDE", sSubtitle)]]
sub_table = Table(sub_data, colWidths=[PAGE_W - 2*MARGIN], rowHeights=[36])
sub_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_MED_BLUE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [6]),
]))
story.append(sub_table)
story.append(sp(20))
# Topics covered grid
topics = [
["Subatomic Particles", "Atomic Models", "Quantum Numbers"],
["Orbital Shapes", "Electron Config", "Hund's Rule"],
["Atomic Spectra", "Ionisation Energy","Periodic Trends"],
["Key Formulas", "Practice Q&A", "Quick Revision"],
]
col_w = (PAGE_W - 2*MARGIN) / 3
topic_data = []
for row in topics:
topic_data.append([Paragraph(t, S("tc", fontName="Helvetica-Bold", fontSize=9,
textColor=C_DARK_BLUE, alignment=TA_CENTER, leading=13))
for t in row])
t = Table(topic_data, colWidths=[col_w]*3)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_LIGHT_BLUE),
("ROWBACKGROUNDS",(0,0),(-1,-1), [C_LIGHT_BLUE, C_YELLOW]),
("GRID", (0,0), (-1,-1), 0.5, C_MED_BLUE),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("ROUNDEDCORNERS", [4]),
]))
story.append(Paragraph("Topics Covered:", S("tc2", fontName="Helvetica-Bold",
fontSize=11, textColor=C_MED_BLUE, alignment=TA_CENTER,
spaceBefore=10, spaceAfter=6)))
story.append(t)
story.append(sp(20))
story.append(Paragraph("Class 11 | JEE | A-Level | IGCSE | University General Chemistry",
sSmall))
story.append(PageBreak())
# ─── Section 1: Subatomic Particles ─────────────────────────────────────────
def section1(story):
story.append(SectionHeader(1, "Subatomic Particles & Atomic Definitions"))
story.append(sp(10))
story.append(Paragraph("1.1 The Three Fundamental Particles", sH2))
tdata = [
[Paragraph(h, sTableHead) for h in
["Particle", "Symbol", "Relative Mass", "Rel. Charge", "Location", "Discovered By"]],
["Proton", "p⁺", "1", "+1", "Nucleus", "Rutherford (1919)"],
["Neutron", "n⁰", "1", "0", "Nucleus", "Chadwick (1932)"],
["Electron", "e⁻", "1/1836", "−1", "Shells / Orbitals", "Thomson (1897)"],
]
cw = [85, 52, 85, 70, 110, 115]
story.append(make_table(tdata, cw))
story.append(sp(8))
story.append(Paragraph("1.2 Key Definitions", sH2))
defs = [
("<b>Atomic Number (Z)</b> — Number of protons in the nucleus. Uniquely identifies the element."),
("<b>Mass Number (A)</b> — Total protons + neutrons. Written as superscript before symbol (e.g., <super>12</super>C)."),
("<b>Number of Neutrons</b> = A − Z"),
("<b>Neutral atom:</b> protons = electrons. | <b>Cation:</b> lost electrons (positive). | <b>Anion:</b> gained electrons (negative)."),
("<b>Isotopes</b> — Same element, same Z, different A (different neutron count). Same chemical properties, different physical properties."),
("<b>Isoelectronic species</b> — Same number of electrons. E.g., Na<super>+</super>, Mg<super>2+</super>, Al<super>3+</super>, Ne all have 10 electrons."),
("<b>Relative Atomic Mass (Ar)</b> — Weighted average mass of all isotopes relative to 1/12 mass of C-12."),
]
for d in defs:
story.append(bullet(d))
story.append(sp(6))
story.append(Paragraph("Isotope Example — Chlorine:", sH3))
iso_data = [
[Paragraph(h, sTableHead) for h in ["Isotope", "Protons", "Neutrons", "Abundance"]],
["Cl-35 (³⁵Cl)", "17", "18", "75.77%"],
["Cl-37 (³⁷Cl)", "17", "20", "24.23%"],
]
story.append(make_table(iso_data, [110,80,80,90], header_bg=C_ACCENT2))
story.append(sp(4))
story.append(Paragraph("Ar(Cl) = (35 × 75.77 + 37 × 24.23) / 100 = 35.48", sFormula))
story.append(sp(6))
story.append(InfoBox(
"KEY FORMULA",
["A = Z + N (Mass number = Protons + Neutrons)",
"Neutrons (N) = A − Z",
"Ar = Σ (isotope mass × fractional abundance)"],
bg=C_YELLOW, border=C_ACCENT, label_color=C_ACCENT
))
story.append(sp(12))
# ─── Section 2: Atomic Models ────────────────────────────────────────────────
def section2(story):
story.append(SectionHeader(2, "Historical Atomic Models", C_PURPLE, colors.HexColor("#7B1FA2")))
story.append(sp(10))
models = [
("Dalton (1803)", C_GRAY_BG, C_GRAY, [
"Atoms are solid, indivisible spheres — like billiard balls.",
"All atoms of the same element are identical in mass and properties.",
"Compounds form by combining atoms in fixed whole-number ratios.",
"<b>Limitation:</b> Cannot explain subatomic particles, ions, or electrical effects.",
]),
("Thomson (1897) — Plum Pudding", C_PURPLE_BG, C_PURPLE, [
"Discovered the electron using cathode ray tube experiments.",
"Model: positively charged sphere with electrons embedded throughout (like plums in pudding).",
"Charge-to-mass ratio (e/m) of electron measured.",
"<b>Limitation:</b> Could not explain Rutherford's gold foil scattering results.",
]),
("Rutherford (1911) — Nuclear Model", C_ORANGE_BG, C_ORANGE, [
"<b>Gold Foil Experiment:</b> fired alpha particles at a thin gold sheet.",
"Most passed straight through → atom is mostly empty space.",
"Few deflected at large angles → tiny, dense, positively charged nucleus.",
"Very few bounced back (1 in 20,000) → nucleus contains most of the mass.",
"<b>Limitation:</b> Accelerating electrons should emit radiation and spiral into nucleus (unstable).",
]),
("Bohr (1913) — Planetary Model", C_GREEN_BG, C_GREEN, [
"Electrons orbit in fixed circular shells (stationary states) — do not radiate energy.",
"Each shell has a quantised energy level: E<sub>n</sub> = −13.6/n² eV (for hydrogen).",
"Electrons absorb energy → jump to higher level (excited state).",
"Electrons fall back → emit photon of energy <b>ΔE = hν</b>.",
"Explained hydrogen emission spectrum perfectly.",
"<b>Limitation:</b> Works only for H-like (one-electron) atoms; fails for multi-electron atoms.",
]),
("Quantum Mechanical Model (1926+)", C_LIGHT_BLUE, C_MED_BLUE, [
"Based on Schrödinger wave equation (ψ).",
"Electrons have wave-particle duality (de Broglie: λ = h/mv).",
"Heisenberg Uncertainty Principle: cannot know exact position AND momentum simultaneously.",
"Orbitals are <b>probability density clouds</b> — regions where e⁻ is most likely found.",
"Described by 4 quantum numbers: n, l, m<sub>l</sub>, m<sub>s</sub>.",
"This is the currently accepted model.",
]),
]
for name, bg, border, points in models:
story.append(Paragraph(name, sH2))
box_lines = []
for p in points:
# Render as paragraphs inside KeepTogether
story.append(bullet(p, sBullet if "<b>" not in p else sBulletBold))
story.append(sp(6))
story.append(hr(color=border, thickness=0.5))
story.append(sp(4))
story.append(InfoBox(
"MEMORY TIP — Model Progression",
["Dalton → Thomson → Rutherford → Bohr → Quantum Mechanical",
"Each model BUILT on the previous one's experimental evidence.",
"Key experiments: Cathode rays (Thomson), Gold foil (Rutherford), Hydrogen spectrum (Bohr)"],
bg=C_GREEN_BG, border=C_GREEN, label_color=C_GREEN
))
story.append(sp(12))
# ─── Section 3: Quantum Numbers ──────────────────────────────────────────────
def section3(story):
story.append(SectionHeader(3, "Quantum Numbers", C_ACCENT2, colors.HexColor("#00ACC1")))
story.append(sp(10))
story.append(Paragraph(
"Each electron in an atom is uniquely described by a set of four quantum numbers. "
"No two electrons can share the same four quantum numbers (Pauli Exclusion Principle).",
sBody))
story.append(sp(8))
qn_data = [
[Paragraph(h, sTableHead) for h in
["Quantum No.", "Symbol", "What it Describes", "Allowed Values", "Represents"]],
["Principal", "n", "Shell / energy level", "1, 2, 3, 4 ...", "Distance from nucleus"],
["Azimuthal (Angular)", "l", "Shape of orbital (subshell)", "0 to (n−1)", "l=0→s, 1→p, 2→d, 3→f"],
["Magnetic", "mₗ", "Orientation in space", "−l to +l", "# of orbitals = 2l+1"],
["Spin", "mₛ", "Electron spin direction", "+½ or −½", "↑ (spin up) or ↓ (spin down)"],
]
cw = [105, 50, 130, 90, 150]
story.append(make_table(qn_data, cw, header_bg=C_ACCENT2))
story.append(sp(10))
story.append(Paragraph("3.1 Subshell Labels and Orbital Counts", sH2))
sub_data = [
[Paragraph(h, sTableHead) for h in
["l value", "Subshell", "# Orbitals (2l+1)", "Max Electrons", "Shape"]],
["0", "s", "1", "2", "Sphere"],
["1", "p", "3", "6", "Dumbbell (3 orientations: px, py, pz)"],
["2", "d", "5", "10", "Double dumbbell / clover (5 orientations)"],
["3", "f", "7", "14", "Complex multi-lobed (7 orientations)"],
]
cw2 = [55, 65, 110, 95, 200]
story.append(make_table(sub_data, cw2, header_bg=C_MED_BLUE))
story.append(sp(8))
story.append(Paragraph("3.2 Shell Capacities", sH2))
shell_data = [
[Paragraph(h, sTableHead) for h in
["Shell (n)", "Subshells present", "# Orbitals (n²)", "Max e⁻ (2n²)"]],
["1", "1s", "1", "2"],
["2", "2s, 2p", "4", "8"],
["3", "3s, 3p, 3d", "9", "18"],
["4", "4s, 4p, 4d, 4f","16", "32"],
]
story.append(make_table(shell_data, [80, 130, 110, 100], header_bg=C_DARK_BLUE))
story.append(sp(8))
story.append(InfoBox(
"FORMULAS",
["Max electrons in shell n = 2n²",
"Number of orbitals in shell n = n²",
"Number of orbitals in subshell l = 2l + 1"],
bg=C_YELLOW, border=C_ACCENT, label_color=C_ACCENT
))
story.append(sp(12))
# ─── Section 4: Orbital Shapes & Energy Order ────────────────────────────────
def section4(story):
story.append(SectionHeader(4, "Orbital Shapes & Energy Ordering", C_MED_BLUE, C_DARK_BLUE))
story.append(sp(10))
story.append(Paragraph("4.1 Shapes of Orbitals", sH2))
orb_info = [
("<b>s orbitals</b>: Spherically symmetrical. One per shell. 1s is smallest; 2s is larger with a spherical node. Holds 2 electrons."),
("<b>p orbitals</b>: Dumbbell shaped (two lobes either side of nucleus). Three degenerate orbitals per shell (px, py, pz). Present from n=2. Holds 6 electrons."),
("<b>d orbitals</b>: More complex shapes — four have four-lobed cloverleaf pattern; one (dz²) has two lobes with a torus ring. Five degenerate orbitals. Present from n=3. Holds 10 electrons."),
("<b>f orbitals</b>: Very complex multi-lobed shapes. Seven degenerate orbitals. Present from n=4. Holds 14 electrons."),
("<b>Node</b>: A surface where probability of finding electron = 0. Number of radial nodes = n − l − 1. Angular nodes = l."),
]
for o in orb_info:
story.append(bullet(o))
story.append(sp(8))
story.append(Paragraph("4.2 Aufbau Energy Order (Fill Order)", sH2))
story.append(sBody and Paragraph(
"Orbitals are filled in order of increasing energy. Use the diagonal (n+l) rule — "
"lower (n+l) fills first; for equal (n+l), lower n fills first.", sBody))
story.append(sp(4))
energy_order = "1s → 2s → 2p → 3s → 3p → 4s → 3d → 4p → 5s → 4d → 5p → 6s → 4f → 5d → 6p"
story.append(Paragraph(energy_order, sFormula))
story.append(sp(6))
story.append(InfoBox(
"IMPORTANT EXCEPTIONS (Extra stability from half-filled / fully-filled d)",
["Cr (Z=24): expected [Ar] 3d⁴ 4s² → actual [Ar] 3d⁵ 4s¹ (half-filled d = extra stable)",
"Cu (Z=29): expected [Ar] 3d⁹ 4s² → actual [Ar] 3d¹⁰ 4s¹ (fully-filled d = extra stable)",
"Mo (Z=42), Ag (Z=47) follow similar patterns."],
bg=C_RED_BG, border=C_RED, label_color=C_RED
))
story.append(sp(12))
# ─── Section 5: Electronic Configuration ─────────────────────────────────────
def section5(story):
story.append(SectionHeader(5, "Electronic Configuration Rules", colors.HexColor("#004D40"), colors.HexColor("#00695C")))
story.append(sp(10))
rules = [
("Aufbau Principle",
"Electrons fill orbitals starting from the lowest available energy level upward.",
C_GREEN_BG, C_GREEN),
("Pauli Exclusion Principle",
"No two electrons in an atom can have identical sets of all four quantum numbers. "
"An orbital can hold a maximum of TWO electrons and they must have OPPOSITE spins (↑↓).",
C_PURPLE_BG, C_PURPLE),
("Hund's Rule of Maximum Multiplicity",
"Electrons occupy degenerate (equal-energy) orbitals SINGLY with parallel spins before pairing. "
"This minimises electron-electron repulsion and gives the most stable arrangement.",
C_ORANGE_BG, C_ORANGE),
]
for rname, rdesc, bg, col in rules:
rd = [[Paragraph(f"<b>{rname}</b>", S("rh", fontName="Helvetica-Bold", fontSize=10.5,
textColor=col, leading=15)),
Paragraph(rdesc, S("rb", fontName="Helvetica", fontSize=9.5,
textColor=colors.HexColor("#212121"), leading=14))]]
rt = Table(rd, colWidths=[130, PAGE_W - 2*MARGIN - 130])
rt.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("TOPPADDING", (0,0),(-1,-1), 8),
("BOTTOMPADDING",(0,0),(-1,-1), 8),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("ROUNDEDCORNERS", [5]),
("BOX", (0,0),(-1,-1), 1, col),
]))
story.append(rt)
story.append(sp(6))
story.append(sp(6))
story.append(Paragraph("5.1 Example Configurations", sH2))
ec_data = [
[Paragraph(h, sTableHead) for h in ["Element", "Z", "Full Configuration", "Noble Gas Notation"]],
["H", "1", "1s¹", "1s¹"],
["He", "2", "1s²", "1s²"],
["C", "6", "1s² 2s² 2p²", "[He] 2s² 2p²"],
["N", "7", "1s² 2s² 2p³", "[He] 2s² 2p³"],
["O", "8", "1s² 2s² 2p⁴", "[He] 2s² 2p⁴"],
["Na", "11", "1s² 2s² 2p⁶ 3s¹", "[Ne] 3s¹"],
["Cl", "17", "1s² 2s² 2p⁶ 3s² 3p⁵", "[Ne] 3s² 3p⁵"],
["Fe", "26", "1s² 2s² 2p⁶ 3s² 3p⁶ 4s² 3d⁶", "[Ar] 3d⁶ 4s²"],
["Cr", "24", "1s² 2s² 2p⁶ 3s² 3p⁶ 4s¹ 3d⁵", "[Ar] 3d⁵ 4s¹ ⚠ Exception"],
["Cu", "29", "1s² 2s² 2p⁶ 3s² 3p⁶ 4s¹ 3d¹⁰", "[Ar] 3d¹⁰ 4s¹ ⚠ Exception"],
]
story.append(make_table(ec_data, [45, 30, 190, 165], header_bg=colors.HexColor("#004D40")))
story.append(sp(8))
story.append(Paragraph("5.2 Ions — Writing Configuration", sH2))
ion_pts = [
"For <b>cations (positive)</b>: remove electrons from the outermost shell first. "
"For transition metals, remove from 4s BEFORE 3d. E.g., Fe²⁺: [Ar] 3d⁶ (4s² removed first)",
"For <b>anions (negative)</b>: add electrons to the next available orbital. "
"E.g., Cl⁻: [Ne] 3s² 3p⁶ (one electron added to 3p)",
]
for p in ion_pts:
story.append(bullet(p))
story.append(sp(12))
# ─── Section 6: Atomic Spectra ────────────────────────────────────────────────
def section6(story):
story.append(SectionHeader(6, "Atomic Spectra & Line Spectra", colors.HexColor("#BF360C"), colors.HexColor("#E64A19")))
story.append(sp(10))
story.append(Paragraph(
"When an electron absorbs energy it is promoted to a higher energy level (excited state). "
"When it falls back to a lower level, it emits energy as a photon. "
"This produces a <b>line emission spectrum</b> — a fingerprint unique to each element.", sBody))
story.append(sp(6))
story.append(Paragraph("6.1 Energy of a Photon", sH2))
formulas = [
"E = hν (h = Planck's constant = 6.626 × 10⁻³⁴ J·s, ν = frequency in Hz)",
"E = hc / λ (c = speed of light = 3.0 × 10⁸ m/s, λ = wavelength in m)",
"E = hcν̄ (ν̄ = wavenumber = 1/λ in cm⁻¹)",
"ΔE = E_higher − E_lower = Energy emitted or absorbed",
]
for f in formulas:
story.append(Paragraph(f, sFormula))
story.append(sp(8))
story.append(Paragraph("6.2 Bohr Model Energy Levels (Hydrogen)", sH2))
story.append(Paragraph("E_n = −13.6 / n² eV or E_n = −2.18 × 10⁻¹⁸ / n² J", sFormula))
story.append(Paragraph("The negative sign means energy is released relative to the ionised (free) electron at E = 0.", sBody))
story.append(sp(6))
story.append(Paragraph("6.3 Rydberg Equation (Hydrogen Spectral Lines)", sH2))
story.append(Paragraph("1/λ = R_H × (1/n₁² − 1/n₂²) where R_H = 1.097 × 10⁷ m⁻¹ (Rydberg constant)", sFormula))
story.append(Paragraph("n₁ = lower level (series), n₂ = upper level (n₂ > n₁)", sBody))
story.append(sp(8))
story.append(Paragraph("6.4 Spectral Series of Hydrogen", sH2))
spec_data = [
[Paragraph(h, sTableHead) for h in ["Series", "n₁ (lower level)", "n₂ (upper levels)", "Region", "Transitions"]],
["Lyman", "1", "2, 3, 4 ...", "Ultraviolet (UV)", "e⁻ falls to n=1"],
["Balmer", "2", "3, 4, 5 ...", "Visible + near UV", "e⁻ falls to n=2"],
["Paschen", "3", "4, 5, 6 ...", "Infrared (IR)", "e⁻ falls to n=3"],
["Brackett", "4", "5, 6, 7 ...", "Infrared", "e⁻ falls to n=4"],
["Pfund", "5", "6, 7, 8 ...", "Far Infrared", "e⁻ falls to n=5"],
]
story.append(make_table(spec_data, [65, 80, 95, 110, 100],
header_bg=colors.HexColor("#BF360C")))
story.append(sp(8))
story.append(InfoBox(
"KEY CONCEPT",
["Emission spectrum: bright coloured lines on dark background (electron FALLS = emits photon).",
"Absorption spectrum: dark lines on continuous spectrum (electron ABSORBS photon = rises to higher level).",
"Line series converge (get closer) as n increases, reaching the series limit at ionisation."],
bg=C_ORANGE_BG, border=C_ORANGE, label_color=C_ORANGE
))
story.append(sp(12))
# ─── Section 7: Ionisation Energy ────────────────────────────────────────────
def section7(story):
story.append(SectionHeader(7, "Ionisation Energy", C_MED_BLUE, C_DARK_BLUE))
story.append(sp(10))
story.append(Paragraph(
"The <b>First Ionisation Energy (IE₁)</b> is the minimum energy required to remove one mole of "
"electrons from one mole of gaseous atoms in their ground state:", sBody))
story.append(Paragraph("X(g) → X⁺(g) + e⁻ ΔH = +IE₁ (always endothermic)", sFormula))
story.append(sp(6))
story.append(Paragraph("7.1 Factors Affecting Ionisation Energy", sH2))
factors = [
("<b>Nuclear Charge (Z)</b>: More protons → stronger attraction to electrons → higher IE.",
"+"),
("<b>Atomic Radius</b>: Larger radius → electron further from nucleus → weaker attraction → lower IE.",
"−"),
("<b>Electron Shielding</b>: More inner shells → inner electrons repel outer electrons → weaker nuclear attraction → lower IE.",
"−"),
]
fdata = [[Paragraph(f, S("fb", fontName="Helvetica", fontSize=9.5,
textColor=C_BLACK, leading=14, alignment=TA_LEFT)),
Paragraph(effect, S("fe", fontName="Helvetica-Bold", fontSize=14,
textColor=C_GREEN if "+" in effect else C_RED,
alignment=TA_CENTER, leading=14))]
for f, effect in factors]
ft = Table(fdata, colWidths=[PAGE_W - 2*MARGIN - 40, 40])
ft.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0),(-1,-1), [C_LIGHT_BLUE, C_WHITE]),
("GRID", (0,0),(-1,-1), 0.5, colors.HexColor("#B0BEC5")),
("TOPPADDING", (0,0),(-1,-1), 7),
("BOTTOMPADDING", (0,0),(-1,-1), 7),
("LEFTPADDING", (0,0),(-1,-1), 8),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
]))
story.append(ft)
story.append(sp(8))
story.append(Paragraph("7.2 Trends in Ionisation Energy", sH2))
trend_pts = [
"<b>Across a period (left → right):</b> IE generally INCREASES — nuclear charge increases, same shielding, radius decreases.",
"<b>Down a group:</b> IE DECREASES — atomic radius increases, more electron shielding.",
]
for p in trend_pts:
story.append(bullet(p))
story.append(sp(6))
story.append(Paragraph("Period 2 Exceptions (must know!):", sH3))
exc_data = [
[Paragraph(h, sTableHead) for h in ["Exception", "Comparison", "Reason"]],
["Be > B", "IE(Be) > IE(B)", "B has a 2p electron (higher energy / easier to remove than Be's 2s)"],
["N > O", "IE(N) > IE(O)", "O has a paired 2p electron; e⁻-e⁻ repulsion makes it easier to remove"],
]
story.append(make_table(exc_data, [70, 100, 280], header_bg=C_RED))
story.append(sp(8))
story.append(Paragraph("7.3 Successive Ionisation Energies", sH2))
succ_pts = [
"IE values increase with each successive removal — harder to remove each subsequent electron from more positive ion.",
"A <b>large jump</b> in IE between two successive values indicates crossing from valence shell to inner shell.",
"Example Na (2,8,1): Large jump between IE₁ and IE₂ → confirms 1 outer (valence) electron → Group 1.",
"Example Mg (2,8,2): Large jump between IE₂ and IE₃ → 2 outer electrons → Group 2.",
]
for p in succ_pts:
story.append(bullet(p))
story.append(sp(12))
# ─── Section 8: Periodic Trends ───────────────────────────────────────────────
def section8(story):
story.append(SectionHeader(8, "Periodic Trends from Atomic Structure", colors.HexColor("#1B5E20"), colors.HexColor("#2E7D32")))
story.append(sp(10))
pt_data = [
[Paragraph(h, sTableHead) for h in
["Property", "Across Period →", "Down Group ↓", "Reason"]],
["Atomic Radius", "Decreases", "Increases",
"More protons pull e⁻ inward (period) / more shells added (group)"],
["Ionic Radius", "Cations < Atoms", "Increases",
"Same trend as atomic radius"],
["IE₁", "Increases (±)", "Decreases",
"Nuclear charge vs shielding & radius"],
["Electron Affinity", "Generally increases","Decreases",
"Ease of accepting extra electron"],
["Electronegativity", "Increases", "Decreases",
"Ability to attract bonding electrons"],
["Nuclear Charge (Z)", "Increases", "Increases",
"More protons across & down"],
["Electron Shielding", "Roughly constant", "Increases",
"More inner shells added going down"],
["Metallic Character", "Decreases", "Increases",
"Ease of losing electrons"],
]
story.append(make_table(pt_data,
[110, 100, 90, 220],
header_bg=colors.HexColor("#1B5E20")))
story.append(sp(10))
story.append(InfoBox(
"ELECTRONEGATIVITY NOTE",
["Most electronegative element: F (fluorine) — top right of periodic table.",
"Least electronegative (most electropositive): Cs (caesium) — bottom left.",
"Noble gases excluded from electronegativity scale (no tendency to attract)."],
bg=C_GREEN_BG, border=C_GREEN, label_color=C_GREEN
))
story.append(sp(12))
# ─── Section 9: Key Formulas Summary ──────────────────────────────────────────
def section9(story):
story.append(SectionHeader(9, "Master Formula Sheet", C_DARK_BLUE, C_MED_BLUE))
story.append(sp(10))
formula_data = [
[Paragraph(h, sTableHead) for h in
["Formula", "Symbol Meanings", "Used For"]],
["A = Z + N",
"A=mass no., Z=protons, N=neutrons",
"Finding number of neutrons"],
["E = hν",
"h=6.626×10⁻³⁴ J·s, ν=frequency (Hz)",
"Energy of a photon"],
["E = hc/λ",
"c=3×10⁸ m/s, λ=wavelength (m)",
"Energy from wavelength"],
["ΔE = E₂ − E₁ = hν",
"Energy difference between levels",
"Spectral line energy"],
["Eₙ = −13.6/n² eV",
"n = principal quantum number",
"Bohr model (H atom)"],
["1/λ = R(1/n₁² − 1/n₂²)",
"R=1.097×10⁷ m⁻¹, n₁<n₂",
"Hydrogen spectral lines"],
["Max e⁻ per shell = 2n²",
"n = shell number",
"Shell capacity"],
["Orbitals per shell = n²",
"n = shell number",
"Total orbital count"],
["Orbitals per subshell = 2l+1",
"l = azimuthal quantum number",
"Subshell orbital count"],
["λ = h/mv",
"m=mass, v=velocity (de Broglie)",
"Wave nature of electron"],
["Δx·Δp ≥ h/4π",
"Δx=position uncertainty, Δp=momentum uncertainty",
"Heisenberg Uncertainty"],
["Ar = Σ(mass × abundance)/100",
"abundance in %",
"Relative atomic mass"],
]
story.append(make_table(formula_data, [140, 160, 150], header_bg=C_DARK_BLUE))
story.append(sp(12))
# ─── Section 10: Practice Questions ──────────────────────────────────────────
def section10(story):
story.append(SectionHeader(10, "Practice Questions & Answers", C_ACCENT, colors.HexColor("#F57F17")))
story.append(sp(10))
qa_pairs = [
("Q1. How many protons, neutrons and electrons does ⁵⁶Fe have?",
"Fe (Z=26), A=56. Protons = 26, Neutrons = 56−26 = 30, Electrons = 26 (neutral atom)."),
("Q2. Write the full electronic configuration of Cr (Z=24).",
"[Ar] 3d⁵ 4s¹ (exception — half-filled d is extra stable vs [Ar] 3d⁴ 4s²)"),
("Q3. A photon has wavelength 486 nm. Find its energy. (h=6.626×10⁻³⁴, c=3×10⁸)",
"E = hc/λ = (6.626×10⁻³⁴ × 3×10⁸) / (486×10⁻⁹) = 4.09 × 10⁻¹⁹ J"),
("Q4. Why is IE(B) < IE(Be) even though B has more protons?",
"B's outermost electron is in a 2p orbital (higher energy than 2s in Be). 2p electrons are slightly further from nucleus and easier to remove."),
("Q5. Identify the element with successive IEs: 578, 1817, 2745, 11578 kJ/mol.",
"Large jump between 3rd and 4th IE → 3 outer electrons → Group 3 → Aluminium (Al)."),
("Q6. What are the four quantum numbers for the last electron in Cl (Z=17)?",
"Config: [Ne] 3s² 3p⁵. Last e⁻ in 3p: n=3, l=1, mₗ = −1 (or 0 or +1), mₛ = −½"),
("Q7. Which series of H spectrum lines fall in the visible region?",
"Balmer series (transitions to n=2). Visible range: 400−700 nm."),
("Q8. A sodium atom emits yellow light at 589 nm. Calculate frequency.",
"ν = c/λ = 3×10⁸ / 589×10⁻⁹ = 5.09 × 10¹⁴ Hz"),
]
for i, (q, a) in enumerate(qa_pairs):
q_data = [[Paragraph(q, S("qs", fontName="Helvetica-Bold", fontSize=9.5,
textColor=C_DARK_BLUE, leading=14, alignment=TA_LEFT))]]
a_data = [[Paragraph(f"✓ {a}", S("as", fontName="Helvetica", fontSize=9.5,
textColor=C_GREEN, leading=14, alignment=TA_LEFT))]]
qa_table = Table(q_data + a_data,
colWidths=[PAGE_W - 2*MARGIN])
qa_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), C_LIGHT_BLUE),
("BACKGROUND", (0,1), (-1,1), C_GREEN_BG),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4]),
("BOX", (0,0), (-1,-1), 0.8, C_MED_BLUE),
]))
story.append(KeepTogether([qa_table, sp(6)]))
story.append(sp(6))
# ─── Section 11: Quick Revision Checklist ─────────────────────────────────────
def section11(story):
story.append(SectionHeader(11, "Quick Revision Checklist", C_ACCENT2, colors.HexColor("#006064")))
story.append(sp(10))
items = [
"I can state the charge, mass and location of protons, neutrons and electrons.",
"I can calculate protons, neutrons and electrons from atomic/mass numbers.",
"I can define isotopes and calculate relative atomic mass.",
"I can describe Dalton, Thomson, Rutherford and Bohr models with limitations.",
"I can explain Rutherford's gold foil experiment and its conclusions.",
"I can state and apply all four quantum numbers.",
"I know the shapes of s, p, d, f orbitals.",
"I can write electron configurations using Aufbau, Pauli and Hund's rules.",
"I know the exceptions Cr and Cu and can explain them.",
"I can calculate energy of photons using E=hν and E=hc/λ.",
"I know the hydrogen spectral series and their regions.",
"I can use the Rydberg equation to find wavelengths.",
"I can explain factors affecting ionisation energy.",
"I can identify group number from successive IE data.",
"I know periodic trends in atomic radius, IE, electronegativity.",
"I can write configurations for ions (cations and anions).",
]
col1 = items[:8]
col2 = items[8:]
col_w = (PAGE_W - 2*MARGIN - 10) / 2
rows = max(len(col1), len(col2))
check_data = []
for i in range(rows):
c1 = Paragraph(f"☐ {col1[i]}" if i < len(col1) else "",
S("ck", fontName="Helvetica", fontSize=8.8,
textColor=C_BLACK, leading=14, alignment=TA_LEFT))
c2 = Paragraph(f"☐ {col2[i]}" if i < len(col2) else "",
S("ck2", fontName="Helvetica", fontSize=8.8,
textColor=C_BLACK, leading=14, alignment=TA_LEFT))
check_data.append([c1, c2])
ct = Table(check_data, colWidths=[col_w, col_w], spaceBefore=0, spaceAfter=0)
ct.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0),(-1,-1), [C_LIGHT_BLUE, C_WHITE]),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING", (0,0),(-1,-1), 5),
("LEFTPADDING", (0,0),(-1,-1), 8),
("RIGHTPADDING", (0,0),(-1,-1), 8),
("GRID", (0,0),(-1,-1), 0.3, colors.HexColor("#CFD8DC")),
]))
story.append(ct)
story.append(sp(14))
story.append(Paragraph(
"Study Guide compiled for Class 11 | JEE | A-Level | IGCSE | University Chemistry",
sSmall))
story.append(sp(4))
story.append(HRFlowable(width="100%", thickness=2, color=C_DARK_BLUE,
spaceAfter=4, spaceBefore=4))
story.append(Paragraph("⚛ Atomic Structure — Comprehensive Study Guide | All rights reserved",
sSmall))
# ─── Page numbering ───────────────────────────────────────────────────────────
def on_first_page(canvas, doc):
canvas.saveState()
canvas.restoreState()
def on_later_pages(canvas, doc):
canvas.saveState()
canvas.setFont("Helvetica", 8)
canvas.setFillColor(C_GRAY)
canvas.drawCentredString(PAGE_W/2, 18, f"Atomic Structure Study Guide | Page {doc.page}")
canvas.setStrokeColor(C_MED_BLUE)
canvas.setLineWidth(0.5)
canvas.line(MARGIN, 25, PAGE_W - MARGIN, 25)
canvas.restoreState()
# ─── Main build ───────────────────────────────────────────────────────────────
def build_pdf():
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=MARGIN,
rightMargin=MARGIN,
topMargin=MARGIN,
bottomMargin=1.8 * cm,
title="Atomic Structure - Comprehensive Study Guide",
author="Orris AI",
subject="Chemistry",
)
story = []
cover_page(story)
section1(story)
story.append(PageBreak())
section2(story)
story.append(PageBreak())
section3(story)
story.append(PageBreak())
section4(story)
section5(story)
story.append(PageBreak())
section6(story)
story.append(PageBreak())
section7(story)
story.append(PageBreak())
section8(story)
section9(story)
story.append(PageBreak())
section10(story)
story.append(PageBreak())
section11(story)
doc.build(story,
onFirstPage=on_first_page,
onLaterPages=on_later_pages)
print(f"PDF created: {OUTPUT}")
if __name__ == "__main__":
build_pdf()
cd /tmp/workspace/atomic-structure-guide && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/atomic-structure-guide/
| # | Section | Highlights |
|---|---|---|
| 1 | Subatomic Particles | Particle table, key definitions, isotope example, Ar calculation |
| 2 | Historical Atomic Models | All 5 models (Dalton → Quantum), evidence & limitations |
| 3 | Quantum Numbers | All 4 quantum numbers, subshell table, shell capacities |
| 4 | Orbital Shapes & Energy Order | s/p/d/f shapes, Aufbau order, Cr & Cu exceptions |
| 5 | Electronic Configuration Rules | Aufbau, Pauli, Hund's (with color-coded rule boxes + examples) |
| 6 | Atomic Spectra | Energy formulas, Bohr model, Rydberg equation, all 5 H series |
| 7 | Ionisation Energy | Factors, period/group trends, Period 2 exceptions, successive IEs |
| 8 | Periodic Trends | Full trends table (all key properties) |
| 9 | Master Formula Sheet | Every formula in one place |
| 10 | Practice Q&A | 8 worked exam-style questions with answers |
| 11 | Quick Revision Checklist | 16-point self-check list |
Atomic Structure Study Guide
PDF Document · PDF