← Home

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 1

He 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

Resources