# Function decorator exercises #################### # Alexander Kosik ############################ # Exercise 1 ############################ def double(f): """ Double is a decorator which doubles the return value of passed function Args: f: function to call. Result of f should be doubled Returns: Returns a new function which calls f and doubles the result """ pass # TODO ############################ # Exercise 2 ############################ """ Write a decorator function `time_this(f)` that wraps a function with an extra layer of logic that prints out how long it takes for a function to execute. To do this, you'll surround the function with timing calls like this: ```python start = time.time() r = func(*args,**kwargs) end = time.time() print('%s.%s: %f' % (func.__module__, func.__name__, end-start)) ``` Here is an example of how your decorator should work: ```python >>> @time_this def countdown(n): while n > 0: n -= 1 >>> countdown(10000000) __main__.countdown : 0.076562 >>> ``` If you define a function, its name and module are stored in the `__name__` and `__module__` attributes. For example: ```python >>> def add(x, y): return x+y >>> add.__name__ 'add' >>> add.__module__ '__main__' >>> ``` Use the __name__ and __module__ attribute for your output """ def time_this(f): pass # TODO ############################ # Exercise 3 ############################ """ Copy your code from time_this decorator to a new decorator. Extend the decorator with an optional parameter `call_time=False` which (if set to True) should print the time the function was called. You can use datetime.now() to receive the current date and time. For this you will need an parametrized decorator (also known as decorator factory). Remember: The decorator factory receives the parameters to customize the decorator. It must return a function which wraps and decoratores the target function. So you need in total 3 nested functions. """ def time_this(call_time=False): def decorate(f): pass # TODO return decorate