libs.utils.dictutil

libs/utils/dictutil.py

  1"""
  2libs/utils/dictutil.py
  3"""
  4
  5import logging
  6from typing import TYPE_CHECKING, Any
  7
  8import libs.global_value as g
  9from cls.parser import CommandParser
 10from cls.timekit import ExtendedDatetime as ExtDt
 11from libs.data import lookup
 12from libs.utils import formatter
 13
 14if TYPE_CHECKING:
 15    from cls.config import SubCommand
 16
 17
 18def placeholder(subcom: "SubCommand") -> dict:
 19    """プレースホルダに使用する辞書を生成
 20
 21    Args:
 22        subcom (SubCommand): パラメータ
 23
 24    Returns:
 25        dict: プレースホルダ用辞書
 26    """
 27
 28    parser = CommandParser()
 29    ret_dict: dict = {}
 30
 31    # 初期化
 32    g.params.clear()
 33
 34    # 設定周りのパラメータ
 35    ret_dict.update(command=subcom.section)
 36    ret_dict.update(g.cfg.mahjong.to_dict())
 37    ret_dict.update(guest_name=g.cfg.member.guest_name)
 38
 39    # デフォルト値の取り込み
 40    ret_dict.update(subcom.to_dict())
 41
 42    # always_argumentの処理
 43    pre_param = parser.analysis_argument(subcom.always_argument)
 44    logging.info("%s", pre_param)
 45    ret_dict.update(pre_param.flags)
 46
 47    # 引数の処理
 48    param = parser.analysis_argument(g.msg.argument)
 49    logging.info("%s", param)
 50    ret_dict.update(param.flags)  # 上書き
 51
 52    # 検索範囲取得
 53    departure_time = ExtDt(hours=-g.cfg.setting.time_adjust)
 54    if (rule_version := ret_dict.get("rule_version")):  # ルールバージョンのみ先行評価
 55        g.params.update(rule_version=rule_version)
 56    if param.search_range:
 57        search_range = param.search_range
 58    elif pre_param.search_range:
 59        search_range = pre_param.search_range
 60    else:
 61        search_range = departure_time.range(subcom.aggregation_range)
 62
 63    ret_dict.update(starttime=(departure_time.range(search_range) + {"hours": g.cfg.setting.time_adjust}).start)
 64    ret_dict.update(endtime=(departure_time.range(search_range) + {"hours": g.cfg.setting.time_adjust}).end)
 65    ret_dict.update(onday=departure_time.range(search_range).end)
 66
 67    # どのオプションにも該当しないキーワードはプレイヤー名 or チーム名
 68    player_name: str = str()
 69    target_player: list = []
 70
 71    check_list: list = param.unknown + pre_param.unknown
 72    if ret_dict.get("individual"):
 73        if ret_dict.get("all_player"):
 74            check_list.extend(lookup.internal.get_member())
 75        target_player = _collect_member(check_list)
 76    else:
 77        if ret_dict.get("all_player"):
 78            check_list.extend(lookup.internal.get_team())
 79        target_player = _collect_team(check_list)
 80
 81    if target_player:
 82        player_name = target_player[0]
 83
 84    # リスト生成
 85    player_list: dict = {}
 86    competition_list: dict = {}
 87
 88    for idx, name in enumerate(target_player):
 89        player_list[f"player_{idx}"] = name
 90        if name != player_name:
 91            competition_list[f"competition_{idx}"] = name
 92
 93    ret_dict.update(player_name=player_name)
 94    ret_dict.update(target_player=target_player)
 95    ret_dict.update(player_list=player_list)
 96    ret_dict.update(competition_list=competition_list)
 97
 98    # プレイヤーリスト/対戦相手リスト
 99    if ret_dict["player_list"]:
100        for k, v in ret_dict["player_list"].items():
101            ret_dict[k] = v
102    if ret_dict["competition_list"]:
103        for k, v in ret_dict["competition_list"].items():
104            ret_dict[k] = v
105
106    return ret_dict
107
108
109def _collect_member(target_list: list) -> list:
110    ret_list: list = []
111    save_flg = g.params.get("individual")
112    g.params.update(individual=True)
113    for name in list(dict.fromkeys(target_list)):
114        if name in lookup.internal.get_team():
115            teammates = lookup.internal.get_teammates(name)
116            ret_list.extend(teammates)
117            continue
118        ret_list.append(formatter.name_replace(name))
119
120    g.params.update(individual=save_flg)
121    return list(dict.fromkeys(ret_list))
122
123
124def _collect_team(target_list: list) -> list:
125    ret_list: list = []
126    for team in list(dict.fromkeys(target_list)):
127        if team in lookup.internal.get_member():
128            name = lookup.internal.which_team(team)
129            if name:
130                ret_list.append(name)
131        else:
132            ret_list.append(team)
133
134    return list(dict.fromkeys(ret_list))
135
136
137def merge_dicts(dict1: Any, dict2: Any) -> dict:
138    """辞書の内容をマージする
139
140    Args:
141        dict1 (Any): 1つ目の辞書
142        dict2 (Any): 2つ目の辞書
143
144    Returns:
145        dict: マージされた辞書
146    """
147
148    merged: dict = {}
149
150    for key in set(dict1) | set(dict2):
151        val1: Any = dict1.get(key)
152        val2: Any = dict2.get(key)
153
154        if isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
155            merged[key] = val1 + val2
156        elif isinstance(val1, str) and isinstance(val2, str):
157            merged[key] = val1 + val2
158        elif isinstance(val1, list) and isinstance(val2, list):
159            merged[key] = sorted(list(set(val1 + val2)))
160        else:
161            merged[key] = val1 if val2 is None else val2
162
163    return merged
def placeholder(subcom: cls.config.SubCommand) -> dict:
 19def placeholder(subcom: "SubCommand") -> dict:
 20    """プレースホルダに使用する辞書を生成
 21
 22    Args:
 23        subcom (SubCommand): パラメータ
 24
 25    Returns:
 26        dict: プレースホルダ用辞書
 27    """
 28
 29    parser = CommandParser()
 30    ret_dict: dict = {}
 31
 32    # 初期化
 33    g.params.clear()
 34
 35    # 設定周りのパラメータ
 36    ret_dict.update(command=subcom.section)
 37    ret_dict.update(g.cfg.mahjong.to_dict())
 38    ret_dict.update(guest_name=g.cfg.member.guest_name)
 39
 40    # デフォルト値の取り込み
 41    ret_dict.update(subcom.to_dict())
 42
 43    # always_argumentの処理
 44    pre_param = parser.analysis_argument(subcom.always_argument)
 45    logging.info("%s", pre_param)
 46    ret_dict.update(pre_param.flags)
 47
 48    # 引数の処理
 49    param = parser.analysis_argument(g.msg.argument)
 50    logging.info("%s", param)
 51    ret_dict.update(param.flags)  # 上書き
 52
 53    # 検索範囲取得
 54    departure_time = ExtDt(hours=-g.cfg.setting.time_adjust)
 55    if (rule_version := ret_dict.get("rule_version")):  # ルールバージョンのみ先行評価
 56        g.params.update(rule_version=rule_version)
 57    if param.search_range:
 58        search_range = param.search_range
 59    elif pre_param.search_range:
 60        search_range = pre_param.search_range
 61    else:
 62        search_range = departure_time.range(subcom.aggregation_range)
 63
 64    ret_dict.update(starttime=(departure_time.range(search_range) + {"hours": g.cfg.setting.time_adjust}).start)
 65    ret_dict.update(endtime=(departure_time.range(search_range) + {"hours": g.cfg.setting.time_adjust}).end)
 66    ret_dict.update(onday=departure_time.range(search_range).end)
 67
 68    # どのオプションにも該当しないキーワードはプレイヤー名 or チーム名
 69    player_name: str = str()
 70    target_player: list = []
 71
 72    check_list: list = param.unknown + pre_param.unknown
 73    if ret_dict.get("individual"):
 74        if ret_dict.get("all_player"):
 75            check_list.extend(lookup.internal.get_member())
 76        target_player = _collect_member(check_list)
 77    else:
 78        if ret_dict.get("all_player"):
 79            check_list.extend(lookup.internal.get_team())
 80        target_player = _collect_team(check_list)
 81
 82    if target_player:
 83        player_name = target_player[0]
 84
 85    # リスト生成
 86    player_list: dict = {}
 87    competition_list: dict = {}
 88
 89    for idx, name in enumerate(target_player):
 90        player_list[f"player_{idx}"] = name
 91        if name != player_name:
 92            competition_list[f"competition_{idx}"] = name
 93
 94    ret_dict.update(player_name=player_name)
 95    ret_dict.update(target_player=target_player)
 96    ret_dict.update(player_list=player_list)
 97    ret_dict.update(competition_list=competition_list)
 98
 99    # プレイヤーリスト/対戦相手リスト
100    if ret_dict["player_list"]:
101        for k, v in ret_dict["player_list"].items():
102            ret_dict[k] = v
103    if ret_dict["competition_list"]:
104        for k, v in ret_dict["competition_list"].items():
105            ret_dict[k] = v
106
107    return ret_dict

プレースホルダに使用する辞書を生成

Arguments:
  • subcom (SubCommand): パラメータ
Returns:

dict: プレースホルダ用辞書

def merge_dicts(dict1: Any, dict2: Any) -> dict:
138def merge_dicts(dict1: Any, dict2: Any) -> dict:
139    """辞書の内容をマージする
140
141    Args:
142        dict1 (Any): 1つ目の辞書
143        dict2 (Any): 2つ目の辞書
144
145    Returns:
146        dict: マージされた辞書
147    """
148
149    merged: dict = {}
150
151    for key in set(dict1) | set(dict2):
152        val1: Any = dict1.get(key)
153        val2: Any = dict2.get(key)
154
155        if isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
156            merged[key] = val1 + val2
157        elif isinstance(val1, str) and isinstance(val2, str):
158            merged[key] = val1 + val2
159        elif isinstance(val1, list) and isinstance(val2, list):
160            merged[key] = sorted(list(set(val1 + val2)))
161        else:
162            merged[key] = val1 if val2 is None else val2
163
164    return merged

辞書の内容をマージする

Arguments:
  • dict1 (Any): 1つ目の辞書
  • dict2 (Any): 2つ目の辞書
Returns:

dict: マージされた辞書