Python Forum
Proposed Tutorial: Introduction to (Pseudo) Random Numbers and Python
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Proposed Tutorial: Introduction to (Pseudo) Random Numbers and Python
#1
Introduction to (Pseudo) Random Numbers and Python

The term 'Pseudo' is used because the numbers are not truly random, but eventually repeat. The acronym 'PRNG' is often used for 'Pseudo Random Number Generator'. The term 'Pseudo' will not be used further, but it is implied.


Items covered:
a. Introduction
b. How Random Number Generators work
c. Generating Python Random Numbers of type 'Float' or type 'Integer' Example
d. Typical Monte Carlo Simulation Example


**** Introduction ****
Random numbers in Python are used for many things including:
a. Card games, dice games and other games of chance
b. Generating Random Work Assignments
c. Monte Carlo Simulation, which uses random numbers to simulate real world events. This technique is used when an event is known to follow some kind of probability pattern, and it is difficult or impossible or you are too lazy to mathematically model the event. For a typical use see http://people.brunel.ac.uk/~mastjjb/jeb/or/queue.html

Python uses an algorithm known as the 'Mersenne Twister'. For more details see https://en.wikipedia.org/wiki/Mersenne_Twister . Modern Pseudo Random Number Generators (PRNG) have a repeat rate on the order of 2**19937 − 1, which is a very long sequence. Random numbers are generally represented internally by a sequence of bits, then converted to a 'float' number 0 <= x < 1. For other types of random numbers (e.g. integers or special type of distributions), Python has methods available. Most Python implementations follow the IEEE-754 standard which provides between 15 and 17 significant digits depending on the number. For more information see: https://en.wikipedia.org/wiki/Double-pre...int_format For Python Random Number documentation see https://docs.python.org/3/library/random.html . The 'random' package includes a lot more than the simple examples below including the ability to:
a. Use different types of distributions.
b. Randomly select an item from a list (text or numeric).
c. Randomize (shuffle) a list.

To use random numbers in Python, you can import the 'random' module. Python 3.6 introduced the 'secrets' module, which is better suited for cryptography or security purposes (e.g. passwords). See https://docs.python.org/3.6/library/secr...le-secrets
Both modules are included in the 'Python Standard Library'.

For an additional discussion including using an alternate Python Random Number Generator see: https://people.duke.edu/~ccc14/sta-663/MonteCarlo.html


**** How Random Number Generators (PRNG) work ****
Before the first Random Number can be generated the computer needs a 'seed number'. The 'seed number' can be input by the user, or can be internally generated by the computer. Most 'computer generated' seeds use some kind of algorithm based on the computer system time. The 'seed number' creates a 'state'. Each Random Number generated is based on the previous 'state'. Each time a 'Random Number' is generated, the 'state' changes. Older algorithms used the 'previous Random Number' as the 'state'. 'Random Number' sequences that use the same 'seed number' will be identical (i.e. will generate the same sequence of Random Numbers). A 'known sequence' of random numbers is often useful in debugging computer code.
import random

# Create a random number seed internally created by Python
# If this statement is omitted, it will be implied the first time a random number is requested
random.seed()

# Create a user entered random number 'seed' 
random.seed(12345)

**** Generating Python Random Numbers of type 'float' or type 'Integer' Example ****
import random
s = """
#################################################
Generate 5 pseudo random float numbers in the range 0.0 <= x < 10.0.
NOTE: This sequence is a continuation of the previous sequence.
"""
print(s, end="")
for i in range(5):
   xrand = random.uniform(0.0, 10.0)
   print("{0:4d}   {1:12.9f}".format(i, xrand))
   
s = """
#################################################
Generate 5 pseudo random integers in the range 0 <= x < 2
"Calling sequence: 'random.randrange(2)'
"NOTE: This sequence is a continuation of the previous sequence."
"""
print(s, end="")
for i in range(5):
   irand = random.randrange(2)
   print("{0:4d}   {1:4d}".format(i, irand))
 
s = """
#################################################
Generate 5 pseudo random integers in the range 0 <= x < 2
Calling sequence: 'random.randrange(0, 2)'
NOTE: This sequence is a continuation of the previous sequence.
"""
print(s, end="")
for i in range(5):
   irand = random.randrange(0, 2)
   print("{0:4d}   {1:4d}".format(i, irand))
 
s = """
#################################################
Generate 5 pseudo random integers in the range 0 <= x < 2
Calling sequence: 'random.randint(0, 1)'
NOTE: This sequence is a continuation of the previous sequence.
"""
print(s, end="")
for i in range(5):
   irand = random.randint(0, 1)
   print("{0:4d}   {1:4d}".format(i, irand))
 
 
s = """
#################################################
Extract a random item from a list
Calling sequence: 'random.choice(my_list)'
"""
print(s)
my_list = ['Moe', 'Larry', 'Curly', 'Shemp', 'Curly_Joe']   
my_stooge = random.choice(my_list) 
print("List: ", end = "")
print(my_list)
print("Random item: '{}'".format( my_stooge))

s = """
#################################################
Extract a random item from a list including the index
Calling sequence: 'random.randrange(0,len(my_list))' 
followed by:      'my_stooge = my_list[random_index]'
"""
print(s)
random_index = random.randrange(0,len(my_list))
my_stooge = my_list[random_index]
print("List: ", end = "")
print(my_list)
print("Random item: '{}' which is index number: '{}'".format( my_stooge, random_index))


s = """
#################################################
Rearrange items in a list into a new list
Calling sequence: 'random.sample(my_list, k=len(my_list))' 
"""
print(s)
my_newlist = random.sample(my_list, k=len(my_list))
print("Original List: ", end = "")
print(my_list)
print("New      List: ", end = "")
print(my_newlist)


s = """
#################################################
Rearrange items in a list
Calling sequence: 'random.shuffle(my_list)' 
"""
print(s)
print("Original List: ", end = "")
print(my_list)
random.shuffle(my_list)
print("Shuffled List: ", end = "")
print(my_list)
Click to hide/display output.

**** Typical Monte Carlo Simulation Example ****
import random
import time
import operator

# Problem: A manufacturer assembles a machine that uses a rotating shaft that is inserted into a pulley.
# All shafts and pulleys (holes) are labeled with their dimensions. 
# Engineers have come up with the following specifications:
# a. Hole  size must be 2.0000 to 2.0018 inches.
# b. Shaft size must be 1.9963 to 1.9975 inches.
# c. Clearances are assigned a 'weighted score' below.  Clearances above 0.0039 inches can not be used due to excess vibration.

# From the numbers above, the clearance must be 0.0025 inches (= 2.0000 - 1.9975) thru 0.0055 inches (=2.0018 - 1.9963). 
# 0.0025 inches thru 0.0029 inches, score =   1 
# 0.0030 inches thru 0.0034 inches, score =   6
# 0.0035 inches thru 0.0039 inches, score =  10 
# 0.0040 inches thru 0.0055 inches, score = -10 


NUMBER_OF_ITERATIONS = 50000
MY_SPACE = " "

def calculate_lineitem_score(idelta):
    if idelta <= 29:
        ilineitem_score = 1
    elif idelta <= 34:
        ilineitem_score = 6
    elif idelta <= 39:
        ilineitem_score = 10
    else:
        ilineitem_score = -10
    #
    return ilineitem_score

# Initialize the elapsed second timer
start_time = time.time()

#Comment out the 'seed line' when software development is done
#random.seed(12345)

# Initialize the lists
# Permutations  6 items is 720   8 items taken 6 at a time is 20160
# Guess: Average Number of iterations for max value is 20160 (Average of 12 runs = 16604)
hole_list  = [2.0000, 2.0001, 2.0005, 2.0006, 2.0007, 2.0011]
shaft_list = [1.9968, 1.9969, 1.9970, 1.9971, 1.9972, 1.9973, 1.9974, 1.9975]

# Convert lists to integer to avoid floating point subtraction rounding errors
# NOTE: int(2.0018 * 10000) = 20017 (hence the need for round()
hole_list  = [int(round(i * 10000, 1)) for i in hole_list]
shaft_list = [int(round(i * 10000, 1)) for i in shaft_list]

# Sort the lists to enable removing either 'large holes' or 'small shafts' from the rear of the list
hole_list.sort()
shaft_list.sort(reverse=True)

# Get the number of items to compare
# either the minimum number of 'shafts' or the minimum number of 'holes'
ihole_item_count = len(hole_list)
ishaft_item_count = len(shaft_list)
icount = min(ihole_item_count, ishaft_item_count)

#Initialize the final list
my_final_list = []
my_final_list = [[0] * 4 for i in range(icount)]

iiteration_number = 0
imax_score = 0

# Perform the required number of simulations
for iiteration_number in range(NUMBER_OF_ITERATIONS):
    #
    # Initialize the result score
    iscore = 0
    #
    # Only one list has to be randomized - the list with the greater number of items
    if ihole_item_count >= ishaft_item_count:
      random.shuffle(hole_list)
    else:
      random.shuffle(shaft_list)
    #
    for i in range(icount):
        ihole_size = hole_list[i]
        ishaft_size = shaft_list[i]
        idelta = ihole_size - ishaft_size
        ilineitem_score = calculate_lineitem_score(idelta)
        iscore += ilineitem_score
    #
    # Update the 'final list' if the score is greater than the existing max score
    if iscore > imax_score:
        imax_score = iscore
        print("New Max score of {:>4} on iteration {:>9,d} of {:>9,d} iterations.".format(imax_score, iiteration_number + 1, NUMBER_OF_ITERATIONS))
    #        
        iscore = 0
        for ii in range(icount):
            ihole_size = hole_list[ii]
            ishaft_size = shaft_list[ii]
            idelta =ihole_size - ishaft_size
            ilineitem_score = calculate_lineitem_score(idelta)
            iscore += ilineitem_score
            my_final_list[ii] = [ihole_size/10000, ishaft_size/10000, idelta/10000, ilineitem_score]

# Print score criteria
s = """
Score Criteria:
0.0025 inches thru 0.0029 inches, score =   1 
0.0030 inches thru 0.0034 inches, score =   6
0.0035 inches thru 0.0039 inches, score =  10
0.0040 inches thru 0.0055 inches, score = -10"""
print(s)            

#Sort the final list by 'Delta' then by 'Hole Diameter'
my_final_list=sorted(my_final_list, key=operator.itemgetter(2,0))
            
# Print final results
s = """
Final Results:
  n   Hole     Shaft    Delta    Score
      Diameter Diameter
"""      
print(s)
for i,z in enumerate(my_final_list, 1):
    print("{:>3d}{:>9.4f}{:>9.4f}{:>9.4f}{:>6d}".format(i, round(z[0],4), round(z[1],4), round(z[2],4), z[3]))
print("{}       ====".format(MY_SPACE*25))
print("      Total score: {:>17d}".format(imax_score))

print()
elapsed_time = time.time() - start_time
print("Elapsed time is {:.2f} seconds.".format(elapsed_time))
Click to hide/display output.

Lewis
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply
#2
I want to know how you can sort a randomly distributed list of a certain number of integers between a certain range without using any built-in functions or external libraries.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Basic] Basic Python Tutorial (Playlist) coffeejunkie34 0 836 Sep-28-2023, 12:18 PM
Last Post: coffeejunkie34
  Is there a good tutorial on installing Python correctly on Windows? CynthiaMoore 4 2,078 Aug-31-2022, 12:47 PM
Last Post: snippsat
  Complete Python Tutorial jamessidis 2 5,254 Dec-04-2020, 07:48 PM
Last Post: khalifa
  [Basic] Python Tutorial for Beginners MK_CodingSpace 0 2,196 Dec-03-2020, 09:43 PM
Last Post: MK_CodingSpace
  Python Scrapy Tutorial Knight18 0 3,932 Oct-19-2020, 04:56 PM
Last Post: Knight18
  [Basic] The ‘Pythonic’ Python Tutorial! TheMachinePreacher 5 8,002 Mar-12-2020, 09:20 PM
Last Post: DimaBereza
  12 mini games python tutorial series ninedeadeyes 2 2,409 Feb-16-2020, 11:18 PM
Last Post: ninedeadeyes
  [Basic] Python Tutorial for Beginners in One Lesson (98 minutes) artur_m 0 4,020 Jan-23-2020, 09:15 AM
Last Post: artur_m
  Complete Python 3 Tutorial Series KodeBlog 0 5,166 Sep-06-2019, 10:00 AM
Last Post: KodeBlog
  Tutorial for Python, Flask > data into a form Ecniv 1 2,394 May-01-2019, 07:49 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020