# [SOLVED] Passing a function with single or multiple arguments into another function

## 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 = 

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 = 

``````

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?

## 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)