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

shekhar bhardwaj
seal-mask
.a{fill-rule:evenodd;}techdegree
shekhar bhardwaj
Full Stack JavaScript Techdegree Student 12,373 Points

Bummer! Got the wrong length for a `Hand`, Please if somebody could shed some light here.

I am clearly passing two arguments in cls -> size and class, I have initialize the hand class to accept two arguments as well, what I am missing here any clue.

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):
        super().__init__(sides=20)
hands.py
from dice import D20


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

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

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

Hi Shekhar, When it is time to use the class method you will do something like obj.roll(2) Since you will send the value of 2, then in the return you would use the size=size? Otherwise you could only use the classmethod for 2 die?

1 Answer

Hi there!

Ah, so close! Remember that python runs line by line, even inside methods inside classes! If you move your

super().__init__()

Above the for loop in your __init __ method, you won't get an empty Hand object anymore. What the super().__init __() line does is create the instance (self) using the __init _ _ method of the parent (list) class. If you run it last, you get a new instance of the list class with nothing in it, and that's the first reason you get the wrong length - the length will always be 0.

The second, is, I think just a typo or misunderstanding the question. In your classmethod roll,

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

I think you got your default parameters backwards. Here roll() will expect one argument, but whatever it is, it will create a Hand instance of 2 D20 instances. You just need to remove the "=2" part, so the size can be set when calling the Hand.roll() method ( the checker will try sizes other than 2 as well) :)

A quick tip in the hope it helps:

In python 3, super() is so powerful, that we don't actually need to call super().__init __() if we're not passing in any values, we can literally just use super() as if we were calling the parent class with no arguments. For example:

class Array(list):  
    """A Friendly name for a list for new python users""" 
    def __init__(self,  itr):
        super()
        for _ in itr:
            self.append(_)

This gives us an Array instance with all the attributes and methods of a list, just a different name. However in this case, we're not really doing anything with that for loop, so here we could just use list's __init __ method. To pass in the itr value, we do need to use super().__init __() however (otherwise super would think we were giving it the itr value!):

class Array(list):  
    """A Friendly name for a list for new python users""" 
    def __init__(self, itr):
        super().__init__(itr) 

And again, Array instances have all the qualities of lists :)

Hope it helps!