#!/usr/bin/python # BayesCards.py demos Bayes' rule (conditional probability) with a card deck. # Initial code 2017, hyptothesis and evidence may be functions as of 10/2019. import random import copy import types SuitToColor = { "hearts" : "red", "diamonds" : "red", "clubs" : "black", "spades" : "black" } colors = set(SuitToColor.values()) values = [str(v) for v in range(2,11)] # 2 through 10 as string values = values + ["jack", "queen", "king", "ace"] hand = None # I am using a global in case I forget to assign deal's result. deck = [] for v in values: for s in SuitToColor.keys(): deck.append((v, s, SuitToColor[s])) deckCopy = copy.copy(deck) print("There are", len(deck), "cards in the deck.") def deal(count): global deckCopy global hand deckCopy = copy.copy(deck) # In case we called deal before result = [] if count > len(deckCopy): raise ValueError("ERROR, count " + str(count) + " is too high.") for i in range(0, count): index = random.randrange(0, len(deckCopy)) result.append(deckCopy[index]) del deckCopy[index] # I am using a global in case I forget to assign deal's result. hand = result return result def cprob(thehand, hypothesis, evidence): ''' hypothesis, evidence may be string or predicate-function. ''' # https://brilliant.org/wiki/bayes-theorem/ # P(H | E) = (P(E | H) / P(E)) x P(H) # return the probability of the hypothesis, given the evidence PHC = 0.0 # P(H)'s count PEC = 0.0 # P(E)'s count PHEC = 0.0 # P(H | E)'s count PEHC = 0.0 # P(E | H)'s count for card in thehand: if ((type(evidence) == types.FunctionType and evidence(card)) or (evidence in card)): PEC += 1 if ((type(hypothesis) == types.FunctionType and hypothesis(card)) or (hypothesis in card)): PHEC += 1 if ((type(hypothesis) == types.FunctionType and hypothesis(card)) or (hypothesis in card)): PHC += 1 if ((type(evidence) == types.FunctionType and evidence(card)) or (evidence in card)): PEHC += 1 PE = PEC / len(thehand) PH = PHC / len(thehand) print("Out of", len(thehand), "cards, PE =", PE, ", PH = ", PH) result = 0.0 PEH = PEHC/PHC if PHC > 0 else None # PEH = (PHC > 0) ? PEHC/PHC : None PHE = PHEC/PEC if PEC > 0 else None # Above is the C/C++/Java syntax for # a conditional expression. if PHC == 0: print("P(H) of 0 gives multiplier of 0, tentative result of 0.") result = 0.0 if PEC == 0: print("Cannot compute P(H | E) with P(E) of 0.") result = None if PHC > 0 and PEC > 0: print("Measured P(E | H) =",PEH,",measured P(H | E) =", PHE, ", computed P(H | E) =", (PEH / PE) * PH)