Hi Guys. I am new here. I am trying to run a Poker program that can detect the different hands in poker.
here is my code

class Card:
        # A card is an Object with a suit and rank
        # attributes.

    def __init__(self, rank, suit):
        # To create a new Card, we pass in strings
        # representing the rank and suit (e.g.,
        # "A" and "H" for the ace of hearts).
        # We then populate a new Card object
        # with the appropriate information.
        self.rank = rank
        self.suit = suit

    def __str__(self):
        # This function defines a string used to print
        # this object.  
        return self.rank + self.suit

    def getRank(self):
        # return my rank
        return self.rank

    def getSuit(self):
        # return my suit
        return self.suit

class Deck:
        # A Deck is an Object which contains a list of Cards. 

    def __init__(self):
        # Create a new deck of cards. 
        self.cards = []
        for r in ["A", "2","3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]:
            for s in "SHDC":
                newCard = Card(r, s)
                self.cards.append(newCard)
        # The random module contains a number of useful
        # functions including one that randomly reorders
        # a list.
        from random import shuffle
        shuffle(self.cards)

    def __str__(self):
        # This returns a string representing the Deck.  Defining
        # this function allows `print deck' to work properly.
        s = ""
        for c in self.cards:
            s = s + c.__str__() + " "
        return "[ " + s + "]"

    def shuffleDeck(self):
        # Return a random permutation of the cards in the
        # deck.
        from random import shuffle
        shuffle(self.cards)

    def nextCard(self):
        # Remove and return the first card from the deck.
        c = self.cards.pop(0)
        return c

    def size(self):
        # Ask how many cards are left in the deck.
        return len(self.cards)
class Hand:
    # A Hand is an object that contains a list of 5 cards.  We need to 
    # be able to draw a hand from a deck and evaluate it to see what
    # it contains. 

    # These two arrays are used to compute the right place to index
    # into the other arrays created below.
    suits = [ "S", "H", "D", "C" ]
    ranks = ["A", "2", "3", "4", "5", "6", "7",
             "8", "9", "10", "J", "Q", "K"]
    #Ranks = {'A' : 1, '2' :2, '3': 3, '4' : 4, '5' : 5, '6' : 6, '7' :7, '8': 8, '9':9,
             #'10': 10, 'J' :11, 'Q' : 12, 'K' : 13}
    counter= None
    rindex= None

    def __init__(self, deck):
        # A hand is simply the first five cards in the deck, if there are
        # five cards available.
        if ( deck.size() < 5 ):
            print "Not enough cards left!"
            return
        self.mycards = []
        for i in range(5):
            card = deck.nextCard()           # returns next card
            self.mycards.append(card)        # appends it to the hand
        self.processHand()

    def processHand(self):
        # These are used to record the information in the hand:
        self.myranks = [0] * 13 
        self.mysuits = [0] * 4	
        # For each card, extract and record its suit and rank in myranks
        # and mysuits arrays.
        for c in self.mycards:
            r = c.getRank()
            rind = Hand.ranks.index(r)
            self.myranks[rind] = self.myranks[rind] + 1
            s = c.getSuit()
            sind = Hand.suits.index(s)
            self.mysuits[sind] = self.mysuits[sind] + 1

    def __str__(self):
        s=""
        for c in self.mycards:
            s= s + c.__str__() + " "
        return "[ " + s + " ]"

    # You may need some auxiliary functions beyond what is here. 

    def hasFlush(self):
        # checks if any of the suits in mysuits has 5; if so, then there is a flush.
        if 5 in self.mysuits:
            return True
        return False
                

    def hasFourOfAKind(self):
        # Checks if any of the cards in myranks list has 4 of the same value; if so, then there are four of a kind.
        if 4 in self.myranks:
            return True
        return False
                

            
            

    def hasThreeOfAKind(self):
        # checks to see if first card's rank is equal to second card's rank; if not
        # then goes through loop of temp in other cards; process repeated with second card check again subsequent cards
        #  uses iteration to see number of times the ranks match; if match two times, then there is a three of a kind.
        if 3 in self.myranks:
            return True
        return False
        

    def hasPair(self):
        # checks to see if two cards match using algorithm described in hasThreeOfAKind(self)
        if 2 in self.myranks:
            return True
        return False



    def hasTwoPair(self):
        # Loop through the rankList. Then, use temp as pointer
        # that points to the next card  after rank. Compares pointer's rank to temp's
        # rank. iteration keeps track of how many matches in the hand. 
        iteration= 0
        result= False
        rankList= self.myranks.tolist()
        
        for pointer in self.rankList:
            for temp in self.rankList[rankList.index(pointer)+1 : len(self.rankList)-1]:
            
                if pointer== temp:
                    iteration= iteration + 1
            
            
        if iteration == 2:
            result = True
        return result
       

            
    def hasStraight(self):
        # Does this code work?
        # Convert myranks array to a list. loop through the five ranks in cards.
        # Temp runs from the rank after cards to the end of cards list. If the value
        # in the rank array after the counter is equal to the rank of the next card
        # in cards and the previous condition is satisfied
        # in all of the ranks, then there is a straight.
        animal= 0
        for kite in self.myranks:
            coyote= self.myranks[trap+1]
            if 1 in kite and 1 in coyote:
                animal= animal + 1
        if 1 in self.myranks[0]:
            animal= animal + 1
        if animal == 4:
            return True
        return False
         
                  

    def hasFullHouse(self):
        
        integer= 0
        countess= 0
        for beans in self.myranks:
            if 2 in beans:
                integer+= 1

        for bill in self.myranks:
            if 3 in bill:
                countess= countess + 1
        if integer== 1 and countess== 1:
            return True
        return False
                
            
        

    def hasRoyalStraight(self):
        clock= 0
        control= 0
        for mod in self.mysuits:
            if 4 in mod:
                clock= clock + 1
        for trap in self.myranks:
            time= self.myranks[trap+1]
            if 1 in trap and 1 in time:
                control= control + 1
        if 1 in self.myranks[0]:
            control= control + 1
        if clock== 1 and control == 4:
            return True
        return False
            

    def hasStraightFlush(self):
        flash= 0
        bash= False
        cash= False
        lash= False
        for kitten in self.myranks:
            kat= self.myranks[kitten+1]
            if 1 in self.myranks[kitten]:
                bash= True
            if 1 in self.myranks[kat]:
                bash= True
            if bash== True and cash== True:
                flash= flash + 1
        if 1 in self.myranks[0]:
            flash= flash + 1
        if 5 in self.mysuits:
            lash= True
        if flash == 4 and lash== True:
            return True
        return False

    def evaluateHand(self):
        
        if self.hasStraightFlush():
            return "Straight Flush"
        elif self.hasFourOfAKind():
            return "Four of a kind"
        elif self.hasFullHouse():
            return "Full House"
        elif self.hasFlush():
            return "Flush"
        elif self.hasStraight():
            return "Straight"
        elif self.hasThreeOfAKind():
            return "Three of a kind"
        elif self.hasTwoPair():
            return "Two pair"
        elif self.hasPair():
            return "Pair"
        else:
            return "Nothing"

when I try to execute the code.

d= Deck()
h= Hand(d)
h.evaluateHand()

It gives me this error:
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 237, in evaluateHand
if self.hasStraightFlush():
File "C:\Python26\Poker.py", line 228, in hasStraightFlush
if 1 in self.myranks[kitten] and 1 in self.myranks[kat]:
TypeError: argument of type 'int' is not iterable

I looked under the error in this forum, and thought that perhaps python is trying to concatenate self.myranks[kitten] and 1, so I broke the code into different lines.
But the error still remains.

How should I fix it?

You don't have
if 1 in self.myranks[kitten] and 1 in self.myranks[kat]:
in any of the code you posted. Is there more than one version of this program?

It apparently thinks that self.myranks[kitten] or [kat] is an integer. Do a
print type(self.myranks[kitten])
before the offending line and see what prints. Then you will have to try and discover where self.myranks[x] is set to an integer if it indeed is one now. Note that you initialize it to a list of integers, not a list of lists, i.e. a list would be
if 1 in self.myranks

How should I fix it?

Don't create it in the first place. Don't write long blocks of code without testing and ask someone else to clean up your mess. At a minimum, test each function after you write it.

def evaluateHand(self):
 
        if self.hasStraightFlush():
            return "Straight Flush"
        elif self.hasFourOfAKind():
            return "Four of a kind"
        elif self.hasFullHouse():
            return "Full House"
        elif self.hasFlush():
            return "Flush"
        elif self.hasStraight():
            return "Straight"
        elif self.hasThreeOfAKind():
            return "Three of a kind"
        elif self.hasTwoPair():
            return "Two pair"
        elif self.hasPair():
            return "Pair"
        else:
            return "Nothing"

The above function can be optimized by testing for a pair, and not testing for 3 or 4 of a kind if a pair isn't found. along the lines of:

def evaluateHand(self):
        return_lit = 'Nothing'
        if self.hasStraight():
            return_lit = "Straight"
            if self.hasStraightFlush():
                return_lit = "Straight Flush"
        elif self.hasPair():
            return_lit = "Pair"
            if self.hasThreeOfAKind():
                return_lit = "Three of a kind"
                if self.hasFourOfAKind():
                    return_lit = "Four of a kind"
                elif self.hasFullHouse():
                   return_lit = "Full House"
##   etc 

return return_lit

Edited 6 Years Ago by woooee: n/a

I see. so you are saying that self.myranks[kitten] is a list of integers ??
I will try printing the line like you said.
and wooee, I did know how to test before today, so that is why I wrote long lines of code.

And wooee, you were right the program thinks that self.myranks[kitten] is an integer. the program printed out 1.

So I changed my code for hasStraightFlush(self) to just the line "return hasFlush(self) and hasStraight(self)" and a new error message occurs:
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 249, in evaluateHand
if self.hasStraightFlush():
File "C:\Python26\Poker.py", line 225, in hasStraightFlush
return hasFlush(self) and hasStraight(self)
NameError: global name 'hasFlush' is not defined
Why does python think hasFlush is a global name?

Because it hasn't been defined. You defined (and should use)
return self.hasFlush()

self.xxx means that it is a member of the class

return hasFlush(self)
is passing self to a hasFlush function outside of the class.

Edited 6 Years Ago by woooee: n/a

The same error happened even after I called self.hasFlush() .
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 249, in evaluateHand
File "C:\Python26\Poker.py", line 225, in hasStraightFlush
# two previous methods and evaluate whether the cards satisfy the criteria through a boolean.
NameError: global name 'hasFlush' is not defined
>>>

Anyone have any ideas on how I should fix it? I tried Hands.hasFlush() and Hands(self).hasFlush() and Hands.hasFlush(self) all to no avail.

Or

Hands.hasFlush()

for outside the class Hands, or

self.hasFlush()

if it's inside the class that defines hasFlush().

Cheers and Happy coding

Edited 6 Years Ago by Beat_Slayer: n/a

thank you Beat_Slayer. I appreciate your response to my questions

This question has already been answered. Start a new discussion instead.