<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Data
Chance Models
Step3:  Uniform Sample
A uniform sample is a sample drawn at random without replacements
Step4:  Dice
Step5:  Coin
Step7:  We can simulate the act of rolling dice by just pulling out rows
Step9:  Modeling the Law of Averages
The law of averages states that as the number of draws increases, so too does the difference between the expected average versus the observed average. 
$$ Chance \ Error = Observed - Expected $$
In the case of coin tosses, as the number of tosses goes up, so does the absolute chance error.
<ASSISTANT_TASK:>
Python Code:
%pylab inline
# Import libraries
from __future__ import absolute_import, division, print_function
# Ignore warnings
import warnings
warnings.filterwarnings('ignore')
import sys
sys.path.append('tools/')
import numpy as np
import pandas as pd
import math
# Graphing Libraries
import matplotlib.pyplot as pyplt
import seaborn as sns
sns.set_style("white")  
# Configure for presentation
np.set_printoptions(threshold=50, linewidth=50)
import matplotlib as mpl
mpl.rc('font', size=16)
from IPython.display import display
Explanation: Data
Chance Models
End of explanation
def sample(num_sample, top):
    
    Create a random sample from a table
    
    Attributes
    ---------
    num_sample: int
    top: dataframe
    
    Returns a random subset of table index
    
    df_index = []
    for i in np.arange(0, num_sample, 1):
        # pick randomly from the whole table
        sample_index = np.random.randint(0, len(top))
        # store index
        df_index.append(sample_index)
        
    return df_index
def sample_no_replacement(num_sample, top):
    
    Create a random sample from a table
    
    Attributes
    ---------
    num_sample: int
    top: dataframe
    
    Returns a random subset of table index
    
    df_index = []
    lst = np.arange(0, len(top), 1)
    for i in np.arange(0, num_sample, 1):
        # pick randomly from the whole table
        sample_index = np.random.choice(lst)
        lst = np.setdiff1d(lst,[sample_index])
        df_index.append(sample_index)
            
    return df_index
Explanation: Uniform Sample
A uniform sample is a sample drawn at random without replacements
End of explanation
die = pd.DataFrame()
die["Face"] = [1,2,3,4,5,6]
die
Explanation: Dice
End of explanation
coin = pd.DataFrame()
coin["Face"] = [1,2]
coin
Explanation: Coin
End of explanation
index_ = sample(3, die)
df = die.ix[index_, :]
df
index_ = sample(1, coin)
df = coin.ix[index_, :]
df
def sum_draws( n, box ):
    
    Construct histogram for the sum of n draws from a box with replacement
    
    Attributes
    -----------
    n: int (number of draws)
    box: dataframe (the box model)
    
    data = numpy.zeros(shape=(n,1))
    if n > 0:
        for i in range(n):
            index_ = np.random.randint(0, len(box), n)
            df = box.ix[index_, :]
            data[i] = df.Content.sum()
        bins = np.arange(data.min()-0.5, data.max()+1, 1) 
        pyplt.hist(data, bins=bins, normed=True)
        pyplt.ylabel('percent per unit')
        pyplt.xlabel('Number on ticket')
        pyplt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.);
    else:
        raise ValueError('n has to be greater than 0')
    
        
box = pd.DataFrame()
box["Content"] = [0,1,2,3,4]
pyplt.rcParams['figure.figsize'] = (4, 3)
sum_draws(100, box)
pyplt.rcParams['figure.figsize'] = (4, 3)
low, high = box.Content.min() - 0.5, box.Content.max() + 1
bins = np.arange(low, high, 1) 
box.plot.hist(bins=bins, normed=True)
pyplt.ylabel('percent per unit')
pyplt.xlabel('Number on ticket')
pyplt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.);
sum_draws(1000, box)
Explanation: We can simulate the act of rolling dice by just pulling out rows
End of explanation
def number_of_heads( n, box ):
    
    The number of heads in n tosses
    
    Attributes
    -----------
    n: int (number of draws)
    box: dataframe (the coin box model)
    
    data = numpy.zeros(shape=(n,1))
    if n > 0:
        value = np.random.randint(0, len(box), n)
        data = value
    else:
        raise ValueError('n has to be greater than 0')
        
    return data.sum()
box = pd.DataFrame()
box["Content"] = [0,1]
low, high, step = 100, 10000, 2
length = len(range(low, high, step))
num_tosses = numpy.zeros(shape=(length,1))
num_heads = numpy.zeros(shape=(length,1))
chance_error = numpy.zeros(shape=(length,1))
percentage_difference = numpy.zeros(shape=(length,1))
i= 0
for n in range(low, high, step):
    observed = number_of_heads(n, box)
    expected = n//2
    num_tosses[i] = n
    num_heads[i] = observed
    chance_error[i] = math.fabs(expected - observed)
    percentage_difference[i] = math.fabs(((num_heads[i] / num_tosses[i]) * 100) - 50)
    i += 1
    
avg_heads = pd.DataFrame(index= range(low, high, step) )
avg_heads['num_tosses'] = num_tosses
avg_heads['num_heads'] = num_heads
avg_heads['chance_error'] = chance_error
avg_heads['percentage_difference'] = percentage_difference
avg_heads.reset_index(inplace=True)
pyplt.rcParams['figure.figsize'] = (8, 3)
pyplt.plot(avg_heads.chance_error, 'ro', markersize=1)
pyplt.ylim(-50, 500)
pyplt.title('Modeling the Law of Averages')
pyplt.ylabel('Difference between \nObserved versus Expected')
pyplt.xlabel('Number of Tosses');
pyplt.rcParams['figure.figsize'] = (8, 4)
ax = pyplt.plot(avg_heads.percentage_difference, 'bo', markersize=1)
pyplt.ylim(-5, 20)
pyplt.ylabel('The Percentage Difference\n Between Observed and Expected')
pyplt.xlabel('Number of Tosses');
pyplt.rcParams['figure.figsize'] = (4, 3)
Explanation: Modeling the Law of Averages
The law of averages states that as the number of draws increases, so too does the difference between the expected average versus the observed average. 
$$ Chance \ Error = Observed - Expected $$
In the case of coin tosses, as the number of tosses goes up, so does the absolute chance error.
End of explanation
<END_TASK>