class searchByPlyr(object): def __init__(self): self.fontsize = 10 self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 8 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.RoP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('球员数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.stats_setting = {} # 保存查询条件设置 self.plyr_ent_value = StringVar() self.plyr_ent_value.set('LeBron James') self.RoP = StringVar() self.RoP.set(None) self.AoS = StringVar() self.AoS.set(None) self.scope = StringVar() self.PON = StringVar() self.PON.set('yes') self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.plyr = None self.plyr_ent = None def label(self, win, text, fs, w, h, ac): return Label(win, text=text, font=('SimHei', fs), width=w, height=h, anchor=ac) def one_tick_sel(self, win, text, value, w, variable, command): return Radiobutton(win, text=text, value=value, command=command, variable=variable, width=w, height=1) def place_sep(self, win, row, columnspan=12): # 分割线 sep = ttk.Separator(win, orient='horizontal') sep.grid(padx=3, pady=3, row=row, column=0, columnspan=columnspan, sticky='ew') def place_equal_inf(self, row): # 信息数据Frame equal_fm = Frame(self.wd) equal_fm.grid(row=row, column=0, columnspan=12) ls = ['Tm', 'Opp', 'GS', 'RoH', 'WoL'] if self.RoP.get() == 'regular'\ else ['Tm', 'Opp', 'GS', 'RoH', 'WoL', 'Series'] self.place_stat(equal_fm, ls, 'i // 3 + 1', 'i % 3 * 2', type=0) def place_basic(self, row): # 基础数据Frame basic_fm = Frame(self.wd) basic_fm.grid(row=row, column=0, columnspan=12) ls = [ 'PTS', 'TRB', 'AST', 'BLK', 'STL', 'TOV', 'ORB', 'DRB', 'PF', 'MP', 'GmSc', '+/-' ] self.place_stat(basic_fm, ls, 'i // 3 + 1', 'i % 3 * 4') def place_shooting(self, row): # 投篮数据Frame shooting_fm = Frame(self.wd) shooting_fm.grid(row=row, column=0, columnspan=12) ls = ['FG', 'FGA', 'FG%', '3P', '3PA', '3P%', 'FT', 'FTA', 'FT%'] self.place_stat(shooting_fm, ls, 'i // 3 + 1', 'i % 3 * 4') def place_inf(self, row): # 信息比较数据Frame inf_fm = Frame(self.wd) inf_fm.grid(row=row, column=0, columnspan=12) ls = ['G', 'Date', 'Age', 'Diff'] if self.RoP.get() == 'regular'\ else ['G', 'Playoffs', 'G#', 'Diff'] self.place_stat(inf_fm, ls, 'i // 2 + 1', 'i % 2 * 4') def place_stat(self, win, ls, row_, col_, type=1): # type 1:大于小于 0:等于 # ==============查询条件输入框布局==================== for i, k in enumerate(ls): row, col = eval(row_), eval(col_) if type: self.label(win, en2ch[k][0] + ':', self.fontsize, self.col_w, 1, 'e').grid(padx=self.paddingx, pady=self.paddingy, row=row, column=col) ent1, ent2 = Entry(win, width=10), Entry(win, width=10) self.label(win, '-', self.fontsize, self.col_w // 3, 1, 'center').grid(padx=self.paddingx // 2, pady=self.paddingy, row=row, column=col + 2) ent1.grid(row=row, column=col + 1, padx=self.paddingx // 2, pady=self.paddingy) ent2.grid(row=row, column=col + 3, padx=self.paddingx // 2, pady=self.paddingy) self.stats_setting[k] = [ent1, ent2] else: self.label(win, en2ch[k][0] + ':', self.fontsize, 12, 1, 'center').grid(padx=self.paddingx, pady=self.paddingy, row=row, column=col) ent = Entry(win, width=10) ent.grid(row=row, column=col + 1, padx=self.paddingx, pady=self.paddingy) self.stats_setting[k] = eval('[ent1, ent2]') if type else eval( '[ent]') def RoPselection(self): [i.grid_remove() for i in self.wd.grid_slaves()[:-10]] self.place_equal_inf(3) self.place_sep(self.wd, 4) self.place_basic(5) self.place_sep(self.wd, 6) self.place_shooting(7) self.place_sep(self.wd, 8) self.place_inf(9) def AoSselection(self): pass def plyr_or_not(self): # 是否按球员分组 self.plyr['text'] = '最小场数' if self.PON.get() == 'no' else '球员' self.plyr_ent_value.set('1') if self.PON.get( ) == 'no' else self.plyr_ent_value.set('LeBron James') def search_enter(self, event): # 绑定回车键触发搜索函数 self.search() def search(self): # 点击按钮触发搜索函数 if self.stats_setting: stats = {} for k in self.stats_setting.keys(): # 遍历文本框控件,收集查询条件 tp = 1 if en2ch[k][1] == 1 or k == 'WoL' or k == 'MP' else 0 ent_s = self.stats_setting[k] if len(ent_s) == 1: # 相等比较 if ent_s[0].get(): stats[k] = [ ' == "%s" and ' % ent_s[0].get() if tp else ' == %s and ' % ent_s[0].get() ] else: if ent_s[0].get() and ent_s[1].get(): # 大于小于同时存在 stats[k] = [ ' >= "%s" and ' % ent_s[0].get() if tp else ' >= %s and ' % ent_s[0].get(), ' <= "%s" and ' % ent_s[1].get() if tp else ' <= %s and ' % ent_s[1].get() ] elif ent_s[0].get() and not ent_s[1].get(): # 只有大于 stats[k] = [ ' >= "%s" and ' % ent_s[0].get() if tp else ' >= %s and ' % ent_s[0].get() ] elif not ent_s[0].get() and ent_s[1].get(): # 只有小于 stats[k] = [ ' <= "%s" and ' % ent_s[1].get() if tp else ' <= %s and ' % ent_s[1].get() ] if not stats: messagebox.showinfo('提示', '请设置查询条件!') else: if self.PON.get() == 'yes': # 单球员查询 if self.plyr_ent_value.get() not in self.pn2pm.keys(): messagebox.showinfo('提示', '球员姓名不存在!') return player = Player(self.pn2pm[self.plyr_ent_value.get()], self.RoP.get()) if self.scope.get() == '单场比赛': pt = 1 res = player.search_by_game(stats) elif self.scope.get() == '赛季': pt = 2 res = player.search_by_season(stats, int(self.AoS.get())) elif self.scope.get() == '职业生涯': pt = 2 res = player.search_by_career(stats, int(self.AoS.get())) res = [[self.plyr_ent_value.get(), x] for x in res] elif self.scope.get() == '连续比赛': pt = 0 res = player.search_by_consecutive(stats) else: # 按球员分组查询 pt = 0 # start = time.time() # pp = [[x, self.RoP.get(), stats] for x in list(self.pm2pn.keys())] # print(time.time() - start) # pool = ThreadPool(4) # tmp = pool.map(process, pp) # pool.close() # pool.join() # print(time.time() - start) # res = [] # for x in tmp: # if x: # res.append(x) # print(time.time() - start) start = time.time() res = [] min_ = 50 if self.RoP.get() == 'regular' else 5 for p in tqdm(list(self.pm2pn.keys())): player = Player(p, self.RoP.get()) if player.exists and not isinstance( player.data, list) and player.games > min_: if self.scope.get() == '单场比赛': tmp = player.search_by_game( stats, minG=int(self.plyr_ent_value.get())) if tmp: res.append([self.pm2pn[p], tmp]) elif self.scope.get() == '赛季': pt = 2 tmp = player.search_by_season( stats, int(self.AoS.get())) res += tmp elif self.scope.get() == '职业生涯': pt = 2 tmp = player.search_by_career( stats, int(self.AoS.get())) if tmp: tmp = [[self.pm2pn[p], x] for x in tmp] res += tmp elif self.scope.get() == '连续比赛': pt = 0 res += player.search_by_consecutive( stats, minG=int(self.plyr_ent_value.get())) print(time.time() - start) # 处理结果 if res: RP = regular_items_en if self.RoP.get( ) == 'regular' else playoff_items_en win_klass = ShowSingleResults if pt else ShowGroupResults print(win_klass) if pt == 2: win_klass = ShowResults result_window = win_klass(res, list(RP.keys()), self.RoP.get(), detail=False if pt else True, AoS=int(self.AoS.get())) win_title = '%s %s 查询结果(按%s)' % (self.plyr_ent_value.get(), self.RoP_dict[self.RoP.get()], self.scope.get())\ if pt else '%s查询结果(按%s)' % ('常规赛' if self.RoP.get() == 'regular' else '季后赛', self.scope.get()) result_window.title(win_title) num = (len(res) - 2 * pt) if pt != 2 else len(res) result_window.loop('共查询到%d组数据' % num, stats) else: messagebox.showinfo('提示', '未查询到符合条件的数据!') else: messagebox.showinfo('提示', '请选择比赛类型!') def loop(self): # ==============背景图片==================== bg_img = Image.open('../images/james.jpg') bg_img = bg_img.resize( (int(bg_img.size[0] * 0.95), int(bg_img.size[1] * 0.95))) bg_img = cv2.cvtColor(np.asarray(bg_img), cv2.COLOR_RGB2BGR) bg_img = cv2.copyMakeBorder(bg_img, 0, 0, 100, 100, cv2.BORDER_REFLECT_101) bg_img = Image.fromarray(cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGB)) bg_img.putalpha(32) # 透明度 bg_img = ImageTk.PhotoImage(bg_img) Label(self.wd, image=bg_img).place(x=0, y=0, relwidth=1, relheight=1) # ==============球员名称label&entry==================== self.plyr = self.label(self.wd, '球员:', self.fontsize, self.col_w, 1, 'e') self.plyr_ent = Entry(self.wd, width=20, textvariable=self.plyr_ent_value, font=('SimHei', 15)) self.plyr.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=0) self.plyr_ent.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=1, columnspan=3) # ==============单球员or多球员单选Frame==================== plyr_fm = Frame(self.wd, height=1) plyr_yes = self.one_tick_sel(plyr_fm, '单球员查询', 'yes', self.radiobutton_w * 2, self.PON, self.plyr_or_not) plyr_no = self.one_tick_sel(plyr_fm, '按球员分组', 'no', self.radiobutton_w * 2, self.PON, self.plyr_or_not) plyr_fm.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=4, columnspan=3) plyr_yes.grid(row=1, column=0) plyr_no.grid(row=1, column=1) # ==============比赛类型组合选择Frame==================== gametype_fm = Frame(self.wd) rglr_sel = self.one_tick_sel(gametype_fm, '常规赛', 'regular', self.radiobutton_w, self.RoP, self.RoPselection) plyf_sel = self.one_tick_sel(gametype_fm, '季后赛', 'playoff', self.radiobutton_w, self.RoP, self.RoPselection) scope_sel = ttk.Combobox(gametype_fm, width=7, textvariable=self.scope) scope_sel['value'] = ['单场比赛', '赛季', '职业生涯', '连续比赛', '连续赛季'] scope_sel.current(0) ave_sel = self.one_tick_sel(gametype_fm, '场均', '1', 2, self.AoS, self.AoSselection) sum_sel = self.one_tick_sel(gametype_fm, '总和', '0', 2, self.AoS, self.AoSselection) self.AoS.set('1') self.place_sep(gametype_fm, 2, columnspan=2) gametype_fm.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=7, columnspan=4) rglr_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) plyf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=1) scope_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=3, column=2, columnspan=2) ave_sel.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=0, sticky='e') sum_sel.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=1, sticky='w') # ==============搜索button==================== search_img = Image.open('../images/kobe_dunk.jpg') search_img = ImageTk.PhotoImage(search_img) search_button = Button(self.wd, text='查 询', width=60, height=30, image=search_img, compound='center', cursor='hand2', command=self.search, font=('SimHei', 14)) search_button.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=11) # ==============说明label==================== self.place_sep(self.wd, 20) notion = self.label(self.wd, '说明:', self.fontsize, self.col_w, 1, 'e') help_note = '主客场:0客1主 比赛序号:赛季第n场比赛\n' \ '年龄:35-001 赛果:W/L 日期:%s\n' \ '季后赛轮次:E/WC1->第一轮,E/WCS->分区半决赛,' \ 'E/WCF->分区决赛,FIN->总决赛' % time.strftime("%Y%m%d") notion_ = Label(self.wd, text=help_note, font=('SimHei', 11), width=self.col_w * 5, height=6, anchor='w', justify='left') notion.grid(padx=self.paddingx, pady=self.paddingy, row=26, column=0) notion_.grid(padx=self.paddingx, pady=self.paddingy, row=26, rowspan=6, column=1, columnspan=11, sticky='w') # wd.attributes("-alpha", 0.8) self.RoP.set('regular') self.RoPselection() self.wd.mainloop()
class Search_by_game(object): def __init__(self): self.fontsize = 10 self.font = ('SimHei', self.fontsize) self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 10 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.ROP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('比赛数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.comboboxs = [] self.stats = [] self.season = StringVar() self.ROP = StringVar() self.ROP.set(None) self.qtr = StringVar() self.qtr.set('whole') self.sels = [] self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.radioframe = None def one_tick_sel(self, text, value, command, win): return Radiobutton(win, text=text, value=value, command=command, variable=self.qtr, width=self.radiobutton_w, height=1) def season_cbox_sel(self, event): [i.grid_remove() for i in self.radioframe.grid_slaves()] if self.season.get()[:4] >= '1996': end = 8 elif self.season.get()[:4] < '1983': end = 1 else: end = 2 for ix, i in enumerate(self.sels[:end]): i.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=ix) def search_enter(self, event): # 绑定回车键触发搜索函数 self.search() def search(self): print('功能尚未开放') def timespan(self): pass def ROPselection(self): pass def QTRselection(self): pass def loop(self): # 背景图片 bg_img = Image.open('../images/james2.jpg') bg_img.putalpha(64) bg_img = ImageTk.PhotoImage(bg_img) Label(self.wd, image=bg_img).place(x=0, y=0, relwidth=1, relheight=1) self.radioframe = Frame(self.wd) self.radioframe.grid(padx=self.paddingx, pady=self.paddingy, row=4, column=0, columnspan=5, sticky='ew') # 控件设置 season_label = Label(self.wd, text='赛季:', font=self.font, width=self.col_w, height=1, anchor='e') season_sel = ttk.Combobox(self.wd, width=9, textvariable=self.season) season_sel['value'] = ['%d-%d' % (x, x + 1) for x in range(1949, 2020)] season_sel.current(len(season_sel['value']) - 1) timespan_frame = LabelFrame(self.wd, text='时间跨度', labelanchor="nw") sglssn_sel = self.one_tick_sel('单赛季', 'single_season', self.timespan, timespan_frame) tilnow_sel = self.one_tick_sel('至今', 'tillnow', self.timespan, timespan_frame) rf_frame = LabelFrame(self.wd, text='比赛类型', labelanchor="nw") rglr_sel = self.one_tick_sel('常规赛', 'regular', self.ROPselection, rf_frame) plyf_sel = self.one_tick_sel('季后赛', 'playoff', self.ROPselection, rf_frame) search_img = Image.open('../images/kobe_dunk.jpg') search_img = ImageTk.PhotoImage(search_img) search_button = Button(self.wd, text='查 询', width=65, height=30, image=search_img, compound='center', cursor='hand2', command=self.search, font=('SimHei', 14)) team_label = Label(self.wd, text='球队:', font=self.font, width=self.col_w, height=1, anchor='e') oppteam_label = Label(self.wd, text='对手球队:', font=self.font, width=self.col_w, height=1, anchor='e') team_ent = Entry(self.wd, width=10) oppteam_ent = Entry(self.wd, width=10) sel_texts = [['全场', 'whole'], ['进阶', 'advcd'], ['第一节', '1st'], ['第二节', '2nd'], ['上半场', '1hf'], ['第三节', '3rd'], ['第四节', '4th'], ['下半场', '2hf']] for ts in sel_texts: self.sels.append(self.one_tick_sel(ts[0], ts[1], self.QTRselection, self.radioframe)) # 控件布局 season_label.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=0) season_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=1) season_sel.bind("<<ComboboxSelected>>", self.season_cbox_sel) timespan_frame.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=2) sglssn_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) tilnow_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0) rf_frame.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=3) rglr_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) plyf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0) search_button.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=4, columnspan=2) team_label.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=0) oppteam_label.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=2) team_ent.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=1) oppteam_ent.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=3) # whole_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=2, sticky='ew') # advcd_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=3, sticky='ew') # first_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0, sticky='ew') # secnd_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=1, sticky='ew') # fsthf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=2, sticky='ew') # third_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=3, sticky='ew') # forth_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=4, sticky='ew') # sndhf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=5, sticky='ew') self.wd.mainloop()
#!/usr/bin/python # -*- coding:utf8 -*- from klasses.Player import Player from util import LoadPickle, writeToPickle from klasses.stats_items import * from tqdm import tqdm import pandas as pd # 计算球员赛季和生涯场均及总和并保存 pm2pn = LoadPickle('../data/playermark2playername.pickle') for p in tqdm(list(pm2pn.keys())): # print(p) for RoP in ['regular', 'playoff']: player = Player(p, RoP) if player.exists and not isinstance(player.data, list): res = [] for sss, ss in player.yieldSeasons(): sss = player.on_board_games(sss) res += player.ave_and_sum(sss, type=2) res[-2] = [ss] + res[-2] res[-1] = [ss] + res[-1] sss = player.on_board_games(player.data) res += player.ave_and_sum(sss, type=2) res[-2] = ['career'] + res[-2] res[-1] = ['career'] + res[-1] res = pd.DataFrame(res, columns=['Season'] + list(regular_items_en.keys() if RoP == 'regular' else playoff_items_en.keys())) # for col in res.columns: # res[col] = res[col].astype('category')