这一章我们实现男子和女子3000米跑成绩的计算,原始数据是时间,多少分多少秒,全年龄段考核内容都是3公里,但是海拔不同标准不同,是所有科目中最复杂的计算。
一、基本情况
通过分析3000米跑“成绩计算标准表”,发现标准表也只是参照标准表,不是连续的全覆盖。比如平原3000米标准中24岁以下男子,只规定了11分30秒的成绩为100分,11分55秒的成绩为95分,那么中间的情况多少分呢?
男子3000米成绩计算标准表
女子3000米成绩计算标准表
高原男子3000米成绩计算标准表
高原女子3000米成绩计算标准表
还是只能是我们根据公平原则去补充,在11分30秒、11分55秒的成绩之间去取平均分,但手工补充的数据量太大,我们编程解决。
所以录入Excel表中的标准和规定的相同,没有增加手工计算的标准:
男女平原3000米标准
男子高原3000米标准
女子高原3000米标准
同样,通过Python的openpyxl模块读取标准表中的数据,制成 {原始3公里跑时长:分数} 格式的字典,以供主程序查询出换算成绩,再写入成绩表的对应位置中。
这里要使用海拔数据,后期等级评定还需要人员类别的信息,所以设计了一个工作簿来输入这些参数信息。
人员参数设置
在B2位置输入人员类别,在B3位置输入海拔。
二、代码实现
原始成绩登记表
1.我把计算高原男子和女子3000米的文件分开,同时海拔3000以下与3000米以上标准又不同,这里我以男子2001米~3000米的计算为例讲解,文件命名为highland2001up_3km_male.py。这个模块类的构造方法“__init__()” 有一个参数,ele,传递海拔数据。
另外将 {原始3公里跑时长:分数} 格式的字典的键全部取出来,转换成列表,如24岁以下的时间键,age24_keys=[datetime.time(0, 11, 42), datetime.time(0, 12, 7), datetime.time(0, 12, 22), datetime.time(0, 12, 37), datetime.time(0, 12, 52), datetime.time(0, 13, 7), datetime.time(0, 13, 22), datetime.time(0, 13, 42), datetime.time(0, 13, 47), datetime.time(0, 13, 52)]。目的是计算标准中未给出的中间值要用到,比如计算11分45秒的成绩,就需要与标准中有的11分42秒和12分7秒做计算。
还要根据海拔,计算出每增加100米高度标准递增8秒后的标准时间列表,因为2201米的标准比2000米~2100米的标准多了16秒。
# 男子海拔2001~3000米,3000米跑的成绩计算
# 从工作表“男子高原3000米标准”中读取数据
import openpyxl
import datetime as dt
from run_standard_add import standard_add
from score_computing import score_computing
class Highland2001up3kmMaleStandardData:
def __init__(self, ele):
elevation = ele # 海拔高度
multiple = (elevation - 2001) // 100 # 整数除法返回向下取整后的结果
addition = multiple * 8 # 每增加100米高度,标准递增8秒
wb = openpyxl.load_workbook('通用训练课目考核成绩计算.xlsx')
ws_long_run_male = wb['男子高原3000米标准']
self.age24 = {} # 24岁以下,{原始男子3000米分秒数:分数}
self.age25_27 = {} # 25~27岁,{原始男子3000米分秒数:分数}
self.age28_30 = {}
self.age31_33 = {}
self.age34_36 = {}
self.age37_39 = {}
self.age40_42 = {} # 40岁以上,{原始男子3000米分秒数:分数}
self.age43_45 = {} # 43~45岁,{原始男子3000米分秒数:分数}
self.age46_48 = {}
self.age49_51 = {}
self.age52_54 = {}
self.age55_57 = {}
self.age58_59 = {}
rngs2000 = ws_long_run_male.iter_rows(min_row=3,max_row=12,min_col=2,max_col=15)
# 生成{原始男子3000米分秒数:分数}的字典
for row in rngs2000:
# print([c.value for c in row])
self.age24[row[1].value] = row[0].value
self.age25_27[row[2].value] = row[0].value
self.age28_30[row[3].value] = row[0].value
self. age31_33[row[4].value] = row[0].value
self.age34_36[row[5].value] = row[0].value
self.age37_39[row[6].value] = row[0].value
self.age40_42[row[7].value] = row[0].value
self.age43_45[row[8].value] = row[0].value
self.age46_48[row[9].value] = row[0].value
self.age49_51[row[10].value] = row[0].value
self.age52_54[row[11].value] = row[0].value
self.age55_57[row[12].value] = row[0].value
self.age58_59[row[13].value] = row[0].value
# print('-----age24-----') # 打印数据以便检查
# for m in self.age24.items():
# print(m)
# print('-----age25_27-----')
# for m in self.age25_27.items():
# print(m)
# print('-----age28_30-----')
# for m in self.age28_30.items():
# print(m)
# print('-----age31_33-----')
# for m in self.age31_33.items():
# print(m)
# print('-----age34_36-----')
# for m in self.age34_36.items():
# print(m)
# print('-----age37_39-----')
# for