0

Learning some Python, I'm doing the exercises on Kaggle.

Basically my problem reduce to a > comparator between two int doesn't work as I want.

The problem is to write a function that compares two BlackJack hands (string lists)

I first wrote a function that gives me a hand's value

def hand_val(hand):
        
    ace_count=0
        
    for i in range(len(hand)) :
        val_hand=hand
        if ((hand[i] == 'J') | (hand[i] == 'Q') | (hand[i] == 'K')):
            val_hand[i]=10
        elif (hand[i] == 'A'):
            val_hand[i]=11
            ace_count+=1
        else :
            val_hand[i]=int(hand[i])
        
    value=0
    
    for i in val_hand :
        value = value + i
    for i in range(ace_count) :
        if value>21 :
            value=value-10
            
    return value

Then another one that compares two different hands

def blackjack_hand_greater_than(hand_1, hand_2):
    if (hand_val(hand_1)>21):
        return False
    elif (hand_val(hand_2)>21):
        return True
    elif (hand_val(hand_1)>hand_val(hand_2)):
        return True
    else:
        return False

( I know that I should do this as return ((hand_val(hand_1)<22) and ((hand_val(hand_1)>hand_val(hand_2))or(hand_val(hand_2)>21))), but with separate conditions is way more readable)

With these two specific hands the second function doesn't work as intended. I think I've managed to trace the problem back to the first elif Here's the debugging code I wrote

hand_1=['3', '2', '6', '8']
hand_2=['8', 'A', '5']
print(hand_val(hand_1))
print(hand_val(hand_2))
print(type(hand_val(hand_1)))
print(type(hand_val(hand_2)))
print(hand_val(hand_1)>21)
print(hand_val(hand_2)>21)   ############# WHY??? OH WHY??
print(14>21)
print(hand_val(hand_1)>hand_val(hand_2))

here's the output

19
14
<class 'int'>
<class 'int'>
False
True
False
False

See that print(hand_val(hand_2)>21) returns True while print(14>21) returns False as it should?

Can someone help?

Red
  • 26,798
  • 7
  • 36
  • 58
  • `val_hand=hand` isn't a copy. Your `hand_val` mutates its input, so the result when you call it a second time isn't `14` the second time. – user2357112 Jul 14 '20 at 19:05
  • See https://stackoverflow.com/questions/2612802/list-changes-unexpectedly-after-assignment-how-do-i-clone-or-copy-it-to-prevent – user2357112 Jul 14 '20 at 19:06
  • Just a suggestion: Use `or` instead of `|`: `if (hand[i] == 'J') or (hand[i] == 'Q') or (hand[i] == 'K'):` You can even use this: `if hand[i] in ['J', 'Q', 'K']:` – Alperen Jul 14 '20 at 19:07

1 Answers1

0

The correct way to write:

def blackjack_hand_greater_than(hand_1, hand_2):
    return and_val(hand_1) < 22 and (hand_val(hand_1) > hand_val(hand_2) or hand_val(hand_2) > 21)

into multiple lines is:

def blackjack_hand_greater_than(hand_1, hand_2):
    if and_val(hand_1) < 22:
        if hand_val(hand_1) > hand_val(hand_2):
            return True
        elif hand_val(hand_2) > 21:
            return True
        else:
            return False
    else:
        return False
Red
  • 26,798
  • 7
  • 36
  • 58