【体能五项】体能五项训练成绩计算Python实现


一、项目介绍

1.1 简介

本程序使用Python3编制,可实现军体五项中除体型外的成绩换算,并根据人员类型标注成绩等级。

1.2 项目编制环境

Python 3.7 32位(Conda)
(注:使用该环境是考虑到办公电脑一般使用32位Windows7操作系统)

1.3 程序界面

(1)自动填表程序界面

自动填表程序界面

(2)成绩计算程序界面

成绩计算程序界面

1.4 实现效果

(1)自动填表功能

获取模板:
获取模板
填写基本信息及成绩:
填写基本信息及成绩
导入表格:
拖动文件导入
选择文件导入
计算对应分数:
计算对应分数

(2)成绩计算功能

成绩计算功能


二、项目结构

2.1 程序结构

Main
all_standard
button_handle()
get_dir()
get_file()
change_date()
get_model()
file_select()
calculate()
open_dir()
change_item()
get_information()
calculate_score()
fill_score()
fill_item()
mainWindow
setupUi()
retranslateUi()
MyWidget
dragEnterEvent()
dropEvent()
rwExcel
rw_excel()
gradeCalculate
male_dgfwc()
female_qbxcfwc()
both_ywqz()
both_zfp()
both_threekm()
male_grade()
female_grade()
testStandard
male_dgfwc_standard
male_ywqz_standard
male_zfp_standard
male_threekm_standard
female_qbxcfwc_standard
female_ywqz_standard
female_zfp_standard
female_threekm_standard
myFunction
age_calculate()
age_classification()
person_classification()
grade_classification()

2.2 文件结构

(1)在myFunction.py中包含:

方法名称
年龄计算方法age_calculate()
年龄索引计算方法age_classification()
人员分级方法person_classification()
成绩分级方法grade_classification()

(2)在gradeCalculate.py中包含:

方法名称
计算男生引体向上/俯卧撑分数male_dgfwc()
计算女生屈臂悬垂/俯卧撑分数female_qbxcfwc()
计算仰卧起坐分数both_ywqz()
计算30m*2折返跑分数both_zfp()
计算3000m分数both_threekm()
计算男生的分数male_grade()
计算女生的分数female_grade()

(3)在rwExcel.py中包含:

方法名称
填写成绩登记表rw_excel()

(4)在testStandard类中包含:

属性名称
男生单杠引体向上/俯卧撑标准male_dgfwc_standard
男生仰卧起坐标准male_ywqz_standard
男生30m*2折返跑标准male_zfp_standard
男生3000m标准male_threekm_standard
女生单杠屈臂悬垂/俯卧撑标准female_qbxcfwc_standard
女生仰卧起坐标准female_ywqz_standard
女生30m*2折返跑标准female_zfp_standard
女生3000m标准female_threekm_standard

三、部分方法的原理及代码

3.1 根据人员出生日期计算年龄

(1)基本算法

日期输入格式为:YYYY-mm-dd
将出生日期与结算日期使用Python内置的datetime模块转换成datetime对象,并将出生日期的年份与结算日期的年份设置为同一年。通过比较结算日期与转换后的出生日期,推算当年生日是否已过。若已过,则年龄为结算日期与出生日期年份之差加1,否则不加1。
例如:
出生日期为:1998-12-2
结算日期为:2021-9-5
则将出生日期年份转换为结算日期的年份:2021-12-2
比较结算日期与转换后的出生日期,得出当年生日未过,则年龄为2021-1998=22岁。

(2)流程图

出生日期 Y1-M1-D1
结算日期 Y2-M2-D2
转换出生日期 Y2-M1-D1
Y2-M1-D1 > Y2-M2-D2
年龄 = Y2-Y1+1
年龄 = Y2-Y1

(3)代码

def age_calculate(birthday, target_date):
    """
    该函数用于计算年龄
    :param birthday: 出生日期('1998-12-2')
    :param target_date: 结算日期('2021-9-5')
    :return: 年龄(22)
    """
    birth = datetime.datetime.strptime(birthday, "%Y-%m-%d")
    target = datetime.datetime.strptime(target_date, "%Y-%m-%d")
    birth_convert = birth.replace(year=target.year)
    if target > birth_convert:
        age = target.year - birth.year
    else:
        age = target.year - birth.year - 1
    return age

3.2 计算年龄分级的索引

由于各项体能考核标准中年龄分级相同,因此可以根据本算法计算待测者年龄在标准表中的列索引。

def age_classification(age):
    """
    该函数用于计算年龄分级的索引
    :param age: 年龄
    :return: 年龄分级的索引
    """
    age_range = [24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60]
    age_count = len(age_range)
    if age < 0:
        raise Exception('有人年龄输入错误,为负数!')
    elif age > age_range[-1]:
        raise Exception('有人年龄太大,不用测体能啦!')
    for i in range(age_count):
        if age <= age_range[i]:
            return i

3.3 计算人员的分数等级

用于计算不同人员类别的分数等级。

人员类别不及格不及格及格良好优秀特3级特2级特1级
一类人员单项<65<260260340380440480500
二类人员单项<60<240240320360440480500
三类人员单项<55<220220300340440480500
def grade_classification(rank, grade1, grade2, grade3, grade4, inall):
    """
    该函数用于计算人员分数等级
    :param rank: 人员类别(1、2、3)
    :param grade1: 体能第一项成绩
    :param grade2: 体能第二项成绩
    :param grade3: 体能第三项成绩
    :param grade4: 体能第四项成绩
    :param inall: 体能总分
    :return: 人员体能等级
    """
    if rank == 1:
        cl = [65, 260, 340, 380, 440, 480, 500]
    elif rank == 2:
        cl = [60, 240, 320, 360, 440, 480, 500]
    elif rank == 3:
        cl = [55, 220, 300, 340, 440, 480, 500]
    else:
        raise Exception('人员类别输入错误!')
    if grade1 < cl[0] or grade2 < cl[0] or grade3 < cl[0] or grade4 < cl[0] or inall < cl[1]:
        return '不及格'
    elif inall < cl[2]:
        return '及格'
    elif inall < cl[3]:
        return '良好'
    elif inall < cl[4]:
        return '优秀'
    elif inall < cl[5]:
        return '特3级'
    elif inall < cl[6]:
        return '特2级'
    else:
        return '特1级'

注:3.2节与3.3节中将分级标准存为列表主要是为了便于后期维护,各项体能标准可见附录。

3.4 数值类指标分数计算方法

部分项目成绩体现为个数,如男生的男生单杠引体向上/俯卧撑、女生的俯卧撑,以及仰卧起坐;还有部分项目成绩体现为一个数值,如30m*2折返跑。我们将此类项目统称为数值类指标项目。
对于这类考核项目,我们考虑直接使用线性插值(Linear)的方式计算成绩。对于超出插值范围的成绩,如超出100分时,我们另行做计算。
使用Python进行插值计算的方法可以见:(数值分析)各种插值法的python实现
以计算俯卧撑分数为例:

def both_ywqz(standard_df, age_index, score):
    """
    该函数用于计算仰卧起坐换算成百分制的成绩
    :param standard_df: 仰卧起坐的标准
    :param age_index: 年龄在标准中的索引
    :param score: 成绩
    :return: 换算成百分制的成绩
    """
    if score < 0:
        raise Exception('成绩为负数,输入错误!')
    score_range = list(standard_df.iloc[:, age_index])
    if score > score_range[0]:
        return 100 + int((score - score_range[0]) / 2)
    _score_range = copy.copy(score_range)
    _score_range.append(0)
    _grade_range = copy.copy(grade_range)
    _grade_range.append(0)
    f = interpolate.interp1d(_score_range, _grade_range, kind="previous")
    return int(f(score))

3.5 时间类指标分数计算方法

部分项目成绩体现为时间,如3000m跑及女生的单杠屈臂悬垂。
对于这类考核项目,我们考虑将其转换为以分钟为单位的浮点型数据,再进行线性插值(Linear)的方式计算成绩。
以计算3000m跑分数为例:

def both_threekm(standard_df, age_index, score):
    """
    该函数用于计算3000米换算成百分制的成绩
    :param standard_df: 3000米的标准
    :param age_index: 年龄在标准中的索引
    :param score: 成绩('13:30')
    :return: 换算成百分制的成绩
    """
    try:
        m, s = score.split(':')
    except:
        m, s = score.split(':')
    score = int(m) + int(s) / 60
    if score < 0:
        raise Exception('成绩为负数,输入错误!')
    time_range = list(standard_df.iloc[:, age_index])
    score_range = []
    for i in range(len(time_range)):
        try:
            m, s = map(int, time_range[i].split(':'))
        except:
            m, s = map(int, time_range[i].split(':'))
        score_range.append(m + s / 60)
    if score > score_range[-1]:
        grade = (grade_range[-1] - grade_range[-2]) / (score_range[-1] - score_range[-2]) * \
                (score - score_range[-1]) + grade_range[-1]
        if grade < 0:
            grade = 0
        return int(grade)
    if score < score_range[0]:
        return int(100 + (score_range[0] - score) / 5)
    f = interpolate.interp1d(score_range, grade_range, kind="previous")
    return int(f(score))


四、附录

4.1 男生单杠引体向上/俯卧撑标准

男生引体向上/俯卧撑标准
(1)单杠引体向上超出100分后每增加1次加1分;俯卧撑超出100分后每递增2次加1分。
(2)俯卧撑考核时间为2分钟。

4.2 男生仰卧起坐标准

男生仰卧起坐标准
超出100分后每递增2次增加1分,考核时间为2分钟。

4.3 男生30m*2折返跑标准

男生30m*2折返跑标准
超出100分后每递减0.1秒增加1分。

4.4 男生3000m跑标准

男生3000m跑标准
超出100分后每递减5秒增加1分。

4.5 女生单杠屈臂悬垂/俯卧撑标准

女生屈臂悬垂/俯卧撑标准
(1)单杠屈臂悬垂超出100分后每增加5秒加1分;俯卧撑超出100分后每递增2次加1分。
(2)俯卧撑考核时间为2分钟。

4.6 女生仰卧起坐标准

女生仰卧起坐标准
超出100分后每递增2次增加1分,考核时间为2分钟。

4.7 女生30m*2折返跑标准

女生30m*2折返跑标准
超出100分后每递减0.1秒增加1分。

4.8 女生3000m跑标准

女生3000m跑标准
超出100分后每递减5秒增加1分。

4.9 成绩填写模板

成绩填写模板


五、附件

5.1 按插值方式计算分数

按此方式将会在成绩表的基础之上进行插值,如:10对应80分,20对应100分,则15对应90分。
① 打包后的文件,可直接运行:链接
② 程序源码:链接

5.2 按间断方式计算分数

按此方式将按间断方式计算分数,如:10对应80分,20对应100分,则15对应80分。
① 打包后的文件,可直接运行:链接
② 程序源码:链接


六、更新记录

2022/11/08:将成绩计算由连续插值调整为间断。


欢迎交流!
联系方式

  • 3
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CharlesWYQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值