The Programmer's Grimoire: learn to code, starting with Python
Every program is a bound demon: a small literal spirit that does exactly what it was told, forever, without tiring. Programming is the summoning discipline: you learn to summon carefully, bind precisely, and dismiss cleanly. The first spell is Python, the friendliest imp in the book, and this grimoire teaches it rank by rank, from the first print to a shipped project. The second spells follow: each language you add afterward is a new demon with its own temperament, and Python makes every one of them easier to bind.
The first spell: Python
Python is the Summon Imp of languages: the first demon, the friendly one, the one that handles chores while you learn the craft. It runs everywhere, reads almost like English, and the standard library alone can carry a beginner for a year.
Summon the environment
Install Python from python.org (on Windows the Microsoft Store copy is fine too). Open a terminal and check it answers: the version command below should print 3.something. Then type the interpreter name with no arguments and drop into the interactive prompt: this REPL is your sandbox, where every later incantation can be tested one line at a time. Finally, put two lines in a file named hello.py and run it with the file name. Congratulations: you have summoned and commanded.
$ python3 --version
Python 3.13.2
$ python3 hello.py
Hello, AzerothWords and numbers
Variables are labeled jars; values have types. Learn str, int, float, and bool, and let f-strings carry your formatting. Ask the user for input (it always arrives as a string) and answer back. Ten minutes of this in the REPL teaches more than a chapter of reading.
name = "Chromie"
level = 60
print(f"{name} is level {level}")
print(int("60") + 1) # types convert on purpose, never silentlyBranching paths
Programs become programs when they decide. if, elif, and else choose paths; comparison operators produce booleans; and, or, and not combine them. Then loop: for walks a sequence, while repeats until a condition breaks. Write a number guessing game in fifteen lines; it uses everything in this rank.
for i in range(1, 4):
print("cast", i)
if level >= 60 and name == "Chromie":
print("the timeline holds")
else:
print("keep leveling")Bind a function
A function is a bound demon with a name: def creates it, arguments feed it, return brings back the result. Write many small functions instead of few large ones; if you can name it in three words, it should probably be a function. Learn default argument values, and learn that scope is real: a function sees its own variables and its parameters, not your scratchpad.
def heal(target, amount=10):
"""Return the heal message for a target."""
return f"{target} healed for {amount}"
print(heal("tank"))
print(heal("party", 25))Collections
Lists are ordered packs, dicts are spellbooks keyed by name, sets drop duplicates, tuples do not change. Master .append, .items(), in, and len first; comprehensions second: they build a new collection from an old one in one readable line. Almost all real data arrives as some nest of lists and dicts, so this rank pays for the whole apprenticeship.
spells = {"fireball": 3, "frostbolt": 2, "polymorph": 1}
for name, rank in sorted(spells.items()):
print(f"{name}: rank {rank}")
maxed = [s.title() for s in spells if spells[s] >= 2]Files and errors
Programs that remember things read and write files. The with-statement opens a file and guarantees it closes. Errors are not shame: they are the machine reporting reality, and try/except is how a program survives them without lying about what happened. Catch the specific error you expect (ValueError, KeyError, FileNotFoundError), never everything.
with open("journal.txt", "a") as f:
f.write("day 1: summoned an imp\n")
try:
level = int("sixty")
except ValueError:
print("that was not a number, apprentice")Objects, modules, and the hoard
Classes bundle data with the functions that belong to it; import borrows ready-made power; and the ecosystem is the hoard. Learn to create a virtual environment and install from the package index: this is how you summon other summoners' demons without wrecking your own circle. Write one small class with an __init__ and two methods, then rewrite an earlier function-based exercise with it.
class Imp:
def __init__(self, name):
self.name = name
def work(self, chore):
return f"{self.name} sorted the {chore}"
imp = Imp("Pip")
print(imp.work("files"))
# $ python3 -m venv .venv && source .venv/bin/activate
# $ pip install rich # then: import richShip a real project
The apprenticeship ends when something real exists. Climb the ladder: a command line tool you actually use (rename files, track a habit, tally expenses), then a scraper for a page you own, then a small web API or site. Put it under version control from day one, write three tests and run them with pytest, and publish the repository so the project has a public soul. Then read your own code from rank 1 and feel the distance.
$ git init && git add . && git commit -m "first summoning"
$ pytest -q
3 passed in 0.02s
$ # push it to a public code host: the project now existsThe second spells
Each language after Python is a new demon with its own temperament. Learn them in whatever order your work demands; Python has already taught you the circle.
Wears the Classic Mage spell Blink
Why: The language every browser speaks. With Python on the server and JavaScript on the page, one person can build the whole web.
When: After Python rank 6, or the moment you want your pages to react, animate, and call APIs.
What transfers: Functions, collections, and control flow map almost one to one. Watch for strict equality, asynchronous code (promises and async/await), and let/const scoping.
Start: The free guides on the Mozilla developer network, then a to-do page in a single HTML file that saves to the browser's own storage.
Full grimoire: ranks and incantations →
Wears the Classic Shaman spell Far Sight
Why: Data lives in tables and SQL is the scrying that reads them. Every app, job, and analysis eventually becomes a query.
When: Anytime; it pairs with Python immediately (the sqlite3 module ships in the standard library).
What transfers: Less code than a re-orientation: think in sets and joins instead of loops. Your dict and list intuition becomes rows and columns.
Start: Open a SQLite database in your terminal and drill SELECT, WHERE, GROUP BY, and JOIN against data you actually care about.
Full grimoire: ranks and incantations →
Wears the Classic Mage spell Mana Shield
Why: JavaScript wearing a protective ward: types that catch whole classes of bugs before the code ever runs. Large codebases are written in it.
When: After two or three months of JavaScript, not before: the shield only makes sense once you know what it is protecting you from.
What transfers: Everything from JavaScript, plus your Python type hints if you wrote them. The compiler messages read like a strict but fair tutor.
Start: Add types to a small JavaScript project you already understand and let the compiler show you what it catches.
Full grimoire: ranks and incantations →
Wears the Classic Rogue spell Sprint
Why: A deliberately small language that compiles to a single fast binary. It runs much of the cloud's tooling and deploys with nothing but a file copy.
When: After Python, when you want speed of execution and operation without a mountain of concepts.
What transfers: Functions, packages, and testing transfer directly. Interfaces and explicit error returns are the new discipline.
Start: The official interactive tour, then a small HTTP service that serves one JSON endpoint.
Full grimoire: ranks and incantations →
Wears the Classic Paladin spell Divine Shield
Why: Systems speed with memory safety: the compiler refuses programs that would corrupt memory. The discipline is the feature.
When: After C, or after strong Python plus genuine systems curiosity. Expect the training to fight back at first; that is by design.
What transfers: Control flow and functions arrive with you; ownership and borrowing are the new school. Python's type hints soften the landing.
Start: The official book, freely online, and cargo new: fight the borrow checker on purpose until it starts explaining itself.
Full grimoire: ranks and incantations →
Wears the Classic Shaman spell Rockbiter Weapon
Why: The bedrock. Operating systems, embedded devices, and the runtimes of other languages are written in it, close to the metal it runs on.
When: When you want to understand what Python hides: memory, pointers, and why some errors are catastrophic.
What transfers: Syntax looks familiar; the ideas underneath do not. Arrays become pointers, strings become buffers, and you manage the memory yourself.
Start: A classic short book or a free university course, one small program a day, compiled with gcc or clang.
Full grimoire: ranks and incantations →
Wears the Classic Warlock spell Unending Breath
Why: The enterprise elemental: verbose, explicit, and effectively immortal. Huge back ends and much of Android's legacy run on it.
When: When a course, job, or platform demands it; it is rarely anyone's recreational first choice, and that is fine.
What transfers: Python rank 7 maps almost directly: classes, imports, and collections with different names. Static typing will feel like TypeScript's stricter ancestor.
Start: An official getting-started guide, one small class-based command line tool, then the web framework your environment uses.
Full grimoire: ranks and incantations →
Honorable mentions for later: Bash for the terminal scripts that glue everything together, C# if your platform speaks it, PHP for an enormous share of the web's legacy, Lua for embedding inside games and tools, and WebAssembly, which is less a language you write and more a target other languages compile to. HTML and CSS are not programming languages; they are the runes every web page is inked with, and worth an afternoon each.