# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/misc.ipynb.

# %% auto 0
__all__ = ['Timer', 'timeit', 'io']

# %% ../nbs/misc.ipynb 2
import time
from .logger import Info
from .inspector import inspect

# %% ../nbs/misc.ipynb 3
class Timer:
    def __init__(self, N):
        "print elapsed time every iteration and print out remaining time"
        "assumes this timer is called exactly N times or less"
        self.start = time.time()
        self.N = N
        self.ix = 0

    def __call__(self, ix=None, info=None):
        ix = self.ix if ix is None else ix
        info = "" if info is None else f"{info}\t"
        elapsed = time.time() - self.start
        speed = elapsed / (ix + 1)
        unit = 's/iter'
        if speed < 1:
            speed = 1 / speed
            unit = 'iters/s'
        print(
            "{}{}/{} ({:.2f}s - {:.2f}s remaining - {:.2f} {}){}".format(
                info, ix + 1, self.N, elapsed, (self.N - ix) * (elapsed / (ix + 1)), speed, unit, " "*10
            ),
            end="\r",
        )
        self.ix += 1

# %% ../nbs/misc.ipynb 5
def timeit(func):
    def inner(*args, **kwargs):
        s = time.time()
        o = func(*args, **kwargs)
        Info(f"{time.time() - s:.2f} seconds to execute `{func.__name__}`")
        return o

    return inner


def io(func):
    def inner(*args, **kwargs):
        s = time.time()
        o = func(*args, **kwargs)
        Info(f"Args: {inspect(args)}\nKWargs: {inspect(kwargs)}\nOutput: {inspect(o)}")
        return o

    return inner

