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

Ryan Cross
Ryan Cross
5,742 Points

rpg roller part 2 'can't get length of hand'

I'm really stuck. I see they want a class method and return an instance of hand. ok...but it says it can.t get the length of hand?...why wouldn't it? It should have the parent class len method right? I mean the init ought to make Hand instances basically lists right? What am i missing here?

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__(20)
hands.py
from dice import D20 

class Hand(list):

    def __init__(self):
        super.__init__()



    @classmethod
    def roll(cls,many):
        x = Hand()
        for _ in range(1, many):
            x.append(D20())
        return x



    @property
    def total(self):
        return sum(self)
Ryan Cross
Ryan Cross
5,742 Points

here is the objective:

Challenge Task 1 of 2 passed! Challenge Task 2 of 2

Now update Hand in hands.py. 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. I'll leave the implementation of all of that up to you. I don't care how you do it, I only care that it works.

1 Answer

Hey Ryan Cross

You're quite close!

First, your __init__ function is unnecessary. You're not overriding anything there anyway. Python will call __init__ automatically when you instantiate Hand. You only write your own if you're modifying the base class.

Second, instead of calling Hand() to create a list, just initialize an empty list, like dice = []. The whole point of a class method is that you call it on a class, not an instance of a class, but you're creating an instance of a class to run a class method.

Third, if you call Hand.roll(2) it should create two dice, but the way you've used range, it's only going to create 1. That's because the second parameter in range() is an exclusive stop. If you call range(1, 2), you're going up to but not including 2, so the loop is only going to run 1 time. If you just pass the number to range, like range(2) it will run two times (0, 1).

Lastly, when you make a class method, it needs to return cls(), which is like converting the result to the class. In this case you pass in Hand as cls, do some stuff, and return cls(dice) which is like calling Hand(dice).

I just posted a detailed answer here: https://teamtreehouse.com/community/unable-to-create-a-roll-method-in-hand In general, I find it useful to first do a search to see if someone already answered my question. Most likely, many people had the same problem and it has been answered already. There are so many duplicate questions in the forum because people don't do this.

Also, I write and test the code in workspace because the error messages from the code challenge page are confusing and not helpful. Testing the code in workspace is much more helpful.

Ryan Cross
Ryan Cross
5,742 Points

".....Lastly, when you make a class method, it needs to return cls()...."

Is that actually true? I did forget that the range was exclusive and updated that. And I agree the init was just unnecessary so i pulled that too. problem persists. still working on it.

I looked for previous answers on the one,,,there were tons! many had other problems and didnt find a satisfactory answer on len() problem. Im gonna keep trying!