Placement Prep

Generate Random Numbers in Python: randint, choice, seed

Python's random module covers seven functions used in placement tests and projects. Covers randint, choice, sample, shuffle, uniform, seed, and the secrets module.

By FACE Prep Team 5 min read
python random-numbers placement-prep coding-interview python-programs

Python’s random module gives you a clean, one-import path to pseudo-random floats, integers, and list operations: the exact toolkit that appears in placement coding rounds and simulation problems.

The module is part of the Python standard library. No additional install required.

import random

The default generator is the Mersenne Twister, a 32-bit pseudo-random algorithm that passes standard statistical tests. It is not cryptographically secure, but it is more than adequate for dice simulations, data sampling, quiz shuffles, and Monte Carlo exercises. The Python random module documentation covers the full API; this article focuses on the seven functions that matter most for placement tests and project work.

What random gives you

Seven functions cover almost every use case:

FunctionReturnsTypical use
random.random()float in [0, 1)Probability gates
random.uniform(a, b)float in [a, b]Continuous ranges
random.randint(a, b)int, both ends inclusiveDice rolls, index picks
random.randrange(start, stop, step)int, stop exclusiveRange-based picks
random.choice(seq)one element from sequenceSingle pick from list
random.sample(seq, k)list of k unique elementsDraw without replacement
random.shuffle(seq)None, modifies in placeRandomise order

The distinction between randint and randrange causes the most wrong answers in placement coding tests, out of all the items in this table. That comparison gets its own section below.

Float randomness: random() and uniform()

random.random() returns a float f where 0 <= f < 1. The left boundary is closed; the right is open. Every call produces a different value from the previous one (unless you fix the seed, covered later).

import random

print(random.random())   # e.g. 0.7324159821
print(random.random())   # different value, same session

random.uniform(a, b) stretches that range to any two bounds. The return value is a + (b - a) * random(), so both endpoints are reachable.

import random

# Float between 5 and 10
sensor_reading = random.uniform(5, 10)
print(sensor_reading)    # e.g. 7.841326409

Both functions appear in simulation problems and probability exercises, particularly in the numerical-aptitude and coding sections of campus recruitment tests for CSE and ECE students.

Integer randomness: randint vs randrange

This is the section that fixes the most placement test wrong answers.

random.randint(a, b) — both ends inclusive

random.randint(a, b) returns a random integer N where a <= N <= b. Both endpoints are included in the possible output.

import random

# Simulates one roll of a fair six-sided die
roll = random.randint(1, 6)
print(roll)    # can be 1, 2, 3, 4, 5, or 6

Writing random.randint(1, 5) to simulate a six-sided die is wrong. It will never return 6. That mistake accounts for a significant portion of logic errors in placement test coding submissions.

random.randrange(start, stop, step) — stop is exclusive

random.randrange(start, stop, step) behaves like Python’s range(): the stop value is excluded from the output.

import random

# Returns 1, 2, 3, 4, or 5 — does NOT return 6
print(random.randrange(1, 6))

# Returns 0, 3, 6, 9, 12, 15, or 18 — not 20
print(random.randrange(0, 20, 3))

Side-by-side comparison (same distribution, different syntax):

CallPossible outputs
random.randint(1, 6)1, 2, 3, 4, 5, 6
random.randrange(1, 7)1, 2, 3, 4, 5, 6
random.randrange(1, 6)1, 2, 3, 4, 5
random.randrange(6)0, 1, 2, 3, 4, 5

randint(1, 6) and randrange(1, 7) produce the same distribution. If you remember only one thing from this section, make it that equivalence.

Picking and rearranging lists: choice, sample, shuffle

These three functions all work on sequences. The differences in mutability and replacement behaviour matter when writing correct code quickly under exam conditions.

random.choice(seq)

Picks and returns one element at random. The original sequence is unchanged.

import random

cities = ["Chennai", "Hyderabad", "Pune", "Bangalore", "Coimbatore"]
print(random.choice(cities))    # e.g. "Pune"
print(cities)                   # unchanged

random.sample(seq, k)

Returns a new list of k unique elements drawn from seq. Non-destructive: the original sequence is not modified. Raises ValueError if k > len(seq).

import random

candidates = ["Arjun", "Priya", "Kiran", "Meena", "Ravi", "Divya"]
shortlist = random.sample(candidates, 3)
print(shortlist)     # e.g. ['Meena', 'Arjun', 'Divya']
print(candidates)    # unchanged: all six names still present

Use sample when you need draw-without-replacement semantics: picking interview slots, assigning test questions, or selecting a random subset of records. For related list-processing patterns, summing elements in a Python list shows how to combine iteration with list operations cleanly.

random.shuffle(seq)

Shuffles the list in place. Returns None. If you need the original order preserved, copy before shuffling.

import random

questions = [1, 2, 3, 4, 5]
random.shuffle(questions)
print(questions)    # e.g. [3, 1, 5, 2, 4]
import random

# Preserve the original
original = [10, 20, 30, 40, 50]
shuffled = original.copy()
random.shuffle(shuffled)
print(original)    # [10, 20, 30, 40, 50] — unchanged
print(shuffled)    # e.g. [40, 10, 50, 20, 30]

The in-place mutation is the most frequent source of bugs when students assign random.shuffle(mylist) to a variable and then print that variable: the variable holds None, not the shuffled list.

Reproducibility with seed() and when to use secrets

random.seed() for consistent output

Every call to the random module draws from the Mersenne Twister’s internal state. random.seed(n) resets that state to a fixed starting point. The same seed produces the same sequence on the same Python version.

import random

random.seed(42)
print(random.randint(1, 100))   # always 82 with seed 42, CPython 3.x
print(random.randint(1, 100))   # always 15
print(random.randint(1, 100))   # always 4

Use cases for seed():

  • Unit-testing functions that call random (fix the seed in setUp, assert the expected result)
  • Reproducing a specific edge case that appeared during one run
  • Generating a deterministic dataset for a classroom exercise or interview demo

Without seed(), each program run produces a different sequence. That’s the correct behaviour for games and simulations; it’s inconvenient for debugging.

When to use secrets instead

For anything security-sensitive, the Mersenne Twister’s predictability is a liability. The Python secrets module uses OS-level randomness and is suitable for generating passwords, tokens, and OTPs.

import secrets

# 6-digit OTP
otp = secrets.randbelow(1000000)
print(f"{otp:06d}")      # e.g. 047832

# 32-character hex token (for API keys, session tokens)
token = secrets.token_hex(16)
print(token)             # e.g. 'b4b4b8a1c3f40d9e2a5f...'

The decision is straightforward: if the output protects a resource (a login session, a payment, an account), use secrets. If it drives a simulation, a quiz shuffle, or a Monte Carlo run, random is the right tool.

The seed() discipline (fixing one variable at a time to isolate its effect) carries directly into LLM experiment work. TinkerLLM (₹299 entry) is built around that same methodology: fix the prompt structure, vary the temperature parameter, measure the output delta. If random.sample() already feels natural in your code, the jump to calling LLM APIs in Python is a smaller step than it looks. The Python programs for practice collection is a good place to build the broader Python fluency before taking that step. For structuring interactive programs with user input, the Python calculator program walkthrough is a practical companion.

Primary sources

Frequently asked questions

Does random.randint(1, 6) include 6 in its output?

Yes. random.randint(a, b) is inclusive on both ends, so randint(1, 6) can return 1, 2, 3, 4, 5, or 6. This is different from range(1, 6), which stops at 5.

What is the difference between random.random() and random.uniform()?

random.random() returns a float in the half-open interval [0, 1). random.uniform(a, b) stretches that to any range, returning a float between a and b inclusive on both ends.

When should I use the secrets module instead of random?

Use secrets for anything security-critical: passwords, API tokens, session keys, OTP generation. The random module uses Mersenne Twister, which is not cryptographically secure.

How do I shuffle only part of a list in Python?

random.shuffle() shuffles the entire list in place. To shuffle a sub-list, use random.sample() on the slice and assign back: lst[2:5] = random.sample(lst[2:5], 3).

Is Python's random module thread-safe?

The module-level functions share a single global Random instance, which is not thread-safe. For multi-threaded code, create a separate random.Random() instance per thread.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF