# Modeling the Monty Hall Problem in Python

A few weeks ago, I watched an episode of Numberphile about the Monty Hall problem. This happens to be one of my favorite little “that-doesn’t-seem-right” statistics things, and I thought it would be a great way to play with Python.

## The Problem

If you’re not familiar with the Problem, here’s the gist of it. There are three doors and you’re asked to pick one of them. Now, behind one door is an amazing prize: a new car, a bunch of money, a trip to a tropical island. You get the idea. Behind the other two doors, though, there’s something useless or just nothing. Maybe it’s a goat. Regardless, you don’t want what’s behind those other two doors.

So you pick your door and the host, Monty Hall, opens one of the two doors you didn’t pick. It’s always one of the horrible non-prizes. And now comes the stressful part of the game: Monty asks if you’d like to switch doors. Do you stick with the door you picked in the beginning or do you switch to the new door?

## Our Python Classes

While you think about that, let’s get to the code. We need a couple of things set up before we can play the game. Mostly, though, we need a door.

``````class Door(object):
prize = False
opened = False
``````

So, OK, here’s our door. By default, it’s closed (`opened = False`) and it doesn’t have a prize. Since we’ll make multiple doors for a game, I think it makes more sense to have the game pick which door has the prize than it does for the doors to decide for themselves. No one wants a sentient door.

Speaking of our game, let’s look at that object too.

``````class Game(object):
chosen_door = None
switched_doors = False

def __init__(self):
self.doors = [
Door(),
Door(),
Door()
]
# Pick a random door and give it a prize
random.choice(self.doors).prize = True
``````

We start with no doors chosen and, of course, since no doors have been chosen, the player couldn’t possibly have switched doors. Then we create three doors and randomly pick one of them to have a prize. We’re all set up to play the game.

## The Whole Game

Here’s a gist of the entire game:

The way it’s set up, you can just call `Game.play()` however many times you want to play the game. I found that playing it a small number of times, say 10–50, doesn’t yield any noticeable results but bump the number up into the hundreds or thousands and you start to see real answers.

For example, here’s what I’ve gotten when I run it:

Won & Switched Won & Stayed Lost & Switched Lost & Stayed
340 178 170 312
322 194 162 322
329 161 190 320
317 160 187 336
337 167 186 310

While this is only the results of running the script 5 times, you can see that it’s generally a 2:1 ration of winning when the player switches compared to winning when they don’t switch.

## Takeaways

My script is pretty simple. You could easily change this to have more doors or to take user input on whether or not to switch. You could also use the handy plotting techniques from Data Science Basics to make a chart showing wins and loses, switches and stays. Oh, and if the list comprehensions and uses of `filter` and `lambda` are confusing, we have a couple of workshops on those you should check out. All of the code in the gist should run in both Python 2 and Python 3.

So, what’s your decision? Will you switch doors or stick with the one you have?

Photo by Frank Müller