Periodic table for neet notes

Asking for Preferences
Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not found"

Running Command

mkdir -p /home/daytona/workspace/neet-periodic-table && echo "Directory created"

Writing File

~/neet-periodic-table/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 cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import Flowable

OUTPUT = "/home/daytona/workspace/neet-periodic-table/Periodic_Table_NEET_Notes.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1A237E")
MID_BLUE    = colors.HexColor("#1565C0")
LIGHT_BLUE  = colors.HexColor("#E3F2FD")
ACCENT      = colors.HexColor("#0288D1")
YELLOW      = colors.HexColor("#FFF9C4")
GREEN_BG    = colors.HexColor("#E8F5E9")
ORANGE_BG   = colors.HexColor("#FFF3E0")
PINK_BG     = colors.HexColor("#FCE4EC")
PURPLE_BG   = colors.HexColor("#EDE7F6")
RED_ACCENT  = colors.HexColor("#C62828")
GREEN_ACC   = colors.HexColor("#2E7D32")
ORANGE_ACC  = colors.HexColor("#E65100")
WHITE       = colors.white
GREY_BG     = colors.HexColor("#F5F5F5")
DARK_GREY   = colors.HexColor("#424242")

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

TITLE_STYLE = S("Title",
    fontSize=26, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_CENTER, spaceAfter=4)

SUBTITLE_STYLE = S("Sub",
    fontSize=13, fontName="Helvetica",
    textColor=colors.HexColor("#B3E5FC"), alignment=TA_CENTER, spaceAfter=2)

H1 = S("H1",
    fontSize=13, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_LEFT, spaceAfter=0, leading=16)

H2 = S("H2",
    fontSize=11, fontName="Helvetica-Bold",
    textColor=DARK_BLUE, alignment=TA_LEFT, spaceAfter=2, leading=14)

BODY = S("Body",
    fontSize=9.5, fontName="Helvetica",
    textColor=DARK_GREY, alignment=TA_LEFT, leading=14, spaceAfter=2)

BODY_BOLD = S("BodyBold",
    fontSize=9.5, fontName="Helvetica-Bold",
    textColor=DARK_GREY, alignment=TA_LEFT, leading=14)

SMALL = S("Small",
    fontSize=8.5, fontName="Helvetica",
    textColor=DARK_GREY, leading=12, spaceAfter=1)

BULLET = S("Bullet",
    fontSize=9.5, fontName="Helvetica",
    textColor=DARK_GREY, leading=13,
    leftIndent=14, firstLineIndent=-10, spaceAfter=1)

CAPTION = S("Cap",
    fontSize=8, fontName="Helvetica-Oblique",
    textColor=colors.HexColor("#757575"), alignment=TA_CENTER)

WARN = S("Warn",
    fontSize=9.5, fontName="Helvetica-Bold",
    textColor=RED_ACCENT, leading=13, leftIndent=14, firstLineIndent=-10)

# ── Helpers ──────────────────────────────────────────────────────────────────
def bullet(text, style=BULLET, marker="•"):
    return Paragraph(f"<b>{marker}</b>  {text}", style)

def warn(text):
    return Paragraph(f"⚠  {text}", WARN)

def section_header(title, bg=MID_BLUE):
    data = [[Paragraph(title, H1)]]
    t = Table(data, colWidths=[17.5*cm])
    t.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 t

def info_box(content_rows, bg=LIGHT_BLUE, col_widths=None):
    if col_widths is None:
        col_widths = [17.5*cm]
    t = Table(content_rows, colWidths=col_widths)
    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), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#B0BEC5")),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    return t

# ── Document setup ────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=1.8*cm, rightMargin=1.8*cm,
    topMargin=1.5*cm,  bottomMargin=1.8*cm,
    title="Periodic Table – NEET Quick Revision",
    author="Orris Study Notes"
)

story = []
W = 17.5*cm  # usable width

# ══════════════════════════════════════════════════════════════════════════════
# COVER / HEADER BLOCK
# ══════════════════════════════════════════════════════════════════════════════
cover_data = [[
    Paragraph("PERIODIC TABLE", TITLE_STYLE),
], [
    Paragraph("NEET Quick Revision Notes  |  Chemistry – Class 11", SUBTITLE_STYLE),
], [
    Paragraph("Chapter 3 – NCERT  •  Trends, Exceptions & PYQ Patterns", CAPTION),
]]
cover_t = Table(cover_data, colWidths=[W])
cover_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), DARK_BLUE),
    ("TOPPADDING",    (0,0), (-1,-1), 10),
    ("BOTTOMPADDING", (0,0), (-1,-1), 10),
    ("LEFTPADDING",   (0,0), (-1,-1), 12),
    ("ROUNDEDCORNERS", [6,6,6,6]),
]))
story.append(cover_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 1. BASICS AT A GLANCE
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("1.  BASICS AT A GLANCE"))
story.append(Spacer(1, 4))

basics = [
    ["<b>Total elements</b>", "118  (7 periods, 18 groups)"],
    ["<b>Periods</b>", "Horizontal rows (1–7); elements arranged by increasing atomic number"],
    ["<b>Groups</b>", "Vertical columns (1–18);  similar chemical properties"],
    ["<b>Blocks</b>", "s-block (Gr 1–2),  p-block (Gr 13–18),  d-block (Gr 3–12),  f-block"],
    ["<b>Dobereiner's Triads</b>", "Middle element's at. wt ≈ avg of 1st & 3rd  (e.g. Li–Na–K)"],
    ["<b>Newlands' Octaves</b>", "8th element repeats properties of 1st (failed after Ca)"],
    ["<b>Mendeleev's Table</b>", "Arranged by at. wt; predicted Eka-B (Sc), Eka-Al (Ga), Eka-Si (Ge)"],
    ["<b>Modern Periodic Law</b>", "Properties are periodic function of <b>atomic number</b> (Moseley, 1913)"],
]
basic_rows = [
    [Paragraph(r[0], BODY_BOLD), Paragraph(r[1], BODY)]
    for r in basics
]
bt = Table(basic_rows, colWidths=[4.5*cm, 13*cm])
bt.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_BLUE),
    ("BACKGROUND",    (0,0), (0,-1), colors.HexColor("#BBDEFB")),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#90CAF9")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [LIGHT_BLUE, WHITE]),
]))
story.append(bt)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 2. PERIODS OVERVIEW TABLE
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2.  PERIODS OVERVIEW"))
story.append(Spacer(1, 4))

period_headers = [
    Paragraph("<b>Period</b>", BODY_BOLD),
    Paragraph("<b>Elements</b>", BODY_BOLD),
    Paragraph("<b>Shell filling</b>", BODY_BOLD),
    Paragraph("<b>Key note</b>", BODY_BOLD),
]
period_rows = [
    ["1", "H, He  (2)", "1s", "Shortest period"],
    ["2", "Li → Ne  (8)", "2s, 2p", "Short period – first ionisation energy & EN highest at Ne/F"],
    ["3", "Na → Ar  (8)", "3s, 3p", "Short period; Cl most electronegative non-metal"],
    ["4", "K → Kr  (18)", "4s, 3d, 4p", "Long period; first d-block (Sc-Zn); Cr & Cu exceptions"],
    ["5", "Rb → Xe  (18)", "5s, 4d, 5p", "Long period; Pd exception (4d¹⁰ 5s⁰)"],
    ["6", "Cs → Rn  (32)", "6s, 4f, 5d, 6p", "Longest typical period; includes 4f lanthanoids"],
    ["7", "Fr → Og  (32)", "7s, 5f, 6d, 7p", "Incomplete; includes actinoids; all radioactive from Z=84+"],
]
pt_data = [period_headers] + [
    [Paragraph(r[0], BODY), Paragraph(r[1], BODY), Paragraph(r[2], SMALL), Paragraph(r[3], SMALL)]
    for r in period_rows
]
pt = Table(pt_data, colWidths=[1.2*cm, 3.8*cm, 3.2*cm, 9.3*cm])
pt.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), MID_BLUE),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#90CAF9")),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("ALIGN",         (0,0), (0,-1), "CENTER"),
]))
story.append(pt)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 3. PERIODIC TRENDS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("3.  PERIODIC TRENDS  (Most Tested in NEET)"))
story.append(Spacer(1, 4))

trends_header = [
    Paragraph("<b>Property</b>", BODY_BOLD),
    Paragraph("<b>Across period (→)</b>", BODY_BOLD),
    Paragraph("<b>Down group (↓)</b>", BODY_BOLD),
    Paragraph("<b>Key exception / note</b>", BODY_BOLD),
]
trends_data = [
    ["Atomic radius", "Decreases  ↘", "Increases  ↗", "Noble gas radius > halogen in same period (vdW vs covalent)"],
    ["Ionic radius", "Cation < atom < Anion", "Increases  ↗", "Isoelectronic: more protons → smaller (e.g. N³⁻ > O²⁻ > F⁻ > Na⁺)"],
    ["Ionisation enthalpy (IE₁)", "Increases  ↗", "Decreases  ↘", "BE > B; N > O; Mg > Al  (half-filled & full-filled stability)"],
    ["Electron gain enthalpy", "More –ve  (increases)", "Less –ve  (decreases)", "F less –ve than Cl (small size → more e⁻ repulsion); noble gases +ve"],
    ["Electronegativity (EN)", "Increases  ↗", "Decreases  ↘", "F highest (3.98); Cs lowest (0.79); noble gases not assigned"],
    ["Valency", "1→4 then 4→0 (period 2/3)", "Generally same in group", "Variable valency in d-block; Group 15: +3, +5"],
    ["Metallic character", "Decreases  ↘", "Increases  ↗", "Diagonal relationship: Li/Mg; Be/Al; B/Si"],
    ["Oxidising power", "Increases  ↗", "Decreases  ↘", "F₂ strongest oxidising agent (not because of EN alone)"],
]
trows = [trends_header] + [
    [Paragraph(r[0], BODY_BOLD), Paragraph(r[1], SMALL), Paragraph(r[2], SMALL), Paragraph(r[3], SMALL)]
    for r in trends_data
]
tt = Table(trows, colWidths=[3.8*cm, 3.4*cm, 3.3*cm, 7*cm])
tt.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), DARK_BLUE),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#B0BEC5")),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(tt)
story.append(Spacer(1, 4))

story.append(warn("IE₁ dip: Be > B  because 2p electron is easier to remove than 2s."))
story.append(warn("IE₁ dip: N > O  because O has paired electron in 2p; easier to remove."))
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 4. ELECTRONIC CONFIGURATION & BLOCKS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4.  BLOCKS & ELECTRONIC CONFIG"))
story.append(Spacer(1, 4))

block_data = [
    [Paragraph("<b>Block</b>", BODY_BOLD), Paragraph("<b>Groups</b>", BODY_BOLD),
     Paragraph("<b>Last e⁻ enters</b>", BODY_BOLD), Paragraph("<b>Nature</b>", BODY_BOLD)],
    [Paragraph("s", BODY), Paragraph("1, 2", BODY), Paragraph("s-orbital", BODY), Paragraph("Metals (H, He exceptions)", BODY)],
    [Paragraph("p", BODY), Paragraph("13–18", BODY), Paragraph("p-orbital", BODY), Paragraph("Non-metals, metalloids, noble gases", BODY)],
    [Paragraph("d", BODY), Paragraph("3–12", BODY), Paragraph("d-orbital", BODY), Paragraph("Transition metals; variable valency", BODY)],
    [Paragraph("f", BODY), Paragraph("—", BODY), Paragraph("f-orbital", BODY), Paragraph("Lanthanoids (4f) & Actinoids (5f); inner transition", BODY)],
]
bt2 = Table(block_data, colWidths=[1.5*cm, 2.5*cm, 3.5*cm, 10*cm])
bt2.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), ACCENT),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("BACKGROUND",    (0,1), (0,1), colors.HexColor("#C5CAE9")),
    ("BACKGROUND",    (0,2), (0,2), colors.HexColor("#B2EBF2")),
    ("BACKGROUND",    (0,3), (0,3), colors.HexColor("#F8BBD0")),
    ("BACKGROUND",    (0,4), (0,4), colors.HexColor("#DCEDC8")),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(bt2)
story.append(Spacer(1, 5))

story.append(Paragraph("<b>Important electronic config exceptions (d-block):</b>", H2))
exc_rows = [
    [Paragraph("<b>Element</b>", BODY_BOLD), Paragraph("<b>Expected</b>", BODY_BOLD), Paragraph("<b>Actual</b>", BODY_BOLD), Paragraph("<b>Reason</b>", BODY_BOLD)],
    [Paragraph("Cr  (Z=24)", BODY), Paragraph("[Ar] 3d⁴ 4s²", BODY), Paragraph("<b>[Ar] 3d⁵ 4s¹</b>", BODY_BOLD), Paragraph("Half-filled 3d⁵ extra stability", BODY)],
    [Paragraph("Cu  (Z=29)", BODY), Paragraph("[Ar] 3d⁹ 4s²", BODY), Paragraph("<b>[Ar] 3d¹⁰ 4s¹</b>", BODY_BOLD), Paragraph("Fully-filled 3d¹⁰ extra stability", BODY)],
    [Paragraph("Mo  (Z=42)", BODY), Paragraph("[Kr] 4d⁴ 5s²", BODY), Paragraph("<b>[Kr] 4d⁵ 5s¹</b>", BODY_BOLD), Paragraph("Same as Cr pattern", BODY)],
    [Paragraph("Pd  (Z=46)", BODY), Paragraph("[Kr] 4d⁸ 5s²", BODY), Paragraph("<b>[Kr] 4d¹⁰ 5s⁰</b>", BODY_BOLD), Paragraph("Fully-filled 4d; no 5s electron", BODY)],
]
et = Table(exc_rows, colWidths=[3*cm, 3.8*cm, 3.8*cm, 6.9*cm])
et.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), colors.HexColor("#880E4F")),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [PINK_BG, WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#F48FB1")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(et)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# PAGE BREAK
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════════════════
# 5. ATOMIC & IONIC RADII – ISOELECTRONIC SERIES
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5.  ATOMIC RADIUS & ISOELECTRONIC SERIES", bg=colors.HexColor("#1B5E20")))
story.append(Spacer(1, 4))

story.append(Paragraph("<b>Isoelectronic species</b> – same number of electrons, order by Z (more protons → smaller):", H2))
iso = [
    [Paragraph("<b>Series (10 e⁻)</b>", BODY_BOLD), Paragraph("N³⁻  >  O²⁻  >  F⁻  >  Ne  >  Na⁺  >  Mg²⁺  >  Al³⁺", BODY)],
    [Paragraph("<b>Series (18 e⁻)</b>", BODY_BOLD), Paragraph("S²⁻  >  Cl⁻  >  Ar  >  K⁺  >  Ca²⁺  >  Sc³⁺", BODY)],
]
iso_t = Table(iso, colWidths=[4*cm, 13.5*cm])
iso_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), GREEN_BG),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#A5D6A7")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 7),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(iso_t)
story.append(Spacer(1, 5))

story.append(Paragraph("<b>Periodic radius trend (pm) — Period 3:</b>  Na(186) > Mg(160) > Al(143) > Si(117) > P(110) > S(104) > Cl(99)", BODY))
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 6. IONISATION ENTHALPY  (IE)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("6.  IONISATION ENTHALPY  (IE)", bg=colors.HexColor("#4A148C")))
story.append(Spacer(1, 4))

ie_points = [
    ("General trend", "IE₁ increases across a period (↗) and decreases down a group (↘)"),
    ("Largest IE₁", "He (2372 kJ/mol) — smallest atom, full shell"),
    ("Lowest IE₁", "Cs (375 kJ/mol) — largest atom, single valence e⁻"),
    ("2nd period anomaly", "IE₁: Li < B < Be < C < O < N < F < Ne  — note Be > B and N > O"),
    ("Successive IE jumps", "Large jump in successive IE signals the group number (no. of valence e⁻)"),
    ("Al vs Mg", "IE₁ Al (577) < Mg (738): 3p¹ easier to lose than 3s²"),
    ("O vs N", "IE₁ O (1314) < N (1402): O has paired 2p electron, repulsion lowers IE"),
]
ie_rows = [[Paragraph(f"<b>{p[0]}</b>", BODY_BOLD), Paragraph(p[1], BODY)] for p in ie_points]
ie_t = Table(ie_rows, colWidths=[4*cm, 13.5*cm])
ie_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), PURPLE_BG),
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [PURPLE_BG, WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#CE93D8")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 7),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(ie_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 7. ELECTRON GAIN ENTHALPY  &  ELECTRONEGATIVITY
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("7.  ELECTRON GAIN ENTHALPY  &  ELECTRONEGATIVITY", bg=ORANGE_ACC))
story.append(Spacer(1, 4))

left_col = [
    Paragraph("<b>Electron Gain Enthalpy (EGE)</b>", H2),
    bullet("More –ve across period (more tendency to gain e⁻)"),
    bullet("Less –ve down group"),
    bullet("Cl has most –ve EGE (–349 kJ/mol), <i>not</i> F"),
    bullet("F: –328 kJ/mol (smaller, more e⁻–e⁻ repulsion in compact 2p shell)"),
    bullet("Noble gases: positive EGE (stable full shell)"),
    bullet("N, Be, Mg: positive or nearly zero EGE (half/full-filled stability)"),
    Spacer(1, 4),
    Paragraph("<b>Order:</b>  Cl > F > Br > I  (EGE, most –ve)", BODY),
]
right_col = [
    Paragraph("<b>Electronegativity (Pauling scale)</b>", H2),
    bullet("Increases across period (↗);  decreases down group (↘)"),
    bullet("F = 3.98  (highest of all elements)"),
    bullet("Cs = 0.79  (lowest)"),
    bullet("Same period: EN of noble gas not defined"),
    bullet("If ΔEN > 1.7 → ionic bond;  0.4–1.7 → polar covalent;  < 0.4 → non-polar"),
    bullet("EN used to predict bond polarity and oxidation states"),
    Spacer(1, 4),
    Paragraph("<b>Diagonal relationship</b>:  Li≈Mg, Be≈Al, B≈Si in EN & chemistry", BODY),
]
two_col = Table([[left_col, right_col]], colWidths=[8.5*cm, 9*cm])
two_col.setStyle(TableStyle([
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
]))
story.append(two_col)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 8. METALS / NON-METALS / METALLOIDS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("8.  METALS, NON-METALS & METALLOIDS"))
story.append(Spacer(1, 4))

mnm_data = [
    [Paragraph("<b>Metals (~80 elements)</b>", BODY_BOLD), Paragraph("<b>Non-metals (22)</b>", BODY_BOLD), Paragraph("<b>Metalloids (7)</b>", BODY_BOLD)],
    [
        Paragraph("s, d, f-block + Ga, In, Tl, Sn, Pb, Bi\nLow IE, Low EN\nLustre, malleable, ductile, conductors\nForm basic oxides & cations", SMALL),
        Paragraph("p-block (mostly)\nH, C, N, O, F, P, S, Cl, Se, Br, I, At\nHigh IE, High EN\nForm acidic oxides & anions", SMALL),
        Paragraph("B, Si, Ge, As, Sb, Te, Po\nProperties intermediate\nSemiconductors\nFound along staircase line", SMALL),
    ]
]
mnm_t = Table(mnm_data, colWidths=[6*cm, 5.8*cm, 5.7*cm])
mnm_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (0,0), colors.HexColor("#1565C0")),
    ("BACKGROUND",    (0,0), (1,0), colors.HexColor("#2E7D32")),
    ("BACKGROUND",    (0,0), (2,0), colors.HexColor("#E65100")),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("BACKGROUND",    (0,1), (0,1), colors.HexColor("#E3F2FD")),
    ("BACKGROUND",    (1,1), (1,1), GREEN_BG),
    ("BACKGROUND",    (2,1), (2,1), ORANGE_BG),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(mnm_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# PAGE BREAK
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════════════════
# 9. OXIDES & HYDROXIDES NATURE
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("9.  NATURE OF OXIDES & HYDROXIDES", bg=colors.HexColor("#B71C1C")))
story.append(Spacer(1, 4))

ox_data = [
    [Paragraph("<b>Across period (left → right)</b>", BODY_BOLD),
     Paragraph("Basic  →  Amphoteric  →  Acidic", BODY),
     Paragraph("Na₂O (basic), Al₂O₃ (amphoteric), P₄O₁₀ / SO₃ / Cl₂O₇ (acidic)", SMALL)],
    [Paragraph("<b>Down group</b>", BODY_BOLD),
     Paragraph("Metallic character ↑, so oxides become more basic", BODY),
     Paragraph("Bi₂O₃ more basic than N₂O₃", SMALL)],
    [Paragraph("<b>Amphoteric oxides</b>", BODY_BOLD),
     Paragraph("Al₂O₃, ZnO, PbO, SnO, Cr₂O₃, BeO", BODY),
     Paragraph("React with both acid and base", SMALL)],
    [Paragraph("<b>Neutral oxides</b>", BODY_BOLD),
     Paragraph("CO, NO, N₂O, H₂O", BODY),
     Paragraph("Neither acidic nor basic", SMALL)],
]
ox_t = Table(ox_data, colWidths=[4.5*cm, 6.5*cm, 6.5*cm])
ox_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), colors.HexColor("#FFEBEE")),
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [colors.HexColor("#FFEBEE"), WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#EF9A9A")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(ox_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 10. IMPORTANT ELEMENT FACTS FOR NEET
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("10.  IMPORTANT ELEMENT FACTS  (NEET PYQ Favourites)"))
story.append(Spacer(1, 4))

facts = [
    ("Hydrogen", "Unique; placed in Gr 1 but not an alkali metal. Can lose (H⁺) or gain (H⁻) 1 e⁻."),
    ("Helium", "Placed in Group 18 (noble) despite 1s² config; second lightest, used in balloons."),
    ("Fluorine", "Most electronegative (3.98); most reactive non-metal; only –1 oxidation state."),
    ("Chlorine", "Highest electron affinity; used as bleaching & disinfecting agent."),
    ("Noble gases", "Zero electron affinity (approx.); ionisation enthalpy highest in their period."),
    ("Lanthanoid contraction", "Steady decrease in atomic radius across 4f series; causes Zr≈Hf radii."),
    ("Group 13 anomaly", "Al is more metallic than B; B is metalloid; Tl shows +1 stable state."),
    ("Diagonal relationship", "Li/Mg, Be/Al, B/Si share properties (similar charge-to-radius ratios)."),
    ("Alkali metals (Gr 1)", "Soft, low density; react with water; Li most +ve reduction potential."),
    ("Alkaline earths (Gr 2)", "Be and Mg do NOT form hydroxides as easily; BeO is amphoteric."),
    ("Group 15 oxoacids", "HNO₃ (N, +5); H₃PO₄ (P, +5); Bi(OH)₃ acts as base."),
    ("Effective nuclear charge", "Increases across period; shielding constant (σ) same for same shell."),
]
fact_rows = [
    [Paragraph(f"<b>{f[0]}</b>", BODY_BOLD), Paragraph(f[1], BODY)]
    for f in facts
]
fact_t = Table(fact_rows, colWidths=[4*cm, 13.5*cm])
fact_t.setStyle(TableStyle([
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [YELLOW, WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#F9A825")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(fact_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 11. FORMULAE & QUICK CALCULATIONS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("11.  FORMULAE & QUICK TRICKS", bg=colors.HexColor("#004D40")))
story.append(Spacer(1, 4))

formulas = [
    ("Slater's rule (nuclear shielding)", "σ = Σ contributions from other electrons\nZ* = Z – σ  (effective nuclear charge)"),
    ("Period from electron config", "Highest principal quantum number (n) = period number"),
    ("Group from config (main group)", "s-block: group = no. of valence e⁻\np-block: group = 10 + valence e⁻\nd-block: group = (n–1)d + ns electrons"),
    ("Max elements per period", "2n²  where n = period number  (n=1→2, n=2→8, n=3→8, n=4→18 ...)"),
    ("Dobereiner's rule", "Atomic wt of middle = (1st + 3rd)/2"),
]
form_rows = [
    [Paragraph(f"<b>{f[0]}</b>", BODY_BOLD), Paragraph(f[1], BODY)]
    for f in formulas
]
form_t = Table(form_rows, colWidths=[5*cm, 12.5*cm])
form_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), colors.HexColor("#E0F2F1")),
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [colors.HexColor("#E0F2F1"), WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#80CBC4")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 7),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(form_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# 12. NEET PYQ PATTERNS  – MEMORY HOOKS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("12.  NEET PYQ PATTERNS  &  MEMORY HOOKS", bg=colors.HexColor("#880E4F")))
story.append(Spacer(1, 4))

pyqs = [
    "IE₁ order: He > Ne > Ar > Kr > Xe  (noble gases highest in their period)",
    "Correct IE₁ order for 2nd period:  Li < B < Be < C < O < N < F < Ne",
    "Electron affinity: Cl > F > Br > I  (Cl, not F, has highest EA)",
    "Smallest cation in isoelectronic series = highest Z  (Na⁺ < Mg²⁺ < Al³⁺)",
    "Lanthanoid contraction → Zr and Hf have nearly identical radii (very common PYQ!)",
    "Metallic oxides are basic; non-metallic oxides are acidic; Al₂O₃ is amphoteric",
    "Cr = [Ar] 3d⁵ 4s¹  and  Cu = [Ar] 3d¹⁰ 4s¹  — asked every year",
    "Number of periods = 7; total groups = 18; elements in period 6 = 32",
    "F cannot exhibit +ve oxidation states (no d-orbitals in n=2)",
    "Mendeleev left gaps for Eka-Boron (Sc), Eka-Aluminium (Ga), Eka-Silicon (Ge)",
    "Shielding order: s > p > d > f  (s electrons shield most effectively)",
    "Diagonal relationship — BeO & Al₂O₃ both amphoteric; LiF & MgF₂ both sparingly soluble",
]
pyq_col1 = [bullet(pyqs[i], marker="★") for i in range(0, len(pyqs), 2)]
pyq_col2 = [bullet(pyqs[i], marker="★") for i in range(1, len(pyqs), 2)]
pyq_t = Table([[pyq_col1, pyq_col2]], colWidths=[8.5*cm, 9*cm])
pyq_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), PINK_BG),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#F48FB1")),
]))
story.append(pyq_t)
story.append(Spacer(1, 8))

# ══════════════════════════════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════════════════════════════
story.append(HRFlowable(width=W, thickness=1, color=MID_BLUE))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "Periodic Table  •  NEET Quick Revision  •  Based on NCERT Class 11 Chapter 3  •  Prepared by Orris",
    CAPTION))

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF generated:", OUTPUT)
Running Command

cd /home/daytona/workspace/neet-periodic-table && python generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/neet-periodic-table/Periodic_Table_NEET_Notes.pdf

Your NEET quick revision PDF is ready!

Periodic Table NEET Notes

PDF Document · PDF


Here's what's covered across 3 pages:
SectionContent
1. Basics at a GlanceDobereiner, Newlands, Mendeleev, Modern Periodic Law
2. Periods OverviewAll 7 periods - shell filling, key notes
3. Periodic TrendsAtomic radius, IE, EGE, EN, valency, metallic character - with directions
4. Blocks & e⁻ Configs/p/d/f blocks + Cr, Cu, Mo, Pd exceptions table
5. Atomic & Ionic RadiiIsoelectronic series (10e⁻ and 18e⁻), Period 3 radii values
6. Ionisation EnthalpyKey values, Be>B and N>O anomalies, successive IE jumps
7. EGE & ElectronegativityCl > F for EA, Pauling scale, diagonal relationship
8. Metals / Non-metals / MetalloidsClassification, properties, staircase elements
9. Oxides & HydroxidesBasic → amphoteric → acidic trend, amphoteric list
10. Important Element Facts12 NEET-favourite element facts (H, F, noble gases, lanthanoids...)
11. Formulae & TricksSlater's rule, group from config, 2n² formula
12. NEET PYQ Patterns12 starred memory hooks from actual PYQs
This is a shared conversation. Sign in to Orris to start your own chat.