BMI calculator in python using if statements I am a beginner in the python language. I wrote a BMI calculator and I am wondering if there are any improvements I could make to the code. This is the code below:

print('Enter your weight in kilo:')
weightInKilo = float(input())

print('Enter your height in feet:')

heightInFeet = float(input())

heightInMeter = heightInFeet * 12 * 0.025

bodyMassIndex = weightInKilo / (heightInMeter ** 2)

if bodyMassIndex &lt; 15:
    print('Your BMI = ' + str(bodyMassIndex)  + ' You are very severely underweight.')

elif bodyMassIndex &gt;= 15 and bodyMassIndex &lt;= 16 :
    print('Your BMI = ' + str(bodyMassIndex)     + ' You are severely underweight.')

elif bodyMassIndex &gt; 16 and bodyMassIndex &lt;= 18.5:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are underweight.')

elif bodyMassIndex &gt; 18.5 and bodyMassIndex &lt;= 25:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are Normal(healthy weight).')

elif bodyMassIndex &gt; 25 and bodyMassIndex &lt;= 30:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are overweight.')


elif bodyMassIndex &gt; 30 and bodyMassIndex &lt;= 35:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are moderately obese.')

elif bodyMassIndex &gt; 35 and bodyMassIndex &lt;= 40:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are severely obese.')

elif bodyMassIndex &gt; 40:
    print('Your BMI = ' + str(bodyMassIndex) + ' You are very severely obese.')

input('Please press Enter to exit')
This kind of programming exercice, despite its apparent simplicity, is a good opportunity to learn various things.

Style

Python has a Code Style guide called PEP 8. If you begin with Python, I highly recommend reading it every now and then and trying to apply it.

In your case, a few things could be improved regarding style:


blank lines between the different branches of if are more an inconvenience from my point of view
variables should follow the snake_case naming convention (instead of camelCase)


Builtin input

As you've noticed for the end of the function, the input builtin takes an optional prompt parameter. This could be used at the beginning of the function as well.

Duplicated code

A lot of code looks like the same line with minimal variations. Having duplicated code makes the code more tedious to read and harder to maintain (if you need to change something, you'll need to change it in many places). One of the principles of software programming is Don't Repeat Yourself (also written DRY).

In your case, we could store the body category in a variable and only print the ouput from a single place:

Chained comparison

This is very specific to Python but instead of body_mass_index &gt; 30 and body_mass_index &lt;= 35, we can write: 30 &lt; body_mass_index &lt;= 35 using chained comparisons.

Magic numbers

Magic Numbers are usually frowned upon. In our case, one needs a bit of thinking to understand where the 12 and 0.025 come from. A better way to handle this is to store them in a variable with a meaningful name.

I am not quite sure about the best naming convention for names related to conversion constant. I've followed the names suggested by Solomon Ucko in the comments.



At this stage, we have the following code:

INCHES_PER_FOOT = 12
METERS_PER_INCH = 0.0254

weight_in_kilo = float(input('Enter your weight in kilo:'))
height_in_feet = float(input('Enter your height in feet:'))

height_in_meter = height_in_feet * INCHES_PER_FOOT * METERS_PER_INCH
body_mass_index = weight_in_kilo / (height_in_meter ** 2)

if body_mass_index &lt; 15:
    category = 'very severely underweight'
elif 15 &lt;= body_mass_index &lt;= 16 :
    category = 'severely underweight'
elif 16 &lt; body_mass_index &lt;= 18.5:
    category = 'underweight'
elif 18.5 &lt; body_mass_index &lt;= 25:
    category = 'Normal(healthy weight)'
elif 25 &lt; body_mass_index &lt;= 30:
    category = 'overweight'
elif 30 &lt; body_mass_index &lt;= 35:
    category = 'moderately obese'
elif 35 &lt; body_mass_index &lt;= 40:
    category = 'severely obese'
elif body_mass_index &gt; 40:
    category = 'very severely obese'

print('Your BMI = ' + str(body_mass_index) + ' You are ' + category + '.')
input('Please press Enter to exit')


Which can still be improved.



Mutually exclusive conditions

Because of the way we check body_mass_index, if it is under 15, we get into the first case so there is no need to check elif 15 &lt;= body_mass_index in the else part. This is guaranteed to be always true. Similarly, half the checks have no effect.

Code organisation

To make the code easier to understand (and easier to reuse, to test, etc), it is a good habit to split in into smaller reusable chunks. In our case, defining functions could be a nice touch.

Disclaimer: Next paragraph can be a bit overwhelming for a beginner, do not worry if you do not fully get it. It highlights how to solve problems you may not be interested in yet but it is a good chance to do things properly.

Also, if we want to be able to actually reuse your functions, we want to be able to import the file. Currently, if we do so, we get stuck into the parts asking for user inputs. Thus, the usual strategy is the following: split your code into 2 parts:


code defining functions/constants/classes/etc but without any side-effect or user interactions
code actually doing things (input/output, etc) behind an if __name__ == "__main__": guard. As pointed out by Solomon Ucko, it's generally a good idea to have this performed via a main() function and have the last two (non-blank) lines be if __name__ == '__main__': main(). This allows the interactivity to be triggered as needed.




At this stage, we have:

INCHES_PER_FOOT = 12
METERS_PER_INCH = 0.0254

def convert_feet_to_meter(height_in_feet):
    return height_in_feet * INCHES_PER_FOOT * METERS_PER_INCH

def get_body_mass_index(height_in_meter, weight_in_kilo):
    return weight_in_kilo / (height_in_meter ** 2)

def get_category(body_mass_index):
    if body_mass_index &lt; 15:
        return 'very severely underweight'
    elif body_mass_index &lt;= 16 :
        return 'severely underweight'
    elif body_mass_index &lt;= 18.5:
        return 'underweight'
    elif body_mass_index &lt;= 25:
        return 'Normal(healthy weight)'
    elif body_mass_index &lt;= 30:
        return 'overweight'
    elif body_mass_index &lt;= 35:
        return 'moderately obese'
    elif body_mass_index &lt;= 40:
        return 'severely obese'
    else:
        return 'very severely obese'

def main():
    weight_in_kilo = float(input('Enter your weight in kilo:'))
    height_in_feet = float(input('Enter your height in feet:'))
    height_in_meter = convert_feet_to_meter(height_in_feet)
    body_mass_index = get_body_mass_index(height_in_meter, weight_in_kilo)
    category = get_category(body_mass_index)
    print('Your BMI = ' + str(body_mass_index) + ' You are ' + category + '.')
    input('Please press Enter to exit')

if __name__ == "__main__":
    main()




Going further, a few more details could be improved.

String formatting

Python offers many tools to format strings so that you do not need to use string concatenations. You can refer to PyFormat.info for documentations and examples.

You could write:

print('Your BMI = %f You are %s.' % (body_mass_index, category))


Or the newer technique:

print('Your BMI = {} You are {}.'.format(body_mass_index, category))


Also, in Python 3.6, yet another soution was added: F-strings.

Data over code

This may be a bit overkill here but sometimes a lot of code can be replaced by a small amount of code working on a properly filled data structure. In our case, the get_category function does the same thing for all categories: check the if we are under a given limit and if so, return the category name.

Disclaimer: Next part works under the assumption that body_mass_index &lt; 15 should actually use &lt;= like the other cases.

# List of pairs (higher-limit, name) sorted
CATEGORIES = [
    (15, 'very severely underweight'),
    (16, 'severely underweight'),
    (18.5, 'underweight'),
    (25, 'Normal(healthy weight)'),
    (30, 'overweight'),
    (35, 'moderately obese'),
    (40, 'severely obese'),
]

def get_category(body_mass_index):
    for limit, name in CATEGORIES:
        if body_mass_index &lt;= limit:
            return name
    return 'very severely obese'