<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Probabilistic Programming in Python
Author 
Step1:  Summary 
Step2:  Summary 
Random variables are abstract objects. Methods are available for operating on them algebraically. The probability
distributions, methods for drawing random samples, statistical metrics, are transparently propagated.
1.3 More PPL coolness 
Step3:  Summary
Conditioning, which is the first step towards inference, is done automatically. A wide variety of conditions can be used. P(A | B) translates to a.given(b).
1.4 Reasoning under uncertainty "PPL style"
Replace with medical example
<ASSISTANT_TASK:>
Python Code:
from lea import *
# the canonical random variable : a fair coin
faircoin = Lea.fromVals('Head', 'Tail')
# toss the coin a few times
faircoin.random(10)
# Amitabh Bachan's coin from Sholay
sholaycoin = Lea.fromVals('Head', 'Head')
# Amitabh always wins (and, heroically, sacrifices himself for Dharamendra!)
sholaycoin.random(10)
# more reasonably, a biased coin
biasedcoin = Lea.fromValFreqs(('Head', 1), ('Tail', 2))
# toss it a few times
biasedcoin.random(10)
# random variables with more states : a fair die
die = Lea.fromVals(1, 2, 3, 4, 5, 6)
# throw the die a few times
die.random(20)
# Lea does standard statistics
# die.mean
# die.mode
# die.var
# die.entropy
Explanation: Probabilistic Programming in Python
Author : Ronojoy Adhikari 
Email  : rjoy@imsc.res.in | Web    : www.imsc.res.in/~rjoy
Github : www.github.com/ronojoy | Twitter: @phyrjoy
Part 1 : Introduction to Lea
1.1 : Getting started
End of explanation
# Lets create a pair of dies
die1 = die.clone()
die2 = die.clone()
# The throw of dice
dice = die1 + die2
dice
dice.random(10)
dice.mean
dice.mode
print dice.histo()
Explanation: Summary : Random variables are objects. N samples are drawn from the random variable y using
Python
y.random(N)
Standard statistical measures of distributions are provided. Nothing extraordinary (yet!).
Exercise : Write a Python code that produces the same output as the following Lea code
Python
Lea.fromVals('rain', 'sun').random(20)
How many lines do you need in Python ? 
1.2 : Now some PPL coolness
End of explanation
## We can create a new distribution, conditioned on our state of knowledge : P(sum | sum <= 6)
conditionalDice = dice.given(dice<=6)
## What is our best guess for the result of the throw ? 
conditionalDice.mode
## Conditioning can be done in many ways : suppose we know that the first die came up 3. 
dice.given(die1 == 3)
## Conditioning can be done in still more ways : suppose we know that **either** of the two dies came up 3
dice.given((die1 == 3) | (die2 == 3))
Explanation: Summary 
Random variables are abstract objects. Methods are available for operating on them algebraically. The probability
distributions, methods for drawing random samples, statistical metrics, are transparently propagated.
1.3 More PPL coolness : conditioning
"You just threw two dice. Can you guess the result ?"
"Here's a tip : the sum is less than 6"
End of explanation
# Species is a random variable with states "common" and "rare", with probabilities determined by the population. Since
# are only two states, species states are, equivalently, "rare" and "not rare". Species can be a Boolean!
rare = Lea.boolProb(1,1000)
# Similarly, pattern is either "present" or "not present". It too is a Boolean, but, its probability distribution
# is conditioned on "rare" or "not rare"
patternIfrare = Lea.boolProb(98, 100)
patternIfNotrare = Lea.boolProb(5, 100)
# Now, lets build the conditional probability table for P(pattern | species)
pattern = Lea.buildCPT((rare , patternIfrare), ( ~rare , patternIfNotrare))
# Sanity check : do we get what we put in ? 
pattern.given(rare)
# Finally, our moment of truth : Bayesian inference - what is P(rare | pattern )? 
rare.given(pattern)
# And, now some show off : what is the probability of being rare and having a pattern ? 
rare & pattern
# All possible outcomes
Lea.cprod(rare,pattern)
Explanation: Summary
Conditioning, which is the first step towards inference, is done automatically. A wide variety of conditions can be used. P(A | B) translates to a.given(b).
1.4 Reasoning under uncertainty "PPL style"
Replace with medical example
End of explanation
<END_TASK>