Craps Simulator Exercise I did another exercise, this time it simulates n games of craps(dice game) and outputs the wins and win percentage!

#craps.py -- Simulates multiple games of craps
#   and estimates the probability that the player wins.

import random

def output(wins, total):
    winrate = wins / total
    print("The player won {0} of {1} games ({2:0.2%})".format(wins, total, winrate))

def rolldies():
    dice1 = random.randint(1, 6)
    dice2 = random.randint(1, 6)
    roll = dice1 + dice2
    return roll

def simOneGame():
    initial_roll = rolldies()
    if initial_roll == 2 or initial_roll == 3 or initial_roll == 12:
        return True     # won
    elif initial_roll == 7 or initial_roll == 11:
        return False    #lost
    else:
        #Roll until roll is 7 or initial roll
        roll = rolldies()
        while roll != 7 and roll != initial_roll:
            roll = rolldies()
        if roll == 7:
            return True     #won
        else:
            #roll is inital_roll
            return False    #lost

def simNGames(games_to_sim):
    wins = 0
    for i in range(games_to_sim):
        if simOneGame():
            wins += 1
    return wins

def main():
    games_to_sim = int(input("How many games to simulate? "))
    wins = simNGames(games_to_sim)
    output(wins, games_to_sim)

if __name__ == "__main__":
    main()


Always open for suggestions on what to improve/do differently or more pythonic.
First, Python has an official style-guide, PEP8, which programmers are encouraged to follow. This makes it easier for other Python programmers to read your code. PEP8 recommends using lower_case both for variable and function names, which I have used in the code below.

In your output function you use string formatting (good). However note that if you just want to paste the values in order, there is no need to explicitly mention the indices. So you could write "The player won {} of {} games ({:0.2%})".format(wins, total, winrate). But there is an even easier way in Python 3.6+: f-strings. I also think this is not enough to put it into a function, I would just leave it as a single line in main:

print(f"The player won {wins} of {total} games ({wins/total:0.2%})")


Your rolldies function could be made more general if it accepted a parameter telling it how many dice to roll. You can also use a list comprehension here, or random.choices:

def roll_dice(n=2):
    return sum(random.randint(1, 6) for _ in range(n))

DIE = [1, 2, 3, 4, 5, 6]
def roll_dice(n=2):
    return sum(random.choices(DIE, k=n))


Note that the singular is "die" and the plural is "dice", not "dies".

In your simOneGame function, instead of chaining a lot of comparisons with or, just use in:

def sim_game():
    initial_roll = roll_dice()
    if initial_roll in {2, 3, 12}:
        return True     # won
    elif initial_roll in {7, 11}:
        return False    # lost


Your rolling in the else branch can also be a bit shortened:

    else:
        #Roll until roll is 7 or initial roll
        roll = roll_dice()
        while roll not in {7, initial_roll}:
            roll = roll_dice()
        return roll == 7    # 7 wins


You could theoretically replace the while loop with a single random.choices call, but you would have to manually set the probabilities to the right values.

The simNGames function can be shortened a lot by using the fact that False == 0 and True == 1:

def sim_n_games(n):
    return sum(sim_game() for _ in range(n))