【AQI计算器】简易实现代码

分享代码前,先作几点说明:

1.关于污染物浓度数据有效性的判断

对于整数,采用isdecimal()方法判断;对于小数(仅一氧化碳),采用split(‘.’)方法将字符串拆成两部分判断。

2.关于IAQI的计算

查阅资料,大多通过定义各污染物IAQI函数,然后elif分浓度区间计算。其实大可不必,因即使污染物不同、浓度范围不同,IAQI计算原理都是一样的:已知两个端点横纵坐标和未知点横坐标,利用相似三角形相似比性质,求未知点纵坐标。在这里,我们只要确定是什么污染物,处在什么浓度区间,定义一个函数通过两层遍历就可以解决。

3.关于开发环境

Python==3.4.4

pywin32==221.win32-py3.4

pyinstaller==3.2.1

选择以上开发环境,打包后的软件在XP平台也能运行

4.关于打包

推荐ToYcon制作多帧图标,pipenv虚拟环境打包

打包命令:pyinstaller -i *.ico -F -w *.py --upx-dir "upx主程序所在路径"

注意:因upx压缩后会加壳,杀软有报毒几率,慎用之

简易实现代码分享如下:

from math import ceil  #导入进位取整函数
from collections import OrderedDict  #导入有序字典模块(Python3.6以下字典无序)
 
#定义包含污染物名称、浓度区间和IAQI区间的有序字典
mapping = OrderedDict([
            ('PM2.5', ((0,0),(35,50),(75,100),(115,150),(150,200),(250,300),
                      (350,400),(500,500))),
            ('PM10', ((0,0),(50,50),(150,100),(250,150),(350,200),(420,300),
                      (500,400),(600,500))),
            ('臭氧', ((0,0),(100,50),(160,100),(215,150),(265,200),(800,300),
                      (1000,400),(1200,500))),
            ('一氧化碳', ((0,0),(2,50),(4,100),(14,150),(24,200),(36,300),
                      (48,400),(60,500))), 
            ('二氧化氮', ((0,0),(40,50),(80,100),(180,150),(280,200),(565,300),
                      (750,400),(940,500))),
            ('二氧化硫', ((0,0),(50,50),(150,100),(475,150),(800,200), (1600,300),
                      (2100,400),(2620,500)))
          ])
 
def data_validity(pollutants):
    """判断数据有效性"""
    for k, v in pollutants.items():
        if not v:
            pollutants[k] = '0'  #空白初始化为0
        elif not v.isdecimal():
            if k != '一氧化碳':  #因CO可保留3位以下小数,需单独判断
                return False
            num = v.split('.')  #以小数点为分割符切成两部分来判断
            if len(num) != 2 or (not num[0].isdecimal()) or (not num[1].isdecimal()) or len(num[1]) > 3:
                return False
        if float(pollutants[k]) > mapping[k][-1][0]:  #超过限值情况
            return False
    else:  #正常循环退出
        return True
 
def iaqi_calc(pollutants):
    """计算各污染物IAQI"""
    for k, v in mapping.items():  #遍历字典,确定污染物名称
        for i in range(len(v)-1):  #遍历嵌套元组,确定污染物浓度所处区间
            if float(pollutants[k]) <= v[i+1][0]:  #利用相似三角形相似比求值
                iaqi = ceil((float(pollutants[k])-v[i][0])*(v[i+1][1]-v[i][1])/(v[i+1][0]-v[i][0]))+v[i][1]
                pollutants[k] = iaqi  #更新污染物浓度为IAQI
                break  #计算完毕,需及时跳出(为什么^-^)
    for k, v in pollutants.items():
        print("{}-IAQI:{}".format(k, v))
 
def aqi_calc(pollutants):
    """计算AQI及相关信息"""
    aqi = max(pollutants.values())
 
    if aqi > 50:  #首要污染物
        prime_pollutants = '、'.join(k for k, v in pollutants.items() if v == aqi)
    else:
        prime_pollutants = '无'
 
    if aqi > 100:  #超标污染物
        exceed_pollutants = '、'.join(k for k, v in pollutants.items() if v > 100)
    else:
        exceed_pollutants = '无'

    print("AQI:{}".format(aqi))
    print("首要污染物:{}".format(prime_pollutants))
    print("超标污染物:{}".format(exceed_pollutants))

def main():
    """主程序"""
    while True:
        #定义临时存放各污染物浓度和IAQI数值的有序字典
        pollutants = OrderedDict([(k, input('请输入{}浓度:'.format(k))) for k in mapping])
 
        if data_validity(pollutants):
            print("-"*50)
            iaqi_calc(pollutants)
            print("-"*50)
            aqi_calc(pollutants)
            print("-"*50)
            if input("如需终止计算,请输入q后回车:").lower() == 'q':
                break
            print("-"*50)
        else:
            print("-"*50)
            print("数据无效,请重新输入!")
            print("-"*50)
 
if __name__ == '__main__':
    main()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值