Python Object-Oriented Python Dice Roller Giving a Hand

Why doesn't my D6 have 'value' attribute?

#################################################################

# copy_1.py

import random

class Die:
    def __init__(self, sides=2, value=0):
        if not sides >= 2:
            raise ValueError("Must have at least 2 sides")
        if not isinstance(sides, int):
            raise ValueError("Sides must be a whole number")

        self.value = value or random.randint(1, sides)

    def __int__(self):
        return self.value

    def __eq__(self, other):
        return int(self) == other

    def __ne_(self, other):
        return int(self) != other

    def __gt__(self, other):
        return int(self) > other

    def __lt__(self, other):
        return int(self) < other

    def __ge__(self, other):
        return int(self) >= other

    def __le__(self, other):
        return int(self) <= other

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

    def __radd__(self, other):
        # return self + other OR    
        return int(self) + other 

    def __repr__(self):
        return str(self.string)

class D6(Die):
    def __init__(self, value=0):
        super().__init__(sides=6, value=value)

#################################################################

# script.py

from copy_1 import D6
class Hand(list):

    def __init__(self, size=8, die_class=None, *args, **kwargs):

        if not die_class:
            raise ValueError("Please provide a die_class")
        super().__init__()

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

hand = Hand(size=5, die_class=D6)
print(hand)                  # works
print(hand[0].value)   # AttributeError: type object 'D6' has no attribute 'value'

4 Answers

Steven Parker
Steven Parker
182,024 Points

In "Hand", this code appends the "die_class" itself, but you probably intended to use instances of the die class:

        for _ in range(size):
            self.append(die_class())  # use () to create an instance

So I added that correction, but now it does this...

print(hand)                # AttributeError: D6 has no attribute 'string'
print(hand[0].value) # Not reached
Steven Parker
Steven Parker
182,024 Points

Sure, because to be able to print an object directly it must define a "__str__" method, and this one doesn't have one (yet).
But printing "hand[0].value" should work now.

I get that, but I'm just trying to reproduce what Ken did in the video (about the 2:30 mark). What am I missing that Ken has (besides expertise? lol)

treehouse:~/workspace$ python3                                                                     
Python 3.6.4 (default, Oct 17 2019, 23:24:40)                                                      
[GCC 5.4.0 20160609] on linux                                                                      
Type "help", "copyright", "credits" or "license" for more information.                             
>>> import dice, hands                                                                             
>>> hand = hands.Hand(size=5, die_class=dice.D6)                                                   
>>> hand                                                                                           
Traceback (most recent call last):                                                                 
  File "<stdin>", line 1, in <module>                                                              
  File "/home/treehouse/workspace/dice.py", line 42, in __repr__                                   
    return str(self.string)                                                                        
AttributeError: 'D6' object has no attribute 'string' 
KRIS NIKOLAISEN
KRIS NIKOLAISEN
53,388 Points

The error shown is at line 42 in dice.py

def __repr__(self):
    return str(self.string)

You can verify with Ken's code at 5:00 in the video that it should be:

def __repr__(self):
    return str(self.value)