1 The Problem
We want a flexible unit converter: convert metres to feet, kilograms to pounds, and so on. Rather than a tangle of if-statements, we store the conversion factors in a table and look them up. It teaches data-driven design — using data to drive behaviour instead of hard-coded logic.
2 How to Think About It
Think about how to avoid a mess of if-statements, before any code:
3 The Build — explained part by part
Here is the complete converter. Each part is explained below.
# A data-driven unit converter.
# Each conversion and its multiply-by factor.
factors = {
("m", "ft"): 3.281,
("ft", "m"): 0.3048,
("kg", "lb"): 2.205,
("lb", "kg"): 0.4536,
("km", "mi"): 0.6214,
("mi", "km"): 1.609,
}
print("Units: m, ft, kg, lb, km, mi")
from_unit = input("From: ")
to_unit = input("To: ")
amount = float(input("Amount: "))
key = (from_unit, to_unit)
if key in factors:
result = amount * factors[key]
print(f"{amount} {from_unit} = {result:.3f} {to_unit}")
else:
print("Sorry, that conversion is not available.")
key = (from_unit, to_unit) — build the lookup key from the user’s choices.
if key in factors: — check the conversion exists before trying it, so an unknown pair gives a friendly message instead of a crash.
result = amount * factors[key] — the entire conversion: look up the factor and multiply. One line handles every conversion in the table.
{result:.3f} — show three decimal places for precision.
KeyError.if key in factors first.4 Test & Prove Each Part
We test that conversions use the right factors and that unknown ones are handled safely.
FACTORS = {
("m", "ft"): 3.281,
("ft", "m"): 0.3048,
("kg", "lb"): 2.205,
}
def convert(amount, from_unit, to_unit):
key = (from_unit, to_unit)
if key in FACTORS:
return amount * FACTORS[key]
return None
def test_metres_to_feet():
"""1 metre is about 3.281 feet."""
assert round(convert(1, "m", "ft"), 3) == 3.281
def test_round_trip():
"""Converting there and back is close to the start."""
feet = convert(10, "m", "ft")
back = convert(feet, "ft", "m")
assert round(back) == 10
def test_unknown_conversion():
"""An unknown conversion returns None, not a crash."""
assert convert(5, "m", "kg") is None
Run with pytest -v. The convert function is tiny because the table does the work. Adding a conversion needs only a new table entry — and the tests still pass.
5 The Interface
What it expects
From: m
To: ft
Amount: 10What it returns
10.0 m = 32.810 ft6 Run It & Automate It
python3 convert.pyEnter the units and amount to convert.
Jenkins runs the tests automatically — each line explained below.
Units: m, ft, kg, lb, km, mi
From: m
To: ft
Amount: 10
10.0 m = 32.810 ftKeyError on conversion.// 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.' }
}
}
- Temperature. Add C↔F (needs a formula, not just a factor). (Teaches: when a table is not enough.)
- Auto-reverse. Generate the reverse factor automatically. (Teaches: building data from data.)
- List options. Show all available conversions. (Teaches: reading dictionary keys.)