import functools
import time


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
        signature = ", ".join(args_repr + kwargs_repr)
        print(f"Calling {func.__name__}({signature})")
        value = func(*args, **kwargs)
        print(f"{func.__name__!r} returned {value!r}")
        return value

    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
        return value

    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):
        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)

        return wrapper_slow_down

    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


def count_calls(func):
    """
    Counts the number of times a function calls
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_count_calls(*args, **kwargs):
        wrapper_count_calls.num_calls += 1
        print(f"Call {wrapper_count_calls.num_calls} of {func.__name__!r}")
        return func(*args, **kwargs)

    wrapper_count_calls.num_calls = 0
    return wrapper_count_calls


def singleton(cls):
    """
    Make a class a Singleton class (only one instance)
    :param cls:
    :return:
    """

    @functools.wraps(cls)
    def wrapper_singleton(*args, **kwargs):
        if not wrapper_singleton.instance:
            wrapper_singleton.instance = cls(*args, **kwargs)
        return wrapper_singleton.instance

    wrapper_singleton.instance = None
    return wrapper_singleton


PLUGINS = dict()


def register(func):
    """
    Register a function as a plug-in
    :param func:
    :return:
    """
    PLUGINS[func.__name__] = func
    return func

51e34383d1b3b55f82aab9b380e09250d70ef814
<mask token>


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f'{k}={v!r}' for k, v in kwargs.items()]
        signature = ', '.join(args_repr + kwargs_repr)
        print(f'Calling {func.__name__}({signature})')
        value = func(*args, **kwargs)
        print(f'{func.__name__!r} returned {value!r}')
        return value
    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f'Finished {func.__name__!r} in {run_time:.4f} secs')
        return value
    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):

        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)
        return wrapper_slow_down
    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


<mask token>

<mask token>


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f'{k}={v!r}' for k, v in kwargs.items()]
        signature = ', '.join(args_repr + kwargs_repr)
        print(f'Calling {func.__name__}({signature})')
        value = func(*args, **kwargs)
        print(f'{func.__name__!r} returned {value!r}')
        return value
    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f'Finished {func.__name__!r} in {run_time:.4f} secs')
        return value
    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):

        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)
        return wrapper_slow_down
    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


<mask token>


def register(func):
    """
    Register a function as a plug-in
    :param func:
    :return:
    """
    PLUGINS[func.__name__] = func
    return func

<mask token>


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f'{k}={v!r}' for k, v in kwargs.items()]
        signature = ', '.join(args_repr + kwargs_repr)
        print(f'Calling {func.__name__}({signature})')
        value = func(*args, **kwargs)
        print(f'{func.__name__!r} returned {value!r}')
        return value
    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f'Finished {func.__name__!r} in {run_time:.4f} secs')
        return value
    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):

        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)
        return wrapper_slow_down
    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


def count_calls(func):
    """
    Counts the number of times a function calls
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_count_calls(*args, **kwargs):
        wrapper_count_calls.num_calls += 1
        print(f'Call {wrapper_count_calls.num_calls} of {func.__name__!r}')
        return func(*args, **kwargs)
    wrapper_count_calls.num_calls = 0
    return wrapper_count_calls


def singleton(cls):
    """
    Make a class a Singleton class (only one instance)
    :param cls:
    :return:
    """

    @functools.wraps(cls)
    def wrapper_singleton(*args, **kwargs):
        if not wrapper_singleton.instance:
            wrapper_singleton.instance = cls(*args, **kwargs)
        return wrapper_singleton.instance
    wrapper_singleton.instance = None
    return wrapper_singleton


PLUGINS = dict()


def register(func):
    """
    Register a function as a plug-in
    :param func:
    :return:
    """
    PLUGINS[func.__name__] = func
    return func

import functools
import time


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f'{k}={v!r}' for k, v in kwargs.items()]
        signature = ', '.join(args_repr + kwargs_repr)
        print(f'Calling {func.__name__}({signature})')
        value = func(*args, **kwargs)
        print(f'{func.__name__!r} returned {value!r}')
        return value
    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f'Finished {func.__name__!r} in {run_time:.4f} secs')
        return value
    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):

        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)
        return wrapper_slow_down
    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


def count_calls(func):
    """
    Counts the number of times a function calls
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_count_calls(*args, **kwargs):
        wrapper_count_calls.num_calls += 1
        print(f'Call {wrapper_count_calls.num_calls} of {func.__name__!r}')
        return func(*args, **kwargs)
    wrapper_count_calls.num_calls = 0
    return wrapper_count_calls


def singleton(cls):
    """
    Make a class a Singleton class (only one instance)
    :param cls:
    :return:
    """

    @functools.wraps(cls)
    def wrapper_singleton(*args, **kwargs):
        if not wrapper_singleton.instance:
            wrapper_singleton.instance = cls(*args, **kwargs)
        return wrapper_singleton.instance
    wrapper_singleton.instance = None
    return wrapper_singleton


PLUGINS = dict()


def register(func):
    """
    Register a function as a plug-in
    :param func:
    :return:
    """
    PLUGINS[func.__name__] = func
    return func

import functools
import time


def debug(func):
    """
    Print the function signature and the return value
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
        signature = ", ".join(args_repr + kwargs_repr)
        print(f"Calling {func.__name__}({signature})")
        value = func(*args, **kwargs)
        print(f"{func.__name__!r} returned {value!r}")
        return value

    return wrapper_debug


def timer(func):
    """
    Prints the runtime of the decorated function
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
        return value

    return wrapper_timer


def slow_down(_func=None, *, rate=1):
    """
    Sleep given amount of seconds before calling the function
    :param _func:
    :param rate:
    :return:
    """

    def decorator_slow_down(func):
        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(rate)
            return func(*args, **kwargs)

        return wrapper_slow_down

    if _func is None:
        return decorator_slow_down
    else:
        return decorator_slow_down(_func)


def count_calls(func):
    """
    Counts the number of times a function calls
    :param func:
    :return:
    """

    @functools.wraps(func)
    def wrapper_count_calls(*args, **kwargs):
        wrapper_count_calls.num_calls += 1
        print(f"Call {wrapper_count_calls.num_calls} of {func.__name__!r}")
        return func(*args, **kwargs)

    wrapper_count_calls.num_calls = 0
    return wrapper_count_calls


def singleton(cls):
    """
    Make a class a Singleton class (only one instance)
    :param cls:
    :return:
    """

    @functools.wraps(cls)
    def wrapper_singleton(*args, **kwargs):
        if not wrapper_singleton.instance:
            wrapper_singleton.instance = cls(*args, **kwargs)
        return wrapper_singleton.instance

    wrapper_singleton.instance = None
    return wrapper_singleton


PLUGINS = dict()


def register(func):
    """
    Register a function as a plug-in
    :param func:
    :return:
    """
    PLUGINS[func.__name__] = func
    return func
