# -*- coding: utf-8 -*- import time from colorama import Fore from colorama import Back from colorama import Style from functools import ( reduce, partial, wraps ) ########## # TIMERS # ########## _timers = {} _calls = {} def reset_timers(): global _timers global _calls _timers = {} _calls = {} def display_timers(): global _timers global _calls print(f" +--{Fore.BLUE}Timers{Style.RESET_ALL}---------------------------------------------------------+") lst = sorted( map( lambda f: (f, _timers[f], _calls[f]), _timers ), key = lambda f: f[1], reverse = True ) for func, time, calls in lst: print(f" | {Fore.GREEN}{func:<32}{Style.RESET_ALL} | {time:>10.6f} sec | {calls:>5} calls |") print(" +-----------------------------------------------------------------+") def timer(func): """Function wrapper to register function runtime""" @wraps(func) def wrapper(*args, **kwargs): start_time = time.perf_counter() value = None try: value = func(*args, **kwargs) except Exception as e: print(f"{e}") end_time = time.perf_counter() run_time = end_time - start_time if func.__qualname__ not in _timers: _timers[func.__qualname__] = 0 _calls[func.__qualname__] = 0 _timers[func.__qualname__] += run_time _calls[func.__qualname__] += 1 return value return wrapper ######### # DEBUG # ######### def trace(func): @wraps(func) def wrapper(*args, **kwargs): t = time.ctime() head = f"[{Fore.BLUE}TRACE{Style.RESET_ALL}]" c = f"{head}[{t}] Call {func.__module__}.{Fore.GREEN}{func.__qualname__}{Style.RESET_ALL}({args}, {kwargs})" print(c) value = func(*args, **kwargs) t = time.ctime() r = f"{head}[{t}] Return {func.__module__}.{Fore.GREEN}{func.__qualname__}{Style.RESET_ALL}" print(r) return value return wrapper ################ # OTHERS TOOLS # ################ @timer def flatten(lst): """Flatten list of list Args: lst: A list of list Returns: returns a list of element """ if not lst: return [] return reduce(list.__add__, lst)