New bowling score tabulation program release

1.新プログラムリリース

 ボウリングのスコア集計のプログラムをリリースします。

デバッグはまだ未完ですが、通常使用の範囲では問題なしの見込みです。

次回のボウリングスコア登録から使用していきます。

2.実行結果

 6ゲーム分のスコアを3ゲームずつ分けて登録しました。

プログラムの実行結果
メイン画面

年間アベレージ、月間アベレージ、ハイスコアのベスト3、3ゲームトータルのベスト3を表示できています。

また、過去の年間アベレージも算出し表示しています。

3.制約事項

何点か、制約事項があります。

(1)同日に4ゲーム以上を登録する場合、3ゲームずつ分けて登録しますが、

  3ゲームトータルのハイスコアチェックは、3ゲーム登録時のみ実施します。

  例えば、5ゲームを登録する場合、最初の3ゲーム登録時にチェックを行い、残りの2ゲームはチェックの対象外になります。

また、6ゲーム登録する場合は、3ゲームずつの登録になるので、両方ともチェックの対象になります。

(2)3ゲーム未満の登録時は、登録しないテキストフィールドに「999」を入力することにします。

「none」とかの文字を入れようとも考えましたが、「none」だと、文字列を数値として扱うときに都合が悪いです。

   int(文字列)で、文字列を数値として扱う場合、noneだとエラーになります。

(3)年間アベレージは2020年から8年分を計算します。

  (2020,2021,2022,2023,2024,2025,2026,2027年)

  これは、データの確保の数の問題だけで、それ以上の表示をする場合は、データ領域を拡張すれば対応可能です。

4.ソースコード

画面構成の個々の部品のIDなどは省略し、ソースコードは公開します。

※貼り付けたら下記のような感じになってしまい、タブの長さを変えられないので、そのままにします。

#This program is for calculating of bowling-score
#Average in this year, monthly
#High game top3
#Input data is CSV file that format "No. of game, date, score"
import ui
import csv

thisYear = 2025		#年が変わったら更新
gNum = 0		#game num.
dnum = 0		#Num. of data
top1 = 0		#Top score = Highest
top2 = 0		#Second score
top3 = 0		#3rd score
top1_3g = 0		#Top1 of Total-3games
top2_3g = 0		#Top2 of Total-3games
top3_3g = 0		#Top3 of Total-3games	
totalGameNum = 0
G_MAX = 2000	#Max. game nums
gNumLst = [0] * G_MAX		#game num. list
dateLst = [0] * G_MAX		#Date List
scoreLst = [0] * G_MAX		#Score List
sumScYear = [0,0,0,0,0,0,0,0]	#for Sum of score in year 2020.2022.....2027
gNumYear = [0,0,0,0,0,0,0,0]	#for Num. of game in year 2020.2022.....2027
monScData = [[0] * 12 for i in range(8)]	#Sum. score for each month
monGnData = [[0] * 12 for i in range(8)]	#Num. of game for each month
aveMonth = [0] * 12
ret = [('','','')] * G_MAX * 4	#add *4 2021/8/25

#Display Total Game Num.
def displayTotalGameNum():
	totalNum.text = str(totalGameNum)		

def displayTotal3gHS():
	highsg1.text = str(top1_3g)
	highsg2.text = str(top2_3g)
	highsg3.text = str(top3_3g)


def displayHighScore():
	highs1.text = str(top1)
	highs2.text = str(top2)
	highs3.text = str(top3)

def displayThisYearData():
	n = thisYear - 2020
	ave = format(sumScYear[n]/gNumYear[n], '.1f')	#Average in this year
	aveY.text = str(ave)

def displayYearsData():
	for i in range(0,7):
		if gNumYear[i] != 0:
			ave = format(sumScYear[i]/gNumYear[i], '.1f')
			print(ave)
			if i == 0:
				ave2020.text = str(ave)
			elif i == 1:
				ave2021.text = str(ave)
			elif i == 2:
				ave2022.text = str(ave)		
			elif i == 3:			
				ave2023.text = str(ave)
			elif i == 4:			
				ave2024.text = str(ave)	
			elif i == 5:			
				ave2025.text = str(ave)
			elif i == 6:			
				ave2026.text = str(ave)
			elif i == 7:			
				ave2027.text = str(ave)		
			
#Display Average of month in this year
def displayMonthAve():
	for m in range(12):
		if aveMonth[m] != 0:
			if m == 0:
				aveM1.text = str(aveMonth[0])
			elif m == 1:
				aveM1.text = str(aveMonth[1])
			elif m == 2:
				aveM1.text = str(aveMonth[2])
			elif m == 3:
				aveM1.text = str(aveMonth[3])
			elif m == 4:
				aveM1.text = str(aveMonth[4])
			elif m == 5:
				aveM1.text = str(aveMonth[5])
			elif m == 6:
				aveM1.text = str(aveMonth[6])
			elif m == 7:
				aveM1.text = str(aveMonth[7])
			elif m == 8:
				aveM1.text = str(aveMonth[8])
			elif m == 9:
				aveM1.text = str(aveMonth[9])
			elif m == 10:
				aveM1.text = str(aveMonth[10])
			elif m == 11:
				aveM1.text = str(aveMonth[11])

#Calc. Month Data
#Only this year
def calcMonthData():
		for m in range(12):
			gn = monGnData[thisYear-2020][m]
			if gn != 0:
				aveMonth[m] = format(monScData[thisYear-2020][m] / gn, '.1f')

def setYearsData(str_d, sc):
	if str_d.startswith('2020') == True:	#2020?
		sumScYear[0] = sumScYear[0] + sc
		gNumYear[0] += 1		#Renew Num. of Game in 2021
		mon = str_d[4:6]		#set Month
		monScData[0][int(mon)-1] += sc	#Renew sum_score of each month		
		monGnData[0][int(mon)-1] += 1		
	if str_d.startswith('2021') == True:	#2021?
		sumScYear[1] = sumScYear[1] + sc
		gNumYear[1] += 1		#Renew Num. of Game in 2021
		mon = str_d[4:6]		#set Month
		monScData[1][int(mon)-1] += sc	#Renew sum_score of each month		
		monGnData[1][int(mon)-1] += 1		
	if str_d.startswith('2022') == True:	#2022?
		sumScYear[2] = sumScYear[2] + sc
		gNumYear[2] += 1		#Renew Num. of Game in 2022		
		mon = str_d[4:6]		#set Month
		monScData[2][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[2][int(mon)-1] += 1		
	if str_d.startswith('2023') == True:	#2023?
		sumScYear[3] = sumScYear[3] + sc
		gNumYear[3] += 1		#Renew Num. of Game in 2023
		mon = str_d[4:6]		#set Month
		monScData[3][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[3][int(mon)-1] += 1			
	if str_d.startswith('2024') == True:	#2024?
		sumScYear[4] = sumScYear[4] + sc
		gNumYear[4] += 1		#Renew Num. of Game in 2024	
		mon = str_d[4:6]		#set Month
		monScData[4][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[4][int(mon)-1] += 1			
	if str_d.startswith('2025') == True:	#2025?
		sumScYear[5] = sumScYear[5] + sc
		gNumYear[5] += 1		#Renew Num. of Game in 2025
		mon = str_d[4:6]		#set Month
		monScData[5][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[5][int(mon)-1] += 1			
	if str_d.startswith('2026') == True:	#2026?
		sumScYear[6] = sumScYear[6] + sc
		gNumYear[6] += 1		#Renew Num. of Game in 2026
		mon = str_d[4:6]		#set Month
		monScData[6][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[6][int(mon)-1] += 1			
	if str_d.startswith('2027') == True:	#2027?
		sumScYear[7] = sumScYear[7] + sc
		gNumYear[7] += 1		#Renew Num. of Game in 2027
		mon = str_d[4:6]		#set Month
		monScData[7][int(mon)-1] += sc	#Renew sum_score of each month
		monGnData[7][int(mon)-1] += 1			

	print(sumScYear, gNumYear)		

def setTotal3g(nd1, nd2, nd3):
	global top1_3g,top2_3g,top3_3g
	
	tsc = nd1 + nd2 + nd3		#Total
	if top3_3g < tsc:
		if top2_3g < tsc:
			if top1_3g < tsc:
				top3_3g = top2_3g
				top2_3g = top1_3g
				top1_3g = tsc
			else:
				top3_3g = top2_3g
				top2_3g = tsc
		else:
			top3 = tsc	


def setHighScore(sc):
	global top1,top2,top3
	if top3 < sc:
		if top2 < sc:
			if top1 < sc:
				top3 = top2
				top2 = top1
				top1 = sc
			else:
				top3 = top2
				top2 = sc
		else:
			top3 = sc	

def readData():
	global gNum
	global ret
	global totalGameNum
	count3 = 0
	ts3g = [0,0,0]

	fr = open("bs2025.csv")		#open file
	rp = csv.reader(fr)		#for read csv

	for rd in rp:
		print(rd)		#rd[0]=NO., rd[1]=date, rd[2]=score
		if rd == []:
			break	
		else:
			if gNum > G_MAX:  #check Max num.(for mem.)
				break
			#print(rd[0], rd[1], rd[2])
			ret[(gNum)*4] = rd[0]		#for check
			ret[(gNum)*4+1] = rd[1]		#for check
			ret[(gNum)*4+2] = rd[2]
			gNumLst[gNum] = rd[0]		#set game num. list
			dateLst[gNum] = rd[1]		#set date list
			scoreLst[gNum] = rd[2]		#set score list
			setHighScore(int(rd[2]))	#Set HighScore
			setYearsData(rd[1], int(rd[2]))	#Set sum of Score in year
			calcMonthData()
			gNum += 1
			if gNum >= 3:			#ちょっとごまかし
				if dateLst[gNum-2] == dateLst[gNum-1]:
					ts3g[0] = int(scoreLst[gNum-3])
					ts3g[1] = int(scoreLst[gNum-2])
					ts3g[2] = int(scoreLst[gNum-1])
					count3 += 1
				else:
					count3 = 0
				if count3 == 2:		#3games?
					setTotal3g(ts3g[0], ts3g[1], ts3g[2])					
					count3 = 0		

	totalGameNum = gNum
	fr.close()
	return ret



#Write New Data Proc.
#without checking valid data
#valid or not should be check in caller
def writeData(ndate, nd):
	global gNum
	print("gNum before write=", gNum, ndate, nd)
	fw = open('bs2025.csv','a')
	wp = csv.writer(fw,lineterminator='\n')
	ad_data = ['','','','']		#append data: GameNum, Date, Score
	gNumLst[gNum] = ad_data[0] = str(gNum+1)
	dateLst[gNum] = ad_data[1] = ndate
	scoreLst[gNum] = ad_data[2] = str(nd)
	setHighScore(int(nd))
	setYearsData(ad_data[1], int(nd))	#Set sum of Score in year
	calcMonthData()
	gNum += 1				#increment here. because for display 0 to g_num-1
	
	print("game num after write=",gNum)				#for check
	print("add data=", ad_data[0],ad_data[1],ad_data[2])		#for check
	wp.writerow(ad_data)
	fw.close()


def ExcecProc(sender):
	res = 0					#input data is OK
	dnum = 					#init. data num.
	nd1 = nd_sc1.text			#set new data1
	nd2 = nd_sc2.text			#set new data2
	nd3 = nd_sc3.text			#set new data3

	if nd1.isdecimal() == False or nd2.isdecimal() == False or nd3.isdecimal() == False:
		msg = 'One or more are not decimal'
		print(msg)
		err_msg.txt = msg
		res = -1
		return res		
			
	if nd1 == '' or nd2 == '' or nd3 == '':		#One or more are blank?
		msg = 'One or more are blank!'
		print(msg)
		err_msg.text = msg		
		res = -10
		return res

	if int(nd1) == 0 or int(nd2) == 0 or int(nd3) == 0:	#One or more are zero?
		msg = 'One or more are zero!'
		print(msg)
		err_msg.text = msg
		res = -20
		return res

	if int(nd1) != 999 and int(nd1) > 300:
			res = -30
	if int(nd2) != 999 and int(nd2) > 300:
			res = -40
	if int(nd3) != 999 and int(nd3) > 300:
			res = -50
											
	if res < 0:
		msg = 'One or more are over 300'			
		print(msg)
		err_msg.text = msg
		return res

	#Read Date
	regdate = nd_date.text			#input reg. date
	
	if int(nd1) != 999:
		writeData(regdate, nd1)		#with set_highScore
		dnum += 1
	if int(nd2) != 999:
		writeData(regdate, nd2)		#with set_highScore
		dnum += 1
	if int(nd3) != 999:
		writeData(regdate, nd3)		#with set_highScore
		dnum += 1
	
	if(dnum == 3):				#3game in a day?
		setTotal3g(int(nd1), int(nd2), int(nd3))
		displayTotal3gHS()

	displayTotalGameNum()			#Renew Total Game Num.

	displayHighScore()
	displayYearsData()
	displayThisYearData()
	displayMonthAve()
	displayTotalGameNum()
	displayTotal3gHS()

v = ui.load_view()
v.present('sheet')

nd_sc1 = v['tf_sc1']		#Input Score1 in text field
nd_sc2 = v['tf_sc2']		#Input Score2 in text field 
nd_sc3 = v['tf_sc3']		#Input Score3 in text field  
nd_date = v['tf_date']		#Input Score1 in text field 
err_msg = v['tf_msg']		#for display error message
aveY = v['tf_avY']		#Average in this year
aveM1 = v['tf_avM1']		#average of Jan. in this year 
aveM2 = v['tf_avM2']		#average of Feb. in this year 
aveM3 = v['tf_avM3']		#average of Mar. in this year 
aveM4 = v['tf_avM4']		#average of Apr. in this year 
aveM5 = v['tf_avM5']		#average of May. in this year 
aveM6 = v['tf_avM6']		#average of Jun. in this year 
aveM7 = v['tf_avM7']		#average of Jul. in this year 
aveM8 = v['tf_avM8']		#average of Aug. in this year 
aveM9 = v['tf_avM9']		#average of Sep. in this year 
aveM10 = v['tf_avM10']		#average of Oct. in this year 
aveM11 = v['tf_avM11']		#average of Nov. in this year 
aveM12 = v['tf_avM12']		#average of Dec. in this year 
highs1 = v['tf_hs1']		#High Score No.1
highs2 = v['tf_hs2']		#High Score No.2
highs3 = v['tf_hs3']		#High Score No.3
highsg1 = v['tf_hs3g1']		#High Score of 3 game  No.1
highsg2 = v['tf_hs3g2']		#High Score of 3 game  No.2
highsg3 = v['tf_hs3g3']		#High Score of 3 game  No.3
ave2020 = v['tf_2020av']	#Average in 2020
ave2021 = v['tf_2021av']	#Average in 2021
ave2022 = v['tf_2022av']	#Average in 2022
ave2023 = v['tf_2023av']	#Average in 2023
ave2024 = v['tf_2024av']	#Average in 2024
ave2025 = v['tf_2025av']	#Average in 2025
ave2026 = v['tf_2026av']	#Average in 2026
ave2027 = v['tf_2027av']	#Average in 2027
totalNum = v['tf_TotalNum']
r_data = readData()		#read csv-file and set data
displayHighScore()
displayYearsData()
displayThisYearData()
displayMonthAve()
displayTotalGameNum()
displayTotal3gHS()

5.UIファイル

画面レイアウトの.pyuiファイルについては、簡単に添付できないようで、そちらは後日、添付することにします。

画面は下記のような画面です。

UI画面、.pyui
Screenshot

6.ファイル

後日、添付の予定です。

.py, .pyui, .csvファイルを添付の予定です。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です