Racquetball Simulation

First level "refinement"

In [50]:
from random import random, choice
In [26]:
def main():
    # Print an introduction
    print_intro()
    
    # Get the inputs prob_a, prob_b, n
    prob_a, prob_b, n = get_inputs()
    
    # Simulate n games of racquetball, return the wins for players A and B
    wins_a, wins_b = sim_n_games(prob_a, prob_b, n)
    
    # Print a report on the wins for players_a and players_b
    print_summary(wins_a, wins_b)

Second level refinement

In [27]:
def print_intro():
    print("This plays racquetball, good luck I don't know the rules.")
In [28]:
def get_inputs():
    player_a = float(input("What is the prob player A wins a serve? "))
    player_b = float(input("What is the prob player B wins a serve? "))
    n_games = int(input("How many games to simulate? "))
    return player_a, player_b, n_games
In [29]:
def sim_n_games(prob_a, prob_b, n):
    # Initialize wins_a, wins_b to 0
    wins_a, wins_b = 0, 0
    
    # Loop n times to simulate the game
    for i in range(n):
        # Play one game of racquetball
        score_a, score_b = sim_one_game(prob_a, prob_b)
        
        if score_a > score_b:
            wins_a += 1
        else:
            wins_b += 1
            
    return wins_a, wins_b
In [30]:
def print_summary(wins_a, wins_b):
    n = wins_a + wins_b
    print("\nGames simulated:", n)
    print("Wins for A: {0} ({1:0.1%})".format(wins_a, wins_a/n))
    print("Wins for B: {0} ({1:0.1%})".format(wins_b, wins_b/n))

Third level refinement

In [46]:
def sim_one_game(prob_a, prob_b):
    # Initialize scores to zero
    score_a, score_b = 0, 0
    
    # Set a the server to A
    server = "A"

    # Loop while the game is not over
    while not game_over(score_a, score_b):
        # Simulate one serve of a particular player who is current serving
        # Update the status of the game (scores)
        if server == "A":
            if random() < prob_a:
                # Won the serve!
                score_a += 1
            else:
                server = "B"
        else:
            # Player 'B'
            if random() < prob_b:
                # Won the serve!
                score_b += 1
            else:
                server = "A"
                
    # Return scores
    return score_a, score_b

Fourth level refinement

In [32]:
def game_over(score_a, score_b):
    #if score_a == 15 or score_b == 15:
    #    return True
    #else:
    #    return False
    return score_a == 15 or score_b == 15

Run our simulation

In [ ]:
main()
In [ ]:
main()
In [ ]:
main()

Unit Testing

In [ ]:
dir()
In [ ]:
print_intro()
In [ ]:
get_inputs()
In [ ]:
print_summary(12, 72)
In [ ]:
sim_n_games(0.6, 0.75, 1000)
In [ ]:
sim_one_game(0.6, 0.75)
In [ ]:
game_over(5, 15)
In [ ]:
game_over(5, 10)

Improve the Program

In [ ]:
main()
In [34]:
def get_inputs_2():
    while True:
        try:
            # Let the user enter 60% or 0.6, for example as input values
            player_a_str = input("What is the prob player A wins a serve? (enter a fraction or percent) ")
            player_b_str = input("What is the prob player B wins a serve? (enter a fraction or percent) ")
            
            if player_a_str[-1] == "%":
                player_a_str = player_a_str[0:-1]
                player_a = float(player_a_str)/100
            else:
                player_a = float(player_a_str)
                
            if player_b_str[-1] == "%":
                player_b_str = player_b_str[0:-1]
                player_b = float(player_b_str)/100
            else:
                player_b = float(player_b_str)

            n_games = int(input("How many games to simulate? "))
        except ValueError:
            print("Invalid Input!")
            print("Please type in a fractional number.")
            continue
            
        return player_a, player_b, n_games
In [35]:
get_inputs_2()
What is the prob player A wins a serve? 0.6
What is the prob player B wins a serve? 65%
How many games to simulate? 1000
Out[35]:
(0.6, 0.65, 1000)
In [36]:
import random
In [45]:
random.choice(['A', 'B'])
Out[45]:
'A'
In [48]:
def sim_one_game_2(prob_a, prob_b, serving="A"):
    # Initialize scores to zero
    score_a, score_b = 0, 0
    
    # Set a the server to A
    server = choice(['A', 'B'])
    print(server)
    # Loop while the game is not over
    while not game_over(score_a, score_b):
        # Simulate one serve of a particular player who is current serving
        # Update the status of the game (scores)
        if server == "A":
            if random() < prob_a:
                # Won the serve!
                score_a += 1
            else:
                server = "B"
        else:
            # Player 'B'
            if random() < prob_b:
                # Won the serve!
                score_b += 1
            else:
                server = "A"
                
    # Return scores
    return score_a, score_b
In [57]:
sim_one_game_2(0.6, 0.65)
B
Out[57]:
(3, 15)
In [ ]: