Let's say someone asks you to do an experiement: You are to flip a coin 1,000 times and record how many heads and tails you actually get.
It's a simple experiment, and anyone could do it. But who has time for that? Who wants to stand there flipping a coin 1,000 times and recording the results on a piece of paper? It could take an hour. If they asked you to flip the coin 10,000 times, it would take all day.
This is a perfect place to use a computer simulation. A little computer program can flip a coin 1,000 times in less than a second and tell you the result.
How to do it? The first thing we need to learn about is something called a random number generator. This is a piece of code that generates a random number for us. Here is a tiny little program that shows you how one of Python's random number generators works:
Python allows people to create libraries of code that are easy to pass around to other programmers. In this case we are importing one of these libraries for random numbers. Then inside that library we are calling a function called randrange. Randrange creates a random number in the range of numbers you give it. So if you run this program, it will print one random number between 0 and 9. If you run the program once, it might produce 8. The next time it might produce 3. The next time 1. And so on. You can't tell what it will do, because every run produces a random value. But a random value like that can be extremely useful in simulations.
We can use randrange to simulate coin flipping. Let's say we want to flip a coin 10 times. This code can simulate it:
This little program uses randrange to produce a 0 or a 1, and it does it 10 times, printing the results. Every time you run the program, you will see a different sequence of 10 zeros and ones. We could say that 0 is tails and 1 is heads and we have simulated a coin being tossed 10 times.
What if we want the program say "heads" and "tails" instead of 0 and 1? There are several ways to do this in Python - here is one way using an "if" statement:
ThisFlip is a variable that holds one random number. Then, in the if statement, we test ThisFlip to see if it is a zero or a one. We print "heads" or "tails" depending on what we find. Using a for loop we repeat this 10 times. Every time you run the program, you will see a different sequence of heads and tails.
For our experiment, we want to flip a coin 1,000 times. Each time we flip the coin, we want to count whether it is heads or tails. This little program shows you how to write this simulation in Python:
We have created two variables to hold the number of heads and tails. So each time we "flip the coin", we see if it is heads or tails and increment that variable by one. We flip the coin 1,000 times, and then print the data we gathered from those 1,000 flips. Every time you run the program, you will get a slightly different result, just like you would if you were really flipping a coin 1,000 times.
What if we want to perform the 1,000-flip experiment 10 times, flipping the coin a total of 10,000 times? We can add one more for loop - just one line of code - to make that happen, like this:
This is called a "nested for loop" - one for loop is nested inside another for loop. The outer loop goes 10 times and the inner loop goes 1,000 times for a total of 10,000 total flips of the virtual coin.
When I was typing this code in, I made two mistakes. The first one: I left off the colon on the new for loop. Python informed me of the problem (by refusing to run the program) and I fixed it. Yes, a single mistake of one missing character can keep a whole program from running. My second mistake was an indentation error. Python uses indentation to tell what is "inside" a for loop or an if statement. If you mess up the indentation (use the tab key to indent), it can cause incorrect output. Once I fixed the indentation, everything worked fine. It shows that you have to be careful when writing computer software. Just one missing colon or one incorrect indentation can mess the whole program up.
Could we make this code shorter and more efficient? Programmers think about this, because it can sometimes help make their programs faster. We can get rid of the else part of the program. If we know the number of heads and the number of times we flipped the coin, then we also know the number of tails. There is no reason to actually count the number of tails in this case, so why bother? Here is the revised code:
Now the program is 11 lines long. And if you think about it, it does about half as many additions compared to the previous version. That's a win - the program has to do less work to get the job done.
One thing you might be noticing is that, even though the program is only 11 lines long, our program is getting a bit complicated. If you were looking at it for the first time, you would have to think about it to figure out what it is doing. In the next tutorial, we will look at two ways to make this program easier to understand....