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 trialDuy Pham
Courses Plus Student 44,614 PointsI really need help on this question to move on. Please help
Alright! Now I need you to add a new property called doubles. It should return True if both of the dice have the same value. Otherwise, return False.
from dice import D6
class Hand(list):
def __init__(self, size=0, die_class=None, *args, **kwargs):
if not die_class:
raise ValueError("You must provide a die class")
super().__init__()
for _ in range(size):
self.append(die_class())
self.sort()
def _by_value(self, value):
dice = []
for die in self:
if die == value:
dice.append(die)
return dice
class CapitalismHand(Hand):
def __init__(self, *args, **kwargs):
super().__init__(size=2, die_class=D6, *args, **kwargs)
@property
def ones(self):
return self._by_value(1)
@property
def twos(self):
return self._by_value(2)
@property
def threes(self):
return self._by_value(3)
@property
def fours(self):
return self._by_value(4)
@property
def fives(self):
return self._by_value(5)
@property
def sixes(self):
return self._by_value(6)
@property
def _sets(self):
return {
1: len(self.ones),
2: len(self.twos),
3: len(self.threes),
4: len(self.fours),
5: len(self.fives),
6: len(self.sixes)
}
3 Answers
ds1
7,627 PointsHi, Duy
The [underscore]sets property returns a dictionary, and the values of this dictionary are the number of times a 1 or 2 or 3 or 4 or 5 or 6 was rolled. So if you have a CapitalismHand instance that rolls 2 six-sided dice, and one dice gives you a 5 and the other dice gives you a 6, then the [underscore]sets property on that instance would return the dictionary "1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 1".... but if you rolled doubles instead, then you would have gotten two 6's or two 5's or two 4's, etc. So, here's one way to solve this using the dictionary's "values" method.
@property
def doubles(self):
for num in self._sets.values():
if num > 1:
return True
return False # if the "for" loop never returns True (thereby exiting the method) then the method returns False.
Musashi Schroeder
4,289 PointsEnded up with something like Chris Freeman :
@property
def doubles(self):
if self[0] == self[1]:
return True
else:
return False
daniel steinberg
14,651 PointsChris Freeman , can you tell me why set() does not work here:
@property
def doubles(self):
if (len(set(self))==1):
return True
else:
return False
in the previous code challenge this code is fine:
def score_yatzy(self, hand):
if (len(set(hand))==1):
return 50
else:
return 0
is it related to @property vs a normal function?
Chris Freeman
Treehouse Moderator 68,453 PointsIt is not whether it is a property or not. The challenges appear to use different inputs. In yatzy_scoring
, the hand
input for the self
appears to be a simple list of int
s. In the CapitalismHand
, self
is a list of D6
instances.
For set
to operate on an object, the object needs to be hashable, that is, it has defined both __hash__
and __eq__
methods.
Without these two methods, set
will simply compare the object reference id
s which is guaranteed to be unique. Defining a __repr__
method would allow a cleaner view of what is being compared, but without the __hash__
and __eq__
methods, no actual comparison is being made.
>>> ch = CapitalismHand()
>>> ch
in CH.__repr__
in Hand.__repr__
[<__main__.D6 object at 0x7fc75176cef0>, <__main__.D6 object at 0x7fc75176ce80>]
# Add yatzy method and call
def yatzy(self):
print("in Hand.__yatzy__")
if (len(set(self))==1):
return True
else:
return False
>>> ch, ch.yatzy()
in Hand.__yatzy__
in CH.__repr__
in Hand.__repr__
([<__main__.D6 object at 0x7fc7517854e0>, <__main__.D6 object at 0x7fc7517857f0>],
False)
# add Die.__repr__ method
def __repr__(self):
print("in Die.__repr__")
return str(int(self))
>>> ch, ch.yatzy()
in Hand.__yatzy__
in CH.__repr__
in Hand.__repr__
in Die.__repr__
in Die.__repr__
([4, 4], False) # yatzy still False
# Add __hash__ and __eq__
def __hash__(self):
print("in Die.__hash__")
return int(self)
def __eq__(self, other):
print("in Die.__eq__")
return self.value == other
>>> ch, ch.yatzy()
in Hand.__yatzy__
in Die.__hash__
in Die.__hash__
in Die.__eq__
in Die.__eq__
in CH.__repr__
in Hand.__repr__
in Die.__repr__
in Die.__repr__
([5, 5], True)
Post back if you wish more help. Good luck!!
ds1
7,627 PointsYou're very much welcome!! : )
Duy Pham
Courses Plus Student 44,614 PointsDuy Pham
Courses Plus Student 44,614 PointsThank you so much ds1. You showed what need to be done with a great explaination and that's exactly what i need. Thanks again. I really appreciated
Chris Freeman
Treehouse Moderator 68,453 PointsChris Freeman
Treehouse Moderator 68,453 PointsThere is a short cut solution to Task 2. Since the class inherits from
list
class, it's members can be accessed directly. "Doubles" can be checked usingself[0].value == self[1].value
or even simpler:self[0] == self[1]