## 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**.

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.

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())
```

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))
```

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)`

`random.randint(20, 30)`

`random.randint(20, 30)`

`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))
```

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))
```

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.