import random
class Card:
    def __init__(self, suit, rank):
        self.rank = rank
        self.suit = suit
        if self.rank == 1:
            self.rank = "Ace"
            self.value = 11
        elif self.rank == 11:
            self.rank = "Jack"
            self.value = 10
        elif self.rank == 12:
            self.rank = "Queen"
            self.value = 10
        elif self.rank == 13:
            self.rank = "King"
            self.value = 10
        elif 2 <= self.rank <= 10:
            self.rank = str(self.rank)
            self.value = self.rank

        if self.suit == 1:
            self.suit = "Clubs"
        if self.suit == 2:
            self.suit = "Spades"
        if self.suit == 3:
            self.suit = "Diamonds"
        if self.suit == 4:
            self.suit = "Hearts"
        self.cardname = self.rank + " of " + self.suit

deck = []
for suit in range(1,5):
    for rank in range(1,14):
        deck.append(Card(suit,rank))

class Player:
    def player_turn(self):
        hand = []
        for cards in range(0,2):
            a = random.choice(deck)
            hand.append(a)
            deck.remove(a)

        print "This is your hand:"
        for card in hand:
            print card.cardname

        print "Would you like to hit or stay?"
        response= raw_input("Type either 'hit' or 'stay'")
        while response =="hit":
            card=random.choice(deck)
            hand.append(card)
            deck.remove(card)
            print "Your next card is", card.cardname
            sum = 0
            for i in hand:
                sum=sum+i.value
                if sum > 21:
                    break
            print "Would you like to hit or stay?"
            response = raw_input("Type either 'hit' or stay'")        


        sum=0
        for i in hand:
            sum=sum+i.value
        if sum > 21:
            return "You lose. You Busted", sum
        else:
            return "This is your score: ", sum

In LINE 58, we keep getting the message unsupported operand type(s) for +: 'int' and 'str'. Why won't saying "for i in hand: sum=sum+i.value" not work, and what are we supposed to do to fix it

Recommended Answers

All 6 Replies

elif 2 <= self.rank <= 10:
self.rank = str(self.rank)
self.value = self.rank

In LINE 20 you set self.rank to a string, then assigned that same string to self.value . Hence the error. You really are trying to add a string to an integer.

Incidentally, I suggest avoiding the use of sum as a variable name. It's also the name of a built-in function, but you won't be able to call sum() if you store a value therein.

commented: good observation! +10

Thanks so much for the help with that problem. I realized it a few minutes after I posted it, lol.

I have another problem with the program, when I run it, I always end up losing and whenever I say to print p.sum or d.sum, I get this weird message. Could you all please help me?

Here is the new code:

import random
class Card:
    def __init__(self, suit, rank, value):
        self.rank = rank
        self.suit = suit
        self.value= value
        if self.rank == 1:
            self.rank = "Ace"
            self.value = 11
        elif self.rank == 11:
            self.rank = "Jack"
            self.value = 10
        elif self.rank == 12:
            self.rank = "Queen"
            self.value = 10
        elif self.rank == 13:
            self.rank = "King"
            self.value = 10
        elif 2 <= self.rank <= 10:
            self.rank = str(self.rank)
            self.value = self.rank

        if self.suit == 1:
            self.suit = "Clubs"
        if self.suit == 2:
            self.suit = "Spades"
        if self.suit == 3:
            self.suit = "Diamonds"
        if self.suit == 4:
            self.suit = "Hearts"
        self.cardname = self.rank + " of " + self.suit

deck = []
for suit in range(1,5):
    for rank in range(1,14):
        for value in range(2,12):

            deck.append(Card(suit,rank,value))

class Player:

    def player_turn(self):
        hand = []
        for cards in range(0,2):
            a = random.choice(deck)
            hand.append(a)
            deck.remove(a)

        print "This is your hand:"
        for card in hand:
            print card.cardname

        print "Would you like to hit or stay?"
        response= raw_input("Type either 'hit' or 'stay'")

        while response =="hit":
            card=random.choice(deck)
            hand.append(card)
            deck.remove(card)
            print "Your next card is", card.cardname
            psum=0
            for i in hand:
                psum=int(i.value) + psum
            if psum > 21:
                break
            print "Would you like to hit or stay?"
            response = raw_input("Type either 'hit' or stay'")

            return psum

    def sum(self):
        sum=0
        for i in hand:
            sum= int(i.value)+sum
        return sum


class Dealer:

    def computer_turn(self):
        dealerhand = []
        for cards in range(0,2):
            a = random.choice(deck)
            dealerhand.append(a)
            deck.remove(a)
        dsum = 0
        for i in dealerhand:
            dsum = int(i.value)+dsum
        while dsum < 17:
            card = random.choice(deck)
            dealerhand.append(card)
            deck.remove(card)
            dsum = int(card.value)+dsum

        return dsum

    def sum(self):
        sum=0
        for i in dealerhand:
            sum= int(i.value)+sum
        return sum



print "Would you like to play?"
answer = raw_input("'Yes' or 'No'")
while answer == "Yes":
    p = Player()
    d = Dealer()
    p.player_turn()
    d.computer_turn()

    if p.sum > d.sum and p.sum <= 21:
        print "You won! Here is the dealer's score."
        print d.sum
    else:
        print "You lost. Here is the computer's score.", str(d.sum)


    print "Would you like to play again?"
    answer = raw_input("'Yes' or 'No'")

I already see a problem, you should swap lines 20 and 21 because here, in line 21, you are giving a string value to self.value.
In the __init__ method, you should never have written line 4 if you want to give self.rank a string value, you can work with the rank argument directly.

There are quite a number of errors in your code. Check the remarks ending with '!!!!!!!!!!!' in the corrected code ...

import random

class Card:
    def __init__(self, suit, rank, value):
        self.rank = rank
        self.suit = suit
        self.value= value
        if self.rank == 1:
            self.rank = "Ace"
            self.value = 11
        elif self.rank == 11:
            self.rank = "Jack"
            self.value = 10
        elif self.rank == 12:
            self.rank = "Queen"
            self.value = 10
        elif self.rank == 13:
            self.rank = "King"
            self.value = 10
        elif 2 <= self.rank <= 10:
            self.value = self.rank     # this line first!!!!!!!!!
            self.rank = str(self.rank)
        
        if self.suit == 1:
            self.suit = "Clubs"
        if self.suit == 2:
            self.suit = "Spades"
        if self.suit == 3:
            self.suit = "Diamonds"
        if self.suit == 4:
            self.suit = "Hearts"
        self.cardname = self.rank + " of " + self.suit

deck = []
for suit in range(1,5):
    for rank in range(1,14):
        for value in range(2,12):

            deck.append(Card(suit,rank,value))

class Player:

    def player_turn(self):
        # prefix hand with 'self.' to pass into method !!!!!!
        self.hand = []
        for cards in range(0,2):
            a = random.choice(deck)
            self.hand.append(a)
            deck.remove(a)

        print "This is your hand:"
        for card in self.hand:
            print card.cardname

        print "Would you like to hit or stay?"
        response = raw_input("'hit' or 'stay' (h or s) ").lower()
        
        while 'h' in response:
            card=random.choice(deck)
            self.hand.append(card)
            deck.remove(card)
            print "Your next card is", card.cardname
            ptotal=0
            for i in self.hand:
                ptotal = int(i.value) + ptotal
            if ptotal > 21:
                break
            print "Would you like to hit or stay?"
            response = raw_input("'hit' or 'stay' (h or s) ").lower()
            
            return ptotal
    
    def total(self):
        total=0
        for i in self.hand:
            total= int(i.value)+total
        return total


class Dealer:

    def computer_turn(self):
        # prefix dealerhand with 'self.' to pass into method !!!!!!
        self.dealerhand = []
        for cards in range(0,2):
            a = random.choice(deck)
            self.dealerhand.append(a)
            deck.remove(a)
        dtotal = 0
        for i in self.dealerhand:
            dtotal = int(i.value)+dtotal
        while dtotal < 17:
            card = random.choice(deck)
            self.dealerhand.append(card)
            deck.remove(card)
            dtotal = int(card.value) + dtotal
        
        return dtotal
    
    def total(self):
        total=0
        for i in self.dealerhand:
            total= int(i.value) + total
        return total

    
        
print "Would you like to play?"
# added lower() so 'Yes' will be 'yes' ...
answer = raw_input("'Yes' or 'No' (y or n) ").lower()
while 'y' in answer:
    p = Player()
    d = Dealer()
    p.player_turn()
    d.computer_turn()
    # test
    print p.total(), d.total()
  
    # use () to call methods!!!!!!!!!!!!!!
    if p.total() > d.total() and p.total() <= 21:
        print "You won! Here is the dealer's score."
        print d.total()
    # dealer busted!!!!!!!!!!!!!!
    elif d.total() > 21:
        print "Dealer lost."
    # got a draw!!!!!!!!!!!!!!!!!
    elif p.total() == d.total():
        print "A draw."
    else:
        print "You lost. Here is the computer's score.", str(d.total())
        
    
    print "Would you like to play again?"
    answer = raw_input("'Yes' or 'No' (y or n) ")

Also changed 'sum' to 'total' to avoid any conflict with Python's sum() function. Added lower() and changed to 'in' to make user entry easier.

Thanks for all the help. It ended up working. One last question. When asking hit or stay and also whether you want to play again, how do you make sure they give a valid response?

Thanks for all the help. It ended up working. One last question. When asking hit or stay and also whether you want to play again, how do you make sure they give a valid response?

Well you can do a couple things. A couple examples.

def Again():
    again = raw_input("Play again? y or n")
    if again.lower() in "y yea yes".split():
        main()
    else:
        Again()

Where main() is the game itself.
Or...

import re
yes = re.compile('yes', re.I)
def Again():
    again = raw_input("Play again?")
    if yes.search(again):
        main()
    else:
        Again()

Same thing with hit or stay.

hit = raw_input("Hit or stay? h or s")
if hit.lower() in "hit h".split():
    hit()
else:
    stay()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.