020. Modulus Operator
Remainder reveals cyclic patterns
020. Modulus Operator
RAM Manager — Round-Robin Monitoring
Aryan’s RAM manager polls multiple servers in round-robin order. With 5 worker threads and an ever-growing list of servers, each poll cycle should assign servers to workers evenly:
Server 0 → Worker 0
Server 1 → Worker 1
Server 5 → Worker 0 (wraps back around)
Server 11 → Worker 1He writes assign_worker(server_id, num_workers), but uses // (floor division) instead of % (modulo). So assign_worker(5, 5) returns 1 (the quotient of 5÷5) instead of 0 (the remainder), and all workers get wrong assignments after the first cycle.
The lesson:
//gives the quotient (how many times it fits);%gives the remainder (what’s left over). Cyclic assignment needs the remainder.
💡 Fun fact: Python’s modulo operator always returns a non-negative result when the divisor is positive — -1 % 7 gives 6, not -1 (unlike C and Java). This makes Python’s % perfect for clock arithmetic and cyclic indexing, because the result always falls within [0, divisor).
⚠️ Watch out: Using // (quotient) instead of % (remainder) for round-robin assignment is a silent bug — 5 // 5 = 1 while 5 % 5 = 0. The code runs without error but assigns workers in the wrong pattern, and it only becomes obvious after the first full cycle wraps around.
🤔 Think about it: The leap year rule has three parts: divisible by 4, except centuries, unless divisible by 400. This rule was introduced in 1582 with the Gregorian calendar reform. Why does a purely mathematical rule like modulo need three separate conditions to handle a real-world calendar?
Learning objectives
- Use % to compute remainders
- Apply modulo for cyclic/round-robin assignments
- Use modulo in divisibility tests
Key concepts
- modulus
- %
- remainder
- cyclic
Try it
Concept detail
The modulo operator % returns the remainder after division. 10 % 3 = 1. Key patterns: n % 2 == 0 → even, n % k == 0 → divisible by k. Cycling: index % length wraps around (round-robin, clock arithmetic). In Python, the result always has the same sign as the divisor (unlike C/Java): -1 % 7 = 6 (Python), but -1 % 7 = -1 (C). This makes clock math correct. Combined with //: n = (n // k) * k + (n % k) is always true.
Solution
def assign_worker(task_id, num_workers):
return task_id % num_workers
def is_even(n):
return n % 2 == 0
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)Tests
def test_assign_worker_basic():
assert assign_worker(0, 3) == 0
assert assign_worker(1, 3) == 1
assert assign_worker(2, 3) == 2
assert assign_worker(3, 3) == 0
def test_is_even_true():
assert is_even(4) == True
assert is_even(0) == True
def test_is_even_false():
assert is_even(3) == False
assert is_even(7) == False
def test_leap_year_div4():
assert is_leap_year(2024) == True
def test_not_leap_century():
assert is_leap_year(1900) == False
def test_leap_400():
assert is_leap_year(2000) == True