You have built a real program across this series: an expense tracker that records spending, saves it, totals it by month, runs on a schedule, and has a couple of tests. Right now it lives in a folder on your machine. This part turns it into something a stranger can find, understand, run, and be impressed by, which is what a portfolio project actually is.
.gitignore, and put it on GitHub. One polished project you can talk about beats ten unfinished tutorials every time.This part gathers everything from the series, so no single new concept, just the finishing work that turns code into a project. You need Python 3 and about thirty minutes, plus a free GitHub account if you want to publish it online.
Give the project a clean shape
Loose files in one folder look like a scratchpad. A small, deliberate structure looks like a project. Here is a layout a reviewer reads at a glance, with the code, its tests, and the supporting files each in their place:
expense-tracker/
expenses.py
monthly_summary.py
tests/
test_expenses.py
requirements.txt
.gitignore
README.mdNothing here is new. expenses.py and monthly_summary.py are the code you wrote, the tests from Part 18 sit in a tests folder, and requirements.txt is the pinned list from Part 14. The two new files, .gitignore and README.md, are the difference between a folder and a project, and they take ten minutes to write.
The README does the talking
Most people who look at your project read the README and nothing else at first. It is the front door. A good one answers four questions fast: what is this, how do I install it, how do I run it, and what does it look like when it works. Keep it short and concrete:
# Expense Tracker A small command line tool to record expenses and print a monthly spending summary. ## Install python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ## Run python monthly_summary.py 2026-07 ## Example output Category Amount food 120.50 travel 40.00 ## Tests pytest
That is enough. Someone lands on your project, copies three lines, and it runs. The single biggest reason a reviewer gives up on a project is that they cloned it and could not get it to start, usually because there was no README or the install steps were missing. A short, accurate README removes that wall entirely.
| README section | Answers |
|---|---|
| Title and one line | What is this |
| Install | How do I set it up |
| Run | How do I use it |
| Example output | What should I expect to see |
| Tests | How do I check it works |
Table 1. The five things a README should cover, in order.
Keep the noise out with .gitignore
When you put the project under version control, some files should never be committed: the virtual environment, Python’s cache folders, and often your personal data file. A .gitignore lists patterns for git to skip, so your repository stays to the code that matters:
.venv/ __pycache__/ *.pyc expenses.json
Ignoring .venv and __pycache__ keeps large, machine specific files out, exactly as Part 14 argued. Ignoring your expenses.json keeps your own spending private while still shipping the code that creates it. A reviewer clones a clean, small repository instead of wading through generated clutter.
Put it on GitHub
A project a stranger can find lives online, and the standard place is GitHub. With git, the whole thing is a few commands from your project folder. This records a first version and pushes it to a repository you create on the site:
git init git add . git commit -m 'first working version' git remote add origin YOUR_REPO_URL git push -u origin main
Once it is up, the README renders on the project page automatically, so the first thing a visitor sees is your clear explanation and run instructions. That page, with code that runs in one command, is a stronger signal to an employer than any line on a resume, because they can see and test the real thing.
Figure 1. The first minute on your repo: the README and a clean run matter most.
One finished project beats ten started
Here is the opinion, and it runs against common advice. You do not need a wall of projects. A single small program that is finished, documented, tested, and actually runs says more about you than ten half done clones of someone else’s tutorial. Depth reads as care, and care is what a hiring manager is scanning for. Polish the tracker until you are proud of it rather than rushing to start the next thing.
Finished does not mean large. It means the edges are handled: it does not crash on an empty file, the README is accurate, the tests pass, and a stranger can run it without asking you a single question. That standard, applied to something genuinely small, is exactly what junior portfolios are judged on.
# Word Counter Counts words in a text file. ## Run python count.py notes.txt
Show solution
# Word Counter A tiny script that prints how many words are in a text file you give it. ## Run python count.py notes.txt
A title, one plain sentence, and a run command a stranger can copy. That is a real README, just small.
Portfolio questions beginners ask
How many projects do I need? One that is genuinely finished and yours is enough to start. A second, different in kind, helps. Quality over count every time.
Does it have to be original? It should be built by you and something you understand fully. The tracker is perfect because you made every decision in it and can explain all of it.
Do I need a fancy web app? No. A clear command line tool that runs and is well documented is more convincing than a flashy app you cannot explain. Substance reads louder than surface.
What if my code is not clever? Good. Clear beats clever in real work. Reviewers want code they can read, not a puzzle. Plain, working, tested code is the goal.
Should I keep committing after the first push? Yes. A short history of small commits shows how you work. Commit each improvement with a message that says what changed.
What finished actually means
Finished is a checklist, not a feeling. Before you call the tracker done and put it in front of anyone, walk these points once. Each is small, and together they are the difference between a project that survives a reviewer and one that falls over on the first try.
| Check | Why it matters |
|---|---|
| Runs in one command from the README | The reviewer never gets stuck |
| README example matches real output | Nothing misleading, so it earns trust |
| Tests pass with pytest | Visible proof it works |
| Handles an empty or missing file | No crash on the obvious edge case |
| No personal data or secrets committed | Privacy and basic safety |
| Names and style stay consistent | Reads as careful, not rushed |
Table 2. The finishing checklist to run before you show a project.
Go through it once and fix whatever fails, which is usually a line or two each. The empty file case is the one beginners skip and reviewers always try first, so make sure your load handles a missing expenses.json by returning an empty list, exactly the guard you wrote in Part 11. An edge case handled quietly is the mark of someone who has shipped before.
Commit messages a reader can follow
Once the project is on GitHub, every change you make leaves a message in its history, and those messages get read. A vague one tells a reviewer nothing about how you think; a specific one shows that you understand your own changes. The cost of a good message is a few extra seconds:
| Vague | Clearer |
|---|---|
fix | fix crash when expenses.json is missing |
stuff | add monthly totals to the summary |
update | pin tabulate version in requirements |
Table 3. A vague message and a clear one for the same change.
A simple trick is to write the message as the end of the sentence, this commit will, so it names what the change does. Small, honest commits with clear messages read as someone who works with care, and that steady impression across a history is exactly what a portfolio should leave behind.
.gitignore, and publish the whole thing to GitHub as a finished piece. Your expense tracker is now a portfolio project, not just a folder. In Part 20, the last one, you learn to present it and yourself: the Python job paths, the interview, and what to learn next.


DrJha