IHE Python course, 2017

Three-doors quiz (famous statistical fallacy)

T.N.Olsthoorn, April 18, 2017

The famous three doors fallacy goes like this. You participate in a television game and won. The only thing you still have to do is choose one out of three doors behing one of which is the prize to be won. After choosing your door, the quizmaster opens one of the two other doors. He shows that the prize is not behind the door he opened. Now you're given the opportunity to change your mind. What do you decide? Stick with your door, choose randomly one of the two closed doors? Or switch to the other closed door? Does it make any difference and if so, why?

Below this problem is coded in Python. First in pieces, step by step and easy to checke each step. At the end everything is put together in one cell, so that the game can be run any number of times, while the scores of each strategy are accumulated. Guess beforehand what the outcomes of the strategies "stick", "choose" or "change" will be after thousand trials.

First part, step by step


In [43]:
import random

verbose = True

N = 1 if verbose else 10000

verbose = True

Three strategies will be explored

a) The candicate sticks with his/her initial door

b) The candiates chooses anew from the twoo remaining doors

c) The candidats switches to the other of the two remaining doors, the one he / she did not choose initially


In [44]:
# here are the scores (total number of successes) of the three strategies:
str_a, str_b, str_c = 0, 0, 0  # initially all three zero

# here are the doors, a list (we could also use a set)
# it's easy to switch between list and set using list() and set() functions
doors = [1, 2, 3]

So we have three doors, numbered 1, 2 and 3

The prize door will be chosen randomly from these three doors. It will not been known to anyone at this point.

Then the candicate chooses hes /her door from the three doors.

Then we remove the chosen door from the doors. So that doors now only contains the two unchosen doors.

If verbose, we show the differnt doors (only for ourselves to check the procedure).


In [45]:
prize_door


Out[45]:
2

In [46]:
prize_door = random.choice(doors) # door with prize, chosen randomly

cand_door = random.choice(doors) # the candidate's choice

Then the quiz master steps in. He / she is informed behind the scenes which door has the prize and also knows the choise of the candicate. He / she then opens the door that was neither chosen nor has the prize.


In [47]:
quizm_door = set(doors) - {prize_door, cand_door}

# note that the quizm_door is a set (with one item) no list, that's ok for now
# but we may need to use *quizm_door to unpack this time as an int, see below

if verbose:
    print("cand_door   = ", cand_door)
    print("prize_door  = ", prize_door)
    print("quizm_door  = ",  *quizm_door)  # use * to unpack, because quizm_door is a set


cand_door   =  2
prize_door  =  3
quizm_door  =  1

In [48]:
closed_doors = set(doors) - quizm_door  # closed_doors is a set, not a list, that's fine

if verbose:
    print("closed_doors =", closed_doors)


closed_doors = {2, 3}

Now, finally it's up to the candidate to make his / her decision. That is choose a stragegy, either stick, choose, or stick


In [49]:
stick = cand_door
choose = random.choice(list(closed_doors))
switch = closed_doors - {cand_door}

if verbose:
    print("prize = {}, stick = {}, choose = {}, switch = {}".format(prize_door, stick, choose, switch))


prize = 3, stick = 2, choose = 3, switch = {3}

And we score the successes for each strategy


In [50]:
# strategy 1: stick with the original door
if stick == prize_door:
    str_stick += 1

# strategy 2: choose anew from the two remaining doors
if choose  == prize_door:
    str_choose += 1

# strategy 3: choose the other closed door
if switch == prize_door:  # we use set logic { }
    str_switch += 1

Put all together in a single loop to do N trials


In [51]:
import random

verbose=False

N = 10 if verbose else 1000

if verbose:
    print((" {:>8s}"*8).format(
            "trial", "prize", "stick", "choose", "switch",
            "str_stick", "str_choose", "str_switch"))

# intialize scores for the 3 scenarios
str_stick, str_choose, str_switch= 0, 0, 0  # initially all three zero

for trial in range(N):
    
    doors      = [1, 2, 3]
    prize_door = random.choice(doors)
    cand_door  = random.choice(doors)
    quizm_door = random.choice(list(set(doors) - {prize_door, cand_door}))

    closed_doors = set(doors) - {quizm_door}  # closed_doors is a set

    #print(doors, prize_door, cand_door, quizm_door, closed_doors, cand_door)

    # apply strategy, all three
    stick  = cand_door
    choose = random.choice(list(closed_doors))
    switch = list(closed_doors - {cand_door})[0]

    # score result of each strategy
    if stick  == prize_door:    str_stick += 1
    if choose == prize_door:    str_choose += 1
    if switch == prize_door:    str_switch += 1

    if verbose:
        print((" {:8d}" * 8).format(
              trial,
              prize_door,
              stick,
              choose,
              switch,
              str_stick,
              str_choose,
              str_switch))

print("Total")
print((" {:>8s}"*8).format("trial", "prize", "stick", "choose", "switch", "str_stick", "str_choose", "str_switch"))
print(((" {:8}") * 8).format(N, "_", "_", "_", "_", str_stick, str_choose, str_switch))


Total
    trial    prize    stick   choose   switch str_stick str_choose str_switch
        5 _        _        _        _               3        1        2

In [ ]:


In [ ]: