"""Docstring for ``decorator``.
========================
Function Decorator
========================
==================== =========================================================
Profiler
==============================================================================
time_profiler Function running time command-line profiler.
time_logger Function running time log profiler.
profiler High level API combining `time_profiler` & `time_logger`.
==================== =========================================================
==================== =========================================================
Commandline printout
==============================================================================
job_wrapper Command-line line dragging tool.
==================== =========================================================
==================== =========================================================
Code Translation
==============================================================================
Infix Function to operator translator.
infix Functional API for ``Infix``.
==================== =========================================================
"""
import logging
from datetime import datetime as dt
from functools import partial
from functools import wraps
__all__ = ['time_profiler',
'time_logger',
'profiler',
'job_wrapper',
'Infix',
'infix']
[docs]def time_profiler(func):
"""Print wrapper for time profiling.
This wrapper prints out start, end and elapsed time.
Parameters
----------
func: Function
A function to profile.
Returns
-------
Function
A wrapped function.
See Also
--------
``functools.wraps``
``decorator``
Examples
--------
>>> import unipy as up
>>> @up.time_profiler
... def afunc(i):
... return len(list(range(i)))
...
>>> res = afunc(58)
(afunc) Start : 2018-06-20 22:11:35.511374
(afunc) End : 2018-06-20 22:11:35.511424
(afunc) Elapsed : 0:00:00.000050
>>> res
58
"""
@wraps(func)
def profiler(*args, **kwargs):
start_tm = dt.now()
print("(%s) Start : %26s" % (func.__name__, start_tm))
res = func(*args, **kwargs)
end_tm = dt.now()
print("(%s) End : %26s" % (func.__name__, end_tm))
elapsed_tm = end_tm - start_tm
print("(%s) Elapsed : %26s" % (func.__name__, elapsed_tm))
return res
return profiler
[docs]def time_logger(func):
"""Logging wrapper for time profiling.
This wrapper logs start, end and elapsed time.
Parameters
----------
func: Function
A function to profile.
Returns
-------
Function
A wrapped function.
See Also
--------
``functools.wraps``
``decorator``
Examples
--------
>>> import unipy as up
>>> @up.time_logger
... def afunc(i):
... return len(list(range(i)))
...
>>> res = afunc(58)
(afunc) Start : 2018-06-20 22:11:35.511374
(afunc) End : 2018-06-20 22:11:35.511424
(afunc) Elapsed : 0:00:00.000050
>>> res
58
"""
@wraps(func)
def logger(*args, **kwargs):
start_tm = dt.now()
logging.info(
"(%s) Start : %26s" % (func.__name__, str(start_tm))
)
res = func(*args, **kwargs)
end_tm = dt.now()
logging.info(
"(%s) End : %26s" % (func.__name__, str(end_tm))
)
elapsed_tm = end_tm - start_tm
logging.info(
"(%s) Elapsed : %26s" % (func.__name__, str(elapsed_tm))
)
return res
return logger
[docs]class profiler(object):
def __init__(self, type='logging'):
if type not in {'logging', 'printing'}:
raise Exception("`type` should be one of {'logging', 'printing'}")
else:
self.type = type
def _printer(self, func):
@wraps(func)
def _stdout_fn(*args, **kwargs):
start_tm = dt.now()
print("(%s) Start : %26s" % (func.__name__, start_tm))
res = func(*args, **kwargs)
end_tm = dt.now()
print("(%s) End : %26s" % (func.__name__, end_tm))
elapsed_tm = end_tm - start_tm
print("(%s) Elapsed : %26s" % (func.__name__, elapsed_tm))
return res
return _stdout_fn
def _logger(self, func):
@wraps(func)
def _log_fn(*args, **kwargs):
start_tm = dt.now()
logging.info(
"(%s) Start : %26s" % (func.__name__, start_tm)
)
res = func(*args, **kwargs)
end_tm = dt.now()
logging.info(
"(%s) End : %26s" % (func.__name__, end_tm)
)
elapsed_tm = end_tm - start_tm
logging.info(
"(%s) Elapsed : %26s" % (func.__name__, elapsed_tm)
)
return res
return _log_fn
def __call__(self, func):
if self.type=='logging':
return self._logger(func)
else:
return self._printer(func)
[docs]def job_wrapper(func):
"""Print wrapper for time profiling.
This wrapper prints out start & end line.
Parameters
----------
func: Function
A function to separate print-line job.
Returns
-------
Function
A wrapped function.
See Also
--------
``functools.wraps``
``decorator``
Examples
--------
>>> import unipy as up
>>> @up.job_wrapper
... def afunc(i):
... return len(list(range(i)))
...
>>> afunc(458)
----------- [afunc] START -----------
----------- [afunc] END -----------
afunc : 0:00:00.000023
458
"""
@wraps(func)
def wrapper(*args, **kwargs):
# Message Length = 40 + 2 (\n)
dash_len = int((40 - len(func.__name__) - 12) / 2)
start_msg = '-'*dash_len + ' [{}] START '.format(func.__name__) + \
'-'*dash_len + '\n'
print(start_msg)
start_tm = dt.now()
res = func(*args, **kwargs)
end_tm = dt.now()
end_msg = '-'*dash_len + ' [{}] END '.format(func.__name__) + \
'-'*dash_len + '\n'
print(end_msg)
print("{} :".format(func.__name__), end_tm - start_tm, '\n')
return res
return wrapper
[docs]class Infix(object):
"""Wrapper for define an operator.
This wrapper translates a function to an operator.
Returns
-------
Function
A wrapped function.
See Also
--------
``functools.partial``
``decorator``
Examples
--------
>>> @Infix
... def add(x, y):
... return x + y
...
>>> 5 |add| 6
11
>>> instanceof = Infix(isinstance)
>>> 5 |instanceof| int
True
"""
def __init__(self, func):
"""__init__ method.
Parameters
----------
function: Function
A function to translate as an operator.
"""
self.func = func
def __or__(self, other):
return self.func(other)
def __ror__(self, other):
return Infix(partial(self.func, other))
def __rshift__(self, other):
return self.func(other)
def __rlshift__(self, other):
return Infix(partial(self.func, other))
def __call__(self, lhs, rhs):
return self.func(lhs, rhs)
[docs]def infix(func):
"""A functional API for Infix decorator.
Returns
-------
Function
A wrapped function.
See Also
--------
``unipy.utils.wrapper.infix``
Examples
--------
>>> @infix
... def add(x, y):
... return x + y
...
>>> 5 |add| 6
11
>>> instanceof = infix(isinstance)
>>> 5 |instanceof| int
True
"""
return Infix(func)