# The Normal Distribution

First derived from the binomial distribution you can get an idea for how it arises by looking at Galton Boards

Short Galton Board Demonstration:

<https://www.youtube.com/watch?v=Kq7e6cj2nDw>

Longer Galton Board Video with the Vsauce guy:

<https://www.youtube.com/watch?v=UCmPmkHqHXk>

## The Central Limit Theorem:

If we were to take a whole bunch of different samples from a population, and calculate the means of each of those samples, those **sample** means will be distributed according to the normal distribution - regardless of the shape of the original distribution that they were sampled from.

Lets actually try and recreate what we're seeing in the Galton Board as closely as possible.

```
import numpy as np
import matplotlib.pyplot as plt

sample_means = []
for x in range(0,3000):
  coinflips = np.random.binomial(n=1, p=.5, size=12)
  sample_means.append(coinflips.mean())

print(len(sample_means))
print(sample_means)
```

    3000
    [0.25, 0.6666666666666666, 0.4166666666666667, 0.25, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5, 0.5, 0.4166666666666667, 0.6666666666666666, 0.75, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.16666666666666666, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5, 0.16666666666666666, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.25, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.25, 0.5, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.6666666666666666, 0.4166666666666667, 0.25, 0.25, 0.3333333333333333, 0.3333333333333333, 0.5, 0.25, 0.75, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.25, 0.4166666666666667, 0.16666666666666666, 0.5, 0.4166666666666667, 0.8333333333333334, 0.5, 0.25, 0.5833333333333334, 0.4166666666666667, 0.5, 0.16666666666666666, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.5, 0.4166666666666667, 0.8333333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.16666666666666666, 0.75, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5, 0.3333333333333333, 0.25, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.25, 0.16666666666666666, 0.3333333333333333, 0.75, 0.16666666666666666, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.25, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.5, 0.3333333333333333, 0.3333333333333333, 0.16666666666666666, 0.4166666666666667, 0.5, 0.5, 0.8333333333333334, 0.5, 0.4166666666666667, 0.5, 0.25, 0.5, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.25, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.75, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5, 0.75, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5, 0.75, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.3333333333333333, 0.4166666666666667, 0.75, 0.4166666666666667, 0.5, 0.3333333333333333, 0.3333333333333333, 0.75, 0.5, 0.25, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5, 0.25, 0.75, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.75, 0.5, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.25, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.8333333333333334, 0.5833333333333334, 0.25, 0.4166666666666667, 0.4166666666666667, 0.25, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.75, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5, 0.5, 0.4166666666666667, 0.25, 0.25, 0.5, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.5, 0.75, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.75, 0.16666666666666666, 0.25, 0.16666666666666666, 0.4166666666666667, 0.3333333333333333, 0.25, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.25, 0.5, 0.6666666666666666, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.75, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.5, 0.4166666666666667, 0.6666666666666666, 0.75, 0.4166666666666667, 0.5, 0.8333333333333334, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.3333333333333333, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.25, 0.4166666666666667, 0.16666666666666666, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.75, 0.5, 0.08333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.75, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5, 0.3333333333333333, 0.6666666666666666, 0.5, 0.5833333333333334, 0.9166666666666666, 0.4166666666666667, 0.5, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.75, 0.3333333333333333, 0.75, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5, 0.5, 0.3333333333333333, 0.5, 0.5, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5, 0.5833333333333334, 0.9166666666666666, 0.75, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5, 0.5833333333333334, 0.6666666666666666, 0.25, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.25, 0.3333333333333333, 0.25, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.25, 0.6666666666666666, 0.5, 0.6666666666666666, 0.5, 0.25, 0.25, 0.5, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.75, 0.4166666666666667, 0.6666666666666666, 0.8333333333333334, 0.6666666666666666, 0.3333333333333333, 0.8333333333333334, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.75, 0.9166666666666666, 0.5, 0.5, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.25, 0.3333333333333333, 0.25, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.75, 0.4166666666666667, 0.5, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.75, 0.6666666666666666, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.75, 0.5, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.6666666666666666, 0.5, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.8333333333333334, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.5, 0.5, 0.5, 0.25, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.5, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.5, 0.25, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5, 0.3333333333333333, 0.6666666666666666, 0.25, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5, 0.3333333333333333, 0.5, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5, 0.75, 0.25, 0.25, 0.4166666666666667, 0.4166666666666667, 0.5, 0.4166666666666667, 0.25, 0.4166666666666667, 0.5833333333333334, 0.75, 0.4166666666666667, 0.75, 0.6666666666666666, 0.4166666666666667, 0.75, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.75, 0.3333333333333333, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5, 0.6666666666666666, 0.8333333333333334, 0.6666666666666666, 0.4166666666666667, 0.25, 0.5, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.75, 0.5, 0.75, 0.5833333333333334, 0.75, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.75, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.8333333333333334, 0.3333333333333333, 0.25, 0.6666666666666666, 0.25, 0.75, 0.5833333333333334, 0.5, 0.75, 0.16666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.16666666666666666, 0.5, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5, 0.16666666666666666, 0.5833333333333334, 0.3333333333333333, 0.5, 0.75, 0.5, 0.5, 0.75, 0.4166666666666667, 0.75, 0.25, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5, 0.8333333333333334, 0.25, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.25, 0.5, 0.5833333333333334, 0.5, 0.5, 0.5, 0.5, 0.16666666666666666, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.9166666666666666, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.8333333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5, 0.16666666666666666, 0.75, 0.5, 0.8333333333333334, 0.6666666666666666, 0.4166666666666667, 0.25, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.75, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.75, 0.4166666666666667, 0.25, 0.16666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.25, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.75, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.08333333333333333, 0.4166666666666667, 0.25, 0.5, 0.25, 0.5, 0.6666666666666666, 0.25, 0.3333333333333333, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.25, 0.5, 0.75, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.5, 0.25, 0.4166666666666667, 0.8333333333333334, 0.5, 0.3333333333333333, 0.5, 0.6666666666666666, 0.5, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.5, 0.25, 0.3333333333333333, 0.4166666666666667, 0.25, 0.5, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.25, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.75, 0.3333333333333333, 0.25, 0.5, 0.16666666666666666, 0.6666666666666666, 0.25, 0.4166666666666667, 0.5, 0.16666666666666666, 0.4166666666666667, 0.4166666666666667, 0.75, 0.5, 0.5833333333333334, 0.4166666666666667, 0.8333333333333334, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.75, 0.8333333333333334, 0.5833333333333334, 0.8333333333333334, 0.25, 0.4166666666666667, 0.4166666666666667, 0.25, 0.6666666666666666, 0.75, 0.4166666666666667, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.16666666666666666, 0.6666666666666666, 0.6666666666666666, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.08333333333333333, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.5, 0.4166666666666667, 0.25, 0.5833333333333334, 0.75, 0.5, 0.3333333333333333, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.5, 0.25, 0.75, 0.5, 0.5, 0.8333333333333334, 0.6666666666666666, 0.4166666666666667, 0.75, 0.25, 0.4166666666666667, 0.3333333333333333, 0.75, 0.25, 0.3333333333333333, 0.4166666666666667, 0.08333333333333333, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5, 0.4166666666666667, 0.9166666666666666, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.5, 0.6666666666666666, 0.6666666666666666, 0.75, 0.5833333333333334, 0.25, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.8333333333333334, 0.5833333333333334, 0.75, 0.6666666666666666, 0.5, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.5, 0.4166666666666667, 0.75, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.5, 0.16666666666666666, 0.5, 0.25, 0.5, 0.6666666666666666, 0.4166666666666667, 0.25, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5, 0.8333333333333334, 0.5833333333333334, 0.75, 0.5833333333333334, 0.25, 0.3333333333333333, 0.75, 0.25, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5, 0.75, 0.8333333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.25, 0.6666666666666666, 0.5, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.5, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.75, 0.75, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.5, 0.3333333333333333, 0.75, 0.5, 0.5, 0.3333333333333333, 0.3333333333333333, 0.08333333333333333, 0.5, 0.4166666666666667, 0.25, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.5, 0.5, 0.4166666666666667, 0.75, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.75, 0.4166666666666667, 0.4166666666666667, 0.5, 0.3333333333333333, 0.4166666666666667, 0.75, 0.75, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.75, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.4166666666666667, 0.16666666666666666, 0.5833333333333334, 0.8333333333333334, 0.5, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.75, 0.08333333333333333, 0.5833333333333334, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.25, 0.25, 0.5833333333333334, 0.4166666666666667, 0.5, 0.3333333333333333, 0.4166666666666667, 0.5, 0.16666666666666666, 0.5, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.5, 0.6666666666666666, 0.75, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5, 0.16666666666666666, 0.5, 0.5833333333333334, 0.16666666666666666, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5, 0.25, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.16666666666666666, 0.6666666666666666, 0.5, 0.8333333333333334, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.25, 0.3333333333333333, 0.5, 0.6666666666666666, 0.5, 0.6666666666666666, 0.4166666666666667, 0.75, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.25, 0.5833333333333334, 0.5, 0.6666666666666666, 0.3333333333333333, 0.5, 0.5, 0.16666666666666666, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5, 0.4166666666666667, 0.25, 0.5, 0.3333333333333333, 0.5, 0.5, 0.6666666666666666, 0.5, 0.75, 0.25, 0.4166666666666667, 0.5, 0.5, 0.16666666666666666, 0.5, 0.5833333333333334, 0.25, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5, 0.75, 0.5, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5833333333333334, 0.25, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5, 0.08333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5, 0.3333333333333333, 0.75, 0.5, 0.5833333333333334, 0.5, 0.16666666666666666, 0.6666666666666666, 0.4166666666666667, 0.16666666666666666, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.75, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.6666666666666666, 0.25, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.25, 0.5, 0.5, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.8333333333333334, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5, 0.4166666666666667, 0.4166666666666667, 0.25, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.6666666666666666, 0.75, 0.5, 0.5, 0.25, 0.5, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.25, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.4166666666666667, 0.75, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.25, 0.4166666666666667, 0.4166666666666667, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.25, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.25, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.25, 0.3333333333333333, 0.5, 0.6666666666666666, 0.6666666666666666, 0.5833333333333334, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5, 0.5833333333333334, 0.25, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.25, 0.25, 0.3333333333333333, 0.25, 0.5, 0.3333333333333333, 0.5, 0.4166666666666667, 0.75, 0.5833333333333334, 0.5, 0.25, 0.4166666666666667, 0.75, 0.6666666666666666, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.5, 0.6666666666666666, 0.5, 0.8333333333333334, 0.75, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.5, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.25, 0.5, 0.16666666666666666, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.75, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.5, 0.75, 0.4166666666666667, 0.3333333333333333, 0.75, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.75, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.8333333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.25, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.25, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.8333333333333334, 0.5, 0.3333333333333333, 0.5, 0.16666666666666666, 0.3333333333333333, 0.16666666666666666, 0.25, 0.75, 0.4166666666666667, 0.5, 0.5833333333333334, 0.3333333333333333, 0.25, 0.6666666666666666, 0.75, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.25, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.25, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.75, 0.4166666666666667, 0.25, 0.6666666666666666, 0.5, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.5, 0.5, 0.5, 0.5, 0.75, 0.4166666666666667, 0.8333333333333334, 0.5833333333333334, 0.6666666666666666, 0.16666666666666666, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.8333333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.5, 0.75, 0.5833333333333334, 0.5, 0.5, 0.75, 0.5, 0.5833333333333334, 0.75, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.5, 0.75, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.4166666666666667, 0.8333333333333334, 0.25, 0.5833333333333334, 0.5, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.6666666666666666, 0.16666666666666666, 0.5833333333333334, 0.75, 0.5, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5, 0.4166666666666667, 0.16666666666666666, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.16666666666666666, 0.5, 0.6666666666666666, 0.25, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.5, 0.5, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.25, 0.5, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5, 0.6666666666666666, 0.4166666666666667, 0.75, 0.6666666666666666, 0.5, 0.25, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.25, 0.6666666666666666, 0.5833333333333334, 0.75, 0.4166666666666667, 0.5, 0.75, 0.5, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5833333333333334, 0.75, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5, 0.75, 0.5, 0.4166666666666667, 0.5833333333333334, 0.25, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.6666666666666666, 0.25, 0.5, 0.6666666666666666, 0.4166666666666667, 0.75, 0.6666666666666666, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5, 0.5, 0.5833333333333334, 0.9166666666666666, 0.5, 0.3333333333333333, 0.25, 0.5, 0.5, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.4166666666666667, 0.75, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.25, 0.25, 0.4166666666666667, 0.75, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.16666666666666666, 0.25, 0.5, 0.5, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.08333333333333333, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.25, 0.4166666666666667, 0.25, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.75, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.5, 0.3333333333333333, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.8333333333333334, 0.5833333333333334, 0.5, 0.75, 0.75, 0.5833333333333334, 0.25, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.75, 0.5, 0.5, 0.25, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.16666666666666666, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.25, 0.5, 0.6666666666666666, 0.5, 0.5833333333333334, 0.75, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5833333333333334, 0.16666666666666666, 0.4166666666666667, 0.4166666666666667, 0.25, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.25, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.75, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.5, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.6666666666666666, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.75, 0.4166666666666667, 0.75, 0.6666666666666666, 0.16666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5, 0.4166666666666667, 0.6666666666666666, 0.8333333333333334, 0.5, 0.3333333333333333, 0.5, 0.3333333333333333, 0.3333333333333333, 0.16666666666666666, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.75, 0.25, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.75, 0.3333333333333333, 0.5, 0.5, 0.5, 0.5, 0.4166666666666667, 0.5, 0.5, 0.6666666666666666, 0.5, 0.5, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.75, 0.5, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.25, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5, 0.5, 0.9166666666666666, 0.3333333333333333, 0.75, 0.75, 0.5, 0.5833333333333334, 0.5, 0.75, 0.5833333333333334, 0.5, 0.4166666666666667, 0.75, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.75, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.25, 0.5, 0.5, 0.16666666666666666, 0.6666666666666666, 0.25, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5, 0.75, 0.3333333333333333, 0.4166666666666667, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5, 0.6666666666666666, 0.6666666666666666, 0.75, 0.5, 0.3333333333333333, 0.16666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.75, 0.4166666666666667, 0.5, 0.6666666666666666, 0.25, 0.5, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5, 0.4166666666666667, 0.6666666666666666, 0.6666666666666666, 0.5, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.25, 0.25, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5, 0.5, 0.3333333333333333, 0.4166666666666667, 0.8333333333333334, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.6666666666666666, 0.25, 0.6666666666666666, 0.25, 0.4166666666666667, 0.3333333333333333, 0.8333333333333334, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.75, 0.5, 0.6666666666666666, 0.8333333333333334, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.5833333333333334, 0.8333333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.6666666666666666, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5, 0.4166666666666667, 0.75, 0.25, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.25, 0.5833333333333334, 0.5, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.4166666666666667, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.75, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.6666666666666666, 0.3333333333333333, 0.16666666666666666, 0.25, 0.75, 0.5, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.16666666666666666, 0.5, 0.3333333333333333, 0.5833333333333334, 0.75, 0.5, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.25, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.25, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5, 0.25, 0.6666666666666666, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.8333333333333334, 0.5833333333333334, 0.4166666666666667, 0.25, 0.3333333333333333, 0.5, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.75, 0.9166666666666666, 0.4166666666666667, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5833333333333334, 0.25, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.3333333333333333, 0.75, 0.5833333333333334, 0.5, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5833333333333334, 0.25, 0.5, 0.4166666666666667, 0.4166666666666667, 0.16666666666666666, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5, 0.6666666666666666, 0.75, 0.5, 0.6666666666666666, 0.5833333333333334, 0.5, 0.3333333333333333, 0.4166666666666667, 0.25, 0.6666666666666666, 0.4166666666666667, 0.5, 0.6666666666666666, 0.5, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.5, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.3333333333333333, 0.25, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.8333333333333334, 0.4166666666666667, 0.3333333333333333, 0.25, 0.75, 0.75, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.4166666666666667, 0.5833333333333334, 0.5, 0.75, 0.5, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.5, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.5, 0.4166666666666667, 0.75, 0.5, 0.4166666666666667, 0.5833333333333334, 0.25, 0.5833333333333334, 0.5, 0.6666666666666666, 0.5, 0.5833333333333334, 0.3333333333333333, 0.6666666666666666, 0.6666666666666666, 0.5, 0.4166666666666667, 0.5, 0.75, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5, 0.4166666666666667, 0.3333333333333333, 0.4166666666666667, 0.5, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.25, 0.5833333333333334, 0.4166666666666667, 0.75, 0.6666666666666666, 0.3333333333333333, 0.5833333333333334, 0.5, 0.5, 0.5, 0.5, 0.6666666666666666, 0.25, 0.3333333333333333, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.5833333333333334, 0.3333333333333333, 0.25, 0.5, 0.9166666666666666, 0.5, 0.3333333333333333, 0.5, 0.5, 0.25, 0.08333333333333333, 0.75, 0.5, 0.16666666666666666, 0.3333333333333333, 0.5, 0.6666666666666666, 0.5, 0.25, 0.8333333333333334, 0.6666666666666666, 0.6666666666666666, 0.5, 0.8333333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.25, 0.6666666666666666, 0.6666666666666666, 0.5, 0.25, 0.4166666666666667, 0.5833333333333334, 0.16666666666666666, 0.5, 0.4166666666666667, 0.3333333333333333, 0.5, 0.3333333333333333, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.4166666666666667, 0.5, 0.4166666666666667, 0.6666666666666666, 0.4166666666666667, 0.25, 0.5, 0.75, 0.8333333333333334, 0.6666666666666666, 0.5, 0.5, 0.6666666666666666, 0.5, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5, 0.75, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.5, 0.75, 0.16666666666666666, 0.5, 0.75, 0.6666666666666666, 0.5, 0.5833333333333334, 0.75, 0.6666666666666666, 0.5833333333333334, 0.4166666666666667, 0.5, 0.6666666666666666, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.5, 0.3333333333333333, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.6666666666666666, 0.3333333333333333, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.25, 0.5833333333333334, 0.5, 0.5, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.75, 0.5833333333333334, 0.25, 0.4166666666666667, 0.5, 0.5, 0.75, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5, 0.6666666666666666, 0.4166666666666667, 0.4166666666666667, 0.75, 0.25, 0.4166666666666667, 0.5833333333333334, 0.5, 0.5833333333333334, 0.5, 0.3333333333333333, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5833333333333334, 0.6666666666666666, 0.6666666666666666, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5833333333333334, 0.8333333333333334, 0.25, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.25, 0.75, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.75, 0.5833333333333334, 0.4166666666666667, 0.5, 0.75, 0.25, 0.5, 0.5, 0.16666666666666666, 0.5833333333333334, 0.4166666666666667, 0.6666666666666666, 0.5, 0.5, 0.5, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.4166666666666667, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5833333333333334, 0.5, 0.3333333333333333, 0.6666666666666666, 0.5833333333333334, 0.6666666666666666, 0.75, 0.5833333333333334, 0.5, 0.5833333333333334, 0.6666666666666666, 0.4166666666666667, 0.75, 0.6666666666666666, 0.5833333333333334, 0.5, 0.4166666666666667, 0.5833333333333334, 0.4166666666666667, 0.4166666666666667, 0.5, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.5833333333333334, 0.16666666666666666, 0.4166666666666667, 0.4166666666666667, 0.4166666666666667, 0.5833333333333334, 0.6666666666666666, 0.5833333333333334, 0.75, 0.08333333333333333, 0.5, 0.5, 0.4166666666666667, 0.4166666666666667, 0.3333333333333333, 0.5, 0.5833333333333334, 0.5, 0.5, 0.6666666666666666, 0.3333333333333333, 0.3333333333333333, 0.5, 0.3333333333333333, 0.3333333333333333, 0.4166666666666667, 0.16666666666666666, 0.8333333333333334, 0.4166666666666667, 0.25, 0.5833333333333334, 0.5, 0.5, 0.9166666666666666, 0.75, 0.5, 0.5, 0.5833333333333334, 0.6666666666666666]

```
ax = plt.hist(sample_means, bins=24)
plt.title('Distribution of 3000 sample means \n (of 12 coinflips each)');
```

# What does the Normal Distribution Represent?

## The area under the curve of the normal distribution == probability of seeing a value within that range

The most important thing to understand about the normal distribution is that it is a PDF: Probability Density Function

This just means that the area under the curve == 1

Therefore,  by specifying a cutoff point (z-score) anywhere along the distribution, we can pick a cutoff point that

# The Z-score is the number of standard deviations away from the mean

# The T Distribution

Wait, why is the Z equation in the screenshot below different from the z-score equation that we looked at above?? Well, they're describing two slightly different things. (but are using the same variable, sorry for the notation confusion)

A Z-score describes how many standard deviations some value is from the population mean (usually that point is a sample mean that we're comparing but it doesn't have to be.)

The Z equation below takes into account that the calculation of our sample mean is an estimate and has an amount of variance that's described as:

\begin{align}
Var(\bar{X}) = \frac{\sigma^2}{n} = \frac{\sigma}{\sqrt{n}} = \text{standard error}
\end{align}

In other words, when comparing our sample mean to our population mean we have to take into account the fact that if we were to take a larger sample, we would estimate the sample mean more accurately so we take into account the variance of our sample mean. The variance of our sample mean is the **standard error**.

### Here are some stack exchange questions that try and explain it as well

<https://math.stackexchange.com/questions/917045/when-to-use-which-z-score-equation/917052>

<https://math.stackexchange.com/questions/845769/why-does-the-normalized-z-score-introduce-a-square-root-and-some-more-confusio>

But the short of it is, the equation above just calculates how many standard deviations a value is from the population mean

The equation below describes the distribution of sample means taking into account the variance of the sample means themselves. The Z statistic equation below is very similar to the t-statistic equation, but with one important difference. (see below)

The Z statistic in the screenshot above refers to

<https://www.youtube.com/watch?v=Uv6nGIgZMVw>

We work with the normal distribution and z-statistics (z scores) to calculate confidence intervals and do "z-tests" **when we know the population standard deviation**.

**How the heck would we ever know the population standard deviation???** To calculate it we would have to have every observation in the population and if we had that then we could just compute the mean directly and wouldn't have to infer/estimate it. So most stats classes start you off with the normal distribution and Z-scores and confidence intervals around the mean using z-scores as an introduction but then tell you to forget all that once they move you on to t-tests and t statistics. In practice, z-scores are not ever really used in inferential statistics.

This is why for our purposes we have kind of skipped over all of the normal distribution z-score stuff and started you off right at t-tests and the student's t-distribution, this probably made it a little bit confusing where the t-distribution even comes from in the first place.

# Why does the t-distribution have fatter tails and approximate the normal distribution as sample size increases?

Because the sample standard error gets smaller as the sample size increases leading to a tighter distribution.

# With a large sample size, the T-distribution becomes the normal distribution and T-statistics become Z-statistics

Which is why most confidence interval equations use Z instead of T

## Congressional Voting Assignment - Apply the t-test to real data

Your assignment is to determine which issues have "statistically significant" differences between political parties in this [1980s congressional voting data](https://archive.ics.uci.edu/ml/datasets/Congressional+Voting+Records). The data consists of 435 instances (one for each congressperson), a class (democrat or republican), and 16 binary attributes (yes or no for voting for or against certain issues). Be aware - there are missing values!

Your goals:

1. Load and clean the data (or determine the best method to drop observations when running tests)
2. Using hypothesis testing, find an issue that democrats support more than republicans with p < 0.01
3. Using hypothesis testing, find an issue that republicans support more than democrats with p < 0.01
4. Using hypothesis testing, find an issue where the difference between republicans and democrats has p > 0.1 (i.e. there may not be much of a difference)

Note that this data will involve *2 sample* t-tests, because you're comparing averages across two groups (republicans and democrats) rather than a single group against a null hypothesis.

```
# Grab the file from UCI
!wget https://archive.ics.uci.edu/ml/machine-learning-databases/voting-records/house-votes-84.data
```

    --2019-04-11 21:08:52--  https://archive.ics.uci.edu/ml/machine-learning-databases/voting-records/house-votes-84.data
    Resolving archive.ics.uci.edu (archive.ics.uci.edu)... 128.195.10.252
    Connecting to archive.ics.uci.edu (archive.ics.uci.edu)|128.195.10.252|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 18171 (18K) [application/x-httpd-php]
    Saving to: ‘house-votes-84.data.2’

    house-votes-84.data 100%[===================>]  17.75K  --.-KB/s    in 0.07s

    2019-04-11 21:08:52 (270 KB/s) - ‘house-votes-84.data.2’ saved [18171/18171]

```
# Imports
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
```

```
# Load Data
df = pd.read_csv('house-votes-84.data',
                 header=None,
                 names=['party','handicapped-infants','water-project',
                          'budget','physician-fee-freeze', 'el-salvador-aid',
                          'religious-groups','anti-satellite-ban',
                          'aid-to-contras','mx-missile','immigration',
                          'synfuels', 'education', 'right-to-sue','crime','duty-free',
                          'south-africa'])
print(df.shape)
df.head()
```

    (435, 17)

      party
      handicapped-infants
      water-project
      budget
      physician-fee-freeze
      el-salvador-aid
      religious-groups
      anti-satellite-ban
      aid-to-contras
      mx-missile
      immigration
      synfuels
      education
      right-to-sue
      crime
      duty-free
      south-africa

      0
      republican
      n
      y
      n
      y
      y
      y
      n
      n
      n
      y
      ?
      y
      y
      y
      n
      y

      1
      republican
      n
      y
      n
      y
      y
      y
      n
      n
      n
      n
      n
      y
      y
      y
      n
      ?

      2
      democrat
      ?
      y
      y
      ?
      y
      y
      n
      n
      n
      n
      y
      n
      y
      y
      n
      n

      3
      democrat
      n
      y
      y
      n
      ?
      y
      n
      n
      n
      n
      y
      n
      y
      n
      n
      y

      4
      democrat
      y
      y
      y
      n
      y
      y
      n
      n
      n
      n
      y
      ?
      y
      y
      y
      y

```
# Replace '?' with np.NaN, 'n' with 0, and 'y' with 1
df = df.replace({'?':np.NaN, 'n':0, 'y':1})

df.head()
```

      party
      handicapped-infants
      water-project
      budget
      physician-fee-freeze
      el-salvador-aid
      religious-groups
      anti-satellite-ban
      aid-to-contras
      mx-missile
      immigration
      synfuels
      education
      right-to-sue
      crime
      duty-free
      south-africa

      0
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      0.0
      1.0

      1
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      1.0
      0.0
      NaN

      2
      democrat
      NaN
      1.0
      1.0
      NaN
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0

      3
      democrat
      0.0
      1.0
      1.0
      0.0
      NaN
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      0.0
      0.0
      1.0

      4
      democrat
      1.0
      1.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      1.0

```
# How many abstentions? (NaNs)
df.isnull().sum()
```

    party                     0
    handicapped-infants      12
    water-project            48
    budget                   11
    physician-fee-freeze     11
    el-salvador-aid          15
    religious-groups         11
    anti-satellite-ban       14
    aid-to-contras           15
    mx-missile               22
    immigration               7
    synfuels                 21
    education                31
    right-to-sue             25
    crime                    17
    duty-free                28
    south-africa            104
    dtype: int64

```
# Create Republicans Dataframe
rep = df[df.party == "republican"]
print(rep.shape)
rep.head()
```

    (168, 17)

      party
      handicapped-infants
      water-project
      budget
      physician-fee-freeze
      el-salvador-aid
      religious-groups
      anti-satellite-ban
      aid-to-contras
      mx-missile
      immigration
      synfuels
      education
      right-to-sue
      crime
      duty-free
      south-africa

      0
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      0.0
      1.0

      1
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      1.0
      0.0
      NaN

      7
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      NaN
      1.0

      8
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      1.0
      0.0
      1.0

      10
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      NaN
      NaN
      1.0
      1.0
      0.0
      0.0

```
# Create Democrats Dataframe
dem = df[df.party == "democrat"]
print(dem.shape)
dem.head()
```

    (267, 17)

      party
      handicapped-infants
      water-project
      budget
      physician-fee-freeze
      el-salvador-aid
      religious-groups
      anti-satellite-ban
      aid-to-contras
      mx-missile
      immigration
      synfuels
      education
      right-to-sue
      crime
      duty-free
      south-africa

      2
      democrat
      NaN
      1.0
      1.0
      NaN
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0

      3
      democrat
      0.0
      1.0
      1.0
      0.0
      NaN
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      0.0
      0.0
      1.0

      4
      democrat
      1.0
      1.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      1.0

      5
      democrat
      0.0
      1.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      1.0
      1.0

      6
      democrat
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      NaN
      1.0
      1.0
      1.0

# 1 Sample T-Tests

In a 1-sample T-test we are testing the mean of one sample against a null hypothesis of our choosing.

The null hypothesis that we designate depends on how we have encoded our data and the kind of questions that we want to test.

If I have encoded votes as 0 for no and 1 for yes, I want to test Democratic support for an issue, and I use a null hypothesis of 0, then I am comparing Democrat voting support against a null hypothesis of no Democrat support at all for a given issue.

If I use a null hypothesis of .5 then I am comparing the democrat voting support against a null hypothesis of democrats being neither in favor or against a particular issue.

If I use a null hypothesis of 1 then I am comparing the democrat voting support against a null hypothesis of all democrats being favor of a particular issue.

Lets use the 0 and .5 null-hypotheses to test the significance of those particular claims. They're all valid questions to be asking, they're just posing a slightly different question --testing something different.

```
# Lets test this out on the handicapped-infants issue since it's the first one.
# I am just going to omit NaN values from my tests.
# Null Hypothesis that Democratic support is 0.
stats.ttest_1samp(dem['handicapped-infants'], 0, nan_policy='omit')
```

    Ttest_1sampResult(statistic=19.825711173357988, pvalue=1.0391992873567661e-53)

Given the results of the above test I would REJECT the null hypothesis that there is no Democrat support for the handicapped-infants bill at the 95% significance level.

In Layman's terms It would be a FALSE statment to declare that there is no democratic support for this bill. That's something that you might hear a political pundit declare, but you'll notice that they don't report their alpha value or p-value when they make such claims, they just spew them. --*Tell us how you really feel!*

```
# Null Hypothesis that Democrats neither support not oppose the issue
stats.ttest_1samp(dem['handicapped-infants'], .5, nan_policy='omit')
```

    Ttest_1sampResult(statistic=3.431373087696574, pvalue=0.000699612317167372)

```
# Look at vote counts by party and by issue
# It's very easy to perform some Interocular Traumatic Tests (IOT) on this data
# https://www.r-bloggers.com/inter-ocular-trauma-test/
# We can eyeball the outcomes of some of these before we perform any T-tests.
# But which of the differences is statistically significant?
dem.apply(pd.Series.value_counts).T
```

    /usr/local/lib/python3.6/dist-packages/pandas/core/indexes/api.py:87: RuntimeWarning: '<' not supported between instances of 'str' and 'float', sort order is undefined for incomparable objects
      result = result.union(other)
    /usr/local/lib/python3.6/dist-packages/pandas/core/indexes/api.py:87: RuntimeWarning: '<' not supported between instances of 'float' and 'str', sort order is undefined for incomparable objects
      result = result.union(other)

      democrat
      1.0
      0.0

      party
      267.0
      NaN
      NaN

      handicapped-infants
      NaN
      156.0
      102.0

      water-project
      NaN
      120.0
      119.0

      budget
      NaN
      231.0
      29.0

      physician-fee-freeze
      NaN
      14.0
      245.0

      el-salvador-aid
      NaN
      55.0
      200.0

      religious-groups
      NaN
      123.0
      135.0

      anti-satellite-ban
      NaN
      200.0
      59.0

      aid-to-contras
      NaN
      218.0
      45.0

      mx-missile
      NaN
      188.0
      60.0

      immigration
      NaN
      124.0
      139.0

      synfuels
      NaN
      129.0
      126.0

      education
      NaN
      36.0
      213.0

      right-to-sue
      NaN
      73.0
      179.0

      crime
      NaN
      90.0
      167.0

      duty-free
      NaN
      160.0
      91.0

      south-africa
      NaN
      173.0
      12.0

As we look at the above table we see our findings corroborated in the raw voting counts of democrats. They are definitely not all against the handicapped-infants bill hence the very high p-value. We also see that democrats on this issue are not evenly split but that there is a significant margin of support for the handicapped-infants bill. However this margin is not as extreme for our second hypothesis as for our first, and hence our secont 1-sample t-test has a lower t statistic and a higher p-value although it is still significant.

```
# Null hypothesis that there is no democratic support for the bill.
stats.ttest_1samp(dem['physician-fee-freeze'], 0, nan_policy='omit')
```

    Ttest_1sampResult(statistic=3.8396428405331067, pvalue=0.0001550891349511097)

We see that even though this issue has the most extreme Democrat opposition, we cannot conclude that there is no Democrat support for this issue. We will again REJECT the null hypothesis that the mean of democratic support is 0 --or that there is no Democrat support for this issue.

```
# Null hypothesis that there is even support for the bill among democrats.
stats.ttest_1samp(dem['physician-fee-freeze'], .5, nan_policy='omit')
```

    Ttest_1sampResult(statistic=-31.67705343439813, pvalue=6.796885728494356e-91)

Here we are again testing the null hypothesis of Democrats being neither for nor against the issue, but being split in their voting. This time we see a strong negative t-statistic and low p-value. The negative sign on this t-statistic suggests that democratic support is much further to the left of .5 (our null hypothesis of even yes/no voting in the party) in other words, this t-statistic says that not only are democrats not split on the issue, they are highly against this policy. Again this is very clear to us as we consult the output of raw vote counts for the democrats.

As a final test and example of 1-sample T-tests lets try and get something that's not statistically significant. Lets test our split-support hypothesis on the "synfuels" policy.

```
stats.ttest_1samp(dem['synfuels'], .5, nan_policy='omit')
```

    Ttest_1sampResult(statistic=0.18751153526716705, pvalue=0.8514092819865365)

```
dem['synfuels'].hist()
```

Here we FAIL TO REJECT the null hypothesis that democrats voting is even on this issue because our t-statistic is small resulting in a p-value greater than .05. So we would fail to reject this null hypothesis at the 95% level. Remember that we never "accept" the null hypothesis, we only "fail to reject" it. We're not claiming that the null hypothesis is true, we're just stating that our test doesn't have enough statistical power to show otherwise.

### We could do the same thing with the Republicans dataframe, but the result would be extremely similar.

```
# Look at republican voting patterns
rep.apply(pd.Series.value_counts).T
```

    /usr/local/lib/python3.6/dist-packages/pandas/core/indexes/api.py:87: RuntimeWarning: '<' not supported between instances of 'float' and 'str', sort order is undefined for incomparable objects
      result = result.union(other)

      republican
      0.0
      1.0

      party
      168.0
      NaN
      NaN

      handicapped-infants
      NaN
      134.0
      31.0

      water-project
      NaN
      73.0
      75.0

      budget
      NaN
      142.0
      22.0

      physician-fee-freeze
      NaN
      2.0
      163.0

      el-salvador-aid
      NaN
      8.0
      157.0

      religious-groups
      NaN
      17.0
      149.0

      anti-satellite-ban
      NaN
      123.0
      39.0

      aid-to-contras
      NaN
      133.0
      24.0

      mx-missile
      NaN
      146.0
      19.0

      immigration
      NaN
      73.0
      92.0

      synfuels
      NaN
      138.0
      21.0

      education
      NaN
      20.0
      135.0

      right-to-sue
      NaN
      22.0
      136.0

      crime
      NaN
      3.0
      158.0

      duty-free
      NaN
      142.0
      14.0

      south-africa
      NaN
      50.0
      96.0

## What if we didn't split our dataframe up by Republicans and Democrats, then what would that be testing?

The contents of the overall dataframe that we're working with determines the GENERALIZABILITY of our results. If we're running tests on Democrat voting behavior then our hypothesis tests can only make claims about Democrat voting, they say nothing about Republican support or opposition for an issue, we would have to run those tests on the Republican dataframe.

But then what do T-tests on the entire dataframe of both Republicans and Democrats say? They're testing the same thing but generalized to all congresspeople and the results are not specific to one party or another.

```
# Look at congressional voting patterns
df.apply(pd.Series.value_counts).T
```

    /usr/local/lib/python3.6/dist-packages/pandas/core/indexes/api.py:87: RuntimeWarning: '<' not supported between instances of 'float' and 'str', sort order is undefined for incomparable objects
      result = result.union(other)

      democrat
      republican
      0.0
      1.0

      party
      267.0
      168.0
      NaN
      NaN

      handicapped-infants
      NaN
      NaN
      236.0
      187.0

      water-project
      NaN
      NaN
      192.0
      195.0

      budget
      NaN
      NaN
      171.0
      253.0

      physician-fee-freeze
      NaN
      NaN
      247.0
      177.0

      el-salvador-aid
      NaN
      NaN
      208.0
      212.0

      religious-groups
      NaN
      NaN
      152.0
      272.0

      anti-satellite-ban
      NaN
      NaN
      182.0
      239.0

      aid-to-contras
      NaN
      NaN
      178.0
      242.0

      mx-missile
      NaN
      NaN
      206.0
      207.0

      immigration
      NaN
      NaN
      212.0
      216.0

      synfuels
      NaN
      NaN
      264.0
      150.0

      education
      NaN
      NaN
      233.0
      171.0

      right-to-sue
      NaN
      NaN
      201.0
      209.0

      crime
      NaN
      NaN
      170.0
      248.0

      duty-free
      NaN
      NaN
      233.0
      174.0

      south-africa
      NaN
      NaN
      62.0
      269.0

We'll give one example of this, but it's the same as the T-tests above, just with the context being congress as a whole rather than a specific party.

```
stats.ttest_1samp(df['mx-missile'], .5, nan_policy='omit')
```

    Ttest_1sampResult(statistic=0.049147318718299554, pvalue=0.9608257103188511)

We FAIL TO REJECT the null hypothesis that congressional support for the 'mx-missile' policy is split (even) among congresspeople.

# 2-sample T-tests (for means)

Two-sample T-tests are very similar to 1-sample t-tests, except that instead of providing a raw value as a null hypothesis, we will be comparing the mean of a second sample as the alternate hypothesis.

```
stats.ttest_ind(dem['mx-missile'], rep['mx-missile'], nan_policy='omit')
```

    Ttest_indResult(statistic=16.437503268542994, pvalue=5.03079265310811e-47)

## Don't make this mistake!

Notice that a 2-sample T-test does not give the same results as a 1-sample t-test where the null hypothesis is the mean of a second sample. The test below is representative of a t-test comparing the mean of the first sample to a null-hypothesis value of .115, but it is not representative of comparing the mean of the sample to the mean of a second sample. This is because passing in the mean as a single value does not account for the variance around the mean of the second sample, so the 1-sample t-test against the mean value of another sample has a much higher t-statistic and significance than a test where you pass in the full data of both samples.

You can avoid this mistake by making sure that you provide a raw null-hypothesis value (like 0, .5, 1) as the null-hypothesis value when performing a 1-sample t-test, and only two separate samples in their entirety to the function when performing a two-sample t-test.

```
rep_mx_missile_mean = rep['mx-missile'].mean()
print(rep_mx_missile_mean)
```

    0.11515151515151516

```
stats.ttest_1samp(dem['mx-missile'], rep_mx_missile_mean, nan_policy='omit')
```

    Ttest_1sampResult(statistic=23.593795768600376, pvalue=3.200954476509414e-65)

Also notice that the order in which you pass the two samples to the 2-sample test will reverse the direction of the t-statistic.

A t-statistic with a positive sign indicates that the first sample mean is higher than the second sample mean, and the significance level indicates whether or not the means are different at the 95% confidence level.

```
print(dem['mx-missile'].mean())
print(rep['mx-missile'].mean())

stats.ttest_ind(dem['mx-missile'], rep['mx-missile'], nan_policy='omit')
```

    0.7580645161290323
    0.11515151515151516

    Ttest_indResult(statistic=16.437503268542994, pvalue=5.03079265310811e-47)

Here we have reversed the order of which sample we pass in first to demonstrate how `ttest_ind` might result in a negative t-statistic.

```
print(dem['mx-missile'].mean())
print(rep['mx-missile'].mean())

stats.ttest_ind(rep['mx-missile'], dem['mx-missile'], nan_policy='omit')
```

    0.7580645161290323
    0.11515151515151516

    Ttest_indResult(statistic=-16.437503268542994, pvalue=5.03079265310811e-47)

Because of this, in order to ensure consistency of the signs of the t-statistic during 2-sample tests, I suggest sticking with passing in one party as the first argument and the other party as the second argument and sticking with that pattern throughout your testing so that you don't confuse yourself.

## Two-sample T-tests for Democrat Support, Republican Support, and no singnificant difference in support between parties:

## Significant Democrat Support

The outcome of this tests indicates that we should reject the null hypothesis that the mean of Democrat votes is equal to the mean of Republican votes for this issue. We would conclude due to the positive t-statistic here that Democrat support is significantly higher than republican support for this issue.

```
stats.ttest_ind(dem['synfuels'], rep['synfuels'], nan_policy='omit')
```

    Ttest_indResult(statistic=8.293603989407588, pvalue=1.5759322301054064e-15)

## Significant Republican Support

The outcome of this tests indicates that we should reject the null hypothesis that the mean of democrat votes is equal to the mean of republican votes for this issue. We would conclude due to the positive t-statistic here that Republican support is significantly higher than Democrat support for this issue.

```
print(dem['south-africa'].mean())
print(rep['south-africa'].mean())

stats.ttest_ind(rep['south-africa'], dem['south-africa'], nan_policy='omit')
```

    0.9351351351351351
    0.6575342465753424

    Ttest_indResult(statistic=-6.849454815841208, pvalue=3.652674361672226e-11)

## No Significant Difference in Support

Due to the insignificant p-value we would FAIL TO REJECT the null hypothesis that the means of Democrat support and Republican support are equal. This means that regardless of the sign on the t-statistic, we cannot make statistically significant claims about the difference between Republican and Democrat support of this issue.

```
print(dem['water-project'].mean())
print(rep['water-project'].mean())

stats.ttest_ind(dem['water-project'], rep['water-project'], nan_policy='omit')
```

    0.502092050209205
    0.5067567567567568

    Ttest_indResult(statistic=-0.08896538137868286, pvalue=0.9291556823993485)

# $\chi^2$ Hypothesis Tests

Chi-square hypothesis tests can only be performed on categorical data to test independence (lack of association) between two variables.

You can tabulate the different cross-sections of your categorical data by creating a "contingency table" also known as a "cross-tab". If we see substantial differences between categories in the cross-tab, this might indicate a dependence between variables (possibly indicating some level of correlation although correlation and dependence are not perfectly synonymous),however, we must perform a chi-square test in order to test this hypothesis.

Correlation implies dependence (association), but dependence does not necessarily imply correlation. (Although it is correlated with correlation - you see what I did there?)

## First, a Numpy vs Scipy implementation

Lets demonstrate a chi-squared test on the "Adult" dataset (1994 census data) from UCI.

Lets compare gender and binned working hours per week (both are categorical).

<http://archive.ics.uci.edu/ml/datasets/adult>

```
df = pd.read_csv('https://raw.githubusercontent.com/ryanleeallred/datasets/master/adult.csv')
print(df.shape)
df.head()
```

    (32561, 15)

      age
      workclass
      fnlwgt
      education
      education-num
      marital-status
      occupation
      relationship
      race
      sex
      capital-gain
      capital-loss
      hours-per-week
      country
      salary

      0
      39
      State-gov
      77516
      Bachelors
      13
      Never-married
      Adm-clerical
      Not-in-family
      White
      Male
      2174
      0
      40
      United-States
      <=50K

      1
      50
      Self-emp-not-inc
      83311
      Bachelors
      13
      Married-civ-spouse
      Exec-managerial
      Husband
      White
      Male
      0
      0
      13
      United-States
      <=50K

      2
      38
      Private
      215646
      HS-grad
      9
      Divorced
      Handlers-cleaners
      Not-in-family
      White
      Male
      0
      0
      40
      United-States
      <=50K

      3
      53
      Private
      234721
      11th
      7
      Married-civ-spouse
      Handlers-cleaners
      Husband
      Black
      Male
      0
      0
      40
      United-States
      <=50K

      4
      28
      Private
      338409
      Bachelors
      13
      Married-civ-spouse
      Prof-specialty
      Wife
      Black
      Female
      0
      0
      40
      Cuba
      <=50K

```
pd.scatter_matrix(df, alpha=0.2)
```

```
import seaborn as sns
g = sns.pairplot(df, kind='reg', plot_kws={'line_kws':{'color':'red'}, 'scatter_kws': {'alpha': 0.1}})
```

Notice that for chi-squared tests, I will not have to categorically encode my data since I will perform my calculations on the contingency table (cross-tab) and not on the raw dataframe.

```
def process_hours(df):
  cut_points = [0,9,19,29,39,49,1000]
  label_names = ["0-9","10-19","20-29","30-39","40-49","50+"]
  df["hours_per_week_categories"] = pd.cut(df["hours-per-week"],
                                           cut_points,labels=label_names)
  return df

data = process_hours(df)
workhour_by_sex = data[['sex', 'hours_per_week_categories']]
workhour_by_sex.head()
```

      sex
      hours_per_week_categories

      0
      Male
      40-49

      1
      Male
      10-19

      2
      Male
      40-49

      3
      Male
      40-49

      4
      Female
      40-49

```
workhour_by_sex['sex'].value_counts()
```

     Male      21790
     Female    10771
    Name: sex, dtype: int64

```
workhour_by_sex['hours_per_week_categories'].value_counts()
```

    40-49    18336
    50+       6462
    30-39     3667
    20-29     2392
    10-19     1246
    0-9        458
    Name: hours_per_week_categories, dtype: int64

Before we calculate our contingency table, lets make very clear what our null and alternative hypotheses are in this situation.

$H_{0}$ : There is *no* statistically significant relationship between gender and working hours per week.

$H_{a}$ : There *is* a statistically significant relationship between gender and working hours per week.

```
df.corr()
```

      age
      fnlwgt
      education-num
      capital-gain
      capital-loss
      hours-per-week

      age
      1.000000
      -0.076646
      0.036527
      0.077674
      0.057775
      0.068756

      fnlwgt
      -0.076646
      1.000000
      -0.043195
      0.000432
      -0.010252
      -0.018768

      education-num
      0.036527
      -0.043195
      1.000000
      0.122630
      0.079923
      0.148123

      capital-gain
      0.077674
      0.000432
      0.122630
      1.000000
      -0.031615
      0.078409

      capital-loss
      0.057775
      -0.010252
      0.079923
      -0.031615
      1.000000
      0.054256

      hours-per-week
      0.068756
      -0.018768
      0.148123
      0.078409
      0.054256
      1.000000

```
# Calculate our contingency table with margins
contingency_table = pd.crosstab(
    workhour_by_sex['sex'],
    workhour_by_sex['hours_per_week_categories'],
    margins = True)

contingency_table
```

      hours_per_week_categories
      0-9
      10-19
      20-29
      30-39
      40-49
      50+
      All

      sex

      Female
      235
      671
      1287
      1914
      5636
      1028
      10771

      Male
      223
      575
      1105
      1753
      12700
      5434
      21790

      All
      458
      1246
      2392
      3667
      18336
      6462
      32561

Using the contingency table with margins included will make our from-scratch implementation a little bit easier.

Our code would be more reusable if we calculated totals as we went instead of pulling them from the table, but I wanted to be really clear about what they represented, so we're going to grab the row and column totals from the margins of the contingency table directly.

### Visualizing preferences with a stacked bar-chart.

```
#Assigns the frequency values
malecount = contingency_table.iloc[0][0:6].values
femalecount = contingency_table.iloc[1][0:6].values

#Plots the bar chart
fig = plt.figure(figsize=(10, 5))
sns.set(font_scale=1.8)
categories = ["0-9","10-19","20-29","30-39","40-49","50+"]
p1 = plt.bar(categories, malecount, 0.55, color='#d62728')
p2 = plt.bar(categories, femalecount, 0.55, bottom=malecount)
plt.legend((p2[0], p1[0]), ('Male', 'Female'))
plt.xlabel('Hours per Week Worked')
plt.ylabel('Count')
plt.show()
```

It's harder to eyeball if these variables might be dependent. I would look at the ratios between 30-39, 40-49 and 50+. As we do this we see that males working 40-49 hours per week experiences something like 5x jump from the amount working 30-39 whereas for women it's something like a 2.5x jump. Similarly for men we see a decrease to about 1/3 the size as we move from >40 to the >50 category, but for women the final category is about 1/5 the size. This suggests to me that gender and working hours are not independent. Hopefully this passes the smell test for you as it matches your intuition that has been trained from a lifetime of training data.

### Expected Value Calculation
\begin{align}
expected_{i,j} =\frac{(row_{i} \text{total})(column_{j} \text{total}) }{(\text{total observations})}
\end{align}

```
# Get Row Sums
row_sums = contingency_table.iloc[0:2,6].values
print(row_sums)
```

    [10771 21790]

```
# Get Column Sums
col_sums = contingency_table.iloc[2,0:6].values
print(col_sums)
```

    [  458  1246  2392  3667 18336  6462]

```
# Calculate Expected Values for each cell
total = contingency_table.loc['All', 'All']
print("Total number of observations:", total)

expected = []
for i in range(len(row_sums)):
  expected_row = []
  for column in col_sums:
    expected_val = column*row_sums[i]/total
    expected_row.append(expected_val)
  expected.append(expected_row)

print(np.array(expected))
```

    Total number of observations: 32561
    [[  151.50388502   412.16995793   791.26046497  1213.02346365
       6065.44811277  2137.59411566]
     [  306.49611498   833.83004207  1600.73953503  2453.97653635
      12270.55188723  4324.40588434]]

## Chi-Squared Statistic with Numpy

\begin{align}
\chi^2 = \sum \frac{(observed_{i}-expected_{i})^2}{(expected_{i})}
\end{align}

For the $observed$ values we will just use a version of our contingency table without the margins as a numpy array. In this way, if our observed values array and our expected values array are the same shape, then we can subtract them and divide them directly which makes the calculations a lot cleaner. No for loops!

```
# Get contingency table without margins
contingency = pd.crosstab(workhour_by_sex['sex'],
                          workhour_by_sex['hours_per_week_categories'])
contingency = contingency.values

print(contingency.shape)
print(contingency)
```

    (2, 6)
    [[  235   671  1287  1914  5636  1028]
     [  223   575  1105  1753 12700  5434]]

```
chi_squared = ((contingency - expected)**2/(expected)).sum()
print(f"Chi-Squared: {chi_squared}")
```

    Chi-Squared: 2287.190943926107

### Degrees of Freedom

\begin{align}
DoF = (\text{Number of Rows} -1)\times(\text{Number of Columns}-1)
\end{align}

```
dof = (len(row_sums)-1)*(len(col_sums)-1)
print(f"Degrees of Freedom: {dof}")
```

    Degrees of Freedom: 5

```
# Calculate the p-value from the chi_squared and dof
p_value = stats.chi2.sf(chi_squared, dof)
print(f"P-value: {p_value}")
```

    P-value: 0.0

```
chi_squared, p_value, dof, expected = stats.chi2_contingency(contingency)

print(f"Chi-Squared: {chi_squared}")
print(f"P-value: {p_value}")
print(f"Degrees of Freedom: {dof}")
print("Expected: \n", np.array(expected))
```

    Chi-Squared: 2287.190943926107
    P-value: 0.0
    Degrees of Freedom: 5
    Expected:
     [[  151.50388502   412.16995793   791.26046497  1213.02346365
       6065.44811277  2137.59411566]
     [  306.49611498   833.83004207  1600.73953503  2453.97653635
      12270.55188723  4324.40588434]]

# Can we perform a Chi2 test on our congressional voting data?

Is it categorical? Then yes. Lets do it!

Are political party and voting behavior on the "budget" independent? Lets test it!

```
# Load the data again to be safe:
df = pd.read_csv('house-votes-84.data',
                 header=None,
                 names=['party','handicapped-infants','water-project',
                          'budget','physician-fee-freeze', 'el-salvador-aid',
                          'religious-groups','anti-satellite-ban',
                          'aid-to-contras','mx-missile','immigration',
                          'synfuels', 'education', 'right-to-sue','crime','duty-free',
                          'south-africa'])
df = df.replace({'?':np.NaN, 'n':0, 'y':1})
print(df.shape)
df.head()
```

    (435, 17)

      party
      handicapped-infants
      water-project
      budget
      physician-fee-freeze
      el-salvador-aid
      religious-groups
      anti-satellite-ban
      aid-to-contras
      mx-missile
      immigration
      synfuels
      education
      right-to-sue
      crime
      duty-free
      south-africa

      0
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      0.0
      1.0

      1
      republican
      0.0
      1.0
      0.0
      1.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      1.0
      1.0
      0.0
      NaN

      2
      democrat
      NaN
      1.0
      1.0
      NaN
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0

      3
      democrat
      0.0
      1.0
      1.0
      0.0
      NaN
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      1.0
      0.0
      0.0
      1.0

      4
      democrat
      1.0
      1.0
      1.0
      0.0
      1.0
      1.0
      0.0
      0.0
      0.0
      0.0
      1.0
      NaN
      1.0
      1.0
      1.0
      1.0

```
contingency_table =  pd.crosstab(df['party'], df['budget'])
contingency_table
```

      budget
      0.0
      1.0

      party

      democrat
      29
      231

      republican
      142
      22

```
chi_squared, p_value, dof, expected = stats.chi2_contingency(contingency_table)

print(f"Chi-Squared: {chi_squared}")
print(f"P-value: {p_value}")
print(f"Degrees of Freedom: {dof}")
print("Expected: \n", np.array(expected))
```

    Chi-Squared: 234.65408769323486
    P-value: 5.759792112623893e-53
    Degrees of Freedom: 1
    Expected:
     [[104.85849057 155.14150943]
     [ 66.14150943  97.85849057]]

```
# Calculate the p-value from the chi_squared and dof
p_value = stats.chi2.sf(chi_squared, dof)
print(f"P-value: {p_value}")
```

    P-value: 5.759792112623893e-53

We REJECT the null hypothesis that political party and voting on the budget are independent. They must be associated. Which hopefully also passes the smell test.

# Confidence Interval Plotting Examples

## For Categorical Data (congressional voting dataset)

```
# Calculate the Confidence interval around the democrat handicapped-infants mean
# Confidence intervals!
# Similar to hypothesis testing, but centered at sample mean
# Generally better than reporting the "point estimate" (sample mean)
# Why? Because point estimates aren't always perfect

import numpy as np
from scipy import stats

def confidence_interval(data, confidence=0.5):
  """
  Calculate a confidence interval around a sample mean for given data.
  Using t-distribution and two-tailed test, default 95% confidence.

  Arguments:
    data - iterable (list or numpy array) of sample observations
    confidence - level of confidence for the interval

  Returns:
    tuple of (mean, lower bound, upper bound)
  """
  data = np.array(data)
  mean = np.mean(data)
  n = len(data)
  stderr = stats.sem(data)
  interval = stderr * stats.t.ppf((1 + confidence) / 2.0, n - 1)
  return (mean, mean - interval, mean + interval)
```

```
def confidence_interval_dataframe(df):

  confidence_intervals = []

  # Turn dataframe into a numpy array
  # List values by column and not by row
  df = df.values.T

  # Remove nan values from columns
  cleaned_df = []
  for col in df:
    cleaned_col = col[~np.isnan(col)]

    # Calculate Confidence interval for each issue
    confidence_intervals.append(confidence_interval(cleaned_col))

  confidence_intervals = pd.DataFrame(confidence_intervals, columns=['mean', 'lower', 'upper'])

  return confidence_intervals

# We only want the issue columns not the string "party" column
only_votes = dem.drop('party', axis='columns')

confidence_interval_df = confidence_interval_dataframe(only_votes)
confidence_interval_df.head()
```

      mean
      lower
      upper

      0
      0.604651
      0.544593
      0.664710

      1
      0.502092
      0.438245
      0.565939

      2
      0.888462
      0.849944
      0.926980

      3
      0.054054
      0.026332
      0.081776

      4
      0.215686
      0.164863
      0.266509

```
confidence_interval_df['margin_of_error'] = confidence_interval_df['upper'] - confidence_interval_df['mean']

print(confidence_interval_df.shape)
confidence_interval_df.head()
```

    (16, 4)

      mean
      lower
      upper
      margin_of_error

      0
      0.604651
      0.544593
      0.664710
      0.060058

      1
      0.502092
      0.438245
      0.565939
      0.063847

      2
      0.888462
      0.849944
      0.926980
      0.038518

      3
      0.054054
      0.026332
      0.081776
      0.027722

      4
      0.215686
      0.164863
      0.266509
      0.050823

```
import matplotlib.pyplot as plt
```

```
x = np.linspace(0, confidence_interval_df.shape[0], confidence_interval_df.shape[0])
y = confidence_interval_df['mean']
yerr = confidence_interval_df['margin_of_error']

plt.style.use('ggplot')
plt.errorbar(x, y, yerr, fmt='o');
plt.title('Average Democratic Support with Confidence Intervals')
plt.ylabel("Percent of Democrats voting 'yes'")
```

```
fig, ax = plt.subplots()
means = confidence_interval_df['mean']
error = confidence_interval_df['margin_of_error']
x_pos = np.arange(confidence_interval_df.shape[0])
issues = ['party','handicapped-infants','water-project',
                          'budget','physician-fee-freeze', 'el-salvador-aid',
                          'religious-groups','anti-satellite-ban',
                          'aid-to-contras','mx-missile','immigration',
                          'synfuels', 'education', 'right-to-sue','crime','duty-free',
                          'south-africa']

# Matplotlib Named Colors: https://matplotlib.org/2.0.0/examples/color/named_colors.html
ax.bar(x, means, yerr=error)
ax.set_ylabel("% of Democrats voting 'yes'")
ax.set_xticks(x_pos)
ax.set_xticklabels(issues)
ax.set_title('Democratic Support with MOE', color='k')
ax.yaxis.grid(True)

# Save the figure and show
# Different style sheets: https://matplotlib.org/3.1.0/gallery/style_sheets/style_sheets_reference.html
plt.style.use('ggplot')
plt.tight_layout()
plt.xticks(rotation=90)
plt.savefig('bar_plot_with_error_bars.png')
plt.show()
```

```
# Plot Kernel Density Function for Immigration with Confidence Interval
from scipy.stats import t

immigration = dem['immigration'].dropna()
n = len(immigration)
mean = immigration.mean()
sample_std = immigration.std()
std_err = sample_std/n**.5
# std_err = sample_std/np.sqrt(n)

CI_immigration = t.interval(.95, n-1, loc=mean, scale=std_err)
print("95% Confidence Interval: ", CI_immigration)
```

    95% Confidence Interval:  (0.41075744059137587, 0.5322083388763047)

```
## Our in-class version
confidence_interval(immigration)
```

    (0.4714828897338403, 0.41075744059137587, 0.5322083388763047)

Plotting a confidence interval on the density plot of our sample doesn't look that great because these two things are not as related to each other as we might think.

The confidence interval is related to the distribution of sample means if we were to run this experiment multiple times.

This is impossible to do with the congressional data unless we could relive the 80s over and over again, but we can show it better with some coinflips.

```
import seaborn as sns

sns.kdeplot(immigration)
plt.axvline(x=CI_immigration[0], color='red')
plt.axvline(x=CI_immigration[1], color='red')
plt.axvline(x=mean, color='k');
```

## Coinflips Example

```
import numpy as np

coinflip_means = []
for x in range(0,100):
  coinflips = np.random.binomial(n=1, p=.5, size=30)
  coinflip_means.append(coinflips.mean())

print(coinflip_means)
```

    [0.43333333333333335, 0.5333333333333333, 0.5, 0.4, 0.4, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.6, 0.5333333333333333, 0.6, 0.43333333333333335, 0.5, 0.5, 0.4, 0.7, 0.36666666666666664, 0.6, 0.5333333333333333, 0.5666666666666667, 0.36666666666666664, 0.6, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5, 0.6, 0.6, 0.6, 0.43333333333333335, 0.4666666666666667, 0.5, 0.3333333333333333, 0.5333333333333333, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.4, 0.5333333333333333, 0.43333333333333335, 0.6, 0.5333333333333333, 0.6, 0.5, 0.4, 0.5, 0.5666666666666667, 0.5, 0.4666666666666667, 0.6, 0.5333333333333333, 0.4, 0.43333333333333335, 0.6, 0.43333333333333335, 0.6333333333333333, 0.4666666666666667, 0.4, 0.6333333333333333, 0.5, 0.5, 0.5333333333333333, 0.43333333333333335, 0.6, 0.4666666666666667, 0.5666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.36666666666666664, 0.6333333333333333, 0.3, 0.4666666666666667, 0.6666666666666666, 0.4, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.5, 0.43333333333333335, 0.6666666666666666, 0.5, 0.6666666666666666, 0.4, 0.5333333333333333, 0.6333333333333333, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.5666666666666667, 0.6333333333333333, 0.5, 0.3333333333333333, 0.4666666666666667, 0.5333333333333333, 0.3, 0.36666666666666664, 0.43333333333333335, 0.5333333333333333]

```
# Sample Size
n = len(coinflip_means)
# Degrees of Freedom
dof = n-1
# The Mean of Means:
mean = np.mean(coinflip_means)
# Sample Standard Deviation
sample_std = np.std(coinflip_means, ddof=1)
# Standard Error
std_err = sample_std/n**.5

CI = t.interval(.95, dof, loc=mean, scale=std_err)
print("95% Confidence Interval: ", CI)
```

    95% Confidence Interval:  (0.48474701530174785, 0.5192529846982519)

```
'''You can roll your own CI calculation pretty easily.
The only thing that's a little bit challenging
is understanding the t stat lookup'''

t_stat = t.ppf(.975, dof)
print("t Statistic:", t_stat)

CI = (mean-(t_stat*std_err), mean+(t_stat*std_err))
print("Confidence Interval", CI)
```

    t Statistic: 1.9842169515086827
    Confidence Interval (0.48474701530174785, 0.5192529846982519)

```
sns.kdeplot(coinflip_means)
plt.axvline(x=CI[0], color='red')
plt.axvline(x=CI[1], color='red')
plt.axvline(x=mean, color='k');
```

# Relationship between Confidence Intervals and T-tests

## Confidence Interval == Bounds of statistical significance for null hypothesis

```
# Sample Size
n = len(coinflip_means)
# Degrees of Freedom
dof = n-1
# The Mean of Means:
mean = np.mean(coinflip_means)
# Sample Standard Deviation
sample_std = np.std(coinflip_means, ddof=1)
# Standard Error
std_err = sample_std/n**.5

CI = t.interval(.95, dof, loc=mean, scale=std_err)
print("95% Confidence Interval: ", CI)
```

    95% Confidence Interval:  (0.48474701530174785, 0.5192529846982519)

```
immigration = dem['immigration'].dropna()
n = len(immigration)
mean = immigration.mean()
sample_std = immigration.std()
std_err = sample_std/n**.5

CI_immigration = t.interval(.99, n-1, loc=mean, scale=std_err)
print("95% Confidence Interval: ", CI_immigration)
```

    95% Confidence Interval:  (0.3914620619071199, 0.5515037175605607)

```
from scipy.stats import ttest_1samp
```

```
ttest_1samp(immigration, .391)
```

    Ttest_1sampResult(statistic=2.609706773357915, pvalue=0.00958326671015711)

```

```

```

```

```

```

```

```

```

```

```

```