# Simulations in Python

Simulations are useful for simulating events many times without actually doing them. By using python libraries such as `random`

, we can analyze the outcomes and behavior of these events in a virtual setting, saving us the trouble from tedious experiments.

For example, what should we do if we want to get the power of three for a range of numbers? It would be too tedious to calculate this one by one. By introducing a for loop, declaring a placeholder variable 'i', and computing the power of three raised to the value of 'i', we can skillfully simplify this task to a few lines of code. Additionally, by putting the outcome into a dataframe, we can enhance clearity and facilitate better analysis.

The overall structure is as follows:

**Initializing an empty list**: We start by creating an empty list named data, so that we can store the data inside.**Iterating through a range**: We utilize a for loop to iterate through a specific number of times. In this case, we input the argument 10 into range() for simplicity, so the loop variable 'i' will range from 0 to 9.**Appending data to the list**: We append the calculated power of 3 to the data list as a dictionary with the key 'power' and the corresponding value.**Transforming the list into a DataFrame**: After all data is collected, we exit the`for`

loop and transform the list data into a DataFrame using the`pd.DataFrame()`

function from the Pandas library.

```
import pandas as pd
# Create a for loop that appends text to a list, and then transform the list into a dataframe
data = [] # Initialize an empty list to store the data
for i in range(10): # Loop for 10 times
data.append({"power": 3**i}) # Calculate the power of 3 raised to the ith exponent and append it as a dictionary
df = pd.DataFrame(data)
df
```

power | |
---|---|

0 | 1 |

1 | 3 |

2 | 9 |

3 | 27 |

4 | 81 |

5 | 243 |

6 | 729 |

7 | 2187 |

8 | 6561 |

9 | 19683 |

A detailed explanation of for loops can be found as follows:

`Random`

library

The `random`

library is very useful because it allows us to generate random numbers, sample elements from certain distribution or population, shuffle the whole array, and so on! Below is a highly concise showcase of some basic functions in `random`

library.

A more detailed explanation of random library can be found as follows:

For example, let's generate a random integer from 1 to 6 ten times and see the results:

```
data = []
for i in range(10):
data.append(random.randint(1,6)) # Returns a random number between 1 to 6
df = pd.DataFrame(data)
df
```

0 | |
---|---|

0 | 3 |

1 | 2 |

2 | 5 |

3 | 4 |

4 | 4 |

5 | 3 |

6 | 6 |

7 | 5 |

8 | 4 |

9 | 3 |

By calling the `randint`

function of `random`

, we can generate an integer in a specified range, which is 1-6 in this case. Each iteration of the loop will generate a random number between 1 and 6 and append it to `data`

, allowing us to simulate random events such as rolling a die or flipping a coin.

If we run this code cell again, the result will be different than the first time:

```
data = []
for i in range(10):
data.append(random.randint(1,6))
df = pd.DataFrame(data)
df
```

0 | |
---|---|

0 | 6 |

1 | 6 |

2 | 5 |

3 | 1 |

4 | 5 |

5 | 6 |

6 | 1 |

7 | 1 |

8 | 3 |

9 | 3 |

## Simple Simulations (Die Roll)

What we did above was basically how to create a simulation for rolling a die! We just need to add a few more elements, such as the column name, and we will have created our first simulation.

Let's simulate rolling a six-sided die 50 times:

```
# Rolling a die 50 times
data = []
for i in range (50):
roll = random.randint(1,6)
d = {"roll" : roll}
data.append(d)
df = pd.DataFrame(data)
df
```

roll | |
---|---|

0 | 3 |

1 | 1 |

2 | 2 |

3 | 1 |

4 | 1 |

5 | 6 |

6 | 5 |

7 | 1 |

8 | 2 |

9 | 1 |

10 | 4 |

11 | 3 |

12 | 4 |

13 | 4 |

14 | 3 |

15 | 2 |

16 | 1 |

17 | 6 |

18 | 3 |

19 | 2 |

20 | 5 |

21 | 5 |

22 | 3 |

23 | 5 |

24 | 4 |

25 | 6 |

26 | 3 |

27 | 5 |

28 | 1 |

29 | 5 |

30 | 1 |

31 | 5 |

32 | 5 |

33 | 2 |

34 | 2 |

35 | 3 |

36 | 3 |

37 | 5 |

38 | 1 |

39 | 6 |

40 | 2 |

41 | 2 |

42 | 4 |

43 | 4 |

44 | 2 |

45 | 4 |

46 | 6 |

47 | 3 |

48 | 6 |

49 | 2 |

Here, we created a column called `roll`

, attached the integer of our die roll to it, and added it to `data`

in each iteration. This way, the columns of the simulation can have meaningful names and help you understand the simulation better.

## Simple Simulations (Coin Toss)

We can also simulate events where the outcome for each iteration is not a number. For this we will have to use `random.choice`

.

```
# coin toss 10 times
data = []
for i in range (10):
flip = random.choice(["heads", "tails"])
d = {"flip" : flip}
data.append(d)
df = pd.DataFrame(data)
df
```

flip | |
---|---|

0 | heads |

1 | heads |

2 | heads |

3 | tails |

4 | tails |

5 | heads |

6 | heads |

7 | tails |

8 | tails |

9 | heads |

`random.choice`

allows us to choose from a list, in this case between `heads`

and `tails`

. We can add more into the list if we wanted to simulate other events with more possible outcomes.

## Simulations with Conditionals

Imagine a game where a random integer between 1 and 10 is rolled and you win if the outcome is a 7. It can be simulated using the following code. From the dataframe, all the available result is surprisingly a "lose". Since the probability of winning in each trail is 0.1, this is totally feasible and a likely outcome.

```
# Simulating a game where a random integer between 1 and 10 is rolled.
# If the rolled number is 7, the outcome is "win"; otherwise, it's "lose".
data = []
for i in range(10):
roll = random.randint(1, 10) # Generate a random integer between 1 and 10 (inclusive)
if roll == 7: # if the outcome is a seven, you wins!
outcome = "win"
else: # otherwise you lose
outcome = "lose"
data.append({"outcome": outcome}) # Store the outcome as a dictionary and append it to the list
df = pd.DataFrame(data)
df
```

outcome | |
---|---|

0 | lose |

1 | lose |

2 | lose |

3 | lose |

4 | lose |

5 | lose |

6 | lose |

7 | lose |

8 | lose |

9 | lose |

## Complex Simulations (One-Dimension Random Walk)

Random walk describes a path consisting of a series of random steps. In its simplest form, a one-dimensional random walk takes place on a straight line. At each step, the walker moves either to the left or to the right with equal probability of 0.5. Additionally, position of the walker after each step is determined only by the previous position, also known as the memoryless property. Mathematically, if $x_i$ represents the position of the walker after $i$ steps, then $x_i=x_i−1+ϵ_i$, where $ϵ_i$ is a random variable representing the step taken at step $i$. Random walk is a extremely simple case of Markov Property and Stochastic Process.

```
data = []
current_value = 0
for i in range(100):
step = random.choice([-1, 1]) # equal probability of getting up and down
current_value += step
data.append(current_value)
df = pd.DataFrame(data, columns=['Time'])
df
```

Time | |
---|---|

0 | 1 |

1 | 2 |

2 | 1 |

3 | 0 |

4 | 1 |

... | ... |

95 | 4 |

96 | 5 |

97 | 6 |

98 | 5 |

99 | 4 |

100 rows × 1 columns

## Complex Simulations (Drawing Poker Card with Replacement)

Let's simulate drawing 20 cards with replacement from a standard deck of 52 playing cards. Each card has a suit (hearts, diamonds, clubs, or spades) and a rank (2 to 10, plus Jack, Queen, King, Ace). Since each individual card can be expressed by a suit and a rank, we'll randomly select one suit and one rank for each draw. Therefore, we can come up with the following simulation:

```
# simulation to select 20 cards from a standard 52 card deck with replacement
data = []
for i in range(20):
rank = random.choice(['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'])
suit = random.choice(['heart', 'diamond', 'spade', 'club'])
d = { "rank" : rank, "suit" : suit}
data.append(d)
df = pd.DataFrame(data)
df
```

rank | suit | |
---|---|---|

0 | Q | diamond |

1 | 9 | club |

2 | 8 | spade |

3 | 4 | club |

4 | 6 | spade |

5 | 3 | spade |

6 | A | club |

7 | 6 | spade |

8 | 8 | diamond |

9 | 4 | diamond |

10 | 7 | club |

11 | 2 | club |

12 | 8 | heart |

13 | K | spade |

14 | 4 | heart |

15 | 6 | spade |

16 | 10 | heart |

17 | 10 | club |

18 | 7 | club |

19 | 2 | diamond |

Additional explanations for simple simulations can be found here:

## Python Documentation

Click Here for the full python documentation for `random`

.