# Numpy Exercise 2

## Imports

``````

In [4]:

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

``````
``````

In [5]:

import antipackage
import github.ellisonbg.misc.vizarray as va

``````
``````

Using existing version:  github.ellisonbg.misc.vizarray

``````

## Factorial

Write a function that computes the factorial of small numbers using `np.arange` and `np.cumprod`.

``````

In [26]:

def np_fact(n):
if n == 0:
return 1
elif n == 1:
return 1
else:
a = np.arange(1,n+1,1)
b = a.cumprod()
return b[-1]

``````
``````

In [27]:

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]

``````

Write a function that computes the factorial of small numbers using a Python loop.

``````

In [40]:

def loop_fact(n):
if n == 0:
return 1
elif n == 1:
return 1
else:
a = 1
while n >= 1:
a = n * a
n = n - 1
return a

``````
``````

In [41]:

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]

``````

Use the `%timeit` magic to time both versions of this function for an argument of `50`. The syntax for `%timeit` is:

```%timeit -n1 -r1 function_to_time()
```
``````

In [43]:

%timeit -n1 -r1 (loop_fact)

%timeit -n1 -r1 (np_fact)

``````
``````

1 loops, best of 1: 3.1 µs per loop
1 loops, best of 1: 2.86 µs per loop

``````

In the cell below, summarize your timing tests. Which version is faster? Why do you think that version is faster?

np_fact is faster, but by a very small amount of time. np_fact is faster because it does not loop through each iteration of the loop like np_loop does. Instead, I called the cumprod function, which acts on the entire array at the same time.