1 The Problem
We want a program that takes a bill amount and a tip percentage, works out the tip and the new total, and can split it between people. It is a genuinely useful tool, and it teaches percentages, division, and clean money formatting.
2 How to Think About It
Think about the maths before the code:
3 The Build — explained part by part
Here is the complete tip calculator, explained line by line below.
# A tip calculator that also splits the bill.
bill = float(input("Bill amount: "))
tip_percent = float(input("Tip percent (e.g. 15): "))
people = int(input("Split between how many people? "))
# Work out the tip, then the total, then each person's share.
tip = bill * (tip_percent / 100)
total = bill + tip
per_person = total / people
# :.2f means "show two decimal places", like real money.
print(f"Tip: ${tip:.2f}")
print(f"Total: ${total:.2f}")
print(f"Each person pays: ${per_person:.2f}")
tip_percent = float(...) — read the tip percent, like 15.
people = int(...) — read how many people. This is a whole number (you cannot have half a person).
tip = bill * (tip_percent / 100) — turn the percent into a fraction (15 becomes 0.15) and multiply. The brackets make sure the division happens first.
total = bill + tip and per_person = total / people — simple addition and division.
{tip:.2f} — the
:.2f formats the number with exactly two decimal places, so $3.5 shows as $3.50 like real money.
bill * tip_percent / 100 without thinking about order — it happens to work, but bill * (tip_percent/100) makes the intent clear.:.2f — then $3.5 shows instead of $3.50, which looks wrong for money.:.2f for two decimal places.int() for the bill — then $19.99 becomes $19.float() for money so cents are kept.4 Test & Prove Each Part
We test the maths against amounts we can work out by hand — a $100 bill at 10% should give a $10 tip and a $110 total.
def calculate(bill, tip_percent, people):
"""Return (tip, total, per_person) for a bill."""
tip = bill * (tip_percent / 100)
total = bill + tip
return tip, total, total / people
def test_ten_percent():
"""10% of $100 is $10."""
tip, total, _ = calculate(100, 10, 1)
assert tip == 10
assert total == 110
def test_split_in_two():
"""Splitting $110 between 2 people is $55 each."""
_, _, per = calculate(100, 10, 2)
assert per == 55
def test_zero_tip():
"""A 0% tip means total equals the bill."""
_, total, _ = calculate(50, 0, 1)
assert total == 50
Run with pytest -v. We pulled the maths into a calculate function so tests can check it directly against hand-worked answers.
5 The Interface
What it expects
Bill amount: 80
Tip percent: 15
Split between how many people? 4What it returns
Tip: $12.00
Total: $92.00
Each person pays: $23.006 Run It & Automate It
python3 tip.pyEnter the bill, tip percent, and number of people.
Jenkins runs the tests automatically — each line explained below.
Bill amount: 80
Tip percent (e.g. 15): 15
Split between how many people? 4
Tip: $12.00
Total: $92.00
Each person pays: $23.00ZeroDivisionError.ValueError on the bill.49.99.// Jenkinsfile — automated tests on every change.
pipeline {
agent any
stages {
stage('Get the code') { steps { checkout scm } }
stage('Install') { steps { sh 'python3 -m venv venv && . venv/bin/activate && pip install pytest' } }
stage('Test') { steps { sh '. venv/bin/activate && pytest -v' } }
}
post {
success { echo 'The maths checks out.' }
failure { echo 'A calculation is wrong — look above.' }
}
}
- Round up per person. So the tip is always covered. (Teaches:
math.ceil.) - Suggest tip levels. Show 10%, 15%, and 20% side by side. (Teaches: doing the maths three times.)
- Guard zero people. Ask again instead of crashing. (Teaches: input validation.)
float and int, and money formatting with :.2f — the toolkit for any app that handles money. Related: f-strings, Variables & Types.