
Kohei Ashida
4,881 PointsAttributeError: 'function' object has no attribute 'items'
I followed along with the code in the lesson but I got back the attribution error below.
>>> from hands import YatzyHand
>>> from dice import D6
>>> from scoresheets import YatzyScoresheet
>>> hand = YatzyHand()
>>> three = D6(value=3)
>>> four = D6(value=4)
>>> one = D6(value=1)
>>> hand[:] = [one, three, three, four, four]
>>> YatzyScoresheet().score_one_pair(hand)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/treehouse/workspace/yatzy/scoresheets.py", line 13, in score_one_pair
return self._score_set(hand, 2)
File "/home/treehouse/workspace/yatzy/scoresheets.py", line 7, in _score_set
for worth, count in hand._sets.items():
AttributeError: 'function' object has no attribute 'items'
Could anyone help me with fixing this?
dice.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 or int(self) == other
def __le__(self, other):
return int(self) < other or int(self) == other
def __add__(self, other):
return int(self) + other
def __radd__(self, other):
return int(self) + other
def __repr__(self):
return self.value
class D6(Die):
def __init__(self, value=0):
super().__init__(sides=6, value=value)
hands.py
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 YatzyHand(Hand):
def __init__(self, *args, **kwargs):
super().__init__(size=5, die_class=D6, *args, **kwargs)
@property
def ones(self):
return self._by_value(1)
def twos(self):
return self._by_value(2)
def threes(self):
return self._by_value(3)
def fours(self):
return self._by_value(4)
def fives(self):
return self._by_value(5)
def sixes(self):
return self._by_value(6)
def _sets(self):
return {
1: len(self.ones),
2: len(self.twos),
3: len(self.trees),
4: len(self.fours),
5: len(self.fives),
6: len(self.sixes)
}
scoresheets.py
class YatzyScoresheet:
def score_ones(self, hand):
return sum(hand.ones)
def _score_set(self, hand, set_size):
scores = [0]
for worth, count in hand._sets.items():
if count == set_size:
scores.append(worth*set_size)
return max(scores)
def score_one_pair(self, hand):
return self._score_set(hand, 2)
1 Answer

Steven Parker
205,147 PointsIn "scoresheets.py", line 7, there is "hand._sets.items()
", but "_sets" is a method (function). To call a method, you need parentheses after the name:
for worth, count in hand._sets().items():
Otherwise, you could make "_sets" a property, then you don't need to call it using parentheses (probably what was intended).
Kohei Ashida
4,881 PointsKohei Ashida
4,881 PointsThank you! but scoresheets.py was fine then I found that I forgot putting @property , and made a typo on def _sets(self) in YaztzyHand class.
Kohei Ashida
4,881 PointsKohei Ashida
4,881 PointsI forgot to add my comment here but thanks a lot for the further explanation:)