Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Python Modulo: Using the % Operator
Python supports a wide range of arithmetic operators that you can use when working with numbers in your code. One of these operators is the modulo operator (%
), which returns the remainder of dividing two numbers.
In this tutorial, you’ll learn:
.__mod__()
in your classes to use them with the modulo operatorThe Python modulo operator can sometimes be overlooked. But having a good understanding of this operator will give you an invaluable tool in your Python tool belt.
Free Bonus: Click here to get a Python Cheat Sheet and learn the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.
Modulo in MathematicsThe term modulo comes from a branch of mathematics called modular arithmetic. Modular arithmetic deals with integer arithmetic on a circular number line that has a fixed set of numbers. All arithmetic operations performed on this number line will wrap around when they reach a certain number called the modulus.
A classic example of modulo in modular arithmetic is the twelve-hour clock. A twelve-hour clock has a fixed set of values, from 1 to 12. When counting on a twelve-hour clock, you count up to the modulus 12 and then wrap back to 1. A twelve-hour clock can be classified as “modulo 12,” sometimes shortened to “mod 12.”
The modulo operator is used when you want to compare a number with the modulus and get the equivalent number constrained to the range of the modulus.
For example, say you want to determine what time it would be nine hours after 8:00 a.m. On a twelve-hour clock, you can’t simply add 9 to 8 because you would get 17. You need to take the result, 17, and use mod
to get its equivalent value in a twelve-hour context:
17 mod 12
returns 5
. This means that nine hours past 8:00 a.m. is 5:00 p.m. You determined this by taking the number 17
and applying it to a mod 12
context.
Now, if you think about it, 17
and 5
are equivalent in a mod 12
context. If you were to look at the hour hand at 5:00 and 17:00, it would be in the same position. Modular arithmetic has an equation to describe this relationship:
This equation reads “a
and b
are congruent modulo n
.” This means that a
and b
are equivalent in mod n
as they have the same remainder when divided by n
. In the above equation, n
is the modulus for both a
and b
. Using the values 17
and 5
from before, the equation would look like this:
This reads “17
and 5
are congruent modulo 12
.” 17
and 5
have the same remainder, 5
, when divided by 12
. So in mod 12
, the numbers 17
and 5
are equivalent.
You can confirm this using division:
Both of the operations have the same remainder, 5
, so they’re equivalent modulo 12
.
Now, this may seem like a lot of math for a Python operator, but having this knowledge will prepare you to use the modulo operator in the examples later in this tutorial. In the next section, you’ll look at the basics of using the Python modulo operator with the numeric types int
and float
.
The modulo operator, like the other arithmetic operators, can be used with the numeric types int
and float
. As you’ll see later on, it can also be used with other types like math.fmod()
, decimal.Decimal
, and your own classes.
int
Most of the time you’ll use the modulo operator with integers. The modulo operator, when used with two positive integers, will return the remainder of standard Euclidean division:
Be careful! Just like with the division operator (/
), Python will return a ZeroDivisionError
if you try to use the modulo operator with a divisor of 0
:
Next, you’ll take a look at using the modulo operator with a float
.
float
Similar to int
, the modulo operator used with a float
will return the remainder of division, but as a float
value:
An alternative to using a float
with the modulo operator is to use math.fmod()
to perform modulo operations on float
values:
The official Python docs suggest using math.fmod()
over the Python modulo operator when working with float
values because of the way math.fmod()
calculates the result of the modulo operation. If you’re using a negative operand, then you may see different results between math.fmod(x, y)
and x % y
. You’ll explore using the modulo operator with negative operands in more detail in the next section.
Just like other arithmetic operators, the modulo operator and math.fmod()
may encounter rounding and precision issues when dealing with floating-point arithmetic:
If maintaining floating-point precision is important to your application, then you can use the modulo operator with decimal.Decimal
. You’ll look at this later in this tutorial.
All modulo operations you’ve seen up to this point have used two positive operands and returned predictable results. When a negative operand is introduced, things get more complicated.
As it turns out, the way that computers determine the result of a modulo operation with a negative operand leaves ambiguity as to whether the remainder should take the sign of the dividend (the number being divided) or the sign of the divisor (the number by which the dividend is divided). Different programming languages handle this differently.
For example, in JavaScript, the remainder will take the sign of the dividend:
The remainder in this example, 2
, is positive since it takes the sign of the dividend, 8
. In Python and other languages, the remainder will take the sign of the divisor instead:
Here you can see that the remainder, -1
, takes the sign of the divisor, -3
.
You may be wondering why the remainder in JavaScript is 2
and the remainder in Python is -1
. This has to do with how different languages determine the outcome of a modulo operation. Languages in which the remainder takes the sign of the dividend use the following equation to determine the remainder:
There are three variables this equation:
r
is the remainder.a
is the dividend.n
is the divisor.trunc()
in this equation means that it uses truncated division, which will always round a negative number toward zero. For more clarification, see the steps of the modulo operation below using 8
as the dividend and -3
as the divisor:
Here you can see how a language like JavaScript gets the remainder 2
. Python and other languages in which the remainder takes the sign of the divisor use the following equation:
floor()
in this equation means that it uses floor division. With positive numbers, floor division will return the same result as truncated division. But with a negative number, floor division will round the result down, away from zero:
Here you can see that the result is -1
.
Now that you understand where the difference in the remainder comes from, you may be wondering why this matters if you only use Python. Well, as it turns out, not all modulo operations in Python are the same. While the modulo used with the int
and float
types will take the sign of the divisor, other types will not.
You can see an example of this when you compare the results of 8.0 % -3.0
and math.fmod(8.0, -3.0)
:
math.fmod()
takes the sign of the dividend using truncated division, whereas float
uses the sign of the divisor. Later in this tutorial, you’ll see another Python type that uses the sign of the dividend, decimal.Decimal
.
divmod()
Python has the built-in function divmod()
, which internally uses the modulo operator. divmod()
takes two parameters and returns a tuple containing the results of floor division and modulo using the supplied parameters.
Below is an example of using divmod()
with 37
and 5
:
You can see that divmod(37, 5)
returns the tuple (7, 2)
. The 7
is the result of the floor division of 37
and 5
. The 2
is the result of 37
modulo 5
.
Below is an example in which the second parameter is a negative number. As discussed in the previous section, when the modulo operator is used with an int
, the remainder will take the sign of the divisor:
Now that you’ve had a chance to see the modulo operator used in several scenarios, it’s important to take a look at how Python determines the precedence of the modulo operator when used with other arithmetic operators.
Modulo Operator PrecedenceLike other Python operators, there are specific rules for the modulo operator that determine its precedence when evaluating expressions. The modulo operator (%
) shares the same level of precedence as the multiplication (*
), division (/
), and floor division (//
) operators.
Take a look at an example of the modulo operator’s precedence below:
Both the multiplication and modulo operators have the same level of precedence, so Python will evaluate them from left to right. Here are the steps for the above operation:
4 * 10
is evaluated, resulting in 40 % 12 - 9
.40 % 12
is evaluated, resulting in 4 - 9
.4 - 9
is evaluated, resulting in -5
.If you want to override the precedence of other operators, then you can use parentheses to surround the operation you want to be evaluated first:
In this example, (12 - 9)
is evaluated first, followed by 4 * 10
and finally 40 % 3
, which equals 1
.
Now that you’ve gone through the basics of the Python modulo operator, you’ll look at some examples of using it to solve real-world programming problems. At times, it can be hard to determine when to use the modulo operator in your code. The examples below will give you an idea of the many ways it can be used.
How to Check if a Number Is Even or OddIn this section, you’ll see how you can use the modulo operator to determine if a number is even or odd. Using the modulo operator with a modulus of 2
, you can check any number to see if it’s evenly divisible by 2
. If it is evenly divisible, then it’s an even number.
Take a look at is_even()
which checks to see if the num
parameter is even:
Here num % 2
will equal 0
if num
is even and 1
if num
is odd. Checking against 0
will return a Boolean of True
or False
based on whether or not num
is even.
Checking for odd numbers is quite similar. To check for an odd number, you invert the equality check:
This function will return True
if num % 2
does not equal 0
, meaning that there’s a remainder proving num
is an odd number. Now, you may be wondering if you could use the following function to determine if num
is an odd number:
The answer to this question is yes and no. Technically, this function will work with the way Python calculates modulo with integers. That said, you should avoid comparing the result of a modulo operation with 1
as not all modulo operations in Python will return the same remainder.
You can see why in the following examples:
In the second example, the remainder takes the sign of the negative divisor and returns -1
. In this case, the Boolean check 3 % -2 == 1
would return False
.
However, if you compare the modulo operation with 0
, then it doesn’t matter which operand is negative. The result will always be True
when it’s an even number:
If you stick to comparing a Python modulo operation with 0
, then you shouldn’t have any problems checking for even and odd numbers or any other multiples of a number in your code.
In the next section, you’ll take a look at how you can use the modulo operator with loops to control the flow of your program.
How to Run Code at Specific Intervals in a LoopWith the Python modulo operator, you can run code at specific intervals inside a loop. This is done by performing a modulo operation with the current index of the loop and a modulus. The modulus number determines how often the interval-specific code will run in the loop.
Here’s an example:
This code defines split_names_into_rows()
, which takes two parameters. name_list
is a list of names that should be split into rows. modulus
sets a modulus for the operation, effectively determining how many names should be in each row. split_names_into_rows()
will loop over name_list
and start a new row after it hits the modulus
value.
Before breaking down the function in more detail, take a look at it in action:
As you can see, the list of names has been split into three rows, with a maximum of three names in each row. modulus
defaults to 3
, but you can specify any number:
Now that you’ve seen the code in action, you can break down what it’s doing. First, it uses enumerate()
to iterate over name_list
, assigning the current item in the list to name
and a count value to index
. You can see that the optional start
argument for enumerate()
is set to 1
. This means that the index
count will start at 1
instead of 0
:
Next, inside the loop, the function calls print()
to output name
to the current row. The end
parameter for print()
is an empty string (""
) so it won’t output a newline at the end of the string. An f-string is passed to print()
, which uses the string output formatting syntax that Python provides:
Without getting into too much detail, the :-^15
syntax tells print()
to do the following:
15
characters, even if the string is shorter than 15 characters.-
).Now that the name has been printed to the row, take a look at the main part of split_names_into_rows()
:
This code takes the current iteration index
and, using the modulo operator, compares it with modulus
. If the result equals 0
, then it can run interval-specific code. In this case, the function calls print()
to add a newline, which starts a new row.
The above code is only one example. Using the pattern index % modulus == 0
allows you to run different code at specific intervals in your loops. In the next section, you’ll take this concept a bit further and look at cyclic iteration.
Cyclic iteration describes a type of iteration that will reset once it gets to a certain point. Generally, this type of iteration is used to restrict the index of the iteration to a certain range.
You can use the modulo operator to create cyclic iteration. Take a look at an example using the turtle
library to draw a shape:
The above code uses an infinite loop to draw a repeating star shape. After every six iterations, it changes the color of the pen. The pen size increases with each iteration until i
is reset back to 0
. If you run the code, then you should get something similar to this:
The important parts of this code are highlighted below:
Each time through the loop, i
is updated based on the results of (i + 1) % 6
. This new i
value is used to increase the .pensize
with each iteration. Once i
reaches 5
, (i + 1) % 6
will equal 0
, and i
will reset back to 0
.
You can see the steps of the iteration below for more clarification:
When i
is reset back to 0
, the .pencolor
changes to a new random color as seen below:
The code in this section uses 6
as the modulus, but you could set it to any number to adjust how many times the loop will iterate before resetting the value i
.
In this section, you’ll look at how you can use the modulo operator to convert units. The following examples take smaller units and convert them into larger units without using decimals. The modulo operator is used to determine any remainder that may exist when the smaller unit isn’t evenly divisible by the larger unit.
In this first example, you’ll convert inches into feet. The modulo operator is used to get the remaining inches that don’t evenly divide into feet. The floor division operator (//
) is used to get the total feet rounded down:
Here’s an example of the function in use:
As you can see from the output, 450 % 12
returns 6
, which is the remaining inches that weren’t evenly divided into feet. The result of 450 // 12
is 37
, which is the total number of feet by which the inches were evenly divided.
You can take this a bit further in this next example. convert_minutes_to_days()
takes an integer, total_mins
, representing a number of minutes and outputs the period of time in days, hours, and minutes:
Breaking this down, you can see that the function does the following:
total_mins // 1440
, where 1440
is the number of minutes in a dayextra_minutes
left over with total_mins % 1440
extra_minutes
to get the evenly divisible hours
and any extra minutes
You can see how it works below:
While the above examples only deal with converting inches to feet and minutes to days, you could use any type of units with the modulo operator to convert a smaller unit into a larger unit.
Note: Both of the above examples could be modified to use divmod()
to make the code more succinct. If you remember, divmod()
returns a tuple containing the results of floor division and modulo using the supplied parameters.
Below, the floor division and modulo operators have been replaced with divmod()
:
As you can see, divmod(total_inches, 12)
returns a tuple, which is unpacked into feet
and inches
.
If you try this updated function, then you’ll receive the same results as before:
You receive the same outcome, but now the code is more concise. You could update convert_minutes_to_days()
as well:
Using divmod()
, the function is easier to read than the previous version and returns the same result:
Using divmod()
isn’t necessary for all situations, but it makes sense here as the unit conversion calculations use both floor division and modulo.
Now that you’ve seen how to use the modulo operator to convert units, in the next section you’ll look at how you can use the modulo operator to check for prime numbers.
How to Determine if a Number Is a Prime NumberIn this next example, you’ll take a look at how you can use the Python modulo operator to check whether a number is a prime number. A prime number is any number that contains only two factors, 1
and itself. Some examples of prime numbers are 2
, 3
, 5
, 7
, 23
, 29
, 59
, 83
, and 97
.
The code below is an implementation for determining the primality of a number using the modulo operator:
This code defines check_prime_number()
, which takes the parameter num
and checks to see if it’s a prime number. If it is, then a message is displayed stating that num
is a prime number. If it’s not a prime number, then a message is displayed with all the factors of the number.
Note: The above code isn’t the most efficient way to check for prime numbers. If you’re interested in digging deeper, then check out the Sieve of Eratosthenes and Sieve of Atkin for examples of more performant algorithms for finding prime numbers.
Before you look more closely at the function, here are the results using some different numbers:
Digging into the code, you can see it starts by checking if num
is less than 2
. Prime numbers can only be greater than or equal to 2
. If num
is less than 2
, then the function doesn’t need to continue. It will print()
a message and return
:
If num
is greater than 2
, then the function checks if num
is a prime number. To check this, the function iterates over all the numbers between 2
and the square root of num
to see if any divide evenly into num
. If one of the numbers divides evenly, then a factor has been found, and num
can’t be a prime number.
Here’s the main part of the function:
There’s a lot to unpack here, so let’s take it step by step.
First, a factors
list is created with the initial factors, (1, num)
. This list will be used to store any other factors that are found:
Next, starting with 2
, the code increments i
until it reaches the square root of num
. At each iteration, it compares num
with i
to see if it’s evenly divisible. The code only needs to check up to and including the square root of num
because it wouldn’t contain any factors above this:
Instead of trying to determine the square root of num
, the function uses a while
loop to see if i * i <= num
. As long as i * i <= num
, the loop hasn’t reached the square root of num
.
Inside the while
loop, the modulo operator checks if num
is evenly divisible by i
:
If num
is evenly divisible by i
, then i
is a factor of num
, and a tuple of the factors is added to the factors
list.
Once the while
loop is complete, the code checks to see if any additional factors were found:
If more than one tuple exists in the factors
list, then num
can’t be a prime number. For nonprime numbers, the factors are printed out. For prime numbers, the function prints a message stating that num
is a prime number.
The Python modulo operator can be used to create ciphers. A cipher is a type of algorithm for performing encryption and decryption on an input, usually text. In this section, you’ll look at two ciphers, the Caesar cipher and the Vigenère cipher.
Caesar CipherThe first cipher that you’ll look at is the Caesar cipher, named after Julius Caesar, who used it to secretly communicate messages. It’s a substitution cipher that uses letter substitution to encrypt a string of text.
The Caesar cipher works by taking a letter to be encrypted and shifting it a certain number of positions to the left or right in the alphabet. Whichever letter is in that position is used as the encrypted character. This same shift value is applied to all characters in the string.
For example, if the shift were 5
, then A
would shift up five letters to become F
, B
would become G
, and so on. Below you can see the encryption process for the text REALPYTHON
with a shift of 5
:
The resulting cipher is WJFQUDYMTS
.
Decrypting the cipher is done by reversing the shift. Both the encryption and decryption processes can be described with the following expressions, where char_index
is the index of the character in the alphabet:
This cipher uses the modulo operator to make sure that, when shifting a letter, the index will wrap around if the end of the alphabet is reached. Now that you know how this cipher works, take a look at an implementation:
This code defines a function called caesar_cipher()
, which has two required parameters and one optional parameter:
text
is the text to be encrypted or decrypted.shift
is the number of positions to shift each letter.decrypt
is a Boolean to set if text
should be decrypted.decrypt
is included so that a single function can be used to handle both encryption and decryption. This implementation can handle only alphabetic characters, so the function first checks that text
is an alphabetic character in the ASCII encoding:
The function then defines three variables to store the lowercase
ASCII characters, the uppercase
ASCII characters, and the results of the encryption or decryption:
Next, if the function is being used to decrypt text
, then it multiplies shift
by -1
to make it shift backward:
Finally, caesar_cipher()
loops over the individual characters in text
and performs the following actions for each char
:
char
is lowercase or uppercase.index
of the char
in either the lowercase
or uppercase
ASCII lists.shift
to this index
to determine the index of the cipher character to use.% 26
to make sure the shift will wrap back to the start of the alphabet.result
string.After the loop finishes iterating over the text
value, the result
is returned:
Here’s the full code again:
Now run the code in the Python REPL using the text meetMeAtOurHideOutAtTwo
with a shift of 10
:
The encrypted result is woodWoKdYebRsnoYedKdDgy
. Using this encrypted text, you can run the decryption to get the original text:
The Caesar cipher is fun to play around with for an introduction to cryptography. While the Caesar cipher is rarely used on its own, it’s the basis for more complex substitution ciphers. In the next section, you’ll look at one of the Caesar cipher’s descendants, the Vigenère cipher.
Vigenère CipherThe Vigenère cipher is a polyalphabetic substitution cipher. To perform its encryption, it employs a different Caesar cipher for each letter of the input text. The Vigenère cipher uses a keyword to determine which Caesar cipher should be used to find the cipher letter.
You can see an example of the encryption process in the following image. In this example, the input text REALPYTHON
is encrypted using the keyword MODULO
:
For each letter of the input text, REALPYTHON
, a letter from the keyword MODULO
is used to determine which Caesar cipher column should be selected. If the keyword is shorter than the input text, as is the case with MODULO
, then the letters of the keyword are repeated until all letters of the input text have been encrypted.
Below is an implementation of the Vigenère cipher. As you’ll see, the modulo operator is used twice in the function:
You may have noticed that the signature for vigenere_cipher()
is quite similar to caesar_cipher()
from the previous section:
The main difference is that, instead of a shift
parameter, vigenere_cipher()
takes a key
parameter, which is the keyword to be used during encryption and decryption. Another difference is the addition of text.isupper()
. Based on this implementation, vigenere_cipher()
can only accept input text that is all uppercase.
Like caesar_cipher()
, vigenere_cipher()
iterates over each letter of the input text to encrypt or decrypt it:
In the above code, you can see the function’s first use of the modulo operator:
Here, the current_key
value is determined based on an index returned from i % len(key)
. This index is used to select a letter from the key
string, such as M
from MODULO
.
The modulo operator allows you to use any length keyword regardless of the length of the text
to be encrypted. Once the index i
, the index of the character currently being encrypted, equals the length of the keyword, it will start over from the beginning of the keyword.
For each letter of the input text, several steps determine how to encrypt or decrypt it:
char_index
based on the index of char
inside uppercase
.key_index
based on the index of current_key
inside uppercase
.char_index
and key_index
to get the index for the encrypted or decrypted character.Take a look at these steps in the code below:
You can see that the indices for decryption and encryption are calculated differently. That’s why decrypt
is used in this function. This way, you can use the function for both encryption and decryption.
After the index
is determined, you find the function’s second use of the modulo operator:
index % 26
ensures that the index
of the character doesn’t exceed 25
, thus making sure it stays inside the alphabet. With this index, the encrypted or decrypted character is selected from uppercase
and appended to results
.
Here’s the full code the Vigenère cipher again:
Now go ahead and run it in the Python REPL:
Nice! You now have a working Vigenère cipher for encrypting text strings.
Python Modulo Operator Advanced UsesIn this final section, you’ll take your modulo operator knowledge to the next level by using it with decimal.Decimal
. You’ll also look at how you can add .__mod__()
to your custom classes so they can be used with the modulo operator.
decimal.Decimal
Earlier in this tutorial, you saw how you can use the modulo operator with numeric types like int
and float
as well as with math.fmod()
. You can also use the modulo operator with Decimal
from the decimal
module. You use decimal.Decimal
when you want discrete control of the precision of floating-point arithmetic operations.
Here are some examples of using whole integers with decimal.Decimal
and the modulo operator:
Here are some floating-point numbers used with decimal.Decimal
and the modulo operator:
All modulo operations with decimal.Decimal
return the same results as other numeric types, except when one of the operands is negative. Unlike int
and float
, but like math.fmod()
, decimal.Decimal
uses the sign of the dividend for the results.
Take a look at the examples below comparing the results of using the modulo operator with standard int
and float
values and with decimal.Decimal
:
Compared with math.fmod()
, decimal.Decimal
will have the same sign, but the precision will be different:
As you can see from the above examples, working with decimal.Decimal
and the modulo operator is similar to working with other numeric types. You just need to keep in mind how it determines the sign of the result when working with a negative operand.
In the next section, you’ll look at how you can override the modulo operator in your classes to customize its behavior.
Using the Python Modulo Operator With Custom ClassesThe Python data model allows to you override the built-in methods in a Python object to customize its behavior. In this section, you’ll look at how to override .__mod__()
so that you can use the modulo operator with your own classes.
For this example, you’ll be working with a Student
class. This class will track the amount of time a student has studied. Here’s the initial Student
class:
The Student
class is initialized with a name
parameter and starts with an empty list, study_sessions
, which will hold a list of integers representing minutes studied per session. There’s also .add_study_sessions()
, which takes a sessions
parameter that should be a list of study sessions to add to study_sessions
.
Now, if you remember from the converting units section above, convert_minutes_to_day()
used the Python modulo operator to convert total_mins
into days, hours, and minutes. You’ll now implement a modified version of that method to see how you can use your custom class with the modulo operator:
You can use this function with the Student
class to display the total hours a Student
has studied. Combined with the Student
class above, the code will look like this:
If you load this module in the Python REPL, then you can use it like this:
The above code prints out the total hours jane
studied. This version of the code works, but it requires the extra step of summing study_sessions
to get total_mins
before calling total_study_time_in_hours()
.
Here’s how you can modify the Student
class to simplify the code:
By overriding .__mod__()
and .__floordiv__()
, you can use a Student
instance with the modulo operator. Calculating the sum()
of study_sessions
is included in the Student
class as well.
With these modifications, you can use a Student
instance directly in total_study_time_in_hours()
. As total_mins
is no longer needed, you can remove it:
Here’s the full code after modifications:
Now, calling the code in the Python REPL, you can see it’s much more succinct:
By overriding .__mod__()
, you allow your custom classes to behave more like Python’s built-in numeric types.
At first glance, the Python modulo operator may not grab your attention. Yet, as you’ve seen, there’s so much to this humble operator. From checking for even numbers to encrypting text with ciphers, you’ve seen many different uses for the modulo operator.
In this tutorial, you’ve learned how to:
int
, float
, math.fmod()
, divmod()
, and decimal.Decimal
.__mod__()
in your own classes to use them with the modulo operatorWith the knowledge you’ve gained in this tutorial, you can now start using the modulo operator in your own code with great success. Happy Pythoning!
Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Python Modulo: Using the % Operator
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4