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! While you're at it, check out some resources Treehouse students have shared here.

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

Python Object-Oriented Python Dice Roller Comparing and Combining Dice

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 91,252 Points

int() - TypeError, Argument must be a string

Hi all. I've got my Die and D6 class here with a few comments added

dice.py
#import random module
import random

#define a Die class
class Die:
    def __init__(self, sides=2, value=0):
    #A die must have more than 2 sides
        if not sides >= 2:
            raise ValueError("Must have at least 2 sides")
    #sides must be a whole number
        if not isinstance(sides, int):
            raise ValueError("Sides must be a whole number")
        self.value = value or random.randint(1, sides)    

    #compare dice using magic methods for a range of game scenarios 
    def __eq__(self, other):
        return int(self) == other

    def __ne__(self, other):
        return not int(self) == other

    def __gt__(self, other):
        return int(self) > other

    def __lt__(self, other):
        return int(self) < other

    def __ge__(self, other):
        return int(self) > other or int(self) == other    

    def __le__(self, other):
        return int(self) < other or int(self) == other

    def __add__(self, other):
        return int(self, other)

    def __radd__(self, other):
        return int(self) + other            


#extend Die class      
class D6(Die):  
    #override init method
    def __init__(self, value=0):
        #call super
        super().__init__(sides=6, value=value)

But I can't seem to be able to run any comparisons on it in the console as it tells me I need to convert it as a string.

>>> from dice import D6
>>> d1 = D6()
>>> d2 = D6()
>>> int(d1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'D6'
>>>

I'm at a loss. Can anyone point me in the direction as to where I've gone wrong? Thanks. :)

4 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

You are missing the __int__ method added at video time 0:40:

    def __int__(self):
        return self.value

:tada:

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,252 Points

Thanks for the nod Chris, I got there in the end. Also had to fix one or 2 of the other methods too.

I swear though I had that method in before. I must have put it in the wrong place and then taken it out.

The error you are receiving is much simpler than it seems. You are trying to parse d1 (a D6 object) into a function ( int() ) which takes a string as an argument. i.e. int(String) To do the comparisons you don't need to convert your D6 objects ( d1 and d2 ) into int objects as you have already programmed the magic methods. This means that because of those magic methods python will now understand what to do when you type 'd1 > d2'.

In short, there is no need to turn your D6 objects into ints, but instead, just execute the comparison like so:

>>> from dice import D6
>>> d1 = D6()
>>> d2 = D6()
>>> if d2 > d1:
       print("d2 is larger than d1")

Did this help? If so don't forget to upvote to help others find this answer.

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,252 Points

Hi Oli,

Then, I don't understand what's happening because in the video Kenneth is doing just those comparisons. Passing in the instances to int()which I assumed he was doing so he could make those calculations.

e.g.

>>> d1 = D6()
>>> d2 = D6()
>>> int(d1)
4
>>> int(d2)
6
>>>d1 + d2
10

If I try to bypass that and simply calculate d1 and d2 I then get returned another TypeError that the objects can't be interpreted as integers. Clearly something has gone wrong somewhere but can't see where.

I believe that if you want to parse your abject into an int then you need to add the magic method for that as well. It’s been a while since I did this course but I believe it’s int and return whatever value you want as long as it’s and int.

This may or may not be contributing to the issue you're having, but I think this part:

def __add__(self, other):
        return int(self, other)

Should instead be like so:

def __add__(self, other):
        return int(self) + other