Python Modulus Operator Tutorial

Final Exam & Certification

Complete this tutorial and pass the 12-question final exam to earn a downloadable certificate of completion.

skip to exam

The Python modulus operator % returns the remainder after division. It is one of the most useful tools in the language — small enough to fit on one line, powerful enough to appear in scheduling logic, game loops, data pipelines, and unit conversion routines. This tutorial covers how it works, how it handles negative numbers, how it differs from math.fmod(), and the precedence rules that trip up programmers who mix it with multiplication and division.

What's in this Python Tutorial

Whether you need to filter every third row in a dataset, wrap a playlist index, or convert a raw number of seconds into hours, minutes, and seconds, % makes the job straightforward. This tutorial covers the mechanics, the edge cases, the math.fmod() distinction that separates Python's behavior from C and JavaScript, the precedence rules, and the patterns that appear again and again in real Python code.

How the Modulus Operator Works

Division produces two values: a quotient and a remainder. Python's floor division operator // gives you the quotient; % gives you the remainder. The two are related by a simple identity:

python
# The modulus identity
# (a // b) * b + (a % b) == a

a = 17
b = 5

quotient  = a // b   # 3
remainder = a % b    # 2

print(quotient)   # 3
print(remainder)  # 2

# Verify the identity
print(quotient * b + remainder == a)  # True

Read 17 % 5 as: "17 divided by 5 is 3 with 2 left over." The % expression evaluates to that leftover value, 2.

Note

When both operands are positive integers, the result of a % b is always in the range 0 to b - 1 (inclusive) — it can never be greater than or equal to the divisor. When the divisor is negative, the result falls in the range b + 1 to 0 instead. Python's % always carries the sign of the divisor.

A quick way to build intuition is to walk through several examples and observe the pattern:

Expression Result Reasoning
10 % 3110 = 3 × 3 + 1
15 % 5015 = 5 × 3 + 0 (evenly divisible)
7 % 1077 = 10 × 0 + 7 (dividend smaller than divisor)
100 % 72100 = 7 × 14 + 2
1 % 10Any number divided by itself has remainder 0

When the dividend is smaller than the divisor, the quotient is zero and the remainder is the dividend itself. That is why 7 % 10 returns 7 — Python cannot fit even one copy of 10 into 7, so the entire value is leftover.

code builder click a token to place it

Build the correct Python expression that checks whether the variable n is divisible by 4 (remainder equals zero):

your code will appear here...
4 n == != % // 0
Why: The correct expression is n % 4 == 0. The % operator gives the remainder of n divided by 4. When that remainder is 0, n is divisible by 4. Using // gives the quotient, not the remainder, so it would not test divisibility. Using != would detect numbers that are not divisible by 4.

Common Uses of the % Operator

The modulus operator appears in a surprisingly wide variety of everyday programming tasks. The four patterns below cover the majority of situations you will encounter.

Even and Odd Detection

The most common use is determining whether a number is even or odd. An even number divided by 2 leaves no remainder; an odd number leaves 1.

python
def classify(n):
    if n % 2 == 0:
        return "even"
    return "odd"

print(classify(8))   # even
print(classify(13))  # odd
print(classify(0))   # even (zero is even)

Cyclic Indexing

Modulus is the standard way to keep an index within the bounds of a sequence. When the index reaches the end, % len(sequence) wraps it back to the beginning.

python
colors = ["red", "green", "blue"]

for i in range(9):
    color = colors[i % len(colors)]
    print(f"Item {i}: {color}")

# Item 0: red
# Item 1: green
# Item 2: blue
# Item 3: red   <-- wraps back
# Item 4: green
# ...
Pro Tip

Cyclic indexing with % is how rotation ciphers, round-robin schedulers, and playlist repeat features are commonly implemented — the pattern is the same regardless of the domain.

Divisibility Testing

When n % k == 0, k divides n evenly. This is the foundation of the classic FizzBuzz problem and many number-theory exercises.

python
for n in range(1, 21):
    if n % 15 == 0:
        print("FizzBuzz")
    elif n % 3 == 0:
        print("Fizz")
    elif n % 5 == 0:
        print("Buzz")
    else:
        print(n)

Rate-Limiting Repeated Actions

In a long loop you often want to run a side effect (print progress, flush a buffer, log a status) every n iterations without breaking the loop's structure. Checking i % n == 0 accomplishes exactly that.

python
records = list(range(1000))

for i, record in enumerate(records):
    process(record)
    if i % 100 == 0:           # log every 100 items
        print(f"Processed {i} records...")
What it returns
The leftover after dividing dividend by divisor
Example
17 % 52
What it returns
The integer quotient, rounded down toward negative infinity
Example
17 // 53
What it returns
A tuple (a // b, a % b) in a single built-in call
Example
divmod(17, 5)(3, 2)
spot the bug click the line that contains the bug

The function below is supposed to return True if n is divisible by 3, and False otherwise. One line contains the bug. Click it, then hit check.

1 def divisible_by_3(n):
2 return n // 3 == 0
3
4 print(divisible_by_3(9)) # expected True
5 print(divisible_by_3(7)) # expected False
The fix: Change n // 3 == 0 to n % 3 == 0. The // operator performs floor division, returning the quotient. For n = 9, 9 // 3 is 3, not 0, so the function incorrectly returns False. The % operator returns the remainder — when that is 0, the number is evenly divisible.

Modulus with Negative Numbers and Floats

Python's behavior with negative operands surprises programmers coming from C or Java. In Python, the result of % always carries the sign of the divisor (the right operand), not the dividend. This is a deliberate design choice tied to floor division.

python
# Negative dividend, positive divisor
print(-7 % 3)    # 2  (NOT -1)

# Positive dividend, negative divisor
print(7 % -3)    # -2 (NOT 2)

# Both negative
print(-7 % -3)   # -1

# Verify the identity still holds
a, b = -7, 3
print((a // b) * b + (a % b) == a)  # True
Watch Out

If you are porting code from C, JavaScript, or Java, double-check any modulus expressions that use negative numbers. Those languages follow the sign of the dividend, which produces different results from Python for negative inputs.

The % operator also works with floats, though the result may include floating-point rounding imprecision. For integer-precision work, stick to integer operands.

python
print(7.5 % 2.5)   # 0.0
print(10.0 % 3.0)  # 1.0
print(1.1 % 0.3)   # 0.19999999999999996  (floating-point imprecision)

math.fmod(): The Other Remainder Function

Python ships a second remainder function in its standard library that behaves differently from % in one critical way: math.fmod(x, y) returns a result whose sign follows the dividend (x), not the divisor. This matches how C's fmod() works and is intentional. The Python documentation for math.fmod() explicitly states that the result has the same sign as the first argument.

python
import math

# % follows the sign of the DIVISOR (y)
print(-7 % 3)            # 2   (positive — matches divisor 3)
print(7 % -3)            # -2  (negative — matches divisor -3)

# math.fmod() follows the sign of the DIVIDEND (x)
print(math.fmod(-7, 3))  # -1.0  (negative — matches dividend -7)
print(math.fmod(7, -3))  # 1.0   (positive — matches dividend 7)

# For positive operands, both agree
print(17 % 5)            # 2
print(math.fmod(17, 5))  # 2.0
Expression % result math.fmod() result Sign follows
-7, 32-1.0% → divisor  |  fmod → dividend
7, -3-21.0% → divisor  |  fmod → dividend
-7, -3-1-1.0Both negative (agree)
17, 522.0Both positive (agree)

The practical rule: use % for integer work and for any situation where you want the result to stay non-negative when the divisor is positive (cyclic indexing, time conversion, even/odd checks). Use math.fmod() when interoperating with C libraries or when you specifically need the C-style truncation behavior with floats. Note that math.fmod() always returns a float, even when both inputs are integers.

Operator Precedence with %

In Python, % shares the same precedence level as *, /, and //. Operators at the same level evaluate left to right. This can produce surprising results when % is mixed with multiplication or division without parentheses.

python
# Left-to-right evaluation at same precedence
result = 4 * 10 % 12     # reads as (4 * 10) % 12 = 40 % 12 = 4
print(result)            # 4

# Adding parentheses changes meaning entirely
result = 4 * (10 % 12)   # reads as 4 * (10 % 12) = 4 * 10 = 40
print(result)            # 40

# % and // at the same level, left-to-right
print(100 % 30 // 4)     # (100 % 30) // 4 = 10 // 4 = 2
print(100 % (30 // 4))   # 100 % 7 = 2  (coincidentally the same here, but not always)
Pro Tip

When % appears in an expression alongside *, /, or //, use explicit parentheses to make the intended evaluation order unambiguous. It costs nothing and prevents subtle bugs.

17 divided by 5 fills 3 complete groups of 5 (quotient = 3) with 2 items remaining (remainder = 2).

How to Use the Modulus Operator in Python

The four steps below cover the most common ways to apply % in real code, from a simple remainder calculation to a full unit-conversion routine.

  1. Write a basic modulus expression

    Place the dividend on the left and the divisor on the right of %. Python evaluates the expression and returns the remainder. For example, remainder = 17 % 5 stores 2 in remainder.

  2. Check whether a number is even or odd

    Use number % 2 == 0 to test for even numbers. When the condition is True, the number is even. When False, it is odd. Zero evaluates as even because 0 % 2 == 0.

  3. Create a cyclic index

    Use index % len(sequence) to wrap an index back to the start of a sequence when it exceeds the length. This prevents IndexError and enables circular iteration through a list of any size.

  4. Convert units using modulus and floor division together

    Combine % and // to extract time or unit components. For 4000 seconds: hours = 4000 // 3600, then minutes = (4000 % 3600) // 60, then seconds = 4000 % 60. Each step isolates one component without affecting the others.

"The % (modulo) operator yields the remainder from the division of the first argument by the second." — Python Language Reference, Binary arithmetic operations (Python Software Foundation)

Python Learning Summary Points

  1. The % operator returns the remainder after dividing the left operand by the right. For positive integer operands, the result is always in the range 0 to divisor - 1. The result can never be greater than or equal to the divisor.
  2. The modulus identity (a // b) * b + (a % b) == a always holds, regardless of the signs of the operands.
  3. Python's % result follows the sign of the divisor, not the dividend — this differs from C, Java, and JavaScript when negative numbers are involved.
  4. math.fmod(x, y) follows the sign of the dividend instead, matching C behavior. It always returns a float. Use % for integer and cyclic work; use math.fmod() when C-compatible float behavior is required.
  5. The four most common applications are: even/odd detection, cyclic indexing, divisibility testing, and rate-limiting repeated actions in loops.
  6. The built-in divmod(a, b) returns (a // b, a % b) in a single call and is more efficient than computing the two values separately.
  7. % shares precedence with *, /, and //. When mixing these operators in one expression, use explicit parentheses to make the evaluation order clear.

Mastering the modulus operator unlocks a pattern that recurs across data processing, game development, scheduling, and cryptography. Once you recognize when a problem involves remainders or cyclic behavior, % becomes your first instinct rather than an afterthought.

check your understanding question 1 of 5

Frequently Asked Questions

The % operator in Python is the modulus operator. It returns the remainder after dividing the left operand by the right operand. For example, 10 % 3 evaluates to 1 because 10 divided by 3 is 3 with a remainder of 1.

Use number % 2. If the result is 0, the number is even. If the result is 1, the number is odd. For example, 8 % 2 == 0 is True (even), and 7 % 2 == 1 is True (odd).

Python's modulus operator follows the sign of the divisor (the right operand), not the dividend. For example, -7 % 3 returns 2, not -1, because Python uses floor division internally. This differs from C and Java, which follow the sign of the dividend.

The // operator is floor division and returns the quotient — how many times the divisor fits into the dividend. The % operator returns the remainder. Together they satisfy the identity: (a // b) * b + (a % b) == a.

Yes. Python's % operator works with floating-point numbers. For example, 7.5 % 2.5 returns 0.0. However, floating-point results can include small rounding errors, so integer modulus is preferred when precision is critical.

Common uses include cycling through a fixed-length list with index % len(list), implementing time conversions such as minutes = total_seconds % 3600 // 60, and rate-limiting repeated actions in loops by checking whether a counter is divisible by a threshold.

Dividing by zero with % raises a ZeroDivisionError in Python. Always validate that the divisor is not zero before using % in production code, or handle the exception with a try/except block.

divmod(a, b) is a Python built-in that returns a tuple of (a // b, a % b) in a single call. It is useful when you need both the quotient and the remainder without computing them separately, and it is slightly more efficient than writing two separate expressions.

Both compute a remainder, but they differ in sign behavior when operands are negative. Python's % result carries the sign of the divisor (right operand). math.fmod(x, y) result carries the sign of the dividend (left operand, matching C behavior). For example, -7 % 3 returns 2, but math.fmod(-7, 3) returns -1.0. Additionally, math.fmod() always returns a float. Use % for integer and cyclic work; use math.fmod() when you need C-compatible float remainder behavior.

Yes. In Python, % shares the same precedence level as *, /, and //. When these operators appear together in an expression without parentheses, Python evaluates them left to right. For example, 4 * 10 % 12 evaluates as (4 * 10) % 12, which is 40 % 12 = 4. Adding explicit parentheses wherever the order matters prevents subtle bugs.

Certificate of Completion
Final Exam
Pass mark: 80% · Score 80% or higher to receive your certificate

Enter your name as you want it to appear on your certificate, then start the exam. Your name is used only to generate your certificate and is never transmitted or stored anywhere.

Question 1 of 10