I made a simple Blackjack game in Python 3.4.3. I'm a beginner, so it would be awesome if you could rip up my code and tell me everything I did wrong. I know there's no insurance for when the dealer has an ace (yet), and there's some other blackjack rules that I'm going to add in the future, but I wanted to get a base code out there.import random as rimport itertools as isuit = 'scdh'rank = '23456789TJQKA'deck = tuple(''.join(card) for card in i.product(rank, suit))val = ()for _ in range(9):    val = val + (_+2, _+2, _+2, _+2)    if _ == 8:        for __ in range(3):            val = val + (10, 10, 10, 10)val = val + (1, 1, 1, 1)deckval = dict(zip(deck, val))def deal():    global hand, dealer_hand, player_hand, counter    hand = r.sample(deck, 52)    counter = 0    dealer_hand = list(hand[counter:counter + 1])    counter += 2    player_hand = list(hand[counter:counter + 2])    counter += 2def sum_player_hand():    global hand, player_hand, counter, player_sum, opt_player_sum    player_sum = 0    opt_player_sum = 0    for a in range(len(player_hand)):        if int(deckval[player_hand[a]]) == 1 and opt_player_sum + int(deckval[player_hand[a]]) <= 21:            opt_player_sum = player_sum + int(deckval[player_hand[a]]) + 10            player_sum += int(deckval[player_hand[a]])        elif opt_player_sum > 21:            player_sum += int(deckval[player_hand[a]])            opt_player_sum = player_sum        else:            player_sum += int(deckval[player_hand[a]])            opt_player_sum += int(deckval[player_hand[a]])def dealer_init():    global hand, dealer_hand, counter, dealer_sum, opt_dealer_sum    dealer_sum = 0    opt_dealer_sum = 0    if int(deckval[dealer_hand[0]]) == 1:        dealer_sum += int(deckval[dealer_hand[0]])        opt_dealer_sum += dealer_sum + 10    else:        dealer_sum = int(deckval[dealer_hand[0]])        opt_dealer_sum = int(deckval[dealer_hand[0]])    dealer_logic()def dealer_logic():    global hand, dealer_hand, counter, dealer_sum, opt_dealer_sum    if dealer_sum >= 17 or opt_dealer_sum >= 17:        pass    else:        while opt_dealer_sum <= 16:            dealer_sum = 0            opt_dealer_sum = 0            dealer_hand = dealer_hand + list(hand[counter:counter + 1])            counter += 1            for _ in range(len(dealer_hand)):                if int(deckval[dealer_hand[_]]) == 1 and (opt_dealer_sum + int(deckval[dealer_hand[_]])) <= 21:                    opt_dealer_sum += int(deckval[dealer_hand[_]])                    dealer_sum += int(deckval[dealer_hand[_]])                else:                    dealer_sum += int(deckval[dealer_hand[_]])                    opt_dealer_sum += int(deckval[dealer_hand[_]])def main():    global hand, dealer_hand, player_hand, counter, player_sum,     dealer_sum, opt_player_sum, opt_dealer_sum    sum_player_hand()    print('\nDealer has:', dealer_hand[0:2], '--')    if player_sum <= 21:        if opt_player_sum == player_sum or opt_player_sum > 21:            print('Your hand is:', player_hand, '\n', 'Your sum is:', player_sum)        else:            print('Your hand is:', player_hand, '\n', 'Your sum is:', player_sum, 'or', opt_player_sum)        choice = input('Hit or stay? ').lower()        if choice == 'hit':            player_hand = player_hand + list(hand[counter:counter + 1])            counter += 1            main()        elif choice == 'stay':            print('')            if opt_player_sum <= 21:                print('Final Hand: ', player_hand, 'Final Sum:', opt_player_sum)                dealer_init()                if opt_dealer_sum <= 21:                    print('Dealer has:', dealer_hand, 'Sum:', opt_dealer_sum)                    if 21 >= opt_dealer_sum > opt_player_sum:                        print('DEALER WINS')                    else:                        print('YOU WIN')                    run()                else:                    print('Dealer has:', dealer_hand, 'Sum:', dealer_sum)                    if 21 >= dealer_sum > opt_player_sum:                        print('DEALER WINS')                    else:                        print('YOU WIN')                    run()            else:                print('Final Hand: ', player_hand, '\n', 'Final Sum:', player_sum)                dealer_init()                if opt_dealer_sum <= 21:                        print('Dealer has:', dealer_hand, 'Sum:', opt_dealer_sum)                    if 21 >= opt_dealer_sum > player_sum:                        print('DEALER WINS')                    else:                        print('YOU WIN')                    run()                else:                    print('Dealer has:', dealer_hand, 'Sum:', dealer_sum)                    if 21 >= dealer_sum > player_sum:                        print('DEALER WINS')                    else:                        print('YOU WIN')                    run()            else:                print('')                print('***Please enter hit or stay***')                main()        else:            print('BUST\nYOUR HAND WAS:', player_hand, '\nYOUR SUM WAS:', player_sum, '\n')        dealer_init()        if opt_dealer_sum < 21:            print('Dealer has:', dealer_hand, 'Sum:', opt_dealer_sum)            if dealer_sum > 21:                print('DEALER BUSTS')            run()        else:            print('Dealer has:', dealer_hand, 'Sum:', dealer_sum)            if dealer_sum > 21:                print('DEALER BUSTS')            run()def run():    play = input('********************\nWould you like to play again?').lower()    if play == 'yes':        deal()        main()    elif play == 'no':        pass    else:        print('Please enter yes or no')        run()deal()main()run()
Simple Blackjack game in Python 3.4
python;beginner;python 3.x;playing cards
I'd like to add few things to previous answer:Constants should be in upper case, even if they constructed dynamically, e.g. SUIT, RANK, DECK.Group you code by responsibility, let Card class cover SUIT, RANK and VALUE constants to handle every static information that belongs to cards. The same relate to deck and hand.global do not use it. It makes you program hard for reading and understanding. There are a lot of other techniques that are lot cleaner. Also you are not just using global variables you modify them, it is really hard to understand full logic. At least, every function should receive all needed data via arguments and return modified tuple of values, but do not modify globals.main function. Well, it is pretty dirty. It should chain other functions with minimal possible logic, no direct input or output. I'm talking not about your main function, but about what everybody think when somebody says: main function. Main is entry point, this is where your entire module start and finish working.UPD: I'd start with this draftimport itertoolsclass Card(object):    SUIT = 'scdh'    RANK = '23456789TJQKA'    def __init__(self, suit, rank):        self.suit = suit        self.rank = rank    def get_value(self):        return 2 + self.RANK.find(self.rank)    def __repr__(self):        return '{}{}'.format(self.suit, self.rank)DECK = [    Card(suit, rank)     for suit, rank in itertools.product(Card.SUIT, Card.RANK)]class Hand(object):    def __init__(self):        self.cards = []    def add_card(card):        self.cards.append(card)    def get_value():        return sum([card.get_value() for card in self.cards])class Match(object):    def prompt_continue(self):        Asks user for starting new round        pass    def run(self):        Single round logic        self.init_deck()        self.init_player_hand()        self.init_dealer_hand()        while not self.all_ready():            self.player_take_card()            self.dealer_take_card()        self.print_results()    def run_loop(self):        while self.prompt_continue():            self.run()if __name__ == '__main__':    match = Match()    match.run_loop()