Monty Hall and the Python #2: Testing out our simulation

Published July 23, 2021, 2:56 p.m.

Last time we explained what the Monty Hall problem is and we began to program a simulation of it.  This time we will finish a simulation of the problem and test it out.

To do that we need to add the ability to switch our answer once Monty Hall has revealed the wrong choice.  Let's get started!

At the bottom of our existing code we will start by defining a variable we will call "switch".  We will make it a boolean variable (meaning it has the value of 'True' or 'False').  Then we will ask for some more user input so that we can determine if the user wants to switch their answer or not.  If the user indicates 'yes', then we will change the value of the variable 'switch' to the value 'True'.  By defining the variable as 'False' from the start we are simply establishing a default value so that we avoid a coding situation where we try to use the variable before we have actually defined a value for it.  The code then looks like this:

switch = False
switch_answer = input("Do you want to switch your answer? ")
if 'y' in switch_answer.lower():
    switch = True

Notice that what we have done here is to assume that the user will use some form of 'Yes' to indicate that they want to switch their answer.  Then we use the '.lower()' extension to force the input into lower case letters.  Finally we test whether or not the input has the letter 'y' in it (lower case).  So now, the user may type 'YES', 'Yes', 'yes', 'y', 'Y', or some other way of saying 'yes' and all of those inputs will contain a lower case 'y' when the '.lower()' extension is applied to them.

If the use says 'yes', then we change value of switch to 'True'.

So now we have more input to work with.  If the user wants to switch their answer then we need to make sure we applie the correct new answer.

if switch:
    new_answer =

So what will our 'new_answer' be?  Well, it cannot be our original answer, and it cannot be the answer that Monty Hall has revealed.  With only three choices there is only one other choice that it could be.  Move the cursor back above what we just started typing and let us define what our new_answer could be.

remaining_choices = [c for c in choices if not(c == my_choice or c == reveal)]

For convenience later, we will establish a list now of the remaining choices (even though at this point there is only one).  The code above will create a list from the list of original choices as long as the value is not (a) what we chose originally (aka 'my_choice') or (b) not what Monty Hall revealed (aka 'reveal').  Notice the logic we say 'not' to negate what is in the parentheses.  Then we use a logical 'or' so that the value in parentheses is 'True' if the value is (a) or (b).

Now we return to our 'if switch' logic.  If the value of switch is 'True' then we want to pick from our 'remaining_choices' list.  If the value of switch is 'False', then we want to keep our original answer.  However, after this choice, we want to be able to use a new variable that we started to call 'new_answer'.  That will be convenient to just make sure that the new vaiable 'new_answer' is the one to test for correctness.

if switch:
    new_answer = remaining_choices[0]
else:
    new_answer = my_choice

It is important, at this point, to add that '[0]' to remaining_choices in order to pick the first value from the list.

Now for some 'razzle-dazzle'.  (Not really, just go with it).

We can have python print to the screen the final state of affairs.  Were we correct?  Tell us python!

Using a similar framework as we have above, we can define a variable string that assumes we are incorrect, then test our final answer agains the correct answer and if we are correct we can change our string to say 'correct'.  With all that sorted out, we can print what the correct choice was and whether or not we chose correctly:

how_did_you_do = "incorrect"
if new_answer == correct_choice:
    how_did_you_do = "correct"
    
print(f"Correct choice was {correct_choice}.")
print(f"My choice was {new_answer} and I was {how_did_you_do}.")

We use 'f-strings' to simply add our answers to the final print statements.

Now we save and run our code in the terminal.  Voila!  We have a simple, working, Monty Hall problem simulator. 

Next time we will put our code into a loop so that we can run it some number of times and tally how often we were correct and how often we were incorrect.  Thanks for watching and see you in the next tutorial!

Your final code should look like the following:

import sys, os
from random import sample

choices = ['A', 'B', 'C']

correct_choice = sample(choices, 1)[0]

wrong_choices = [c for c in choices if c != correct_choice]

my_choice = input(f"Choose one of the following {choices}. ")

if my_choice not in choices:
    sys.exit("You messed up moron!")

print(my_choice)

reveals = [c for c in wrong_choices if c != my_choice]

reveal = sample(reveals,1)[0]

print(f"Monty Hall reveals {reveal}! ")

switch = False
switch_answer = input("Do you want to switch your answer? ")
if 'y' in switch_answer.lower():
    switch = True

remaining_choices = [c for c in choices if not(c == my_choice or c == reveal)]

if switch:
    new_answer = remaining_choices[0] 
else:
    new_answer = my_choice
    
how_did_you_do = "incorrect"
if new_answer == correct_choice:
    how_did_you_do = "correct"
    
print(f"Correct choice was {correct_choice}.")
print(f"My choice was {new_answer} and I was {how_did_you_do}.")
    
skip_nextMonty Hall and the Python #3: Collecting results from several simulations
  • Monty Hall and the Python #1: Setting up the Monty Hall Problem

  • Monty Hall and the Python #2: Testing out our simulation
    (currently viewing)
  • Monty Hall and the Python #3: Collecting results from several simulations

  • Monty Hall and the Python #4: Automating responses and running 10,000 times

  • Monty Hall and the Python #5: Expand and Understand; Monty Hall with 100 doors!

  • Monty Hall and the Python #6: Name those doors OR Generate any number of unique strings.