Python Object-Oriented Python Dice Roller RPG Roller

Akshaan Mazumdar
Akshaan Mazumdar
2,356 Points

Code not working- RPG ROLLER

I get the error Cant get the length of Hand

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
import dice

class Hand(list):

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

    def roll(self,num):
        for _ in range(num):
            self.append(dice.D20())

        return self    

    def sum(self):
        total_sum=0
        for xx in range(len(self)):
            total_sum=total_sum+self[xx]

        return total_sum   

1 Answer

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 21,420 Points

It took me a while to redo this challenge. I wrote the code out which worked perfectly in my IDE but would not pass the challenge automated grader-- then I noticed "the clue." "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."

In case you didn't catch the hint: the automated grader wants you to have something that creates the hand and rolls at the same time-- e.g. we're going to need (drumroll please) the notorious "@classmethod" and the mild mannered (as Kenneth calls it) "dunder init".

What's cool about this example, is that we really inherit lots of wonderful list-class goodness, like sum(), append(), etc. and independent methods like len() work perfectly.

I hope this helps! Enjoy the Python journey, it really is worthwhile.

--Spoiler Alert Below--

import dice

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

    def __init__(self, num=0): # you're going to need this!
        # Notice this looks exactly like your roll method you wrote above!
        for _ in range(num):
            self.append(dice.D20())

    @classmethod # this declares a class method-- this was the trick
    def roll(cls, count):
        return Hand(count) # here we actually return a Hand of length count