一、基本框架
項目任務 :
每個人的體能測試有單杠、仰卧起坐、30米x2蛇形跑、3000米跑四個項目,外加體型是否合格(BMI身體質量指數或者PBF體脂百分比),每項原始測試數據,通過不同項目各自規定的標准轉換成100分制的分數,最終匯總得出個人的評定成績,而且能夠批量計算。

算法思路 :
1.總體思路。通過讀取Excel表上該行人員的性別、年齡、海拔數據(計算3000米跑才需要,其它項目不需要),和原始成績,去查詢該項“成績計算標准表”,得到對應的分數,將分數寫入該項目“換算成績”一列中。循環計算完所有的列。
2.制作成績計算標准表。通過分析各項“成績計算標准表”,發現標准表只是參照標准表,不是連續的全覆蓋,以男子引體向上成績計算標准為例,標准中24歲以下,只規定了單桿30個100分,27個95分,那么28/29個的情況多少分呢?

只能是我們根據公平原則去補充,在30/27之間去取平均分,這可以通過代碼自動換算(3000米跑),也可以手工計算(引體向上、仰卧起坐等),補充到成績計算標准表里,精確到小數點后一位。

3.讀取成績計算標准表。通過Python的openpyxl模塊讀取補充成績計算標准表中的數據,制成 {原始單杠個數:分數} 格式的字典,以供查詢。
二、年齡計算
我認為編程有一個基本原則,就是做一步,驗證一步,否則代碼積累很多之后再驗證正確性,BUG就可能非常復雜,難以排除。
所以要能夠及時驗證計算的正確性,就將計算的幾個要素一開始就納入進來,性別、海拔、原始成績都可以直接讀取,但是年齡是動態的,不同時間組織的考核,人員的年齡會可能不同,最佳方式就是通過出生日期,即時計算出人員在考核時的年齡,能夠精確到天。

函數calculate_age(born),參數born是出生日期,函數返回的就是年齡值。
import openpyxl # 導入openpyxl模塊
import datetime as dt
# 打開Excel文件'通用訓練課目考核成績計算.xlsx'
wb=openpyxl.load_workbook('通用訓練課目考核成績計算.xlsx')
# 打開Excel文件中的工作簿“體能考核成績”
ws_training_performance = wb['體能考核成績']
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 #生日的月日大於今天的月日,則今天不滿周歲,要減1
else:
return today.year - born.year #生日的月日小於或等於今天的月日,則已滿周歲,不用減1
#iter_rows方法截取的表格數據從原表第6行,第2列(B列)開始
rngs = ws_training_performance.iter_rows(min_row=6,min_col=2)
for row in rngs: #截取的表格數據逐行循環
if row[3].value: #生日數據不為空,則對這一行的生日數據進行處理,row[n]中的n從0開始
# print(row[3].value)
age = calculate_age(row[3].value) # 由出生日期計算年齡,精確到天
row[4].value = age #將年齡值寫入到表中的年齡表格中
wb.save('計算結果.xlsx')
運行上面的代碼,生成一個Excel文件“計算結果.xlsx”:

這里實現了年齡自動計算的功能,但代碼的健壯性不足,比如出生日期的格式如果不對,會彈出錯誤,這將在后面的工作中逐步完善。
原創不易,有償下載,請多支持:
軍事體能考核成績評定系統下載
軍事體能考核成績評定系統全套Python源碼下載
