I'm pretty new to Python (I've been doing it for about 4 months, but not every day) and I've been struggling to get to grips with how to use functions and deploy them efficiently to solve problems. To test my abilities, I created the below program to simulate the Monty Hall problem. The program does the following things:
- It chooses a winning door at the start from list
door = [1,2,3].
- It then asks the user to choose a door.
- Then it checks to see if the user's guess matches the winning door.
- If the user guesses the winning door, it randomly selects one of the two remaining doors to 'open'. If, however, the user doesn't guess the winning door, it 'opens' the one remaining unpicked door.
- It then asks the user if they want to switch doors. If the user picked the correct door first time out, then sticking with that choice wins the game and switching loses. The reverse is true if the user didn't pick the correct door first time.
- Finally, it updates a running tally of wins and losses, then asks the user if he wants to play again.
The program works and the probabilities are correct (I ran it 100 times just to make sure and got 74 wins and 26 losses, which is around about what I'd expect). I'm just not sure the program is as efficient as it could be. In fact, given my relative lack of experience I'm pretty sure it isn't. Would anyone be able to tell me how good they think the code is, how I could go about improving it?
import random
win = 0
lose = 0
while True:
door = [1,2,3]
x = 0
def pick_answer():
"""Computer chooses the winning door"""
answer = random.choice(door)
return answer
a = pick_answer()
def pick_guess():
"""User guesses winning door"""
guess = int(input("Please choose a door (1-3): ").strip())
return guess
b = pick_guess()
if a == b:
def montys_door_if_a_is_b():
"""If answer = guess, pick one of the remaining doors to open"""
global x
door = [1,2,3]
door.remove(a)
x = random.choice(door)
return x
c = montys_door_if_a_is_b()
print("You chose door {}".format(b))
print("I choose door {}".format(c))
def montys_final_choice():
"""Tells user which 2 doors are now left"""
door = [1,2,3]
door.remove(x)
door.remove(a)
y = door[0]
return y
d = montys_final_choice()
print("You're left with doors {} and {}".format(b,d))
choice = input("Will you SWITCH to door {}? y/n: ".format(d))
def switch_or_stick():
"""Asks user if they want to switch. y = Lose / n = win"""
if choice == "y":
print("Bad luck. You lost. You should have stuck as you already had the right answer.")
global lose
lose = lose + 1
print("{} wins and {} losses".format(win,lose))
else:
print("Huzzah! You made the right choice by STICKING!")
global win
win = win + 1
print("{} wins and {} losses".format(win,lose))
switch_or_stick()
input("\nPress Enter to play again")
else:
def montys_door_if_a_not_b():
"""If answer != guess, remove answer & guess and 'open' the remaining door"""
door = [1,2,3]
door.remove(a)
door.remove(b)
md = door[0]
return md
e = montys_door_if_a_not_b()
print("You chose door {}".format(b))
print("I choose door {}".format(e))
def montys_final_choice_if_a_not_b():
"""Asks user to choose between answer & guess"""
door = [1,2,3]
door.remove(e)
f = montys_final_choice_if_a_not_b()
print("You're left with doors {} and {}".format(a,b))
choice = input("Will you SWITCH to door {}? y/n: ".format(a))
def switch_or_stick_redux():
"""Since answer != guess, if user sticks, he loses but if he switches he wins"""
if choice == "y":
print("HUZZAH! YOU WIN")
global win
win = win + 1
print("{} wins and {} losses".format(win,lose))
else:
print("Bad luck. You should have switched. You chose the wrong door at the start")
global lose
lose = lose + 1
print("{} wins and {} losses".format(win,lose))
switch_or_stick_redux()
input("\nPress Enter to play again")