# How to use a random module to check the lottery winner and to program a password generator.

##### What is a random module and where it is used?

A random module is used to generate a random number or sequences. The module implements pseudo-random number generators (PRNG) for various distributions. PRNG refers to an algorithm that uses mathematical formulas to produce sequences of random numbers.

Specifically, Python uses the Mersenne Twister as the core generator which is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes and is completely unsuitable for cryptographic purposes. A random seed which is a number used to initialize a pseudorandom number generator makes it deterministic.

Random modules are widely used in R, statistics, cryptography, gambling, gaming, and other fields.

However, it is not recommended for managing data such as passwords, account authentication, security tokens, and related secrets. For generating cryptographically strong random numbers we have to use the *secrets* module. The *secrets* module provides access to the most secure source of randomness that your operating system provides.

##### Random module functions

The random module has 22 functions in python version 3.8. Let’s look into a few functions that are used for integers, sequences, and for real-valued distribution.

###### Random functions for integers

**1. random.randrange( start, stop,[step])**

Example*(It will pick any random value from a given range)*:

```
import random
print(random.randrange(5,10)) # Integer value from 5 to 9 inclusive
print(random.randrange(5,10,2)) # Even integer from 5 to 9 inclusive
print(random.randrange(10)) # Integer from 0 to 9 inclusive
```

Output:

```
8
9
7
```

**2. random.randint( a, b)**

Example *(Returns a random integer in the range [a, b], including both endpoints)*:

```
import random
print(random.randint(0,2))
print(random.randint(0,2))
```

Output:

```
0
2
```

###### Random functions for sequences

**1. random. choice( seq)**

Chooses a random element from a non-empty sequence. If a sequence is empty, raise IndexError.

Example:

```
import random
fruits = ['mango', 'banana', 'apple', 'orange']
print(random.choice(fruits))
print(random.choice(fruits))
```

Output:

```
banana
mango
```

**2. random.choices( population, weights=None, *, cum_weights=None, k=1)**

Returns a *k-sized* list of elements chosen from the population with replacement. If the population is empty, raise **IndexError**. It is new in python version 3.6 and it can repeat the element.

Example:

```
import random
fruits = ['mango', 'banana', 'apple', 'orange']
print(random.choices(fruits, k=3))
print(random.choices(fruits, k=2))
```

Output:

```
['mango', 'mango', 'orange']
['banana', 'banana']
```

**3. random.shuffle( x, random=None)**

Shuffles list x in place and return **None**.

Example:

```
import random
fruits = ['mango', 'banana', 'apple', 'orange']
random.shuffle(fruits)
print(fruits)
```

Output:

```
['banana', 'apple', 'mango', 'orange']
```

**4. random.sample( population, k)**

Chooses k unique random elements from a population sequence or set. Returns a new list containing elements from the population while leaving the original population unchanged.

Example:

```
import random
fruits = ['mango', 'banana', 'apple', 'orange']
print(random.sample(fruits, 2))
print(random.sample(fruits, 3))
```

Output:

```
['apple', 'orange']
['apple', 'banana', 'orange']
```

###### Random functions for real-valued distributions

The function for real-valued distributions is used in the distribution equations in statistics.

**1. random.random()**

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

Example:

```
import random
print(random.random())
print(random.random())
```

Output:

```
0.5297641647354941
0.41745522197295726
```

**2. random.uniform( a, b)**

Get a random number in the range (a, b) depending on rounding.

Example:

```
import random
print(random.uniform(5, 10))
print(random.uniform(5, 10))
```

Output:

```
5.383841001175535
7.3370102199936165
```

##### What is random.seed() and how to use it?

The seed() is one of the methods in Python’s random module. It initializes the pseudorandom number generator. You should call it before generating the random number. By default, the random number generator uses the **current system time**. If you use the same seed to initialize, then the random output will remain the same.

Example:

```
import random
random.seed(2)
print(random.random())
random.seed(2)
print(random.random())
# Not using a seed value
print(random.random())
```

Output:

```
0.9560342718892494
0.9560342718892494
0.9478274870593494
```

##### Sample activity

###### 1. Program to check Bhutan Lottery Winners

Question:

*Generate 100 random lottery tickets and pick five lucky ticket winners.*

Code:

```
import random
print("Bhutan Lottery Association: try your luck")
print('**************************************\n')
lottery_ticket_list=[]
for i in range(100):
lottery_ticket_list.append(random.randrange(100000,999999))
winners=random.sample(lottery_ticket_list, 5)
print('Lottery number:\n', lottery_ticket_list,'\n')
print('Winners are: ', winners)
print('Congratulations to all the five winners!!!')
```

Output (Winners):

```
Bhutan Lottery Association: try your luck
**************************************
Lottery number:
[467633, 613450, 172528, 863121, 648031, 704661, 461807, 102381, 976925, 249236, 314979,
382713, 990193, 116249, 970498, 367358, 576877, 755518, 826404, 434487, 759752, 580614,
691616, 758368, 449851, 273603, 927755, 591597, 427058, 815201, 475234, 183283, 441144,
380439, 441171, 657996, 913037, 981752, 756388, 321616, 788008, 887528, 422617, 338322,
114290, 207575, 815597, 735091, 320784, 107272, 471022, 719619, 253535, 948093, 475865,
512770, 411344, 484365, 619403, 606901, 517234, 191000, 946411, 994072, 768847, 809430,
928384, 793081, 857790, 272753, 878279, 887381, 479623, 120449, 350365, 790824, 412053,
570060, 444545, 891812, 573887, 538545, 439370, 902039, 733426, 516075, 258012, 152840,
692042, 622408, 111599, 647951, 127671, 342231, 397146, 207883, 868826, 719427, 521529,
824880]
Winners are: [981752, 461807, 928384, 793081, 350365]
Congratulations to all the five winners!!!
```

###### 2. Auto password generator program

Question:

*Generate a random password that meets the following conditions:i. Password length must be 8 characters long.ii. Must contain at least 1 upper case letter, 1 digit, and 1 special character.*

Code:

```
import random
import string
def generatingPassword():
randomPassword = string.ascii_letters + string.digits + string.punctuation
password = random.sample(randomPassword, 5)
password += random.choice(string.ascii_uppercase)
password += random.choice(string.digits)
password += random.choice(string.punctuation)
passwordList = list(password)
random.shuffle(passwordList)
password = "".join(passwordList)
return password
print("System generated Password: ", generatingPassword())
```

Output (your password):

```
System generated Password: M(>M63)P
```

###### 3. A program to generate the same value after rolling a die.

Question:

*Write a program to generate the same value after rolling *dice *5 times.*

Code:

```
import random
dice = [1,2,3,4,5,6]
for i in range(5):
random.seed(10)
print("Dice value:",random.choice(dice))
```

Output:

```
Dice value: 5
Dice value: 5
Dice value: 5
Dice value: 5
Dice value: 5
```