Introduction

Working with random numbers is an important part of most applications today. Games are one of the most common user of them. Generating random numbers effectively is likewise an important concern of today's computing world.

In this chapter, we shall see how to work with random numbers in Python. Specifically, we'll see how to generate a random float in the range [0, 1) and how to generate random integers in a given arithmetic progression, including the progression of natural numbers.

What are pseudo-random numbers?

When we take the term 'random', we basically mean something that's not predictable. It's purely based on chance.

Random numbers generated by computers are random, but predictable.

Now this might confuse you — and it should because it goes against our usual understanding of the term 'random'.

Random numbers generated by computers simply form a sequence where consecutive elements don't follow any given pattern — they're random. However, there comes a point when the sequence start to repeat itself.

In other words, it's predictable after a given length of elements.

Thereby, random numbers generated by computers are termed specially — they're called pseudo-random numbers.

A pseudo-random number is a computer-generated random number.

An algorithm that generates a pseudo-random number is called a pseudo-random number generator, or simply PRNG.

Almost all programming languages today use PRNG to generate random numbers. Python is no exception.

How exactly do these algorithms work is beyond the scope of this book. They use complex math and theories from sophisticated areas of mathematics such as number theory, congruences, and much more geeky stuff.

Now the next time, whenever you encounter a random number in Python, or any other programming language, you would know that it's a pseudo-random number — not a pure random number.

The random module

The fuel of random numbers in Python is the random module. Without it, one can't imagine randomness in Python, unless that person is a PRNG programmer!

Hence, we start by importing the random module into our script:

import random

One this is done, we can validly operate on random numbers.

Now there are a couple of methods to get a random number using the random module. The section below explores some of those methods one by one.

A random number in [0, 1)

The most basic method of the random module is the random() method.

It returns a float in the range [0, 1) (greater than or equal to 0 and lesser than 1).

Let's see it in action:

import random

# a random number
print(random.random())

# another random number
print(random.random())
0.8171490774449344
0.34983672178530134

Using the random() method and a bit of arithmetic, one can generate random numbers in any given range. The exercises below demonstrate this.

Construct a function random_number() that returns a random float between 0 (inclusive) and 100 (exclusive).

As we saw above, random() returns a float in the range [0, 1). If we multiply its result with 100 we get a float in the range [0, 100).

So, this is how we'll define the random_number() function:

import random

def random_number():
    return random.random() * 100

Although, a bit of arithmetic of random() allows us to generate any sort of random number in Python, it's not really straightforward and out-of-the-box. Fortunately, Python provides a couple of other methods to produce random numbers in given ranges and of given types.

Let's see them..

A random integer

The randint() method takes in two arguments and returns a random integer between these numbers (both inclusive).

random.randint(lower_limit, upper_limit)

randint() is a handy way to get random integers in Python.

Consider the code below:

import random

# random integer between 0 and 5 
print(random.randint(0, 5))

# random integer between 20 and 30 
print(random.randint(20, 30))
4
24

First we get a random number between 0 and 5 (both inclusive), and then we get another one between 20 and 30.

Let's call random.randint(20, 30) a couple of times to see what values do we get in a run:

random.randint(20, 30)
21
random.randint(20, 30)
30
random.randint(20, 30)
25
Before working with the random module in the interactive shell, make sure that you have it imported via import random.

How to generate a random integer between 0 (inclusive) and 10 (exclusive) using randint()?

  • Using randint(0, 9)
  • Using randint(0, 10)

The randrange() method

Python enables one to get a random integer in a given arithmetic progression using the randrange() method.

It works just like the range() method — except for that it doesn't return a sequence, but rather a randomly selected item from the sequence.

Consider the example below:

import random

# random item from the sequence below:
# 0, 1, 2, 3, 4, 5, 6, 7, 8
print(random.randrange(9))
5

First think of what does range(9) define. It defines a sequence of the integers from 0 to 8 (both inclusive). rangrange() accordingly selects one item from this sequence.

Now let's consider another sequence:

import random

# random item from:
# 0, 2, 4, 6, 8, 10
print(random.randrange(0, 11, 2))
print(random.randrange(0, 11, 2))
print(random.randrange(0, 11, 2))
2
10
0

As before, first let's see what does range(0, 11, 2) define. It defines all even integers from 0 to 10 (both inclusive). Thereby, randrange(0, 11, 2) returns a randomly selected item from this sequence of evens.

randrange() doesn't compute a sequence!

One might be tempted to think that randrange() creates an actual sequence and then selects a number from it. However, this is not the case.

Instead, randrange() uses random() internally and a bit of elementary arithmetic to return a random integer in a given arithmetic progression.

Moving on

These are not the only methods of the random module. There are a couple more, however they are related to lists and statistics and other concepts that we shall explore later on.