libs.commands.ranking.rating
libs/commands/results/rating.py
1""" 2libs/commands/results/rating.py 3""" 4 5import pandas as pd 6 7import libs.global_value as g 8from cls.types import GameInfoDict 9from libs.data import aggregate, loader 10from libs.functions import message 11from libs.utils import formatter 12 13 14def aggregation() -> tuple[str, dict, dict]: 15 """レーティングを集計して返す 16 17 Returns: 18 tuple[str, dict, dict]: 19 - str: ヘッダ情報 20 - dict: 集計データ 21 - dict: 生成ファイルの情報 22 """ 23 24 # 情報ヘッダ 25 add_text: str = "" 26 headline: str = "*【レーティング】*\n" 27 28 # データ収集 29 # g.params.update(guest_skip=False) # 2ゲスト戦強制取り込み 30 game_info: GameInfoDict = aggregate.game_info() 31 if not game_info["game_count"]: # 検索結果が0件のとき 32 headline += "\t" + message.reply(message="no_hits") 33 return (headline, {}, {}) 34 35 df_results = loader.read_data("ranking/results.sql").set_index("name") 36 df_ratings = aggregate.calculation_rating() 37 38 # 最終的なレーティング 39 final = df_ratings.ffill().tail(1).transpose() 40 final.columns = ["rate"] 41 final["name"] = final.copy().index 42 43 df = pd.merge(df_results, final, on=["name"]).sort_values(by="rate", ascending=False) 44 df = df.query("count >= @g.params['stipulated']").copy() # 足切り 45 46 # 集計対象外データの削除 47 if g.params.get("unregistered_replace"): # 個人戦 48 for player in df.itertuples(): 49 if player.name not in g.member_list: 50 df = df.copy().drop(player.Index) 51 52 if not g.params.get("individual"): # チーム戦 53 df = df.copy().query("name != '未所属'") 54 55 # 順位偏差 / 得点偏差 56 df["point_dev"] = (df["rpoint_avg"] - df["rpoint_avg"].mean()) / df["rpoint_avg"].std(ddof=0) * 10 + 50 57 df["rank_dev"] = (df["rank_avg"] - df["rank_avg"].mean()) / df["rank_avg"].std(ddof=0) * -10 + 50 58 59 # 段位 60 if g.cfg.badge.grade.display: 61 for idx in df.index: 62 name = str(df.at[idx, "name"]).replace(f"({g.cfg.setting.guest_mark})", "") 63 df.at[idx, "grade"] = message.badge_grade(name, False) 64 65 # 表示 66 if g.params.get("anonymous"): 67 mapping_dict = formatter.anonymous_mapping(df["name"].unique().tolist()) 68 df["name"] = df["name"].replace(mapping_dict) 69 70 if df.empty: 71 headline += "\t" + message.reply(message="no_target") 72 return (headline, {}, {}) 73 74 headline += message.header(game_info, add_text, 1) 75 df = formatter.df_rename(df.filter( 76 items=[ 77 "name", "rate", "rank_distr", "rank_avg", "rank_dev", "rpoint_avg", "point_dev", "grade" 78 ] 79 ), short=False).copy() 80 df = df.drop(columns=[x for x in g.cfg.dropitems.ranking if x in df.columns.to_list()]) # 非表示項目 81 82 msg: dict = {} 83 table_param: dict = { 84 "index": False, 85 "tablefmt": "simple", 86 "numalign": "right", 87 "floatfmt": ["", ".1f", "", ".2f", ".0f", ".1f", ".0f"], 88 } 89 90 step = 30 91 length = len(df) 92 for i in range(int(length / step) + 1): 93 s = step * i 94 e = step * (i + 1) 95 if e + step / 2 > length: 96 table = df[s:].to_markdown(**table_param) 97 msg[s] = f"```\n{table}\n```\n" 98 break 99 100 table = df[s:e].to_markdown(**table_param) 101 msg[s] = f"```\n{table}\n```\n" 102 103 prefix_rating: str = "rating" 104 if g.params.get("filename"): 105 prefix_rating = f"{g.params["filename"]}" 106 107 file_list: dict = {"レーティング": ""} 108 match g.params.get("format", "default").lower().lower(): 109 case "csv": 110 file_list = { 111 "レーティング": formatter.save_output(df, "csv", f"{prefix_rating}.csv", headline), 112 } 113 case "text" | "txt": 114 file_list = { 115 "レーティング": formatter.save_output(df, "txt", f"{prefix_rating}.txt", headline), 116 } 117 118 return (headline, msg, file_list)
def
aggregation() -> tuple[str, dict, dict]:
15def aggregation() -> tuple[str, dict, dict]: 16 """レーティングを集計して返す 17 18 Returns: 19 tuple[str, dict, dict]: 20 - str: ヘッダ情報 21 - dict: 集計データ 22 - dict: 生成ファイルの情報 23 """ 24 25 # 情報ヘッダ 26 add_text: str = "" 27 headline: str = "*【レーティング】*\n" 28 29 # データ収集 30 # g.params.update(guest_skip=False) # 2ゲスト戦強制取り込み 31 game_info: GameInfoDict = aggregate.game_info() 32 if not game_info["game_count"]: # 検索結果が0件のとき 33 headline += "\t" + message.reply(message="no_hits") 34 return (headline, {}, {}) 35 36 df_results = loader.read_data("ranking/results.sql").set_index("name") 37 df_ratings = aggregate.calculation_rating() 38 39 # 最終的なレーティング 40 final = df_ratings.ffill().tail(1).transpose() 41 final.columns = ["rate"] 42 final["name"] = final.copy().index 43 44 df = pd.merge(df_results, final, on=["name"]).sort_values(by="rate", ascending=False) 45 df = df.query("count >= @g.params['stipulated']").copy() # 足切り 46 47 # 集計対象外データの削除 48 if g.params.get("unregistered_replace"): # 個人戦 49 for player in df.itertuples(): 50 if player.name not in g.member_list: 51 df = df.copy().drop(player.Index) 52 53 if not g.params.get("individual"): # チーム戦 54 df = df.copy().query("name != '未所属'") 55 56 # 順位偏差 / 得点偏差 57 df["point_dev"] = (df["rpoint_avg"] - df["rpoint_avg"].mean()) / df["rpoint_avg"].std(ddof=0) * 10 + 50 58 df["rank_dev"] = (df["rank_avg"] - df["rank_avg"].mean()) / df["rank_avg"].std(ddof=0) * -10 + 50 59 60 # 段位 61 if g.cfg.badge.grade.display: 62 for idx in df.index: 63 name = str(df.at[idx, "name"]).replace(f"({g.cfg.setting.guest_mark})", "") 64 df.at[idx, "grade"] = message.badge_grade(name, False) 65 66 # 表示 67 if g.params.get("anonymous"): 68 mapping_dict = formatter.anonymous_mapping(df["name"].unique().tolist()) 69 df["name"] = df["name"].replace(mapping_dict) 70 71 if df.empty: 72 headline += "\t" + message.reply(message="no_target") 73 return (headline, {}, {}) 74 75 headline += message.header(game_info, add_text, 1) 76 df = formatter.df_rename(df.filter( 77 items=[ 78 "name", "rate", "rank_distr", "rank_avg", "rank_dev", "rpoint_avg", "point_dev", "grade" 79 ] 80 ), short=False).copy() 81 df = df.drop(columns=[x for x in g.cfg.dropitems.ranking if x in df.columns.to_list()]) # 非表示項目 82 83 msg: dict = {} 84 table_param: dict = { 85 "index": False, 86 "tablefmt": "simple", 87 "numalign": "right", 88 "floatfmt": ["", ".1f", "", ".2f", ".0f", ".1f", ".0f"], 89 } 90 91 step = 30 92 length = len(df) 93 for i in range(int(length / step) + 1): 94 s = step * i 95 e = step * (i + 1) 96 if e + step / 2 > length: 97 table = df[s:].to_markdown(**table_param) 98 msg[s] = f"```\n{table}\n```\n" 99 break 100 101 table = df[s:e].to_markdown(**table_param) 102 msg[s] = f"```\n{table}\n```\n" 103 104 prefix_rating: str = "rating" 105 if g.params.get("filename"): 106 prefix_rating = f"{g.params["filename"]}" 107 108 file_list: dict = {"レーティング": ""} 109 match g.params.get("format", "default").lower().lower(): 110 case "csv": 111 file_list = { 112 "レーティング": formatter.save_output(df, "csv", f"{prefix_rating}.csv", headline), 113 } 114 case "text" | "txt": 115 file_list = { 116 "レーティング": formatter.save_output(df, "txt", f"{prefix_rating}.txt", headline), 117 } 118 119 return (headline, msg, file_list)
レーティングを集計して返す
Returns:
tuple[str, dict, dict]:
- str: ヘッダ情報
- dict: 集計データ
- dict: 生成ファイルの情報