1. 场景描述

BMI指数(身体质量指数,英文Body Mass Index)是用体重公斤数除以身高米数的平方得出的数字,是目前国际上通用的衡量人体胖瘦程度以及是否健康的一个标准。“身体质量指数”这个概念,是由19世纪中期的比利时数学家凯特勒最先提出来的,BMI指数的计算公式:
BMI=weight/height2BMI = weight / height ^2BMI=weight/height2
其中weight体重的度量单位是公斤,height身高的度量单位是米。
BMI指数的设计初衷是一个用于公共健康研究的统计工具。如果我们需要知道肥胖与某一疾病的致病原因是否相关时,就可以把病人的身高和体重换算为BMI值,再找出BMI值与病发率是否有线性关系。不过,随着医学科技的发展和进步,现在BMI值只是一个参考值,要检测一个人是否肥胖有了更加科学和先进的检测手段。因此BMI的角色也在慢慢地改变,从医学上的用途逐步变为一般大众的纤体指标。事实上,对于健康达人或者是普通的健身爱好者来说,BMI指数已经成为了衡量健身成效的重要标准。
接下来,我们使用Python来编写一个基于图形界面的BMI计算器。


2. 编程思路

2.1 计算公式

BMI=weight/height2BMI = weight / height^2BMI=weight/height2

2.2 判断标准

BMI 值中国标准含义如下:BMI <= 18.4 偏瘦;18.4 < BMI < 24 正常;24.0 <= BMI <28 过重; >= 28 肥胖。

2.3 健康建议

我们可以针对各种形体人群给出相关的健康建议。需要强调的是这些健康建议均取材于互联网,为编写程序的需要,仅供参考:
偏瘦:适度参加体育运动,特别是要多吃鱼、蛋和奶类等各类健康食品。
正常:注重适度运动,平衡的饮食结构,食物多样化,讲究粗细合理搭配。
超重:建议加强体育锻炼,注重食物搭配,特别是少吃高脂肪、高蛋白、含糖高食品,每天40分钟运动。
肥胖:加强体育锻炼,调整饮食结构,少吃或者不吃高脂肪、高蛋白、含糖量高食品,每天40分钟运动。
我们要把这些健康建议保存到文本文件suggestions.txt中,便于以后可以简单地使用Windows Notepad记事本程序就可以修改和完善这些健康建议。而不必修改Python源代码程序,实现数据与程序的分离。为了与我们的程序配套,这个文件保存时需要使用utf8的文件格式。


3. 代码编写

本程序由4个文件组成,它们是:
bmi.py :BMI计算器的图形界面程序。
bmi_base.py:BMI计算器的一些基础函数模块。
suggestions.txt:存放一些与形体相关的健康建议。
calculator.png:BMI计算器的图片文件。

bmi.py 模块的源代码程序

"""bmi.py : BMI的前世今生
"""
from tkinter import *
import tkinter.messagebox as msg_box
from common.bmi_base import *def calculate():""" 计算 BMI值"""try:height = float(v_height.get())weight = float(v_weight.get())except ValueError:msg_box.showinfo('提示', '检查数据:身高或体重!')else:bmi = calc_bmi(height, weight)report = check_report(bmi)advice = make_suggestion(report)v_bmi.set(str(round(bmi, 1)) + '   ' + report)info_area.delete("1.0", END)info_area.insert("1.0", advice)def reset():"""清除输入域内容"""v_height.set('')v_weight.set('')v_bmi.set('')info_area.delete("1.0", END)lbl_height.focus()def initialize():"""初始化屏幕内容"""v_height.set('1.70')v_weight.set('65')lbl_height.focus()calculate()if __name__ == '__main__':root = Tk()root.title('BMI 计算器')root.geometry('350x350+500+300')# 设置初值v_height = StringVar()   # ①v_weight = StringVar()v_bmi = StringVar()v_bmi.set('')# 定义图片photo = PhotoImage(file='calculator.png')   # ②lbl_banner = Label(root, image=photo, compound='top', width=340, height=120)lbl_banner.grid(row=0, column=0, columnspan=4, sticky=N + S + E + W)# 显示身高提示和输入身高Label(root, text='身高 (m)').grid(row=1, column=1, pady=5, sticky=E)   # ③lbl_height = Entry(root, textvariable=v_height)   # ④lbl_height.grid(row=1, column=2)   # ⑤# 定义体重提示和输入体重Label(root, text='体重 (kg)').grid(row=2, column=1, sticky=E)Entry(root, textvariable=v_weight).grid(row=2, column=2)# 定义功能按钮Button(root, text='计算', width=8, command=calculate).grid(row=6, column=1, pady=6, sticky=E)   # ⑥Button(root, text='清空', width=8, command=reset).grid(row=6, column=2)# 定义结果显示字段Label(root, text='BMI').grid(row=5, column=1, pady=5, sticky=E)Entry(root, textvariable=v_bmi).grid(row=5, column=2)Label(text='健康建议').grid(row=8, column=1, pady=5, sticky=E)info_area = Text(width=20, height=4, font=("微软雅黑", 9))   # ⑦info_area.grid(row=8, column=2)# 防止屏幕开"天窗"initialize()   # ⑧# 进入事件驱动模式
root.mainloop()   # ⑨

重要函数说明如下:
函数calculate():计算bmi指数,获取形体诊断结果,提取相关的健康建议。
函数reset():清除BMI计算器界面中的输入域的内容。
函数initialize():初始化界面内容,自动计算一个案例,填充屏幕内容。
重要语句说明如下:
语句①定义与界面控件联动的变量内容,也就是说当屏幕界面控件Entry输入域内容发生变化,将自动映射到关联的变量中,实现同步更新。
语句②加载图片以便与有关屏幕控件关联。
语句③定义有关标签控件,以便存放文本字符串。
语句④定义一个输入域控件,并与变量关联,实现数据同步更新。
语句⑤把控件放到屏幕中的指定位置,这里使用tkinter 的grid布局方式。
语句⑥定义按钮实现与函数的关联绑定。意味着当你鼠标点击这个按钮,将自动执行在参数command中指定的函数代码。
语句⑦使用控件Text定义多行的文本输入框,既能输入内容,又可显示文本。
语句⑧执行初始化的案例计算,并使用计算结果填充屏幕内容,避免在图形界面上开“天窗”,留下空白内容,它会给人造成界面不友好的印象。
语句⑨程序进入事件驱动模式。也就是说当用户点击屏幕界面中的控件时,将执行不同的程序代码。

bmi_base.py 模块的源代码

"""
bmi_base.py : BMI计算器可重用代码
"""
__all__ = ['calc_bmi', 'check_report', 'make_suggestion']   # ①
suggestions = {}def decorate_bmi(func):    # ②"""扩展calc_bmi()函数功能的装饰器"""def wrapper(height, weight):if is_valid(height, weight):return func(height, weight)else:return -1return wrapper@decorate_bmi   # ③
def calc_bmi(height, weight):"""height : 计量单位是米weight : 计量单位是公斤"""bmi = weight / height ** 2bmi = round(bmi, 1)return abs(bmi)def is_number(number):"""判断 number 是数字"""if isinstance(number, int) or isinstance(number, float):   # ④return Trueelse:return Falsedef is_valid(height, weight):"""判断 height,weight有效性"""if height and is_number(height) and is_number(weight):return Trueelse:return Falsedef check_report(bmi):"""bmi : BMI 指数值report : 形体评测结果"""report = '正常'if bmi < 18.5:report = '偏瘦'elif 18.5 <= bmi < 24:report = '正常'elif 24 <= bmi < 28:report = '超重'elif bmi >= 28:report = '肥胖'return reportdef load_suggestions(file_name):"""加载健康建议"""with open(file_name, encoding='utf-8') as file:   # ⑤for line in file:key, value = line.split(':')   # ⑥suggestions[key.strip()] = value.strip()   # ⑦def make_suggestion(report):"""形成健康建议"""if not suggestions:# 一次性加载健康建议load_suggestions('suggestions.txt')if report in suggestions:return suggestions[report]else:return None

重要函数说明:
函数load_suggestions():从文本文件suggestions.txt中读入健康建议,以字典的方式保存,供后续程序访问。
函数make_suggestion():针对不同的体型,生成不同的健康建议。
函数def calc_bmi(height, weight):计算BMI值的函数,需要注意的是调用此函数,将自动执行该函数的装饰器函数decorate_bmi(),以便对height和weight参数的有效性进行检测。
函数decorate_bmi():是一个装饰器函数,用于对calc_bmi()函数的参数进行有效性检测,以增强程序执行的容错能力。
函数check_report(bmi):通过对bmi值进行判断,获得形体类型的结论报告。
函数is_number(number):判断参数number是否是数字。
函数is_valid(height, weight):判断身高height和体重weight参数的有效性。
重要语句说明:
语句①定义本模块中提供的公共接口函数,即是可由其他程序模块调用的函数,以此实现代码重用。
语句②定义装饰器函数。
语句③将装饰器函数decorate_bmi()与被装饰函数calc_bmi(height, weight)建立绑定关系,当程序调用函数calc_bmi()时,首先要调用装饰器函数decorate_bmi(),然后再执行calc_bmi()函数。使用装饰器功能,我们可以在不修改calc_bmi()函数代码的情况下,扩展其功能。这里相当于利用装饰器是实现了对函数calc_bmi()的输入参数height和参数weight进行的合法性检查。
语句④判断某个变量是否是整数或者浮点数。
语句⑤以utf8的方式打开文件,供后续处理。这里需要强调的是文件suggestions.txt是以utf8的格式保存的文本文件。
语句⑥以冒号为分隔符,解析形体类型和健康建议的内容。
语句⑦以形体类型为键,健康建议为值,创建字典suggestions有存放健康建议,供后续代码使用。


4. 执行效果

首先说明程序结构:模块bmi.py、suggestions.txt和calculator.png存放在当前目录:D:\cases\BMI指数的前世今生,而bmi_base.py则是以Python包的形式,存放在目录common中。

D:\cases\BMI指数与健身达人>dir
2022/12/08  11:47             2,442 bmi.py
2020/12/04  17:49            75,504 calculator.png
2022/12/08  14:33    <DIR>          common
2022/12/08  11:59               473 suggestions.txtD:\cases\BMI指数与健身达人>

查询Python包文件内容

D:\cases\BMI指数与健身达人>cd common
D:\cases\BMI指数与健身达人\common>
D:\cases\BMI指数与健身达人\common>dir
2022/12/08  14:33             1,867 bmi_base.py
2022/04/01  07:34               106 __init__.py
D:\cases\BMI指数与健身达人\common>

执行程序结果显示

D:\cases\BMI指数与健身达人>python bmi.py

将显示以下界面,你可以根据提示进行操作。

经过测试表明,BMI计算器完全达到甚至超越了设计要求。更为重要的是BMI计算器提供了比较完善的容错机制,那就是对输入参数height和weight的有效性检测。如果留意的话,你会发现这样一个事实:往往一个程序的容错处理程序代码量不少于10%。如果一个程序尤其是具有商业用途的产品没有适当的容错机制的话,容易引发程序执行中的意外终止。这些现象通常会被客户或者用户认为程序中存在bugs,程序很low,最起码会认为程序员不够专业!

场景编程集锦 - BMI指数与健身达人相关推荐

  1. 场景编程集锦 - 懵懂的青春

    1. 场景描述 "等待着下课,等待着放学,等待游戏的童年".当罗大佑这首耳熟能详的"童年"再度想起的时候,你和我是否都会被这个熟悉的旋律带回到那个只属我们的懵懂 ...

  2. 场景编程集锦 - 吉米的总统梦想

    1. 场景描述   吉米是太平洋岛国一个贫苦家庭的孩子,他的梦想就是当总统,引领国家走向富强之路.   开学的第一堂课上,老师用白色的粉笔在黑板上写下了"我的梦想",同学们都陷入了 ...

  3. 场景编程集锦-月光族的期待

    1. 场景描述 "月光族"是指没到下一个发薪日,工资就被全部花光的一群人.这个称谓是一个没有贬义的中性词."月光族"通常是有知识有文化.有固定的工作收入,秉持着 ...

  4. 场景编程集锦 - 乒坛争锋:孙颖莎vs伊藤美城

    1. 场景描述 孙颖莎和伊藤美诚是世界女子乒坛的顶尖运动员.根据国际乒联2022年11月15日公布的世界排名,孙颖莎位列第一,伊藤美诚排名第五.孙颖莎是中国女子乒乓球队的三大主力,曾获得2020年东京 ...

  5. c语言编程 BMI判断健康,BMI指数真的可以反映人的健康状态吗?看完你就懂了

    在现代社会,人们的健康意识越来越强,而如何来评判个人的健康状态是一个热点话题!其中BMI(身体质量指数)是其中比较常用的指标,因为该方法简便--只需要把你的体重(单位为千克)除以身高(单位为米)的平方 ...

  6. 【BMI指数计算器V3.0】项目实战

    [BMI指数计算器V3.0]项目实战震撼发布,欢迎前来交流~~~,如果是刚来的朋友可以先从 [BMI指数计算器V1.0]项目实战,[BMI指数计算器V2.0]项目实战开始,这样循序渐进更能感受到每一个 ...

  7. 使用Python语言实现Bmi指数计算器

    使用Python3.7实现Bmi指数计算器 使用Python中界面编程来实现Bmi指数计算器 1使用tkinter实现bmi指数计算器 使用Python中界面编程来实现Bmi指数计算器 1使用tkin ...

  8. 在读博士练成健身达人,女大学生在宿舍练出八块腹肌……

    大学生活 不应该只是 宿舍--学校--图书馆 三点一线还 应该分出来一部分 给让自己挥汗如雨的"健身房"! >>>> 考研压力大 "搬砖" ...

  9. python 身体BMI指数判断

    3.30 python身体BMI指数判断 代码: height,weight=eval(input("请输入身高(米)体重(公斤):")) bim=weight/pow(heigh ...

最新文章

  1. Attribute在.net编程中的应用
  2. 20171019_Python学习第四天
  3. 轻松与外来客户进行REST通信
  4. 印度朋友手把手教你学Scala(10):Scala里的样本对象
  5. 额外sql使用什么封装_为什么建立社区值得付出额外的努力
  6. 条款5:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)...
  7. hardmard积 用什么符号表示_表面粗糙度=表面光洁度?数值为什么用0.8、1.6、3.2等表示?...
  8. android中json解析及使用(上)
  9. integer为null_走进 JDK 之 Integer
  10. 关于郑州大学校园网锐捷客户端禁止热点分享,禁止多网卡的解决办法
  11. Web渗透测试-Xss跨站脚本攻击(Cross Site Scripting)
  12. kuangbin14数论解析
  13. Android - singleTask启动模式详解
  14. Report Machine 在WIN7系统下 IE里面运行错误
  15. ImageMagick-libs安装报错
  16. Software Performance Testing - 全链路压测知识点整理
  17. 电商时代得流量者得天下,思域流量要怎么做
  18. CAD关于图层隐藏图层操作(com接口c#语言)
  19. 眼见为实:关于微服务熔断这几个知识点,你可能理解错了
  20. 获得Windows主机的主机序列号

热门文章

  1. 这一份最全的TCP总结,请务必收下
  2. 如何关闭台式计算机,台式机如何关闭显示器
  3. K8S kube-proxy iptables 原理分析
  4. 上升了百分之几怎么算_如何简单计算同期上升下降的百分比?
  5. 如何区分电梯卡为id卡ic卡_怎么看小区门禁卡是ic还是id
  6. 高德地图获取坐标距离_高德地图获取两个经纬度点间直线距离JS/PHP/SQL代码
  7. k8s iptable升级到ipvs
  8. Android攻城狮 Handler与子线程
  9. 相关子查询和不相关子查询
  10. RSS订阅微信公众号初探-feed43