1 The Problem
We want a calculator: the user picks an operation, enters two numbers, and gets the result. It teaches organising code into functions, choosing between options, and guarding against the one maths error that crashes programs — dividing by zero.
2 How to Think About It
The plan, before any code:
3 The Build — explained part by part
Here is the complete calculator. Each part is explained below.
# A calculator with one function per operation.
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Cannot divide by zero"
return a / b
print("1. Add 2. Subtract 3. Multiply 4. Divide")
choice = input("Choose an operation (1-4): ")
a = float(input("First number: "))
b = float(input("Second number: "))
if choice == "1":
print(f"Result: {add(a, b)}")
elif choice == "2":
print(f"Result: {subtract(a, b)}")
elif choice == "3":
print(f"Result: {multiply(a, b)}")
elif choice == "4":
print(f"Result: {divide(a, b)}")
else:
print("Please choose 1 to 4.")
add that takes two numbers and returns their sum. We make one for each operation. A function is a named, reusable piece of logic.def divide(a, b): — division needs a guard: if
b is 0, we return a friendly message instead of crashing, because dividing by zero is mathematically impossible.choice = input(...) and a, b = float(...) — ask which operation, then read two numbers as decimals.
if / elif / else — run the function that matches the choice.
{add(a, b)} calls the function and drops its result straight into the message.
ZeroDivisionError.if b == 0 before dividing.choice == 1 (number) instead of "1" (text).input() returns text, so compare to "1" in quotes.int() for the numbers — then 2.5 becomes 2.float() so decimals work.4 Test & Prove Each Part
Each operation is its own function, which makes testing clean — we check each against answers we already know, including the divide-by-zero guard.
from calculator import add, subtract, multiply, divide
def test_add():
"""2 + 3 is 5."""
assert add(2, 3) == 5
def test_subtract():
"""10 - 4 is 6."""
assert subtract(10, 4) == 6
def test_multiply():
"""6 times 7 is 42."""
assert multiply(6, 7) == 42
def test_divide():
"""10 / 2 is 5."""
assert divide(10, 2) == 5
def test_divide_by_zero():
"""Dividing by zero returns a message, not a crash."""
assert divide(5, 0) == "Cannot divide by zero"
Run with pytest -v. Because each operation is a named function, the tests import them directly. The divide-by-zero test proves our guard works — the difference between a toy and a reliable tool.
5 The Interface
What it expects
Choose an operation (1-4): 1
First number: 8
Second number: 5What it returns
Result: 13.06 Run It & Automate It
python3 calculator.pyPick an operation, enter two numbers, get the result.
Jenkins runs the tests automatically — each line explained below.
1. Add 2. Subtract 3. Multiply 4. Divide
Choose an operation (1-4): 1
First number: 8
Second number: 5
Result: 13.0ZeroDivisionError.if b == 0: return "Cannot divide by zero"."1", "2", etc.// Jenkinsfile — automated tests on every change.
pipeline {
agent any
stages {
stage('Get the code') { steps { checkout scm } } // download the code
stage('Install') { steps { sh 'python3 -m venv venv && . venv/bin/activate && pip install pytest' } } // test tool
stage('Test') { steps { sh '. venv/bin/activate && pytest -v' } } // run every test
}
post {
success { echo 'All tests passed.' }
failure { echo 'A test failed — look above.' }
}
}
- Keep calculating. Loop so the user can do many sums. (Teaches: a while loop.)
- More operations. Add power and remainder. (Teaches: more functions.)
- Use a dictionary. Map choices to functions to shrink the if/elif chain. (Teaches: dictionaries of functions.)