场景编程集锦 - BMI指数与健身达人

news2025/1/14 0:49:24

1. 场景描述

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


2. 编程思路

2.1 计算公式

B M I = w e i g h t / h e i g h t 2 BMI = weight / height^2 BMI=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 -1
    return wrapper

@decorate_bmi   # ③
def calc_bmi(height, weight):
    """
    height : 计量单位是米
    weight : 计量单位是公斤
    """
    bmi = weight / height ** 2
    bmi = round(bmi, 1)
    return abs(bmi)

def is_number(number):
    """
    判断 number 是数字
    """
    if isinstance(number, int) or isinstance(number, float):   # ④
        return True
    else:
        return False

def is_valid(height, weight):
    """
    判断 height,weight有效性
    """
    if height and is_number(height) and is_number(weight):
        return True
    else:
        return False

def 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 report

def 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.txt

D:\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,最起码会认为程序员不够专业!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

马蹄集 宽度与对齐

宽度与对齐 难度&#xff1a;白银 时间限制&#xff1a;1秒巴占用内存&#xff1a;64M 输出455、-123、987654&#xff0c;宽度为5&#xff0c;分别左对齐和右对齐 格式 输入格式&#xff1a;无 输出格式&#xff1a;输出为整型&#xff0c;空格分隔。每个数的输出占一行 #inc…

[34]. 在排序数组中查找元素的第一个和最后一个位置

在排序数组中查找元素的第一个和最后一个位置题目算法设计&#xff1a;二分查找题目 算法设计&#xff1a;二分查找 进行两次二分查找&#xff08;定制版本&#xff09;&#xff0c;第一次先查找【第一个大于等于target的数】&#xff0c;第二次再查找【第一个大于target的数】…

Mac安装python3并配置环境变量

文章目录homebrew 安装 python3配置 python3 环境变量homebrew 安装 python3 可以用 homebrew 安装&#xff0c;也可以官网下载安装&#xff0c;我这里选择使用 homebrew 安装&#xff0c;没有装 homebrew 的小伙伴请自行百度 brew install python3我们执行下 python3 发现可…

Centos7安装高版本zshzim框架安装powerlevel10k

1. 安装高版本zsh 1.1 卸载低版本zsh sudo yum remove zsh -y1.2 下载源码 源码&#xff1a;https://zsh.sourceforge.io/Arc/source.html # 下载 wget https://jaist.dl.sourceforge.net/project/zsh/zsh/5.9/ # 解压 $ tar xvf zsh-5.9.tar.xz1.3 编译安装 yum install …

新应用——养老院管理应用,信息化的多功能管理应用

养老院管理系统专门为医养结合的养老机构量身打造的信息化管理系统&#xff0c;还适用于社区医院&#xff0c;包含诊断、病历、财务、物资、照护记录、处方等功能点。此应用分为经营管理、长者管理、物资库存、财会综合等四个大模块&#xff0c;全方面打造适用于养老院&#xf…

精准招聘!一图了解2023牛客校招专场

当「简历海投」成为当代大学生一种「硬核求职」的方式&#xff0c;如何精准地找到与招聘目标相匹配的专业人才成为HR校园招聘工作中的一大难点。为了帮助企业解决这些难题&#xff0c;牛客为企业推出了「牛客招聘专场」助力企业做好雇主品牌传播&#xff0c;提升收到的简历质量…

自动驾驶道路曲率计算

自动驾驶系列 车道曲率和中心点偏离距离计算 文章目录自动驾驶系列目标一、曲率的介绍圆的曲率曲线的曲率二、实现1.计算曲率半径的方法&#xff0c;代码实现如下&#xff1a;总结目标 知道车道曲率计算的方法 知道计算中心点偏离距离的计算 一、曲率的介绍 曲线的曲率就是针…

CSS入门五、定位

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…

Revit出图问题:打印机中新建纸张尺寸?批量导出图纸?

一、Revit中在打印机中新建纸张尺寸 Revit导出PDF图纸&#xff0c;如何在打印机中新建纸张的尺寸&#xff1f; 在导出PDF的时候&#xff0c;我们需要将图纸放在合适的纸张页面上&#xff0c;而这个时候系统又没有提供所需的页面尺寸&#xff0c;如图1所示。 这种情况下我们该如…

数据结构学习笔记——二叉排序树

目录一、二叉排序树的定义二、二叉排序树的插入和构造三、二叉排序树的查找四、二叉排序树的平均查找长度五、二叉排序树的删除六、二叉排序树和二分查找对比二叉排序树的查找过程与折半查找&#xff08;二分查找&#xff09;相似&#xff0c;即折半查找的判定树就是一棵二叉排…

【安卓学习笔记】界面编程入门

安卓应用采用View组件进行界面布局&#xff0c;可以通过两种方式进行布局&#xff0c;分别是XML文件和Java代码。 其中采用XML文件进行布局是较好的方式&#xff0c;因为这样可以将XML文件和Java代码分开编写&#xff0c;使得项目结构变得更加清晰。 简单的图片浏览器 下面是…

git仓库清理瘦身解决 .git文件夹过大的问题

git仓库清理找了很多资料和方案都没有很完美执行成功的&#xff1b;现在找到一个完美方案&#xff0c;分享给大家&#xff1b;希望能帮助大家 问题 1、gitlab代码开发了仓库开发了五年了&#xff0c;代码只有10M&#xff1b;clone的时候要700多兆很浪费时间 2、创建分支和切换…

Java泛型通配符的使用

目录 泛型在继承方面的体现 类A是类B的父类&#xff0c;G和G二者不具有子父类关系&#xff0c;二者是并列关系 类A是类B的父类&#xff0c;A是B的父类 通配符的使用 类A是类B的父类&#xff0c;G和G是没有关系的&#xff0c;二者共同父类是:G 使用通配符后&#xff0c;数…

Linux学习记录——칠 git、gdb部分基础知识以及进度条小程序

文章目录一、/r/n二、简单理解缓冲区概念三、进度条四、了解git五、初步学会使用gdb1、背景知识2、部分简单指令一、/r/n 在写小程序之前&#xff0c;我们先看一下/r和/n的区别。 /n我们遇到过&#xff0c;它叫做换行符。/r并不知道是什么符号。实际应用中&#xff0c;/n可以起…

鲍春健:从“走进客户”奔向“成为客户”

站在当下来看&#xff0c;小鹅通的服务力的特殊性在于其可以穿透三层&#xff0c;即以自身的服务力赋能客户的服务力。其中&#xff0c;一层是客户&#xff1b;一层是客户的服务&#xff1b;一层是客户的客户。 作者|斗斗 出品|产业家 累计终端用户数达8.2亿、最高日活14…

mysql系列之索引(待续)

目录一、索引简述1、什么叫索引2、索引的优缺点3、索引的使用场景二、索引的算法1、线性查找 Linear Search2、二分查找 Binary Search3、二叉查找树 Binary Search Tree4、平衡二叉树 AVL Tree5、B树6、B树三、B树和B树的理解1、B树和B树的区别2、数据库为什么使用B树而不是B树…

第二章.线性回归以及非线性回归—一元线性回归,代价函数,相关系数,决定系数

第二章.线性回归以及非线性回归 2.1 一元线性回归 1.概念&#xff1a; 1).自变量&#xff1a; 被用来进行预测的变量&#xff0c;相当于输入 2).因变量&#xff1a; 被预测的变量&#xff0c;相当于输出 3).回归分析&#xff1a; 用来建立方程模拟两个或者多个变量之间如何关…

从零开始学习Maven

maven Maven是apache公司开发的基于项目对象模型&#xff08;POM&#xff09; 可以通过一些描述信息来管理项目的构建、报告和文档的软件管理工具。 Maven 是用来管理项目&#xff0c;进行项目构建的一个软件。 java编写 项目构建流程&#xff1a; 1. 导入jar包 2. 配置文…

【MyBatis】RC隔离级别下,MyBatis 一级缓存、二级缓存造成的不一致情况

前言 数据库的MVCC 及 锁机制保证了数据的隔离、一致性。而建立在数据库之上的缓存&#xff0c;都会破坏掉数据库的一致性保障。本文探索在RC隔离级别下&#xff0c;MyBatis 一级缓存、二级缓存造成的坑。顺便复习一下 Spock 的用法&#xff0c;更加体验到了 Groovy 清爽的语法…

insert唯一索引加锁流程

MySQL版本&#xff1a;8.0.29 测试表&#xff1a; 测试数据&#xff1a; 开始测试&#xff1a; 事务1执行 加锁分析&#xff1a; mysql> SELECT * FROM performance_schema.data_locks\G *************************** 1. row ***************************ENGINE: INNO…