Common Uses of %
00:00
In the previous lesson, I introduced you to the various ways of getting mod out of Python. In this lesson, I’m going to show you common uses of the %
operator and why you would use mod in your code.
00:12
I’m pretty sure the thing I do with the %
operator the most in Python is figuring out whether a number is even or odd. This can be done by doing % 2
and checking its value against 0
.
00:25
If the number mod 2 is zero, then it’s even, else it’s odd. One thing to notice here is that if you’re trying to do this kind of calculation, it’s best practice to use == 0
, and in the case of odd, != 0
. Rather than, say, in the case of odd, using == 1
.
00:43
The reason for this goes back to mod and negative numbers. If you compare != 0
, you’ll always get the right answer. If you compare == 1
, depending on whether or not your numerator or divider is negative, you may get different values.
00:58
So it’s just a good habit to stick with == 0
and != 0
.
01:04 Another typical use of mod is to cycle through data. Here’s an example function that takes a list of strings and prints them out to the screen in a series of columns.
01:15
The number of columns that it prints it out in is based on a parameter passed into the function. The first step in make_columns()
is to find the longest item in the list that’s being passed in. Lines 4 and 5 find the longest item and then find the length of that longest item.
01:33 Because I want to print a little bit of padding on each side of this longest item, I’m adding two more to the width, and that’ll be the width of each one of my columns.
01:42
The f-string here is using a format configuration to pad the length of what is being printed. In line 7, I’m enumerating through the contents that are being passed in. For each item in that, I’m going to print that item and I’m going to pad it with hyphens to the width of the width
value—the width of the column that I calculated in line 5.
02:03
Passing in the end
parameter to print()
stops the carriage return from being printed at the end of the line, which is how print()
works by default.
02:11 You don’t want to feed down to the next line unless you’re done printing the columns.
02:17
Line 9 is where the actual modulo math happens. Here, I’m doing a mod of the number of columns to be printed against the index number of the enumerate()
. Because enumerate()
specifies the index based on 0
and I want to start at 1
, I have to do index + 1
.
02:35
Notice the use of the brackets here. Remember the order of operations. If I didn’t have the brackets, I would be doing 1 % num_columns
and then adding index
, rather than doing the mod of index + 1
.
02:49
If the index
being divided is a multiple of the number of columns, i.e. the mod is 0
, then it’s time to do carriage return and go to the next line. Finally, at the end of the function, after all of this, an extra print()
is done just in case the last row has fewer columns than the number of columns being passed in. Inside of the REPL, I can show you this in practice.
03:17 And now I’m going to specify some data to play with with this function.
03:25
And here’s the first example. Passing in the crew
and 3
columns, and the three columns are printed out.
03:36
Same thing with 2
columns.
03:41
And even 1
column works.
03:46 Printing the columns is an example of trying to cycle through some data. Without the mod operator, you have to do special cases to check whether or not you’re near the end of your list or need to wrap around. Because modular arithmetic wraps for you, it saves you some code of conditional checking. Here’s another example.
04:05
The emoji_cycle()
takes a start
and a length
. The faces
string is a list of little faces to print to the screen.
04:13
This function takes the value of start
, uses that as the position in the faces
string to start with, and then the value of length
and continues to print that string, cycling over and over again.
04:25
The key to doing this kind of cycle is determining the position based on the mod. The index of the first emoji to print is calculated inside of the pos
(position) variable. It’s based on start
, modded with the length of the faces
string.
04:41
This guarantees—no matter what number is passed in—a valid happy face position will be found. Without the mod, you would have to do conditions on whether or not start
was less than or greater than the length of the faces
and do math to figure out how to adjust it.
04:57
The loop uses a range()
to print the number of emojis specified in length
. And in line 8, the index
of the emoji to print inside of the for
loop is calculated.
05:08
It uses pos
as the starting position plus the current count
value of the loop. Once again, this is modded with len(faces)
. That way, if index
goes past the end of faces
, it’ll loop back to the beginning.
05:22
Finally, in line 9, the face value is printed. And again, I’m using end
equals blank (""
) so that the carriage return doesn’t happen. In practice, I import this code,
05:39
and here’s an example. This one starts at position 0
, so you end up with the first three emojis.
05:49
Starting at position 3
begins with the halo. Because the length
14
is longer than the list of emojis, the print loops and you end up back at the innocence emoji with the halo once again.
06:04 You can also specify a starting position past the end of the length of emojis and specify a long length of emojis, and you just keep getting the repetition over and over again.
06:16 Without modular arithmetic, this code probably would have had to have required two or three other conditional checks inside of it for boundaries and resets of variables. With the modular arithmetic, the code is nice and succinct.
06:31 Another common use case for modular math is converting between measurement units that aren’t decimal based. For example, the Imperial measurement system uses feet and inches.
06:43 There are 12 inches per foot. If you wish to convert a large number of inches into the combined value of feet and inches, you can use modular arithmetic.
06:53
divmod()
of 133
inches by mod 12
gives you 11
feet, 1
inch. Here’s a quick function that does something similar, converting a total value of minutes to days, hours, and minutes remaining.
07:08
The number of days is calculated using strict integer division of the 1,440 minutes in a day. The number of minutes that are not accounted for in that days
calculation is extra_minutes
, which is the total_minutes % 1440
.
07:26
And then you can use extra_minutes
with strict division and modular math to calculate the hours and minutes remaining. Then, of course, this is printed out.
07:37
So, 7285
minutes turns into 5
days, 1
hour, and 25
minutes. A less lazy programmer would have put a calculation into that so that 'hours'
wasn’t plural, but you get the idea.
07:51 Here are some other uses where you might run into mod. If you’re trying to find all of the factors of a number, you can iterate between 2 and the square root of that number.
08:02
If the number mod the value of this current iteration is 0
, that value is a factor of n
. Modulus is often found in cryptography as well.
08:13
Substitution ciphers map one letter of the alphabet to another. For example, in the message you’re trying to encode, anytime you see an 'A'
, you replace it with a 'C'
. When you find a 'B'
, replace it with a 'D'
. 'C'
with 'E'
, et cetera.
08:28 This kind of substitution can be done with a list of the letters and then shift it by mod 26. That way when you get to the end of the alphabet, it wraps back around to the beginning.
08:40 More complex cryptography also uses modular math. The keys in RSA public key encryption are based on modular arithmetic.
08:50 In the next lesson, I’ll show you how to implement modulo yourself in your own classes.
Jason Van Schooneveld RP Team on Feb. 15, 2021
Great question! This is part of Python’s string formatting syntax. You can read more about it here.
Jason Van Schooneveld RP Team on Feb. 15, 2021
Looks like that was just a link to a section of the article. I’d check out the whole article. Lots of good stuff.
Become a Member to join the conversation.
LeszekG on Feb. 15, 2021
Dear All,
Would you mind helping me to grasp what is going on in this expression: {item:-^{10}, how the item ends up in the middle between ”-“ and maybe where I could read about it, please. Thank you.