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 RPG Roller

haran arbel
haran arbel
2,396 Points

len attribute of Hand

Hey, It says "Can't get the length of 'Hand'" but Hand extends list and list implements len so why doesn't it work? I'm also having trouble understanding how to implement the roll method. Can I have some more clarifications? Thanks :)

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

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

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

class D20(Die):
    def __init__(self, sides=20):
        super().__init__(sides=sides)
hands.py
class Hand(list):

    def __init__(self, Die_class=None, size=0):
        if not Die_class:
            raise ValueError("You must peovide a die class")
        super().__init__()

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

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

    #def __len__(self):
     #   return len(self)

    def roll(self):
        rolled = []
        for dice in self:
            rolled.append(dice.value)
        return rolled

5 Answers

Steven Parker
Steven Parker
229,744 Points

Yea, that's not the best error message. It should say something like "was unable to construct a Hand" instead.

Anyway, your init override adds two arguments. Now, they are both given default values, but the code inside the method throws a ValueError if the default for Die_class is used. That means the validator won't be able to create a Hand instance without using arguments (as it is expecting to).

Then, about the "roll" method, the instructions say "I want to get back an instance of Hand with two D20s rolled in it.", but this one is returning a list instead. Also to get those D20's in it, you'll need to import your task 1 code from dice.py and then reference it in the method.

Extra hint: you might want to implement "roll" as a class method.

haran arbel
haran arbel
2,396 Points

Thanks. I solved the first problem, but I still don't understand what I need to do in the roll method. It appears that now I return an object of Hand were inside the init method 2 D20s are initialised and added to the Hand object. I also imported my code from dice.py but it seems that I'm missing something still.

haran arbel
haran arbel
2,396 Points

So now my code is:

@classmethod def roll(): return Hand(Die_class=D20, size=2)

and above I imported the code:

from dice.py import *

An

@classmethod

Always gets at least one argument, which is the name of the class. So you would start it with

@classmethod
def roll(cls):

Then cls will be the class, which is "Hand", in this example. You could use cls in the body of your function, instead of saying Hand.

By the way, I strongly suggest trying these things with python on your home system (or inside workspaces) so that you can see the error.

haran arbel
haran arbel
2,396 Points

Thank you very much! :) It works!

Steven Parker
Steven Parker
229,744 Points

haran arbel — Good deal! :+1:   You can mark a question solved by choosing a "best answer".
And happy coding!