def wait_all(cls, f_list, sec_timeout, sec_interval): logger = FoxylibLogger.func_level2logger(cls.wait_all, logging.DEBUG) time_end = time.time() + sec_timeout if sec_timeout is not None else None n = len(f_list) status_list = [None] * n logger.debug(format_str("waiting for {} process for {} secs", len(f_list), sec_timeout)) while (time_end is None) or (time.time() < time_end): for i in range(n): if status_list[i] is True: continue status_list[i] = f_list[i]() if all(status_list): break logger.debug(format_str("waiting for {}/{} processes for {} secs with {} sec interval", len(lfilter(lambda x: not x, status_list)), len(f_list), "{:.3f}".format(time_end - time.time()), sec_interval, )) time.sleep(sec_interval) return status_list
def batchrun_missing(cls, f_batch, args, kwargs, cache, indexes_each, k_list, lock=None): i_list_missing = CacheTool.cache_keys2i_list_missing(cache, k_list, lock=lock) if not i_list_missing: return {} def _indexes2args_filtered(indexes): def j2arg(j): arg = args[j] if j not in indexes_each: return arg return lmap(lambda i: arg[i], indexes) args_out = [j2arg(j) for j in range(len(args))] return args_out args_missing = _indexes2args_filtered(i_list_missing, ) v_list_missing = f_batch(*args_missing, **kwargs) assert_equal(len(i_list_missing), len(v_list_missing), msg=format_str("f_batch result incorrect: {} vs {}", len(i_list_missing), len(v_list_missing)), ) h_i2v = dict(zip_strict(i_list_missing, v_list_missing)) # raise Exception({"i_list_missing":i_list_missing,"v_list_missing":v_list_missing}) return h_i2v
def wrapper(f): """ CLASSMETHOD can used cached() too. But for simplicity of the system, CLASSMETHOD is forced to use cachedmethod """ types_valid = { CallableTool.Type.FUNCTION, } assert_in( CallableTool.callable2type(f), types_valid, format_str( "For instancemethod, use attach_cachedmethod() instead. type:{}", CallableTool.callable2type(f))) @wraps(f) def wrapped(*_, **__): # raise Exception({"_":_, "__":__}) f_lazy = partial(f, *_, **__) v = AsymmetricCache._read_or_write(f_lazy, cache, reader, writer, *_, lock=lock, **__) return v return wrapped
def test_01(self): hyp1 = format_str(r"{}{{2,}}", r"a") ref1 = r"a{2,}" self.assertEqual(hyp1, ref1) m = re.match(hyp1, "aaa") self.assertTrue(m)
def _node2rstr_unnamed( cls, node, ancestors, args=None, kwargs=None, ): _args = args or [] _kwargs = kwargs or {} # logger.debug({"node": node, "args": args, "kwargs": kwargs, "type":cls.node2type(node), # "h_node2ak": h_node2ak, # }) if cls.node2type(node) == cls.Type.RSTR_NODE: rstr = node.rstr(*_args, **_kwargs) return rstr subnode_list = node.subnode_list() ancestors_and_me = lchain(ancestors, [node]) rstr_list_subnode = [ cls._node2rstr_named(sn, ancestors_and_me, args=args, kwargs=kwargs) for sn in subnode_list ] str_format = node.rformat(*_args, **_kwargs) rstr = format_str(str_format, *rstr_list_subnode) return rstr
def price_lang2text(cls, price, lang): logger = HenriqueLogger.func_level2logger(cls.price_lang2text, logging.DEBUG) if price is None: return cls.lang2text_idk(lang) rate = MarketpriceDoc.price2rate(price) trend = MarketpriceDoc.price2trend(price) # raise Exception({"price":price}) channel_user_codename = MarketpriceDoc.price2channel_user(price) channel_user = l_singleton2obj( ChannelUser.codenames2channel_users([channel_user_codename])) logger.debug({"price": price, "channel_user": channel_user}) # raise Exception({"price":price}) created_at = MarketpriceDoc.price2created_at( price) or MarketpriceDoc.created_at_backoff() td = datetime.now(tz=pytz.utc) - created_at str_timedelta = HenriqueDatetime.timedelta_lang2str(td, lang) arrow = Trend.trend2arrow(trend) text_out_base = format_str("{}{} @ {}", str(rate), arrow, str_timedelta) if td >= HenriqueDatetime.Constant.TIMEDELTA_OUTDATED: return text_out_base user_alias = ChannelUser.channel_user2alias(channel_user) str_user_alias = "[by {}]".format(user_alias) text_out = " ".join([text_out_base, str_user_alias]) return text_out
def rstr(cls): rstr_short = DayofweekEntityKo.rstr_short() rstr = format_str( "{}(?:(?:\s*,\s*)?{})+", rstr2wrapped(rstr_short), rstr2wrapped(rstr_short), ) return rstr
def battletag2exists(cls, battletag, kwargs_requests=None): url = format_str("https://owapi.net/api/v3/u/{}/blob", BattletagTool.battletag2hyphened(battletag)) httpr = requests.head(url, **(kwargs_requests or {})) # httpr = HttpTool.url2httpr(url) return RequestsTool.response2is_ok(httpr)
def rstr2parenthesised(cls, s, rstr_pars=None): if rstr_pars is None: rstr_pars = (r"\(", r"\)") return format_str( r"{}{}{}", cls.rstr2wrapped(rstr_pars[0]), cls.rstr2wrapped(s), cls.rstr2wrapped(rstr_pars[1]), )
def rstr2rstr_words_prefixed( cls, rstr, rstr_prefix_list=None, ): # \b (word boundary)_does not work when str_query quoted or double-quoted # might wanna use string matching than regex because of speed issue if not rstr_prefix_list: rstr_prefix_list = [""] l = [ format_str(r"(?<=^{0})|(?<=\s{0})|(?<=\b{0})", rstr_prefix) for rstr_prefix in rstr_prefix_list ] rstr_pre = cls.join(r"|", l) return format_str( r'{0}{1}', cls.rstr2wrapped(rstr_pre), cls.rstr2wrapped(rstr), )
def values2cursor(cls, values): # value = ['a','b','c','d','e'] logger = FoxylibLogger.func_level2logger(cls.values2cursor, logging.DEBUG) sql = format_str("SELECT * FROM {} WHERE field_name in {}", cls.NAME, "({})".format(", ".join(map("'{}'".format, values))) ) logger.debug({"sql": sql}) # with MysqlTool.conn2cursor_contexted(CommonutilsMysql.conn()) as c: with FoxylibMysql.cursor_contexted() as c: yield MysqlTool.sql2executed(c, sql)
def rstr(cls): rstr = format_str( r"{}\s*{}?", RegexTool.name_rstr2named( "cardinal", "\d+", ), RegexTool.name_rstr2named( "Metricprefix", Metricprefix.rstr(), ), ) return rstr
def pattern_timedelta(cls): logger = FoxylibLogger.func2logger(cls.pattern_timedelta) j_yaml = cls.yaml() reldalta_name_list = cls.reldelta_name_list() j_reldelta = j_yaml["relativedelta"] j_name2strs = lambda j: lchain.from_iterable(j.values()) rstr_reldelta_list = [format_str(r"(?:(?P<{0}>\d+)\s*(?:{1}))?", k, r"|".join(lmap(re.escape, j_name2strs(j_reldelta[k]))), ) for k in reldalta_name_list] rstr_reldeltas = r"\s*".join([r"(?:{0})".format(rstr) for rstr in rstr_reldelta_list]) rstr = r"\s*".join([r"(?P<sign>[+-])", rstr_reldeltas]) logger.debug({"rstr":rstr}) pattern = re.compile(rstr, re.IGNORECASE) return pattern
def rstr2left_bounded(cls, rstr, bounds): rstr_left_list = [format_str(r"(?<={})", bound) for bound in bounds] rstr_left = cls.join(r"|", rstr_left_list) return r'{0}{1}'.format(rstr_left, rstr)
def rstr(cls): return format_str(r"{}(?:요일)?", rstr2wrapped(DayofweekEntityKo.rstr_short()))
def name_rstr2named(cls, name, rstr): return format_str(r"(?P<{0}>{1})", name, rstr)
def battletag2j_heroes(cls, battletag, kwargs_requests=None): url = format_str("https://owapi.net/api/v3/u/{}/heroes", BattletagTool.battletag2hyphened(battletag)) return cls.url2j(url, kwargs_requests=kwargs_requests)