Table of Contents

## Issue

I am doing some algorithm running time analysis on some simple factorial algorithms, and to avoid code repetition I am trying to create a single time analysis function that will take the different factorial algorithm functions as arguements.

When I pass in factorial functions (e.g. iterative) that only take one argument this works fine, but as part of my assignment I have to use a tail recursive algorithm also, which takes 2 arguments (n,accumlator). Here is my code:

```
def iterFactorial(n):
#running product
factorial = 1
#multiply each number in range 1 to n by the running product(i.e. the factorial)
for i in range(1,n+1):
factorial *= i
#return the factorial
return factorial
def tail_Recur_Factorial(n,accumulator):
if n == 1:
return accumulator
return tail_Recur_Factorial(n-1,n*accumulator)
running_times_1 = []
n_values = [i for i in range(1,1000,100)]
def TimeAnalyis(function):
#array for storing multiple temporary running times of algorithm for a given n
temp_time = [0]
for n in n_values:
#run fucntion 50 times for each given n value
for i in range(50):
#take current timestamp
start_time = time.time()
#run function
function(n)
#take current timestamp
end_time = time.time()
#calculate time taken for function to run
function_time = end_time - start_time
#append to temp time array so mean can be taken
temp_time.append(function_time)
#take average running time
running_times_1.append(statistics.mean(temp_time))
#reset temp time
temp_time = [0]
```

The time analysis fucntion works fine for the iterative factorial function, where I call like:

timeAnalysis(iterFactorial)

How can I modify the time analysis function to allow me to *ALSO* pass in the tail recrusive fucntion which takes two arguments?

## Solution

## Code:

**You can create a decorator for this.**

```
def TimeAnalyis(func):
#Takes any number of args and kwargs
def wrapper(*args,**kargs):
best = float('inf')
for i in range(50):
start = time.time()
# Calls function and stores returned values in result
result = func(*args,**kargs)
total = time.time()-start
if total<best:
best = total
# Print best timing
print(f'Best time taken is {best} seconds')
# returns the values returned by function
return result
# returns wrapper function
return wrapper
#decorator
@TimeAnalyis
def anyfunc(n,m):
for i in range(n):
print(i*m)
```

Answered By – Bibhav

Answer Checked By – Timothy Miller (BugsFixing Admin)