r/CodingHelp • • Jan 18 '22

[Python] Just started learning python as my first language. It seems a BMI calculator is a popular first project so I made one. I was wondering if there was any way to simplify all of the If statements. Are they loopable for something like this?

Post image
127 Upvotes

30 comments sorted by

6

u/calihotsauce Jan 18 '22

A switch statement would also work and be easier to read

3

u/mrdiddlebot Jan 18 '22

No idea what this is but, from a brief google search, it looks like a function that works like a bunch of If statements??? Seems very useful if thats right.

5

u/soumendra Jan 18 '22

This is not right. Search for match and case statement in Python.

3

u/calihotsauce Jan 18 '22

Yeah it’s another type of control structure, it’s used when you want to compare the same thing multiple times like you’re doing here. It has some features that make it more useful than a big if else block.

2

u/skellious Intermediate Coder Jan 19 '22

if statements are like playing 20 questions. you ask each one in turn, and the person says if you are right or not.

switch (match/case) is like asking someone "what age group are you in?" and they just tell you the group they fit into.

10

u/serg06 Jan 18 '22

Is it loopable?

For sure!

from collections import OrderedDict
from math import inf
from numbers import Number

WEIGHTS = OrderedDict((
    (18.5, 'underweight'),
    (25, 'a normal weight'),
    (30, 'overweight'),
    (35, 'obesity class 1'),
    (40, 'obesity class 2'),
    (inf, 'obesity class 3')
))

def get_weight_name(weight: Number) -> str:
	for [max_weight, name] in WEIGHTS.items():
		if weight < max_weight:
			return name

	raise Error('unreachable')

print(name, 'Your BMI is', round(bmi, 2), 'You are', get_weight_name(bmi))

3

u/mrdiddlebot Jan 18 '22

I only just learned about importing things after I made the calculator so I’ll have to look around for other methods like this 👍🏾

13

u/Goobyalus Jan 18 '22

We could just use a tuple of tuples instead of a dict cause we're not using the mapping anyway:

BMI_THRESHOLDS = (
    (18.5, 'underweight'),
    (25, 'a normal weight'),
    (30, 'overweight'),
    (35, 'obesity class 1'),
    (40, 'obesity class 2'),
    (inf, 'obesity class 3'),
)

for threshhold, category in BMI_THRESHOLDS:
    ...

4

u/serg06 Jan 18 '22

Oopsie what was I thinking.

5

u/SantaClausNL Jan 18 '22

Others have given some good suggestions, so I just wanted to say that you are doing great! The project and style looks good, the screenshot fantastic, your eagerness to learn and the ability to think of part of a solution are all awesome. You'll definitely get further so keep at it and welcome to the community :).

3

u/mrdiddlebot Jan 18 '22

This is very encouraging, thank you l!! Learning to code marks what I hope to be a big career shift for me so I’m looking for as much instruction as possible. Don’t really have the money to go back to school so YouTube and forums is all I’ve got for now.

4

u/sai-kiran Jan 18 '22 edited Jan 18 '22

Did you just implement an advanced AI that can calculate your BMI intelligently just based on your height and weight parameters? I don’t believe that you are a beginner.

update: just a joke on the AI humour

1

u/mrdiddlebot Jan 18 '22

Lol, I just watched a CS Dojo video then tried it myself a couple times 😅

0

u/schlopp96 Jan 18 '22

No. No they did not lol.

36

u/atamicbomb Jan 18 '22

You only need one compare for each. Example:

If bmi < 18.5:

Elif bmi <=24.9:

25

u/Meatwad1313 Jan 18 '22 edited Jan 18 '22

This is an important concept. Let’s just consider these two conditions. If less than 18.5. For your code to reach the next elif statement, bmi MUST be greater than or equal to 18.5. So there is no need to check that part again

5

u/DarkSideOfGrogu Jan 19 '22

OP, think about what happens in your code if the users BMI is 24.91?

15

u/[deleted] Jan 18 '22

What I would do is have the if statement set a variable like weight_description or something along those lines, then you only need to put the print statement once at the end

9

u/GoodPrimordialSoup Jan 18 '22

You could try creating a dictionary with descriptions as keys and the corresponding ranges as dictionary values and then return the key based on where the number (rounded down, so floor) is located.
Also, I think you made an error in the comparison: lines 20 and 22, both conditions are valid for BMI values between 34.0 and 34.9.

2

u/breezy_shred Jan 19 '22

This was my thought. Then just map the dictionary.

6

u/Nightcorex_ Jan 18 '22

You can shorten the if-statements. In Python this

if bmi >= 10 and bmi <= 14.9

can be shortened to:

if 10 <= bmi <= 14.9

But you should probably use

if 10 <= bmi < 15

just so you clearly cover the entire range

1

u/mrdiddlebot Jan 18 '22

I appreciate all the comments! I’ll take a look at each when I get back to my desk.

3

u/s96g3g23708gbxs86734 Jan 18 '22

i'd store the different categories in a container a part, then find which category based on the bmi and print only once

2

u/AmirVered Jan 18 '22

I like the graphic

2

u/Full_Ad_5269 Jan 19 '22

A dictionary would be ideal imo

2

u/[deleted] Jan 19 '22

Why can’t you just have switch, case, range like Swift. Much more readable.

2

u/Danteg Jan 19 '22

Also note that there are gaps in your ranges. What happens if the BMI turns out to be 24.95?

1

u/[deleted] Feb 17 '22

Using bmi may help!