**Hint:**You can adjust the default video playback speed in your account settings.

**Hint:**You can set your subtitle preferences in your account settings.

**Sorry!**Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

# Advanced Uses and Overriding .__mod__

**00:00**
In the previous lesson, I showed you some example uses of the `%`

operator. In this lesson, I’m going to take you past `int`

and `float`

and show you how to use the `%`

operator with different classes, including your own.

**00:14**
In an earlier lesson, I mentioned the imprecise nature of floats. Here’s an example. What should be exactly `13.2`

ends up with some crufty stuff at the end.

**00:31**
The capital-d `Decimal`

class supports a fixed precision for float-like operations.

**00:41**
You can create a `Decimal`

object by passing it a string representation of the number that you’re after. You can then do multiplication on that. A `Decimal`

object times an integer or times a float ends up in another `Decimal`

object.

**00:59**
Notice that the resulting value here doesn’t have the precision problem that `float`

does. You can even specify how much precision the `Decimal`

class is supposed to use.

**01:19**
The `.prec`

(precision) value of the context of the `decimal`

module specifies how many digits that `Decimal`

maintains inside of its calculation.

**01:28**
Be aware that this is the total number of digits, both to the left and to the right of the decimal point.

**01:38**
1 divided by 7, normally infinitely repeating, is succinctly kept in just six decimal places. The zero to the left of the decimal point doesn’t count in the total.

**01:50**
You can do modular arithmetic with the `Decimal`

class.

**01:57**
So far, no different than integers.

**02:04**
But here’s a case where the precision is correct. You no longer get the inaccuracy that’s introduced when you do this same calculation with floats. `Decimal`

objects also support negative mods.

**02:23**
But, as you might recall, there are different ways of calculating negative modulus. The `%`

operator uses the `floor()`

method, the `Decimal`

class uses the `trunc()`

method, so results from `Decimal`

will be closer to `math`

library’s `fmod()`

function.

**02:48**
Here’s an example with both the float imprecision and the negative result using the `%`

operator.

**02:59**
And there it is again using the `Decimal`

class. The extra inaccuracy introduced by `float`

is gone, and this uses the `trunc()`

division method, so you get different results depending on whether you’re using ints, floats, or decimals. Everything in Python is an object—the ints, the floats, and, of course, the `Decimal`

objects. Operators on those objects map to methods inside of the objects.

**03:26**
These methods are referred to as dunder methods, dunder being short for *double underscore* (`__`

). The `%`

operator calls `.__mod__()`

.

**03:37**
If you look at the source code of the `decimal`

library that I just demonstrated, when the `%`

operator is called, it gets mapped to `Decimal.__mod__()`

.

**03:48**
This isn’t just a weird little implementation detail—this is also something you can take advantage of. If you want your own classes to support the `%`

operator, you can do that by implementing the `.__mod__()`

method.

**04:03**
Here I’m going to show you a class that represents a series of integers. Inside of it, I’m going to implement the `.__mod__()`

method so that I can do mod math on all of the integers in the series. Let me just scroll down.

**04:20**
First off, in the constructor, it creates a member called `.contents`

where it stores what was passed in. The arguments to the constructor are looped through and appended to `self.contents`

and converted to `int`

.

**04:34**
I’ve done this so that if somebody passes in a non-integer value to `*args`

, line 7 will either convert it or force an exception to be raised.

**04:45**
`.__mod__()`

isn’t the only operator that can be done on this class. Lines 9 and 10 implement `.__len__()`

. This is what gets called when `len()`

(length) is called on the object.

**04:57**
In this case, I’m reporting the length of the internal array as the length of the int list. Implementing `.__iter__()`

provides an iterator for the class. This way, the class can be looped over.

**05:11**
I’m just mapping this to an iterator of the internal representation of the `.contents`

. With me so far? Now here’s how to actually implement `.__mod__()`

.

**05:24**
I’m supporting two different use cases. The first use case is when the object of the class encounters `%`

and then an integer. In this case, I’m doing a list comprehension in line 17, calculating the mod against each one of the items inside of the `.contents`

array, and then I’m creating a new `IntList`

object consisting of the old `int`

object’s `.contents`

modded with that single integer.

**05:54**
The second use case is to mod two `IntList`

objects together. To keep it simple, I’m only going to support the case where the two `IntList`

objects are of the same length. Line 20 checks whether or not a mod is being done against another `IntList`

and double-checks that if it is, that the two lengths are the same.

**06:16**
The `len()`

operator on the `IntList`

objects here will end up calling `.__len__()`

on line 9. I enumerate through the array of items inside of this object and I perform mod against the equivalently indexed value in the other `IntList`

.

**06:36**
All of this is stored inside of a list. And then on line 25, a new `IntList`

object is created with the results. Line 27 is a safety. If you get here, then the mod operation either wasn’t against an `int`

or wasn’t against an `IntList`

of the same length, so an error should be raised.

**07:04**
And here it is in practice.

**07:10**
I’ve created a new `IntList`

containing the numbers `1`

, `5`

, `15`

, and `18`

. I can do `len()`

, which results in `4`

because of the four integers inside of it.

**07:24**
And because of the `.__iter__()`

method being implemented, I can convert this value to a `list`

. The `list`

class iterates through the `IntList`

and returns a list of the values.

**07:37**
Doing `foo % 12`

causes `% 12`

to happen for each item in the list. Converting that `IntList`

that returns into a list presents the following result. `1 % 12`

is `1`

, `5 % 12`

is `5`

, `15 % 12`

is `3`

, and `18 % 12`

is `6`

.

**08:05**
Here, I’m creating another `IntList`

. Again with four values inside of it, this time `12`

, `6`

, `12`

, and `6`

.

**08:17**
Modding `foo`

with `bar`

results in a new `IntList`

. Converting that into a `list`

shows you the results. `1 % 12`

is `1`

, `5 % 6`

is `5`

, `15 % 12`

is `3`

, and `18 % 6`

is `0`

.

**08:38**
And finally, to show you the error condition because I didn’t support a case with floats when I attempt to do `IntList`

mod `3.5`

, the `AttributeError`

gets raised.

**08:51**
And now you’re able to use the mod operator with any class that you implement. Next up, I’ll summarize the course.

Become a Member to join the conversation.