Edited simple Blackjack game in Python 3.4 I'm a beginning Python programmer, and earlier I made a simple Blackjack game in Python. The original version (which can be found here) got a lot of great feedback, so I rewrote the entire program to reflect the feedback I received. Again, any tips are appreciated.

import random
import itertools

# generates the deck and card values
SUIT = 'scdh'
RANK = '23456789TJQKA'
DECK = tuple(''.join(card) for card in itertools.product(RANK, SUIT))
VAL = []
for a in range(9):
    VAL += [a+2] * 4
for _ in range(3):
    VAL += [10] * 4
VAL += [1] * 4
DECKVAL = dict(zip(DECK, VAL))
counter = 0


def shuffle():
    # shuffles the deck into random order
    global s_deck
    s_deck = random.sample(DECK, 52)


class Hand:

    global counter, s_deck

    def __init__(self):
        # deals 2 cards
        # sets up variables hand_sum and init_sum for totaling
        global counter
        self.cards = list(s_deck[counter:counter + 2])
        counter += 2
        self.hand_sum = 0
        self.init_sum = 0

    def sum_hand(self):
        # totals the hand
        self.hand_sum = 0
        self.init_sum = 0
        for b in range(len(self.cards)):
            self.init_sum += DECKVAL[self.cards[b]]
        if ('As' in self.cards or 'Ac' in self.cards or 'Ad' in self.cards or 'Ah' in self.cards)\
                and self.cards and self.init_sum + 10 &lt;= 21:    # special ace rule conditions
            self.hand_sum = self.init_sum + 10
        else:
            self.hand_sum = self.init_sum

    def draw(self):
        # draws a card from the deck
        global counter
        self.cards += list(s_deck[counter:counter + 1])
        counter += 1

    def hit_or_stay(self, dealer):
        # asks the player if they want to hit or stay
        self.bust(dealer)
        print("\n\nDealer's Hand:", dealer.cards[0], "--")
        print("Your hand is:", self.cards, "   Your sum is:", self.hand_sum, "\n")
        choice = input("Hit or Stay? ").lower()
        if choice == 'hit':
            self.draw()
            self.hit_or_stay(dealer)
        elif choice == 'stay':
            self.total(dealer)
        else:
            print("Please enter hit or stay")
            self.hit_or_stay(dealer)

    def total(self, dealer):
        # determines winner
        if self.hand_sum &gt; dealer.hand_sum:
            print("You won the hand")
        elif self.hand_sum &lt; dealer.hand_sum:
            if dealer.hand_sum &lt;= 21:
                print("You lost the hand")
            else:
                print("Dealer busted")
        else:
            print("You tied")
        print("Dealer's hand:", dealer.cards, "   Dealer's sum:", dealer.hand_sum)
        print("Your hand:", self.cards, "Your sum:", self.hand_sum)
        print("\n*******************\n")

    def bust(self, dealer):
        # checks for player busting
        self.sum_hand()
        if self.hand_sum &gt; 21:
            print("YOU BUSTED\n")
            self.hand_sum = 0
            self.total(dealer)
        else:
            pass


class Dealer(Hand):

    def __init__(self):
        Hand.__init__(self)
        self.logic()

    def logic(self):
        # makes sure the dealer hits "soft 17"
        self.sum_hand()
        while self.hand_sum &lt; 17:
            self.draw()
            self.sum_hand()


class Game:

    def __init__(self):
        # starts the game
        x = input("Would you like to play?").lower()
        if x == "yes":
            shuffle()
            player = Hand()
            dealer = Dealer()
            player.hit_or_stay(dealer)
        else:
            pass

if __name__ == '__main__':
    game = Game()
My first tip would be to get rid of the Game class. It serves no value. Rather, it should be a method, appropriately named main. If you want a few tips for determining whether to write a class or not, here are a some instances where you should avoid classes:


If the class only contains two methods, __init__, and another.
If the class never refers to self. (Credit to @jonrsharpe)

Secondly, those comments underneath your function declarations should be docstrings. A typical function docstring would look something like this,

def my_func(args):
    """
    A detailed description of the function
    and its arguments.
    """

The below statement in Game.__init__ is not needed, and does nothing. It can be removed.

else:
    pass

You have some odd naming in places. For example, logic could be renamed to check_for_soft_17 or something along those lines, and total could be renamed to determine_winner.
The two for loops underneath the VAL = [] could be shortened to generator expressions. Here's how that would be done.

VAL = [[a + 2] * 4 for a in range(9)] + [[10] * 4 for _ in range(3)]

Preferably, the variable a in the above example should also be renamed to something a little more descriptive, and you should apply some of those "magic numbers" to variables as well.
As mentioned by @Josay, you're using globals in a lot of your functions. Rather than assigning a value to a global, try returning a value instead. It makes things a whole lot easier to manage.


Anyways, that's about all I can think of. If there's anything else that you want me to cover, just mention it in the comments, and I'll see what I can do. I hope this helps!