首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python+Excel数据分析实战:军事体能考核成绩评定(四)女子曲臂悬垂计算

Python+Excel数据分析实战:军事体能考核成绩评定(四)女子曲臂悬垂计算

作者头像
张国平
发布2021-03-02 15:10:55
7870
发布2021-03-02 15:10:55
举报

上一章Python+Excel数据分析实战:军事体能考核成绩评定(三)男子引体向上计算成功实现了男子引体向上计算的功能,这一章我们实现女子单杠考试成绩的计算,女子的单杠考核与男子的引体向上不同,为曲臂悬垂计时。

一、基本情况

通过分析女子单杠“成绩计算标准表”,发现标准表也只是参照标准表,不是连续的全覆盖,比如标准中24岁以下,只规定了曲臂悬垂1分10秒的成绩为100分,1分6秒的成绩为95分,那么中间的情况多少分呢?

女子单杠成绩计算标准表

还是只能是我们根据公平原则去补充,在1分6秒、1分10秒之间去取平均分,数据量比较小,我也选择手工计算,补充到成绩计算标准表里,精确到小数点后一位。

女子单杠曲臂悬垂补充标准

当然根据标准,40岁以上组织俯卧撑考核替代曲臂悬垂考核。

女子俯卧撑补充标准

同样,通过Python的openpyxl模块读取补充成绩计算标准表中的数据,制成 {原始单杠成绩:分数} 格式的字典,以供主程序查询出换算成绩,再写入成绩表的对应位置中。

二、代码实现

女子单杠考核原始成绩统计表

这里在原始成绩统计表中增加了“性别”这一项,在主程序中就要更改其它项目的相应序号。而且曲臂悬垂的原始成绩为时间格式,输入类似0:01:20的格式,这样在程序中才能比较大小。

1.计算年龄作为复用频率较高的函数,我把它放入单独的模块中,文件命名为calculate_age.py。

# 根据出生日期计算年龄,精确到天
# born参数为datetime.datetime类型

import datetime as dt

def calculate_age(born):
    '''由出生日期计算年龄,精确到天'''
    today =dt.datetime.today()
    # today = today.replace(year=2020)
    # print(born)
    try:
        birthday = born.replace(year = today.year)
    except ValueError:
        # 出生日期是2月29日但今年不是润年时,29要减1天为28天
        birthday = born.replace(year=today.year, day=born.day-1)
    # print(birthday)
    if birthday > today:
        return today.year - born.year - 1
    else:
        return today.year - born.year

2.计算女子曲臂悬垂的模块我命名为flex_arm_hang.py,首先是读取出标准数据,制成 {原始曲臂悬垂时长:分数} 格式的字典。每一个字典是分年龄段的,字典“age24”指24岁以下的数据字典,“age25_27”指25~27岁的数据字典。

下面代码中有一些注释掉的语句,是为了中间测试,并且有大部分已经被删除了,因为实际编程过程中,都是每一小段代码都要测试的,成功了才能继续下步,就像大楼一层一层的建起来。

# 女性单杠曲臂悬垂的成绩计算,40岁及以上计算俯卧撑个数
# 从工作表“女子单杆曲臂悬垂标准”中读取数据

import openpyxl
import datetime as dt

class Flex_arm_hang_standard_data():
    wb=openpyxl.load_workbook('通用训练课目考核成绩计算.xlsx')
    ws_flex_arm_hang = wb['女子单杆曲臂悬垂标准']

    age24={}     # 24岁以下,{原始悬垂时间:分数}
    age25_27={}  # 25~27岁,{原始悬垂时间:分数}
    age28_30={}
    age31_33={}
    age34_36={}
    age37_39={}

    rngs1 = ws_flex_arm_hang.iter_rows(min_row=3,max_row=43,min_col=1,max_col=8)
    # 生成{原始悬垂时间:分数}的字典
    for row in rngs1:
        #print([c.value for c in row])
        age24[row[1].value]=row[0].value
        age25_27[row[3].value]=row[2].value
        age28_30[row[4].value]=row[2].value
        age31_33[row[5].value]=row[2].value
        age34_36[row[6].value]=row[2].value
        age37_39[row[7].value] = row[2].value
    # print('-----age24-----') # 打印数据以便检查
    # for m in age24.items():
    #     print(m)
    # print('-----age25_27-----')
    # for m in age25_27.items():
    #     print(m)
    # print('-----age28_30-----')
    # for m in age28_30.items():
    #     print(m)
    # print('-----age31_33-----')
    # for m in age31_33.items():
    #     print(m)
    # print('-----age34_36-----')
    # for m in age34_36.items():
    #     print(m)
    # print('-----age37_39-----')
    # for m in age37_39.items():
    #     print(m)

    age40_42 = {}  # 40岁以上,{原始俯卧撑个数:分数}
    age43_45 = {}  # 43~45岁,{原始俯卧撑个数:分数}
    age46_48 = {}
    age49_51 = {}
    age52_54 = {}
    age55_57 = {}
    age58_59 = {}

    rngs2 = ws_flex_arm_hang.iter_rows(min_row=49,max_row=69,min_col=1,max_col=14)
    # 生成{原始俯卧撑个数:分数}的字典
    for row in rngs2:
        #print([c.value for c in row])
        age40_42[row[1].value]=row[0].value
        age43_45[row[3].value]=row[2].value
        age46_48[row[5].value]=row[4].value
        age49_51[row[7].value]=row[6].value
        age52_54[row[9].value]=row[8].value
        age55_57[row[11].value] = row[10].value
        age58_59[row[13].value] = row[12].value

    # print('-----age40_42-----') # 打印数据以便检查
    # for m in age40_42.items():
    #     print(m)
    # print('-----age43_45-----')
    # for m in age43_45.items():
    #     print(m)
    # print('-----age46_48-----')
    # for m in age46_48.items():
    #     print(m)
    # print('-----age49_51-----')
    # for m in age49_51.items():
    #     print(m)
    # print('-----age52_54-----')
    # for m in age52_54.items():
    #     print(m)
    # print('-----age55_57-----')
    # for m in age55_57.items():
    #     print(m)
    # print('-----age58_59-----')
    # for m in age58_59.items():
    #     print(m)

3.设计曲臂悬垂的计算函数flex_arm_hang_performance_computing(),首先IF语句判定年龄;再判定是否小于55分的曲臂悬垂时长或者俯卧撑个数,是则返回0分;再判定是否大于100分的曲臂悬垂时长或者俯卧撑个数,是则按超出100分的方法计算;最后55分~100分的情况,查询字典,返回对应分数。对于一类人员65分及格、二类人员60分及格的情况,后期在主程序里考虑。

    def flex_arm_hang_performance_computing(self,age,original_amount):
        '''根据年龄,实际单杠曲臂悬垂时间,计算所得分数'''
        if age <= 24:
            # 判定是否小于55分的曲臂悬垂时长,是则返回0分
            if original_amount < dt.time(0,0,30):  
                return 0
            # 判定是否大于100分的曲臂悬垂时长,是则按照引体向上超出100分计算,每递增5秒加一分
            elif original_amount > dt.time(0,1,10):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-1)*60+original_amount.second-10)/5
            elif dt.time(0,0,30) <= original_amount <= dt.time(0,1,10) :
                return self.age24[original_amount]
        elif 25 <= age <= 27:
            if original_amount < dt.time(0,0,29):
                return 0
            elif original_amount > dt.time(0,1,5):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-1)*60+original_amount.second-5)/5
            elif dt.time(0,0,29) <= original_amount <= dt.time(0,1,5) :
                return self.age25_27[original_amount]
        elif 28 <= age <= 30:
            if original_amount < dt.time(0,0,27):
                return 0
            elif original_amount > dt.time(0,1,3):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-1)*60+original_amount.second-3)/5
            elif dt.time(0,0,27) <= original_amount <= dt.time(0,1,3) :
                return self.age28_30[original_amount]
        elif 31 <= age <= 33:
            if original_amount < dt.time(0,0,24):
                return 0
            elif original_amount > dt.time(0,1,0):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-1)*60+original_amount.second-0)/5
            elif dt.time(0,0,24) <= original_amount <= dt.time(0,1,00) :
                return self.age31_33[original_amount]
        elif 34 <= age <= 36:
            if original_amount < dt.time(0,0,21):
                return 0
            elif original_amount > dt.time(0,0,57):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-0)*60+original_amount.second-57)/5
            elif dt.time(0,0,21) <= original_amount <= dt.time(0,0,57) :
                return self.age34_36[original_amount]
        elif 37 <= age <= 39:
            if original_amount < dt.time(0,0,18):
                return 0
            elif original_amount > dt.time(0,0,54):
                return 100+((original_amount.hour-0)*3600+(original_amount.minute-0)*60+original_amount.second-54)/5
            elif dt.time(0,0,18) <= original_amount <= dt.time(0,0,54) :
                return self.age37_39[original_amount]
        # 大于40岁时计算俯卧撑
        elif 40 <= age <= 42:
            if original_amount < 13:
                return 0
            elif original_amount > 30:
                return 100 + (original_amount-30)*0.5
            elif 13 <= original_amount <= 30 :
                return self.age40_42[original_amount]
        elif 43 <= age <= 45:
            if original_amount < 11:
                return 0
            elif original_amount > 27:
                return 100 + (original_amount-27)*0.5
            elif 11 <= original_amount <= 27 :
                return self.age43_45[original_amount]
        elif 46 <= age <= 48:
            if original_amount < 11:
                return 0
            elif original_amount > 24:
                return 100 + (original_amount-24)*0.5
            elif 11 <= original_amount <= 24 :
                return self.age46_48[original_amount]
        elif 49 <= age <= 51:
            if original_amount < 9:
                return 0
            elif original_amount > 21:
                return 100 + (original_amount-21)*0.5
            elif 9 <= original_amount <= 21 :
                return self.age49_51[original_amount]
        elif 52 <= age <= 54:
            if original_amount < 8:
                return 0
            elif original_amount > 19:
                return 100 + (original_amount-19)*0.5
            elif 8 <= original_amount <= 19 :
                return self.age52_54[original_amount]
        elif 55 <= age <= 57:
            if original_amount < 7:
                return 0
            elif original_amount > 17:
                return 100 + (original_amount-17)*0.5
            elif 7 <= original_amount <= 17 :
                return self.age55_57[original_amount]
        elif 58 <= age <= 59:
            if original_amount < 3:
                return 0
            elif original_amount > 16:
                return 100 + (original_amount-16)*0.5
            elif 3 <= original_amount <= 16 :
                return self.age58_59[original_amount]

if __name__ == "__main__":   #本模块测试
    flex_arm_hang_std_data = Flex_arm_hang_standard_data()
    result = flex_arm_hang_std_data.flex_arm_hang_performance_computing(59,15)
    #print(type(dt.time(0, 1, 10).second))
    print(result)

4.对主程序training_performance.py进行修改,如果原始成绩不为空,则进行分数计算,再将分数写入表中换算成绩的相应位置。这里增加了出生日期格式异常检测,性别判断。如果性别为“男”,则进行男子引体向上或俯卧撑成绩计算;如果性别为“女”,则进行女子曲臂悬垂或俯卧撑成绩计算

import openpyxl
import datetime as dt
from calculate_age import calculate_age  # 导入年龄计算模块
from pullup_standard_data import Pullup_standard_data # 导入男子引体向上成绩计算模块
from flex_arm_hang import Flex_arm_hang_standard_data # 导入女子单杠曲臂悬垂的成绩计算模块

wb=openpyxl.load_workbook('通用训练课目考核成绩计算.xlsx')
ws_training_performance = wb['体能考核成绩']

pullup_sd = Pullup_standard_data() #实例化男子引体向上成绩计算
flexarmhang_sd = Flex_arm_hang_standard_data() #实例化女子单杠曲臂悬垂成绩计算

rngs = ws_training_performance.iter_rows(min_row=6)
for row in rngs:
    gender = row[4].value   # 性别
    pullup = row[11].value  # 单杠原始数量
    if row[5].value:
        if not type(row[5].value) is dt.datetime: # 核查日期格式
            print('序号%d %s 的出生日期格式不对'%(row[0].value,row[1].value))
        # print(row[5].value)
        else:
            age = calculate_age(row[5].value)    # 由出生日期计算年龄,精确到天
            row[6].value = age

    if gender == '男' :  # 男子引体向上或俯卧撑成绩计算
        if row[6].value != None:
            row[12].value = pullup_sd.pullup_performance_computing(age, pullup)
            print(row[0].value,pullup,row[12].value)
    elif gender == '女':  # 女子曲臂悬垂或俯卧撑成绩计算
        if row[6].value != None:
            row[12].value = flexarmhang_sd.flex_arm_hang_performance_computing(age, pullup)
            print(row[0].value,pullup, row[12].value)
    else:    #核查性别
        print('序号%d %s 的性别填写错误'%(row[0].value,row[1].value))

wb.save('计算结果.xlsx')

运行后,生成文件“计算结果.xlsx”如下:

女子单杠考核计算结果

到此,我们成功实现了女子单杠考核成绩计算的功能。

原创不易,有偿下载,请多支持:

军事体能考核成绩评定系统下载

军事体能考核成绩评定系统全套Python源码下载

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、基本情况
  • 二、代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档