You Finished. Here Is What Happens Next.
A short celebration, and the four things worth doing this month
In this lesson
You have reached the end of the curriculum: sixteen units, from what a variable is to packaging a tool other people can install. That is a real thing to have done, and most people who start do not.
This lesson is short. It is an inventory of what you can now build, four things worth doing in the next month, and a send-off.
Explain it like I’m 5
You finished the map. This page is the bit where you look at how far you walked, and pick which way to go next.
Look at what you can build now
Start with the audit, because progress is genuinely hard to see from the inside. Everything below was impossible for you at some point that is more recent than it feels.
CAN_BUILD = {
"Beginner": ["read and write files", "loop over data", "write functions"],
"Intermediate": ["classes", "command-line tools", "a Flask app with forms"],
"Advanced": ["API clients", "SQLite behind them", "charts", "tests",
"an installable package"],
}
total = 0
for track, skills in CAN_BUILD.items():
total += len(skills)
print(f"{track:13s} {len(skills)} {', '.join(skills)}")
print()
print(f"{total} things you could not do a while ago. Pick ONE and build with it.")
Beginner 3 read and write files, loop over data, write functions Intermediate 3 classes, command-line tools, a Flask app with forms Advanced 5 API clients, SQLite behind them, charts, tests, an installable package 11 things you could not do a while ago. Pick ONE and build with it.
The four things worth doing this month
In order, and the first one matters most.
- Ship one small thing. The capstone build is two lessons back, with a five-day plan. Small and finished, not ambitious and abandoned.
- Write its README. Ten minutes, and it is the difference between a folder and a project. The template is in Unit 15.
- Pick one path. Seven of them, one at a time, chosen by what you want to build rather than by what sounds impressive.
- Teach one thing you learned. Answer one beginner question, or write up one thing that confused you. It is the fastest way to find out which parts you actually understand.
Notice that only one of the four is about learning more. That ratio is deliberate: from here, the limiting factor is not what you know.
Where the rest of this site is
The lessons are not everything here.
- Projects — complete guided builds with sample data and downloadable code, from beginner mini-projects to advanced builds that combine several units. The obvious next thing after finishing the path.
- Glossary — every term this course used, defined in plain English with a runnable example. Useful when reading someone else's code or documentation.
- Beginner, Intermediate and Advanced — the paths themselves, which are worth revisiting. Lessons you found hard the first time read very differently once you have built something.
- Start Here — worth a second look now. It is the page you would point a friend at, and it reads differently from this end.
And if something here was wrong, missing, or explained badly, say so. A specific note — which lesson, which paragraph, what you expected — is worth more than a general one, and it is how this site gets better.
Write down what you can build
One last exercise, and it is not about code. Write three claims that start with “I can build…” — not “I understand…” and not “I want to learn…”. The distinction matters: a claim about building is testable, and a claim about studying is not.
Keep the list. It is the raw material for a CV line, a README, and an interview answer, and it will look conservative in six months.
Replace the three claims with your own, then run it. vague() rejects anything that starts like a study plan, or is too short to be a real claim — and it is deliberately strict, because “learn more Python” is not a thing anyone can build.
# "What I can build now" - a claim about building, not about studying.
VAGUE_STARTS = ("learn", "understand", "study", "master", "get better")
# TODO: replace these with three of your own, then run it again.
CLAIMS = [
"I can read a CSV and write a summary of it",
"I can put a small Flask app behind a form",
"I can package a script so a friend can install it",
]
def vague(claim):
"""Is this a study plan pretending to be a skill?"""
return False # TODO: starts with one of VAGUE_STARTS (case-insensitively),
# TODO: or is fewer than five words
def check(claims):
"""The claims that do not yet describe something you can build."""
return [] # TODO
for claim in CLAIMS:
print(f"{'vague' if vague(claim) else 'solid':5s} {claim}")
print("still vague:", check(CLAIMS))
print("solid claims:", len(CLAIMS) - len(check(CLAIMS)), "of", len(CLAIMS))
str.startswith accepts a tuple and returns True if any of them match, so claim.lower().startswith(VAGUE_STARTS) is the whole first test — no loop needed. Then len(claim.split()) < 5 catches the too-short ones.
# "What I can build now" - a claim about building, not about studying.
VAGUE_STARTS = ("learn", "understand", "study", "master", "get better")
CLAIMS = [
"I can read a CSV and write a summary of it",
"I can put a small Flask app behind a form",
"I can package a script so a friend can install it",
]
def vague(claim):
"""Is this a study plan pretending to be a skill?"""
return (claim.lower().startswith(VAGUE_STARTS)
or len(claim.split()) < 5)
def check(claims):
"""The claims that do not yet describe something you can build."""
return [claim for claim in claims if vague(claim)]
for claim in CLAIMS:
print(f"{'vague' if vague(claim) else 'solid':5s} {claim}")
print("still vague:", check(CLAIMS))
print("solid claims:", len(CLAIMS) - len(check(CLAIMS)), "of", len(CLAIMS))
solid I can read a CSV and write a summary of it
solid I can put a small Flask app behind a form
solid I can package a script so a friend can install it
still vague: []
solid claims: 3 of 3
Thank you
Genuinely: thank you for reading this far. Sixteen units is a long way, and finishing a course you were not required to take, with nobody checking, is a harder thing than it gets credit for.
You are not finished learning Python. Nobody is — the people who write the libraries you use look things up every day, and the feeling of not quite knowing enough turns out to be permanent and completely normal. What has changed is that you can now find things out. That is the actual skill, and it is the one this course was built to leave you with.
So go and build the small thing. Then tell someone about it.
Common mistake: Finishing the lessons and stopping
Completing a course feels like the goal, because it was the thing with a progress bar.
The goal was always to build things. Start something small this week, while it is all still fresh — the week after you finish is the easiest week you will ever have to start.
Common mistake: Collecting more resources instead of choosing one
Saving a course is progress you can make in ten seconds; building is slower.
Pick one path, one project, one book if you want one. A folder of unopened bookmarks is a to-do list you will never finish and will feel bad about.
Common mistake: Comparing your beginning to someone else's middle
People publish their finished work, not their false starts.
Compare yourself to your own last project. The engineer whose code intimidates you has years you cannot see, and a folder of abandoned attempts they never posted.
Common mistake: Waiting to feel ready
There is always one more thing that seems like a prerequisite.
You will not feel ready, and it is not a signal. Start the project at the level you are at now; the gaps will announce themselves, and gaps you hit while building are the easiest ones you will ever fill.
What is the best next step after finishing the lessons?
Reading is how you meet an idea; building is how you keep it. Small and finished beats ambitious and abandoned, every time.
Why keep the first project small?
Everything you learn from a project, you learn in the last twenty per cent — the part that only exists if you get there.
You have not written any Python for three weeks. What is the best move?
Momentum is easier to keep than to restart, and twenty minutes three times a week genuinely beats one heroic Saturday a month.
What is the real skill this course was trying to leave you with?
Everybody looks things up, every day. Recognizing which tool a problem calls for and knowing how to find the details is the durable part.
Mini exercise (medium)
Write the last function of the course, and make it about you. commitment(path, project, weeks, hours_per_week) returns your next step in one line — or the reason it is not yet a plan. Check in this order: the path must be one of the seven; the project needs at least four words; the timeline must be one to eight weeks; and the total hours must reach twenty, because less than that will not finish anything.
Now you. Edit the starter code below, then Run it, everything happens in the browser.
PATHS = ("web", "data", "automation", "backend", "security", "games", "core")
def commitment(path, project, weeks, hours_per_week):
"""The next step in one line, or the reason it is not a plan yet."""
return "?" # TODO, in this order:
# path not in PATHS -> "pick one path"
# fewer than 4 words -> "say what you will build"
# weeks outside 1..8 -> "one to eight weeks"
# weeks * hours under 20 -> f"{total}h will not finish it"
# otherwise -> f"{project} ({path}), {weeks} weeks x {hours_per_week}h"
print(commitment("data", "chart two years of electricity bills", 4, 6))
print(commitment("everything", "chart two years of electricity bills", 4, 6))
print(commitment("web", "a blog", 4, 6))
print(commitment("games", "a two-room text adventure", 52, 6))
print(commitment("core", "a decorator that retries failed calls", 3, 2))
Four guard clauses that each return a short reason, then one return with the f-string. Work out total = weeks * hours_per_week after the weeks check, so the message can quote it. The order is the design: a plan with no path is not worth counting the hours of.
PATHS = ("web", "data", "automation", "backend", "security", "games", "core")
def commitment(path, project, weeks, hours_per_week):
"""The next step in one line, or the reason it is not a plan yet."""
if path not in PATHS:
return "pick one path"
if len(project.split()) < 4:
return "say what you will build"
if not 1 <= weeks <= 8:
return "one to eight weeks"
total = weeks * hours_per_week
if total < 20:
return f"{total}h will not finish it"
return f"{project} ({path}), {weeks} weeks x {hours_per_week}h"
print(commitment("data", "chart two years of electricity bills", 4, 6))
print(commitment("everything", "chart two years of electricity bills", 4, 6))
print(commitment("web", "a blog", 4, 6))
print(commitment("games", "a two-room text adventure", 52, 6))
print(commitment("core", "a decorator that retries failed calls", 3, 2))
chart two years of electricity bills (data), 4 weeks x 6h
pick one path
say what you will build
one to eight weeks
6h will not finish it
assert commitment("data", "chart two years of electricity bills", 4, 6) == "chart two years of electricity bills (data), 4 weeks x 6h", "a real plan comes back as one line"
assert commitment("everything", "chart two years of electricity bills", 4, 6) == "pick one path", "the path check comes first"
assert commitment("web", "a blog", 4, 6) == "say what you will build", "three words is a wish, not a project"
assert commitment("games", "a two-room text adventure for my nephew", 52, 6) == "one to eight weeks", "a year is not a plan"
assert commitment("core", "a decorator that retries failed calls", 3, 2) == "6h will not finish it", "check the total hours too, not just the number of weeks"
assert commitment("web", "a links page I actually use", 5, 4) == "a links page I actually use (web), 5 weeks x 4h", "20 hours exactly is enough"
print("\u2713 Looks good!")