The goal of this lab assignment to allow you to explore repeated
execution by writing Python programs that utilize for
and while
loops along with lists to simulate dice rolling and compound
interest.
For this assignment, record your work in a Jupyter Notebook and upload it to the form below by 11:59 PM Friday, February 14.
To help you get started, we have provided you with a starter notebook, which you can download and then use to record your answers. To utilize the starter notebook, download it to wherever you are running Jupyter Notebook and then use the Jupyter Notebook interface to open the downloaded file.
The starter notebook is already formatted for all the various sections you need to fill out. Just look for the red instructions that indicates were you need to write text or the cyan comments that indicate where you need to write code.
For the first activity, you are to simulate rolling a multiple-sided die multiple times to see its distribution of outcomes. To do so, we will use Python's random.randint function to generate a series of random integers and then store these dice rolls into a list for plotting:
To simulate dice rolling, you will need to complete the following function:
import random
def simulate_dice(rolls, sides=6):
''' Simulate dice rolls '''
results = []
# TODO: Initialize results list to zeroes
# TODO: Simulate dice rolls
return results
This function takes the number of rolls
to simulate and the number of
sides
each die has.
Your first TODO
is to initialize the results
list to contain enough
zeroes for each possible side (ie. die roll). For instance, if sides
is
6
, we may wish to initialize the results
to contain the following:
[0, 0, 0, 0, 0, 0, 0]
Note, we pad the results
list by one item because we want to be able to
roll from 1
to the number of sides
. The idea is that if we roll say a
2
we would increment results[2]
by one to keep track of the number
times we rolled a 2
.
results[2] += 1
Your next TODO
is to simulate the dice rolls by using the
random.randint function to generate a random number between 1
and the
number of possible sides
. You should then update the appropriate item in
the results
list to keep track of the number of times we rolled that
side.
Finally, return the final set of results
.
Here is an exammple simulate_dice
in action:
>>> simulate_dice(100)
[0, 15, 19, 15, 20, 16, 15]
Once you have a working simulate_dice
function, you can take the results
it produces and plot a bar graph (as shown above). To do so, you will
need to complete the following function:
import matplotlib.pyplot as plt
def plot_dice_rolls(results, sides):
''' Plot a bar graph of the dice roll simulation results '''
plt.figure(figsize=(10, 10))
# TODO: plot a bar where x coordinates are the sides and y
# coordinates are the results of the simulation
plt.ylabel('Counts')
plt.title('Dice Roll Simulation')
The TODO
you need to complete is to call the plot.bar
graph with the
two following arguments:
x coordinates: This should be a range from 1
to the number of
sides
. For instance if sides
is 6
, then you want a range that
consists of:
[1, 2, 3, 4, 5, 6]
y coordinates: This should be the provided results
excluding the
initial 0
. For instance, if the results
were [0, 15, 19, 15, 20, 16, 15]
then you want to pass the following argument:
[15, 19, 15, 20, 16, 15]
Once you have a working plot_dice_rolls
function, you can do the
following to produce a bar graph:
sides = 6
rolls = 100
results = simulate_dice(rolls, sides)
plot_dice_rolls(results, sides)
Your last task is to create a run_dice_simulation
function that uses both
simulate_dice_rolls
and plot_dice_rolls
to simulate rolling dice
and then plotting them:
from ipywidgets import interact
def run_dice_simulation(rolls, sides):
''' Simulate dice rolls and then plot the results '''
Once you have a working run_dice_simulation
function, you can use it to
create an interactive widget with the following code:
interact(run_dice_simulation, rolls=(1, 1000), sides=(2, 20))
This will allow you to run your simulation with a different number of
rolls
and with dice with different number of sides
.
After you have completed the program above, answer the following questions:
Describe the flow control of your program. What sort of conditional or repeated execution statements did you use?
Use your code to run a few simulations of rolling dice. If your application depended on unbiased or a fair distribution of results, would Python's default random number generator suffice? Explain.
For the second activity, you are to simulate the calculation of compound interest so you can answer the question:
Given a starting principal and annual interest rate, how many years will it take for you to grow your principal to a target amount?
Once again, we will use functions, loops, and lists to produce a plot as shown below:
To simulate the calculation of compound interest, you will need to complete the following function:
def simulate_compound_interest(principal, rate, target):
''' Simulate compound interest '''
years = 0
interest = 0
totals = [principal]
print('Years Principal Interest')
print(f'{years:5} {principal:9.2f} {interest:8.2f}')
# TODO: Compute compound interest until total principal exceeds target
print(f'After {years} years you will have ${principal:.2f}')
return totals
As can be seen, the initial bookkeeping variables are defined for you. The
years
variable keeps track how many years have passed, while the
interest
is used to store the amount of interest for the current year.
The totals
list is used to keep track of the principal for each year.
Likewise, we have provided you with some formatted strings so you can output a simple table as shown below.
Your TODO
is to use a loop that updates the principal
with the
amount of annual interest generated until the principal
reaches or
surpasses the target
using the following formula:
AnnualInterest = OldPrincipal * InterestRate
NewPrincipal = OldPrincipal + AnnualInterest
After computing the updated principal
, you should print out another entry
in the output table using the following code:
print(f'{years:5} {principal:9.2f} {interest:8.2f}')
Be sure to increment the years
appropriately and append the principal
to the totals
list.
Here is an exammple simulate_compound_interest
in action:
>>> simulate_compound_interest(1000, 0.05, 2000)
Years Principal Interest
0 1000.00 0.00
1 1050.00 50.00
2 1102.50 52.50
3 1157.62 55.12
4 1215.51 57.88
5 1276.28 60.78
6 1340.10 63.81
7 1407.10 67.00
8 1477.46 70.36
9 1551.33 73.87
10 1628.89 77.57
11 1710.34 81.44
12 1795.86 85.52
13 1885.65 89.79
14 1979.93 94.28
15 2078.93 99.00
After 15 years you will have $2078.93
Once you have a working simulate_compound_interest
function, you can take
the totals it produces and plot a line graph (as shown above). To do
so, you will need to complete the following function:
import matplotlib.pyplot as plt
def plot_compound_interest(totals):
''' Plot a line graph of compound interest simulation totals '''
plt.figure(figsize=(10, 10))
# TODO: plot line graph where x coordinates are the years and y
# coordinates are the yearly totals from the simulation
plt.plot(range(len(totals)), totals)
plt.ylabel('Principal')
plt.title('Compound Interest Simulation')
The TODO
you need to complete is to call the plot.plot
graph with the
two following arguments:
x coordinates: This should be a range from 1
to the number of
items in the totals
list. For instance if totals
had 4
items, you
would a range that consists of:
[0, 1, 2, 3]
y coordinates: This should be the provided totals
.
Once you have a working plot_compound_interest
function, you can do the
following to produce a line graph:
principal = 1000
rate = 0.05
target = 2000
totals = simulate_compound_interest(principal, rate, target)
plot_compound_interest(totals)
Note, this will output both the table and the plot.
Your last task is to create a run_cpi_simulation
function that uses both
simulate_compound_interest
and plot_compound_interest
to simulate calculating
compound interest and then plotting the yearly totals:
from ipywidgets import interact
def run_cpi_simulation(principal, rate, target):
''' Simulate compound interest and plot totals '''
Once you have a working run_cpi_simulation
function, you can use it to
create an interactive widget with the following code:
interact(run_cpi_simulation, principal='', rate=(0.0, 1.0, 0.05), target='')
This will allow you to run your simulation with a different starting
principal
, annual interest rate
, and final target
.
After you have completed the program above, answer the following questions:
Describe the flow control of your program. What sort of conditional or repeated execution statements did you use?
Use your code to run a few simulations of compound interest. What is it important to invest early and for long periods of time?
Once you have completed your lab, submit your Jupyter Notebook using the form: