HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Monty hall python simulation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
hallpythonsimulationmonty

Problem

I have the following code that simulates the monty hall problem (see google for more details). I used sets to do it but is there a more intuitive or efficient way to do it?

import random as r
from sets import Set
def montysim(N):
  K = 0
  for i in range(N):
    s = Set([1,2,3])
    doorstoswitch = Set([1,2,3])
    cardoor = r.randint(1,3)
    chosendoor = r.randint(1,3)
    doorstoswitch.remove(chosendoor)
    if chosendoor != cardoor:
        s.remove(chosendoor)
    s.remove(cardoor)

    montydoor = r.sample(s, 1)[0]
    doorstoswitch.remove(montydoor)
    newdoor = r.sample(doorstoswitch, 1)[0]
    if newdoor == cardoor:
        K+=1
  return float(K) / float(N)

print montysim(10000)

Solution

Two things stick out to me:

First, Python has an official style-guide, PEP8. It recommends consistently using 4 spaces as indentation (you use a mix of two and four). It also recommends using lower_case_with_underscores for names.

Second, the sets module has been deprecated. You can just use the built-in set, instead of sets.Set.

import random

def monty_sim(n):
    k = 0
    for i in range(n):
        s = set([1, 2, 3])
        doors_to_switch = set([1, 2, 3])
        car_door = random.randint(1, 3)
        chosen_door = random.randint(1, 3)
        doors_to_switch.remove(chosen_door)
        if chosen_door != car_door:
            s.remove(chosen_door)
        s.remove(car_door)

        monty_door = random.sample(s, 1)[0]
        doors_to_switch.remove(monty_door)
        newdoor = random.sample(doors_to_switch, 1)[0]
        if newdoor == car_door:
            k += 1
      return float(k) / float(n)

if __name__ == "__main__":
    print monty_sim(10000)


This even comes with a nice speed-boost for free!

In [2]: %timeit montysim(10000)
10 loops, best of 3: 109 ms per loop

In [4]: %timeit monty_sim(10000)
10 loops, best of 3: 54 ms per loop

Code Snippets

import random


def monty_sim(n):
    k = 0
    for i in range(n):
        s = set([1, 2, 3])
        doors_to_switch = set([1, 2, 3])
        car_door = random.randint(1, 3)
        chosen_door = random.randint(1, 3)
        doors_to_switch.remove(chosen_door)
        if chosen_door != car_door:
            s.remove(chosen_door)
        s.remove(car_door)

        monty_door = random.sample(s, 1)[0]
        doors_to_switch.remove(monty_door)
        newdoor = random.sample(doors_to_switch, 1)[0]
        if newdoor == car_door:
            k += 1
      return float(k) / float(n)

if __name__ == "__main__":
    print monty_sim(10000)
In [2]: %timeit montysim(10000)
10 loops, best of 3: 109 ms per loop

In [4]: %timeit monty_sim(10000)
10 loops, best of 3: 54 ms per loop

Context

StackExchange Code Review Q#160567, answer score: 10

Revisions (0)

No revisions yet.