<jupyter_start><jupyter_text>**I asked a question on [math.stackexchange.com](math.stackexchange.com), and recieved a great answer. This is my attempt to implement the insighful solution** ([link to question](http://math.stackexchange.com/questions/1350456/probability-a-blackjack-dealer-will-bust-if-you-know-their-score-and-know-the-ex))**After some thought and reading comments on math stackexchange, i decided to implement the recursive solution rather than the linear algebra one for now**<jupyter_code>from __future__ import division
from copy import deepcopy

def hit_hand(score, soft, value):
    '''given a hand and a card, returns the new hand
    
    arguments: 
    score: the current score of the hand (int)
    soft: whether or not the score is soft (boolean)
    value: the value of the card to add to the hand
    
    returns (score, soft): the score and whether or not the score is soft of the resulting hand
    '''
    if soft and score + value > 21:
        score = score - 10 + value
        soft = False
    elif value == 1 and score + 11 <= 21:
        score += 11
        soft = True
    else:
        score += value
    return (score, soft)


def p_bust(hand, shoe, p=0.0):
    '''given a hand and a shoe, returns the probability of busting
    assumes dealer stands on soft 17
    
    arguments:
    hand: tuple containing score and whether score is soft (tuple)
    shoe: the number of cards of each value left to draw (list)
    
    keyword_arguments:
    p: aggregator for probability of busting (default=0.0)
    
    returns p: probability of busting (float)
    '''
    score, soft = hand
    if score <= 16:
        for card in range(10):
            if shoe[card] > 0:
                score_after_hitting, soft = hit_hand(score, soft, card + 1)
                if score_after_hitting >= 22:
                    p += shoe[card]/sum(shoe)
                elif score_after_hitting <= 16:
                    new_shoe = deepcopy(shoe)
                    new_shoe[card] -= 1
                    p += shoe[card]/sum(shoe) * p_bust((score_after_hitting, soft), new_shoe)
    return p


def possible_hands(showing, shoe):
    ''' generates a list of all possible hands and the probability 
    of seeing that hand given a shoe and an upcard
    
    arguments:
    showing: the value of the card that is showing
    shoe: the number of cards of each value left to draw (list)
    
    returns [((score, scoft) p), ...]: list of the hands (tuple of the score and whether it is soft) and probability of hand
    '''
    hands = []
    for card in range(10):
        p_card = shoe[card] / sum(shoe)
        new_shoe = shoe_minus_card(shoe, card)
        if showing == 1:
            hands.append((hit_hand(11, True, card + 1), new_shoe, p_card))
        else:
            hands.append((hit_hand(showing, False, card + 1), new_shoe, p_card))
    return hands

def shoe_minus_card(shoe, card):
    new_shoe = deepcopy(shoe)
    new_shoe[card] -= 1
    return new_shoe

master_shoe = [4*6 for _ in range (9)] + [4*4*6]

for card in range(10):
    shoe = shoe_minus_card(master_shoe, card)
    print 'Probability of bust showing %d: %f' % (card + 1, sum([p_bust(hand, new_shoe)*p_card for hand, new_shoe, p_card in possible_hands(card + 1, shoe)]))<jupyter_output>Probability of bust showing 1: 0.185319
Probability of bust showing 2: 0.351725
Probability of bust showing 3: 0.375495
Probability of bust showing 4: 0.399843
Probability of bust showing 5: 0.426344
Probability of bust showing 6: 0.416197
Probability of bust showing 7: 0.257623
Probability of bust showing 8: 0.241649
Probability of bust showing 9: 0.229242
Probability of bust showing 10: 0.212471
{'fraction_non_alphanumeric': 0.08947939262472886, 'fraction_numerical': 0.03633405639913232, 'mean_word_length': 2.8030927835051545, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '644420', 'license': 'MIT', 'n_tokens_mistral': 1255, 'n_tokens_neox': 1136, 'n_words': 434, 'path': 'Calculating Probability of Dealer Busting.ipynb', 'repo_name': 'elsherbini/iPython-Notebooks', 'size': '3688'}