本程序使用Python3编制,可实现军体五项中除体型外的成绩换算,并根据人员类型标注成绩等级。
Python 3.7 32位(Conda)
(注:使用该环境是考虑到办公电脑一般使用32位Windows7操作系统)
获取模板:
填写基本信息及成绩:
导入表格:
计算对应分数:
(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 |
(1)基本算法
日期输入格式为:YYYY-mm-dd
将出生日期与结算日期使用Python内置的datetime模块转换成datetime对象,并将出生日期的年份与结算日期的年份设置为同一年。通过比较结算日期与转换后的出生日期,推算当年生日是否已过。若已过,则年龄为结算日期与出生日期年份之差加1,否则不加1。
例如:
出生日期为:1998-12-2
结算日期为:2021-9-5
则将出生日期年份转换为结算日期的年份:2021-12-2
比较结算日期与转换后的出生日期,得出当年生日未过,则年龄为2021-1998=22岁。
(2)流程图
(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
由于各项体能考核标准中年龄分级相同,因此可以根据本算法计算待测者年龄在标准表中的列索引。
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级 | 特2级 | 特1级 |
---|---|---|---|---|---|---|---|---|
一类人员 | 单项<65 | <260 | 260 | 340 | 380 | 440 | 480 | 500 |
二类人员 | 单项<60 | <240 | 240 | 320 | 360 | 440 | 480 | 500 |
三类人员 | 单项<55 | <220 | 220 | 300 | 340 | 440 | 480 | 500 |
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节中将分级标准存为列表主要是为了便于后期维护,各项体能标准可见附录。
部分项目成绩体现为个数,如男生的男生单杠引体向上/俯卧撑、女生的俯卧撑,以及仰卧起坐;还有部分项目成绩体现为一个数值,如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="linear")
return int(f(score))
部分项目成绩体现为时间,如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="linear")
return int(f(score))
(1)单杠引体向上超出100分后每增加1次加1分;俯卧撑超出100分后每递增2次加1分。
(2)俯卧撑考核时间为2分钟。
(1)单杠屈臂悬垂超出100分后每增加5秒加1分;俯卧撑超出100分后每递增2次加1分。
(2)俯卧撑考核时间为2分钟。