<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Chapter 4
Examples and Exercises from Think Stats, 2nd Edition
http
Step1:  Examples
One more time, I'll load the data from the NSFG.
Step2:  And compute the distribution of birth weight for first babies and others.
Step3:  We can plot the PMFs on the same scale, but it is hard to see if there is a difference.
Step4:  PercentileRank computes the fraction of scores less than or equal to your_score.
Step5:  If this is the list of scores.
Step6:  If you got the 88, your percentile rank is 80.
Step7:  Percentile takes a percentile rank and computes the corresponding percentile.
Step8:  The median is the 50th percentile, which is 77.
Step9:  Here's a more efficient way to compute percentiles.
Step10:  Let's hope we get the same answer.
Step11:  The Cumulative Distribution Function (CDF) is almost the same as PercentileRank.  The only difference is that the result is 0-1 instead of 0-100.
Step12:  In this list
Step13:  We can evaluate the CDF for various values
Step14:  Here's an example using real data, the distribution of pregnancy length for live births.
Step15:  Cdf provides Prob, which evaluates the CDF; that is, it computes the fraction of values less than or equal to the given value.  For example, 94% of pregnancy lengths are less than or equal to 41.
Step16:  Value evaluates the inverse CDF; given a fraction, it computes the corresponding value.  For example, the median is the value that corresponds to 0.5.
Step17:  In general, CDFs are a good way to visualize distributions.  They are not as noisy as PMFs, and if you plot several CDFs on the same axes, any differences between them are apparent.
Step18:  In this example, we can see that first babies are slightly, but consistently, lighter than others.
We can use the CDF of birth weight to compute percentile-based statistics.
Step19:  Again, the median is the 50th percentile.
Step20:  The interquartile range is the interval from the 25th to 75th percentile.
Step21:  We can use the CDF to look up the percentile rank of a particular value.  For example, my second daughter was 10.2 pounds at birth, which is near the 99th percentile.
Step22:  If we draw a random sample from the observed weights and map each weigh to its percentile rank.
Step23:  The resulting list of ranks should be approximately uniform from 0-1.
Step24:  That observation is the basis of Cdf.Sample, which generates a random sample from a Cdf.  Here's an example.
Step25:  This confirms that the random sample has the same distribution as the original data.
Exercises
Exercise
Step26:  Exercise
<ASSISTANT_TASK:>
Python Code:
import numpy as np
from os.path import basename, exists
def download(url):
    filename = basename(url)
    if not exists(filename):
        from urllib.request import urlretrieve
        local, _ = urlretrieve(url, filename)
        print("Downloaded " + local)
download("https://github.com/AllenDowney/ThinkStats2/raw/master/code/thinkstats2.py")
download("https://github.com/AllenDowney/ThinkStats2/raw/master/code/thinkplot.py")
download("https://github.com/AllenDowney/ThinkStats2/raw/master/code/nsfg.py")
download("https://github.com/AllenDowney/ThinkStats2/raw/master/code/first.py")
download("https://github.com/AllenDowney/ThinkStats2/raw/master/code/2002FemPreg.dct")
download(
    "https://github.com/AllenDowney/ThinkStats2/raw/master/code/2002FemPreg.dat.gz"
)
import thinkstats2
import thinkplot
Explanation: Chapter 4
Examples and Exercises from Think Stats, 2nd Edition
http://thinkstats2.com
Copyright 2016 Allen B. Downey
MIT License: https://opensource.org/licenses/MIT
End of explanation
import first
live, firsts, others = first.MakeFrames()
Explanation: Examples
One more time, I'll load the data from the NSFG.
End of explanation
first_wgt = firsts.totalwgt_lb
first_wgt_dropna = first_wgt.dropna()
print('Firsts', len(first_wgt), len(first_wgt_dropna))
 
other_wgt = others.totalwgt_lb
other_wgt_dropna = other_wgt.dropna()
print('Others', len(other_wgt), len(other_wgt_dropna))
first_pmf = thinkstats2.Pmf(first_wgt_dropna, label='first')
other_pmf = thinkstats2.Pmf(other_wgt_dropna, label='other')
Explanation: And compute the distribution of birth weight for first babies and others.
End of explanation
width = 0.4 / 16
# plot PMFs of birth weights for first babies and others
thinkplot.PrePlot(2)
thinkplot.Hist(first_pmf, align='right', width=width)
thinkplot.Hist(other_pmf, align='left', width=width)
thinkplot.Config(xlabel='Weight (pounds)', ylabel='PMF')
Explanation: We can plot the PMFs on the same scale, but it is hard to see if there is a difference.
End of explanation
def PercentileRank(scores, your_score):
    count = 0
    for score in scores:
        if score <= your_score:
            count += 1
    percentile_rank = 100.0 * count / len(scores)
    return percentile_rank
Explanation: PercentileRank computes the fraction of scores less than or equal to your_score.
End of explanation
t = [55, 66, 77, 88, 99]
Explanation: If this is the list of scores.
End of explanation
PercentileRank(t, 88)
Explanation: If you got the 88, your percentile rank is 80.
End of explanation
def Percentile(scores, percentile_rank):
    scores.sort()
    for score in scores:
        if PercentileRank(scores, score) >= percentile_rank:
            return score
Explanation: Percentile takes a percentile rank and computes the corresponding percentile.
End of explanation
Percentile(t, 50)
Explanation: The median is the 50th percentile, which is 77.
End of explanation
def Percentile2(scores, percentile_rank):
    scores.sort()
    index = percentile_rank * (len(scores)-1) // 100
    return scores[int(index)]
Explanation: Here's a more efficient way to compute percentiles.
End of explanation
Percentile2(t, 50)
Explanation: Let's hope we get the same answer.
End of explanation
def EvalCdf(sample, x):
    count = 0.0
    for value in sample:
        if value <= x:
            count += 1
    prob = count / len(sample)
    return prob
Explanation: The Cumulative Distribution Function (CDF) is almost the same as PercentileRank.  The only difference is that the result is 0-1 instead of 0-100.
End of explanation
t = [1, 2, 2, 3, 5]
Explanation: In this list
End of explanation
EvalCdf(t, 0), EvalCdf(t, 1), EvalCdf(t, 2), EvalCdf(t, 3), EvalCdf(t, 4), EvalCdf(t, 5)
Explanation: We can evaluate the CDF for various values:
End of explanation
cdf = thinkstats2.Cdf(live.prglngth, label='prglngth')
thinkplot.Cdf(cdf)
thinkplot.Config(xlabel='Pregnancy length (weeks)', ylabel='CDF', loc='upper left')
Explanation: Here's an example using real data, the distribution of pregnancy length for live births.
End of explanation
cdf.Prob(41)
Explanation: Cdf provides Prob, which evaluates the CDF; that is, it computes the fraction of values less than or equal to the given value.  For example, 94% of pregnancy lengths are less than or equal to 41.
End of explanation
cdf.Value(0.5)
Explanation: Value evaluates the inverse CDF; given a fraction, it computes the corresponding value.  For example, the median is the value that corresponds to 0.5.
End of explanation
first_cdf = thinkstats2.Cdf(firsts.totalwgt_lb, label='first')
other_cdf = thinkstats2.Cdf(others.totalwgt_lb, label='other')
thinkplot.PrePlot(2)
thinkplot.Cdfs([first_cdf, other_cdf])
thinkplot.Config(xlabel='Weight (pounds)', ylabel='CDF')
Explanation: In general, CDFs are a good way to visualize distributions.  They are not as noisy as PMFs, and if you plot several CDFs on the same axes, any differences between them are apparent.
End of explanation
weights = live.totalwgt_lb
live_cdf = thinkstats2.Cdf(weights, label='live')
Explanation: In this example, we can see that first babies are slightly, but consistently, lighter than others.
We can use the CDF of birth weight to compute percentile-based statistics.
End of explanation
median = live_cdf.Percentile(50)
median
Explanation: Again, the median is the 50th percentile.
End of explanation
iqr = (live_cdf.Percentile(25), live_cdf.Percentile(75))
iqr
Explanation: The interquartile range is the interval from the 25th to 75th percentile.
End of explanation
live_cdf.PercentileRank(10.2)
Explanation: We can use the CDF to look up the percentile rank of a particular value.  For example, my second daughter was 10.2 pounds at birth, which is near the 99th percentile.
End of explanation
sample = np.random.choice(weights, 100, replace=True)
ranks = [live_cdf.PercentileRank(x) for x in sample]
Explanation: If we draw a random sample from the observed weights and map each weigh to its percentile rank.
End of explanation
rank_cdf = thinkstats2.Cdf(ranks)
thinkplot.Cdf(rank_cdf)
thinkplot.Config(xlabel='Percentile rank', ylabel='CDF')
Explanation: The resulting list of ranks should be approximately uniform from 0-1.
End of explanation
resample = live_cdf.Sample(1000)
thinkplot.Cdf(live_cdf)
thinkplot.Cdf(thinkstats2.Cdf(resample, label='resample'))
thinkplot.Config(xlabel='Birth weight (pounds)', ylabel='CDF')
Explanation: That observation is the basis of Cdf.Sample, which generates a random sample from a Cdf.  Here's an example.
End of explanation
# Solution
first_cdf.PercentileRank(8.5)
# Solution
other_cdf.PercentileRank(8.5)
Explanation: This confirms that the random sample has the same distribution as the original data.
Exercises
Exercise: How much did you weigh at birth? If you don’t know, call your mother or someone else who knows. Using the NSFG data (all live births), compute the distribution of birth weights and use it to find your percentile rank. If you were a first baby, find your percentile rank in the distribution for first babies. Otherwise use the distribution for others. If you are in the 90th percentile or higher, call your mother back and apologize.
End of explanation
# Solution
t = np.random.random(1000)
# Solution
pmf = thinkstats2.Pmf(t)
thinkplot.Pmf(pmf, linewidth=0.1)
thinkplot.Config(xlabel='Random variate', ylabel='PMF')
# Solution
cdf = thinkstats2.Cdf(t)
thinkplot.Cdf(cdf)
thinkplot.Config(xlabel='Random variate', ylabel='CDF')
Explanation: Exercise: The numbers generated by numpy.random.random are supposed to be uniform between 0 and 1; that is, every value in the range should have the same probability.
Generate 1000 numbers from numpy.random.random and plot their PMF.  What goes wrong?
Now plot the CDF. Is the distribution uniform?
End of explanation
<END_TASK>