# Python Random - Generate Pseudo-Random Numbers and Data

This lesson demonstrates how to generate random data in Python using a random module. In Python, a random module implements pseudo-random number generators for various distributions, including integer and float (real).

## Table of contents

- How to Use a random module
- Random module functions
- Generate random String
- Cryptographically secure random generator in Python
- Get and Set the state of random Generator
- Numpy random package for multidimensional array
- Generate random Universally unique IDs
- Dice Game Using a Random module
- Exercise and Quiz

## How to Use a random module

You need to import the random module in your program, and you are ready to use this module. Use the following statement to import the random module in your code.

`import random`

**Example**

```
import random
print("Printing random number using random.random()")
print(random.random())
# Output 0.5015127958234789
```

As you can see in the result, we have got 0.50. You may get a different number.

- The
`random.random()`

is the most basic function of the random module. - Almost all functions of the random module depend on the basic function random().
`random()`

return the next random floating-point number in the range [0.0, 1.0).

## Random module functions

Now let see the different functions available in the random module and their usage.

**Click on each function to study it in detail.**

Function | Meaning |
---|---|

`randint(a, b)` |
Generate a random integer number within a range `a` to `b` . |

`randrange(start, stop [, step])` |
Returns a random integer number within a range by specifying the `step` increment. |

`choice(seq)` |
Select a random item from a `seq` such as a list, string. |

`sample(population, k)` |
Returns a `k` sized random samples from a `population` such as a list or set |

`choices(population, weights, k)` |
Returns a `k` sized weighted random choices with probability (`weights` ) from a `population` such as a list or set |

`seed(a=None, version=2)` |
Initialize the pseudorandom number generator with a seed value `a` . |

`shuffle(x[, random])` |
Shuffle or randomize the sequence `x` in-place. |

`uniform(start, end)` |
Returns a random floating-point number within a range |

`triangular(low, high, mode)` |
Generate a random floating-point number `N` such that `low <=N <=high` and with the specified mode between those bounds |

`betavariate(alpha, beta)` |
Returns a random floating-point number with the beta distribution in such a way that `alpha > 0 and beta > 0` . |

`expovariate(lambd)` |
It returns random floating-point numbers, exponentially distributed. If `lambda` is positive, it returns values range from 0 to positive infinity. Else from negative infinity to 0 if `lambda` is negative. |

`gammavariate(alpha, beta)` |
Returns a random floating-point number N with gamma distribution such that `alpha > 0 and beta > 0` |

**Example**

```
import random
# random number from 0 to 1
print(random.random())
# Output 0.16123124494385477
# random number from 10 to 20
print(random.randint(10, 20))
# Output 18
# random number from 10 to 20 with step 2
print(random.randrange(10, 20, 2))
# Output 14
# random float number within a range
print(random.uniform(5.5, 25.5))
# Output 5.86390810771935
# random choice from sequence
print(random.choice([10, 20, 30, 40, 50]))
# Output 30
# random sample from sequence
print(random.sample([10, 20, 30, 40, 50], k=3))
# Output [50, 10, 20]
# random sample without replacement
print(random.choices([10, 20, 30, 40, 50], k=3))
# Output [30, 10, 40]
# random shuffle
x = [10, 20, 30, 40, 50, 60]
random.shuffle(x)
print(x)
# [60, 10, 30, 20, 50, 40]
# random seed
random.seed(2)
print(random.randint(10, 20))
# 10
random.seed(2)
print(random.randint(10, 20))
# 10
```

`random.triangular(low, high, mode)`

The `random.triangular()`

function returns a random floating-point number N such that `lower <=N <=upper`

and with the specified mode between those bounds.

The default value of a lower bound is ZERO, and the upper bounds are one. Moreover, the peak argument defaults to the midpoint between the bounds, give symmetric distribution.

Use the `random.triangular()`

function to generate random numbers for triangular distribution to use these numbers in a simulation. i.e., to generate value from a triangular probability distribution.

Example:

```
import random
print("floating point triangular")
print(random.triangular(10.5, 25.5, 5.5))
# Output 16.114862085401924
```

## Generate random String

**Refer** to **Generate the random string and passwords in Python**.

This guide includes the following things: -

- Generate a random string of any length.
- Generate the random password, which contains the letters, digits, and special symbols.

## Cryptographically secure random generator in Python

Random Numbers and data generated by the random module are not cryptographically secure.

The cryptographically secure random generator generates random data using synchronization methods to ensure that no two processes can obtain the same data simultaneously.

A secure random generator is useful for security-sensitive applications such as OTP generation.

We can **use the following approaches** to secure the random generator in Python.

- The secrets module to secure random data in Python 3.6 and above.
- Use the random.SystemRandom class in Python 2.

## Get and Set the state of random Generator

The random module has two functions: `random.getstate()`

and `random.setstate()`

to capture the random generator's current internal state. Using these functions, we can generate the same random numbers or sequence of data.

`random.getstate()`

The `getstate()`

function returns a tuple object by captures the current internal state of the random generator. We can pass this state to the setstate method to restore this state as a current state.

`random.setstate(state)`

The setstate() function restores the random generator's internal state to the `state`

object passed to it.

**Note**: By changing the state to the previous state, we can get the same random data. For example, If you want to get the same sample items again, you can use these functions.

### Example

If you get a previous state and restore it, you can reproduce the same random data repeatedly. Let see the example now to get and set the state of a random generator in Python.

```
import random
number_list = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
print("First Sample is ", random.sample(number_list, k=5))
# Output [3, 27, 21, 24, 18]
# Get current state and store
state = random.getstate()
# set current state
random.setstate(state)
# Now it will print the same second sample list
print("Second Sample is ", random.sample(number_list, k=5))
# Output [3, 27, 21, 24, 18]
random.setstate(state)
# again it will print the same sample list again
print("Third Sample is ", random.sample(number_list, k=5))
# Output [3, 27, 21, 24, 18]
# Without setstate
# Gives new sample
print("Fourth Sample is ", random.sample(number_list, k=5))
# output [27, 24, 12, 21, 15]
```

As you can see in the output, we are getting the same sample list because we use the same state again and again

## Numpy random package for multidimensional array

PRNG is an acronym for pseudorandom number generator. As you know, using the Python random module, we can generate scalar random numbers and data.

Use a NumPy module to generate a multidimensional array of random numbers. NumPy has the `numpy.random`

package has multiple functions to generate the random n-dimensional array for various distributions.

### Create an n-dimensional array of random float numbers

- Use a
`random.rand(d0, d1, …, dn)`

function to generate an n-dimensional array of random float numbers in the range of`[0.0, 1.0)`

. - Use a
`random.uniform(low=0.0, high=1.0, size=None)`

function to generate an n-dimensional array of random float numbers in the range of`[low, high)`

.

**Example**

```
import numpy as np
random_array = np.random.rand(2, 2)
print("2x2 array for random numbers", random_array, "\n")
random_float_array = np.random.uniform(25.5, 99.5, size=(3, 2))
print("3 X 2 array of random float numbers in range [25.5, 99.5]", random_float_array)
```

**Output**:

2x2 array for random numbers [[0.47248707 0.44770557] [0.33280813 0.64284777]] 3 X 2 array of random float numbers in range [25.5, 99.5] [[52.27782303 49.67787027] [28.33494049 37.99789879] [27.19170587 76.69219575]]

### Generate an n-dimensional array of random integers

Use the random.random_integers(low, high=None, size=None) to generate a random n-dimensional array of integers.

```
import numpy as np
random_integer_array = np.random.random_integers(5, size=(3, 2))
print("2-dimensional random integer array", random_integer_array)
```

**Output**:

2-dimensional random integer array [[2 3] [3 4] [3 2]]

## Generate random Universally unique IDs

**Python UUID Module** provides immutable UUID objects. UUID is a Universally Unique Identifier. It has the functions to generate all versions of UUID. Using the `uuid4(`

) function of a UUID module, you can generate a 128 bit long random unique ID ad it's cryptographically safe.

These unique ids are used to identify the documents, Users, resources, or information in computer systems.

**Example**:

```
import uuid
# get a random UUID
safeId = uuid.uuid4()
print("safe unique id is ", safeId)
```

**Output**:

safe unique id is UUID('78mo4506-8btg-345b-52kn-8c7fraga847da')

## Dice Game Using a Random module

I have created a simple dice game to understand random module functions. In this game, we have two players and two dice.

- One by one, each Player shuffle both the dice and play.
- The algorithm calculates the sum of two dice numbers and adds it to each Player's scoreboard.
- The
**Player who scores high number is the winner**.

**Program**:

```
import random
PlayerOne = "Eric"
PlayerTwo = "Kelly"
EricScore = 0
KellyScore = 0
# each dice contains six numbers
diceOne = [1, 2, 3, 4, 5, 6]
diceTwo = [1, 2, 3, 4, 5, 6]
def shuffle_dice():
# Both Eric and Kelly will roll both the dices using shuffle method
for i in range(5):
# shuffle both the dice 5 times
random.shuffle(diceOne)
random.shuffle(diceTwo)
# use choice method to pick one number randomly
firstNumber = random.choice(diceOne)
SecondNumber = random.choice(diceTwo)
return firstNumber + SecondNumber
print("Dice game using a random module\n")
# Let's play Dice game three times
for i in range(3):
# let's do toss to determine who has the right to play first
# generate random number from 1 to 100. including 100
EricTossNumber = random.randint(1, 100)
# generate random number from 1 to 100. doesn't including 101
KellyTossNumber = random.randrange(1, 101, 1)
if (EricTossNumber > KellyTossNumber):
print("Eric won the toss")
EricScore = shuffle_dice()
KellyScore = shuffle_dice()
else:
print("Kelly won the toss")
KellyScore = shuffle_dice()
EricScore = shuffle_dice()
if (EricScore > KellyScore):
print("Eric is winner of dice game. Eric's Score is:", EricScore, "Kelly's score is:", KellyScore, "\n")
else:
print("Kelly is winner of dice game. Kelly's Score is:", KellyScore, "Eric's score is:", EricScore, "\n")
```

**Output**:

Dice game using a random module Kelly won the toss Eric is the winner of a dice game. Eric's Score is: 9 Kelly's score is: 6 Kelly won the toss Eric is the winner of a dice game. Eric's Score is: 11 Kelly's score is: 9 Eric won the toss Kelly is the winner of a dice game. Kelly's Score is: 12 Eric's score is: 5

**Reference**: -

## Exercise and Quiz

To practice what you learned in this tutorial, I have created a Quiz and Exercise project.

- Solve a Python Random data generation Quiz to test your random data generation concepts.
- Solve the Python Random data generation Exercise to practice and master the random data generation techniques.

**All Python Random Module Tutorials**: -