from __future__ import print_function, division

"""
Explanation: Exercise from Think Stats, 2nd Edition (thinkstats2.com)<br>
Allen Downey
End of explanation
"""


import scipy.stats

%matplotlib inline

"""
Explanation: Exercise 5.1
<tt>scipy.stats</tt> contains objects that represent analytic distributions
End of explanation
"""


mu = 178
sigma = 7.7
dist = scipy.stats.norm(loc=mu, scale=sigma)
type(dist)

"""
Explanation: For example <tt>scipy.stats.norm</tt> represents a normal distribution.
End of explanation
"""


dist.mean(), dist.std()

"""
Explanation: A "frozen random variable" can compute its mean and standard deviation.
End of explanation
"""


dist.cdf(mu-sigma)

"""
Explanation: It can also evaluate its CDF.  How many people are more than one standard deviation below the mean?  About 16%
End of explanation
"""


low = dist.cdf(177.8)    # 5'10"
high = dist.cdf(185.4)   # 6'1"
low, high, high-low

"""
Explanation: How many people are between 5'10" and 6'1"?
End of explanation
"""


alpha = 1.7
xmin = 1
dist = scipy.stats.pareto(b=alpha, scale=xmin)
dist.median()

"""
Explanation: Exercise 5.2
<tt>scipy.stats.pareto</tt> represents a pareto distribution.  In Pareto world, the distribution of human heights has parameters alpha=1.7 and xmin=1 meter.  So the shortest person is 100 cm and the median is 150.
End of explanation
"""


dist.mean()

"""
Explanation: What is the mean height in Pareto world?
End of explanation
"""


dist.cdf(dist.mean())

"""
Explanation: What fraction of people are shorter than the mean?
End of explanation
"""


(1 - dist.cdf(1000)) * 7e9
dist.sf(1000) * 7e9

"""
Explanation: Out of 7 billion people, how many do we expect to be taller than 1 km?  You could use <tt>dist.cdf</tt> or <tt>dist.sf</tt>.
End of explanation
"""


dist.sf(600000) * 7e9            # find the height that yields about 1 person

"""
Explanation: How tall do we expect the tallest person to be?
End of explanation
"""


import random
import thinkstats2
import thinkplot

"""
Explanation: Exercise 5.3
Generate a sample from a Weibull distribution and plot it using a transform that makes a Weibull distribution look like a straight line.
End of explanation
"""


sample = [random.weibullvariate(2, 1) for _ in range(1000)]
cdf = thinkstats2.Cdf(sample)
thinkplot.Cdf(cdf, transform='weibull')
thinkplot.Show(legend=False)

"""
Explanation: thinkplot.Cdf provides a transform that makes the CDF of a Weibull distribution look like a straight line.
End of explanation
"""


cdf.Random()

"""
Explanation: Make a random selection from <tt>cdf</tt>.
End of explanation
"""


cdf.Sample(10)

"""
Explanation: Draw a random sample from <tt>cdf</tt>.
End of explanation
"""


prs = [cdf.PercentileRank(x) for x in cdf.Sample(1000)]
pr_cdf = thinkstats2.Cdf(prs)
thinkplot.Cdf(pr_cdf)

"""
Explanation: Draw a random sample from <tt>cdf</tt>, then compute the percentile rank for each value, and plot the distribution of the percentile ranks.
End of explanation
"""


values = [random.random() for _ in range(1000)]
pmf = thinkstats2.Pmf(values)
thinkplot.Pmf(pmf, linewidth=0.1)

"""
Explanation: Generate 1000 random values using <tt>random.random()</tt> and plot their PMF.
End of explanation
"""


cdf = thinkstats2.Cdf(values)
thinkplot.Cdf(cdf)
thinkplot.Show()

"""
Explanation: Assuming that the PMF doesn't work very well, try plotting the CDF instead.
End of explanation
"""


import analytic

df = analytic.ReadBabyBoom()
diffs = df.minutes.diff()
cdf = thinkstats2.Cdf(diffs, label='actual')

n = len(diffs)
lam = 44.0 / 24 / 60
sample = [random.expovariate(lam) for _ in range(n)]
model = thinkstats2.Cdf(sample, label='model')
    
thinkplot.PrePlot(2)
thinkplot.Cdfs([cdf, model], complement=True)
thinkplot.Show(title='Time between births',
                xlabel='minutes',
                ylabel='CCDF',
                yscale='log')

lam, np.mean(sample)

"""
Explanation: Exercise 5.4
End of explanation
"""


from mystery import *

funcs = [uniform_sample, triangular_sample, expo_sample,
             gauss_sample, lognorm_sample, pareto_sample,
             weibull_sample, gumbel_sample]

for i in range(len(funcs)):
    sample = funcs[i](1000)
    filename = 'mystery%d.dat' % i
    print(filename, funcs[i].__name__)

"""
Explanation: Exercise 5.5
Here is the code from mystery.py that generates the random data files:
End of explanation
"""


