15. Random Numbers#

Many different programming tasks require random numbers:

  • Games

    • Dice rolls

    • Card shuffling

    • Video games

  • Educational programs

    • flash cards (e.g., vocabulary)

    • tests (randomize question order and answer order)

  • Simulations

  • Statistical analysis (pick random samples)

  • Cryptography (generate keys, help encrypt data, salting hashes)

Fun fact: Players could beat the original Pac-Man game by following specific patterns across the game board. The ghosts follow a particular algorithm when chasing the player (Pac-Man). In response, Ms. Pac-Man makes a few random decisions at the start of each round and during the first reversal to prevent the use of patterns.

pac-man level 256 overflow issue Pac-Man also has another notable issue when the player reaches level 256 - the screen becomes split into a jumbled mess on the right-hand side of the screen. This "bug" was caused by the game using an 8-bit slot to hold the game level. At level 256, that value wraps around to 0, and the program didn't handle the overflow issue properly. Back in 1980, memory was still a premium and every bit mattered. Unfortunately, decisions like this haunted the software development community with the Year 2000 Problem. Overflow issues still exist depending upon the data types used, the program language, and the deployed environments.

 

Source: https://pacman.fandom.com/wiki/Map_256_Glitch

15.1. Using Random Numbers in Python#

To create random numbers within Python, you will need to import the random module from Python’s standard library.

import random

You can use several different functions in the random module:

  • generate random numbers for different types (integers, floats)

  • select random values from sequences

  • generate a random number based on a specific distribution(e.g., Gaussian).

View the Python documentation for random to see more methods.

1import random

To generate a random integer, \(r\), where \(a <= r <= b\), use

r = random.randint(a,b)

For example, to generate a number between 1 and 6 (rolling a six-sided die):

1# Execute this cell multiple times to see the different values generated
2r = random.randint(1,6)
3print (r)
2

To generate a random float, \(r\), where \(a <= r <= b\), use

r = random.uniform(a,b)
1print(random.uniform(1,10))
2print(random.uniform(1,10))
6.065910441518751
3.206550120959886

random.random() returns the next random number in the range [0.0, 1.0). The value “1.0” is exclusive and will not be returned as a possibility.

1print(random.random())
2print(random.random())
0.33236456609161646
0.7464026105866566

To generate a random number from a Gaussian distribution, use

random.gauss(mu, sigma)

where mu is the mean and sigma is the standard deviation.

1print(random.gauss(20,5))
2print(random.gauss(20,5))
22.7602514457764
13.959964133032525

To randomly select a value from an existing sequence, use random.choice()

1acc_schools = ["Duke", "Notre Dame", "UNC", "NCSU", "Wake Forest", "Clemson"]
2print(random.choice(acc_schools))
3print(random.choice(acc_schools))
NCSU
UNC

15.2. Seeding#

Computers utilize pseudorandom number generator (PRNG) algorithms to “create” random numbers. In particular, Python uses the Mersenne Twister PRNG to generate these numbers.

To effectively create random numbers, it is necessary to “seed” - establish a starting point - for the sequence of random numbers. Behind the scenes, Python automatically seeds its PRNG. However, we can also override this value by explicitly calling random.seed() ourselves.

Several use cases to set a seed: (note - these all involve reproducibility)

  1. Software development - The system will have consistent behavior and output using a seed with random numbers.

  2. Statistical analysis - By sharing the seed, others can replicate and verify the results.

  3. Teaching simulation - Allows the students to see the same results (and possibly, odd results) for the material

Fun fact #2: One instructor built a blackjack program for his 8th-grade science fair project. While testing the program, his mother noticed a pattern where the same cards appeared after the computer started; she could quickly build up a sizable bankroll by making the appropriate bets and plays. Random numbers are just pseudorandom numbers for computers - a deterministic algorithm produces the value. The key here is to use a random seed to change the starting point to an "unguessable" value. Back then, the Applesoft Basic language did not provide an automatic seed – the programmer had to pass a negative number to the random function explicitly. To create the seed, the instructor put the blackjack program into an infinite loop and counted the number of times the loop executed until the user hit the space key to start playing. Modern libraries utilize an automatic seed if one is not explicitly provided - either by using the current system clock or by using a special device /dev/random/ that collects entropy from the operating system based upon interrupts, network traffic, and other events. However, using the system clock alone as a seed can lead to issues as the range of possible values is finite - yes, it may be a large number of possibilities, but modern computers can "brute-force" those possibilities quickly.

More recently, Scopely’s hit game, Monopoly Go, could be exploited by players utilizing airplane mode to repeat sequences of dice rolls.

Andy Weir wrote a short story, "Randomize", examining the financial issues casinos face when attackers can predict "random" numbers.

15.3. Cryptographic Uses#

You should use the SystemRandom class within the random module to use random numbers for cryptographic purposes. This generator uses the operating system’s cryptographic secure PRNG. You may also use the secrets module, which provides a simplified interface around SystemRandom. Note: attempting to use seed() will not have any effect for SystemRandom - as such number sequences are irreproducible.

More details: CSPRNG on Linux

source: https://xkcd.com/1277/

15.4. Suggested LLM Prompts#

  • Explain what random numbers are, the concept of randomness, and the importance of random numbers in various applications like cryptography, simulation, and gaming. Discuss the difference between true randomness and pseudorandomness, and the challenges of generating truly random numbers using computers.

  • Provide an overview of the random module in Python, which is the standard library for generating pseudorandom numbers. Explain the basic functions like random(), randint(), choice(), shuffle(), and sample(), with examples demonstrating their usage.

  • Discuss the concept of pseudorandom number generators (PRNGs) and how they work. Explain the Mersenne Twister algorithm, which is the default PRNG used in Python’s random module. Demonstrate how to create a PRNG instance and use it for generating random numbers.

  • Explain the importance of seeding in PRNGs and how it affects the sequence of random numbers generated. Demonstrate how to set a specific seed value for reproducibility in Python, which is useful for debugging and testing purposes.

  • Discuss the importance of cryptographic-grade randomness in applications like encryption and security protocols. Explain the limitations of pseudorandom number generators for cryptographic purposes and introduce the secrets module in Python, which provides access to the most secure sources of randomness available.

15.5. Review Questions#

  1. Under what circumstances should we explicitly set a fixed value for a random number generator?

  2. Why is using the current date and time not an effective seed for a random number generator?

  3. Search for “Monopoly Go airplane mode hack”. Why might the developers have allowed this hack to exist? Brainstorm possible ways to prevent.

answers

15.6. Exercises#

  1. Write a function that simulates rolling an x-sided die. def roll_die(num_sides=6)

  2. Write a function named twenty that returns a random integer between 1 and 20.

  3. Write a program to allow a user to play Rock, Paper, Scissors against the computer. The user should be able to enter the values of “rock”, “paper”, or “scissors”. The computer randomly selects a choice from that list. The output should follow this logic:

    • If both select the same item: “It’s a tie: both selected itemName.”

    • If one chooses rock and the other scissors: “Rock smashes scissors!”

    • If one chooses scissors and the other paper: “Scissors cuts paper!”

    • If one chooses paper and the other rock: “Paper covers rock!”

    • If the player wins, print “You win!”

    • If the player loses, print “You lose.”