## 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. # Unable to create a roll method in Hand

I am having trouble getting this method to work. It would be great if I could get some pointers on how to solve this issue.

dice.py
```import random

class Die:
def __init__(self, sides=2):
if sides < 2:
raise ValueError("Can't have fewer than two sides")
self.sides = sides
self.value = random.randint(1, sides)

def __int__(self):
return self.value

return int(self) + other

return self + other

class D20(Die):
def __init__(self,size=20):
super().__init__(size)
```
hands.py
```from dice import D20

class Hand(list):
@property
def total(self):
return sum(self)

def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("You must provide a die class")
super().__init__()

for _ in range(size):
self.append(die_class())
self.sort()

def roll(self,size=2):
return self.__init__(size,D20())
```

It should automatically have 20 sides not size

I made the change from size to sides in the dice.py class but I am still unable to get the roll method to work. ``` class Hand(list):
@property
def total(self):
return sum(self)

def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("You must provide a die class")
super().__init__()

for _ in range(size):
self.append(die_class())

@classmethod
def roll(cls, size=2):
return cls(size=size, die_class=D20)
```

Can anyone provide a method for thinking through this problem? All throughout this course I have had issues with the code challenges because I cannot seem to come up with the methodology to approach these problems based on what I learned in the videos. I usually just de-construct some else's answer and try to understand how they come up with it. This case is no different: I cannot even begin to think about how to approach this! There's gaps for sure. I've found that sometimes I'll get what he means and sometimes no luck. I head to other outside resources like a book or youtube and will get it. On return to the course after I reach understanding I'll rewatch the video and often say, well of course i didn't get it here... there's problems! Nobody's perfect and I imagine that its quite a stretch for someone very advanced to completely see it from the perspective of a stone cold noob.

Assma Al-Adawi This took me a while, but I finally figured it out.

Let's break down the problem. It states: "I'm going to use code similar to Hand.roll(2) and I want to get back an instance of Hand with two D20s rolled in it. I should then be able to call .total on the instance to get the total of the two dice."

The first thing to do is carefully read the problem and restate it to make sure you understand what is being asked. For example, "I need to write a method called roll() which takes a number and creates that many D20 dice. The total() method uses sum() to add up the dice values. Sum() takes an iterable, like a list. So the roll() method will create a list of dice, which makes sense because Hand is a subclass of list." Something like that.

The clue that Kenneth gave was that you're going to call it on Hand (the class), not an instance of Hand. What kind of method do you call directly on the class?

The books.py example from earlier in the course was helpful. Take a look at that and try to solve it before reading further.

```class Bookcase:
def __init(self, books=None):
self.books = books

@classmethod
def create_bookcase(cls, book_list):
books = []
for title, author in book_list:
books.append(Book(title, author))
return cls(books)
```

As others already pointed out, it's a class method, so you put the @classmethod decorator above the class declaration. Class methods don't take self, but cls as the first argument, because you're calling it on the class, not an instance (self). Then you would put in the other argument, which is the number of dice you're creating. You can call that size.

Then, for that many (you can call range() on size), you're going to create a D20 die. So you'll need a for loop and inside the loop you'll create a die. How do you create a D20 die?

Since the function needs to return a list, the dice will need to be appended to a list. You can initialize an empty list and then append to it inside the for loop.

Finally, you'll need to return the list of dice and call cls() on the list to convert it into a Hand. (Is that correct Kenneth Love ? I couldn't find the explanation in the Python docs.)

To test the code, you can try:

```Hand.roll(2).total
``` STAFF

Read the instructions again. My example code was `Hand.roll(2)`. What isn't being created in the example? What kind of method does `roll` need to be?

"Read the instructions again" is pretty poor in terms of response when one of the major issues is the instructions being written in a terribly confusing way. One of the worst challenges ever. My solution works on Jupyter Notebook but here I get `Bummer! Can't get the length of a 'Hand'`. This OOP course sucks! Here is my solution that works on Jupyter Notebook:

```from dice import D20

class Hand(list):
def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("die_class must be provided.")
super().__init__()

for _ in range(size):
self.append(die_class()) # Creating instances of die_class

# Sorting
self.sort()

@classmethod
def roll(cls, size, die_class=D20):
return cls(size=size, die_class=die_class)

@property
def total(self):
return sum(self)

h = Hand.roll(2)
print('Length: ', len(h))
print('Hand: ', h)
print('Total: ', h.total)

>>> Length:  2
>>> Hand:  [14, 18]
>>> Total:  32
```

Taking this now, totally agree. I came into Python already knowing OOP JavaScript and having a decent programming foundation already. This course has managed to confuse me non-stop. Information is presented poorly, little context in terms of real-world usage, unclear explanation, I could go on. I hate to say it because I know Kenneth is a smart and accomplished guy and I have a lot of respect for him, but I think this course could have been done a lot better. I was thinking of repeating the entire course once finished, but instead I am gonna get a good book on Python and read the OOP chapter(s).

Here is my solution, I only post this as reference for people stuck on the challenge. There are other approaches in this thread but they are either too clunky or use concepts I'm not very strong on (classmethods). Happy learning!

'''python

from dice import D20

class Hand(list): @property def total(self): return sum(self)

```def __init__(self, size = 0, *args, **kwargs):  //We dont really care about initialisation because the roll function is important here
super().__init__()

def roll(self, size):
for x in range(size):
self.append(int(D20())) // appending with the value of each dice to the Hand Object
```

'''

h = Hand.roll(2) t = h.total

and it worked fine for me. Thanks for your help in resolving this issue Zac. Zachary, in your explanation I think it would be clearer if you set size = 0 in your roll class method... If my understanding is correct if you have 2 it means the default for roll would always be 2 so if you called Hand.roll() you'd always get that answer.

Thanks for plugging away at this though, it had me stuck for a while!

I tried the following code and was unable to get this working:

from dice import D20

class Hand(list): @property def total(self): return sum(self)

```def __init__(self, sides=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("You must provide a die class")
super().__init__()

for _ in range(sides):
self.append(die_class())

@classmethod
def roll(cls, sides=2):
return cls(sides=sides, die_class=D20)
```

h = Hand.roll(2) t = h.total

Could someone please tell me what I am missing with this code? Ya idk what to tell you man. Works find for me. Here is my entire hands file

```from dice import D20

class Hand(list):

def __init__(self, size=0, die_class=D20):
super().__init__()
for _ in range(size):
self.append(die_class())

@classmethod
def roll(cls, size=2):
return cls(size=size)

@property
def total(self):
return sum(self)
``` After a crazy amount of frustration, I figured it out.

```from dice import D20

class Hand(list):
def __init__(self, size=0, die_class=D20, *args, **kwargs):
super().__init__()
for _ in range(size):
self.append(die_class())

@classmethod
def roll(cls, size=2):
return cls(size=size)

@property
def total(self):
return sum(self)
```

Terribly taught course. Need to redo Treehouse.

I thought it was pretty good tbh. I had to research on my own sometimes. But that's how programming works.

To be fair though, the challenges are wack, and sometimes pointless. So what I advise you to do, after every course create a project using the tools that you had learnt from that course.

Here what I read found working thanks to community here, I have some knowledge about Java and OOP but this course not helpfull much.

from dice import D20

class Hand(list):

```def __init__(self, size=0, die_class=D20):
super().__init__()
for _ in range(size):
self.append(die_class())

@classmethod
def roll(cls, size=2):
return cls(size=size)

@property
def total(self):
return sum(self)
``` Hey guys, not sure who this is still a problem for. But I just looked through all of this and and using the last bit of code I cam up for the answer.

@zachary looked like he had it right.

Only thing I changed is in def roll, I only passes size as is. So like this

def roll(cls, size): return cls(size)

Everything else is the same.

I didn't think of setting the die_class=D20 in the init, I was doing it in the roll with a super like the video,

Also not sure why I didnt use cls as a parameter in the roll().

I'm actually still not sure why that's there. ```from dice import D20
class Hand(list):
@property
def total(self):
return sum(self)
@classmethod
def roll(cls, size):
empty = []
for i in range(size):
i = D20()
empty.append(i)
return cls(empty)
```

This is the solution, ursaminor really helped me out with calling cls() on the list at the end. I still dont understand what that does, but the rest of the thinking makes sense to me.

This course is pretty bad IMO. That's why you don't understand what it does. class methods are actually very helpful and you'll use them in many projects in the future. Anyways, check out Real Python. They have one of the best explanations for this concept.

```from dice import D20

class Hand(list):
def __init__(self, size=0, die_class=None, *args, **kwargs):
self.size = size
super().__init__()
for _ in range(size):
self.append(die_class()) # Creating instances of die_class

@classmethod
def roll(cls, size, die_class=D20):
return cls(size=size, die_class=die_class)

@property
def total(self):
return sum(self)
```