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
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: マージされた辞書