我是一名新程序员,正在通过自己编写代码并观看Youtube videos来解决不同的Euler项目问题。
解决问题54时,Youtube视频的作者在Python 2.7中定义函数时编写的代码是
def __init__(self, *args):
self.cards = sorted(args, key=lambda c: -c.rank)
self.duplicates = {}
for card in self.cards:
if card.rank in self.duplicates:
continue
_duplicates = 0
for card2 in self.cards:
if card.rank == card2.rank:
_duplicates += 1
self.duplicates[card.rank] = _duplicates
这似乎对他来说很好。当我在Python 3.0上运行此代码时,我的Pycharm编译器返回
File "C:/Users/Matthew/PycharmProjects/Project_Euler/Euler54.py", line 51, in __init__
self.cards = sorted(args, key=lambda c: -c.rank)
File "C:/Users/Matthew/PycharmProjects/Project_Euler/Euler54.py", line 51, in <lambda>
self.cards = sorted(args, key=lambda c: -c.rank)
AttributeError: 'function' object has no attribute 'rank'
我尝试更改
self.cards = sorted(args, key=lambda c: -c.rank)
到
self.cards = sorted(args, key=lambda c: -c.rank())
但这似乎是不正确的修复。我不确定如何自行解决此错误。我可以考虑编写其他解决方案,因为视频作者所展示的策略对初学者并不友好。完整的程序粘贴在下面(我不确定是否应包括此程序,因为我不是在正式寻找代码审查。我正在尝试运行该程序,以便完成练习)。>
import time
from collections import namedtuple
start = time.time()
Card = namedtuple('Card', ['rank', 'suit'])
Ace = 14
King = 13
Queen = 12
Jack = 11
Ten = 10
def map_rank(rank_to_map):
if rank_to_map == 'A':
return Ace
if rank_to_map == 'K':
return King
if rank_to_map == 'Q':
return Queen
if rank_to_map == 'J':
return Jack
if rank_to_map == 'T':
return Ten
return int(rank_to_map)
def map_suit(suit_to_map):
if suit_to_map == 'H':
return 1
if suit_to_map == 'D':
return 2
if suit_to_map == 'C':
return 3
# S = Spades
return 4
def map_card(card_to_map):
return Card(rank=map_rank(card_to_map[0]), suit=map_suit(card_to_map[1]))
class Hand(object):
def __init__(self, *args):
self.cards = sorted(args, key=lambda c: -c.rank)
self.duplicates = {}
for card in self.cards:
if card.rank in self.duplicates:
continue
_duplicates = 0
for card2 in self.cards:
if card.rank == card2.rank:
_duplicates += 1
self.duplicates[card.rank] = _duplicates
def __cmp__(self, other):
for rule in self.rules():
rule = getattr(self, rule)
val = rule(other)
if val:
return val
def rules(self):
return []
def _straight(self):
last_card_rank = False
for card in self.cards:
if last_card_rank and last_card_rank != card.rank + 1:
return False
last_card_rank = card.rank
return True
def _flush(self):
last_card_suit = False
for card in self.cards:
if last_card_suit and last_card_suit != card.suit:
return False
last_card_suit = card.suit
return True
def _duplicate_count(self, c):
for rank, value in self.duplicates.items():
if value == c:
yield rank
class PokerHand(Hand):
def rules(self):
rules = super(PokerHand, self).rules()
rules.append('royal_flush')
rules.append('straight_flush')
rules.append('four_of_a_kind')
rules.append('full_house')
rules.append('flush')
rules.append('straight')
rules.append('three_of_a_kind')
rules.append('two_pair')
rules.append('highest_card')
return rules
def royal_flush(self, other):
h1 = self.cards[0].rank == Ace and self._flush() and self._straight()
h2 = other.cards[0].rank == Ace and other._flush() and other._straight()
if h1 and not h2:
return 1
if h2 and not h1:
return -1
if h1 and h2:
return 0
def straight_flush(self, other):
h1 = self._flush() and self._straight()
h2 = other._flush() and other._straight()
if h1 and not h2:
return 1
if h2 and not h1:
return -1
if h1 and h2:
return self.highest_card(other)
def four_of_a_kind(self, other):
return self._of_a_kind(other, 4)
def three_of_a_kind(self, other):
return self._of_a_kind(other, 3)
def _of_a_kind(self, other, value):
h1 = [r for r in self._duplicate_count(value)]
h2 = [r for r in other._duplicate_count(value)]
if len(h1) > len(h2):
return 1
if len(h2) > len(h1):
return -1
for h1_c, h2_c in zip(h1, h2):
if h1_c > h2_c:
return 1
if h2_c > h1_c:
return -1
def two_pair(self, other):
return self._of_a_kind(other, 2)
def full_house(self, other):
h1_3 = [r for r in self._duplicate_count(3)]
h2_3 = [r for r in other._duplicate_count(3)]
h1_2 = [r for r in self._duplicate_count(2)]
h2_2 = [r for r in other._duplicate_count(2)]
if h1_3 and h1_2 and not (h2_3 and h2_2):
return 1
if h2_3 and h2_2 and not (h1_3 and h1_2):
return -1
if h1_3 and h1_2 and h2_3 and h2_2:
for h1_c, h2_c in zip(h1_3, h2_3):
if h1_c > h2_c:
return 1
if h2_c > h1_c:
return -1
for h1_c, h2_c in zip(h1_2, h2_2):
if h1_c > h2_c:
return 1
if h2_c > h1_c:
return -1
def flush(self, other):
h1 = self._flush
h2 = other._flush
if h1 and not h2:
return 1
if h2 and not h1:
return -1
if h1 and h2:
return self.highest_card(other)
def straight(self, other):
h1 = self._straight
h2 = other._straight
if h1 and not h2:
return 1
if h2 and not h1:
return -1
if h1 and h2:
return self.highest_card(other)
def highest_card(self, other):
for c1,c2 in zip(self.cards, other.cards):
if c1.rank != c2.rank:
return 1 if c1.rank > c2.rank else -1
raise Exception("tie in highest_card")
def gen_hands(s):
cards = [map_card for c in s.split(' ')]
return PokerHand(*cards[0:5]), PokerHand(*cards[5:])
p1_wins = 0
with open('poker.txt') as f:
for line in f:
h1, h2 = gen_hands(line.strip())
if h1 > h2:
p1_wins += 1
print(p1_wins)
不添加here提供的poker.txt文件,该程序将无法按粘贴方式运行。请让我知道为SE上的此类属性错误创建帖子是否错误。我不确定是否应该在该网站上发布欧拉计画的代码。
答案 0 :(得分:0)
第195行,
cards = [map_card for c in s.split(' ')]
在
def gen_hands(s):
cards = [map_card for c in s.split(' ')]
return PokerHand(*cards[0:5]), PokerHand(*cards[5:])
生成一个列表,其中包含对map_card
函数的大量引用。这被错误地写为map_card
而不是map_card(c)
。应该是
def gen_hands(s):
cards = [map_card(c) for c in s.split(' ')]
return PokerHand(*cards[0:5]), PokerHand(*cards[5:])