Home > OS >  How can I access variables from a parent class in Python?
How can I access variables from a parent class in Python?

Time:12-08

I am writing a program to create a poker class in python for our introductory python course. The second (TexasHoldem) class inherits the poker class. The method hands() in TexasHoldem serves to add the hands of each player with the table to create one list, puts each list in a nested list, runs the check_hand() method on each list to see the best possible hand, and returns the result in a new list of strings. The code looks as follows:


import random

class poker:
    orderedCards = []
    nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K']
    suits = ['D', 'C', 'S', 'H']
    for i in nums:
            for j in suits:
                orderedCards.append(i j)
    def __init__(self, players = 2):
        self.players = players
        self.decks = []
        for i in range(0, self.players):
            self.decks.append([])
        self.table = []
        #shuffle
        self.shuffledCards = []
        self.tempCards = poker.orderedCards.copy()
        for i in range(0, len(self.tempCards)):
            self.shuffledCards.append(self.tempCards.pop(random.randint(0, len(self.tempCards)-1)))
    def add_card(self, n):
        if n >= self.players:
           print('Player index out of range stoopid.')
           return
        self.decks[n].append(self.shuffledCards.pop(0))
    def add_to_table(self):
        self.table.append(self.shuffledCards.pop(0))
    def IsStraightFlush(self, lst):
        # returns True is all 5 cards in the list are of the same rank and of same order
        straight = poker.IsStraight(lst)
        flush = poker.IsFlush(lst)
        if straight and flush:
            return True
        else:
            return False
    def IsFourofaKind(self, lst):
        # returns true of 4 of 5 cards of the list are of the same rank
        lst_joined = ' '.join(lst)
        for i in lst:
            if lst_joined.count(i[0]) >= 4:
                return True 
        return False
    def IsFullHouse(self, lst):
        # returns true of 3 cards are of same rank and 2 cards are of same rank
        temp = lst.copy()
        lst_joined = ' '.join(lst)
        pair = 0
        trip = 0
        trip_rank = 0
        for i in temp:
            if lst_joined.count(i[0]) >= 3:
                trip = True
                trip_rank = i[0]
        for i in temp:
            if i != trip_rank and lst_joined.count(i[0]) >= 2:
                pair = True
        if trip and pair:
            return True
        else:
            return False
        
    def IsFlush(self, lst):
        # returns true if all 5 cards have the same suit
        lst_joined = ' '.join(lst)
        for i in lst:
            if lst_joined.count(i[1]) >= 5:
                return True 
        return False
    def IsStraight(self, lst):
        # returns true if all 5 cards are in order
        rank_only = []
        for i in lst:
            rank_only.append(i[0])
        temp = -1
        for i in poker.nums: 
            if i in rank_only: 
                temp = rank_only.index(i)
                break
        #print(temp)
        count = 1
        for i in range(temp, len(poker.nums)):
            if i < (len(poker.nums) - 1):
                if (poker.nums[i 1] in rank_only):
                    count  = 1
                    continue
        print(count)
        if count >= 5:
            return True
        else: 
            return False
        
    def IsThreeofaKind(self, lst):
        # returns true is 3 cards have the same rank
        lst_joined = ' '.join(lst)
        for i in lst:
            if lst_joined.count(i[0]) >= 3:
                return True
        return False

    def IsTwoPairs(self, lst):
        # returns true if there are 2 pairs of cards of the same rank
        temp = lst.copy()
        temp_joined = ' '.join(temp)
        pairs = 0
        for i in temp:
            if temp_joined.count(i[0]) >= 2:
                pairs  = 1
                temp.pop(temp.index(i))
        if pairs >= 2:
            return True
        else:
            return False               
    
    def IsOnePair(self, lst): 
        # returns true if there are 2 cards of the same rank
        lst_joined = ' '.join(lst)
        for i in lst:
            if lst_joined.count(i[0]) >= 2:
                return True
        return False


class TexasHoldem(poker):
    def __init__(self, players):
        super().__init__(players)
        #self.table = poker.table 
        #self.decks = poker.decks
        
    def deal(self):
        for i in range(2):
            for i in range(self.players):
                super().add_card(i)
        for i in range(5):
            super().add_to_table()
        
    def check_hand(self, lst):
        if poker.IsStraightFlush(lst):
            return 'Straight Flush'
        elif poker.IsFourofaKind(lst):
            return 'Four of a Kind'
        elif poker.IsFullHouse(lst):
            return 'Full House'
        elif poker.IsFlush(lst):
            return 'Flush'
        elif poker.IsStraight(lst):
            return 'Straight'
        elif poker.IsThreeofaKind(lst):
            return 'Three of a Kind'
        elif poker.IsTwoPairs(lst):
            return 'Two Pairs'
        elif poker.IsOnePair(lst):
            return 'One Pair'
        else:
            return 'High Card'

    def hands(self):
        self.final_decks = []
        for i in TexasHoldem.decks:
            self.final_decks.append(i   TexasHoldem.table)
        self.final_hands= []  
        for i in self.final_decks:
            self.final_hands.append(TexasHoldem.check_hand(i))
        print(self.final_hands)

    #def besthand(self):
        
    
test = poker(5)
#print(test.shuffledCards)
#print(len(test.shuffledCards))
test.add_card(4)
#print(test.decks)
test.add_to_table()
#print(test.table)        
final_test = TexasHoldem(5)
final_test.deal()
print(final_test.decks)
print(final_test.table)
final_test.hands()


Running the current code gives me the following error:

AttributeError: type object 'TexasHoldem' has no attribute 'table'

I can see that my deal() method is indeed making the nested list of cards for each player and dealing the table as it should, but I cannot figure out why TexasHoldem does not have the attribute table, even though it is being printed when I run the file. How can I fix my hands() method so it can access the decks and table list?

CodePudding user response:

"decks" and "tables" are not static elements in your parent class; try using the self keyword in hand(); eg: change TexasHoldem.decks to self.decks

CodePudding user response:

Hello and welcome to StackOverflow! The answer to your question, if I understand correctly, is actually quite simple. The reason you can't access the attribute "decks" from the parent class "poker" is because that attribute doesn't exist in poker! At least, not globally. While it does exist locally within the scope of __init__, it wasn't declared along with the other attributes, such as orderedCards, nums, and suits. I do find it genuinely surprising, however, that Python allows you to create new attributes to a class any time you wish, you learn something new every day I suppose. In any case, however, since it was only declared within a class method, instead of being declared with the rest of the attributes, it doesn't get carried over to derived classes.

A simple solution to this problem, and one that seemed to work for me, would be to simply add the following line of code:

decks = []

to line 5. Doing this should hopefully declare decks as an official attribute of poker. And, likewise, as an official attribute of Texas_holdem (as well as any other derived classes, and derived derived classes, and derived derived derived etc.).

If you need any more help, or if this wasn't quite the answer you were looking for, please feel free to tell us! Happy coding! :)

CodePudding user response:

To access parent class attributes in a child class: Use the super() method to call the constructor of the parent in the child. The init() method will set the instance variables. Access any of the parent class's attributes or methods on the self object.

  • Related