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 trialDominic Birmingham
5,885 PointsI'm not sure where I'm going wrong. Die roller challenge
I've tried to understand what exactly this challenge is looking for but no dice. It seems to function perfectly fine, what do I need to do?
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)
from dice import D20
class Hand(list):
def __init__(self, *args, **kwargs):
super().__init__()
@property
def total(self):
return sum(self)
def roll(self, number):
for _ in range(number):
self.append(D20())
5 Answers
Alexander Davison
65,469 Pointsroll
needs to be a classmethod
of Hand
that returns a new instance of a Hand
containing number
amount of D20
s
Mark Chesney
11,747 PointsCan you please help me with mine? The issue is that if I run my_hand.total, then my_hand.roll(2), then again my_hand.total, the new total won't correspond to the fresh reroll -- it's stuck on the total from when Hand() was instantiated.
Thanks.
class Hand(list):
def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("Please pass in a die_class")
super().__init__()
for _ in range(size):
self.append(die_class())
#self.sort()
@property
def total(self):
return sum(self)
@classmethod
def roll(cls, number):
output=[]
for _ in range(number):
output.append(D20())
return cls(size=number, die_class=D20)
Dominic Birmingham
5,885 PointsYou are instantiating your class and giving it to the variable my_hand. my_hand has the original instance of Hand as a result. When you call your class method you are simply returning a class instance but not assigning it to my_hand therefore my_hand remains the same as it was to begin with.
The challenge asks you to make a class which, when the classmethod roll is called on it, returns an instance of itself, which yours should do, if you have imported your D20 class, but I'm not sure what you're using the output variable for.
Mark Chesney
11,747 PointsHi Dominic. Thanks for your help.
I can accept that my output list is wrong; I'm still unaware of what code would make it correct. I borrowed output=[]
and output.append(D20())
from the @classmethod lesson:
@classmethod
def create_bookcase(cls, book_list):
books = []
for title, author in book_list:
books.append(Book(title, author))
return cls(books)
My hands.py begins with this:
from dice import D20
My dice.py ends with this (which gets me to pass task 1 of 2):
class D20(Die):
def __init__(self):
super().__init__(sides=20)
I've made countless code permutations in my attempts to self-debug this. I can't show them all here. I just need a hint, that the Code Challenge doesn't provide directly.
Thanks
Dominic Birmingham
5,885 PointsAs you can see in that @classmethod lesson they create a class called bookcase and have to create a list object, books, to store the book_list items in. In our case, however, we are given the Hand class which Inherits from List, therefore you can use list methods on Hand instances themselves.
Your first solution was really very close! Just remember you're trying to devise a class where the statement Hand.roll(2) will return a Hand instance with 2 D20 and that cls in your classmethod represents the class Hand itself.
Mark Chesney
11,747 PointsThanks Dominic.
Everything you said makes sense. There's some error and I can't find it.
I'm assuming cls is an instance of a Hand, which inherits from list. But then do you know why I get the error Can't get the length of a Hand
?
Also I ran Python Debugger (pdb), and I see these things:
type(cls)
# >>> <class 'type'>
TypeError: descriptor append requires a list object but received a type
Thanks
from dice import D20
class Hand(list):
def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("Prohibited: User must specify a die_class")
super().__init__()
for _ in range(size):
self.append(die_class())
#self.sort()
@property
def total(self):
return sum(self)
@classmethod
def roll(cls, size=2, die_class=D20):
# import pdb; pdb.set_trace()
for _ in range(size):
cls.append(die_class())
return cls(size, die_class)
Dominic Birmingham
5,885 PointsYou're very close! Pay close attention to what you're doing in your roll method, what are you creating and what are you returning? What is that loop you're doing, doing? What are you appending to? A big hint is that cls represents the class but cls() represents a class instance.
Mark Chesney
11,747 PointsThank you very much Dominic. Very, very much. I've passed the challenge :)
from dice import D20
class Hand(list):
def __init__(self, num_of_items=0, die_class=D20, *args, **kwargs):
if not num_of_items:
raise ValueError("NUMBER OF ITEMS must be specified.")
super().__init__(*args, **kwargs)
for _ in range(num_of_items):
self.append(D20())
@property
def total(self):
return sum(self)
@classmethod
def roll(cls, num_of_items):
return cls(num_of_items)
Dominic Birmingham
5,885 PointsDominic Birmingham
5,885 PointsThanks Alex! Figured it out thanks to that