Python 3 : Object has not attribute - python-3.x

I need your kind assistance on these codes. I am getting this error: 'Card object has no attribute 'equal_rank'. Below are the codes from two files. Basically I am not allowed to modify the cards.py file. My codes are in main.py.
main.py
import cards
#call deck
lmdeck = cards.Deck()
#display message
print("=======messy print a deck========")
#display lDck
print(lmdeck)
#call method
a_card = lmdeck.deal()
#display message
print("Card dealt is:", a_card)
#display message
print('Cards left:', len(lmdeck))
#display message
print("Is deck empty?", lmdeck.is_empty())
#define hand
lHndlist1 = []
#define hand
lHndlist2 = []
#loop
for li in range(5):
#call method
lHndlist1.append(lmdeck.deal())
#call method
lHndlist2.append(lmdeck.deal())
#display message
print("\nHand 1:", lHndlist1)
#display message
print("Hand 2:", lHndlist2)
#display
print()
#define hand 1
lLastCrdHnd1 = lHndlist1.pop()
#define hand 1
lLastCrdHnd2 = lHndlist2.pop()
#display message
print("Hand1 threw down", lLastCrdHnd1, ", Hand2 threw down", lLastCrdHnd2)
#display message
print("Hands are now:", lHndlist1, lHndlist2)
#check condition
if lLastCrdHnd1.equal_rank(lLastCrdHnd2):
#display message
print(lLastCrdHnd1, lLastCrdHnd2, "of equal rank")
#otherwise
elif lLastCrdHnd1.get_rank() > lLastCrdHnd2.get_rank():
#display message
print(lLastCrdHnd1, "of higher rank than", lLastCrdHnd2)
#otherwise
else:
#display message
print(lLastCrdHnd2, "of higher rank than", lLastCrdHnd1)
#check condition
if lLastCrdHnd1.equal_value(lLastCrdHnd2):
#display message
print(lLastCrdHnd1, lLastCrdHnd2, "of equal value")
#otherwise
elif lLastCrdHnd1.get_value() > lLastCrdHnd2.get_value():
#display message
print(lLastCrdHnd1, "of higher value than", lLastCrdHnd2)
#otherwise
else:
#display message
print(lLastCrdHnd2, "of higher value than", lLastCrdHnd1)
#check condition
if lLastCrdHnd1.equal_suit(lLastCrdHnd2):
#display message
print(lLastCrdHnd1, 'of equal suit with', lLastCrdHnd2)
#otherwise
else:
#display message
print(lLastCrdHnd1, 'of different suit than', lLastCrdHnd2)
#define list
foundation_list = [[], [], [], []]
#define column
column = 0
#loop
while not lmdeck.is_empty():
#append
foundation_list[column].append(lmdeck.deal())
#update column
column += 1
#check condition
if column % 4 == 0:
#set value
column = 0
#loop
for li in range(4):
#display message
print("foundation", li, foundation_list[li])
#define function
def lGet1Par(cards):
cards.sort(key=lambda card: card.get_rank())
#loop
for lStrt in range(len(cards) - 2 + 1):
if cards [lStrt].get_rank() == cards[lStrt + 1].get_rank():
return cards[lStrt:lStrt + 2]
return []
#define function
def lGet2Par(cards):
lOnePair = lGet1Par(cards)
if lOnePair:
remaining = [c for c in cards if c not in lOnePair]
another_pair = lGet1Par(remaining)
if another_pair:
lOnePair.extend(another_pair)
return lOnePair
return []
#define function
def lGetstgtflsh(cards):
#sort the cards by their ranks
cards.sort(key=lambda card: card.get_rank())
#check each possibility
for lStrt in range(len(cards) - 5 + 1):
end = lStrt + 1
while end < len(cards):
if cards[end].get_suit() != cards[end - 1].get_suit():
break
if cards[end].get_rank() - cards[end - 1].get_rank() != 1:
break
end = end + 1
if end - lStrt >=5: #found
return cards[lStrt:lStrt + 5]
return
#define function
def lGet4ofKnd(cards):
cards.sort(key=lambda card: card.get_rank())
for lStrt in range(len(cards) - 4 + 1):
if cards[lStrt].get_rank() == cards[lStrt + 3].get_rank():
return cards[lStrt:lStrt + 4]
return []
#define function
def lGet3ofKnd(cards):
cards.sort(key=lambda card: card.get_rank())
for lStrt in range(len(cards) - 3 + 1):
if cards[lStrt].get_rank() == cards[lStrt + 2].get_rank():
return cards [lStrt:lStrt + 3]
return []
#define function
def lGetFllHse(cards):
l3 = lGet3ofKnd(cards)
if l3:
remaining = [c for c in cards if c not in l3]
pair = lGet1Par(remaining)
if pair:
l3.extend(pair)
return l3
return []
#define function
def lGetFlsh(cards):
cards.sort(key=lambda card: card.get_suit())
for lStrt in range(len(cards) - 5 + 1):
if cards[lStrt].get_suit() == cards[lStrt + 4].get_suit():
return cards[lStrt:lStrt + 5]
return []
#define function
def lGetStgth(cards):
cards.sort(key=lambda card: card.get_rank())
for lStrt in range(len(cards) - 5 + 1):
end = lStrt + 1
while end < len(cards):
if cards[end].get_rank() - cards[end - 1]. get_rank() != 1:
break
end = end + 1
if end - lStrt >= 5:
return cards[lStrt:lStrt + 5]
return []
#define function
def test():
c = [cards.Card(1, 1), cards.Card(7, 1), cards.Card(6, 1), cards.Card(8, 1), card.Cards(9, 1), cards.Card(10, 1), cards.Card(3, 1)]
print(lGetstgtflsh(c))
c = [cards.Card(1, 1), cards.Card(7, 1), cards.Card(6, 2), cards.Card(8, 1), cards.Card(9, 1), cards.Card(10, 2), cards.Card(11, 1)]
print(lGetstgtflsh(c))
c = [cards.Card(1, 1), cards.Card(1, 2), cards.Card(1, 3), cards.Card(1, 4), cards.Card(9, 1), cards.Card(10, 2), cards.Card(11, 1)]
print(lGet4ofKnd(c))
c = [cards.Card(3, 1), cards.Card(1, 2), cards.Card(1, 3), cards.Card(1, 4), cards.Card(9, 1), cards.Card(10, 2), cards.Card(11, 1)]
print(lGet4ofKnd(c))
print (lGet3ofKnd(c))
c = [cards.Card(3, 1), cards.Card(3, 2), cards.Card(1, 3), cards.Card(1, 4), cards.Card(9, 1), cards.Card(10, 2), cards.Card(11, 1)]
print(lGet2Par(c))
print(lGet1Par(c))
c = [cards.Card(3, 1), cards.Card(3, 2), cards.Card(1, 3), cards.Card(1, 1), cards.Card(9, 1), cards.Card(10, 1), cards.Card(11, 1)]
print(lGetFlsh(c))
c = [cards.Card(1, 1), cards.Card(7, 2), cards.Card(6, 1), cards.Card(8, 1), cards.Card(9, 1), cards.Card(10, 1), cards.Card(3, 1)]
print(lGetStgth(c))
c = [cards.Card(1, 1), cards.Card(1, 2), cards.Card(1, 3), cards.Card(8, 1), cards.Card(9, 1), cards.Card(10, 1), cards.Card(8, 2)]
print(lGetFllHse(c))
c = [cards.Card(1, 1), cards.Card(1, 2), cards.Card(2, 3), cards.Card(8, 1), cards.Card(9, 1), cards.Card(10, 1), cards.Card(8, 2)]
print(lGetFllHse(c))
print(lGet2Par(c))
#define function
def get(player1, player2, category):
if category == 'straight flush':
return(lGetstgtflsh(player1), lGetstgtflsh(player2))
if category == '4 of a kind':
return(lGet4ofKnd(player1), lGet4ofKnd(player2))
if category == 'full house':
return(lGetFllHse(player1), lGetFllHse(player2))
if category == 'flush':
return(lGetFlsh(player1), lGetFlsh(player2))
if category == 'straight':
return(lGetStgth(player1), lGetStgth(player2))
if category == '3 of a kind':
return(lGet3ofKnd(player1), lGet3ofKnd(player2))
if category == '2 pair':
return(lGet2Par(player1), lGet2Par(player2))
if category == '1 pair':
return(lGet1Par(player1), lGet1Par(player2))
return (player1, player2)
#define main function
def main():
lDck = cards.Deck()
lDck.shuffle()
while True:
print("---------------------------")
print("Let's play poker!")
community_cards = []
player1_cards = []
player2_cards = []
player1_cards.append(lDck.deal())
player2_cards.append(lDck.deal())
player1_cards.append(lDck.deal())
player2_cards.append(lDck.deal())
for li in range(5):
community_cards.append(lDck.deal())
print()
print("Community cards: %s" % (community_cards))
print("Player 1: %s" % (player1_cards))
print("Player 2: %s" % (player2_cards))
print()
player1_cards.extend(community_cards)
player2_cards.extend(community_cards)
for category in ('straight flush', '4 of a kind', 'full house', 'flush', 'straight', '3 of a kind', '2 pair', '1 pair', 'high card'):
player1, player2 = get(player1_cards, player2_cards, category)
if player1 and player2:
print("TIE with a %s: %s" % (category, player1))
break
elif player1 and not player2:
print("Player %d wins with a %s: %s" % (1, category, player1))
break
elif not player1 and player2:
print("Player %d wins with a %s: %s" % (2, category, player2))
break
if lDck.cards_count() < 9:
print("Deck has too few cards so game is done.")
break
print()
c = input("Do you wish to play another hand? (Y or N")
if c not in ('y', 'Y'):
break
if __name__ == '__main__':
main()
cards.py
import random
class Card( object ):
# Rank is an int (1-13), where aces are 1 and kings are 13.
# Suit is an int (1-4), where clubs are 1 and spades are 4.
# Value is an int (1-10), where aces are 1 and face cards are 10.
# List to map int rank to printable character (index 0 used for no rank)
rank_list = ['x','A','2','3','4','5','6','7','8','9','10','J','Q','K']
# List to map int suit to printable character (index 0 used for no suit)
# 1 is clubs, 2 is diamonds, 3 is hearts, and 4 is spades
# suit_list = ['x','c','d','h','s'] # for systems that cannot print Unicode symbols
suit_list = ['x','\u2663','\u2666','\u2665','\u2660']
def __init__( self, rank=0, suit=0 ):
""" Initialize card to specified rank (1-13) and suit (1-4). """
self.__rank = 0
self.__suit = 0
self.__face_up = None
# Verify that rank and suit are ints and that they are within
# range (1-13 and 1-4), then update instance variables if valid.
if type(rank) == int and type(suit) == int:
if rank in range(1,14) and suit in range(1,5):
self.__rank = rank
self.__suit = suit
self.__face_up = True
def rank( self ):
""" Return card's rank (1-13). """
return self.__rank
def value( self ):
""" Return card's value (1 for aces, 2-9, 10 for face cards). """
# Use ternary expression to determine value.
return self.__rank if self.__rank < 10 else 10
def suit( self ):
""" Return card's suit (1-4). """
return self.__suit
def is_face_up( self ):
""" Returns True if card is facing up."""
return self.__face_up
def flip_card( self ):
""" Flips card between face-up and face-down"""
self.__face_up = not self.__face_up
def __str__( self ):
""" Convert card into a string (usually for printing). """
# Use rank to index into rank_list; use suit to index into suit_list.
if self.__face_up:
return "{}{}".format( (self.rank_list)[self.__rank], \
(self.suit_list)[self.__suit] )
else:
return "{}{}".format( "X", "X")
def __repr__( self ):
""" Convert card into a string for use in the shell. """
return self.__str__()
def __eq__( self, other ):
""" Return True, if Cards of equal rank and suit; False, otherwise. """
if not isinstance(other, Card):
return False
return self.rank() == other.rank() and self.suit() == other.suit()
class Deck( object ):
# Implement the deck as a list of cards. The last card in the list is
# defined to be at the top of the deck.
def __init__( self ):
""" Initialize deck--Ace of clubs on bottom, King of spades on top. """
self.__deck = [Card(r,s) for s in range(1,5) for r in range(1,14)]
def shuffle( self ):
""" Shuffle deck using shuffle method in random module. """
random.shuffle(self.__deck)
def deal( self ):
""" Return top card from deck (return None if deck empty). """
# Use ternary expression to guard against empty deck.
return self.__deck.pop() if len(self.__deck) else None
def is_empty( self ):
""" Return True if deck is empty; False, otherwise """
return len(self.__deck) == 0
def __len__( self ):
""" Return number of cards remaining in deck. """
return len(self.__deck)
def __str__( self ):
""" Return string representing deck (usually for printing). """
return ", ".join([str(card) for card in self.__deck])
def __repr__( self ):
""" Return string representing deck (for use in shell). """
return self.__str__()
def display( self, cols=13 ):
""" Column-oriented display of deck. """
for index, card in enumerate(self.__deck):
if index%cols == 0:
print()
print("{:3s} ".format(str(card)), end="" )
print()
print()
I don't think there are errors inside the cards.py because I am not allowed to modify the file. It could be in main.py but I could not figure out. Any help would be much appreciated. Thank you.

As the error message says, cards.py does not define the attribute (i.e., internal storage) equal_rank, nore is there a functio equal_rank(), so when you try to access its value with lLastCrdHnd1.equal_rank(lLastCrdHnd2) it fails.
card.py does override the equals operator to allow card ranks to be cmpared so you should be able to do something like
if lLastCrdHnd1 == lLastCrdHnd2:

Related

Backtracking problem in Knights tour algorithm

**Edit: I managed to find solution for my problem so i put the correct code in place. Everything works perfect now.
I'm trying to complete the last stage of a project in Jetbrains Academy but I can't make my approach to the problem work:
It gives the user the solution for the knights tour in chess if it exists by taking their inputs. I know that there are working solutions out there, but I would like to make it work with the approach I have taken.
I can't make it work. Although, it works fine when the player plays with and I had cut the extra lines.
Example:
Input: A 4x3 board, and 1 3 (column/row)
My implementation gives 2 possible moves [(3, 2), (2, 1)]. It then continues for the possible values of 2 1 and it goes all the way down until it has no other solutions. Then it stops. Those inputs works because they dont require further search in the inside possible valid move. It doesn't check multiple paths that exist at the deeper level.
I don't understand why this happens. Where is the problem in the code?
Initialization of the board (there are extra variables because of the previous steps):
# Write your code here
from copy import deepcopy
import sys
sys.setrecursionlimit(2000)
# With that recursion limit you can test boards up to 40x40 instantly.
# Without this you can test easily up to 30 x 30 any value
# and up to 35x35 any value except edge columns / rows ex 1 4 / 4 1.
class ChessBoard:
def __init__(self, dimensions: str):
self.game_over = False
self.valid_grid = True
self.dimensions = self.board_validation(dimensions.strip().split())
if self.valid_grid:
self.x = self.dimensions[0]
self.y = self.dimensions[1]
self.cell_length = len(str(self.x * self.y)) # Cell format helper for spaces
self.board = [[(x, y) for x in range(1, self.x + 1)] for y in range(self.y, 0, -1)]
self.visual = [["_" * self.cell_length for _ in range(1, self.x + 1)] for _ in range(self.y, 0, -1)]
self.moves_visit = {key: False for i in range(len(self.board)) for key in self.board[i]}
# We need duplicates to reverse the state of the board if we want:
# to continue the game - try other initial move for the valid movements pool
self.board_duplicate = deepcopy(self.board)
self.visual_duplicate = deepcopy(self.visual)
self.moves_visit_duplicate = deepcopy(self.moves_visit)
self.x_boundaries = {i for i in range(1, self.x + 1)}
self.y_boundaries = {i for i in range(1, self.y + 1)}
self.valid_moves = [] # Helper for getting instant valid_moves for the player.
self.is_first_move = True # With that we make it easier to differentiate the first move from other inputs.
self.movements_made = 0 # Move counter direct connection with the AI solution finder and the AI move
self.board_dimensions = self.x * self.y
self.has_solution = False
self.initial_move_for_ai = None
self.first_valid_move = set({})
self.moves_placed = set({}) # Fast comparison to check if the ai_play function will return from recursion
self.total_moves = 0
self.find_solution_mode = False
def set_first(self):
if self.is_first_move:
self.is_first_move = False
def board_validation(self, board_dimensions):
if len(board_dimensions) != 2:
self.valid_grid = False
return False
try:
x = int(board_dimensions[0])
y = int(board_dimensions[1])
if x <= 0 or y <= 0:
self.valid_grid = False
return False
self.valid_grid = True
return x, y
except ValueError:
self.valid_grid = False
return False
def move_validation(self, move_to_validate):
if isinstance(move_to_validate, tuple) and move_to_validate[0] in self.x_boundaries and \
move_to_validate[1] in self.y_boundaries:
return move_to_validate
values = move_to_validate.split()
if len(values) != 2:
return False
try:
column = int(values[0])
row = int(values[1])
movement = (column, row)
if column not in self.x_boundaries or row not in self.y_boundaries:
return False
if not self.is_first_move and self.moves_visit[movement]:
return False
if not self.is_first_move and movement not in self.valid_moves:
return False
return movement
except ValueError:
return False
# Knight movement. X for player - Movement number for AI
def knight_move(self, movement, solution_mode=False):
if self.movements_made == 0:
self.set_first()
movement = self.move_validation(movement)
for m in range(len(self.board)):
if movement in self.board[m]:
index_of_move = self.board[m].index(movement)
if not self.moves_visit[movement]:
if not solution_mode:
self.visual[m][index_of_move] = " " * (self.cell_length - 1) + "X"
else:
move = "" * (self.cell_length - 3) + str(self.movements_made + 1)
self.visual[m][index_of_move] = move.rjust(self.cell_length)
self.possible_moves(movement)
self.movements_made += 1
self.moves_visit[movement] = True
return movement
return False
# Calculating exact moves to chose from. We return index based values based on visual repr
# and also player based values (2, 1), (3, 2) etc.. columns / rows
def move_calculation(self, movement_to_calc):
movement = movement_to_calc
value_to_process = [(-2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (-1, -2), (1, -2)]
possible_calculations = [(movement[0] + value_to_process[i][0], movement[1] +
value_to_process[i][1]) for i in range(len(value_to_process))]
final_possible_indexes = [(r, self.board[r].index(j)) for r in range(len(self.board))
for j in possible_calculations if j in self.board[r] and not self.moves_visit[j]]
final_possible_indexes_translation = [self.board[i][j] for i, j in final_possible_indexes]
return final_possible_indexes, final_possible_indexes_translation
# Function that is used to calculate how many moves we have for the valid placements on board
def depth_calc(self, valid_move):
x, y = self.move_calculation(valid_move)
return len(x)
# Similar to move_calculation but this one is used to register primary valid moves for player on board
# And also to check the state of players game and outputting the depth values for the valid moves.
def possible_moves(self, main_move):
try:
moves, moves_translation = self.move_calculation(main_move)
combined_index_translation = set(zip(moves, moves_translation))
except TypeError:
return False
if not self.find_solution_mode:
for i, j in combined_index_translation:
col, row = i[0], i[1]
if not self.moves_visit[j]:
self.visual[col][row] = f'{" " * (self.cell_length - 1)}{self.depth_calc(j) - 1}'
self.valid_moves = moves_translation
print(self.__str__())
self.board_updater()
self.check_end()
return moves_translation
# Board update based on the moves_visit state True/False (if we visited or not)
def board_updater(self):
for i in range(len(self.board)):
for j in range(len(self.board[i])):
move_to_check = self.board[i][j]
if self.moves_visit[move_to_check]:
self.visual[i][j] = f'{" " * (self.cell_length - 1)}*'
else:
self.visual[i][j] = f'{" " * (self.cell_length - 1)}_'
# Getting all primary valid moves to work with
def get_valid_moves(self, from_move):
valid = self.possible_moves(from_move)
if valid:
return valid
else:
return False
# Key function for the ai_play function. It gives us the valid move with the minimum depth.
def lower_move(self, valid_values):
lengths = {i: self.depth_calc(i) for i in valid_values}
min_depth = min(lengths, key=lengths.get)
return min_depth
# Recursive function that is giving us the solution for the inputted move
def ai_play(self, move, pool, n):
if not self.moves_placed:
self.moves_placed.add(move)
if n == 1:
self.first_valid_move.add(self.lower_move(pool))
if len(self.moves_placed) == self.board_dimensions:
self.has_solution = True
return True
if self.total_moves >= self.board_dimensions ** 4:
return False
self.total_moves += 1
if pool:
best_move = self.lower_move(pool)
ai_move = self.knight_move(best_move, solution_mode=True)
self.moves_placed.add(ai_move)
if ai_move:
possible_moves = self.get_valid_moves(ai_move)
if self.ai_play(ai_move, possible_moves, n + 1):
return True
else:
self.ai_play_reset()
first_move = self.knight_reset()
self.moves_placed.add(first_move)
first_pool = self.get_valid_moves(first_move)
self.first_valid_move.add(first_pool[0])
new_pool = set(first_pool).difference(self.first_valid_move)
try:
self.ai_play(first_move, list(new_pool), 1)
except RecursionError:
self.ai_play_reset()
return False
except IndexError:
print("We tested all initial valid moves and failed.\nChoose one cell higher column and try again")
return False
# Resets the important variables of the board. Crucial if ai_play doesn't find a solution with first try.
def ai_play_reset(self):
self.moves_placed.clear()
self.board = deepcopy(self.board_duplicate)
self.visual = deepcopy(self.visual_duplicate)
self.moves_visit = deepcopy(self.moves_visit_duplicate)
self.movements_made = 0
self.has_solution = False
self.first_valid_move.clear()
# Checks the state of the player's game.
def check_end(self):
if not self.valid_moves:
self.game_over = True
if self.movements_made + 1 == self.board_dimensions:
self.has_solution = True
print("What a great tour! Congratulations!")
return False
else:
print(f"No more possible moves!\nYour knight visited {self.movements_made + 1} squares!")
return False
# Resets the Knight position to the initial for the ai_play function
def knight_reset(self):
main_move = self.knight_move(self.initial_move_for_ai, solution_mode=True)
return main_move
# Helper function that manages the outputs of the ai_play function regarding if player want a solution or not
def ai_solution_test(self, move, for_player=False):
if self.board_dimensions in {16, 4, 9}:
print("No solution exists!")
return False
self.initial_move_for_ai = move
self.find_solution_mode = True
movement = self.knight_move(move, solution_mode=True)
self.set_first()
self.initial_move_for_ai = movement
valid_moves = self.get_valid_moves(movement)
while True:
self.ai_play(movement, valid_moves, 1)
if self.has_solution:
if not for_player:
print("\nHere's the solution!")
print(self.__str__())
break
else:
break
self.find_solution_mode = False
self.ai_play_reset()
return True
def __str__(self):
visualization = [" ".rjust(self.cell_length - 1) + "-" * (self.x * (self.cell_length + 1) + 3)]
for i in range(len(self.visual)):
main_chess = " ".join([str(len(self.visual) - i).rjust(self.cell_length - 1) + "|", *self.visual[i], "|"])
visualization.append(main_chess)
visualization.append(" " * (self.cell_length - 1) + "-" * (self.x * (self.cell_length + 1) + 3))
visualization.append(
" ".rjust(self.cell_length + 2) + " ".join([f"{i}".center(self.cell_length) for i in range(1, self.x + 1)]))
return "\n".join(visualization)
def main():
while True:
board = ChessBoard(input("Enter your board's dimensions: "))
if not board.valid_grid:
print("Invalid dimensions!", end=" ")
continue
while True:
knight_move = board.move_validation(input("Enter the knight's starting position: "))
if not knight_move:
print("Invalid move!", end=" ")
continue
else:
break
while True:
puzzle_try = input("Do you want to try the puzzle? (y/n): ")
if puzzle_try not in {"y", "n"}:
print("Invalid input!", end=" ")
continue
else:
break
if puzzle_try == "y":
check_if_solution = board.ai_solution_test(knight_move, for_player=True)
if check_if_solution:
board.knight_move(knight_move)
while not board.game_over:
next_move = board.knight_move(input("Enter your next move: "))
if next_move:
board.board_updater()
else:
print("Invalid move!", end=" ")
continue
if board.game_over:
break
else:
break
else:
board.ai_solution_test(knight_move)
break
if __name__ == "__main__":
main()

Identifying straight, flush and other categories (from Poker) using Python

I am newbie to python and learning it from books, forums and developers. Recently, I tried to implement various hand-ranking categories in the poker program. The goal is to calculate probabilities and see if it agrees with theoretical poker hand probabilities?
Source: https://en.wikipedia.org/wiki/Poker_probability?oldformat=true
Please find below the code and logic I've used so far to build it. The code contains Card and Deck classes which together implement a deck of standard playing cards used, as well as a sample PyTest test function test_xxx().
So far, I've written hasOnePair, hasTwoPairs, hasThreeOfAKind, hasFullHouse and hasFourOfaKind() functions and it is working fine but I am struggling with Straight, flush, StraightFlush.
Could someone please suggest or give guideline about how to approach straight, flush, royalflush, straightflush cases? Also, any further suggestions to update this code will be great.
import random
SUITS = ["Clubs", "Diamonds", "Hearts", "Spades"]
RANKS = ["", "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"]
# here's two Python classes whose objects represent playing cards and decks thereof
class Card():
"""
Represents a single playing card,
whose rank internally is int _rank: 1..13 => "Ace".."King"
and whose suit internally is int _suit 0..3 => "Clubs".."Spades"
"""
def __init__(self, rank=1, suit=3): # this is the constructor!
'''
Initialize card with given int suit and int rank
:param rank:
:param suit:
:return:
'''
self._rank = rank
self._suit = suit
def __str__(self): # this is the "stringifier"
"""
Return the string name of this card:
"Ace of Spades": translates int fields to strings
:return:
"""
# "Ace of Spades" is string for self._rank==1, self._suit==3
toreturn = RANKS[self._rank] + " of " + SUITS[self._suit]
return toreturn
class Deck():
"""
Represents a deck of 52 standard playing cards,
as a list of Card refs
"""
def __init__(self): # constructor
"""
Initialize deck: field _cards is list containing
52 Card refs, initially
:return: nothing
"""
self._cards = []
for rank in range(1, 14):
for suit in range(4):
c = Card(rank, suit) # create next Card with given value
self._cards.append(c) # add it to this Deck
def __str__(self):
"""
"Stringified" deck: string of Card named,
with \n for easier reading
:return:
"""
toreturn = ''
# for index in range(len(self._cards)):
# self._cards[index]
for c in self._cards:
temp = str(c) # temp is the stringified card
toreturn = toreturn + temp + "\n" # note \n at end
return toreturn
def shuffle(self):
random.shuffle(self._cards) # note random function to do this
def dealCard(self):
toreturn = self._cards.pop(0) # get and remove top card from deck
return toreturn
def buildDict(hand):
dict = {}
for card in hand:
dict[card._rank] = dict.get(card._rank, 0) + 1
return dict
def hasOnePair(dict):
twocount = 0
threecount = 0
for v in dict.values():
if v == 2:
twocount += 1
elif v == 3:
threecount += 1
if twocount==1 and threecount != 1:
return True
else:
return False
def hasTwoPairs(dict):
twocount1 = 0
threecount1 = 0
for v in dict.values():
if v ==2:
twocount1 += 1
elif v == 3:
threecount1 +=1
if twocount1 == 2 and threecount1 != 1:
return True
else:
return False
def hasThreeOfAKind(dict):
twocount = 0
threecount = 0
for v in dict.values():
if v == 2:
twocount += 1
elif v == 3:
threecount += 1
if twocount != 1 and threecount == 1:
return True
else:
return False
def hasFullHouse(dict):
twocount = 0
threecount = 0
for v in dict.values():
if v == 2:
twocount += 1
elif v == 3:
threecount += 1
if twocount == 1 and threecount == 1:
return True
else:
return False
def hasFourOfAKind(dict):
fourcount = 0
onecount = 0
for v in dict.values():
if v ==4:
fourcount += 1
elif v == 1:
onecount +=1
if fourcount == 1 and onecount == 1:
return True
else:
return False
def hasStraight(hand):
return False
def hasFlush(dict):
return False
def hasStraightFlush(dict):
return False
def hasRoyalFlush(dict):
return False
def main():
TRIALS = 1000 # int(input ("Input number of hands to test: "))
hand = [] # list of Card in hand
# accumulators for different counts
onepairCount = 0
twopairCount = 0
threeCount = 0
fourCount = 0
fullHouseCount = 0
StraightCount = 0
for num in range(TRIALS):
# create new Deck and shuffle
d = Deck()
d.shuffle()
# initialize hand as empty list
hand = []
# deal top 5 cards of deck, adding to hand
for count in range(5):
hand.append(d.dealCard())
# build the dictionary of card ranks in hand
dict = buildDict(hand)
# use dictionary to make hand checking easier
if hasOnePair(dict):
onepairCount += 1
elif hasTwoPairs(dict):
twopairCount += 1
elif hasThreeOfAKind(dict):
threeCount += 1
elif hasFourOfAKind(dict):
fourCount += 1
elif hasFullHouse(dict):
fullHouseCount += 1
elif hasStraight(dict):
StraightCount +=1
# add more if needed...
# print out results...
print("Number of one pair hands is: ", onepairCount)
print("% of hands: ", 100.0 * onepairCount / TRIALS)
print("Number of two pair hands is: ", twopairCount)
print("% of hands: ", 100.0 * twopairCount / TRIALS)
print("Number of trips hand is: ", threeCount)
print("% of hands: ", 100.0 * threeCount / TRIALS)
print("Number of quads hand is: ", fourCount)
print("% of hands: ", 100.0 * fourCount / TRIALS)
print("Number of trips hand is: ", fullHouseCount)
print("% of hands: ", 100.0 * fullHouseCount / TRIALS)
print("Number of trips hand is: ", StraightCount)
print("% of hands: ", 100.0 * StraightCount / TRIALS)
def card_example():
card1 = Card() # Card(1,3) => Ace of Clubs
card2 = Card(12, 2) # Card (12,2) => Queen of Hearts
card1._newfield = 47 # we can add new fields to any Python object!
# three ways of printing a Card
#
print(card1.__str__()) # calling the methods against card
print(str(card2)) # type-casting
print(card2) # short-cut: passing obj ref to print does str() automagically
print(card1._newfield) # see the new field value?
print(card1._rank) # see the rank (1..13)
print(card1._suit) # see the suit (0..3)
def deck_example():
"""
Test Deck: create, print then shuffle, print again
Then deal first two cards and print, along with bottom card
"""
deck = Deck()
print(str(deck)) # see entire deck before shuffling
print("Now we shuffle:\n")
deck.shuffle()
print(str(deck)) # see entire deck after shuffling
card1 = deck.dealCard()
card2 = deck.dealCard()
print("The first card dealt is", str(card1), "and the second is", str(card2))
print("Bottom of deck is", deck._cards[-1]) # can't hide the implementation!
if __name__ == "__main__": # only run this if this .py is NOT imported
# pass
# card_example() # uncomment to test creating & calling Card methods
# deck_example() # uncomment to test Deck: create, print, shuffle, print
main() # uncomment to run general poker odds calculations
#
# -------------------------------------------------------------------------
#
#pytest follows...
def test_one_pair():
testhand = [Card(2, 3), Card(1, 2),
Card(3, 1), Card(13, 2),
Card(2, 0)]
dict = buildDict(testhand)
assert hasOnePair(dict) #hasTwoPairs
def test_two_pair():
testhand = [Card(2, 3), Card(1, 2),
Card(3, 1), Card(3, 2),
Card(2, 0)]
dict = buildDict(testhand)
assert hasTwoPairs(dict)
def test_three_pair():
testhand = [Card(1, 3), Card(1, 2),
Card(1, 1), Card(13, 2),
Card(2, 0)]
dict = buildDict(testhand)
assert hasThreeOfAKind(dict)
def has_Four_Of_A_Kind():
testhand = [Card(1, 3), Card(1, 2),
Card(1, 1), Card(1, 0),
Card(2, 0)]
dict = buildDict(testhand)
assert hasFourOfAKind(dict)
def test_full_house():
testhand = [Card(1, 3), Card(1, 2),
Card(1, 1), Card(13, 2),
Card(13, 2)]
dict = buildDict(testhand)
assert hasFullHouse(dict)
def test_Straight():
testhand = [Card(11, 1), Card(10, 3),
Card(9, 2), Card(8, 1),
Card(7, 3)]
dict = buildDict(testhand)
assert hasStraight(dict)
The condition for a straight is for your five cards to have adjacent ranks, such that no two cards have the same rank. You can use two different checks to confirm this:
when sorted, the difference between the top card and the bottom card is equal to the total number of cards minus one(e.g. a 4-8 straight has a difference of 4)
no two cards in the straight have the same rank (thus by pigeonhole principle, all ranks between the minimum and maximum must be present
Here's a sample implementation of that:
def hasStraight(hand):
# account for both low-ace and high-ace
ranks_low = sorted([card._rank for card in hand])
ranks_high = sorted([(14 if card._rank == 1 else card._rank) for card in hand])
return (
(
ranks_low[-1] - (len(hand) - 1) == ranks_low[0]
or ranks_high[-1] - (len(hand) - 1) == ranks_high[0]
) # condition 1
and len(set(hand)) == len(hand) # condition 2
)
You will also have to account for low-aces and high-aces. You can do this by, for example, doing two similar checks, once with the normal card ranks and once by doing something like `if card._rank == 1: card._rank == 14
The condition for a flush is simply that all cards are the same suit. This is easy to verify, by simply making a set of all unique suits in the hand, and returning true if that set has only one element (thus all the suits must be the same):
def hasFlush(hand):
suits_set = set(*[card._suit for card in hand])
return len(suits_set) == 1
Once you have those, straight flush and royal flush are easy:
def hasStraightFlush(hand):
return hasStraight(hand) and hasFlush(hand)
def hasRoyalFlush(hand):
ranks = sorted([14 if card._rank == 1 else card._rank for card in hand])
return (
hasStraightFlush(hand)
and ranks[0] == 10 and ranks[-1] == 14
) # royal flush starts at 10, ends at high-ace

Why aren't the values from my arrays passing though my full bit adder

# 8-bit-binary adder
#if you have questions about the code just ask
# arrays and funtions
Array1 = []
Array2 = []
#Input A and Validation
def vaildNumberA():
a = int(input("Enter your A value:"))
if (a < 0):
print("Please Enter A Valid Number For Input A")
elif (a > 255):
print("Please Enter A Valid Number For Input A")
else:
Array1 = [int(x) for x in list('{0:08b}'.format(a))]
#Input B and Validation
def vaildNumberB():
b = int(input("Enter your B value:"))
if (b < 0):
print("Please Enter A Valid Number For Input B")
elif (b > 255):
print("Please Enter A Valid Number For Input B")
else:
Array2 = [int(x) for x in list('{0:08b}'.format(b))]
# and gate
# AND Gate
def AND (a,b):
if (a == 1 and b == 1):
return 1
else:
return 0
# or gate
#OR Gate
def OR(a,b):
if (a == 1 or b == 1):
return 1
else:
return 0
# XOR GATEE
#XOR Gate
def XOR (a,b):
if (a == b):
return 0
else:
return 1
#carry formula
def carryformula(a,b,c,d):
return OR(AND(a,b), AND(c,d))
# this is where the calculation should be done
#formula for sum
def calculateSum(Array1,Array2):
carry = ""
sumof = []
for index, in range(len(Array1)):
list2 = Array2[index]
sec_xor_form = XOR(Array1[index],Array2[index])
sumof.append(XOR(sec_xor_form,carry))
carry = carryformula(Array1[index],Array2[index],sec_xor_form,carry)
return list(reversed(sumof))
calculateSum(Array1,Array2)
def main(Array1,Array2):
vaildNumberA()
vaildNumberB()
while True:
a = Array1
b = Array2
total = calculateSum(list(reversed(Array1)),list(reversed(Array2)))
print(total)
quit = input("if want to quit type q: ")
if quit == 'q':
break
main(Array1,Array2)
in the send it prints 0
The only problem in your code is that you need to return Array1 and Array2 from your functions and assign them inside the while true loop, once you do that the code works fine.
The updated code will be
# 8-bit-binary adder
#if you have questions about the code just ask
# arrays and funtions
Array1 = []
Array2 = []
#Input A and Validation
def vaildNumberA():
Array1 = []
a = int(input("Enter your A value:"))
if (a < 0):
print("Please Enter A Valid Number For Input A")
elif (a > 255):
print("Please Enter A Valid Number For Input A")
else:
Array1 = [int(x) for x in list('{0:08b}'.format(a))]
#Return the array
return Array1
#Input B and Validation
def vaildNumberB():
Array2 = []
b = int(input("Enter your B value:"))
if (b < 0):
print("Please Enter A Valid Number For Input B")
elif (b > 255):
print("Please Enter A Valid Number For Input B")
else:
Array2 = [int(x) for x in list('{0:08b}'.format(b))]
#Return the array
return Array2
# AND Gate
def AND (a,b):
if (a == 1 and b == 1):
return 1
else:
return 0
#OR Gate
def OR(a,b):
if (a == 1 or b == 1):
return 1
else:
return 0
#XOR Gate
def XOR (a,b):
if (a == b):
return 0
else:
return 1
#carry formula
def carryformula(a,b,c,d):
return OR(AND(a,b), AND(c,d))
# this is where the calculation should be done
#formula for sum
def calculateSum(Array1,Array2):
carry = ""
sumof = []
for index in range(len(Array1)):
list2 = Array2[index]
sec_xor_form = XOR(Array1[index],Array2[index])
sumof.append(XOR(sec_xor_form,carry))
carry = carryformula(Array1[index],Array2[index],sec_xor_form,carry)
return list(reversed(sumof))
#No need of a main function
while True:
#Call the function from within the while True loop
Array1 = vaildNumberA()
Array2 = vaildNumberB()
total = calculateSum(list(reversed(Array1)),list(reversed(Array2)))
print(total)
quit = input("if want to quit type q: ")
if quit == 'q':
break
And the output will look like
Enter your A value:5
Enter your B value:5
[0, 0, 0, 0, 1, 0, 1, 1]
if want to quit type q: 7
Enter your A value:9
Enter your B value:8
[0, 0, 0, 1, 0, 0, 0, 1]
....

Having an issue with modularization, can't get my program to run correctly

I am creating a histogram which shows me the word and the frequency of each word within a text file.
I went through my previous code which worked and attempted to make it modular. This was practice for class, as we will be creating a Tweet Generator in the future.
Somewhere I am doing something wrong, but I can't see what it is for the life of me.
I were to create from the plain-text file:
List of Lists
List of Tuples
Dictionary of key value pairs
Here is what I have so far:
import re
import sys
import string
def read_file(file):
# first_list = [] ### Unsure if I should actually keep these in here.
# second_list = []###
document_text = open(file, 'r')
text_string = document_text.read().lower()
match_pattern = re.findall(r'\b[a-z]{1, 15}\b', text_string)
return match_pattern
#----------LIST_OF_LISTS---------------
def list_of_lists(match_pattern):
read_file(file)
match_pattern.sort()
list_array = []
count = 0
index = None
for word in match_pattern:
if word == index:
count += 1
else:
list_array.append([index, count])
index = word
count = 1
else:
list_array([index, count])
list_array.pop(0)
return str(list_array)
#------END OF LIST_OF_LISTS-------------
#----------LIST_OF_TUPLES---------------
def list_of_tuples(match_pattern):
read_file(file)
frequency = {}
first_list = []
second_list = []
unique_count = 0
for word in match_pattern:
count = frequency.get(word, 0)
frequency[word] = count + 1
first_list.append(word)
if int(frequency[word]) == 1:
unique_count += 1
for word in match_pattern:
second_list.append(int(frequency[word]))
zipped = zip(first_list, second_list)
return list(set((zipped)))
return str("There are " + str(unique_count) + " words in this file")
#----------END OF LIST_OF_TUPLES---------
#----------DICTIONARY FUNCTION-----------
def dictionary_histogram(match_pattern):
dict_histo = {}
for word in match_pattern:
if word not in dict_histo:
dict_histo[word] = 1
else:
dict_histo[word] += 1
return str(dict_histo)
def unique_word_dict(histogram):
''' Takes the histogram and returns the amount of unique words withi it.'''
return len(histogram.keys())
def frequency(histogram, word):
'''takes in the histogram and a word, then returns a value of the word if the
key exists within the dictionary, else return 0'''
if word in histogram:
return str(histogram[word])
else:
return str(0)
#------------End of Dictionary-----------------
#
# def unique_word(histogram):
# ''' Takes the histogram and returns the amount of unique words withi it.'''
# return len(histogram)
#
# def frequency(word, histogram):
# '''takes a histogram and a word, then returns the value of the word.'''
# return histogram[word]
if __name__ == '__main__':
file = str(sys.argv[1])
read_file(file)
list_of_tuples(match_pattern)
Although, I do believe my
if name == 'main':
is wrong but I did try several different variations and nothing seemed to work for me.
I also tried changing some things, but this didn't work either.
import re
import sys
import string
def read_file(file):
document_text = open(file, 'r')
text_string = document_text.read().lower()
# match_pattern = re.findall(r'\b[a-z]{1, 15}\b', text_string) ### Think I should move this to the actual list function maybe???
### I originally had it return match_pattern and then I used match_pattern in my list functions i.e list_of_lists(match_pattern)
document_text.close()
return text_string
#----------LIST_OF_LISTS---------------
def list_of_lists(text_string):
match_pattern = re.findall(r'\b[a-z]{1, 15}\b', text_string)
# match_pattern.sort() #Maybe use this
list_array = []
count = 0
index = None
for word in match_pattern:
if word == index:
count += 1
else:
list_array.append([index, count])
index = word
count = 1
else:
list_array.append([index, count])
list_array.pop(0)
return str(list_array)
#------END OF LIST_OF_LISTS-------------
#----------LIST_OF_TUPLES---------------
def list_of_tuples(text_string):
match_pattern = re.findall(r'\b[a-z]{1, 15}\b', text_string)
frequency = {}
first_list = []
second_list = []
unique_count = 0
for word in match_pattern:
count = frequency.get(word, 0)
frequency[word] = count + 1
first_list.append(word)
if int(frequency[word]) == 1:
unique_count += 1
for word in match_pattern:
second_list.append(int(frequency[word]))
zipped = zip(first_list, second_list)
# return list(set((zipped)))
return str(list(set(zipped)))
# return str("There are " + str(unique_count) + " words in this file")
#----------END OF LIST_OF_TUPLES---------
#----------DICTIONARY FUNCTION-----------
def dictionary_histogram(text_string):
dict_histo = {}
for word in match_pattern:
if word not in dict_histo:
dict_histo[word] = 1
else:
dict_histo[word] += 1
return str(dict_histo)
def unique_word_dict(histogram):
''' Takes the histogram and returns the amount of unique words withi it.'''
return len(histogram.keys())
def frequency(histogram, word):
'''takes in the histogram and a word, then returns a value of the word if the
key exists within the dictionary, else return 0'''
if word in histogram:
return str(histogram[word])
else:
return str(0)
#------------End of Dictionary-----------------
#
# def unique_word(histogram):
# ''' Takes the histogram and returns the amount of unique words withi it.'''
# return len(histogram)
#
# def frequency(word, histogram):
# '''takes a histogram and a word, then returns the value of the word.'''
# return histogram[word]
# read_file(file)
# list_of_tuples(read_file(file))
if __name__ == '__main__':
file = str(sys.argv[1])
# print(list_of_lists(read_file(file)))
I made 2 minor modifications of your code.
First. I replaced regex \b[a-z]{1, 15}\b with \b[a-z]+\b.
Second. I modified main suite:
if __name__ == '__main__':
file = str(sys.argv[1])
match_pattern = read_file(file)
print(match_pattern)
print()
ans = list_of_tuples(match_pattern)
print(ans)
Output for my sample file:
['asdf', 'asdf', 'asdf', 'sdf', 'asdf', 'asdf', 'asdfdf', 'asdfsdf', 'asdfasd', 'fas', 'dfa', 'sd', 'fass', 'dfafas', 'df', 'asdfsdf', 'asdfsdf', 'asdfdfa', 'sdf', 'asdfdf', 'asdfsdfas', 'dfasdf', 'asdfdfasdf', 'asdffas', 'dfasdffas', 'dfs', 'fas', 'sdf', 'asdfd', 'asdfsd', 'asfd', 'as', 'dfdfa', 'sddf', 'asd', 'fasdf', 'asdf', 'assdf', 'asdf', 'asdf', 'das', 'assdffa', 'sdf', 'asdf', 'asdf', 'assdf', 'asd', 'asd', 'asfdd', 'fasasdf', 'asdf', 'assdf', 'asdf', 'assd']
[('asdfsdfas', 1), ('dfafas', 1), ('dfasdffas', 1), ('asdf', 12), ('as', 1), ('dfasdf', 1), ('fasdf', 1), ('assd', 1), ('assdf', 3), ('dfs', 1), ('asdfdf', 2), ('asd', 3), ('df', 1), ('dfdfa', 1), ('fasasdf', 1), ('asdfsd', 1), ('asfd', 1), ('das', 1), ('asfdd', 1), ('asdffas', 1), ('sdf', 4), ('sddf', 1), ('dfa', 1), ('asdfdfasdf', 1), ('asdfsdf', 3), ('assdffa', 1), ('asdfd', 1), ('asdfasd', 1), ('sd', 1), ('fas', 2), ('asdfdfa', 1), ('fass', 1)]
So the program runs and the output looks like some legit result.

Python Tic Tac Toe code propblems

I have tried creating a tic tac toe game using Python but it is not working. Can someone please take a look at it and tell me if I made a mistake?
When I run the game it only prints the board and then asks for a number for x. Once I type that, the game prints a board and closes.
def tic_tac_toe():
end = False
win_combinations = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6))
board = [1,2,3,4,5,6,7,8,9]
def draw():
print(board[0], board[1], board[2])
print(board[3], board[4], board[5])
print(board[6], board[7], board[8])
print()
def player_option_check():
while True:
try:
arg1 = input("please enter number")
arg1 = int(arg1)
if arg1 in range(0,9):
return arg1 - 1
else:
print ('not a number on he board')
except:
print('this is not a number re try')
def player_X():
choice = player_option_check()
board[choice] = 'x'
def player_y():
choice = player_option_check()
board[choice] = 'y'
def check_winner_x ():
for a in win_combinations:
if board[a[0]] == board[a[1]] == board[a[2]] == 'o':
print('player o wins')
return True
if board[a[0]] == board[a[1]] == board[a[2]] == 'x':
print('player x wins')
return True
for a in range(9):
if board[a] == "X" or board[a] == "O":
count += 1
if count == 9:
print("The game ends in a Tie\n")
return True
while not end:
draw()
end = check_winner_x
if end == True:
break
else:
player_X()
draw()
end = check_winner_x
if end == True:
break
else:
player_y()
draw()
if end==True:
again_play=print(input("would u like to play again press (y/n)"))
again_play == "y"
tic_tac_toe()
else:
print('thanks for playing')
break
tic_tac_toe()
So can you please help me find the mistake in my code. This is in Python 3.
I'm assuming it's cause you're not calling check_winner_x, just assigning it to the value end (maybe print(end) at the end of the loop to see it's value).
That means that when you get back to the while statement, end will register as "truthy" as it's no longer set to false and the loop will exit.
Try actually calling check_winner_x:
end = check_winner_x()
Not sure about anything else that might be buggy, but that's definitely a start.

Resources