How to calculate BMI in Python

Learn how to calculate BMI in Python. This guide covers different methods, real-world applications, and debugging common errors.

How to calculate BMI in Python
Published on: 
Mon
Apr 6, 2026
Updated on: 
Wed
Apr 8, 2026
The Replit Team

To calculate Body Mass Index (BMI) in Python is a common task in health and fitness applications. Python's simple syntax makes it easy to implement the standard BMI formula.

In this article, you'll discover several techniques to compute BMI. We explore practical tips, real-world use cases, and provide advice to debug your code for accurate results.

Basic BMI calculation

weight = 70 # weight in kilograms
height = 1.75 # height in meters
bmi = weight / (height ** 2)
print(f"BMI: {bmi:.2f}")--OUTPUT--BMI: 22.86

This snippet directly translates the standard BMI formula into code. It divides the weight by the height squared, using the ** operator for exponentiation. This approach is both efficient and easy to read, making it a common first step in building health-related applications.

Notice the output formatting. The code uses an f-string with the :.2f specifier to round the final BMI to two decimal places. This small detail is crucial for presenting health data in a clear, conventional format.

Different ways to calculate BMI

You can enhance the basic script by encapsulating the logic in a function, accepting user input, and adding validation with try-except blocks.

Using a function for BMI calculation

def calculate_bmi(weight, height):
return weight / (height ** 2)

weight = 70 # kg
height = 1.75 # meters
bmi = calculate_bmi(weight, height)
print(f"BMI: {bmi:.2f}")--OUTPUT--BMI: 22.86

Wrapping the logic in a calculate_bmi function makes your code more modular and organized. This function accepts weight and height as arguments, performs the calculation, and returns the result. This approach separates the core logic from the rest of your script, which is a fundamental practice in clean coding.

  • Reusability: You can call the function multiple times with different inputs without rewriting the formula.
  • Readability: The main part of your code becomes cleaner and easier to understand at a glance.

Getting user input for BMI calculation

weight = float(input("Enter weight in kg: "))
height = float(input("Enter height in meters: "))
bmi = weight / (height ** 2)
print(f"BMI: {bmi:.2f}")--OUTPUT--Enter weight in kg: 70
Enter height in meters: 1.75
BMI: 22.86

This approach makes your script interactive by using the input() function to gather data directly from the user. The function displays a prompt, like "Enter weight in kg:", and captures the user's response.

  • A crucial step is converting the input. The input() function returns data as a string, so you must use float() to change it into a number suitable for mathematical operations.

Using try-except for input validation

try:
weight = float(input("Enter weight in kg: "))
height = float(input("Enter height in meters: "))
if weight <= 0 or height <= 0:
print("Weight and height must be positive values")
else:
bmi = weight / (height ** 2)
print(f"BMI: {bmi:.2f}")
except ValueError:
print("Please enter valid numbers")--OUTPUT--Enter weight in kg: 70
Enter height in meters: 1.75
BMI: 22.86

This version introduces a try-except block to make your script more robust. It anticipates and handles errors gracefully, preventing crashes from invalid user input. This approach separates normal execution from error handling, which is a cornerstone of writing resilient code.

  • The try block attempts to convert the input to a number. If the user enters text, a ValueError occurs, and the code jumps to the except block to print a helpful message.
  • An if statement provides further validation, ensuring the weight and height are positive numbers—a crucial logical check for a valid BMI calculation.

Advanced BMI calculations

With a robust script for calculating BMI, you can now add advanced features like category classification, batch processing with list comprehension, and a BMICalculator class.

Adding BMI category classification

def bmi_category(bmi):
if bmi < 18.5: return "Underweight"
elif bmi < 25: return "Normal weight"
elif bmi < 30: return "Overweight"
else: return "Obesity"

weight, height = 70, 1.75
bmi = weight / (height ** 2)
print(f"BMI: {bmi:.2f}, Category: {bmi_category(bmi)}")--OUTPUT--BMI: 22.86, Category: Normal weight

The bmi_category function adds meaningful context to the raw BMI number. It uses a chain of if/elif/else statements to check the BMI against standard health thresholds and assign a corresponding category. This makes the output far more intuitive for the end-user.

  • The function accepts the calculated bmi as its only argument.
  • It returns a simple string, such as "Underweight" or "Normal weight".

This method effectively separates the classification logic from the core calculation, which is a great practice for keeping your code clean and modular.

Using list comprehension for batch calculations

people = [
{"name": "Alice", "weight": 65, "height": 1.65},
{"name": "Bob", "weight": 80, "height": 1.80},
{"name": "Charlie", "weight": 75, "height": 1.70}
]
bmis = [(p["name"], p["weight"] / (p["height"] ** 2)) for p in people]
for name, bmi in bmis:
print(f"{name}'s BMI: {bmi:.2f}")--OUTPUT--Alice's BMI: 23.88
Bob's BMI: 24.69
Charlie's BMI: 25.95

This example uses a list comprehension to efficiently calculate BMI for multiple people at once. The code processes the people list, applying the BMI formula to each person's data in a single, readable line. This is a classic Pythonic way to handle batch operations.

  • The comprehension builds a new list called bmis, where each item is a tuple containing a person's name and their calculated BMI.
  • This approach is more compact and often faster than writing a traditional for loop to build the new list from scratch.

Creating a BMICalculator class

class BMICalculator:
def __init__(self, weight, height):
self.weight = weight
self.height = height

def calculate(self):
return self.weight / (self.height ** 2)

def get_category(self):
bmi = self.calculate()
if bmi < 18.5: return "Underweight"
elif bmi < 25: return "Normal weight"
elif bmi < 30: return "Overweight"
else: return "Obesity"

calc = BMICalculator(70, 1.75)
print(f"BMI: {calc.calculate():.2f}, Category: {calc.get_category()}")--OUTPUT--BMI: 22.86, Category: Normal weight

Using a BMICalculator class is a great way to bundle data and functionality together. This object-oriented approach uses the __init__ method to store a person's weight and height within an instance of the class. It’s a clean, scalable way to manage more complex logic.

  • The calculate method computes the BMI using the instance's stored data.
  • The get_category method calls the calculate method internally to find the BMI before assigning a category, efficiently reusing your code.

Move faster with Replit

Replit is an AI-powered development platform where all Python dependencies come pre-installed, so you can skip setup and start coding instantly.

While learning to build a BMICalculator class or process data with a list comprehension is useful, Agent 4 helps you move from these techniques to building complete applications. Instead of piecing everything together manually, you can describe the app you want to build and Agent will take it from idea to working product:

  • A web-based health calculator that takes a user's weight and height, calculates their BMI, and displays their health category using the logic from the bmi_category function.
  • A batch analysis tool for a personal trainer that processes a list of clients, calculates the BMI for each, and outputs a formatted report.
  • A simple API that accepts weight and height, returning the calculated BMI and category, built from the BMICalculator class.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

Even a simple BMI script can run into issues, but most errors are easy to anticipate and manage with a bit of foresight.

Handling ZeroDivisionError when height is zero

If a user enters zero for their height, your script will crash with a ZeroDivisionError because dividing by zero is mathematically impossible. You can prevent this by adding a simple check, like the if height <= 0: condition shown earlier, to validate the input before the calculation occurs.

Debugging incorrect imperial to metric unit conversions

Incorrect unit conversions are a common source of logical errors—the code runs without crashing, but the BMI result is wildly inaccurate. This often happens when converting from imperial units like pounds and inches to metric units.

  • Always double-check your conversion factors. For example, one inch is exactly 0.0254 meters.
  • Ensure you're converting both weight and height correctly before they're used in the BMI formula, as a small mistake in either value will skew the final result.

Troubleshooting input type errors in BMI calculation

Python's input() function always returns a string, which can lead to a TypeError if you try to perform math on it directly. Forgetting to convert the input to a number with float() or int() is a frequent mistake.

This is precisely what the try-except block is for. It allows you to attempt the conversion and gracefully handle any ValueError that arises if the user enters non-numeric text, preventing your program from stopping unexpectedly.

Handling ZeroDivisionError when height is zero

Dividing by zero is mathematically impossible, and Python will raise a ZeroDivisionError if you try. In a BMI script, this error crashes your program if the height is 0. The code below sets height to zero to show what happens.

def calculate_bmi(weight, height):
return weight / (height ** 2)

weight = 70 # kg
height = 0 # meters - this will cause an error!
bmi = calculate_bmi(weight, height)
print(f"BMI: {bmi:.2f}")

The function fails because it tries to divide by height when its value is 0, a mathematically impossible operation that triggers a ZeroDivisionError. The following snippet demonstrates how to fix this by validating the input first.

def calculate_bmi(weight, height):
if height <= 0:
raise ValueError("Height must be a positive number")
return weight / (height ** 2)

try:
weight = 70 # kg
height = 0 # meters
bmi = calculate_bmi(weight, height)
print(f"BMI: {bmi:.2f}")
except ValueError as e:
print(f"Error: {e}")

The updated calculate_bmi function now guards against this error. It checks if height is positive before performing the calculation. If the input is invalid, it raises a ValueError with a clear message.

The try-except block then catches this specific error, letting you handle it gracefully without crashing the program. This is a robust way to validate data before it's used in calculations, especially when dealing with user input.

Debugging incorrect imperial to metric unit conversions

This logical error is subtle because the code runs but gives an inaccurate BMI. It often stems from using approximate conversion factors instead of precise ones. The following calculate_bmi_imperial function demonstrates how this can silently skew your results.

def calculate_bmi_imperial(weight_lb, height_in):
# Wrong conversion factors
weight_kg = weight_lb / 2.2
height_m = height_in / 39.37
return weight_kg / (height_m ** 2)

bmi = calculate_bmi_imperial(154, 69)
print(f"BMI: {bmi:.2f}") # Wrong result

The function's use of approximate divisors like 2.2 and 39.37 introduces small rounding errors. These inaccuracies compound, leading to an incorrect final BMI. The following code demonstrates the proper way to handle these conversions for an accurate result.

def calculate_bmi_imperial(weight_lb, height_in):
# Correct conversion factors
weight_kg = weight_lb * 0.45359237
height_m = height_in * 0.0254
return weight_kg / (height_m ** 2)

bmi = calculate_bmi_imperial(154, 69)
print(f"BMI: {bmi:.2f}") # Correct result

The corrected calculate_bmi_imperial function ensures accuracy by using precise multiplication factors, like 0.45359237 for pounds to kilograms, instead of approximate division. This prevents the subtle rounding errors that can skew your results.

You should always use standard conversion values when your code handles different measurement systems. This is a critical detail for any application that needs to support both metric and imperial units, as small inaccuracies can lead to significantly incorrect outcomes.

Troubleshooting input type errors in BMI calculation

Python's input() function always returns a string, which will cause a TypeError if you try to use it in a calculation. Forgetting to convert the input to a number is a frequent mistake. The following code shows this problem in action.

height_str = input("Enter height in meters: ")
weight_str = input("Enter weight in kg: ")
bmi = float(weight_str) / (float(height_str) ** 2)
print(f"BMI: {bmi:.2f}")

This script fails if the user provides non-numeric input. The float() function can't convert text into a number, triggering a ValueError. The following code shows how to anticipate and manage this potential crash.

try:
height_str = input("Enter height in meters: ")
weight_str = input("Enter weight in kg: ")
height = float(height_str)
weight = float(weight_str)
bmi = weight / (height ** 2)
print(f"BMI: {bmi:.2f}")
except ValueError:
print("Please enter numeric values for height and weight")

This solution uses a try-except block to safely handle user input. It attempts to convert the input strings to numbers using float(). If a user enters text instead of a number, Python raises a ValueError. The except block then catches this error, prints a helpful message, and prevents the program from crashing. This is a crucial pattern to use whenever you're working with raw user input from the input() function.

Real-world applications

With your code now robust against common errors, you can build practical applications for handling mixed units and tracking BMI history.

Creating a BMI calculator for imperial and metric units

A flexible function can handle both measurement systems, making your calculator more versatile for a global audience.

This updated calculate_bmi function accepts an optional third argument, system, which defaults to "metric". An if statement checks this argument; if you pass "imperial", the function converts the weight and height from pounds and inches to kilograms and meters before calculating the BMI. Otherwise, it proceeds with the metric values as is.

This design elegantly solves the unit conversion problem by centralizing the logic in one place. You no longer need separate functions or manual conversions, which reduces the risk of errors.

  • The function uses a system parameter to decide which conversion logic to apply.
  • It performs the correct imperial-to-metric conversions internally when needed.
  • By default, it assumes metric units, so your existing code won't break.

def calculate_bmi(weight, height, system="metric"):
if system.lower() == "imperial":
# Convert pounds to kg, inches to meters
weight_kg = weight * 0.45359237
height_m = height * 0.0254
else:
weight_kg = weight
height_m = height

return weight_kg / (height_m ** 2)

# Metric calculation (kg, meters)
print(f"Metric: {calculate_bmi(70, 1.75):.2f}")
# Imperial calculation (pounds, inches)
print(f"Imperial: {calculate_bmi(154, 69, 'imperial'):.2f}")

This function demonstrates a powerful pattern: normalizing data before processing. It uses an optional system argument to decide how to handle the inputs, making the function versatile. This approach simplifies the main logic by handling variations at the entry point.

  • If the system is imperial, it first converts the inputs to metric. The .lower() method makes this check robust against capitalization differences.
  • The core formula, weight_kg / (height_m ** 2), then always operates on a consistent set of units, ensuring an accurate calculation.

Tracking BMI history with CSV files

You can track BMI changes over time by saving each calculation to a CSV file, creating a simple yet effective historical log.

The log_bmi function automates this process using Python's built-in csv and datetime modules. It takes a person's details, calculates their BMI, and captures the current date. Then, it bundles this information to be saved.

The function writes this data to a file named bmi_history.csv. It uses the with open(...) statement, which is a safe way to handle files. Here’s how it works:

  • It opens the file in append mode ('a'), which adds new data to the end of the file without erasing previous entries.
  • The csv.writer object correctly formats your data into a comma-separated row.
  • Finally, writerow writes the list containing the date, name, and health metrics into the file.

After logging the data, the function returns the calculated BMI, so you can still use the value elsewhere in your program, just as the final print statement demonstrates.

import csv
from datetime import datetime

def log_bmi(name, weight, height):
bmi = weight / (height ** 2)
today = datetime.now().strftime('%Y-%m-%d')

with open('bmi_history.csv', 'a', newline='') as file:
csv.writer(file).writerow([today, name, weight, height, f"{bmi:.2f}"])

return bmi

alice_bmi = log_bmi("Alice", 65, 1.65)
print(f"Alice's BMI: {alice_bmi:.2f} - Logged to bmi_history.csv")

The log_bmi function efficiently combines calculation with data persistence. It captures the current date using datetime.now().strftime('%Y-%m-%d') for consistent formatting before appending a new record to bmi_history.csv.

  • The with open(...) statement ensures the file is handled safely, and using newline='' is crucial for preventing extra blank rows in your CSV output.
  • After writing the data, the function returns the raw BMI value, so you can use it immediately in your program.

Get started with Replit

Now, turn these concepts into a real tool. Describe what you want to build to Replit Agent, like "a web-based BMI calculator for metric and imperial units" or "a script to process a client CSV and output their BMIs".

Replit Agent will write the code, test for errors, and help you deploy your application directly from your browser. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.