python中的BMI计算器:if语句如何减少太多?

时间:2018-02-18 23:04:30

标签: python python-3.x

我是编程方面的新手,已经开始学习python。我在python中编写了我自己的第一个BMI计算器,不知怎的,我对我的代码并不满意。我想我的代码中有太多if语句,想知道如何减少它?您能否给我一些建议或建议如何使该脚本更好,更动态?

亲切的问候!!

gender = input("Are you a male(m) or female(f): ")
age = int(input("How old are you: "))
weight = float(input("How much do you weigh in kilograms?: "))
height = float(input("What is your height in centimeters: "))


bmi = round(weight / ((height/100) ** 2))

if bmi in range(19, 24) and age in range(19, 24):
    print("Your BMI is optimal for your age!")
elif bmi in range(25, 34) and age in range(20, 25):
    print("Your BMI is optimal for your age!")
elif bmi in range(35, 44) and age in range(21, 26):
    print("Your BMI is optimal for your age!")
elif bmi in range(45, 54) and age in range(22, 27):
    print("Your BMI is optimal for your age!")
elif bmi in range(55, 64) and age in range(23, 28):
    print("Your BMI is optimal for your age!")
elif bmi >= 65 and age in range(24, 29):
    print("Your BMI is optimal for your age!")
else:
    print("Your BMI is not okay for your age!!!")

if bmi < 20 and gender == "m":
    print("Your BMI is",str(bmi)+". That means underweight")
elif bmi < 19 and gender == "f":
    print("Your BMI is",str(bmi)+". That means underweight")
elif bmi in range(20, 25) and gender == "m":
    print("Your BMI is",str(bmi)+". That means normal weight")
elif bmi in range(19, 24) and gender == "f":
    print("Your BMI is",str(bmi)+". That means normal weight")
elif bmi in range(26, 30) and gender == "m":
    print("Your BMI is",str(bmi)+". That means overweight")
elif bmi in range(25, 30) and gender == "f":
    print("Your BMI is",str(bmi)+". That means overweight")
elif bmi in range(31, 40) and gender == "m":
    print("Your BMI is",str(bmi)+". That means obesity")
elif bmi in range(31, 40) and gender == "f":
    print("Your BMI is",str(bmi)+". That means obesity")
elif bmi > 40 and gender == "m":
    print("Your BMI is",str(bmi)+". That means strong obesity")
elif bmi > 40 and gender == "f":
    print("Your BMI is",str(bmi)+". That means strong obesity")
else:
    print("Your BMI is",bmi)

3 个答案:

答案 0 :(得分:2)

好的,这里有很多需要改进的地方。

  • 没有对性别输入进行验证,因此可以输入无法识别的值,尽管这似乎是在最后的其他情况下处理的,其中只打印了没有解释的BMI。
  • if bmi in range(19, 24)表示&#34;如果bmi具有值19,20,21,22,23和#34;之一。因此,如果bmi为24,这不仅会失败,而且效率非常低,如果您决定更改为BMI的浮动值,则会中断。使用大于和小于检查值是否在一个范围内会好得多。
  • 您在if语句中交换了agebmiif bmi >= 65 and age in range(24, 29)表明,对于25岁的人来说,BMI至少为65是最佳的!
  • 不处理年龄小于19岁的人。他们总会被告知他们的BMI不是最佳的。
  • 所有重复的印刷语句都做同样的事情。一个快速的改进是设置一个名为&#34; is_bmi_optimal&#34;的布尔变量。或类似的,在if情况下,然后在最后有一个if is_bmi_optimal进行打印。

至于你如何减少if语句数量的实际问题,你需要用某种方法来替换它们,在数据结构中定义年龄范围和相应的bmi范围,然后迭代它们。 / p>

这是使用bisect模块的方法。 Bisect用于按排序顺序维护列表,但它也可用于搜索排序列表以查找新值适合的位置,从而维护排序顺序。这意味着它可以用于通过将这些范围定义为每个范围的最小值列表来查找值在一系列范围内的位置。因此,您的年龄范围为19-24,25-35,35-44,45-54,55-64,65 +将表示为列表[25,35,45,55,65]和bisect.bisect_left会告诉我们任何年龄在该列表中的位置,从0(小于25)到5(65或更高)的值。

import bisect

gender = input("Are you a male(m) or female(f): ")
age = int(input("How old are you: "))
weight = float(input("How much do you weigh in kilograms?: "))
height = float(input("What is your height in centimeters: "))

bmi = round(weight / ((height/100) ** 2))

if age < 19:
    print("You're too young for this and I'm concerned you may be at risk of developing an eating disorder.")
    exit()

optimal_bmi_range_min_ages = [25, 35, 45, 55, 65]
optimal_bmi_ranges = [(19, 24), (20, 25), (21, 26), (22, 27), (23, 28), (24, 29)]
optimal_bmi_range = optimal_bmi_ranges[bisect.bisect_left(optimal_bmi_range_min_ages, age)]

if bmi >= optimal_bmi_range[0] and bmi <= optimal_bmi_range[1]:
    print("Your BMI is optimal for your age!")
else:
    print("Your BMI is not okay for your age!!!")

bmi_categories = ["underweight", "normal weight", "overweight", "obesity", "strong obesity"]
if gender == "m":
    bmi_cat_thresholds = [20, 26, 31, 41]
elif gender == "f":
    bmi_cat_thresholds = [19, 25, 31, 41]
else:
    print("Your BMI is",bmi)
    exit()

bmi_category = bmi_categories[bisect.bisect_left(bmi_cat_thresholds,bmi)]
print("Your BMI is " + str(bmi) + ". That means " + bmi_category)

答案 1 :(得分:2)

这里有两个问题:

  1. 性能,即算法对大量输入的执行效率。
  2. 可读性和可维护性。
  3. 由于你的程序只查看一组输入,我只考虑其中的第二组。

    代码的第一部分可以用更简单的方式编写:

    bmi = weight / ((height/100) ** 2)
    
    optimal_bmi_age = [((19, 24), (19, 24)), ((25, 34), (20, 25)), ((35, 44), (21, 26)),
                       ((45, 54), (22, 27)), ((55, 64), (23, 28)), ((65, 1000), (24, 29))]
    
    for ((bmi_min, bmi_max), (age_min, age_max)) in optimal_bmi_age:
        if (bmi_min <= bmi <= bmi_max) and (age_min <= age <= age_max):
            print('Your BMI is optimal for your age!')
            break
    else:
        print('Your BMI is not okay for your age!!!')
    

    注意我们在这里做了什么。我们从逻辑中分离参数,即最佳BMI /年龄的边界,即for / else循环和if语句。此过程可以在整个代码中应用。如果您的参数发生变化,这将提高可读性和维护性。

    如果主要关注性能/优化,请参阅@DavidScarlett's solution。该解决方案还实现了分离参数和逻辑的类似想法。

答案 2 :(得分:0)

试试这个

bmiheight=self.heightcm.get()
      print(bmiheight)
      bmiweight=self.weightkg.get()
      bmi= float((bmiweight)/((bmiheight / 100)**2))
      self.bmi = bmi
      print(bmi)
      self.label1=Label(self.master,text='Your BMI is %.2f' % bmi).grid(row=5,column=0)

      if bmi <= 18.5:
           self.label2=Label(self.master,text='This places you in the underweight group.',fg='blue').grid(row=6,column=0)
           totalindex = 'underweight'
           self.totalindex = totalindex
      elif bmi >18.5 and bmi <25:
           self.label3=Label(self.master,text='This places you in the healthy weight group.',fg='green').grid(row=6,column=0)
           totalindex = 'healthy'
           self.totalindex = totalindex
      elif bmi >= 25 and bmi < 30:
           self.label4=Label(self.master,text='This places you in the overweight group.',fg='orange').grid(row=6,column=0)
           totalindex = 'overweight'
           self.totalindex = totalindex
      elif bmi >=30:
           self.label5=Label(self.master,text='This places you in the obese group.',fg='red').grid(row=6,column=0)
           totalindex = 'obese'
           self.totalindex = totalindex

      if bmi >0 and bmi <999999999999999999999:
           self.button6=Button(self.master,text="Store Data",fg='red',command=self.dynamic_data_entry).grid(row=8,column=0)