libs.utils.formatter

libs/utils/formatter.py

  1"""
  2libs/utils/formatter.py
  3"""
  4
  5import random
  6import re
  7
  8import pandas as pd
  9
 10import libs.global_value as g
 11from libs.data import lookup
 12from libs.utils import textutil
 13
 14
 15def floatfmt_adjust(df: pd.DataFrame, index: bool = False) -> list:
 16    """カラム名に応じたfloatfmtのリストを返す
 17
 18    Args:
 19        df (pd.DataFrame): チェックするデータ
 20        index (bool, optional): リストにIndexを含める. Defaults to False.
 21
 22    Returns:
 23        list: floatfmtに指定するリスト
 24    """
 25
 26    fmt: list = []
 27    if df.empty:
 28        return fmt
 29
 30    field: list = df.columns.tolist()
 31    if index:
 32        field.insert(0, df.index.name)
 33
 34    for x in field:
 35        match x:
 36            case "ゲーム数" | "game_count":
 37                fmt.append(".0f")
 38            case "win" | "lose" | "draw" | "top2" | "top3" | "gs_count":
 39                fmt.append(".0f")
 40            case "通算" | "通算ポイント" | "point_sum":
 41                fmt.append("+.1f")
 42            case "平均" | "平均ポイント" | "point_avg" | "平均収支" | "区間ポイント" | "区間平均":
 43                fmt.append("+.1f")
 44            case "1位(ポイント)" | "2位(ポイント)" | "3位(ポイント)" | "4位(ポイント)" | "5位(ポイント)":
 45                fmt.append("+.1f")
 46            case "1st" | "2nd" | "3rd" | "4th" | "1位" | "2位" | "3位" | "4位" | "rank1" | "rank2" | "rank3" | "rank4":
 47                fmt.append(".0f")
 48            case "1st(%)" | "2nd(%)" | "3rd(%)" | "4th(%)" | "1位率" | "2位率" | "3位率" | "4位率" | "1位(%)" | "2位(%)" | "3位(%)" | "4位(%)":
 49                fmt.append(".2%")
 50            case "top2_rate" | "連対率" | "top3_rate" | "ラス回避率":
 51                fmt.append(".2%")
 52            case"yakuman(%)" | "gs_rate" | "役満和了率":
 53                fmt.append(".2%")
 54            case "トビ" | "flying":
 55                fmt.append(".0f")
 56            case "トビ率" | "flying(%)" | "yakuman(%)":
 57                fmt.append(".2%")
 58            case "平均順位" | "平順" | "rank_avg":
 59                fmt.append(".2f")
 60            case "順位差" | "トップ差":
 61                fmt.append(".1f")
 62            case "平均素点" | "レート":
 63                fmt.append(".1f")
 64            case "順位偏差" | "得点偏差":
 65                fmt.append(".0f")
 66            case "rpoint_max" | "rpoint_min" | "rpoint_mean":
 67                fmt.append(".0f")
 68            case "participation_rate" | "ゲーム参加率":
 69                fmt.append(".2%")
 70            case _:
 71                fmt.append("")
 72
 73    return fmt
 74
 75
 76def column_alignment(df: pd.DataFrame, header: bool = False, index: bool = False) -> list:
 77    """カラム位置
 78
 79    Args:
 80        df (pd.DataFrame): チェックするデータ
 81        header (bool, optional): ヘッダを対象にする
 82        index (bool, optional): リストにIndexを含める. Defaults to False.
 83
 84    Returns:
 85        list: colalignに指定するリスト
 86    """
 87
 88    fmt: list = []  # global, right, center, left, decimal, None
 89    if df.empty:
 90        return fmt
 91
 92    field: list = df.columns.tolist()
 93    if index:
 94        field.insert(0, df.index.name)
 95
 96    if header:  # ヘッダ(すべて左寄せ)
 97        fmt = ["left"] * len(field)
 98    else:
 99        for x in field:
100            match x:
101                case "ゲーム数":
102                    fmt.append("right")
103                case "通算" | "平均" | "1位" | "2位" | "3位" | "4位" | " 平順" | "トビ":
104                    fmt.append("right")
105                case "通算" | "順位差" | "トップ差":
106                    fmt.append("right")
107                case "レート" | "平均順位" | "順位偏差" | "平均素点" | "得点偏差":
108                    fmt.append("right")
109                case _:
110                    fmt.append("left")
111
112    return fmt
113
114
115def name_replace(pname: str, add_mark: bool = False, not_replace: bool = False) -> str:
116    """表記ブレ修正(正規化)
117
118    Args:
119        pname (str): 対象プレイヤー名
120        add_mark (bool, optional): ゲストマークを付与する. Defaults to False.
121        not_replace (bool, optional): ゲスト置換なし(強制/個人戦) Defaults to False.
122
123    Returns:
124        str: 表記ブレ修正後のプレイヤー名
125    """
126
127    check_list = list(set(g.member_list.keys()))  # 別名を含むリスト
128    check_team = lookup.internal.get_team()
129
130    def _judge(check: str) -> str:
131        if g.params.get("individual", True) or not_replace:
132            if check in check_list:
133                return g.member_list.get(check, check)
134        else:
135            if check in check_team:
136                return check
137        return ""
138
139    if (ret_name := _judge(textutil.str_conv(pname, "h2z"))):  # 半角数字 -> 全角数字
140        return ret_name
141
142    pname = honor_remove(pname)  # 敬称削除
143
144    if (ret_name := _judge(pname)):
145        return ret_name
146
147    if (ret_name := _judge(textutil.str_conv(pname, "k2h"))):  # カタカナ -> ひらがな
148        return ret_name
149
150    if (ret_name := _judge(textutil.str_conv(pname, "h2k"))):  # ひらがな -> カタカナ
151        return ret_name
152
153    # メンバーリストに見つからない場合
154    if g.params.get("unregistered_replace", True) and not not_replace:
155        pname = g.cfg.member.guest_name
156    if pname != g.cfg.member.guest_name and add_mark:
157        pname = f"{pname}({g.cfg.setting.guest_mark})"
158
159    return pname
160
161
162def honor_remove(name: str) -> str:
163    """敬称削除
164
165    Args:
166        name (str): 対象の名前
167
168    Returns:
169        str: 敬称を削除した名前
170    """
171
172    honor = r"(くん|さん|ちゃん|クン|サン|チャン|君)$"
173    if re.match(fr".*{honor}", name):
174        if not re.match(fr".*(っ|ッ|ー){honor}", name):
175            name = re.sub(fr"{honor}", "", name)
176
177    return name
178
179
180def anonymous_mapping(name_list: list, initial: int = 0) -> dict:
181    """名前リストから変換用辞書を生成
182
183    Args:
184        name_list (list): 名前リスト
185        initial (int, optional): インデックス初期値. Defaults to 0.
186
187    Returns:
188        dict: マッピング用辞書
189    """
190
191    ret: dict = {}
192
193    if g.params.get("individual", True):
194        prefix = "Player"
195        id_list = lookup.db.get_member_id()
196    else:
197        prefix = "Team"
198        id_list = {x["team"]: x["id"] for x in g.team_list}
199
200    if len(name_list) == 1:
201        name = name_list[0]
202        if name in id_list:
203            idx = id_list[name]
204        else:
205            idx = int(random.random() * 100 + 100)
206        ret[name] = f"{prefix}_{idx + initial:03d}"
207    else:
208        random.shuffle(name_list)
209        for idx, name in enumerate(name_list):
210            ret[name] = f"{prefix}_{idx + initial:03d}"
211
212    return ret
213
214
215def df_rename(df: pd.DataFrame, short=True, kind=0) -> pd.DataFrame:
216    """カラム名をリネームする
217
218    Args:
219        df (pd.DataFrame): 対象データフレーム
220        short (bool, optional): 略語にリネーム. Defaults to True.
221        kind (int, optional): メモの種類
222
223    Returns:
224        pd.DataFrame: リネーム後のデータフレーム
225    """
226
227    rename_dict: dict = {
228        "playtime": "日時",
229        "rate": "レート",
230        "participation_rate": "ゲーム参加率",
231        "total_count": "集計ゲーム数",
232        "deposit": "供託",
233        "comment": "コメント",
234        "rule_version": "ルール識別子",
235        #
236        "rpoint": "素点",
237        "rpoint_avg": "平均素点",
238        "balance_avg": "平均収支",
239        "top2_rate": "連対率", "top2": "連対数",
240        "top3_rate": "ラス回避率", "top3": "ラス回避数",
241        "point_dev": "得点偏差", "rank_dev": "順位偏差",
242        "grade": "段位",
243        # レコード
244        "max_top": "連続トップ", "max_top2": "連続連対", "max_top3": "連続ラス回避",
245        "max_low": "連続トップなし", "max_low2": "連続逆連対", "max_low4": "連続ラス",
246        "point_max": "最大獲得ポイント", "point_min": "最小獲得ポイント",
247        "rpoint_max": "最大素点", "rpoint_min": "最小素点",
248        # 直接対決
249        "results": "対戦結果", "win%": "勝率",
250        "my_point_sum": "獲得ポイント(自分)", "my_point_avg": "平均ポイント(自分)",
251        "vs_point_sum": "獲得ポイント(相手)", "vs_point_avg": "平均ポイント(相手)",
252        "my_rpoint_avg": "平均素点(自分)", "my_rank_avg": "平均順位(自分)", "my_rank_distr": "順位分布(自分)",
253        "vs_rpoint_avg": "平均素点(相手)", "vs_rank_avg": "平均順位(相手)", "vs_rank_distr": "順位分布(相手)",
254        #
255        "p1_name": "東家 名前", "p2_name": "南家 名前", "p3_name": "西家 名前", "p4_name": "北家 名前",
256        "p1_grandslam": "東家 メモ", "p2_grandslam": "南家 メモ", "p3_grandslam": "西家 メモ", "p4_grandslam": "北家 メモ",
257        "p1_rpoint": "東家 素点", "p2_rpoint": "南家 素点", "p3_rpoint": "西家 素点", "p4_rpoint": "北家 素点",
258        "p1_rank": "東家 順位", "p2_rank": "南家 順位", "p3_rank": "西家 順位", "p4_rank": "北家 順位",
259        "p1_point": "東家 ポイント", "p2_point": "南家 ポイント", "p3_point": "西家 ポイント", "p4_point": "北家 ポイント",
260        "p1_str": "東家 入力素点", "p2_str": "南家 入力素点", "p3_str": "西家 入力素点", "p4_str": "北家 入力素点",
261        # レポート - 上位成績
262        "collection": "集計月",
263        "name1": "1位(名前)", "point1": "1位(ポイント)",
264        "name2": "2位(名前)", "point2": "2位(ポイント)",
265        "name3": "3位(名前)", "point3": "3位(ポイント)",
266        "name4": "4位(名前)", "point4": "4位(ポイント)",
267        "name5": "5位(名前)", "point5": "5位(ポイント)",
268    }
269
270    for x in df.columns:
271        match x:
272            case "rank":
273                rename_dict[x] = "#" if short else "順位"
274            case "name" | "player":
275                rename_dict[x] = "名前" if short else "プレイヤー名"
276            case "team":
277                rename_dict[x] = "チーム" if short else "チーム名"
278            case "point":
279                rename_dict[x] = "ポイント" if short else "獲得ポイント"
280            case "seat":
281                rename_dict[x] = "席" if short else "座席"
282            case "count" | "game" | "game_count":
283                rename_dict[x] = "ゲーム数"
284            case "pt_total" | "total_point" | "point_sum" | "total_mix":
285                rename_dict[x] = "通算" if short else "通算ポイント"
286            case "pt_avg" | "avg_point" | "point_avg" | "avg_mix":
287                rename_dict[x] = "平均" if short else "平均ポイント"
288            case "ex_point":
289                rename_dict[x] = "ポイント" if short else "卓外ポイント"
290            case "rank_distr" | "rank_distr1" | "rank_distr2":
291                rename_dict[x] = "順位分布"
292            case "rank_avg":
293                rename_dict[x] = "平順" if short else "平均順位"
294            case "1st" | "rank1" | "1st_mix":
295                rename_dict[x] = "1位数"
296            case "2nd" | "rank2" | "2nd_mix":
297                rename_dict[x] = "2位数"
298            case "3rd" | "rank3" | "3rd_mix":
299                rename_dict[x] = "3位数"
300            case "4th" | "rank4" | "4th_mix":
301                rename_dict[x] = "4位数"
302            case "1st(%)" | "rank1_rate":
303                rename_dict[x] = "1位率"
304            case "2nd(%)" | "rank2_rate":
305                rename_dict[x] = "2位率"
306            case "3rd(%)" | "rank3_rate":
307                rename_dict[x] = "3位率"
308            case "4th(%)" | "rank4_rate":
309                rename_dict[x] = "4位率"
310            case "1st_count":
311                rename_dict[x] = "1位数"
312            case "2nd_count":
313                rename_dict[x] = "2位数"
314            case "3rd_count":
315                rename_dict[x] = "3位数"
316            case "4th_count":
317                rename_dict[x] = "4位数"
318            case "flying" | "flying_mix":
319                rename_dict[x] = "飛" if short else "トビ"
320            case "flying_count":
321                rename_dict[x] = "トビ数"
322            case "flying_rate" | "flying(%)":
323                rename_dict[x] = "トビ率"
324            case "pt_diff":
325                rename_dict[x] = "差分"
326            case "diff_from_above":
327                rename_dict[x] = "順位差"
328            case "diff_from_top":
329                rename_dict[x] = "トップ差"
330            case "yakuman_mix" | "grandslam":
331                rename_dict[x] = "役満和了"
332            case "yakuman_count" | "gs_count":
333                rename_dict[x] = "役満和了数"
334            case "yakuman(%)" | "gs_rate":
335                rename_dict[x] = "役満和了率"
336            case "matter":
337                match kind:
338                    case 0:
339                        rename_dict[x] = "和了役"
340                    case 1:
341                        rename_dict[x] = "内容"
342                    case 2:
343                        rename_dict[x] = "内容"
344
345    if not g.params.get("individual"):
346        rename_dict.update(name="チーム" if short else "チーム名")
347
348    return df.rename(columns=rename_dict)
349
350
351def group_strings(lines: list[str], limit: int = 3000) -> list[str]:
352    """指定文字数まで改行で連結
353
354    Args:
355        lines (list[str]): 連結対象
356        limit (int, optional): 制限値. Defaults to 3000.
357
358    Returns:
359        list[str]: 連結結果
360    """
361
362    result: list = []
363    buffer: list = []
364
365    for i, line in enumerate(lines):
366        is_last = i == len(lines) - 1  # 最終ブロック判定
367        max_char = limit * 1.5 if is_last else limit  # 1ブロックの最大値
368
369        # 仮に追加したときの文字列長を計算
370        temp = buffer + [line]
371        total_len = len("".join(temp))
372
373        if total_len <= max_char:
374            buffer.append(line)
375        else:
376            if buffer:
377                result.append("\n".join(buffer))
378            buffer = [line]
379
380    if buffer:
381        result.append("\n".join(buffer))
382
383    # コードブロックの連結
384    # result = [str(x).replace("\n```\n\n```\n", "\n") for x in result]
385    result = [str(x).replace("\n```\n\n```\n", "\n```\n```\n") for x in result]
386
387    return result
def floatfmt_adjust(df: pandas.core.frame.DataFrame, index: bool = False) -> list:
16def floatfmt_adjust(df: pd.DataFrame, index: bool = False) -> list:
17    """カラム名に応じたfloatfmtのリストを返す
18
19    Args:
20        df (pd.DataFrame): チェックするデータ
21        index (bool, optional): リストにIndexを含める. Defaults to False.
22
23    Returns:
24        list: floatfmtに指定するリスト
25    """
26
27    fmt: list = []
28    if df.empty:
29        return fmt
30
31    field: list = df.columns.tolist()
32    if index:
33        field.insert(0, df.index.name)
34
35    for x in field:
36        match x:
37            case "ゲーム数" | "game_count":
38                fmt.append(".0f")
39            case "win" | "lose" | "draw" | "top2" | "top3" | "gs_count":
40                fmt.append(".0f")
41            case "通算" | "通算ポイント" | "point_sum":
42                fmt.append("+.1f")
43            case "平均" | "平均ポイント" | "point_avg" | "平均収支" | "区間ポイント" | "区間平均":
44                fmt.append("+.1f")
45            case "1位(ポイント)" | "2位(ポイント)" | "3位(ポイント)" | "4位(ポイント)" | "5位(ポイント)":
46                fmt.append("+.1f")
47            case "1st" | "2nd" | "3rd" | "4th" | "1位" | "2位" | "3位" | "4位" | "rank1" | "rank2" | "rank3" | "rank4":
48                fmt.append(".0f")
49            case "1st(%)" | "2nd(%)" | "3rd(%)" | "4th(%)" | "1位率" | "2位率" | "3位率" | "4位率" | "1位(%)" | "2位(%)" | "3位(%)" | "4位(%)":
50                fmt.append(".2%")
51            case "top2_rate" | "連対率" | "top3_rate" | "ラス回避率":
52                fmt.append(".2%")
53            case"yakuman(%)" | "gs_rate" | "役満和了率":
54                fmt.append(".2%")
55            case "トビ" | "flying":
56                fmt.append(".0f")
57            case "トビ率" | "flying(%)" | "yakuman(%)":
58                fmt.append(".2%")
59            case "平均順位" | "平順" | "rank_avg":
60                fmt.append(".2f")
61            case "順位差" | "トップ差":
62                fmt.append(".1f")
63            case "平均素点" | "レート":
64                fmt.append(".1f")
65            case "順位偏差" | "得点偏差":
66                fmt.append(".0f")
67            case "rpoint_max" | "rpoint_min" | "rpoint_mean":
68                fmt.append(".0f")
69            case "participation_rate" | "ゲーム参加率":
70                fmt.append(".2%")
71            case _:
72                fmt.append("")
73
74    return fmt

カラム名に応じたfloatfmtのリストを返す

Arguments:
  • df (pd.DataFrame): チェックするデータ
  • index (bool, optional): リストにIndexを含める. Defaults to False.
Returns:

list: floatfmtに指定するリスト

def column_alignment( df: pandas.core.frame.DataFrame, header: bool = False, index: bool = False) -> list:
 77def column_alignment(df: pd.DataFrame, header: bool = False, index: bool = False) -> list:
 78    """カラム位置
 79
 80    Args:
 81        df (pd.DataFrame): チェックするデータ
 82        header (bool, optional): ヘッダを対象にする
 83        index (bool, optional): リストにIndexを含める. Defaults to False.
 84
 85    Returns:
 86        list: colalignに指定するリスト
 87    """
 88
 89    fmt: list = []  # global, right, center, left, decimal, None
 90    if df.empty:
 91        return fmt
 92
 93    field: list = df.columns.tolist()
 94    if index:
 95        field.insert(0, df.index.name)
 96
 97    if header:  # ヘッダ(すべて左寄せ)
 98        fmt = ["left"] * len(field)
 99    else:
100        for x in field:
101            match x:
102                case "ゲーム数":
103                    fmt.append("right")
104                case "通算" | "平均" | "1位" | "2位" | "3位" | "4位" | " 平順" | "トビ":
105                    fmt.append("right")
106                case "通算" | "順位差" | "トップ差":
107                    fmt.append("right")
108                case "レート" | "平均順位" | "順位偏差" | "平均素点" | "得点偏差":
109                    fmt.append("right")
110                case _:
111                    fmt.append("left")
112
113    return fmt

カラム位置

Arguments:
  • df (pd.DataFrame): チェックするデータ
  • header (bool, optional): ヘッダを対象にする
  • index (bool, optional): リストにIndexを含める. Defaults to False.
Returns:

list: colalignに指定するリスト

def name_replace(pname: str, add_mark: bool = False, not_replace: bool = False) -> str:
116def name_replace(pname: str, add_mark: bool = False, not_replace: bool = False) -> str:
117    """表記ブレ修正(正規化)
118
119    Args:
120        pname (str): 対象プレイヤー名
121        add_mark (bool, optional): ゲストマークを付与する. Defaults to False.
122        not_replace (bool, optional): ゲスト置換なし(強制/個人戦) Defaults to False.
123
124    Returns:
125        str: 表記ブレ修正後のプレイヤー名
126    """
127
128    check_list = list(set(g.member_list.keys()))  # 別名を含むリスト
129    check_team = lookup.internal.get_team()
130
131    def _judge(check: str) -> str:
132        if g.params.get("individual", True) or not_replace:
133            if check in check_list:
134                return g.member_list.get(check, check)
135        else:
136            if check in check_team:
137                return check
138        return ""
139
140    if (ret_name := _judge(textutil.str_conv(pname, "h2z"))):  # 半角数字 -> 全角数字
141        return ret_name
142
143    pname = honor_remove(pname)  # 敬称削除
144
145    if (ret_name := _judge(pname)):
146        return ret_name
147
148    if (ret_name := _judge(textutil.str_conv(pname, "k2h"))):  # カタカナ -> ひらがな
149        return ret_name
150
151    if (ret_name := _judge(textutil.str_conv(pname, "h2k"))):  # ひらがな -> カタカナ
152        return ret_name
153
154    # メンバーリストに見つからない場合
155    if g.params.get("unregistered_replace", True) and not not_replace:
156        pname = g.cfg.member.guest_name
157    if pname != g.cfg.member.guest_name and add_mark:
158        pname = f"{pname}({g.cfg.setting.guest_mark})"
159
160    return pname

表記ブレ修正(正規化)

Arguments:
  • pname (str): 対象プレイヤー名
  • add_mark (bool, optional): ゲストマークを付与する. Defaults to False.
  • not_replace (bool, optional): ゲスト置換なし(強制/個人戦) Defaults to False.
Returns:

str: 表記ブレ修正後のプレイヤー名

def honor_remove(name: str) -> str:
163def honor_remove(name: str) -> str:
164    """敬称削除
165
166    Args:
167        name (str): 対象の名前
168
169    Returns:
170        str: 敬称を削除した名前
171    """
172
173    honor = r"(くん|さん|ちゃん|クン|サン|チャン|君)$"
174    if re.match(fr".*{honor}", name):
175        if not re.match(fr".*(っ|ッ|ー){honor}", name):
176            name = re.sub(fr"{honor}", "", name)
177
178    return name

敬称削除

Arguments:
  • name (str): 対象の名前
Returns:

str: 敬称を削除した名前

def anonymous_mapping(name_list: list, initial: int = 0) -> dict:
181def anonymous_mapping(name_list: list, initial: int = 0) -> dict:
182    """名前リストから変換用辞書を生成
183
184    Args:
185        name_list (list): 名前リスト
186        initial (int, optional): インデックス初期値. Defaults to 0.
187
188    Returns:
189        dict: マッピング用辞書
190    """
191
192    ret: dict = {}
193
194    if g.params.get("individual", True):
195        prefix = "Player"
196        id_list = lookup.db.get_member_id()
197    else:
198        prefix = "Team"
199        id_list = {x["team"]: x["id"] for x in g.team_list}
200
201    if len(name_list) == 1:
202        name = name_list[0]
203        if name in id_list:
204            idx = id_list[name]
205        else:
206            idx = int(random.random() * 100 + 100)
207        ret[name] = f"{prefix}_{idx + initial:03d}"
208    else:
209        random.shuffle(name_list)
210        for idx, name in enumerate(name_list):
211            ret[name] = f"{prefix}_{idx + initial:03d}"
212
213    return ret

名前リストから変換用辞書を生成

Arguments:
  • name_list (list): 名前リスト
  • initial (int, optional): インデックス初期値. Defaults to 0.
Returns:

dict: マッピング用辞書

def df_rename( df: pandas.core.frame.DataFrame, short=True, kind=0) -> pandas.core.frame.DataFrame:
216def df_rename(df: pd.DataFrame, short=True, kind=0) -> pd.DataFrame:
217    """カラム名をリネームする
218
219    Args:
220        df (pd.DataFrame): 対象データフレーム
221        short (bool, optional): 略語にリネーム. Defaults to True.
222        kind (int, optional): メモの種類
223
224    Returns:
225        pd.DataFrame: リネーム後のデータフレーム
226    """
227
228    rename_dict: dict = {
229        "playtime": "日時",
230        "rate": "レート",
231        "participation_rate": "ゲーム参加率",
232        "total_count": "集計ゲーム数",
233        "deposit": "供託",
234        "comment": "コメント",
235        "rule_version": "ルール識別子",
236        #
237        "rpoint": "素点",
238        "rpoint_avg": "平均素点",
239        "balance_avg": "平均収支",
240        "top2_rate": "連対率", "top2": "連対数",
241        "top3_rate": "ラス回避率", "top3": "ラス回避数",
242        "point_dev": "得点偏差", "rank_dev": "順位偏差",
243        "grade": "段位",
244        # レコード
245        "max_top": "連続トップ", "max_top2": "連続連対", "max_top3": "連続ラス回避",
246        "max_low": "連続トップなし", "max_low2": "連続逆連対", "max_low4": "連続ラス",
247        "point_max": "最大獲得ポイント", "point_min": "最小獲得ポイント",
248        "rpoint_max": "最大素点", "rpoint_min": "最小素点",
249        # 直接対決
250        "results": "対戦結果", "win%": "勝率",
251        "my_point_sum": "獲得ポイント(自分)", "my_point_avg": "平均ポイント(自分)",
252        "vs_point_sum": "獲得ポイント(相手)", "vs_point_avg": "平均ポイント(相手)",
253        "my_rpoint_avg": "平均素点(自分)", "my_rank_avg": "平均順位(自分)", "my_rank_distr": "順位分布(自分)",
254        "vs_rpoint_avg": "平均素点(相手)", "vs_rank_avg": "平均順位(相手)", "vs_rank_distr": "順位分布(相手)",
255        #
256        "p1_name": "東家 名前", "p2_name": "南家 名前", "p3_name": "西家 名前", "p4_name": "北家 名前",
257        "p1_grandslam": "東家 メモ", "p2_grandslam": "南家 メモ", "p3_grandslam": "西家 メモ", "p4_grandslam": "北家 メモ",
258        "p1_rpoint": "東家 素点", "p2_rpoint": "南家 素点", "p3_rpoint": "西家 素点", "p4_rpoint": "北家 素点",
259        "p1_rank": "東家 順位", "p2_rank": "南家 順位", "p3_rank": "西家 順位", "p4_rank": "北家 順位",
260        "p1_point": "東家 ポイント", "p2_point": "南家 ポイント", "p3_point": "西家 ポイント", "p4_point": "北家 ポイント",
261        "p1_str": "東家 入力素点", "p2_str": "南家 入力素点", "p3_str": "西家 入力素点", "p4_str": "北家 入力素点",
262        # レポート - 上位成績
263        "collection": "集計月",
264        "name1": "1位(名前)", "point1": "1位(ポイント)",
265        "name2": "2位(名前)", "point2": "2位(ポイント)",
266        "name3": "3位(名前)", "point3": "3位(ポイント)",
267        "name4": "4位(名前)", "point4": "4位(ポイント)",
268        "name5": "5位(名前)", "point5": "5位(ポイント)",
269    }
270
271    for x in df.columns:
272        match x:
273            case "rank":
274                rename_dict[x] = "#" if short else "順位"
275            case "name" | "player":
276                rename_dict[x] = "名前" if short else "プレイヤー名"
277            case "team":
278                rename_dict[x] = "チーム" if short else "チーム名"
279            case "point":
280                rename_dict[x] = "ポイント" if short else "獲得ポイント"
281            case "seat":
282                rename_dict[x] = "席" if short else "座席"
283            case "count" | "game" | "game_count":
284                rename_dict[x] = "ゲーム数"
285            case "pt_total" | "total_point" | "point_sum" | "total_mix":
286                rename_dict[x] = "通算" if short else "通算ポイント"
287            case "pt_avg" | "avg_point" | "point_avg" | "avg_mix":
288                rename_dict[x] = "平均" if short else "平均ポイント"
289            case "ex_point":
290                rename_dict[x] = "ポイント" if short else "卓外ポイント"
291            case "rank_distr" | "rank_distr1" | "rank_distr2":
292                rename_dict[x] = "順位分布"
293            case "rank_avg":
294                rename_dict[x] = "平順" if short else "平均順位"
295            case "1st" | "rank1" | "1st_mix":
296                rename_dict[x] = "1位数"
297            case "2nd" | "rank2" | "2nd_mix":
298                rename_dict[x] = "2位数"
299            case "3rd" | "rank3" | "3rd_mix":
300                rename_dict[x] = "3位数"
301            case "4th" | "rank4" | "4th_mix":
302                rename_dict[x] = "4位数"
303            case "1st(%)" | "rank1_rate":
304                rename_dict[x] = "1位率"
305            case "2nd(%)" | "rank2_rate":
306                rename_dict[x] = "2位率"
307            case "3rd(%)" | "rank3_rate":
308                rename_dict[x] = "3位率"
309            case "4th(%)" | "rank4_rate":
310                rename_dict[x] = "4位率"
311            case "1st_count":
312                rename_dict[x] = "1位数"
313            case "2nd_count":
314                rename_dict[x] = "2位数"
315            case "3rd_count":
316                rename_dict[x] = "3位数"
317            case "4th_count":
318                rename_dict[x] = "4位数"
319            case "flying" | "flying_mix":
320                rename_dict[x] = "飛" if short else "トビ"
321            case "flying_count":
322                rename_dict[x] = "トビ数"
323            case "flying_rate" | "flying(%)":
324                rename_dict[x] = "トビ率"
325            case "pt_diff":
326                rename_dict[x] = "差分"
327            case "diff_from_above":
328                rename_dict[x] = "順位差"
329            case "diff_from_top":
330                rename_dict[x] = "トップ差"
331            case "yakuman_mix" | "grandslam":
332                rename_dict[x] = "役満和了"
333            case "yakuman_count" | "gs_count":
334                rename_dict[x] = "役満和了数"
335            case "yakuman(%)" | "gs_rate":
336                rename_dict[x] = "役満和了率"
337            case "matter":
338                match kind:
339                    case 0:
340                        rename_dict[x] = "和了役"
341                    case 1:
342                        rename_dict[x] = "内容"
343                    case 2:
344                        rename_dict[x] = "内容"
345
346    if not g.params.get("individual"):
347        rename_dict.update(name="チーム" if short else "チーム名")
348
349    return df.rename(columns=rename_dict)

カラム名をリネームする

Arguments:
  • df (pd.DataFrame): 対象データフレーム
  • short (bool, optional): 略語にリネーム. Defaults to True.
  • kind (int, optional): メモの種類
Returns:

pd.DataFrame: リネーム後のデータフレーム

def group_strings(lines: list[str], limit: int = 3000) -> list[str]:
352def group_strings(lines: list[str], limit: int = 3000) -> list[str]:
353    """指定文字数まで改行で連結
354
355    Args:
356        lines (list[str]): 連結対象
357        limit (int, optional): 制限値. Defaults to 3000.
358
359    Returns:
360        list[str]: 連結結果
361    """
362
363    result: list = []
364    buffer: list = []
365
366    for i, line in enumerate(lines):
367        is_last = i == len(lines) - 1  # 最終ブロック判定
368        max_char = limit * 1.5 if is_last else limit  # 1ブロックの最大値
369
370        # 仮に追加したときの文字列長を計算
371        temp = buffer + [line]
372        total_len = len("".join(temp))
373
374        if total_len <= max_char:
375            buffer.append(line)
376        else:
377            if buffer:
378                result.append("\n".join(buffer))
379            buffer = [line]
380
381    if buffer:
382        result.append("\n".join(buffer))
383
384    # コードブロックの連結
385    # result = [str(x).replace("\n```\n\n```\n", "\n") for x in result]
386    result = [str(x).replace("\n```\n\n```\n", "\n```\n```\n") for x in result]
387
388    return result

指定文字数まで改行で連結

Arguments:
  • lines (list[str]): 連結対象
  • limit (int, optional): 制限値. Defaults to 3000.
Returns:

list[str]: 連結結果