So I tried making my first program but it didn't work, but I can't figure out what is wrong with it. I have added some commentary with the code:

#!/usr/bin/env python
import sys
from random import randrange, shuffle, choice, sample

DOORS = ['ant','ant','ant','bee','bee','bee','car','car']

def pickdoor(picked):
    """Returns a number representing the original door chosen"""
    return randrange(8)

def revealants(revealed1):
    """randomly reveals 1 door containing ants (cannot be the original)"""
    alldoors = set([0,1,2,3,4,5,6,7])
    doorswithants = [i for (i,v) in enumerate(DOORS) if v == 'ant']
    originaldoor = set([picked])
    availabledoors1 = list(doorswithants - originaldoor)
    return choice(availabledoors2)

def revealbees(revealed2):
    """ramdomly reveals 1 door containing bees (cannot be the original)"""
    doorswithbees = [i for (i,v) in enumerate(DOORS) if v == 'bee']
    availabledoors2 = list(doorswithbees - originaldoor)
    return choice(doorswithbees)

def revealcars(revealed3):
    """randomly reveals 1 door containing cars (cannot be original)"""
    doorswithcars = [i for (i,v) in enumerate(DOORS) if v == 'car']
    availabledoors3 = list(doorswithcars - originaldoor)
    return choice(doorswithcars)

def switch(switched):
    """randomly chooses a door that is not the original door and that has not been revealed"""
    availabledoors4 = list(alldoors - originaldoor - revealed1 - revealed2 - revaled3)
    return choice(availabledoors4)

def main(iterations=10000):
    shuffle(DOORS)
    obtainedant = 0
    obtainedbee = 0
    obtainedcar = 0

    for dummy in xrange(iterations):
        """calculates the chance of the final switched door containing an ant/bee/car"""
        if switch == 'ant':
            obtainedant += 1
        if switch == 'bee':
            obtainedbee += 1
        if switch == 'car':
            obtainedcar += 1

    chanceofgettingant = (float(obtainedant) / iterations) * 100
    chanceofgettingbee = (float(obtainedbee) / iterations) * 100
    chanceofgettingcar = (float(obtainedcar) / iterations) * 100

    print "Chance of getting ant: %f%%" % chanceofgettingant
    print "Chance of getting bee: %f%%" % chanceofgettingbee
    print "Chance of getting car: %f%%" % chanceofgettingcar
    
if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(int(sys.argv[1]))
    else:
        main()

Running the program currently gets me 0% for everything. Help would be much appreciated :)

The value of the variable switch in the main loop is <function switch at 0x7f17ffb10c08> , so it's never equal to 'ant', 'bee' or 'car'. There are many errors in your code. You are using undefined variables in different places. First concentrate on the content of the main loop: what should it do ?

Doesn't

#
#
def switch(switched):
#
"""randomly chooses a door that is not the original door and that has not been revealed"""
#
availabledoors4 = list(alldoors - originaldoor - revealed1 - revealed2 - revaled3)
#
return choice(availabledoors4)

make it either 'ant', 'bee', or 'car'? Also, is it possible to use the functions without any variables? I'm still not too sure where the errors are so I'll try to play with it a little.

The problem is that you are mistaking function parameters with return values. Here is how you could write your program

#!/usr/bin/env python
import sys
from random import randrange, shuffle, choice, sample

DOORS = ['ant','ant','ant','bee','bee','bee','car','car']

def reveal(what, availabledoors):
    """return an index chosen from 'availabledoors' which as value 'what' in DOORS.
   'what' can be 'ant', 'bee' or 'car'"""
    # the parameters what, availabledoors and the variable doors defined below
    # exist only in this function body. They are unreachable from outside code.
    doors = [i for i in availabledoors if DOORS[i] == what]
    return choice(doors)

# When we are here, the function 'reveal' was defined, but was never executed.

def pickdoor(doors):
    """Returns a number representing the original door chosen.
    The parameter 'doors' is a list containing indexes."""
    return choice(doors)

# again, here , pickdoor was defined but not yet called

def main(iterations=10000):
    shuffle(DOORS)
    obtainedant = 0
    obtainedbee = 0
    obtainedcar = 0

    for dummy in xrange(iterations):
        """calculates the chance of the final switched door containing an ant/bee/car"""
        doors = range(len(DOORS))
        picked = pickdoor(doors) # Here we call pickdoor and get a return value
        doors.remove(picked)
        for kind in ('ant', 'bee', 'car'):
            revealed = reveal(kind, doors) # This is where we call reveal
            doors.remove(revealed)
        picked = pickdoor(doors)
        switch = DOORS[picked]
        if switch == 'ant':
            obtainedant += 1
        elif switch == 'bee':
            obtainedbee += 1
        elif switch == 'car':
            obtainedcar += 1

    chanceofgettingant = (float(obtainedant) / iterations) * 100
    chanceofgettingbee = (float(obtainedbee) / iterations) * 100
    chanceofgettingcar = (float(obtainedcar) / iterations) * 100

    print "Chance of getting ant: %f%%" % chanceofgettingant
    print "Chance of getting bee: %f%%" % chanceofgettingbee
    print "Chance of getting car: %f%%" % chanceofgettingcar
    
if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(int(sys.argv[1]))
    else:
        main()
Comments
Thank you very much

Note that the theoretical probabilities are 13/32, 13/32, 6/32 for ant, bee and car. This is very close from the program's output

Chance of getting ant: 40.160000% # instead of 40.625
Chance of getting bee: 40.470000% # instead of 40.625
Chance of getting car: 19.370000% # instead of 18.75

Thanks! I see now that my previous code had many mistakes. I have a question about the code you wrote: suppose that I wanted to reveal 2 ants, 1 bee, and 1 car (instead of 1, 1, 1). How would I go about doing that? I tried replacing your

for kind in ('ant', 'bee', 'car'):
            revealed = reveal(kind, doors) # This is where we call reveal
            doors.remove(revealed)

with

for kind in ('ant'):
            revealed = reveal(kind, doors)
            doors.remove(revealed)
            revealed = reveal(kind, doors)
            doors.remove(revealed)
        for kind in ('bee', 'car'):
            revealed = reveal(kind, doors)
            doors.remove(revealed)

which didn't work out. I'm not too sure why, though.

No, you must write

for kind in ('ant', 'ant', 'bee', 'car'):
    etc

Also note that ('ant') is not a tuple with a single element but the string 'ant'. If you want a tuple with a single element, you must write ('ant',) .

This article has been dead for over six months. Start a new discussion instead.