Math & Numbers
Random Number Generation
Games need dice rolls, simulations require randomized inputs, and security systems demand unpredictable tokens. The random module provides pseudo-random number generation for games and simulations, while the secrets module offers cryptographically secure randomness for security-sensitive applications.
Statistical Distributions
Random numbers following specific distributions:
basic.py
# Basic random functions
import random
random.seed(42)
# Basic random
print("Basic random:")
# random() - [0.0, 1.0)
print("random():")
for _ in range(5):
print(f" {random.random():.6f}")
# randint(a, b) - [a, b] inclusive
print("\nrandint(1, 100):")
for _ in range(10):
print(f" {random.randint(1, 100)}", end=" ")
print()
# randrange(stop) - [0, stop)
print("\nrandrange(10):")
for _ in range(10):
print(f" {random.randrange(10)}", end=" ")
print()
# randrange(start, stop) - [start, stop)
print("\nrandrange(10, 20):")
for _ in range(10):
print(f" {random.randrange(10, 20)}", end=" ")
print()
# randrange(start, stop, step)
print("\nrandrange(0, 100, 10) - multiples of 10:")
for _ in range(10):
print(f" {random.randrange(0, 100, 10)}", end=" ")
print()
# uniform(a, b) - [a, b] or [a, b)
print("\nuniform(0.0, 10.0):")
for _ in range(5):
print(f" {random.uniform(0.0, 10.0):.2f}")
# triangular(low, high, mode)
print("\ntriangular(0, 100, 50):")
for _ in range(5):
print(f" {random.triangular(0, 100, 50):.2f}")
# choice(seq) - random element
print("\nchoice from list:")
colors =
for _ in range(10):
print(f" {random.choice(colors)}", end=" ")
print()
# choices(seq, k=) - with replacement
print("\nchoices (with replacement, k=5):")
print(f" {random.choices(colors, k=5)}")
# sample(seq, k) - without replacement
print("\nsample (without replacement, k=3):")
for _ in range(3):
print(f" {random.sample(colors, k=3)}")
# shuffle(list) - in-place shuffle
print("\nshuffle:")
numbers = list(range(1, 11))
print(f"Original: {numbers}")
random.shuffle(numbers)
print(f"Shuffled: {numbers}")
# gauss(mu, sigma) - Gaussian distribution
print("\ngauss(50, 10) - mean=50, stddev=10:")
for _ in range(10):
print(f" {random.gauss(50, 10):.2f}")
# seed() for reproducibility
print("\nSeeded random (seed=42):")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}") # Same sequence
# getstate() and setstate()
print("\nSave/restore state:")
state = random.getstate()
print(f" {[random.randint(1, 10) for _ in range(3)]}")
random.setstate(state)
print(f" {[random.randint(1, 10) for _ in range(3)]}") # Same
# Random instance (separate state)
print("\nRandom instance:")
rng = random.Random(42)
print(f" {[rng.randint(1, 100) for _ in range(5)]}")
# Basic random functions
import random
random.seed(42)
# Basic random
print("Basic random:")
# random() - [0.0, 1.0)
print("random():")
for _ in range(5):
print(f" {random.random():.6f}")
# randint(a, b) - [a, b] inclusive
print("\nrandint(1, 100):")
for _ in range(10):
print(f" {random.randint(1, 100)}", end=" ")
print()
# randrange(stop) - [0, stop)
print("\nrandrange(10):")
for _ in range(10):
print(f" {random.randrange(10)}", end=" ")
print()
# randrange(start, stop) - [start, stop)
print("\nrandrange(10, 20):")
for _ in range(10):
print(f" {random.randrange(10, 20)}", end=" ")
print()
# randrange(start, stop, step)
print("\nrandrange(0, 100, 10) - multiples of 10:")
for _ in range(10):
print(f" {random.randrange(0, 100, 10)}", end=" ")
print()
# uniform(a, b) - [a, b] or [a, b)
print("\nuniform(0.0, 10.0):")
for _ in range(5):
print(f" {random.uniform(0.0, 10.0):.2f}")
# triangular(low, high, mode)
print("\ntriangular(0, 100, 50):")
for _ in range(5):
print(f" {random.triangular(0, 100, 50):.2f}")
# choice(seq) - random element
print("\nchoice from list:")
colors =
for _ in range(10):
print(f" {random.choice(colors)}", end=" ")
print()
# choices(seq, k=) - with replacement
print("\nchoices (with replacement, k=5):")
print(f" {random.choices(colors, k=5)}")
# sample(seq, k) - without replacement
print("\nsample (without replacement, k=3):")
for _ in range(3):
print(f" {random.sample(colors, k=3)}")
# shuffle(list) - in-place shuffle
print("\nshuffle:")
numbers = list(range(1, 11))
print(f"Original: {numbers}")
random.shuffle(numbers)
print(f"Shuffled: {numbers}")
# gauss(mu, sigma) - Gaussian distribution
print("\ngauss(50, 10) - mean=50, stddev=10:")
for _ in range(10):
print(f" {random.gauss(50, 10):.2f}")
# seed() for reproducibility
print("\nSeeded random (seed=42):")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}") # Same sequence
# getstate() and setstate()
print("\nSave/restore state:")
state = random.getstate()
print(f" {[random.randint(1, 10) for _ in range(3)]}")
random.setstate(state)
print(f" {[random.randint(1, 10) for _ in range(3)]}") # Same
# Random instance (separate state)
print("\nRandom instance:")
rng = random.Random(42)
print(f" {[rng.randint(1, 100) for _ in range(5)]}")
# Basic random functions
import random
random.seed(42)
# Basic random
print("Basic random:")
# random() - [0.0, 1.0)
print("random():")
for _ in range(5):
print(f" {random.random():.6f}")
# randint(a, b) - [a, b] inclusive
print("\nrandint(1, 100):")
for _ in range(10):
print(f" {random.randint(1, 100)}", end=" ")
print()
# randrange(stop) - [0, stop)
print("\nrandrange(10):")
for _ in range(10):
print(f" {random.randrange(10)}", end=" ")
print()
# randrange(start, stop) - [start, stop)
print("\nrandrange(10, 20):")
for _ in range(10):
print(f" {random.randrange(10, 20)}", end=" ")
print()
# randrange(start, stop, step)
print("\nrandrange(0, 100, 10) - multiples of 10:")
for _ in range(10):
print(f" {random.randrange(0, 100, 10)}", end=" ")
print()
# uniform(a, b) - [a, b] or [a, b)
print("\nuniform(0.0, 10.0):")
for _ in range(5):
print(f" {random.uniform(0.0, 10.0):.2f}")
# triangular(low, high, mode)
print("\ntriangular(0, 100, 50):")
for _ in range(5):
print(f" {random.triangular(0, 100, 50):.2f}")
# choice(seq) - random element
print("\nchoice from list:")
colors =
for _ in range(10):
print(f" {random.choice(colors)}", end=" ")
print()
# choices(seq, k=) - with replacement
print("\nchoices (with replacement, k=5):")
print(f" {random.choices(colors, k=5)}")
# sample(seq, k) - without replacement
print("\nsample (without replacement, k=3):")
for _ in range(3):
print(f" {random.sample(colors, k=3)}")
# shuffle(list) - in-place shuffle
print("\nshuffle:")
numbers = list(range(1, 11))
print(f"Original: {numbers}")
random.shuffle(numbers)
print(f"Shuffled: {numbers}")
# gauss(mu, sigma) - Gaussian distribution
print("\ngauss(50, 10) - mean=50, stddev=10:")
for _ in range(10):
print(f" {random.gauss(50, 10):.2f}")
# seed() for reproducibility
print("\nSeeded random (seed=42):")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}")
random.seed(42)
print(f" {[random.randint(1, 100) for _ in range(5)]}") # Same sequence
# getstate() and setstate()
print("\nSave/restore state:")
state = random.getstate()
print(f" {[random.randint(1, 10) for _ in range(3)]}")
random.setstate(state)
print(f" {[random.randint(1, 10) for _ in range(3)]}") # Same
# Random instance (separate state)
print("\nRandom instance:")
rng = random.Random(42)
print(f" {[rng.randint(1, 100) for _ in range(5)]}")
ranges.py
# Random ranges and distributions
import random
random.seed(42)
# Random ranges
print("Random ranges:")
# Range [0, n)
print("Range [0, 100):")
print(f" {[random.randrange(100) for _ in range(10)]}")
# Range [a, b] inclusive
print("\nRange [10, 20] inclusive:")
print(f" {[random.randint(10, 20) for _ in range(10)]}")
# Range [a, b) exclusive
print("\nRange [10, 20) exclusive:")
print(f" {[random.randrange(10, 20) for _ in range(10)]}")
# Float range [a, b]
print("\nFloat range [0.0, 10.0]:")
print(f" {[random.uniform(0.0, 10.0) for _ in range(5)]}")
# Negative range
print("\nNegative range [-10, 10]:")
print(f" {[random.randint(-10, 10) for _ in range(10)]}")
# Dice roll (1-6)
print("\nDice rolls:")
rolls = [random.randint(1, 6) for _ in range(60)]
total_rolls = len(rolls)
for i in range(1, 7):
count = rolls.count(i)
percent = count / total_rolls * 100
print(f" {i}: {count} times ({percent:.1f}%)")
# Coin flip
print("\nCoin flips:")
flips = [random.choice(['H', 'T']) for _ in range(40)]
heads = flips.count('H')
tails = flips.count('T')
total_flips = len(flips)
print(f" Heads: {heads} ({heads / total_flips * 100:.1f}%)")
print(f" Tails: {tails} ({tails / total_flips * 100:.1f}%)")
# Weighted random
print("\nWeighted random:")
outcomes = ['common', 'uncommon', 'rare', 'epic']
weights = [50, 30, 15, 5]
results = random.choices(outcomes, weights=weights, k=40)
total_results = len(results)
for outcome in outcomes:
count = results.count(outcome)
percent = count / total_results * 100
print(f" {outcome}: {count} ({percent:.1f}%)")
# Probability check
print("\n20% probability:")
probability_trials = 40
successes = sum(1 for _ in range(probability_trials) if random.random() < 0.20)
print(f" Successes: {successes} ({successes / probability_trials * 100:.1f}%)")
# Random steps
print("\nRandom steps (2, 5, 10):")
steps = [random.choice([2, 5, 10]) for _ in range(10)]
print(f" {steps}")
# Multiples of 5
print("\nRandom multiples of 5 [0, 100):")
print(f" {[random.randrange(0, 100, 5) for _ in range(10)]}")
# Random percentage
print("\nRandom percentages:")
percentages = [random.uniform(0, 100) for _ in range(5)]
for p in percentages:
print(f" {p:.2f}%")
# Helper functions
def rand_range(a, b):
"""Random int in [a, b] inclusive."""
return random.randint(a, b)
def rand_float(a, b):
"""Random float in [a, b]."""
return random.uniform(a, b)
def probability(p):
"""Return True with probability p."""
return random.random() < p
print("\nHelper functions:")
print(f"rand_range(10, 20): {[rand_range(10, 20) for _ in range(5)]}")
print(f"rand_float(0, 1): {[rand_float(0, 1) for _ in range(5)]}")
print(f"probability(0.3): {[probability(0.3) for _ in range(10)]}")
shuffle.py
# Shuffling and sampling
import random
random.seed(42)
# Shuffling
print("Shuffling:")
# Shuffle list (in-place)
names = ['Alice', 'Bob', 'Charlie', 'David', 'Eve']
print(f"Original: {names}")
random.shuffle(names)
print(f"Shuffled: {names}")
# Shuffle with seed
print("\nShuffle with seed:")
nums1 = list(range(1, 11))
nums2 = list(range(1, 11))
random.seed(42)
random.shuffle(nums1)
random.seed(42)
random.shuffle(nums2)
print(f"First: {nums1}")
print(f"Second: {nums2}")
print(f"Same: {nums1 == nums2}")
# Sample (without replacement)
print("\nSample (without replacement):")
population = list(range(1, 11))
for _ in range(5):
sample = random.sample(population, k=3)
print(f" {sample}")
# Choices (with replacement)
print("\nChoices (with replacement):")
for _ in range(5):
choices = random.choices(population, k=3)
print(f" {choices}")
# Sample entire population (shuffle alternative)
print("\nSample entire population:")
shuffled = random.sample(population, k=len(population))
print(f" {shuffled}")
# Pick random element
print("\nPick random element:")
colors = ['red', 'green', 'blue', 'yellow', 'purple']
for _ in range(10):
color = random.choice(colors)
print(f" {color}", end=" ")
print()
# Weighted sampling
print("\nWeighted sampling:")
items = ['common', 'uncommon', 'rare', 'legendary']
weights = [50, 30, 15, 5]
print("Weighted choices (k=10):")
for _ in range(5):
result = random.choices(items, weights=weights, k=10)
print(f" {result}")
# Random permutation
print("\nRandom permutations of 'ABCD':")
chars = ['A', 'B', 'C', 'D']
for _ in range(5):
perm = random.sample(chars, k=len(chars))
print(f" {''.join(perm)}")
# Deal cards
print("\nDeal cards:")
suits = ['♠', '♥', '♦', '♣']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
deck = [f"{rank}{suit}" for suit in suits for rank in ranks]
random.shuffle(deck)
print(f"Original (first 13): {deck[:13]}")
# Deal hands
print("\nDeal 4 hands of 5 cards:")
for player in range(4):
hand = deck[player*5:(player+1)*5]
print(f" Player {player+1}: {hand}")
# Random subset
print("\nRandom subsets:")
data = list(range(1, 21))
for size in [3, 5, 10]:
subset = random.sample(data, k=size)
print(f" Size {size}: {subset}")
# Random pairs
print("\nRandom pairs:")
people = ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank']
shuffled = random.sample(people, k=len(people))
pairs = [(shuffled[i], shuffled[i+1]) for i in range(0, len(shuffled)-1, 2)]
for pair in pairs:
print(f" {pair[0]} <-> {pair[1]}")
strings.py
# Random strings and data
import random
import string
random.seed(42)
# Random strings
print("Random strings:")
# Random letters
print("Random letters:")
letters = [random.choice(string.ascii_lowercase) for _ in range(10)]
print(f" {''.join(letters)}")
# Random uppercase
print("\nRandom uppercase:")
uppercase = [random.choice(string.ascii_uppercase) for _ in range(10)]
print(f" {''.join(uppercase)}")
# Random digits
print("\nRandom digits:")
digits = [random.choice(string.digits) for _ in range(10)]
print(f" {''.join(digits)}")
# Random alphanumeric
print("\nRandom alphanumeric:")
def random_alphanumeric(length):
"""Generate random alphanumeric string."""
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
for _ in range(5):
print(f" {random_alphanumeric(12)}")
# Random password
print("\nRandom passwords:")
def random_password(length=12):
"""Generate random password with all character types."""
chars = string.ascii_letters + string.digits + string.punctuation
while True:
password = ''.join(random.choices(chars, k=length))
# Ensure at least one of each type
if (any(c.islower() for c in password) and
any(c.isupper() for c in password) and
any(c.isdigit() for c in password) and
any(c in string.punctuation for c in password)):
return password
for _ in range(5):
print(f" {random_password(16)}")
# Random hex
print("\nRandom hex strings:")
def random_hex(length):
"""Generate random hex string."""
return ''.join(random.choices('0123456789abcdef', k=length))
for _ in range(5):
print(f" {random_hex(16)}")
# Random UUID-like
print("\nRandom UUID-like:")
def random_uuid():
"""Generate random UUID-like string."""
return f"{random_hex(8)}-{random_hex(4)}-{random_hex(4)}-{random_hex(4)}-{random_hex(12)}"
for _ in range(3):
print(f" {random_uuid()}")
# Random email
print("\nRandom emails:")
def random_email():
"""Generate random email address."""
username = ''.join(random.choices(string.ascii_lowercase, k=8))
domain = random.choice(['gmail.com', 'yahoo.com', 'hotmail.com', 'example.com'])
return f"{username}@{domain}"
for _ in range(5):
print(f" {random_email()}")
# Random phone
print("\nRandom phone numbers:")
def random_phone():
"""Generate random phone number."""
area = random.randint(200, 999)
exchange = random.randint(200, 999)
number = random.randint(0, 9999)
return f"({area:03d}) {exchange:03d}-{number:04d}"
for _ in range(5):
print(f" {random_phone()}")
# Random name
print("\nRandom names:")
first_names = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
last_names = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller']
for _ in range(5):
name = f"{random.choice(first_names)} {random.choice(last_names)}"
print(f" {name}")
# Random date
print("\nRandom dates:")
import datetime
def random_date(start_year=2020, end_year=2024):
"""Generate random date."""
year = random.randint(start_year, end_year)
month = random.randint(1, 12)
day = random.randint(1, 28) # Simplified
return datetime.date(year, month, day)
for _ in range(5):
print(f" {random_date()}")
# Random color
print("\nRandom RGB colors:")
def random_color():
"""Generate random RGB color."""
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
return f"#{r:02x}{g:02x}{b:02x}"
for _ in range(5):
print(f" {random_color()}")
distributions.py
# Distributions
import random
import math
random.seed(42)
# Distributions
print("Distributions:")
trials = 50
# Uniform distribution [0, 100)
print("Uniform distribution [0, 100):")
uniform = [0] * 10
for _ in range(trials):
value = random.randint(0, 99)
bin_idx = value // 10
uniform[bin_idx] += 1
for i, count in enumerate(uniform):
bar = 'â–ˆ' * max(1, count // 2)
print(f"[{i*10}-{(i+1)*10}): {count:4d} ({count/trials*100:.1f}%) {bar}")
# Gaussian (normal) distribution
print("\nGaussian distribution (mean=50, stddev=10):")
gaussian = [0] * 10
for _ in range(trials):
value = random.gauss(50, 10)
bin_idx = max(0, min(9, int(value // 10)))
gaussian[bin_idx] += 1
for i, count in enumerate(gaussian):
bar = 'â–ˆ' * max(1, count // 2)
print(f"[{i*10}-{(i+1)*10}): {count:4d} ({count/trials*100:.1f}%) {bar}")
# Exponential distribution
print("\nExponential distribution (lambda=0.1):")
def exponential_random(lambda_param):
"""Generate exponential random variable."""
return -math.log(1 - random.random()) / lambda_param
exponential = [0] * 10
for _ in range(trials):
value = exponential_random(0.1)
bin_idx = min(9, int(value // 10))
exponential[bin_idx] += 1
for i, count in enumerate(exponential):
bar = 'â–ˆ' * max(1, count // 2)
print(f"[{i*10}-{(i+1)*10}): {count:4d} ({count/trials*100:.1f}%) {bar}")
# Binomial distribution (coin flips)
print("\nBinomial distribution (10 flips, p=0.5):")
binomial = [0] * 11
for _ in range(trials):
heads = sum(random.random() < 0.5 for _ in range(10))
binomial[heads] += 1
print("Number of heads:")
for i, count in enumerate(binomial):
print(f"{i:2d}: {count:4d} ({count/trials*100:.1f}%)")
# Triangle distribution
print("\nTriangle distribution [0, 100, mode=50]:")
triangle = [0] * 10
for _ in range(trials):
value = random.triangular(0, 100, 50)
bin_idx = min(9, int(value // 10))
triangle[bin_idx] += 1
for i, count in enumerate(triangle):
bar = 'â–ˆ' * max(1, count // 2)
print(f"[{i*10}-{(i+1)*10}): {count:4d} ({count/trials*100:.1f}%) {bar}")
# Beta distribution (using acceptance-rejection)
print("\nBeta-like distribution:")
def beta_random(alpha, beta):
"""Simple beta random using acceptance-rejection."""
while True:
u = random.random()
v = random.random()
if v <= u**(alpha-1) * (1-u)**(beta-1):
return u
beta_dist = [0] * 10
for _ in range(trials):
value = beta_random(2, 5) * 100
bin_idx = min(9, int(value // 10))
beta_dist[bin_idx] += 1
for i, count in enumerate(beta_dist):
bar = 'â–ˆ' * max(1, count // 2)
print(f"[{i*10}-{(i+1)*10}): {count:4d} ({count/trials*100:.1f}%) {bar}")
# Poisson distribution
print("\nPoisson distribution (lambda=5):")
def poisson_random(lambda_param):
"""Generate Poisson random variable."""
L = math.exp(-lambda_param)
k = 0
p = 1.0
while p > L:
k += 1
p *= random.random()
return k - 1
poisson = [0] * 15
for _ in range(trials):
events = poisson_random(5.0)
if events < len(poisson):
poisson[events] += 1
print("Number of events:")
for i, count in enumerate(poisson[:12]):
print(f"{i:2d}: {count:4d} ({count/trials*100:.1f}%)")
pseudo-random
Numbers generated by a deterministic algorithm that appear random but are reproducible given the same seed - suitable for games and simulations but not security.
seed()
Initializes the random number generator to produce reproducible sequences - essential for testing and debugging randomized code.
choice vs sample
choice() picks one item with replacement, sample() picks multiple unique items without replacement, choices() picks multiple with replacement.
Exercise: practical.py
Create a dice game that rolls multiple dice and determines the winner