前回の続きとして、openpyxlでトーナメント表を作成した。とりあえず参加者が一列に並んでいる状態のもの。
プログラムの途中までは、一昨日のものと全く一緒。その後ろでopenpyxlで作業をしている。手順として、
(1)左に必要な選手情報を並べる。
(2)横に線を引く
(3)上から順次2回戦分の線を引いていく。(条件分岐: シード横の場合1回戦分の線も引く)
(4)線を引くのと同時に順次試合番号の記入
(5)3回戦以降は各位置に対応するインデックスを保持して、インデックス2個ずつで順次線を引くと同時に試合番号の記入
list2tournament.py
--------------------------------------------------------
import sys
import numpy as np
import pandas as pd
import openpyxl
from openpyxl.styles import Alignment, Border, Side
import numpy as np
import pandas as pd
import openpyxl
from openpyxl.styles import Alignment, Border, Side
filename=sys.argv[1]
df=pd.read_excel(filename)
df=df.sort_values(by=["前年度ランク"], ascending=True)
df=pd.read_excel(filename)
df=df.sort_values(by=["前年度ランク"], ascending=True)
rank=df[df["前年度ランク"]>=0]
temp=df[~(df["前年度ランク"]>=0)]
temp=temp.reset_index(drop=True)
temp=df[~(df["前年度ランク"]>=0)]
temp=temp.reset_index(drop=True)
K=np.zeros(temp.shape[0])
for i in range(K.shape[0]):
K[i]=np.sum(df['チーム名']==temp['チーム名'][i])
temp['チーム内ランク']=temp['チーム内ランク']/K
temp=temp.sort_values(by=["チーム内ランク", "チームランク"], ascending=True)
for i in range(K.shape[0]):
K[i]=np.sum(df['チーム名']==temp['チーム名'][i])
temp['チーム内ランク']=temp['チーム内ランク']/K
temp=temp.sort_values(by=["チーム内ランク", "チームランク"], ascending=True)
rank=pd.concat([rank, temp])
rank=rank.reset_index(drop=True)
rank.index+=1
rank.to_excel('rank_'+filename)
rank=rank.reset_index(drop=True)
rank.index+=1
rank.to_excel('rank_'+filename)
#tournament pairs considering rank
N=rank.shape[0]
N=rank.shape[0]
position=np.array([1, 4, 3, 2])
p1=2
while N>pow(2, p1):
i=0
while i<pow(2, p1-1):
position=np.r_[position[:4*i+1], np.zeros(2), position[4*i+1:]]
i+=1
i=0
while i<pow(2, p1):
if position[2*i]==0:
position[2*i]=pow(2, p1+1)+1-position[2*i+1]
else:
position[2*i+1]=pow(2, p1+1)+1-position[2*i]
i+=1
p1+=1
p2=1
while N-pow(2, p1-1)>pow(2, p2):
p2+=1
position=position[position<=pow(2, p1-1)+pow(2, p2)]
position[position>N]=0
p1=2
while N>pow(2, p1):
i=0
while i<pow(2, p1-1):
position=np.r_[position[:4*i+1], np.zeros(2), position[4*i+1:]]
i+=1
i=0
while i<pow(2, p1):
if position[2*i]==0:
position[2*i]=pow(2, p1+1)+1-position[2*i+1]
else:
position[2*i+1]=pow(2, p1+1)+1-position[2*i]
i+=1
p1+=1
p2=1
while N-pow(2, p1-1)>pow(2, p2):
p2+=1
position=position[position<=pow(2, p1-1)+pow(2, p2)]
position[position>N]=0
wb=openpyxl.Workbook()
ws=wb.active
ws.title='tournament'
ws=wb.active
ws.title='tournament'
#ヘッダー部を2行ごとに結合
#前6列にID, 選手姓, 選手名, '(', チーム名, ')'
n_header=6
i=1
while i<=position.shape[0]:
#i行目の処理
#i行目j列の結合と設定
j=1
while j<=n_header:
ws.merge_cells(start_row=2*i-1, start_column=j, end_row=2*i, end_column=j)
ws.cell(row=2*i-1, column=j).alignment=Alignment(
wrap_text=False,
horizontal='center',
vertical='center',
)
j+=1
#前6列にID, 選手姓, 選手名, '(', チーム名, ')'
n_header=6
i=1
while i<=position.shape[0]:
#i行目の処理
#i行目j列の結合と設定
j=1
while j<=n_header:
ws.merge_cells(start_row=2*i-1, start_column=j, end_row=2*i, end_column=j)
ws.cell(row=2*i-1, column=j).alignment=Alignment(
wrap_text=False,
horizontal='center',
vertical='center',
)
j+=1
#ここで列幅の自動調整をさせたいができていない
#while j<=n_header:
# ws.col_dimensions[j].alignment=Alignment(
# ShrinkToFit=True
# )
# j+=1
#ヘッダー中身書き込み
ws.cell(row=2*i-1, column=1, value=i)
ws.cell(row=2*i-1, column=4, value='(')
ws.cell(row=2*i-1, column=6, value=')')
if position[i-1]==0:
ws.cell(row=2*i-1, column=2, value='bye')
else:
ws.cell(row=2*i-1, column=2, value=rank['選手姓'][position[i-1]])
ws.cell(row=2*i-1, column=3, value=rank['選手名'][position[i-1]])
ws.cell(row=2*i-1, column=5, value=rank['チーム名'][position[i-1]])
i+=1
#while j<=n_header:
# ws.col_dimensions[j].alignment=Alignment(
# ShrinkToFit=True
# )
# j+=1
#ヘッダー中身書き込み
ws.cell(row=2*i-1, column=1, value=i)
ws.cell(row=2*i-1, column=4, value='(')
ws.cell(row=2*i-1, column=6, value=')')
if position[i-1]==0:
ws.cell(row=2*i-1, column=2, value='bye')
else:
ws.cell(row=2*i-1, column=2, value=rank['選手姓'][position[i-1]])
ws.cell(row=2*i-1, column=3, value=rank['選手名'][position[i-1]])
ws.cell(row=2*i-1, column=5, value=rank['チーム名'][position[i-1]])
i+=1
#1, 2回戦分
n_round1=1
n_round2=1
list_index=[]
n_seed=pow(2, p2)
i=1
while i<position.shape[0]:
temp=position[i-1:i+2]
if np.min(temp)==0:
temp[np.argmin(temp)]=np.max(temp)
if np.min(temp)<=n_seed:
#連続する3人の中にシードが含まれる場合
if np.argmin(temp)==0:
#若番側がシードの場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1)+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1)-1, column=n_header+2).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
)
ws.cell(row=2*i, column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*(i+1), column=n_header+1, value='1-'+str(n_round1))
ws.cell(row=2*i, column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
ws.cell(row=2*(i+1), column=n_header+1).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round1+=1
n_round2+=1
list_index.append(2*i)
else:
#若番側は1回戦スタートの場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+2).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+3, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+3, column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+1, value='1-'+str(n_round1))
ws.cell(row=2*(i+1), column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*i, column=n_header+1).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
ws.cell(row=2*(i+1), column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round1+=1
n_round2+=1
list_index.append(2*(i+1))
i+=3
else:
#連続する3人にシードがいない場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*i, column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round2+=1
list_index.append(2*i)
i+=2
n_round1=1
n_round2=1
list_index=[]
n_seed=pow(2, p2)
i=1
while i<position.shape[0]:
temp=position[i-1:i+2]
if np.min(temp)==0:
temp[np.argmin(temp)]=np.max(temp)
if np.min(temp)<=n_seed:
#連続する3人の中にシードが含まれる場合
if np.argmin(temp)==0:
#若番側がシードの場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1)+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1)-1, column=n_header+2).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
)
ws.cell(row=2*i, column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*(i+1), column=n_header+1, value='1-'+str(n_round1))
ws.cell(row=2*i, column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
ws.cell(row=2*(i+1), column=n_header+1).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round1+=1
n_round2+=1
list_index.append(2*i)
else:
#若番側は1回戦スタートの場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+2).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+3, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+3, column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*(i+1), column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+1, value='1-'+str(n_round1))
ws.cell(row=2*(i+1), column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*i, column=n_header+1).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
ws.cell(row=2*(i+1), column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round1+=1
n_round2+=1
list_index.append(2*(i+1))
i+=3
else:
#連続する3人にシードがいない場合
ws.cell(row=2*i, column=n_header+1).border=Border(
outline=True,
top=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+1).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2).border=Border(
outline=True,
top=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i+1, column=n_header+2).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+3).border=Border(
outline=True,
bottom=Side(style='medium', color='FF000000')
)
ws.cell(row=2*i, column=n_header+2, value='2-'+str(n_round2))
ws.cell(row=2*i, column=n_header+2).alignment=Alignment(
wrap_text=False,
horizontal='right',
vertical='center',
)
n_round2+=1
list_index.append(2*i)
i+=2
#3回戦以降
r=3 #階層数
while len(list_index)>1:
temp=[] #次のlist_index
n_roundr=1
i=0
while i<len(list_index):
x=list_index[i]+1
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
top=Side('medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
x+=1
while x<list_index[i+1]:
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
x+=1
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
bottom=Side('medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=(list_index[i]+list_index[i+1])/2, column=n_header+r, value=str(r)+'-'+str(n_roundr))
ws.cell(row=(list_index[i]+list_index[i+1])/2, column=n_header+r).alignment=Alignment(
horizontal='right',
vertical='center'
)
n_roundr+=1
temp.append((list_index[i]+list_index[i+1])/2)
i+=2
list_index=temp
r+=1
r=3 #階層数
while len(list_index)>1:
temp=[] #次のlist_index
n_roundr=1
i=0
while i<len(list_index):
x=list_index[i]+1
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
top=Side('medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
x+=1
while x<list_index[i+1]:
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
right=Side(style='medium', color='FF000000')
)
x+=1
ws.cell(row=x, column=n_header+r).border=Border(
outline=True,
bottom=Side('medium', color='FF000000'),
right=Side(style='medium', color='FF000000')
)
ws.cell(row=(list_index[i]+list_index[i+1])/2, column=n_header+r, value=str(r)+'-'+str(n_roundr))
ws.cell(row=(list_index[i]+list_index[i+1])/2, column=n_header+r).alignment=Alignment(
horizontal='right',
vertical='center'
)
n_roundr+=1
temp.append((list_index[i]+list_index[i+1])/2)
i+=2
list_index=temp
r+=1
ws.cell(row=list_index[0], column=n_header+r).border=Border(
outline=True,
bottom=Side('medium', color='FF000000')
)
wb.save('tournament.xlsx')
outline=True,
bottom=Side('medium', color='FF000000')
)
wb.save('tournament.xlsx')
--------------------------------------------------------
これで
python3 list2tournament.py sample.xlsx
でtournament.xlsxが出力される。(←これスマホからみたらとんでもないことになってて笑った)
シート分けやら左右に分けたりする場合、その時々に合わせてシートを何枚にするかなどを事前に決めてからであれば可能そう。
0 件のコメント:
コメントを投稿