Editor

BMI Calculator in Python

Beginner · Useful tools · about 30 minutes to build · 93 lines

Enter a weight and height in metric or imperial units and get the BMI, its category and the healthy weight range for that height.

The program

Press Run and answer its questions in the box that appears under the code.

bmi_calculator.py
"""A BMI calculator for metric or imperial units, with the BMI category."""
# Adult BMI categories (WHO): a BMI below each limit gets that name
CATEGORIES = [
(18.5, "Underweight"),
(25.0, "Healthy weight"),
(30.0, "Overweight"),
(float("inf"), "Obesity"),
]
HEALTHY_LOW = 18.5
HEALTHY_HIGH = 24.9
KG_PER_POUND = 0.45359237
METRES_PER_INCH = 0.0254
# Reading measurements
def read_number(prompt, low, high):
"""Ask until the user types a number from low to high."""
while True:
try:
value = float(input(prompt))
except ValueError:
print(" Please type a number, like 72 or 1.5.")
continue
if low <= value <= high:
return value
print(f" Please type a number from {low} to {high}.")
def metric_measurements():
"""Ask for kilograms and centimetres; return (kg, metres)."""
weight_kg = read_number("Weight in kg: ", 10, 400)
height_cm = read_number("Height in cm: ", 50, 250)
return weight_kg, height_cm / 100
def imperial_measurements():
"""Ask for pounds, feet and inches; return (kg, metres)."""
weight_lb = read_number("Weight in pounds: ", 20, 900)
feet = read_number("Height in feet: ", 1, 8)
inches = read_number("Plus inches: ", 0, 11.99)
total_inches = feet * 12 + inches
return weight_lb * KG_PER_POUND, total_inches * METRES_PER_INCH
# Working out the BMI
def bmi_category(bmi):
"""Return the name of the category the BMI falls in."""
for limit, name in CATEGORIES:
if bmi < limit:
return name
return CATEGORIES[-1][1]
def show_result(weight_kg, height_m, imperial):
"""Print the BMI, its category and the healthy range for this height."""
# Round first, so a BMI shown as 25.0 is never called "Healthy weight"
bmi = round(weight_kg / height_m ** 2, 1)
print(f" Your BMI is {bmi}: {bmi_category(bmi)}")
low = HEALTHY_LOW * height_m ** 2
high = HEALTHY_HIGH * height_m ** 2
if imperial:
low, high, unit = low / KG_PER_POUND, high / KG_PER_POUND, "pounds"
else:
unit = "kg"
print(f" A healthy weight for your height is {low:.1f} to {high:.1f} {unit}.")
def main():
"""Ask for the units, then measure and report until the user quits."""
print("BMI calculator")
print("BMI is a rough guide for adults; it does not measure body fat.")
while True:
print()
print("1) Metric (kg, cm) 2) Imperial (pounds, feet, inches) 3) Quit")
choice = input("Choose 1-3: ").strip()
if choice == "1":
weight_kg, height_m = metric_measurements()
show_result(weight_kg, height_m, imperial=False)
elif choice == "2":
weight_kg, height_m = imperial_measurements()
show_result(weight_kg, height_m, imperial=True)
elif choice == "3":
print("Goodbye.")
break
else:
print(" Please choose 1, 2 or 3.")
if __name__ == "__main__":
main()

Open it in the full editor to save it, share it and keep building.

Sample run

What the program printed, and what was typed (in yellow).

BMI calculator
BMI is a rough guide for adults; it does not measure body fat.

1) Metric (kg, cm)  2) Imperial (pounds, feet, inches)  3) Quit
Choose 1-3: 1
Weight in kg: 72
Height in cm: 175
  Your BMI is 23.5: Healthy weight
  A healthy weight for your height is 56.7 to 76.3 kg.

1) Metric (kg, cm)  2) Imperial (pounds, feet, inches)  3) Quit
Choose 1-3: 2
Weight in pounds: 180
Height in feet: 5
Plus inches: nine
  Please type a number, like 72 or 1.5.
Plus inches: 9
  Your BMI is 26.6: Overweight
  A healthy weight for your height is 125.3 to 168.6 pounds.

1) Metric (kg, cm)  2) Imperial (pounds, feet, inches)  3) Quit
Choose 1-3: 1
Weight in kg: 45
Height in cm: 300
  Please type a number from 50 to 250.
Height in cm: 160
  Your BMI is 17.6: Underweight
  A healthy weight for your height is 47.4 to 63.7 kg.

1) Metric (kg, cm)  2) Imperial (pounds, feet, inches)  3) Quit
Choose 1-3: 3
Goodbye.

How it is built

1. The categories as data

Each pair holds the upper limit of a category and its name, from the WHO table for adults. float("inf") makes the last category catch every BMI of 30 and above.

# Adult BMI categories (WHO): a BMI below each limit gets that name
CATEGORIES = [
    (18.5, "Underweight"),
    (25.0, "Healthy weight"),
    (30.0, "Overweight"),
    (float("inf"), "Obesity"),
]

2. Reading a number in range

Letters raise ValueError, and a number outside the range is asked for again. The range catches typos such as 1750 for a height in centimetres.

def read_number(prompt, low, high):
    """Ask until the user types a number from low to high."""
    while True:
        try:
            value = float(input(prompt))
        except ValueError:
            print("  Please type a number, like 72 or 1.5.")
            continue
        if low <= value <= high:
            return value
        print(f"  Please type a number from {low} to {high}.")

3. Imperial to metric

Pounds become kilograms and feet plus inches become metres, so one BMI formula serves both systems.

def imperial_measurements():
    """Ask for pounds, feet and inches; return (kg, metres)."""
    weight_lb = read_number("Weight in pounds: ", 20, 900)
    feet = read_number("Height in feet: ", 1, 8)
    inches = read_number("Plus inches: ", 0, 11.99)
    total_inches = feet * 12 + inches
    return weight_lb * KG_PER_POUND, total_inches * METRES_PER_INCH

4. Finding the category

The loop returns the name of the first category whose limit is above the BMI.

def bmi_category(bmi):
    """Return the name of the category the BMI falls in."""
    for limit, name in CATEGORIES:
        if bmi < limit:
            return name
    return CATEGORIES[-1][1]

5. The result and the healthy range

BMI is the weight in kilograms divided by the height in metres squared. Turning the formula around gives the weights at a BMI of 18.5 and 24.9 for the same height.

def show_result(weight_kg, height_m, imperial):
    """Print the BMI, its category and the healthy range for this height."""
    # Round first, so a BMI shown as 25.0 is never called "Healthy weight"
    bmi = round(weight_kg / height_m ** 2, 1)
    print(f"  Your BMI is {bmi}: {bmi_category(bmi)}")
    low = HEALTHY_LOW * height_m ** 2
    high = HEALTHY_HIGH * height_m ** 2
    if imperial:
        low, high, unit = low / KG_PER_POUND, high / KG_PER_POUND, "pounds"
    else:
        unit = "kg"
    print(f"  A healthy weight for your height is {low:.1f} to {high:.1f} {unit}.")

Make it bigger

  • Add an option for the lower cut-offs some Asian health bodies use, such as 23 for overweight.
  • Ask for the weight in stones and pounds, as many people in the UK give it.
  • Show how many kilograms lie between the weight and the healthy range.
  • Keep a list of readings with dates and show the change since the first one.

What it practises