import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

"""
Explanation: Numpy Exercise 2
Imports
End of explanation
"""


def np_fact(n):
    """Compute n! = n*(n-1)*...*1 using Numpy."""
    # YOUR CODE HERE
    #raise NotImplementedError()
    #creates array with number from 0 to n
    a=np.arange(0,n+1,1.0)
    #sets first spot in array to 1 (so 0!=1)
    a[0]=1
    x = np.cumprod(a)
    #returns the integer value of the nth spot of the cumulative product array
    return int(x[n])

assert np_fact(0)==1
assert np_fact(1)==1
assert np_fact(10)==3628800
assert [np_fact(i) for i in range(0,11)]==[1,1,2,6,24,120,720,5040,40320,362880,3628800]

"""
Explanation: Factorial
Write a function that computes the factorial of small numbers using np.arange and np.cumprod.
End of explanation
"""


def loop_fact(n):
    """Compute n! using a Python for loop."""
    # YOUR CODE HERE
    #raise NotImplementedError()
    a=1
    fact=[1]
    #mulitplies each value in the range 0 to n by a
    #a redefined as privously mulitplied numbers at end of each iteration
    for i in range(1,n+1):
        a = i*a
        fact.append(a)
    return fact[n]     

loop_fact(10)

assert loop_fact(0)==1
assert loop_fact(1)==1
assert loop_fact(10)==3628800
assert [loop_fact(i) for i in range(0,11)]==[1,1,2,6,24,120,720,5040,40320,362880,3628800]

"""
Explanation: Write a function that computes the factorial of small numbers using a Python loop.
End of explanation
"""


# YOUR CODE HERE
#raise NotImplementedError()
%timeit -n1 -r1 np_fact(50)
%timeit -n1 -r1 loop_fact(50)

"""
Explanation: Use the %timeit magic to time both versions of this function for an argument of 50. The syntax for %timeit is:
python
%timeit -n1 -r1 function_to_time()
End of explanation
"""


