###### Text provided under a Creative Commons Attribution license, CC-BY. All code is made available under the FSF-approved MIT license. (c) Daniel Koehn based on Jupyter notebooks by Marc Spiegelman [Dynamical Systems APMA 4101](https://github.com/mspieg/dynamical-systems) and  Kyle Mandli from his course [Introduction to numerical methods](https://github.com/mandli/intro-numerical-methods), notebook style sheet by L.A. Barba, N.C. Clementi [Engineering Computations](https://github.com/engineersCode)

```python
# Execute this cell to load the notebook's style sheet, then ignore it
from IPython.core.display import HTML
css_file = '../style/custom.css'
HTML(open(css_file, "r").read())
```

<link href="https://fonts.googleapis.com/css?family=Merriweather:300,300i,400,400i,700,700i,900,900i" rel='stylesheet' >
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i,700,700i" rel='stylesheet' >
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:300,400' rel='stylesheet' >
<style>

@font-face {
    font-family: "Computer Modern";
    src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');
}

#notebook_panel { /* main background */
    background: rgb(245,245,245);
}

div.cell { /* set cell width */
    width: 800px;
}

div #notebook { /* centre the content */
    background: #fff; /* white background for content */
    width: 1000px;
    margin: auto;
    padding-left: 0em;
}

#notebook li { /* More space between bullet points */
margin-top:0.5em;
}

/* draw border around running cells */
div.cell.border-box-sizing.code_cell.running {
    border: 1px solid #111;
}

/* Put a solid color box around each cell and its output, visually linking them*/
div.cell.code_cell {
    background-color: rgb(256,256,256);
    border-radius: 0px;
    padding: 0.5em;
    margin-left:1em;
    margin-top: 1em;
}

div.text_cell_render{
    font-family: 'Source Sans Pro', sans-serif;
    line-height: 140%;
    font-size: 110%;
    width:680px;
    margin-left:auto;
    margin-right:auto;
}

/* Formatting for header cells */
.text_cell_render h1 {
    font-family: 'Merriweather', serif;
    font-style:regular;
    font-weight: bold;
    font-size: 250%;
    line-height: 100%;
    color: #004065;
    margin-bottom: 1em;
    margin-top: 0.5em;
    display: block;
}
.text_cell_render h2 {
    font-family: 'Merriweather', serif;
    font-weight: bold;
    font-size: 180%;
    line-height: 100%;
    color: #0096d6;
    margin-bottom: 0.5em;
    margin-top: 0.5em;
    display: block;
}

.text_cell_render h3 {
    font-family: 'Merriweather', serif;
	font-size: 150%;
    margin-top:12px;
    margin-bottom: 3px;
    font-style: regular;
    color: #008367;
}

.text_cell_render h4 {    /*Use this for captions*/
    font-family: 'Merriweather', serif;
    font-weight: 300;
    font-size: 100%;
    line-height: 120%;
    text-align: left;
    width:500px;
    margin-top: 1em;
    margin-bottom: 2em;
    margin-left: 80pt;
    font-style: regular;
}

.text_cell_render h5 {  /*Use this for small titles*/
    font-family: 'Source Sans Pro', sans-serif;
    font-weight: regular;
    font-size: 130%;
    color: #e31937;
    font-style: italic;
    margin-bottom: .5em;
    margin-top: 1em;
    display: block;
}

.text_cell_render h6 { /*use this for copyright note*/
    font-family: 'Source Code Pro', sans-serif;
    font-weight: 300;
    font-size: 9pt;
    line-height: 100%;
    color: grey;
    margin-bottom: 1px;
    margin-top: 1px;
}

    .CodeMirror{
            font-family: "Source Code Pro";
			font-size: 90%;
    }
/*    .prompt{
        display: None;
    }*/

    .warning{
        color: rgb( 240, 20, 20 )
        }
</style>

# Exploring the Lorenz Equations

The Lorenz Equations are a 3-D dynamical system that is a simplified model of Rayleigh-Benard thermal convection.  They are derived and described in detail in Edward Lorenz' 1963 paper [Deterministic Nonperiodic Flow](http://journals.ametsoc.org/doi/pdf/10.1175/1520-0469%281963%29020%3C0130%3ADNF%3E2.0.CO%3B2)  in the Journal of Atmospheric Science.  In their classical form they can be written

\begin{equation}
\begin{split}
\frac{\partial X}{\partial t} &= \sigma( Y - X)\\
\frac{\partial Y}{\partial t} &= rX - Y - XZ \\
\frac{\partial Z}{\partial t} &= XY -b Z
\end{split}
\tag{1}
\end{equation}

where $\sigma$ is the "Prandtl number",  $r = \mathrm{Ra}/\mathrm{Ra}_c$ is a scaled "Rayleigh number" and $b$ is a parameter that is related to the the aspect ratio of a convecting cell in the original derivation.

Here, $X(t)$, $Y(t)$ and $Z(t)$ are the time dependent amplitudes of the streamfunction and temperature fields, expanded in a highly truncated Fourier Series where the streamfunction contains one cellular mode

$$
    \psi(x,z,t) = X(t)\sin(a\pi x)\sin(\pi z)
$$

and temperature has two modes

$$
    \theta(x,z,t) = Y(t)\cos(a\pi x)\sin(\pi z) - Z(t)\sin(2\pi z)
$$

This Jupyter notebook, will provide some simple python routines for numerical integration and visualization of the Lorenz Equations.

## Numerical solution of the Lorenz Equations

We have to solve the uncoupled ordinary differential equations (1) using the finite difference method introduced in [this lecture](https://nbviewer.jupyter.org/github/daniel-koehn/Differential-equations-earth-system/blob/master/02_finite_difference_intro/1_fd_intro.ipynb).

The approach is similar to the one used in [Exercise: How to sail without wind](https://nbviewer.jupyter.org/github/daniel-koehn/Differential-equations-earth-system/blob/master/02_finite_difference_intro/3_fd_ODE_example_sailing_wo_wind.ipynb), except that eqs.(1) are coupled ordinary differential equations, we have an additional differential equation and the RHS are more complex.

Approximating the temporal derivatives in eqs. (1) using the **backward FD operator**

\begin{equation}
\frac{df}{dt} = \frac{f(t)-f(t-dt)}{dt} \notag
\end{equation}

with the time sample interval $dt$ leads to

\begin{equation}
\begin{split}
\frac{X(t)-X(t-dt)}{dt} &= \sigma(Y - X)\\
\frac{Y(t)-Y(t-dt)}{dt} &= rX - Y - XZ\\
\frac{Y(t)-Y(t-dt)}{dt} &= XY -b Z\\
\end{split}
\notag
\end{equation}

After solving for $X(t), Y(t), Z(t)$, we get the **explicit time integration scheme** for the Lorenz equations:

\begin{equation}
\begin{split}
X(t) &= X(t-dt) + dt\; \sigma(Y - X)\\
Y(t) &= Y(t-dt) + dt\; (rX - Y - XZ)\\
Z(t) &= Z(t-dt) + dt\; (XY -b Z)\\
\end{split}
\notag
\end{equation}

and by introducing a temporal dicretization $t^n = n * dt$ with $n \in [0,1,...,nt]$, where $nt$ denotes the maximum time steps, the final FD code becomes:

\begin{equation}
\begin{split}
X^{n} &= X^{n-1} + dt\; \sigma(Y^{n-1} - X^{n-1})\\
Y^{n} &= Y^{n-1} + dt\; (rX^{n-1} - Y^{n-1} - X^{n-1}Z^{n-1})\\
Z^{n} &= Z^{n-1} + dt\; (X^{n-1}Y^{n-1} - b Z^{n-1})\\
\end{split}
\tag{2}
\end{equation}

The Python implementation is quite straightforward, because we can reuse some old codes ...

##### Exercise 1

Finish the function `Lorenz`, which computes and returns the RHS of eqs. (1) for a given $X$, $Y$, $Z$.

```python
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
```

```python
def Lorenz(X,Y,Z,sigma,r,b):

  '''
  Returns the RHS of the Lorenz equations
  '''

  # ADD RHS OF LORENZ EQUATIONS (1) HERE!
  X_dot_rhs =
  Y_dot_rhs =
  Z_dot_rhs =

  # return the state derivatives
  return X_dot_rhs, Y_dot_rhs, Z_dot_rhs
```

Next, we write the function to solve the Lorenz equation `SolveLorenz` based on the `sailing_boring` code from the [Exercise: How to sail without wind](https://nbviewer.jupyter.org/github/daniel-koehn/Differential-equations-earth-system/blob/master/02_finite_difference_intro/3_fd_ODE_example_sailing_wo_wind.ipynb)

##### Exercise 2

Finish the FD-code implementation `SolveLorenz`

```python
def SolveLorenz(tmax, dt, X0, Y0, Z0, sigma=10.,r=28.,b=8./3.0):

    '''
    Integrate the Lorenz equations from initial condition (X0,Y0,Z0)^T at t=0
    for parameters sigma, r, b

    Returns: X, Y, Z, time
    '''

    # Compute number of time steps based on tmax and dt
    nt = (int)(tmax/dt)

    # vectors for storage of X, Y, Z positions and time t
    X  = np.zeros(nt + 1)
    Y  = np.zeros(nt + 1)
    Z  = np.zeros(nt + 1)
    t  = np.zeros(nt + 1)

    # define initial position and time
    X[0] = X0
    Y[0] = Y0
    Z[0] = Z0

    # start time stepping over time samples n
    for n in range(1,nt + 1):

        # compute RHS of Lorenz eqs. (1) at current position (X,Y,Z)^T
        X_dot_rhs, Y_dot_rhs, Z_dot_rhs = Lorenz(X[n-1],Y[n-1],Z[n-1],sigma,r,b)

        # compute new position using FD approximation of time derivative
        # ADD FD SCHEME OF THE LORENZ EQS. HERE!
        X[n] =
        Y[n] =
        Z[n] =
        t[n] = n * dt

    return X, Y, Z, t
```

Finally, we create a function to plot the solution (X,Y,Z)^T of the Lorenz eqs. ...

```python
def PlotLorenzXvT(X,Y,Z,t,sigma,r,b):

    '''
    Create time series plots of solutions of the Lorenz equations X(t),Y(t),Z(t)
    '''

    plt.figure()
    ax = plt.subplot(111)
    ax.plot(t,X,'r',label='X')
    ax.plot(t,Y,'g',label='Y')
    ax.plot(t,Z,'b',label='Z')
    ax.set_xlabel('time t')
    plt.title('Lorenz Equations: $\sigma=${}, $r=${}, $b=${}'.format(sigma,r,b))
    # Shrink current axis's height by 10% on the bottom
    box = ax.get_position()
    ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

    # Put a legend below current axis
    ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),ncol=3)
    plt.show()
```

... and a function to plot the trajectory in the **phase space portrait**:

```python
def PlotLorenz3D(X,Y,Z,sigma,r,b):
    '''
    Show 3-D Phase portrait using mplot3D
    '''
    # do some fancy 3D plotting
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(X,Y,Z)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.title('Lorenz Equations: $\sigma=${}, $r=${}, $b=${}'.format(sigma,r,b))
    plt.show()
```

##### Exercise 3

Solve the Lorenz equations for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=0.5$, starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(2,3,4)^T$. Plot the temporal evolution and 3D phase potrait of the solution $(X(t),Y(t),Z(t))^T$. Mark the fix points, you derived in [Stationary Solutions of Time-Dependent Problems](http://nbviewer.ipython.org/urls/github.com/daniel-koehn/Differential-equations-earth-system/tree/master/03_Lorenz_equations/02_Stationary_solutions_of_DE.ipynb) in the 3D phase portrait. Describe and interpret the results.

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 30
dt = 0.01

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X, Y, Z, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)

# and as a 3-D phase portrait
PlotLorenz3D(X,Y,Z,sigma,r,b)
```

##### Exercise 4

Solve the Lorenz equations for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=10$, starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(2,3,4)^T$. Plot the temporal evolution and 3D phase potrait of the solution $(X(t),Y(t),Z(t))^T$. Mark the fix points, you derived in [Stationary Solutions of Time-Dependent Problems](http://nbviewer.ipython.org/urls/github.com/daniel-koehn/Differential-equations-earth-system/tree/master/03_Lorenz_equations/02_Stationary_solutions_of_DE.ipynb) in the 3D phase portrait. Describe and interpret the results.

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 30
dt = 0.01

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X, Y, Z, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)

# and as a 3-D phase portrait
PlotLorenz3D(X,Y,Z,sigma,r,b)
```

##### Exercise 5

Solve the Lorenz equations again for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=10$. However, starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(-2,-3,4)^T$. Plot the temporal evolution and 3D phase potrait of the solution $(X(t),Y(t),Z(t))^T$. Mark the fix points, you derived in [Stationary Solutions of Time-Dependent Problems](http://nbviewer.ipython.org/urls/github.com/daniel-koehn/Differential-equations-earth-system/tree/master/03_Lorenz_equations/02_Stationary_solutions_of_DE.ipynb) in the 3D phase portrait. Describe and interpret the results. How does the solution change compared to exercise 4?

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 30
dt = 0.01

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X, Y, Z, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)

# and as a 3-D phase portrait
PlotLorenz3D(X,Y,Z,sigma,r,b)
```

##### Exercise 6

Solve the Lorenz equations for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=28$, starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(2,3,4)^T$. Plot the temporal evolution and 3D phase potrait of the solution $(X(t),Y(t),Z(t))^T$. Mark the fix points, you derived in [Stationary Solutions of Time-Dependent Problems](http://nbviewer.ipython.org/urls/github.com/daniel-koehn/Differential-equations-earth-system/tree/master/03_Lorenz_equations/02_Stationary_solutions_of_DE.ipynb) in the 3D phase portrait. Describe and interpret the results. Compare with the previous results.

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 30
dt = 5e-4

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X, Y, Z, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)

# and as a 3-D phase portrait
PlotLorenz3D(X,Y,Z,sigma,r,b)
```

##### Exercise 7

In his 1963 paper Lorenz also investigated the influence of small changes of the initial conditions on the long-term evolution of the thermal convection problem for large Rayleigh numbers.

Solve the Lorenz equations for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=28$, however starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(2,3.001,4)^T$. Plot the temporal evolution and compare with the solution of exercise 6. Describe and interpret the results.

Explain why Lorenz introduced the term **Butterfly effect** based on your results.

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 30
dt = 5e-4

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X1, Y1, Z1, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize differences as a time series
PlotLorenzXvT(X-X1,Y-Y1,Z-Z1,t,sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X1,Y1,Z1,t,sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)
```

##### Exercise 8

Solve the Lorenz equations for a Prandtl number $\sigma=10$, $b=8/3$ and a scaled Rayleigh number $r=350$, starting from the initial condition ${\bf{X_0}}=(X_0,Y_0,Z_0)^T=(2,3,4)^T$. Plot the temporal evolution and 3D phase potrait of the solution $(X(t),Y(t),Z(t))^T$. Mark the fix points, you derived in [Stationary Solutions of Time-Dependent Problems](http://nbviewer.ipython.org/urls/github.com/daniel-koehn/Differential-equations-earth-system/tree/master/03_Lorenz_equations/02_Stationary_solutions_of_DE.ipynb) in the 3D phase portrait. Describe and interpret the results. Compare with the previous result from exercise 8.

```python
# SET THE PARAMETERS HERE!
sigma=
b =

# SET THE INITIAL CONDITIONS HERE!
X0 =
Y0 =
Z0 =

# Set maximum integration time and sample interval dt
tmax = 8.
dt = 5e-4

# SET THE RAYLEIGH NUMBER HERE!
r =

# Solve the Equations
X, Y, Z, t = SolveLorenz(tmax, dt, X0, Y0, Z0, sigma,r,b)

# and Visualize as a time series
PlotLorenzXvT(X,Y,Z,t,sigma,r,b)

# and as a 3-D phase portrait
PlotLorenz3D(X,Y,Z,sigma,r,b)
```

## What we learned:

- How to solve the Lorenz equations using a simple finite-difference scheme.

- How to visualize the solution of ordinary differential equations using the temporal evolution and phase portrait.

- Exporing the dynamic of non-linear differential equations and the sensitivity of small changes of the initial conditions to the long term evolution of the system.

- Why physicists can only predict the time evolution of complex dynamical systems to some extent.


# Lambda School Data Science Module 132
## Sampling, Confidence Intervals, and Hypothesis Testing

## Prepare - examine other available hypothesis tests

If you had to pick a single hypothesis test in your toolbox, t-test would probably be the best choice - but the good news is you don't have to pick just one! Here's some of the others to be aware of:

```
import numpy as np
from scipy.stats import chisquare  # One-way chi square test

# Chi square can take any crosstab/table and test the independence of rows/cols
# The null hypothesis is that the rows/cols are independent -> low chi square
# The alternative is that there is a dependence -> high chi square
# Be aware! Chi square does *not* tell you direction/causation

ind_obs = np.array([[1, 1], [2, 2]]).T
print(ind_obs)
print(chisquare(ind_obs, axis=None))

dep_obs = np.array([[16, 18, 16, 14, 12, 12], [32, 24, 16, 28, 20, 24]]).T
print(dep_obs)
print(chisquare(dep_obs, axis=None))
```

    [[1 2]
     [1 2]]
    Power_divergenceResult(statistic=0.6666666666666666, pvalue=0.8810148425137847)
    [[16 32]
     [18 24]
     [16 16]
     [14 28]
     [12 20]
     [12 24]]
    Power_divergenceResult(statistic=23.31034482758621, pvalue=0.015975692534127565)

```
# Distribution tests:
# We often assume that something is normal, but it can be important to *check*

# For example, later on with predictive modeling, a typical assumption is that
# residuals (prediction errors) are normal - checking is a good diagnostic

from scipy.stats import normaltest
# Poisson models arrival times and is related to the binomial (coinflip)
sample = np.random.poisson(5, 1000)
print(normaltest(sample))  # Pretty clearly not normal
```

    NormaltestResult(statistic=28.280826942833155, pvalue=7.225975047337626e-07)

```
# Kruskal-Wallis H-test - compare the median rank between 2+ groups
# Can be applied to ranking decisions/outcomes/recommendations
# The underlying math comes from chi-square distribution, and is best for n>5
from scipy.stats import kruskal

x1 = [1, 3, 5, 7, 9]
y1 = [2, 4, 6, 8, 10]
print(kruskal(x1, y1))  # x1 is a little better, but not "significantly" so

x2 = [1, 1, 1]
y2 = [2, 2, 2]
z = [2, 2]  # Hey, a third group, and of different size!
print(kruskal(x2, y2, z))  # x clearly dominates
```

    KruskalResult(statistic=0.2727272727272734, pvalue=0.6015081344405895)
    KruskalResult(statistic=7.0, pvalue=0.0301973834223185)

And there's many more! `scipy.stats` is fairly comprehensive, though there are even more available if you delve into the extended world of statistics packages. As tests get increasingly obscure and specialized, the importance of knowing them by heart becomes small - but being able to look them up and figure them out when they *are* relevant is still important.

## T-test Assumptions

<https://statistics.laerd.com/statistical-guides/independent-t-test-statistical-guide.php>

- Independence of means

Are the means of our voting data independent (do not affect the outcome of one another)?

The best way to increase thel likelihood of our means being independent is to randomly sample (which we did not do).

```
from scipy.stats import ttest_ind

?ttest_ind
```

- "Homogeneity" of Variance?

Is the magnitude of the variance between the two roughly the same?

I think we're OK on this one for the voting data, although it probably could be better, one party was larger than the other.

If we suspect this to be a problem then we can use Welch's T-test

```
?ttest_ind
```

- "Dependent Variable" (sample means) are Distributed Normally

<https://stats.stackexchange.com/questions/9573/t-test-for-non-normal-when-n50>

Lots of statistical tests depend on normal distributions. We can test for normality using Scipy as was shown above.

This assumption is often assumed even if the assumption is a weak one. If you strongly suspect that things are not normally distributed, you can transform your data to get it looking more normal and then run your test. This problem typically goes away for large sample sizes (yay Central Limit Theorem) and is often why you don't hear it brought up. People declare the assumption to be satisfied either way.

## Central Limit Theorem

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

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

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

    3000
    [0.5, 0.36666666666666664, 0.43333333333333335, 0.6, 0.3333333333333333, 0.6, 0.6, 0.4666666666666667, 0.3333333333333333, 0.5333333333333333, 0.5666666666666667, 0.6333333333333333, 0.5, 0.36666666666666664, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.4, 0.6333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.3333333333333333, 0.6, 0.5, 0.5666666666666667, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.4666666666666667, 0.3333333333333333, 0.43333333333333335, 0.7, 0.5, 0.5, 0.3, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.3, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.4, 0.36666666666666664, 0.43333333333333335, 0.36666666666666664, 0.6666666666666666, 0.4666666666666667, 0.5, 0.5333333333333333, 0.43333333333333335, 0.6, 0.7333333333333333, 0.5666666666666667, 0.5333333333333333, 0.6666666666666666, 0.6333333333333333, 0.4666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.6, 0.43333333333333335, 0.6, 0.4, 0.6, 0.5666666666666667, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.36666666666666664, 0.5666666666666667, 0.43333333333333335, 0.3333333333333333, 0.6, 0.4, 0.6, 0.6333333333333333, 0.5333333333333333, 0.5666666666666667, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.4666666666666667, 0.5, 0.4, 0.4666666666666667, 0.5, 0.6, 0.4666666666666667, 0.5, 0.5, 0.6, 0.6666666666666666, 0.5333333333333333, 0.3333333333333333, 0.5666666666666667, 0.5, 0.6, 0.36666666666666664, 0.5333333333333333, 0.5666666666666667, 0.6666666666666666, 0.43333333333333335, 0.5666666666666667, 0.5, 0.6333333333333333, 0.6333333333333333, 0.5, 0.6, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5333333333333333, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.5, 0.5, 0.4666666666666667, 0.4666666666666667, 0.36666666666666664, 0.5333333333333333, 0.6333333333333333, 0.7, 0.6333333333333333, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.6, 0.43333333333333335, 0.5, 0.5666666666666667, 0.4, 0.5, 0.5666666666666667, 0.4666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.6, 0.5, 0.5, 0.5666666666666667, 0.3333333333333333, 0.4666666666666667, 0.43333333333333335, 0.4, 0.5, 0.6333333333333333, 0.6, 0.5, 0.5666666666666667, 0.5666666666666667, 0.5, 0.43333333333333335, 0.43333333333333335, 0.5, 0.5333333333333333, 0.5333333333333333, 0.43333333333333335, 0.26666666666666666, 0.5, 0.43333333333333335, 0.4, 0.36666666666666664, 0.4, 0.43333333333333335, 0.6, 0.5666666666666667, 0.5666666666666667, 0.6, 0.5, 0.4666666666666667, 0.26666666666666666, 0.6666666666666666, 0.5666666666666667, 0.5, 0.5333333333333333, 0.4, 0.43333333333333335, 0.5333333333333333, 0.6666666666666666, 0.36666666666666664, 0.5, 0.5, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.36666666666666664, 0.5, 0.4666666666666667, 0.6666666666666666, 0.4666666666666667, 0.5, 0.4666666666666667, 0.4666666666666667, 0.3333333333333333, 0.4, 0.5666666666666667, 0.5, 0.6333333333333333, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.6666666666666666, 0.5333333333333333, 0.4, 0.5, 0.5333333333333333, 0.5, 0.5333333333333333, 0.36666666666666664, 0.6333333333333333, 0.5666666666666667, 0.4666666666666667, 0.4, 0.5, 0.4666666666666667, 0.5, 0.4, 0.5333333333333333, 0.5666666666666667, 0.3333333333333333, 0.5666666666666667, 0.6, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.5, 0.5, 0.5333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5, 0.36666666666666664, 0.43333333333333335, 0.5, 0.5333333333333333, 0.43333333333333335, 0.6, 0.5, 0.4, 0.6666666666666666, 0.4, 0.43333333333333335, 0.5, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5333333333333333, 0.4, 0.5, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.6333333333333333, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.4666666666666667, 0.43333333333333335, 0.4666666666666667, 0.4, 0.5333333333333333, 0.3, 0.5, 0.36666666666666664, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5, 0.43333333333333335, 0.6333333333333333, 0.5333333333333333, 0.6333333333333333, 0.6333333333333333, 0.5333333333333333, 0.6666666666666666, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.36666666666666664, 0.6333333333333333, 0.5666666666666667, 0.5333333333333333, 0.5, 0.5, 0.4666666666666667, 0.43333333333333335, 0.4, 0.3333333333333333, 0.43333333333333335, 0.4666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.36666666666666664, 0.4666666666666667, 0.4, 0.5, 0.5, 0.4666666666666667, 0.5666666666666667, 0.4, 0.5333333333333333, 0.5333333333333333, 0.6, 0.6, 0.5, 0.6333333333333333, 0.4, 0.43333333333333335, 0.4666666666666667, 0.6333333333333333, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.6, 0.3, 0.5333333333333333, 0.4, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5666666666666667, 0.6666666666666666, 0.6666666666666666, 0.36666666666666664, 0.5, 0.5, 0.6, 0.7333333333333333, 0.5333333333333333, 0.6, 0.4666666666666667, 0.43333333333333335, 0.3333333333333333, 0.4, 0.4, 0.5333333333333333, 0.4666666666666667, 0.6, 0.6333333333333333, 0.3333333333333333, 0.6666666666666666, 0.5333333333333333, 0.5666666666666667, 0.36666666666666664, 0.5666666666666667, 0.6333333333333333, 0.3333333333333333, 0.5333333333333333, 0.5666666666666667, 0.5, 0.3333333333333333, 0.4666666666666667, 0.5, 0.5333333333333333, 0.6, 0.43333333333333335, 0.4666666666666667, 0.6, 0.4, 0.5333333333333333, 0.3333333333333333, 0.6333333333333333, 0.4, 0.5, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5, 0.3333333333333333, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5666666666666667, 0.5, 0.4, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.6, 0.43333333333333335, 0.43333333333333335, 0.6666666666666666, 0.26666666666666666, 0.4666666666666667, 0.5333333333333333, 0.43333333333333335, 0.4, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.6333333333333333, 0.36666666666666664, 0.4, 0.6333333333333333, 0.5666666666666667, 0.5, 0.5, 0.6, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5, 0.43333333333333335, 0.5, 0.5666666666666667, 0.6666666666666666, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.5666666666666667, 0.6, 0.36666666666666664, 0.4666666666666667, 0.5333333333333333, 0.4, 0.6333333333333333, 0.5333333333333333, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.5, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.6333333333333333, 0.5666666666666667, 0.36666666666666664, 0.5, 0.6, 0.4666666666666667, 0.4, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.5, 0.4, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.4666666666666667, 0.43333333333333335, 0.5, 0.6666666666666666, 0.43333333333333335, 0.4, 0.36666666666666664, 0.4, 0.4, 0.5, 0.4, 0.6, 0.4, 0.3333333333333333, 0.43333333333333335, 0.43333333333333335, 0.4, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5333333333333333, 0.6333333333333333, 0.7333333333333333, 0.6, 0.5666666666666667, 0.4666666666666667, 0.5, 0.5, 0.3333333333333333, 0.5333333333333333, 0.43333333333333335, 0.5666666666666667, 0.6666666666666666, 0.2, 0.5, 0.36666666666666664, 0.36666666666666664, 0.43333333333333335, 0.43333333333333335, 0.4, 0.5, 0.43333333333333335, 0.5, 0.4, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5333333333333333, 0.43333333333333335, 0.5, 0.3333333333333333, 0.4666666666666667, 0.7, 0.6333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5, 0.5, 0.4, 0.5666666666666667, 0.6, 0.6666666666666666, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.5666666666666667, 0.36666666666666664, 0.5, 0.43333333333333335, 0.5, 0.5666666666666667, 0.6666666666666666, 0.5666666666666667, 0.5, 0.6, 0.5333333333333333, 0.5333333333333333, 0.36666666666666664, 0.5333333333333333, 0.3333333333333333, 0.4666666666666667, 0.3333333333333333, 0.6, 0.43333333333333335, 0.3333333333333333, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.4666666666666667, 0.36666666666666664, 0.4, 0.7, 0.5, 0.4, 0.6, 0.36666666666666664, 0.43333333333333335, 0.3, 0.6, 0.5333333333333333, 0.43333333333333335, 0.5333333333333333, 0.5, 0.5666666666666667, 0.5333333333333333, 0.4, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.36666666666666664, 0.36666666666666664, 0.6, 0.5, 0.4, 0.43333333333333335, 0.6, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5333333333333333, 0.5, 0.6, 0.43333333333333335, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.6, 0.4, 0.43333333333333335, 0.5666666666666667, 0.5, 0.43333333333333335, 0.5, 0.5, 0.43333333333333335, 0.6, 0.5333333333333333, 0.26666666666666666, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.5, 0.36666666666666664, 0.5666666666666667, 0.5333333333333333, 0.4, 0.4, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.5, 0.3333333333333333, 0.5, 0.4, 0.5, 0.5, 0.7, 0.5333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5666666666666667, 0.5, 0.6666666666666666, 0.5666666666666667, 0.5, 0.6, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5, 0.43333333333333335, 0.5666666666666667, 0.36666666666666664, 0.5666666666666667, 0.5, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.6, 0.4666666666666667, 0.6666666666666666, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.4, 0.43333333333333335, 0.5, 0.5333333333333333, 0.4, 0.5333333333333333, 0.5, 0.4666666666666667, 0.4, 0.6333333333333333, 0.5333333333333333, 0.6, 0.5333333333333333, 0.4666666666666667, 0.6, 0.4666666666666667, 0.5333333333333333, 0.5, 0.3333333333333333, 0.43333333333333335, 0.4, 0.5, 0.4666666666666667, 0.6, 0.3333333333333333, 0.5, 0.5333333333333333, 0.6, 0.43333333333333335, 0.5, 0.6666666666666666, 0.43333333333333335, 0.5666666666666667, 0.4, 0.5333333333333333, 0.6666666666666666, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5333333333333333, 0.6, 0.43333333333333335, 0.5, 0.5333333333333333, 0.4666666666666667, 0.6666666666666666, 0.5666666666666667, 0.3333333333333333, 0.3333333333333333, 0.5, 0.5, 0.5333333333333333, 0.5, 0.43333333333333335, 0.3, 0.5333333333333333, 0.3333333333333333, 0.5333333333333333, 0.4, 0.5666666666666667, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.5666666666666667, 0.4, 0.5333333333333333, 0.43333333333333335, 0.5, 0.5333333333333333, 0.5, 0.5, 0.5, 0.5, 0.5666666666666667, 0.7, 0.36666666666666664, 0.5, 0.5666666666666667, 0.5666666666666667, 0.5, 0.4666666666666667, 0.6666666666666666, 0.7, 0.43333333333333335, 0.6, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.4, 0.5333333333333333, 0.4666666666666667, 0.3, 0.4666666666666667, 0.3333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5, 0.5, 0.5666666666666667, 0.36666666666666664, 0.5666666666666667, 0.6666666666666666, 0.3, 0.3333333333333333, 0.4, 0.4666666666666667, 0.6, 0.5666666666666667, 0.43333333333333335, 0.36666666666666664, 0.36666666666666664, 0.6666666666666666, 0.5, 0.26666666666666666, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5333333333333333, 0.4, 0.5, 0.5666666666666667, 0.36666666666666664, 0.6333333333333333, 0.6, 0.5666666666666667, 0.4666666666666667, 0.4, 0.5, 0.5666666666666667, 0.5, 0.5, 0.5666666666666667, 0.5333333333333333, 0.6, 0.5, 0.4666666666666667, 0.5, 0.5, 0.5, 0.43333333333333335, 0.4, 0.5, 0.43333333333333335, 0.5666666666666667, 0.36666666666666664, 0.5, 0.6, 0.5, 0.5, 0.6, 0.6666666666666666, 0.5666666666666667, 0.4666666666666667, 0.4666666666666667, 0.4, 0.6, 0.6, 0.4, 0.43333333333333335, 0.4, 0.43333333333333335, 0.4, 0.4, 0.4, 0.5, 0.7, 0.3333333333333333, 0.4, 0.5333333333333333, 0.4666666666666667, 0.5, 0.6333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.5, 0.4666666666666667, 0.5, 0.3333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5, 0.43333333333333335, 0.43333333333333335, 0.4, 0.5666666666666667, 0.3333333333333333, 0.6666666666666666, 0.5, 0.5666666666666667, 0.5, 0.6, 0.43333333333333335, 0.4, 0.5, 0.5, 0.6, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4, 0.5666666666666667, 0.3333333333333333, 0.43333333333333335, 0.5, 0.6, 0.6333333333333333, 0.43333333333333335, 0.4666666666666667, 0.4, 0.43333333333333335, 0.4, 0.4666666666666667, 0.5, 0.4, 0.36666666666666664, 0.43333333333333335, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4, 0.6333333333333333, 0.5333333333333333, 0.6333333333333333, 0.4, 0.5, 0.43333333333333335, 0.4666666666666667, 0.3, 0.43333333333333335, 0.5333333333333333, 0.4, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.6333333333333333, 0.4666666666666667, 0.36666666666666664, 0.6, 0.5333333333333333, 0.36666666666666664, 0.36666666666666664, 0.5, 0.4666666666666667, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5333333333333333, 0.5, 0.36666666666666664, 0.5333333333333333, 0.5, 0.5, 0.4, 0.5, 0.5, 0.3, 0.5333333333333333, 0.36666666666666664, 0.6333333333333333, 0.5333333333333333, 0.6, 0.4666666666666667, 0.5333333333333333, 0.5, 0.36666666666666664, 0.6, 0.5, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.5, 0.5, 0.4, 0.26666666666666666, 0.5666666666666667, 0.3333333333333333, 0.6, 0.5333333333333333, 0.4666666666666667, 0.6, 0.43333333333333335, 0.6666666666666666, 0.5, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.6333333333333333, 0.43333333333333335, 0.5, 0.4666666666666667, 0.36666666666666664, 0.36666666666666664, 0.5333333333333333, 0.43333333333333335, 0.4, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.4, 0.4, 0.4666666666666667, 0.5, 0.4666666666666667, 0.5, 0.5666666666666667, 0.5, 0.5666666666666667, 0.5333333333333333, 0.23333333333333334, 0.5, 0.5, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5, 0.5333333333333333, 0.4666666666666667, 0.36666666666666664, 0.36666666666666664, 0.6333333333333333, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5666666666666667, 0.5, 0.4666666666666667, 0.3, 0.5333333333333333, 0.5333333333333333, 0.4, 0.3, 0.5666666666666667, 0.43333333333333335, 0.4666666666666667, 0.6, 0.4666666666666667, 0.43333333333333335, 0.3, 0.4666666666666667, 0.5, 0.4666666666666667, 0.6333333333333333, 0.4666666666666667, 0.36666666666666664, 0.4, 0.7666666666666667, 0.4, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.36666666666666664, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.4, 0.4, 0.5, 0.4, 0.6, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.5, 0.3333333333333333, 0.5, 0.4, 0.5, 0.5, 0.36666666666666664, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.5, 0.6666666666666666, 0.6333333333333333, 0.43333333333333335, 0.4666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5, 0.43333333333333335, 0.4, 0.6333333333333333, 0.6333333333333333, 0.43333333333333335, 0.36666666666666664, 0.36666666666666664, 0.5333333333333333, 0.5, 0.5333333333333333, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.6, 0.3333333333333333, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.6333333333333333, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.5, 0.36666666666666664, 0.4666666666666667, 0.6, 0.6, 0.4, 0.4666666666666667, 0.5, 0.5333333333333333, 0.5333333333333333, 0.4, 0.43333333333333335, 0.5, 0.5666666666666667, 0.5, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5, 0.6333333333333333, 0.4, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.5, 0.6, 0.5, 0.5333333333333333, 0.5, 0.43333333333333335, 0.36666666666666664, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.36666666666666664, 0.5, 0.5, 0.6, 0.6, 0.7, 0.5666666666666667, 0.5333333333333333, 0.3333333333333333, 0.43333333333333335, 0.4666666666666667, 0.4, 0.4, 0.5666666666666667, 0.6, 0.5, 0.5333333333333333, 0.5, 0.5, 0.43333333333333335, 0.6666666666666666, 0.43333333333333335, 0.4666666666666667, 0.43333333333333335, 0.6, 0.6, 0.6333333333333333, 0.4666666666666667, 0.3, 0.4, 0.5333333333333333, 0.5666666666666667, 0.5666666666666667, 0.5, 0.4, 0.4666666666666667, 0.7333333333333333, 0.43333333333333335, 0.43333333333333335, 0.4, 0.4666666666666667, 0.5666666666666667, 0.4, 0.5666666666666667, 0.4666666666666667, 0.7666666666666667, 0.5, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.4, 0.7, 0.6333333333333333, 0.5666666666666667, 0.4, 0.36666666666666664, 0.5, 0.5, 0.5, 0.6333333333333333, 0.6666666666666666, 0.5666666666666667, 0.3333333333333333, 0.3333333333333333, 0.36666666666666664, 0.4666666666666667, 0.4, 0.5333333333333333, 0.3, 0.6333333333333333, 0.6, 0.5333333333333333, 0.43333333333333335, 0.6666666666666666, 0.5, 0.4, 0.43333333333333335, 0.5333333333333333, 0.5333333333333333, 0.5666666666666667, 0.6333333333333333, 0.5, 0.5, 0.6666666666666666, 0.5666666666666667, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.4, 0.5333333333333333, 0.5, 0.6, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.7, 0.5333333333333333, 0.5666666666666667, 0.5666666666666667, 0.4, 0.6, 0.5, 0.43333333333333335, 0.6, 0.3333333333333333, 0.5, 0.43333333333333335, 0.36666666666666664, 0.3333333333333333, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.43333333333333335, 0.6333333333333333, 0.5, 0.6, 0.43333333333333335, 0.6333333333333333, 0.36666666666666664, 0.43333333333333335, 0.26666666666666666, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.3333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.36666666666666664, 0.36666666666666664, 0.5, 0.4666666666666667, 0.5666666666666667, 0.4666666666666667, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5, 0.4, 0.5666666666666667, 0.6333333333333333, 0.36666666666666664, 0.5, 0.5, 0.6, 0.4, 0.6, 0.4, 0.6666666666666666, 0.5, 0.5, 0.43333333333333335, 0.4666666666666667, 0.6, 0.5, 0.5666666666666667, 0.4, 0.3333333333333333, 0.6333333333333333, 0.6, 0.43333333333333335, 0.4, 0.4, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5333333333333333, 0.4666666666666667, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5666666666666667, 0.3, 0.6, 0.5, 0.43333333333333335, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.5333333333333333, 0.3333333333333333, 0.5666666666666667, 0.5666666666666667, 0.6666666666666666, 0.5333333333333333, 0.4666666666666667, 0.6666666666666666, 0.3333333333333333, 0.6333333333333333, 0.6, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.43333333333333335, 0.7, 0.5333333333333333, 0.5, 0.4666666666666667, 0.4, 0.7333333333333333, 0.43333333333333335, 0.4, 0.3, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.6666666666666666, 0.5, 0.4, 0.36666666666666664, 0.5666666666666667, 0.4, 0.4666666666666667, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.3333333333333333, 0.36666666666666664, 0.6333333333333333, 0.4, 0.6666666666666666, 0.5, 0.6, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.6333333333333333, 0.5666666666666667, 0.6666666666666666, 0.4666666666666667, 0.43333333333333335, 0.6, 0.5333333333333333, 0.6, 0.36666666666666664, 0.36666666666666664, 0.5, 0.5333333333333333, 0.5, 0.5, 0.6666666666666666, 0.5666666666666667, 0.5333333333333333, 0.4, 0.5, 0.4, 0.6, 0.5, 0.5333333333333333, 0.5, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.26666666666666666, 0.6, 0.5666666666666667, 0.6333333333333333, 0.43333333333333335, 0.6, 0.36666666666666664, 0.4, 0.5333333333333333, 0.43333333333333335, 0.4, 0.6666666666666666, 0.4666666666666667, 0.5, 0.36666666666666664, 0.4666666666666667, 0.5, 0.43333333333333335, 0.5, 0.4, 0.43333333333333335, 0.5, 0.43333333333333335, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.6, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.6, 0.43333333333333335, 0.3, 0.5, 0.5, 0.5666666666666667, 0.5, 0.6, 0.5666666666666667, 0.6, 0.5666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.43333333333333335, 0.5333333333333333, 0.4, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.4, 0.36666666666666664, 0.5, 0.5, 0.5, 0.43333333333333335, 0.7666666666666667, 0.5333333333333333, 0.4, 0.5666666666666667, 0.4666666666666667, 0.5, 0.26666666666666666, 0.4666666666666667, 0.3333333333333333, 0.4666666666666667, 0.3333333333333333, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5, 0.4, 0.5, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5666666666666667, 0.43333333333333335, 0.6333333333333333, 0.6, 0.5, 0.36666666666666664, 0.3, 0.5, 0.43333333333333335, 0.5333333333333333, 0.6, 0.5666666666666667, 0.6, 0.36666666666666664, 0.4666666666666667, 0.3, 0.4666666666666667, 0.4, 0.5666666666666667, 0.5666666666666667, 0.5666666666666667, 0.6, 0.5, 0.4, 0.5333333333333333, 0.5, 0.4, 0.6, 0.6333333333333333, 0.36666666666666664, 0.4666666666666667, 0.5, 0.36666666666666664, 0.36666666666666664, 0.5, 0.4666666666666667, 0.4666666666666667, 0.36666666666666664, 0.5, 0.5, 0.5, 0.5, 0.43333333333333335, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.5, 0.4666666666666667, 0.3333333333333333, 0.5, 0.6, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5, 0.4, 0.5, 0.4, 0.5333333333333333, 0.36666666666666664, 0.43333333333333335, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5, 0.43333333333333335, 0.7, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.3333333333333333, 0.43333333333333335, 0.5, 0.6333333333333333, 0.7, 0.5333333333333333, 0.5, 0.4, 0.43333333333333335, 0.3333333333333333, 0.43333333333333335, 0.5333333333333333, 0.43333333333333335, 0.6, 0.5666666666666667, 0.3333333333333333, 0.4, 0.5333333333333333, 0.5, 0.5666666666666667, 0.5666666666666667, 0.4, 0.5666666666666667, 0.5, 0.3333333333333333, 0.6, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5, 0.36666666666666664, 0.5, 0.4, 0.4, 0.5666666666666667, 0.5333333333333333, 0.5, 0.43333333333333335, 0.4666666666666667, 0.3333333333333333, 0.5, 0.5333333333333333, 0.6, 0.4, 0.6, 0.7, 0.5, 0.3333333333333333, 0.5, 0.3333333333333333, 0.43333333333333335, 0.4666666666666667, 0.6333333333333333, 0.5, 0.5, 0.5666666666666667, 0.5333333333333333, 0.5, 0.5333333333333333, 0.5, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5666666666666667, 0.5, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4, 0.5, 0.36666666666666664, 0.6333333333333333, 0.6666666666666666, 0.7333333333333333, 0.5666666666666667, 0.5666666666666667, 0.5333333333333333, 0.5333333333333333, 0.3333333333333333, 0.4, 0.6666666666666666, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.3333333333333333, 0.5, 0.5, 0.4666666666666667, 0.4, 0.4666666666666667, 0.5, 0.5666666666666667, 0.4, 0.5333333333333333, 0.43333333333333335, 0.4, 0.5, 0.5333333333333333, 0.4666666666666667, 0.6666666666666666, 0.4, 0.7333333333333333, 0.5, 0.5333333333333333, 0.43333333333333335, 0.5333333333333333, 0.5333333333333333, 0.4, 0.5, 0.6666666666666666, 0.4666666666666667, 0.5333333333333333, 0.6, 0.36666666666666664, 0.6666666666666666, 0.5, 0.4, 0.6666666666666666, 0.3333333333333333, 0.6, 0.5, 0.36666666666666664, 0.5, 0.5, 0.5, 0.4, 0.43333333333333335, 0.4666666666666667, 0.6333333333333333, 0.6, 0.5333333333333333, 0.26666666666666666, 0.5666666666666667, 0.6, 0.4666666666666667, 0.43333333333333335, 0.6, 0.36666666666666664, 0.7666666666666667, 0.5333333333333333, 0.6, 0.4666666666666667, 0.3333333333333333, 0.4, 0.4666666666666667, 0.5, 0.36666666666666664, 0.5333333333333333, 0.5, 0.4666666666666667, 0.5333333333333333, 0.5, 0.7666666666666667, 0.6, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.26666666666666666, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.4, 0.6333333333333333, 0.5666666666666667, 0.43333333333333335, 0.36666666666666664, 0.4666666666666667, 0.5333333333333333, 0.4, 0.5333333333333333, 0.6, 0.6, 0.5333333333333333, 0.6, 0.36666666666666664, 0.43333333333333335, 0.4666666666666667, 0.6333333333333333, 0.5666666666666667, 0.6, 0.5666666666666667, 0.5333333333333333, 0.5, 0.5333333333333333, 0.4666666666666667, 0.6, 0.43333333333333335, 0.5333333333333333, 0.43333333333333335, 0.4, 0.5, 0.5666666666666667, 0.5, 0.5333333333333333, 0.5666666666666667, 0.3333333333333333, 0.6666666666666666, 0.5, 0.4, 0.5666666666666667, 0.43333333333333335, 0.4666666666666667, 0.6, 0.6333333333333333, 0.5, 0.5, 0.5666666666666667, 0.5333333333333333, 0.4, 0.5, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.3333333333333333, 0.5, 0.4666666666666667, 0.36666666666666664, 0.43333333333333335, 0.4666666666666667, 0.5, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.3333333333333333, 0.4666666666666667, 0.6, 0.7333333333333333, 0.43333333333333335, 0.6333333333333333, 0.5333333333333333, 0.5333333333333333, 0.26666666666666666, 0.6, 0.36666666666666664, 0.43333333333333335, 0.36666666666666664, 0.7333333333333333, 0.5, 0.6, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.36666666666666664, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.36666666666666664, 0.7, 0.6, 0.5333333333333333, 0.5666666666666667, 0.6, 0.5666666666666667, 0.43333333333333335, 0.4, 0.4666666666666667, 0.5333333333333333, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4, 0.3, 0.5, 0.5, 0.7, 0.5333333333333333, 0.4, 0.4666666666666667, 0.6666666666666666, 0.4666666666666667, 0.5, 0.5333333333333333, 0.5, 0.5666666666666667, 0.5666666666666667, 0.5, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.3, 0.3333333333333333, 0.6333333333333333, 0.6, 0.4, 0.3333333333333333, 0.7, 0.5666666666666667, 0.6, 0.5, 0.4, 0.5333333333333333, 0.4666666666666667, 0.5, 0.5, 0.4666666666666667, 0.4, 0.4, 0.6, 0.5333333333333333, 0.4666666666666667, 0.5, 0.4666666666666667, 0.36666666666666664, 0.6, 0.5, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.43333333333333335, 0.4, 0.5333333333333333, 0.5333333333333333, 0.4, 0.6, 0.6, 0.36666666666666664, 0.43333333333333335, 0.36666666666666664, 0.5333333333333333, 0.5333333333333333, 0.43333333333333335, 0.5, 0.4, 0.43333333333333335, 0.5, 0.6, 0.43333333333333335, 0.4, 0.6, 0.5, 0.5, 0.43333333333333335, 0.4666666666666667, 0.36666666666666664, 0.43333333333333335, 0.6, 0.6333333333333333, 0.6, 0.7333333333333333, 0.4, 0.5, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.5, 0.5333333333333333, 0.5, 0.36666666666666664, 0.4666666666666667, 0.5, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.5, 0.4666666666666667, 0.6, 0.5666666666666667, 0.4, 0.43333333333333335, 0.3333333333333333, 0.4666666666666667, 0.5666666666666667, 0.23333333333333334, 0.5333333333333333, 0.3333333333333333, 0.43333333333333335, 0.5, 0.5, 0.6, 0.5666666666666667, 0.6666666666666666, 0.4, 0.5333333333333333, 0.3333333333333333, 0.5333333333333333, 0.5333333333333333, 0.36666666666666664, 0.4, 0.4666666666666667, 0.6, 0.6, 0.6, 0.6, 0.5, 0.5, 0.43333333333333335, 0.4666666666666667, 0.4, 0.6, 0.5, 0.5, 0.4666666666666667, 0.4, 0.43333333333333335, 0.5333333333333333, 0.5666666666666667, 0.23333333333333334, 0.5333333333333333, 0.5, 0.6, 0.7333333333333333, 0.5, 0.6666666666666666, 0.4666666666666667, 0.6333333333333333, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.4, 0.4666666666666667, 0.5666666666666667, 0.5, 0.6, 0.5, 0.5333333333333333, 0.43333333333333335, 0.3, 0.6, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.6, 0.5666666666666667, 0.6, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.5666666666666667, 0.6, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.6, 0.4666666666666667, 0.6, 0.6, 0.5, 0.4666666666666667, 0.43333333333333335, 0.36666666666666664, 0.5, 0.43333333333333335, 0.36666666666666664, 0.6666666666666666, 0.4666666666666667, 0.5333333333333333, 0.5, 0.6333333333333333, 0.36666666666666664, 0.4, 0.5, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.4666666666666667, 0.6, 0.6333333333333333, 0.5, 0.5, 0.4666666666666667, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.4666666666666667, 0.5, 0.6, 0.43333333333333335, 0.6333333333333333, 0.5666666666666667, 0.4666666666666667, 0.4, 0.5, 0.36666666666666664, 0.5, 0.4666666666666667, 0.7333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.6, 0.5, 0.5666666666666667, 0.43333333333333335, 0.4, 0.4666666666666667, 0.5333333333333333, 0.6, 0.6, 0.6, 0.5333333333333333, 0.5666666666666667, 0.4666666666666667, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.3, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5, 0.6333333333333333, 0.5, 0.5333333333333333, 0.4, 0.5, 0.5333333333333333, 0.6, 0.4, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.4, 0.4666666666666667, 0.5666666666666667, 0.36666666666666664, 0.3, 0.3333333333333333, 0.6, 0.5, 0.36666666666666664, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.6, 0.36666666666666664, 0.43333333333333335, 0.4, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.5, 0.6, 0.5666666666666667, 0.5, 0.7, 0.5, 0.5333333333333333, 0.5, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.5666666666666667, 0.4666666666666667, 0.5333333333333333, 0.4, 0.4, 0.6, 0.6, 0.6333333333333333, 0.43333333333333335, 0.5, 0.7666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.7, 0.4666666666666667, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.5, 0.5333333333333333, 0.5666666666666667, 0.36666666666666664, 0.5333333333333333, 0.5, 0.5, 0.7, 0.5333333333333333, 0.5, 0.4, 0.5333333333333333, 0.4666666666666667, 0.5333333333333333, 0.6, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.6, 0.43333333333333335, 0.5, 0.2, 0.5666666666666667, 0.43333333333333335, 0.36666666666666664, 0.3, 0.5, 0.6666666666666666, 0.6666666666666666, 0.5666666666666667, 0.5333333333333333, 0.6333333333333333, 0.5666666666666667, 0.5, 0.6, 0.4, 0.43333333333333335, 0.43333333333333335, 0.5, 0.4, 0.43333333333333335, 0.43333333333333335, 0.5, 0.5333333333333333, 0.7, 0.43333333333333335, 0.5, 0.4666666666666667, 0.6, 0.13333333333333333, 0.6, 0.4666666666666667, 0.43333333333333335, 0.5666666666666667, 0.5, 0.4, 0.4, 0.43333333333333335, 0.3, 0.36666666666666664, 0.4666666666666667, 0.36666666666666664, 0.5, 0.3333333333333333, 0.5666666666666667, 0.4666666666666667, 0.5333333333333333, 0.6333333333333333, 0.5, 0.5, 0.4, 0.4666666666666667, 0.6333333333333333, 0.6333333333333333, 0.4666666666666667, 0.5333333333333333, 0.6, 0.6666666666666666, 0.6, 0.5333333333333333, 0.6, 0.6666666666666666, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.6333333333333333, 0.43333333333333335, 0.43333333333333335, 0.5333333333333333, 0.5, 0.5, 0.4666666666666667, 0.43333333333333335, 0.6666666666666666, 0.3, 0.4666666666666667, 0.6666666666666666, 0.5666666666666667, 0.6666666666666666, 0.5666666666666667, 0.6, 0.43333333333333335, 0.3333333333333333, 0.36666666666666664, 0.6, 0.5333333333333333, 0.5, 0.5, 0.5, 0.43333333333333335, 0.7333333333333333, 0.4666666666666667, 0.6, 0.7, 0.6333333333333333, 0.7333333333333333, 0.4666666666666667, 0.6, 0.43333333333333335, 0.4666666666666667, 0.3333333333333333, 0.7, 0.6333333333333333, 0.5, 0.43333333333333335, 0.5, 0.4666666666666667, 0.5333333333333333, 0.5, 0.36666666666666664, 0.3333333333333333, 0.5666666666666667, 0.6333333333333333, 0.6, 0.6, 0.5, 0.5666666666666667, 0.5, 0.4, 0.5666666666666667, 0.4666666666666667, 0.4, 0.5, 0.5333333333333333, 0.43333333333333335, 0.5666666666666667, 0.6, 0.5, 0.4, 0.6, 0.5333333333333333, 0.43333333333333335, 0.36666666666666664, 0.6, 0.4666666666666667, 0.6, 0.5, 0.5333333333333333, 0.4666666666666667, 0.5, 0.4, 0.5666666666666667, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4, 0.4666666666666667, 0.6666666666666666, 0.4, 0.43333333333333335, 0.5333333333333333, 0.43333333333333335, 0.5, 0.4, 0.3, 0.5333333333333333, 0.4666666666666667, 0.5, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5, 0.6, 0.4, 0.43333333333333335, 0.5333333333333333, 0.5, 0.5, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.6, 0.6333333333333333, 0.43333333333333335, 0.6333333333333333, 0.4, 0.4, 0.43333333333333335, 0.5, 0.5, 0.5, 0.5666666666666667, 0.4666666666666667, 0.6333333333333333, 0.5, 0.5333333333333333, 0.23333333333333334, 0.43333333333333335, 0.7, 0.4666666666666667, 0.5, 0.5333333333333333, 0.5333333333333333, 0.4, 0.4, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.4666666666666667, 0.43333333333333335, 0.5, 0.6333333333333333, 0.5333333333333333, 0.36666666666666664, 0.5333333333333333, 0.43333333333333335, 0.5333333333333333, 0.6, 0.4, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.43333333333333335, 0.5, 0.5333333333333333, 0.4666666666666667, 0.36666666666666664, 0.5, 0.5666666666666667, 0.6, 0.4666666666666667, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.6, 0.4, 0.43333333333333335, 0.5, 0.36666666666666664, 0.6333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5666666666666667, 0.5, 0.4, 0.4666666666666667, 0.43333333333333335, 0.6666666666666666, 0.5333333333333333, 0.5666666666666667, 0.6333333333333333, 0.4666666666666667, 0.5, 0.7333333333333333, 0.4666666666666667, 0.5666666666666667, 0.4, 0.4666666666666667, 0.3, 0.5666666666666667, 0.6, 0.36666666666666664, 0.43333333333333335, 0.5666666666666667, 0.3333333333333333, 0.6, 0.5, 0.5333333333333333, 0.7333333333333333, 0.3333333333333333, 0.3333333333333333, 0.36666666666666664, 0.6666666666666666, 0.5, 0.5333333333333333, 0.4, 0.43333333333333335, 0.5666666666666667, 0.5, 0.4, 0.43333333333333335, 0.3333333333333333, 0.5666666666666667, 0.4, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.4666666666666667, 0.6, 0.4, 0.6, 0.5333333333333333, 0.6, 0.36666666666666664, 0.4666666666666667, 0.5, 0.5, 0.6, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.6333333333333333, 0.6, 0.5666666666666667, 0.7, 0.5666666666666667, 0.4666666666666667, 0.3333333333333333, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.4, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.6, 0.36666666666666664, 0.5666666666666667, 0.36666666666666664, 0.5, 0.4666666666666667, 0.43333333333333335, 0.4, 0.3333333333333333, 0.5333333333333333, 0.6333333333333333, 0.5, 0.6333333333333333, 0.6333333333333333, 0.6, 0.3333333333333333, 0.4, 0.4, 0.5, 0.43333333333333335, 0.6, 0.5, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.4666666666666667, 0.4666666666666667, 0.3, 0.6, 0.4666666666666667, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.43333333333333335, 0.4, 0.43333333333333335, 0.6666666666666666, 0.43333333333333335, 0.5333333333333333, 0.3333333333333333, 0.23333333333333334, 0.4, 0.4, 0.6, 0.4, 0.43333333333333335, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.5333333333333333, 0.5333333333333333, 0.5, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.7333333333333333, 0.5333333333333333, 0.6, 0.43333333333333335, 0.4666666666666667, 0.3333333333333333, 0.7333333333333333, 0.6333333333333333, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.7, 0.3, 0.4666666666666667, 0.4, 0.5666666666666667, 0.5, 0.6333333333333333, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.6, 0.4666666666666667, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5, 0.5666666666666667, 0.36666666666666664, 0.43333333333333335, 0.3, 0.4666666666666667, 0.36666666666666664, 0.43333333333333335, 0.26666666666666666, 0.6666666666666666, 0.5333333333333333, 0.3333333333333333, 0.4, 0.4666666666666667, 0.4666666666666667, 0.5, 0.5333333333333333, 0.4666666666666667, 0.3, 0.6333333333333333, 0.3333333333333333, 0.4666666666666667, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.6333333333333333, 0.5333333333333333, 0.5333333333333333, 0.3, 0.4, 0.5, 0.36666666666666664, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.5, 0.5, 0.6666666666666666, 0.4, 0.6, 0.6, 0.43333333333333335, 0.43333333333333335, 0.5, 0.3, 0.5333333333333333, 0.6, 0.5333333333333333, 0.43333333333333335, 0.36666666666666664, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4666666666666667, 0.5, 0.7333333333333333, 0.4, 0.6, 0.6, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5, 0.6666666666666666, 0.5333333333333333, 0.6, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4666666666666667, 0.5, 0.4666666666666667, 0.43333333333333335, 0.4666666666666667, 0.5, 0.43333333333333335, 0.5333333333333333, 0.36666666666666664, 0.3333333333333333, 0.6, 0.5, 0.5333333333333333, 0.36666666666666664, 0.4666666666666667, 0.5666666666666667, 0.43333333333333335, 0.5, 0.5, 0.5333333333333333, 0.5333333333333333, 0.5666666666666667, 0.4, 0.4666666666666667, 0.3333333333333333, 0.5666666666666667, 0.36666666666666664, 0.6, 0.6, 0.5333333333333333, 0.3333333333333333, 0.5, 0.23333333333333334, 0.5333333333333333, 0.36666666666666664, 0.6666666666666666, 0.4, 0.6, 0.4666666666666667, 0.6, 0.5666666666666667, 0.4, 0.6, 0.5, 0.43333333333333335, 0.6333333333333333, 0.4666666666666667, 0.6, 0.43333333333333335, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.4, 0.5333333333333333, 0.5666666666666667, 0.6333333333333333, 0.5333333333333333, 0.6, 0.6666666666666666, 0.3, 0.43333333333333335, 0.5, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.6666666666666666, 0.43333333333333335, 0.3, 0.43333333333333335, 0.26666666666666666, 0.5666666666666667, 0.6, 0.43333333333333335, 0.5333333333333333, 0.43333333333333335, 0.5, 0.5666666666666667, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4, 0.5666666666666667, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5, 0.36666666666666664, 0.43333333333333335, 0.5, 0.5333333333333333, 0.5, 0.5, 0.6, 0.5666666666666667, 0.6, 0.5333333333333333, 0.6, 0.5, 0.4, 0.6333333333333333, 0.3333333333333333, 0.5666666666666667, 0.43333333333333335, 0.6666666666666666, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5, 0.3333333333333333, 0.43333333333333335, 0.5, 0.5666666666666667, 0.43333333333333335, 0.5666666666666667, 0.6333333333333333, 0.3333333333333333, 0.5333333333333333, 0.4666666666666667, 0.5666666666666667, 0.4, 0.6, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.43333333333333335, 0.5333333333333333, 0.3, 0.6, 0.5666666666666667, 0.43333333333333335, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.6333333333333333, 0.5333333333333333, 0.5333333333333333, 0.4, 0.4, 0.43333333333333335, 0.43333333333333335, 0.6333333333333333, 0.4, 0.5333333333333333, 0.36666666666666664, 0.3, 0.5666666666666667, 0.5, 0.4, 0.5, 0.6, 0.43333333333333335, 0.5, 0.3333333333333333, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.4, 0.5333333333333333, 0.4, 0.5666666666666667, 0.5333333333333333, 0.5666666666666667, 0.7333333333333333, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.7, 0.5, 0.5333333333333333, 0.6, 0.43333333333333335, 0.5666666666666667, 0.5, 0.6, 0.43333333333333335, 0.5333333333333333, 0.4666666666666667, 0.43333333333333335, 0.5, 0.6666666666666666, 0.3333333333333333, 0.5, 0.4666666666666667, 0.5, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.5, 0.5666666666666667, 0.43333333333333335, 0.6, 0.5, 0.7333333333333333, 0.6, 0.5333333333333333, 0.6, 0.5333333333333333, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.5, 0.4, 0.36666666666666664, 0.5333333333333333, 0.43333333333333335, 0.4666666666666667, 0.5, 0.5, 0.43333333333333335, 0.4666666666666667, 0.5666666666666667, 0.4, 0.6333333333333333, 0.36666666666666664, 0.5333333333333333, 0.6, 0.4666666666666667, 0.6333333333333333, 0.43333333333333335, 0.6, 0.4666666666666667, 0.5333333333333333, 0.4666666666666667, 0.6, 0.6333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5, 0.5333333333333333, 0.4666666666666667, 0.5666666666666667, 0.5, 0.3, 0.6, 0.43333333333333335, 0.4666666666666667, 0.6, 0.5333333333333333, 0.5, 0.5, 0.5333333333333333, 0.4, 0.5333333333333333, 0.5333333333333333, 0.6333333333333333, 0.5333333333333333, 0.5, 0.5, 0.4666666666666667, 0.43333333333333335, 0.5, 0.26666666666666666, 0.4666666666666667, 0.4666666666666667, 0.4, 0.43333333333333335, 0.4, 0.5333333333333333, 0.5333333333333333, 0.6666666666666666, 0.5333333333333333, 0.5666666666666667, 0.5333333333333333, 0.6666666666666666, 0.5333333333333333, 0.5333333333333333, 0.4666666666666667, 0.36666666666666664, 0.5333333333333333, 0.5, 0.3333333333333333, 0.6333333333333333, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.4666666666666667, 0.5333333333333333, 0.6333333333333333, 0.3, 0.4666666666666667, 0.6, 0.5, 0.5333333333333333, 0.5333333333333333, 0.3333333333333333, 0.36666666666666664, 0.5333333333333333, 0.6666666666666666, 0.4, 0.5666666666666667, 0.4, 0.6666666666666666, 0.26666666666666666, 0.6333333333333333, 0.43333333333333335, 0.5, 0.3, 0.5, 0.5333333333333333, 0.43333333333333335, 0.43333333333333335, 0.5666666666666667, 0.5333333333333333, 0.6666666666666666, 0.4666666666666667, 0.5, 0.5, 0.36666666666666664, 0.5, 0.3333333333333333, 0.3, 0.5666666666666667, 0.5, 0.4666666666666667, 0.5, 0.43333333333333335, 0.4, 0.4666666666666667, 0.6, 0.4666666666666667, 0.6333333333333333, 0.5, 0.4, 0.43333333333333335, 0.6, 0.4, 0.4666666666666667, 0.4666666666666667, 0.6666666666666666, 0.4666666666666667, 0.5, 0.6666666666666666, 0.4, 0.43333333333333335, 0.4666666666666667, 0.5]

```
df = pd.DataFrame({'a': one_sample})
df.head()
```

      a

      0
      0

      1
      1

      2
      1

      3
      1

      4
      0

```
df.a.hist();
```

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

What does the Central Limit Theorem State? That no matter the initial distribution of the population, the distribution of sample means taken will approximate a normal distribution as $n \rightarrow \infty$.

This has very important implications for hypothesis testing and is precisely the reason why the t-distribution begins to approximate the normal distribution as our sample size increases.

## Standard Error of the Mean

What does it mean to "estimate"? the Population mean?

```
import numpy as np
import pandas as pd

lambda_heights = np.random.uniform(4,6.5, size=2000)
print(len(lambda_heights))
lambda_heights
```

    2000

    array([4.51572466, 6.28356165, 5.74660261, ..., 4.02088121, 5.68035051,
           4.58423192])

```
print("Population Mean:", lambda_heights.mean())
print("Population Standard Deviation:", lambda_heights.std())
```

    Population Mean: 5.265856045117739
    Population Standard Deviation: 0.7158986145354737

```
population = pd.DataFrame({'heights': lambda_heights})
print(population.shape)
population.head()
```

    (2000, 1)

      heights

      0
      4.515725

      1
      6.283562

      2
      5.746603

      3
      4.647367

      4
      5.055953

```
sample = population.sample(100)
print(sample.shape)
sample.head()
```

    (100, 1)

      heights

      69
      5.397222

      544
      5.582838

      1285
      5.448180

      524
      5.178870

      280
      4.684905

```
print("Sample Mean 1:", sample['heights'].mean())
```

    Sample Mean 1: 5.328376748609253

```
sample = population.sample(100)
print(sample.shape)
sample.head()
```

    (100, 1)

      heights

      1122
      4.531799

      1502
      5.109466

      1423
      5.608430

      120
      5.754977

      686
      4.754457

```
print("Sample Mean 2:", sample['heights'].mean())
```

    Sample Mean 2: 5.230470707607443

## Build and Interpret a Confidence Interval

```
coinflips_100 = np.random.binomial(n=1, p=.5, size=100)

sample_std = np.std(coinflips_100)
print("sample standard deviation:", sample_std)
sample_size = len(coinflips_100)
print("sample size:", sample_size)
```

    sample standard deviation: 0.4950757517794625
    sample size: 100

```
standard_error = sample_std / (sample_size**(.5))

print("standard error:", standard_error)
```

    standard error: 0.04950757517794625

```
from scipy import stats

stderr = stats.sem(coinflips_100, ddof=0)
stderr
```

    0.04950757517794625

### What confidence level do we want our confidence interval to represent?

95% confidence Interval? 99% confidence interval?

```
t = stats.t.ppf(.975 , sample_size-1)
```

```
sample_mean = coinflips_100.mean()
```

```
confidence_interval = (sample_mean - t*stderr, sample_mean + t*stderr)

margin_of_error = t*stderr

print("Sample Mean", sample_mean)
print("Margin of Error:", margin_of_error)
print("Confidence Interval:", confidence_interval)
```

    Sample Mean 0.43
    Margin of Error: 0.09823376989617144
    Confidence Interval: (0.33176623010382855, 0.5282337698961714)

```
confidence_interval[0]
```

    0.33176623010382855

```
confidence_interval[1]
```

    0.5282337698961714

## Graphically Represent a Confidence Interval

```
import seaborn as sns

sns.kdeplot(coinflips_100)
plt.axvline(x=confidence_interval[0], color='red')
plt.axvline(x=confidence_interval[1], color='red')
plt.axvline(x=sample_mean, color='k');
```

## Relationship between Confidence Intervals and T-tests

Confidence Interval == Bounds of statistical significance for our t-test

A sample mean that falls inside of our confidence interval will "FAIL TO REJECT" our null hypothesis

A sample mean that falls outside of our confidence interval will "REJECT" our null hypothesis

```
from scipy.stats import t, ttest_1samp
```

```
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.36666666666666664, 0.6, 0.4666666666666667, 0.4, 0.5, 0.5666666666666667, 0.4, 0.5666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5333333333333333, 0.4666666666666667, 0.5, 0.7333333333333333, 0.36666666666666664, 0.6333333333333333, 0.5666666666666667, 0.5, 0.6, 0.36666666666666664, 0.5333333333333333, 0.5666666666666667, 0.5, 0.43333333333333335, 0.6333333333333333, 0.4, 0.6, 0.23333333333333334, 0.6333333333333333, 0.5666666666666667, 0.3, 0.43333333333333335, 0.36666666666666664, 0.6333333333333333, 0.4, 0.4666666666666667, 0.43333333333333335, 0.43333333333333335, 0.6, 0.5333333333333333, 0.5666666666666667, 0.4666666666666667, 0.6333333333333333, 0.5666666666666667, 0.5666666666666667, 0.6333333333333333, 0.5, 0.6333333333333333, 0.43333333333333335, 0.6, 0.43333333333333335, 0.43333333333333335, 0.43333333333333335, 0.5333333333333333, 0.36666666666666664, 0.6666666666666666, 0.6, 0.5666666666666667, 0.4666666666666667, 0.5, 0.5, 0.7333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5666666666666667, 0.5666666666666667, 0.4666666666666667, 0.36666666666666664, 0.4666666666666667, 0.4, 0.43333333333333335, 0.4666666666666667, 0.3333333333333333, 0.4666666666666667, 0.6666666666666666, 0.5666666666666667, 0.5, 0.6, 0.5, 0.5333333333333333, 0.36666666666666664, 0.6666666666666666, 0.4, 0.43333333333333335, 0.5, 0.4, 0.4, 0.5333333333333333, 0.5333333333333333, 0.5333333333333333, 0.6, 0.4666666666666667, 0.6666666666666666, 0.6333333333333333, 0.4666666666666667, 0.4666666666666667, 0.5333333333333333, 0.4, 0.36666666666666664, 0.5666666666666667]

```
# 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.4852859432008737, 0.5240473901324597)

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

# 95% confidence interval
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.4852859432008737, 0.5240473901324597)

A null hypothesis that's just inside of our confidence interval == fail to reject

```
ttest_1samp(coinflip_means, .471714)
```

    Ttest_1sampResult(statistic=3.3737254397556526, pvalue=0.0010597598838256272)

A null hypothesis that's just outside of our confidence interval == reject

```
ttest_1samp(coinflip_means, .471713)
```

    Ttest_1sampResult(statistic=3.373827820709339, pvalue=0.0010594068333503433)

```
def confidence_interval(data, confidence=0.95):
  """
  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)
```

## Run a $\chi^{2}$ Test "by hand" (Using Numpy)

```
df = pd.read_csv('https://raw.githubusercontent.com/ryanleeallred/datasets/master/adult.csv', na_values=" ?")
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

```
df.columns

```

    Index(['age', 'workclass', 'fnlwgt', 'education', 'education-num',
           'marital-status', 'occupation', 'relationship', 'race', 'sex',
           'capital-gain', 'capital-loss', 'hours-per-week', 'country', 'salary'],
          dtype='object')

```
df.describe()
```

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

      count
      32561.000000
      3.256100e+04
      32561.000000
      32561.000000
      32561.000000
      32561.000000

      mean
      38.581647
      1.897784e+05
      10.080679
      1077.648844
      87.303830
      40.437456

      std
      13.640433
      1.055500e+05
      2.572720
      7385.292085
      402.960219
      12.347429

      min
      17.000000
      1.228500e+04
      1.000000
      0.000000
      0.000000
      1.000000

      25%
      28.000000
      1.178270e+05
      9.000000
      0.000000
      0.000000
      40.000000

      50%
      37.000000
      1.783560e+05
      10.000000
      0.000000
      0.000000
      40.000000

      75%
      48.000000
      2.370510e+05
      12.000000
      0.000000
      0.000000
      45.000000

      max
      90.000000
      1.484705e+06
      16.000000
      99999.000000
      4356.000000
      99.000000

```
df.describe(exclude='number')
```

      workclass
      education
      marital-status
      occupation
      relationship
      race
      sex
      country
      salary

      count
      30725
      32561
      32561
      30718
      32561
      32561
      32561
      31978
      32561

      unique
      8
      16
      7
      14
      6
      5
      2
      41
      2

      top
      Private
      HS-grad
      Married-civ-spouse
      Prof-specialty
      Husband
      White
      Male
      United-States
      <=50K

      freq
      22696
      10501
      14976
      4140
      13193
      27816
      21790
      29170
      24720

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

df.head()
```

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

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

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

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

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

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

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

     Male      21790
     Female    10771
    Name: sex, dtype: int64

```
df['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

```
df = df.sort_values(by='hours_per_week_categories', ascending=True)

df.head()
```

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

      31290
      55
      Self-emp-not-inc
      41938
      Bachelors
      13
      Married-civ-spouse
      Prof-specialty
      Wife
      White
      Female
      0
      0
      8
      United-States
      <=50K
      0-9

      5172
      32
      NaN
      134886
      HS-grad
      9
      Married-civ-spouse
      NaN
      Wife
      White
      Female
      0
      0
      2
      United-States
      >50K
      0-9

      22928
      17
      NaN
      332666
      10th
      6
      Never-married
      NaN
      Own-child
      White
      Female
      0
      0
      4
      United-States
      <=50K
      0-9

      7902
      35
      Private
      359131
      Bachelors
      13
      Married-civ-spouse
      Prof-specialty
      Wife
      White
      Female
      7298
      0
      8
      NaN
      >50K
      0-9

      6604
      41
      Private
      406603
      HS-grad
      9
      Never-married
      Other-service
      Not-in-family
      White
      Male
      0
      0
      6
      Iran
      <=50K
      0-9

```
contingency_table = pd.crosstab(df['sex'], df['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

```
femalecount = contingency_table.iloc[0][0:6].values
femalecount
```

    array([ 235,  671, 1287, 1914, 5636, 1028])

```
malecount = contingency_table.iloc[1][0:6].values
malecount
```

    array([  223,   575,  1105,  1753, 12700,  5434])

```
import matplotlib.pyplot as plt
import seaborn as sns

#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]), ('Female', 'Male'))
plt.xlabel('Hours per Week Worked')
plt.ylabel('Count')
plt.show()
```

## 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
col_sums = contingency_table.iloc[2, 0:6].values

print(row_sums)
print(col_sums)
```

    [10771 21790]
    [  458  1246  2392  3667 18336  6462]

```
total = contingency_table.loc['All','All']
total
```

    32561

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

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

    (2, 6)
    [[  151.50388502   412.16995793   791.26046497  1213.02346365
       6065.44811277  2137.59411566]
     [  306.49611498   833.83004207  1600.73953503  2453.97653635
      12270.55188723  4324.40588434]]

```
observed = pd.crosstab(df['sex'], df['hours_per_week_categories']).values
print(observed.shape)
observed
```

    (2, 6)

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

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

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

    Chi-Squared: 2287.190943926107

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

    Degrees of Freedom: 5

## Run a $\chi^{2}$ Test using Scipy

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

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]]

Null Hypothesis: Hours worked per week bins is **independent** of sex.

Due to a p-value of 0, we REJECT the null hypothesis that hours worked per week and sex are independent, and conclude that there is an association between hours worked per week and sex.

## Assignment - Build a confidence interval

A confidence interval refers to a neighborhood around some point estimate, the size of which is determined by the desired p-value. For instance, we might say that 52% of Americans prefer tacos to burritos, with a 95% confidence interval of +/- 5%.

52% (0.52) is the point estimate, and +/- 5% (the interval $[0.47, 0.57]$) is the confidence interval. "95% confidence" means a p-value $\leq 1 - 0.95 = 0.05$.

In this case, the confidence interval includes $0.5$ - which is the natural null hypothesis (that half of Americans prefer tacos and half burritos, thus there is no clear favorite). So in this case, we could use the confidence interval to report that we've failed to reject the null hypothesis.

But providing the full analysis with a confidence interval, including a graphical representation of it, can be a helpful and powerful way to tell your story. Done well, it is also more intuitive to a layperson than simply saying "fail to reject the null hypothesis" - it shows that in fact the data does *not* give a single clear result (the point estimate) but a whole range of possibilities.

How is a confidence interval built, and how should it be interpreted? It does *not* mean that 95% of the data lies in that interval - instead, the frequentist interpretation is "if we were to repeat this experiment 100 times, we would expect the average result to lie in this interval ~95 times."

For a 95% confidence interval and a normal(-ish) distribution, you can simply remember that +/-2 standard deviations contains 95% of the probability mass, and so the 95% confidence interval based on a given sample is centered at the mean (point estimate) and has a range of +/- 2 (or technically 1.96) standard deviations.

Different distributions/assumptions (90% confidence, 99% confidence) will require different math, but the overall process and interpretation (with a frequentist approach) will be the same.

Your assignment - using the data from the prior module ([congressional voting records](https://archive.ics.uci.edu/ml/datasets/Congressional+Voting+Records)):

### Confidence Intervals:
1. Generate and numerically represent a confidence interval
2. Graphically (with a plot) represent the confidence interval
3. Interpret the confidence interval - what does it tell you about the data and its distribution?

### Chi-squared tests:
4. Take a dataset that we have used in the past in class that has **categorical** variables. Pick two of those categorical variables and run a chi-squared tests on that data
  - By hand using Numpy
  - In a single line using Scipy

Stretch goals:

1. Write a summary of your findings, mixing prose and math/code/results. *Note* - yes, this is by definition a political topic. It is challenging but important to keep your writing voice *neutral* and stick to the facts of the data. Data science often involves considering controversial issues, so it's important to be sensitive about them (especially if you want to publish).
2. Apply the techniques you learned today to your project data or other data of your choice, and write/discuss your findings here.
3. Refactor your code so it is elegant, readable, and can be easily run for all issues.

---

### Confidence Intervals:
1. Generate and numerically represent a confidence interval
2. Graphically (with a plot) represent the confidence interval
3. Interpret the confidence interval - what does it tell you about the data and its distribution?

```
df1 = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/voting-records/house-votes-84.data', header=None)
```

```
df = df.replace('n',0)
```

```
df = df.replace('y',1)
```

---

### Chi-squared tests:
4. Take a dataset that we have used in the past in class that has **categorical** variables. Pick two of those categorical variables and run a chi-squared tests on that data
  - By hand using Numpy
  - In a single line using Scipy

```
df = pd.read_csv('https://raw.githubusercontent.com/ryanleeallred/datasets/master/adult.csv', na_values=" ?")
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

```
df.describe()
```

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

      count
      32561.000000
      3.256100e+04
      32561.000000
      32561.000000
      32561.000000
      32561.000000

      mean
      38.581647
      1.897784e+05
      10.080679
      1077.648844
      87.303830
      40.437456

      std
      13.640433
      1.055500e+05
      2.572720
      7385.292085
      402.960219
      12.347429

      min
      17.000000
      1.228500e+04
      1.000000
      0.000000
      0.000000
      1.000000

      25%
      28.000000
      1.178270e+05
      9.000000
      0.000000
      0.000000
      40.000000

      50%
      37.000000
      1.783560e+05
      10.000000
      0.000000
      0.000000
      40.000000

      75%
      48.000000
      2.370510e+05
      12.000000
      0.000000
      0.000000
      45.000000

      max
      90.000000
      1.484705e+06
      16.000000
      99999.000000
      4356.000000
      99.000000

```
df.describe(exclude='number')
```

      workclass
      education
      marital-status
      occupation
      relationship
      race
      sex
      country
      salary

      count
      30725
      32561
      32561
      30718
      32561
      32561
      32561
      31978
      32561

      unique
      8
      16
      7
      14
      6
      5
      2
      41
      2

      top
      Private
      HS-grad
      Married-civ-spouse
      Prof-specialty
      Husband
      White
      Male
      United-States
      <=50K

      freq
      22696
      10501
      14976
      4140
      13193
      27816
      21790
      29170
      24720

```
cut_points = [0, 9, 19, 29, 39, 49, 100]
label_names = ['0-9', '10-19', '20-29', '30-39', '40-49', '50+']
df['hours_per_week_catergories'] = pd.cut(df['hours-per-week'], cut_points, labels=label_names)

```

```
df.head()
```

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

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

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

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

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

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

```
df['education'].value_counts()

```

     HS-grad         10501
     Some-college     7291
     Bachelors        5355
     Masters          1723
     Assoc-voc        1382
     11th             1175
     Assoc-acdm       1067
     10th              933
     7th-8th           646
     Prof-school       576
     9th               514
     12th              433
     Doctorate         413
     5th-6th           333
     1st-4th           168
     Preschool          51
    Name: education, dtype: int64

```
df['hours_per_week_catergories'].value_counts()
```

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

```
df = df.sort_values(by='hours_per_week_catergories', ascending=True)
df.head()
```

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

      31290
      55
      Self-emp-not-inc
      41938
      Bachelors
      13
      Married-civ-spouse
      Prof-specialty
      Wife
      White
      Female
      0
      0
      8
      United-States
      <=50K
      0-9

      20909
      77
      Self-emp-not-inc
      71676
      Some-college
      10
      Widowed
      Adm-clerical
      Not-in-family
      White
      Female
      0
      1944
      1
      United-States
      <=50K
      0-9

      28127
      28
      Local-gov
      207213
      Assoc-acdm
      12
      Never-married
      Craft-repair
      Own-child
      White
      Male
      0
      0
      5
      United-States
      <=50K
      0-9

      8472
      75
      NaN
      173064
      Bachelors
      13
      Married-civ-spouse
      NaN
      Husband
      White
      Male
      0
      0
      6
      United-States
      <=50K
      0-9

      19616
      40
      NaN
      170649
      Some-college
      10
      Married-civ-spouse
      NaN
      Husband
      White
      Male
      0
      0
      8
      United-States
      <=50K
      0-9

```

```

```
contingency_table = pd.crosstab(df['education'], df['hours_per_week_catergories'], margins=True)
```

```
contingency_table
```

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

      education

      10th
      22
      74
      96
      134
      500
      107
      933

      11th
      44
      147
      187
      137
      539
      121
      1175

      12th
      6
      37
      65
      55
      225
      45
      433

      1st-4th
      2
      7
      21
      26
      89
      23
      168

      5th-6th
      3
      14
      22
      38
      220
      36
      333

      7th-8th
      14
      31
      48
      92
      364
      97
      646

      9th
      9
      22
      50
      61
      316
      56
      514

      Assoc-acdm
      24
      26
      76
      121
      606
      214
      1067

      Assoc-voc
      15
      22
      55
      159
      873
      258
      1382

      Bachelors
      67
      120
      237
      479
      2992
      1460
      5355

      Doctorate
      8
      6
      17
      30
      162
      190
      413

      HS-grad
      116
      275
      658
      1229
      6487
      1736
      10501

      Masters
      21
      37
      64
      162
      880
      559
      1723

      Preschool
      0
      4
      6
      10
      26
      5
      51

      Prof-school
      7
      15
      19
      55
      193
      287
      576

      Some-college
      100
      409
      771
      879
      3864
      1268
      7291

      All
      458
      1246
      2392
      3667
      18336
      6462
      32561

```
hsgrad_count = contingency_table.iloc[11][0:6].values
hsgrad_count
```

    array([ 116,  275,  658, 1229, 6487, 1736])

```
bachelors_count = contingency_table.iloc[9][0:6].array
bachelors_count
```

    <PandasArray>
    [67, 120, 237, 479, 2992, 1460]
    Length: 6, dtype: int64

```
import matplotlib.pyplot as plt
import seaborn as sns
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, hsgrad_count, .55, color='#d62728')
p2 = plt.bar(categories, bachelors_count, .55, bottom=hsgrad_count)
plt.legend((p2[0], p1[0]), ('High School Grad', 'Bachelors Degree'))
plt.xlabel('Hours per Week Worked')
plt.ylabel('Count')
plt.show()
```

# Run a  𝜒2  Test using Scipy

```

```

```

```

## Resources

- [Interactive visualize the Chi-Squared test](https://homepage.divms.uiowa.edu/~mbognar/applets/chisq.html)
- [Calculation of Chi-Squared test statistic](https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test)
- [Visualization of a confidence interval generated by R code](https://commons.wikimedia.org/wiki/File:Confidence-interval.svg)
- [Expected value of a squared standard normal](https://math.stackexchange.com/questions/264061/expected-value-calculation-for-squared-normal-distribution) (it's 1 - which is why the expected value of a Chi-Squared with $n$ degrees of freedom is $n$, as it's the sum of $n$ squared standard normals)

```

```