Build Your First Tool with Claude Code: Monthly Totals from an Expense CSV
Use the fictional expenses.csv and requirements note from the previous articles to practice building a first small Python tool. Put the input example, expected output, and constraints in the request, then run the completed summarize.py separately in the Python tool in GPT chat—not in Claude Code—to verify the result.
Content checked 2026.09.22Copyable prompts
Show contents
Who this is forBeginners who have completed Claude Code installation and the first read-only exercise and are ready to try generating code for one small file
What you need
Have the vibe-expenses practice folder and fictional expenses.csv ready
Understand the workflow of checking proposed changes before allowing Claude Code to modify files
Have Python installed and be able to run the python command in a terminal
Use only fictional data rather than real personal information or payment records
01Start small with one input and one output
The goal of the first hands-on exercise is not a feature-rich expense-tracking app, but a single file, summarize.py, that reads expenses.csv and prints only monthly amount totals. Keeping the scope small makes it easier to verify the AI-generated result yourself. The input is a UTF-8 CSV with the columns date, category, and amount. Assume date uses YYYY-MM-DD and amount is an integer.
Item
Fixed requirement for this exercise
Verification criterion
Input file
expenses.csv
Do not modify the original file
Input columns
date, category, amount
Do not arbitrarily require other columns
Output
Monthly amount totals
2026-09 = 26600, 2026-10 = 9800
Implementation scope
One summarize.py file
Do not add unnecessary config files or packages
Library
Python standard library
No external package installation
The important point at this stage is not to make a broad request such as 'build me an expense tracker.' Reduce the chance that AI arbitrarily expands the task with a UI, database, charts, login, or other features, and delegate only a task whose answer can be checked in a single run.
02Put the input, expected output, and constraints in the request
When asking Claude Code to do the task, provide both the input-file structure and the correct answer. An expected output makes it clear what the generated code has to match, and lets you compare the result visually. Also state the boundaries explicitly—for example, 'use only the standard library,' 'do not modify the original CSV,' and 'write only summarize.py.'
Prompt
Create summarize.py in the current folder so that it reads expenses.csv and prints monthly amount totals.
Input:
- UTF-8 CSV
- Column names: date, category, amount
- date format: YYYY-MM-DD
- amount is an integer
Expected output:
2026-09 = 26600
2026-10 = 9800
Constraints:
- Use only the Python standard library
- Do not modify expenses.csv
- Run with python summarize.py expenses.csv
- First explain the required file and planned changes, then create only summarize.py.
This code block is a request for the user to enter, not a Claude Code response. Because the request already contains values that serve as the correct answer, you can later compare the two numbers exactly instead of merely judging whether the result looks plausible.
03Check what will be created before allowing file edits
Claude Code can read the files it needs and may ask for approval before modifying files or running commands. When an approval screen appears, do not press Yes immediately. Check which files were read, whether summarize.py is the only new file, and whether expenses.csv will remain untouched. If it wants to run an unfamiliar command, you can ask it to explain the command's purpose first.
Prompt
Before making changes, confirm the following.
1) Tell me which file you will read and which file you will create.
2) Confirm that expenses.csv will not be modified.
3) Confirm that no external packages will be installed.
4) In one line, tell me how to compare the result with the expected output after running it.
A real Claude Code response can vary by environment and time, so this article does not invent a particular response and present it as a success example. What matters is the file scope and command scope, not the style of the response.
04Review the completed reference code and run command
The summarize.py below is a completed reference implementation that satisfies the requirements in this article. It reads each row with csv.DictReader, takes the first seven characters of date to obtain YYYY-MM, converts amount to an integer, and adds the values by month. It sorts the month keys to make the output order deterministic. This code is not copied from an actual Claude Code-generated response; it was written to reproduce the exercise result and was executed separately for verification.
Prompt
import csv
import sys
from collections import defaultdict
def summarize_monthly(path):
totals = defaultdict(int)
with open(path, "r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
month = row["date"][:7]
amount = int(row["amount"])
totals[month] += amount
return totals
def main():
if len(sys.argv) != 2:
raise SystemExit("Usage: python summarize.py expenses.csv")
totals = summarize_monthly(sys.argv[1])
for month in sorted(totals):
print(f"{month} = {totals[month]}")
if __name__ == "__main__":
main()
Only the standard library is used, so no separate package installation is required. The run command is shown below. On Windows, if py is configured instead of python, you can use `py summarize.py expenses.csv`.
Prompt
python summarize.py expenses.csv
05Compare the output with the expected values line by line
In the Python tool in GPT chat, the code above and the fictional expenses.csv were saved as files and `python summarize.py expenses.csv` was actually run. Standard output exactly matched the two lines below. This verification was not performed in Claude Code.
Prompt
2026-09 = 26600
2026-10 = 9800
Month
Expected
Actual
Result
2026-09
26600
26600
Match
2026-10
9800
9800
Match
At this stage, confirm only that these two lines matched. Do not overgeneralize this result to assume that the tool also handles other CSV formats, blank values, or invalid numbers. The result matched only for the current test data and current requirements.
You can also check the totals by hand once. September is 12000 + 1450 + 8500 + 3200 + 1450 = 26600, and October contains one entry of 9800, so the total is 9800. With a small example like this, cross-checking program output against a human-calculated reference value makes it easier to trace where results diverge when the functionality is expanded later.
06Stop when the answer is correct instead of adding more features
A common form of scope expansion in a first tool is, 'Since we've built this much, let's also add category totals, charts, and automatic saving.' But the completion condition for this article is simply that the two monthly-total lines are correct. Once that condition is met, keep the current state as a baseline and separate additional features into later requests.
Confirm that no unexpected files other than summarize.py were created.
Confirm that the contents of expenses.csv did not change.
Confirm that no external package installation was added.
Confirm that the two output lines exactly match the expected values.
Keep additional features out of this request and separate them into the next task.
The next article puts the project rules in CLAUDE.md so you do not have to rewrite long constraints every time. That file is also project context read by Claude Code at session start rather than an enforcement mechanism, so the key is to keep it short and specific.
What to check yourself
In the Python tool in GPT chat, saved summarize.py and the fictional expenses.csv using Python 3, then ran `python summarize.py expenses.csv` · Claude Code not actually run
Confirmed that the Python code uses only the standard-library modules csv, sys, and collections.defaultdict
Confirmed that expenses.csv is opened read-only as UTF-8 and the original is not modified
Confirmed that the first 7 characters of date are used as the month and amount is converted with int before summation
Confirmed that actual stdout exactly matches the two lines `2026-09 = 26600` and `2026-10 = 9800`
Confirmed that the request includes the input, expected output, standard-library constraint, and prohibition on modifying the original file
Confirmed that the article does not incorrectly state that execution or verification was performed in Claude Code
Verification limits
Verification was performed only with the six-row fictional CSV in this article. It does not verify exception cases such as blank values, invalid dates, or nonnumeric amount values, and Claude Code's own generated result or interface was not actually tested.
Instead of treating vibe coding as simply 'tell AI what you want and it builds everything for you,' this article frames it as a workflow in which a person defines the requirements and verification criteria, then checks the result produced by AI. Using a fictional household-expense CSV summation tool, it organizes the input, output, things not to do, and verification method into a one-page note.
Check the Claude Code installation command and account requirements for your operating system, then start a first session in a fictional practice folder. Instead of generating code immediately, this article focuses on asking only three questions in plan mode to inspect the folder and CSV, then exiting safely.
Put the run command, data rules, prohibitions, and verification method that were being repeated in every request into the project's CLAUDE.md in a concise form. Distinguish the `/init` function that creates a draft from the purposes of different file locations, and complete a 35-line rules file for the expense CSV example.
Using the example of adding a `--by-category` option to an already working monthly expense summary tool, learn how to review a change plan first in Claude Code's plan mode. Fix the scope of edits and output format before implementation, then run the completed code after approval to verify both the existing monthly totals and the category totals.
Create a git baseline before Claude Code edits files, then read the actual changes with `git status` and `git diff`. You can ask AI to explain the diff, but do not rely on the explanation alone: review the diff and execution results yourself, then stage and commit the changes directly.
Instead of telling AI only that 'there is an error,' reproduce the problem with the same input, narrow down the cause from the actual exception message, and request only the minimum necessary fix. Using a CSV where an amount contains a comma, reproduce a ValueError in Python and rerun the corrected code to verify the fix.
Assuming Claude Code can read and modify files and run commands, organize the safety checks beginners should make before, during, and after work. Connect the differences between permission modes, changes checkpoints cannot restore, the separate role of git, and the rule of not exposing secrets into one practical checklist.