Let's add another dunder method to the class, but this time we'll add one that accepts two arguments.
import random
class Dice:
def __init__(self, probs):
self.probs = probs
self.expected_value = sum(i * p for i, p in self.probs.items())
@classmethod
def from_sides(cls, n=6):
return cls({i: 1/n for i in range(1, n + 1)})
def roll(self, n=1):
sides = list(self.probs.keys())
probabilities = list(self.probs.values())
return random.choices(sides, weights=probabilities, k=n)
def __len__(self):
return len(self.probs)
def __add__(self, other):
if isinstance(other, (float, int)):
other = Dice({other: 1})
new_probs = {}
for s1, p1 in self.probs.items():
for s2, p2 in other.probs.items():
new_key = s1 + s2
if new_key not in new_probs:
new_probs[new_key] = 0
new_probs[new_key] += p1 * p2
return Dice(new_probs)
There's a few things to note about this new __add__
method:
- Note how this method has two arguments. That's because it is used when we want to combine two objects.
- The first argument is
self
and the second argument isother
. This is becauseself
refers to the object on the left of the operator andother
refers to the object on the right of the operator. - The internal code might take a while to appreciate if you're not familiar with probability theory. Feel free to ignore that for now and come back to it later if that is the case.
You should now be able to combine two dice objects with the +
operator and get a new object that has the combined probabilities.
dice = Dice({1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6, 6: 1/6})
(dice + dice).probs