pythonbooleankaggledigital-logic

Understanding the functioning of 'and' and 'or'


Here's a doubt I am facing here.

The code with its purpose in docstring is below :

This is the correct code but I am confused about the final 'if statement' in the blackjack_hand_greater_than(a,b) function.

Here, the 'if statement' is not True for total_1 > total_2 even if it is(* checked through print statements). I am not getting what is the need of adding 'or total_2 > 21' .

def blackjack_hand_greater_than(hand_1, hand_2):
    """
    Return True if hand_1 beats hand_2, and False otherwise.
    
    In order for hand_1 to beat hand_2 the following must be true:
    - The total of hand_1 must not exceed 21
    - The total of hand_1 must exceed the total of hand_2 OR hand_2's total must exceed 21
    
    Hands are represented as a list of cards. Each card is represented by a string.
    
    When adding up a hand's total, cards with numbers count for that many points. Face
    cards ('J', 'Q', and 'K') are worth 10 points. 'A' can count for 1 or 11.
    
    When determining a hand's total, you should try to count aces in the way that 
    maximizes the hand's total without going over 21. e.g. the total of ['A', 'A', '9'] is 21,
    the total of ['A', 'A', '9', '3'] is 14.
    
    Examples:
    >>> blackjack_hand_greater_than(['K'], ['3', '4'])
    True
    >>> blackjack_hand_greater_than(['K'], ['10'])
    False
    >>> blackjack_hand_greater_than(['K', 'K', '2'], ['3'])
    False
    """
    print("hand1 = ",hand_1)
    print("hand2 = ",hand_2)
    total_1 = get_total(hand_1)
    total_2 = get_total(hand_2)
    print(total_1 <= 21)
    print(total_1 > total_2)
    if (total_1 <= 21) and (total_1>total_2 or total_2 > 21):
        return True
    else :
        return False

def get_total(hands) :
    values = {'A': 1 ,'2': 2, '3' : 3, '4' : 4 ,'5' : 5, '6' : 6,'7': 7, '8' : 8, '9' : 9, '10' : 10 , 'J' :10 , 'Q':10, 'K':10}
    total = 0
    aces = 0
    
    for x in hands:
        if x == 'A' :
            aces += 1
        total += values[x]
#         print(total)
        
    while aces>0 and total + 10 <= 21 :
        total += 10
        aces -=1
    
    print(total)
    return total
# Check your answer
q3.check()

The error after removing the 2nd operand of 'or', the error received is as follows :

hand1 = ['J', 'A'] hand2 = ['6'] 21 6 True True

hand1 = ['9'] hand2 = ['9', 'Q', '8', 'A'] 9 28 True False

Incorrect: Expected return value of True given hand_1=['9'], hand_2=['9', 'Q', '8', 'A'], but got False instead.


Solution

  • Im shared how can I solved it

    1-I split the numbers and letters 2-I sorted the letter in order letter A is the last one

    def sum_hand(hand):
    #hand.sort(reverse=True)
    
    letter=[]
    number=[]
    for n in hand:
        if n.isnumeric():
            number.append(n)
        else:
            letter.append(n)
          
    
    #print('letter--',letter)
    #print('number--',number)
    
    letter.sort(reverse=True)
    number.sort(reverse=True)
    number.extend(letter)
    
    hand = number
    #hand = sorted(number) + sorted(letter,reverse:True)
    print(hand)
          
    
    #print(hand)
    result_hand=0
    
    for card in hand:
        if (card == 'J' or card == 'Q' or card == 'K'):
            result_hand += 10
        elif (card.isdigit()):
            result_hand += int(card)
        else:
            if(result_hand <= 10):
                result_hand += 10
            else:
                result_hand += 1
                
    return result_hand
    
    
    def blackjack_hand_greater_than(hand_1, hand_2):
    
    
    result_hand1 = sum_hand(hand_1)
    result_hand2 = sum_hand(hand_2)
    
    print('hand1-', result_hand1 , ' hand2', result_hand2)
    
    if result_hand1 > 21:
        return False
    
    if result_hand2 > 21:
        return True
            
    
    if (result_hand1 > result_hand2 ):
        return True
    else:
        return False