## Project Euler: Problem 54

```class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit

def getRank(self):
return self.rank

def getSuit(self):
return self.suit

def BJValue(self): #Rank of cards in game of Blackjack
if self.rank == 'Ace':
return 1
elif self.rank == 'Jack' or self.rank == 'Queen' or self.rank == 'King':
return 10
else:
return int(self.rank)

def PokerValue(self):
if self.rank == 'Ace':
return 14
elif self.rank == 'King':
return 13
elif self.rank == 'Queen':
return 12
elif self.rank == 'Jack':
return 11
else:
return int(self.rank)

def __str__(self):
return ('{0} of {1}'.format(self.rank, self.suit))

def __repr__(self):
return repr((self.rank, self.suit, self.PokerValue()))
```
```import inspect
import operator

class Hand(object):
"""Models a hand of cards as a list."""
def __init__(self, cards=[]):
self._list = cards

def extend(self, cards):
if isinstance(cards, list): #Only append lists of cards
self._list.extend(cards)
else:
pass

def append(self,card):
if isinstance(card, Card): #Only append instances of the Class object "Card"
self._list.append(card)
else:
pass

def isStraight(self):

"""Tests if the hand is a straight.
Returns True if yes, False if no."""

values = [] #Initialize a list to hold the values of the cards
for card in self._list:
values.append(card.PokerValue())
disvalues = set(values)
values.sort()
if max(values[0:4]) == 5 and max(values) == 14 and len(disvalues) == 5:
return True
elif (max(values) - min(values) == 4) and len(disvalues) == 5:
return True
else:
return False

def isFlush(self):
"""Tests if the hand is a flush. Returns True if yes, False if no."""

suits = [] #Initialize a set to hold the suits of the cards
for card in self._list:
suits.append(card.getSuit())
if len(set(suits)) == 1:
return True
else:
return False

def evaluate(self):
"""Evaluates the poker hand."""

#Create a dictionary to store the number of times
#each rank-value appears in the hand
_d = {2 : 0,
3 : 0,
4 : 0,
5 : 0,
6 : 0,
7 : 0,
8 : 0,
9 : 0,
10 : 0,
11 : 0,
12 : 0,
13 : 0,
14 : 0}

for card in self._list:
_d[card.PokerValue()] += 1 #Count the number of ranks

rank = sum(1 for x in _d.values() if x > 0) #Count the number of distinct rands in the hand
d = sorted(_d.iteritems(), key = operator.itemgetter(1,0), reverse = True)

straight = self.isStraight() #Test if the hand is a straight
flush = self.isFlush() #Test if the hand is a flush

if rank == 2:
if max(_d.values()) == 4:
base_val = 8 #Four of a kind
elif max(_d.values()) == 3:
base_val = 7 #Full House
elif rank == 3:
if max(_d.values()) == 3:
base_val = 4 #Three of a Kind
elif max(_d.values()) == 2:
base_val = 3 #Two Pair
elif rank == 4:
base_val = 2 #One Pair
elif rank == 5:
base_val = 1 #High Card

if straight and flush:
base_val = max(base_val, 9) #Straight flush
elif straight and (not flush):
base_val = max(base_val, 5) #Non-Flush Straight
elif (not straight) and flush:
base_val = max(base_val, 6) #Non-Straight Flush

value = base_val
for x in d:
if x[1] != 0: #Only append ranks with nonzero counts
value = int(str(value) + (x[1]*str(x[0]).zfill(2))) #Pad the string with leading zero, if one digit
return value

def __repr__(self):
return repr(self._list)
```
```#This function converts a two-character string representation of a card to a tuple
def vectorize_card(card):
#The rank is the first character of the string block
if card[0] == 'T':
rank = '10' #The text file represents the rank 10 by the letter T
elif card[0] == 'J':
rank = 'Jack'
elif card[0] == 'Q':
rank = 'Queen'
elif card[0] == 'K':
rank = 'King'
elif card[0] == 'A':
rank = 'Ace'
else:
rank = card[0]
suit = card[1] #The suit is the second character of the string block
return Card(rank, suit)

def get_hands(line):
card_strings = line.split(' ') #Each card is separated by a space
card_list = []
for i in range(0,10):
x = vectorize_card(card_strings[i])
card_list.append(x)
_hand1 = Hand(card_list[0:5]) #The first five cards form the first hand
_hand2 = Hand(card_list[5:10]) #The last five cards form the second hand
return _hand1, _hand2

def get_winner(hand1, hand2):
"""Determines the winner of two poker hands."""

#Evaluate each hand
value1 = hand1.evaluate()
value2 = hand2.evaluate()

if value1 > value2:
return 'player 1' #Return 1 for hand1
if value1 < value2:
return 'player 2' #Return 2 for hand2
else:
return '' #Return 0 in the event of a tie
```
```#Initialize a dictionary to count each player's number of wins
wins = {'player 1' : 0, 'player 2' : 0, '' : 0}

#Initialiaze a list to hold the hands for each round
gamehands = []

file_path = "YOUR_FILE_PATH"
f = open(file_path,'r') #Create a file object in read-mode
for line in f: #loop through the lines of the text file
gamehands.append(get_hands(line)) #Append the hands to the list gamehands
f.close() #Close the file object
```
```for round in gamehands:
winner = get_winner(round[0],round[1])
wins[winner] += 1
print wins
```