# CodeAbbey - Blackjack Counting

Here is my solution for CodeAbbey - Blackjack Counting

My code passes all tests on Code Abbey but I think I have some poor implementation specifically with my handling of the Aces in the score but otherwise I think I overall used good practices and design.

def calculate_player_hand(player_hand_input):
"""Return the score of a player hand"""
# Variable to hold score for a hand
total_player_hand_score = 0

# Dictionary mapping cards to their score value
card_values = {"2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "T": 10, "J": 10, "K": 10, "Q": 10}

# Find score of cards except Aces
for card in player_hand_input:
if card == "A":
continue
else:
total_player_hand_score += card_values[card]

# Return player_hand_score not including Ace card(s)

# Return the total amount of Aces in a player's hand
def get_aces_count(player_hand_input):
"""Return the count of Aces"""
return player_hand_input.count("A")

test_cases = int(input())

# List to hold all total scores
total_scores = []

# Iterate through test cases
for i in range(test_cases):

player_hand = input().split()

# Variable to hold number of Aces in player hand
player_score_without_aces = calculate_player_hand(player_hand)

for j in range(get_aces_count(player_hand)):
if 21 - player_score_without_aces < 11:
player_score_without_aces += 1
else:
player_score_without_aces += 11

# Rename variable since value of Aces were added
total_player_score = player_score_without_aces

# Add total score to total_scores list
if total_player_score > 21:
total_scores.append("Bust")
else:
total_scores.append(total_player_score)

# Output all total scores
for total_score in total_scores:
print(total_score, end=" ")


Thank you.

• What's the score of ace + ace + ten? – Johnbot Feb 28 at 12:24

As was mentioned - always do separation of implementation and test cases.

For a better/optimized functionality consider the following actions:

calculate_player_hand function

• card_values = {"2": 2, "3": 3, ...} is better defined as top-level constant called CARDS:

# Dictionary mapping cards to their score value
CARDS = {"2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "T": 10, "J": 10, "K": 10, "Q": 10}

• instead of going through redundant variable total_player_hand_score and for loop + continue flow - the entire function can be replaced with concise sum + generator expression approach:

def calculate_player_hand(player_hand_input):
"""Return the score of a player hand except Ace card(s)"""
# Variable to hold score for a hand
return sum(CARDS.get(card) for card in player_hand_input if card != 'A')


Iterating through test cases

• the condition if 21 - player_score_without_aces < 11: can be replaced with a shorter equivalent if score_without_aces >= 11: (player_score_without_aces renamed to score_without_aces):

    for j in range(get_aces_count(player_hand)):
score_without_aces += 1 if score_without_aces >= 11 else 11

• no need to rename the variable total_player_score = score_without_aces as score_without_aces will contain the last resulting value from the upper for loop:

total_scores.append("Bust" if score_without_aces > 21 else score_without_aces)

• The optimizations you added are much more desirable. Will try to emulate that in the future. Thanks – King Cold Feb 28 at 12:51
• Adding a comment for the constant CARDS is an indication that your variable name can be improved. Even something simple like CARD_SCORE would make the code more readable. – rootlocus Feb 28 at 17:47

You do not provide a testable function that performs the task of returning the desired answer for a specific test case. It is the ace handling that you intermangled with your test code. The main structure of your program structure should look somewhat like

def calculate_player_hand(player_hand_input):
#[...]
return score