<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Bayesian Statistics Made Simple
Code and exercises from my workshop on Bayesian statistics in Python.
Copyright 2016 Allen Downey
MIT License
Step1:  Working with Pmfs
Create a Pmf object to represent a six-sided die.
Step2:  A Pmf is a map from possible outcomes to their probabilities.
Step3:  Initially the probabilities don't add up to 1.
Step4:  Normalize adds up the probabilities and divides through.  The return value is the total probability before normalizing.
Step5:  Now the Pmf is normalized.
Step6:  And we can compute its mean (which only works if it's normalized).
Step7:  Random chooses a random value from the Pmf.
Step8:  thinkplot provides methods for plotting Pmfs in a few different styles.
Step9:  Exercise 1
Step10:  Exercise 2
Step11:  The cookie problem
Create a Pmf with two equally likely hypotheses.
Step12:  Update each hypothesis with the likelihood of the data (a vanilla cookie).
Step13:  Print the posterior probabilities.
Step14:  Exercise 3
Step15:  Exercise 4
Step16:  The dice problem
Create a Suite to represent dice with different numbers of sides.
Step17:  Exercise 5
Step18:  Exercise 6
Step19:  Now we can create a Dice object and update it.
Step20:  If we get more data, we can perform more updates.
Step21:  Here are the results.
Step22:  The German tank problem
The German tank problem is actually identical to the dice problem.
Step23:  Here are the posterior probabilities after seeing Tank #37.
Step24:  Exercise 7
Step26:  The Euro problem
Exercise 8
Step27:  We'll start with a uniform distribution from 0 to 100.
Step28:  Now we can update with a single heads
Step29:  Another heads
Step30:  And a tails
Step31:  Starting over, here's what it looks like after 7 heads and 3 tails.
Step32:  The maximum posterior probability is 70%, which is the observed proportion.
Here are the posterior probabilities after 140 heads and 110 tails.
Step33:  The posterior mean s about 56%
Step34:  So is the value with Maximum Aposteriori Probability (MAP).
Step35:  The posterior credible interval has a 90% chance of containing the true value (provided that the prior distribution truly represents our background knowledge).
Step37:  Swamping the prior
The following function makes a Euro object with a triangle prior.
Step38:  And here's what it looks like
Step39:  Exercise 9
<ASSISTANT_TASK:>
Python Code:
from __future__ import print_function, division
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
from thinkbayes2 import Pmf, Suite
import thinkplot
Explanation: Bayesian Statistics Made Simple
Code and exercises from my workshop on Bayesian statistics in Python.
Copyright 2016 Allen Downey
MIT License: https://opensource.org/licenses/MIT
End of explanation
d6 = Pmf()
Explanation: Working with Pmfs
Create a Pmf object to represent a six-sided die.
End of explanation
for x in [1,2,3,4,5,6]:
    d6[x] = 1
Explanation: A Pmf is a map from possible outcomes to their probabilities.
End of explanation
d6.Print()
Explanation: Initially the probabilities don't add up to 1.
End of explanation
d6.Normalize()
Explanation: Normalize adds up the probabilities and divides through.  The return value is the total probability before normalizing.
End of explanation
d6.Print()
Explanation: Now the Pmf is normalized.
End of explanation
d6.Mean()
Explanation: And we can compute its mean (which only works if it's normalized).
End of explanation
d6.Random()
Explanation: Random chooses a random value from the Pmf.
End of explanation
thinkplot.Hist(d6)
Explanation: thinkplot provides methods for plotting Pmfs in a few different styles.
End of explanation
# Solution goes here
Explanation: Exercise 1:  The Pmf object provides __add__, so you can use the + operator to compute the Pmf of the sum of two dice.
Compute and plot the Pmf of the sum of two 6-sided dice.
End of explanation
# Solution goes here
Explanation: Exercise 2: Suppose I roll two dice and tell you the result is greater than 3.
Plot the Pmf of the remaining possible outcomes and compute its mean.
End of explanation
cookie = Pmf(['Bowl 1', 'Bowl 2'])
cookie.Print()
Explanation: The cookie problem
Create a Pmf with two equally likely hypotheses.
End of explanation
cookie['Bowl 1'] *= 0.75
cookie['Bowl 2'] *= 0.5
cookie.Normalize()
Explanation: Update each hypothesis with the likelihood of the data (a vanilla cookie).
End of explanation
cookie.Print()
Explanation: Print the posterior probabilities.
End of explanation
# Solution goes here
Explanation: Exercise 3: Suppose we put the first cookie back, stir, choose again from the same bowl, and get a chocolate cookie.
Hint: The posterior (after the first cookie) becomes the prior (before the second cookie).
End of explanation
# Solution goes here
Explanation: Exercise 4: Instead of doing two updates, what if we collapse the two pieces of data into one update?
Re-initialize Pmf with two equally likely hypotheses and perform one update based on two pieces of data, a vanilla cookie and a chocolate cookie.
The result should be the same regardless of how many updates you do (or the order of updates).
End of explanation
pmf = Pmf([4, 6, 8, 12])
pmf.Print()
Explanation: The dice problem
Create a Suite to represent dice with different numbers of sides.
End of explanation
# Solution goes here
Explanation: Exercise 5: We'll solve this problem two ways.  First we'll do it "by hand", as we did with the cookie problem; that is, we'll multiply each hypothesis by the likelihood of the data, and then renormalize.
In the space below, update suite based on the likelihood of the data (rolling a 6), then normalize and print the results.
End of explanation
class Dice(Suite):
        # hypo is the number of sides on the die
        # data is the outcome
        def Likelihood(self, data, hypo):
            return 1
# Solution goes here
Explanation: Exercise 6:  Now let's do the same calculation using Suite.Update.
Write a definition for a new class called Dice that extends Suite.  Then define a method called Likelihood that takes data and hypo and returns the probability of the data (the outcome of rolling the die) for a given hypothesis (number of sides on the die).
Hint: What should you do if the outcome exceeds the hypothetical number of sides on the die?
Here's an outline to get you started:
End of explanation
dice = Dice([4, 6, 8, 12])
dice.Update(6)
dice.Print()
Explanation: Now we can create a Dice object and update it.
End of explanation
for roll in [8, 7, 7, 5, 4]:
    dice.Update(roll)
Explanation: If we get more data, we can perform more updates.
End of explanation
dice.Print()
Explanation: Here are the results.
End of explanation
class Tank(Suite):
    # hypo is the number of tanks
    # data is an observed serial number
    def Likelihood(self, data, hypo):
        if data > hypo:
            return 0
        else:
            return 1 / hypo
Explanation: The German tank problem
The German tank problem is actually identical to the dice problem.
End of explanation
tank = Tank(range(100))
tank.Update(37)
thinkplot.Pdf(tank)
tank.Mean()
Explanation: Here are the posterior probabilities after seeing Tank #37.
End of explanation
# Solution goes here
Explanation: Exercise 7:  Suppose we see another tank with serial number 17.  What effect does this have on the posterior probabilities?
Update the suite again with the new data and plot the results.
End of explanation
class Euro(Suite):
    
    def Likelihood(self, data, hypo):
         
        hypo is the prob of heads (0-100)
        data is a string, either 'H' or 'T'
        
        return 1
# Solution goes here
Explanation: The Euro problem
Exercise 8:  Write a class definition for Euro, which extends Suite and defines a likelihood function that computes the probability of the data (heads or tails) for a given value of x (the probability of heads).
Note that hypo is in the range 0 to 100.  Here's an outline to get you started.
End of explanation
euro = Euro(range(101))
thinkplot.Pdf(euro)
Explanation: We'll start with a uniform distribution from 0 to 100.
End of explanation
euro.Update('H')
thinkplot.Pdf(euro)
Explanation: Now we can update with a single heads:
End of explanation
euro.Update('H')
thinkplot.Pdf(euro)
Explanation: Another heads:
End of explanation
euro.Update('T')
thinkplot.Pdf(euro)
Explanation: And a tails:
End of explanation
euro = Euro(range(101))
for outcome in 'HHHHHHHTTT':
    euro.Update(outcome)
thinkplot.Pdf(euro)
euro.MaximumLikelihood()
Explanation: Starting over, here's what it looks like after 7 heads and 3 tails.
End of explanation
euro = Euro(range(101))
evidence = 'H' * 140 + 'T' * 110
for outcome in evidence:
    euro.Update(outcome)
    
thinkplot.Pdf(euro)
Explanation: The maximum posterior probability is 70%, which is the observed proportion.
Here are the posterior probabilities after 140 heads and 110 tails.
End of explanation
euro.Mean()
Explanation: The posterior mean s about 56%
End of explanation
euro.MAP()
Explanation: So is the value with Maximum Aposteriori Probability (MAP).
End of explanation
euro.CredibleInterval(90)
Explanation: The posterior credible interval has a 90% chance of containing the true value (provided that the prior distribution truly represents our background knowledge).
End of explanation
def TrianglePrior():
    Makes a Suite with a triangular prior.
    suite = Euro(label='triangle')
    for x in range(0, 51):
        suite[x] = x
    for x in range(51, 101):
        suite[x] = 100-x 
    suite.Normalize()
    return suite
Explanation: Swamping the prior
The following function makes a Euro object with a triangle prior.
End of explanation
euro1 = Euro(range(101), label='uniform')
euro2 = TrianglePrior()
thinkplot.Pdfs([euro1, euro2])
thinkplot.Config(title='Priors')
Explanation: And here's what it looks like:
End of explanation
# Solution goes here
Explanation: Exercise 9: Update euro1 and euro2 with the same data we used before (140 heads and 110 tails) and plot the posteriors.  How big is the difference in the means?
End of explanation
<END_TASK>