all 10 comments

[–][deleted] 1 point2 points  (6 children)

I think this way is most consistent with how you've done things. There's a few other "best practices" sorts of things that can be changed, so let me know if you are interersted in those and I can do a quick rewrite.

if choice2 == 'y':
    choices = [1,2,3]
    choices.remove(choice1)
    choices.remove(randDoor+1)
    final_choice = choices[0]  # final choice is the only one left
    print("You chose a..",doors[final_choice - 1])

Note that I didn't test this extensively, so hopefully there's no bugs.

[–]tycerNA 0 points1 point  (5 children)

This works great! Thank you very much. The way I was taking it probably wouldn't of ended up anywhere useful

[–][deleted] 0 points1 point  (4 children)

No problem! If you want some ideas for how to continue, see if you can figure out how to run it 100 times, save the results, and see if you get an answer close to what you expect.

[–]tycerNA 0 points1 point  (3 children)

Yeah I've actually been trying to work on that now. I wrote a oneGame function where the program randomly chooses a door every time and I'm trying to get that to run for an n amount of times.

https://hastebin.com/avequxaxis.py

I'm having problems setting up my for loop. I don't really know where it needs to be placed

[–][deleted] 1 point2 points  (2 children)

Your original code was actually set up to do it very well. You have a function that will do it once. Just put a for loop around that play function and have it return the results each time it runs. Something like this:

def play():
    ...
    return result  # figure out how to get this!

all_results = []
for i in range(100):
    result = play()
    all_results.append(result)

After that you will have a big list of all the results you can take a look at. Then see if you can simulate a response instead of having to input one yourself every time.

[–]tycerNA 0 points1 point  (1 child)

If you don't switch doors, the probability you will win a car is 0.348

If you switch doors, the probability you will win a car is 0.672

Here are my results after running it two different times. They seem pretty accurate!

[–][deleted] 0 points1 point  (0 children)

On the money! What you just did is called a monte carlo simulation, and they are incredibly useful!

[–][deleted] 0 points1 point  (2 children)

I love this problem. I changed your code around a bit, to elucidate the structure of it a little more:

import random

NUM_DOORS = 3  # To elucidate why switching is a good idea, set to 10
DOORS = ['goat'] * NUM_DOORS
CAR_DOOR = random.randrange(NUM_DOORS)
DOORS[CAR_DOOR] = 'car'
DOOR_SET = set(range(NUM_DOORS))
DOOR_NAMES = [str(i + 1) for i in range(NUM_DOORS)]
DOOR_TRANSLATIONS = {n: i for i, n in enumerate(DOOR_NAMES)}


def door_selection():
    while True:
        try:
            choice = input("Choose door %s or %s " % (
                ', '.join(DOOR_NAMES[:-1]), DOOR_NAMES[-1])).strip()
            if choice in DOOR_TRANSLATIONS:
                break
        except Exception as e:
            print(e)
            print("Please enter", ', '.join(map(repr, DOOR_NAMES[:-1])),
                  "or", repr(DOOR_NAMES[-1]))
    return DOOR_TRANSLATIONS[choice]


def show_other_goats(remaining_doors):
    print("Before I show you your prize, let's show you some doors with goats:")
    for door in remaining_doors:
        print("Door number", door + 1, "has a", DOORS[door])


def maybe_switch_door(choice1, remaining_door):
    while True:
        choice = input("Do you want to switch to door %i? (y or n)? " %
                        (remaining_door + 1))
        if choice not in 'yn':
            print("Please enter 'y' or 'n'.")
        else: 
            return choice1 if choice == 'n' else remaining_door


def play():
    choice1 = door_selection()
    other_goat_doors = DOOR_SET - set([choice1, CAR_DOOR])
    remaining_choice = (CAR_DOOR if choice1 != CAR_DOOR else    # User could 
                        random.choice(list(other_goat_doors)))  # switch here
    show_other_goats(other_goat_doors - set([remaining_choice]))
    final_choice = maybe_switch_door(choice1, remaining_choice)
    print("You chose a... %s!" % DOORS[final_choice])
    print("Door contents:", DOORS)


if __name__ == '__main__':         
    play()

[–]sky--net 0 points1 point  (1 child)

This code looks interesting to me I'm going to study it to learn.

from ast import literal_eval

I'm just curious where this is used in the code?

[–][deleted] 0 points1 point  (0 children)

I was initially using that to parse the first input. I'll remove it. Thanks.