Python Object-Oriented Python Dice Roller RPG Roller

Sanket K
Sanket K
2,394 Points

RPG Roller Task 2 failure

I implemented the Task 2 as attached. When I tested this locally, it appears to work as the total is displayed. However, it seems to fail when I run it here. Unfortunately the error message is too generic for me to understand why it fails.

>>> h = Hand.roll(3)
>>> h
[<__main__.D20 object at 0x10dfa79e8>, <__main__.D20 object at 0x10dfa7c50>, <__main__.D20 object at 0x10dfa7cc0>]
>>> h.total
14
>>> sum(h)
14
>>> h[0].value
4
>>> h[1].value
9
>>> h[2].value
1

Maybe I am misunderstanding the requirement. Hopefully someone can clarify

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
class Hand(list):
    @property
    def total(self):
        return sum(self)

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

1 Answer

Steven Parker
Steven Parker
201,999 Points

You just forgot to add "from dice import D20" in hands.py.

However, it's very unconventional to re-assign "cls" in a class method. Normally, you would call it instead of the class itself to create a new instance.

Sanket K
Sanket K
2,394 Points

Thanks Steven. That was such a silly mistake!

I did try what you suggested, and I believe what you meant was something like this?

@classmethod
    def roll(cls, num):
        rolled = cls()
        for _ in range(num):
            rolled.append(D20())
        return rolled  
Steven Parker
Steven Parker
201,999 Points

Yes, much more "best practice". :+1: