Starterpython~60 min

🧮 Calculator

A guided walk through writing a small calculator in Python. You'll meet input parsing, control flow, error handling, and the REPL pattern — and finish with something you can run from your own terminal.

You're going to write a small Python program that adds, subtracts, multiplies, and divides two numbers — and keeps doing it until you tell it to stop. By the end you'll have a file you can run from your own terminal, and you'll have used variables, input parsing, control flow, error handling, and the loop pattern that runs almost every CLI tool you've ever opened.

We're not racing. Each step is one idea. If a hint helps, take it — there's no penalty.

Before you start

Modern macOS ships Python 3 — try python3 --version. If it's older than 3.10, install via Homebrew: brew install python@3.12.

The walkthrough

Make the project file

In your terminal, inside the calculator folder, create an empty file called calc.py. Open it in your editor.

You can do this any way you like — touch calc.py, code calc.py, "File → New" in your editor, whatever's natural for you.

After this step your file should look like… (calc.py)

Print something — anything

In calc.py, write a single line that prints "calc.py is alive" (or whatever you want — the point is to confirm the file runs).

Then run it from your terminal: python3 calc.py.

After this step you should see…
calc.py is alive

Read a number from the user

Replace your print with code that asks the user for a number and prints back what they typed. Run it; type 42; you should see you typed: 42.

After this step you should see…
Enter a number: 42
you typed: 42

Add two numbers

Now ask for two numbers and print their sum. Convert each input from a string to an integer with int(...) so + does math, not string concatenation.

After this step you should see…
First number: 7
Second number: 5
sum: 12

What does `int('0.5')` raise?

Add subtraction, multiplication, division

Extend the program: after reading the two numbers, ask for an operator (+, -, *, /) and print the right result.

After this step you should see…
First number: 12
Second number: 4
Operator (+, -, *, /): /
result: 3.0

Wrap it in a loop so we can do many calculations

The program runs once and exits. Wrap the whole "ask + compute + print" sequence in a while True: loop so you can do calculation after calculation without re-running.

(Don't worry about exiting the loop yet — just press Ctrl+C to kill it. We'll add a clean exit in the next step.)

After this step you should see…
First number: 1
Second number: 2
Operator (+, -, *, /): +
result: 3
First number: 10
Second number: 4
Operator (+, -, *, /): -
result: 6
^C

Add a clean way to quit

Right after reading the first number, check whether the user typed quit. If so, print a goodbye and break out of the loop.

After this step you should see…
First number: 5
Second number: 3
Operator (+, -, *, /): +
result: 8
First number: quit
goodbye!

Don't crash on bad input

Right now, typing seven instead of 7 crashes with ValueError. Wrap the integer parsing in a try/except block: catch ValueError, print "that wasn't a number, try again," and continue to the next loop iteration.

After this step you should see…
First number: hello
that wasn't a number, try again.
First number: 4
Second number: 2
Operator (+, -, *, /): /
result: 2.0

What does `try` / `except ValueError` catch?

Remember every calculation in a list

At the top of the file (above the loop), make an empty list called history. Each time you compute a result, append a description string to that list — something like "7 + 5 = 12".

When the user quits, before the goodbye, print the whole history.

After this step you should see…
First number: 1
Second number: 2
Operator (+, -, *, /): +
result: 3
First number: 4
Second number: 6
Operator (+, -, *, /): *
result: 24
First number: quit
history:
1 + 2 = 3
4 * 6 = 24
goodbye!

Pull the math into a function — and try one test

Move the four operators into a single function: def calc(a, b, op): ... that returns a number (or raises a clear error for unknown operators). Replace the if/elif chain in the loop with one call to calc(a, b, op).

Then, outside the loop, write three tiny assertions to convince yourself the function works:

assert calc(2, 3, "+") == 5
assert calc(10, 4, "-") == 6
assert calc(7, 6, "*") == 42

Run the file. If the assertions pass, you see no output for them. If one fails, you'll see AssertionError.

After this step you should see…
First number: 5
Second number: 3
Operator (+, -, *, /): +
result: 8
First number: quit
history:
5 + 3 = 8
goodbye!

Make the file runnable directly

Add a shebang line at the very top: #!/usr/bin/env python3. Then make the file executable: chmod +x calc.py. Now you can run it as ./calc.py instead of python3 calc.py.

After this step you should see…
First number: 9
Second number: 3
Operator (+, -, *, /): /
result: 3.0
First number: quit
history:
9 / 3 = 3.0
goodbye!

Add a help line + decimal numbers

Two small polish moves:

  1. At the top of the loop body (or above the loop), print a one-line help: "Type 'quit' to exit. Operators: + - * /".
  2. Switch int(...) to float(...) so the calculator handles decimals.
After this step you should see…
Type 'quit' to exit. Operators: + - * /
First number: 1.5
Second number: 2.5
Operator (+, -, *, /): +
result: 4.0
First number: quit
history:
1.5 + 2.5 = 4.0
goodbye!

You did it

Run ./calc.py once more. Watch your history grow as you do calculations. Quit. Take a screenshot — that thing didn't exist a few hours ago.

You wrote:

  • a Python file from scratch
  • input parsing with type conversion
  • an if/elif/else branch
  • a while True: REPL loop with break + continue
  • error handling with a narrow except
  • a list + for loop
  • a refactor to extract a pure function
  • a couple of unit-test-shaped assertions
  • a shebang line + executable permission
  • some basic UX polish

Every one of those is a thing you'll use again — in the next project, in your job, in everything.

Stretch goals