Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Ronald Lira
12,217 PointsHow does this work int(self) == other ?
Hello,
I know this works, but I would like to understand how does the comparison at int(self) == other
work? , because on the right side we are using the int
version of the object (this will bring self.value
), but on the left we are just using the object itself. How does python know it has to use also other.value
.
import random
class Die:
def __init__(self, sides=2, value=0):
if not sides >= 2:
raise ValueError("Must have at least 2 sides")
if not isinstance(sides, int):
raise TypeError("Sides must be an integer value")
self.value = value or random.randint(1,sides)
def __int__(self):
return self.value
def __eq__(self, other):
return int(self) == other
In my mind it would make sense the following:
def __eq__(self, other):
return int(self) == int(other)
Thank you
3 Answers

Steven Parker
225,730 PointsI believe that since you've made the first term into an int, then the system automatically tries to convert the second term into the same type for you. Since we know this type can be converted to int, then it will work if the second item is also a Die. But if the second item is some other type, we don't want to force a particular type of conversion.

Johannes Scribante
19,175 PointsHi Ronald,
I hope I can answer your question. There are actually three parts to your question.
-
self.value
: In this part of the code you define a class Die and you assign the Die a value of 5 as an example. Now I assign a variabled5 = Die()
to create ad5 variable which is of the Die class
. Thed5
now has a value, however if I would like to know what that value is, I would have to use d5.value.
class Die:
def __init__(self, sides=2, value=0):
if not sides >= 2:
raise ValueError("Must have at least 2 sides")
if not isinstance(sides, int):
raise TypeError("Sides must be an integer value")
self.value = 5 # assigning the value 5 just as an example
-
__int__(self)
: Next is the magic method__int__
, here you are setting the Die classes__int__
method to be custom, i.e. you could do what ever you want every time you would useint(d5)
for example. However we would like theint(d5)
to return an integer value of died5 die which is of the class Die
. If you did not specify whatint(d5)
would do, Python would not know what to do whenint()
is called on the Die class, Python does not know what the Die class is or what values or methods for part of the class. You have to explicitly tell Python what you mean when you want to use the methodint(Die)
on the Die class. In this case below we are telling Python, when we use the methodint(Die)
on a class of Die we want to return the value of the Die instance.
def __int__(self):
return self.value
-
__eq__
: Finally the one you want to know about. So now that we know our Die class contain a value (d5.value = 5, from 1.), we know the if I were to use the methodint(d5)
we would get5
to be returned. Now finally we want to be able to testd5 == 2
or maybed5 == 5
to get true of false (in this case False and True). We don't want to have to sayint(d5) == 2
orint(d5) == 5
so we include this in our__eq__
method. When we typeDie == other_value
we are calling the__eq__(Die, other_value)
method passing the Die instance and the other_value. Now the__eq__
method calls our__int__
method (from 2.) to return the value of the Die instance and compares it to the value of other_value and returns the True or False, just as if we were you compare2 == 3
. We are making it easier for ourselves to just be able to used5 == 5
instead ofint(d5) == 5
ord5.value == 5
def __eq__(self, other):
return int(self) == other
I hope it makes sense, thanks for asking, it's a good question! Good luck!

Johannes Scribante
19,175 PointsJust one thing to add that I realized.
The big reason for using return int(self) == other
and not return int(self) == int(other)
is because we know that the Die class will only have integer values, no float values, as a Die cannot have 5.2 sides as an example.
In the same way you want to be explicit in saying that the value you are equating the Die to, should not be altered in any way. Otherwise you would be able to equate Die to integers and floats. If you were to use return int(self) == int(other)
, you would get the following result, given that d5.value = 5
.
d5 == 5.3 # True
d5 == 5 # True

Ronald Lira
12,217 PointsHello @stevenparker and @johannesscribante. Thank you very much for your answers. I found a little more insight with this post: https://stackoverflow.com/questions/3588776/how-is-eq-handled-in-python-and-in-what-order
If we have:
d1 = D6()
d2 = D6()
d1 == d2
Python invoke d1.__eq__(d2)
. The code returns self.value == other
but self.value
is an int
object and python doesnt know how to compare int
to D6
objects, so python invokes now d2.__eq__(int)
which is defined because type(d1) == type(d2)
I would like to note that it also depends on the functionality you want to provide. In this case, we want to:
- Compare a
Die
object directly to anotherDie
object - Compare a
Die
object to anyint
object.
And this code does that exactly. But in general, I would like to compare only apples to apples and oranges to oranges, and if the user tries to compare apple to oranges an exception should be raised or at least return False
. Maybe something like:
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
return False
But I am not sure if there is a more elegant way to do this without having to check for the class that other
belongs to on every magic method.
Thank you

Steven Parker
225,730 PointsYou could make an internal method to compare object types to avoid repeating the same test. But you probably wouldn't need to do this kind of thing often. It's more likely you would provide an int() conversion because you want to be able to compare to ordinary integers.