Readability
Indentation
Per convention, you should indent your code with 4 spaces.
Refactoring
You should consider refactoring your code. This will allow the code to be more readable and will also allow you to reuse it. As Piotr mentioned it, the four functions can be extracted, which would essentially cover first two of his points.
Otherwise, the variable naming is good and easy to understand, following the PEP-8 guide. You can give the guide a read, to understand and follow a good style practice.
Variable input & logic
If you intend to assign a string to a variable using input
, you don't need to specifically convert it to str
. That is because input
automatically assumes the variable to be a string.
Run the following snippet to see for yourself:
new_variable = input('Enter some text: ')
print(type(new_variable))
Abundance of redundant variables & cluttered logic
Your code has too many variables that hold no real purpose. Your store
and total
variables are redundant, as you can work directly off your input.
Operators
height_store = height_store + user_height
total_height = (height_store * height_store)
You can re-write the above two lines using operators. They would look like this:
height_store += user_height
total_height = height_store ** 2
We won't use the first operator in this instance, as it won't be needed. We can narrow that block of logic down to the following code, which still works as intended.
user_weight = float(input('Please enter your weight(kg): '))
user_height = float(input('Please enter your height(m): '))
body_mass_index = (user_weight / user_height ** 2)
print(round(body_mass_index, 1))
BMI Result
The direction of comparison operators doesn't seem to be correct in your block of if statements. If statements don't require parentheses.
if 18.5 < body_mass_index < 25:
print('Normal weight')
elif 25 < body_mass_index < 30:
print('Overweight')
elif body_mass_index > 30:
print('Obese')
else:
print('Underweight')
Also, you seemed to be missing a check for an underweight BMI.
Refactoring
Now that the logic is no longer cluttered, we can put it into different functions. Within those, we can restrain user input to certain values and handle errors. We will also some of the logic into a class.
As the tallest man ever was 2.72 meters tall, we are going to use that as the upper bound for _get_user_info
.
class BodyMassIndex:
def __init__(self, weight, height):
self.weight = weight
self.height = height
@property
def body_mass_index(self):
return round(self.weight / self.height ** 2, 1)
@property
def score(self):
if 18.5 < self.body_mass_index < 25:
return 'normal weight'
elif 25 < self.body_mass_index < 30:
return 'overweight'
elif self.body_mass_index > 30:
return 'obese'
else:
return 'underweight'
def print_score(self):
print('Your Body Mass Index score is: {}'.format(self.body_mass_index))
print('You are {}'.format(self.score))
def _get_user_info():
while True:
try:
weight = float(input('Enter weight in kilograms: '))
height = float(input('Enter height in meters: '))
if 0 < weight and 0 < height < 2.72:
return weight, height
else:
raise ValueError('Invalid height or weight')
except ValueError:
print('Invalid height or weight input')
continue
def calculate_bmi():
weight, height = _get_user_info()
return BodyMassIndex(weight, height)
if __name__ == '__main__':
bmi = calculate_bmi()
bmi.print_score()
calculate_bmi
functions gets user input and returns an instance of BodyMassIndex
class, which performs the logic. If you want to handle weight and height input separately, you can split _get_user_info
into two separate functions, _get_user_weight
and _get_user_height
.
Now, when we run the code, this is how it will behave:
Enter weight in kilograms: 78
Enter height in meters: 1.8
Your Body Mass Index score is: 24.1
You are normal weight
The code is perfectly reusable and you can use it as a module and import it in other programs.
>>> bmi = calculate_bmi()
Enter weight in kilograms: 78
Enter height in meters: 1.8
>>> bmi.height
1.8
>>> bmi.weight
78.0
>>> bmi.body_mass_index
24.1
>>> bmi.score
'normal weight'