# [SOLVED] Decorators for recursion function

## Issue

I want to write a decorator that will compute runtime of function that compute fibonachi number of 5(fib(5)) 10 times and will print a medium runtime value. But my decorator returns an error. How to fix this problem?

``````import functools
import time

def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
total = 0
for i in range(times):
start = time.time()
func(*args, **kwargs)
end = time.time()
total += (end - start)
print('Medium value is {}'.format(total / times))
return func
return wrapper
return cache

@trace(times=10)
def fib(num):
if num < 2:
return num
return fib(num - 1) + fib(num - 2)

fib(5)
``````

## Solution

First, instead of returning `func` in the `wrapper` return the result of it.

We have to make sure the tracing only happens for the first call to `fib` and none of the recursive calls. Let’s use a boolean `traced` argument:

``````import functools
import time

def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, traced=True, **kwargs):
if not traced:
return func(*args, **kwargs)
total = 0
for i in range(times):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
total += (end - start)
print(f'run {i}, time is {total}')
print(f'Mean value is {total / times}')
return result
return wrapper
return cache

@trace(times=10)
def fib(num, traced=True):
if num < 2:
return num
return fib(num - 1, traced=False) + fib(num - 2, traced=False)

fib(5)
``````

`traced` is `True` by default so any call to `fib(n)` will be traced (no need for user to be aware of the `traced` argument). However the recursive calls all have `traced=False` therefore they don’t trigger the loop in the decorator.

Answered By – re-za

Answer Checked By – Cary Denson (BugsFixing Admin)