Following is my code for a blackjack Game I've written:


    import random
    from random import choice
    import os
    import time
    import texttable

    class Stack():
	
	    def __init__(self, replay, winnings):
		    self.start_amount = 100
		    self.stored_bet = 0
		    self.stored_end = 0
		    self.replay = replay
		
		    if self.replay == 0:
			    self.stored_end = 0   #needs to be initialized
		    else:
			    self.stored_end = self.stored_end + winnings
	
	    def load_account(self):
		    self.stored_end = self.start_amount
	
	    def account(self, begin, change):
		    end = float(begin) + float(change)
		    self.stored_end = end  # store class variable??
		    return(begin, change, end)
	
	    def bet_test(self, miss_type):
		    # collect's bet and check input
		    # miss_type should start as 0
		    possible_bets = ['5', '10', '15', '20', '25']
		    while True:
			    print "\nWhat is your bet? (5, 10, 15, 20, 25)"
			    bet = raw_input(' >')
			    if bet in possible_bets:
				    bet = int(bet)
				    if self.replay == 1:
					    begin = self.stored_end
					    self.stored_bet = int(bet)
					    break
				    else:
					    if bet > self.stored_end:
						    print "You don't have enough for that bet."
						    time.sleep(2)
					    else:
						    begin = self.stored_end
						    self.stored_bet = bet
						    break
	
						
    class DECK():	
	    def __init__(self):
		    suite = ('Spades', 'Hearts', 'Diamonds', 'Clubs')
		    rank = ('2', '3', '4', '5', '6', '7', '8', '9', '10', "Jack", "Queen", "King", "Ace")
		    self.full_deck = {}
		    n = 0
		    i = 0
		    for n in range(6):
			    for s in suite:
				    for r in rank:
					    self.full_deck[i + n] = "%s of %s" % (r, s)
					    i += 1
			    n += 1
		
		    self.values = {'Ace':11, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'Jack': 10, 'Queen': 10, 'King': 10}
		    self.test_hand1 = {0: 'Ace of Spades', 1: 'Jack of Clubs' } # for testing
		    self.test_hand2 = {0: 'Ace of Clubs', 1: '10 of Diamonds' } # for testing
		    self.test_hand3 = {0: '8 of Spades', 1: '8 of Hearts'} # for testing splits
		
		    self.hand_dict = {} # this will be a dict of all the hand instances created by Hand.
		    self.incomplete_hands = {} # hands yet to be played
		    self.compltete_hands = {} # hands done being played
		
		    # re-split hands and counters
		    self.split_counter = 0
	
	    def hand_table(self):
		    # show table of hands
		    hands_dict = {}
		    bets_dict = {}
		    points_dict = {}
		    for hand in Hand.instances:
			    hands_dict.setdefault(hand.name, hand.hand_a)
			    bets_dict.setdefault(hand.name, hand.bet)
			    points_dict.setdefault(hand.name, hand.hand_points)
		
		    first_cards = []
		    second_cards = []
		    third_cards = []
		    fourth_cards = []
		    fifth_cards = []
		    bets_list = []
		    points_list = []
		
		    for hand in hands_dict:
			    first_cards.append(hands_dict[hand].get(0))
			    second_cards.append(hands_dict[hand].get(1))
			    third_cards.append(hands_dict[hand].get(2))
			    fourth_cards.append(hands_dict[hand].get(3))
			    fifth_cards.append(hands_dict[hand].get(4))
			    bets_list.append("Bet is %r" % bets_dict[hand])
			    points_list.append("Points are %r" % points_dict[hand])
			
		    print "\n"	
		    header = hands_dict.keys()
		    table = texttable.Texttable()
		    table.header(header)
		    table.add_rows([first_cards, second_cards, third_cards, fourth_cards, fifth_cards, points_list, bets_list], header = False)
		    print table.draw()
	
	    def dhos(self): 
		    # dealer hit or stick
		    os.system("clear")
		
		    #show table of hands
		    self.hand_table()
		
		    print " _ " * 10
		    game.deck.d_hand.show_hand()
		
		    time.sleep(1.5)
		
		    dpoints, d_raw_points = game.deck.d_hand.points()
		
		    if dpoints < 17:
			    new_card = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
			    print new_card
			    hl = len(game.deck.d_hand.hand_a.keys())  # hl is hand length
			    game.deck.d_hand.hand_a[hl] = new_card  # insert new hard into the given hand
			    self.dhos()
		    else:
			    game.deck.d_hand.hand_points = dpoints
			    game.end_game()
		
	
	    def deal(self):
		    # deal two cards each to dealer and player
		    dhand = {}
		    phand = {}
		    for i in range (2):
			    phand[i] = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
			    dhand[i] = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
    # actual hand			
		    # creat instance of Hand for player's starting hand
		    self.start_hand = Hand(phand, game.deck.full_deck, 0, "Opening Hand")
		    # start_hand instance is now a member of the deck object.

		
		    # creat instance of Hand for dealer's starting hand
		    self.d_hand = Hand(dhand, game.deck.full_deck, 0, "Dealer")
		    # d_hand instance is now a member of the deck object.

	    def split_algo(self, hand):
		
		    print hand.hand_a
		
		    # old cards
		    card1 = hand.hand_a[0]
		    card2 = hand.hand_a[1]
		    print card1
		    print card2
		
		    # new cards
		    card_a = self.full_deck.pop(random.choice(self.full_deck.keys()))
		    card_b = self.full_deck.pop(random.choice(self.full_deck.keys()))
		    print card_a
		    print card_b
		
		    #two new hands
		    new_hand_a = {0: card1, 1: card_a}
		    new_hand_b = {0: card2, 1: card_b}
		
		    if game.deck.split_counter == 0:
			    self.split_1 = Hand(new_hand_a, game.deck.full_deck, 0, 'Split 1')
			    self.split_2 = Hand(new_hand_b, game.deck.full_deck, 0, 'Split 2')
			
			    # load bets: equal to bet on first hand
			    self.split_1.bet = game.deck.start_hand.bet
			    self.split_2.bet = game.deck.start_hand.bet
			
			    split_hands_dict = {0: self.split_1, 1: self.split_2}
			
			    # find the staring hand 'test split' in this case and delete it
			    for x in range(len(Hand.instances)):
				    if Hand.instances[x-1].name == 'Opening Hand':
					    del Hand.instances[x-1]
					
		    game.deck.split_counter += 1
		
		    return split_hands_dict
	
				
    class Hand():
	    instances = [] # used to keep track of hand instances
	    def __init__(self, hand_a, play_deck, split_count, name): # hand_a for hand actual
		    Hand.instances.append(self)
		    self.hand_a = hand_a  # the actual hand when instance created
		    # self.play_deck = play_deck  #  need to move this to deck class
		    self.split_count = split_count
		    self.name = name
		    self.hand_points = 0
		    self.raw_points = 0
		    self.aces = 0
		    self.testy = self
		    self.status = 'incomplete'
		    self.bet = 0
		    self.stack_change = 0
		    self.outcome = ''
		    self.black_jack = 0
	
	    def show_hand(self):
		    print "%r hand is:" % self.name
		    for i in range(len(self.hand_a.keys())):
			    print self.hand_a[i]
		    print "\n"
	
	    def show_card(self, key):
		    return self.hand_a[key]
	
	    def points(self):  
		    ln = len(self.hand_a.keys())
		    tpoints = 0
		
		    # add up all the cards with aces = 11
		    self.aces = 0
		    for i in range(ln):
			    card, rank = self.card_and_rank(self.hand_a[i])
			
			    # add up all the aces
			    if rank == 'Ace':
				    self.aces += 1
				
			    # deck is an object of game
			    tpoints = game.deck.values[rank] + tpoints
			    raw_points = tpoints
			
		    # check to see if there are aces in the hand.
		    if self.aces > 0:
			    for n in range(self.aces):
				    # check to see if the total points are more than 21.
				    if tpoints > 21:
					    # subtract 10 points for each ace.
					    tpoints = tpoints - 10	
						
		    return (tpoints, raw_points)
	
	    def card_and_rank(self, card):
		    z = card.split()
		    rank = z[0]
		    return (card, rank)
	
	    def split_test(self):
		    card_a, rank_a = self.card_and_rank(self.hand_a[0])
		    card_b, rank_b = self.card_and_rank(self.hand_a[1])
		    val_a = game.deck.values[rank_a]
		    val_b = game.deck.values[rank_b]
		    if self.bet * 2 > stack.stored_end:
			    print "You don't have enough cash to split."
			    time.sleep(2)
			    return 'no'
		    elif game.deck.split_counter == 1:
			    return 'no'
		    elif val_a == val_b:
			    return 'split'
		    else:
			    return 'no'
	
	    def hos(self):  
		    # hos = hit or stick
		    os.system("clear")		
		
		    self.hand_points, self.raw_points = self.points()
		
		    print "\n"
		    # show dealer's hand
		    print "Dealer's up card is:\n%r\n" % game.deck.d_hand.show_card(0)
		
		    # show starting hand
		    self.show_hand()
		
		    self.softness(self.hand_points, self.raw_points)				
			
		    print "\nYou're bet is $%d." % stack.stored_bet
		    print "Your stack is (less your current bet) $%d" % (stack.stored_end - stack.stored_bet)
		
		    x = self.black_jack_check()
		    if x == 'black_jack':
			    self.black_jack = 1
			    answer = 'stick'
			    self.check_hand(answer)
		
		
		    if self.split_test() == 'split':		
			    answers = ['hit', 'stick', 'double', 'split']
			    while True:
				    print "\nWould you like to 'hit', 'stick', 'double' down or 'split'?"
				    if self.hand_points == 21:
					    answer = 'stick'
					    print "You have 21!"
					    time.sleep(.5)
					    break
				    else:
					    answer = raw_input(' >')
					    if answer in answers:
						    print "end of hos func"
						    break
		    else:
			    answers = ['hit', 'stick', 'double']
			    while True:
				    print "\nWould you like to 'hit', 'stick' or 'double'?"
				    if self.hand_points == 21:
					    answer = 'stick'
					    print "You have 21!"
					time.sleep(.5)
					break
				else:
					answer = raw_input(' >')
					if answer in answers:
						print "end of hos func"
						break
			
		    self.check_hand(answer)
	
	    def check_hand(self, answer):
		    print "\nYou said %r." % answer
		
		    # hit
		    if answer == 'hit':
			    self.hit()
			    if self.hand_points > 21:
				    self.status = 'completed'
				    print "Your busted"
				    print "need to go to end game"
				    self.status = 'completed'
				    return 'done'
		
			    hl = len(self.hand_a.keys())
			    if hl == 5:
				    self.status = 'completed'
				    return 'done'	
						
			    self.hos()
		
		    # stick
		    elif answer == 'stick':
			    self.status = 'completed'
			    print "need to call dhos and end the game"
						
		    # double
		    elif answer == 'double':
			    t_bet = stack.stored_bet  # temp bet
			    t_end = stack.stored_end # temp stack balance (before bet)
			    t_bal = t_end - t_bet # what would the stack be if bet subtracted?
			    if t_bet > t_bal:
				    print "You don't have enough to doule down."
				    print "need to continue with hand - should check this when asking the question."
				    raw_input("Please hit enter to continue")
			    else:
				    print "\nYou doubled down."
				    stack.stored_bet = stack.stored_bet * 2
				    self.bet = self.bet * 2
				    print "Your bet is now $%d." % stack.stored_bet
				    self.hit()
				    self.show_hand()
				    self.status = 'completed'
				    time.sleep(3)
					
		    # split
		    elif answer == 'split':
			    if game.deck.split_counter == 0:
				    split_hands_dict = game.deck.split_algo(game.deck.start_hand)
				    ln = len(split_hands_dict)
				    for x in range(ln):
					    split_hands_dict[x].hos()
			    else:
				    print "Sorry, but no more splits."
				    time.sleep(2)
		
		    else:
			    print "something went horribly wrong."
			    exit(0)		
	
	    def softness(self, points, raw_points):
		    # returns soft hand if hand is soft
		
		    if self.aces > 0:
			    nap = raw_points - (self.aces * 11) # = non-ace - points
			    if nap + 11 < 21:
				    print "\n%s has a soft %d" % (self.name, points)
				    print " _ " * 10				
			    else:				
				    print "%s has %d points.  a" % (self.name, points)	
				    print " _ " * 10		
		    else:
			    print "%s has %d points." % (self.name, points)
			    print " _ " * 10
	
	    def black_jack_check(self):
		    # print " _ " * 10
		    # print "\n"
		    zz = {}
		
		    for i in range(len(self.hand_a.keys())):
			    card, rank = self.card_and_rank(self.hand_a[i])
			    # print "card is %r and rank is %r" % (card, rank)
			    zz[i] = rank
			    i += 1
			
		    if zz[0] == 'Ace' and zz[1] == "Jack":
			    # print "zz[0] is %r and zz[1] is %r a " % (zz[0], zz[1])
			    print "\nBlack Jack!  You Win!\n"
			    time.sleep(1.5)
			    return "black_jack"
		    elif zz[0] == 'Jack' and zz[1] == 'Ace':
			    # print "zz[0] is %r and zz[1] is %r b" % (zz[0], zz[1])
			    print "\nBlack Jack!  You Win!\n"
			    time.sleep(1.5)
			    return "black_jack"
		    else:
			    return 0
	
	    def hit(self):
		    print "hit method"
		    k = len(game.deck.full_deck.keys())
		    print k
		
		    new_card = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
		
		    # hl = len(game.deck.start_hand.hand_a.keys())  # hl is hand length
		    hl = len(self.hand_a.keys())  # hl is hand length
		    print hl
		
		    # add new card tto hand
		    self.hand_a[hl] = new_card  # insert new hard into hand of the given instance.
		
		    # add new opints to self.hand_points
		    self.hand_points, self.raw_points = self.points()
	
		
    class Game():
	
	    def __init__(self):
		    self.hand_dict = {} # this will be a dict of all the hand instances created by Hand.
		    self.incomplete_hands = [] # hands yet to be played
		    self.compltete_hands = {} # hands done being played
	
	    def collect_hands(self):
		    # loops trough Hand.instances and unpacks into indivudual hands
		    print "\nbegin collect_hands\n"
		    i = 0
		    for handy in Hand.instances:
			    self.hand_dict.setdefault(handy.name, handy.hand_a)
			    i += 1
		    print self.hand_dict
		
		    print "\n"
		
		    for player in self.hand_dict:
			    print player
			    n = 0
			    for n in range(len(self.hand_dict[player])):
				    print self.hand_dict[player][n]
				    n += 1
				
		    print "print card rows"
		    # list of rows
		    first_cards = []
		    second_cards = []		
		    third_cards = []
		    fourth_cards = []
		    fifth_cards = []
		    list_of_rows_raw = [first_cards, second_cards, third_cards, fourth_cards, fifth_cards]

		    for x in self.hand_dict:
			    first_cards.append(self.hand_dict[x][0])
		
		    for y in self.hand_dict:
			    second_cards.append(self.hand_dict[y][1])
		
		    table = texttable.Texttable()
		    header = self.hand_dict.keys()
		    table.header(header)
		    table.add_rows([first_cards, second_cards], header=False)
		    print table.draw()
	
	    def end_game(self):
		    # check to see how each completed hand did against the dealer
		    dpoints = self.deck.d_hand.hand_points
		
		    for hand in Hand.instances:
			    hand.stack_change = 0
			    if hand.status == 'completed':
				    # print "hand is %r" hand.name
				    print "hand points are %r" % hand.hand_points
				    print "dpoints are %r" % dpoints
				    print "bet is %r" % hand.bet
				
				    if hand.hand_points == 21:
					    if hand.black_jack == 1:
						    hand.stack_change = hand.stack_change + ((float(3)/2) * hand.bet)
						    hand.outcome = "Black Jack!!"
						
					    else:
						    hand.stack_change += hand.bet
						    hand.outcome = "Win"
				
				    elif hand.hand_points > 21:
					    hand.stack_change -= hand.bet
					    hand.outcome = "Lose"
				
				    elif dpoints > 21: 
					    hand.stack_change += hand.bet
					    hand.outcome = "Win"
					
				    elif hand.hand_points < dpoints:
					    hand.stack_change -= hand.bet
					    hand.outcome = "Lose"
									
				    elif hand.hand_points > dpoints:
					    hand.stack_change += hand.bet
					    hand.outcome = "Win"					
					
				    elif hand.hand_points == dpoints:
					    hand.stack_change + 0
					    hand.outcome = "Push"	
					
				    else:
					    print "not sure what to tell you"
					    exit(0)
		    self.check_score()
	
	    def check_score(self):
		    #check to see if player has money to play again
		    total_winnings = 0
		    for hand in Hand.instances:
			    total_winnings = total_winnings + hand.stack_change
		
		    if stack.stored_end + total_winnings < 0:
			    print "You're out of cash.  Goodbye!"
			    exit(0)
		    else:
			    stack.stored_end += total_winnings
			
		    self.replay(0, total_winnings)
	
	    def replay(self, miss_type, total_winnings):
		    # show table of hands
		    os.system("clear")
		    print "Your hands: \n"
		    hands_dict = {}
		    bets_dict = {}
		    outcomes_dict = {}
		    points_dict = {}
		    for hand in Hand.instances:
			    hands_dict.setdefault(hand.name, hand.hand_a)
			    bets_dict.setdefault(hand.name, hand.bet)
			    outcomes_dict.setdefault(hand.name, hand.outcome)
			    points_dict.setdefault(hand.name, hand.hand_points)
		
		    first_cards = []
		    second_cards = []
		    third_cards = []
		    fourth_cards = []
		    fifth_cards = []
		    bets_list = []
		    outcomes_list = []
		    points_list = []
		
		    for hand in hands_dict:
			    first_cards.append(hands_dict[hand].get(0))
			    second_cards.append(hands_dict[hand].get(1))
			    third_cards.append(hands_dict[hand].get(2))
			    fourth_cards.append(hands_dict[hand].get(3))
			    fifth_cards.append(hands_dict[hand].get(4))
			    bets_list.append("Bet is %r" % bets_dict[hand])
			    points_list.append("Points are %r" % points_dict[hand])
			    outcomes_list.append(outcomes_dict[hand])
		
		    header = hands_dict.keys()
		    table = texttable.Texttable()
		    table.header(header)
		    table.add_rows([first_cards, second_cards, third_cards, fourth_cards, fifth_cards, points_list, bets_list, outcomes_list], header = False)
		    print table.draw()
		
		    print "\n"
		    self.deck.d_hand.show_hand()
		    print "Dealer's points are %r." % self.deck.d_hand.hand_points
		
		    print "\nYou won $%r" % total_winnings
		    print "Your stack is now $%r\n" % stack.stored_end
		    if stack.stored_end <=0:
			    print "You're out of cash.  Better luck next time!"
			    exit(0)
			
		    while True:
			    print "\nWould you like to play again?"
			    a = raw_input(' >')
			    if a == 'no':
				    print "Thanks for playing."
				    print "You ended up with $%d\n" % stack.stored_end
				    exit(0)
			    elif a =='yes':
				    hil = len(Hand.instances) # hil = hand instances length
				    for x in range(hil):
					    del Hand.instances[x-1]
				    time.sleep(1)
				    game.play_game(1, total_winnings) 
				    break	
			    else:
				    print "just 'yes' or 'no' please."
				    time.sleep(1)
	
	    def load_inc_hands(self):
		    # load first opening hand into incomplete hadns dict.
		
		    # remove dealer hand 
		    lnth = len(Hand.instances)
		    for x in range(lnth):
			    if Hand.instances[x-1].name == 'Dealer':
				    del Hand.instances[x-1]
			
		    lnth = len(Hand.instances)
		    for z in range(lnth):
			    self.incomplete_hands.append(Hand.instances[z].name)
	
	    def play_game(self, replay, total_winnings):
    # start
		    self.deck = DECK()
		    if replay == 1:
			    self.stack = Stack(1 , total_winnings)
		
		    os.system("clear")
		    print "Let's play!\n"
		    print " _ " * 10
		
		    begin = stack.stored_end  # need this here for when game is replayed
		    begin, change, end = stack.account(0, begin) #laod account func with initical balance
		    print "You have $%d in your stack.\n" % end
		    print " _ " * 10
		    time.sleep(0.5)
		
		    play_deck = self.deck.full_deck
		
    # bet
		    stack.bet_test(0)
		    bet = stack.stored_bet

    # deal
		    self.deck.deal()
		
    # attach the bet to the starting hand
		    self.deck.start_hand.bet = bet
			
		    os.system("clear")
		    print "deck has %r cads" % len(play_deck.keys())
		    print "play_game method of Game class\n"		
		
		    # load incomeplete hands dict
		    self.load_inc_hands()
		
    # go thorugh each hand and hit or stick
		    for hand in Hand.instances:
			    if hand.status == 'incomplete':
				    print "you're stuck in the hos loop"
				    hand.hos()		
		
    # go to dealer's hand			
		    self.deck.dhos()
		    exit(0)
	

    if __name__ == '__main__':
	    game = Game()
	    stack = Stack(0, 0)
	    stack.load_account()
	    game.play_game(0, 0)

First, if there's a better way to get the code in here than copy and paste, please let me know.  Checking all the indents in python is a bit of a pain.

Second, please rip up this code!  I'm trying to learn Python on my own and need all the feedback I can get.  Please comment on everything: best practices, conventions...etc.  Any and all comments welcome.

Thanks.