-1

I'm doing online python course and they asked to code Blackjack game. I have a problem with function that check score on dealers hand. I checked it with "Thonny" step by step and seems to be working until if >= 17 is true. "Thonny" shows me returned value from if statement and... here magic happens. It jumps straight to else block and prints("why is this showing up?") as many times as function was appending "cards". Then both prints at the very bottom gives: <class 'NoneType'> and: None as returned value. If I remove comment from return in else block, then again it iterates backwards as many times as function was appending "cards" and returns initial value of dealer_hand list, 2 in this case. (print statements are for feedback only)

import random

cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
dealer_hand = []

def value_check(hand):
  card_sum = sum(hand)
  return card_sum

def card_draw():
  card = random.choice(cards)
  return card

def dealer_val_check(hand):
    value = value_check(hand)

    if value >= 17:
        return value
    else:
        hand.append(card_draw())
        print(hand)
        dealer_val_check(hand)
       # return value
        print("why is this showing up?")
         

dealer_hand = [1, 1]
dealer_value = dealer_val_check(dealer_hand)
print(type(dealer_value))
print(dealer_value)
WojtekR
  • 1
  • 1
  • 2
    Could you clarify what the issue is? If I un-comment `return value`, the `print()` statement below it never executes. – BrokenBenchmark Dec 31 '21 at 02:45
  • @BrokenBenchmark The `print` doesn't matter. If you uncomment `return value` the function will return value of initial list before it was appended. In this case value = 2 since list `dealer_hand = [1, 1]`. But line abve it is recursive call of function itself, why it even goes to `return value` or `print()`?. Why `if value >= 17` does not brake this function? :( – WojtekR Dec 31 '21 at 02:56
  • 1
    The underlying misunderstanding here -- thinking that `return`ing inside a recursive function will end _all_ the calls in the stack rather than only the innermost one -- is very common, and has lots of duplicates already in our knowledge base. Those duplicates talk about the function returning `None`, but if you actually read the body of them, the confusion is that the outer call doesn't return the thing the innermost `return` returned -- the same issue you have here. – Charles Duffy Dec 31 '21 at 03:13
  • ...so, just as the linked questions' answers describe, you need an extra `return` as in `return dealer_val_check(hand)` to take the thing the inner call returns, and return that thing yourself. – Charles Duffy Dec 31 '21 at 03:15
  • Oookay. That makes sense now. You are right. I was thinking that return will end all the calls... It explains a lot. I is my beginning with coding so there is so much to learn and understand. Thank you for explanation. Cheers. – WojtekR Dec 31 '21 at 09:35

2 Answers2

0

Because you call dealer_val_check() inside of itself. Until, you finally get a value >= 17. At that point, you return True and return back to the point you called dealer_val_check().

Explanation with an example:

Let's say you start with a hand of 16 (from the very start).

You will call dealer_val_check(). The value will not be >= 17, so it will do the else.

In the else, you will draw another card and call dealer_val_check() again. (Reference Point A)

This time, we will definitely have more than 17, so this time we will return "value".

We now return back to the point where we called this method ("reference point A") and print "why is this showing up?".

Conclusion

As you may see, if it takes multiple card draws, you will print "why is this showing up" multiple times.

Try it out yourself! Make the draw always be 1, it will take 15 cards, so 15 times will it say "why is this showing up?"

So to answer "Why return doesn't stop the function?"

You do stop the function! But not the function that called that function!

This is referred to as recursion, and can be a bit tricky to understand right away. One way to think about it, is that you jump into another instance of the function that you are currently in, and that one may jump into another instance and so on... It continues until at some point one instance returns. At this point, we go backwards to the previous instance, which will go backwards to the previous instance and so on until you eventually exit the function completely.

Regarding the None

You must return some value, currently you have commented out return value. If you don't, you simply return None. So, add it back and it will no longer return None.

Chrimle
  • 490
  • 1
  • 4
  • 10
  • In [How to Answer](https://stackoverflow.com/help/how-to-answer), note the section _Answer Well-Asked Questions_, and therein the bullet point regarding questions that "have been asked and answered many times before". We probably get a new iteration on this question at least once a day. – Charles Duffy Dec 31 '21 at 03:18
  • I mean... If **anything** their question lacks focus, as this is pretty much "debug my program" and there are multiple issues with it that warrants being mentioned and answered. Personally, I feel that the answer falls short if I removed any of it. – Chrimle Dec 31 '21 at 03:26
0

There is no "magic", all calls to dealer_val_check terminate. The value that is printed at the end corresponds to the very first call, with the initial (original) hand, [1,1].

If you want to follow what is happening with the recursive function call stack, change the dealer_val_check function to the following:

def dealer_val_check(hand):
    value = value_check(hand)

    if value >= 17:
        print("It was >=17, so returned: ", value)
        return value
    else:
        hand.append(card_draw())
        print(hand)
        dealer_val_check(hand)
        print("It was < 17, so returned: ", value)
        return value

My example run:

[1, 2, 2]
[1, 2, 2, 8]
[1, 2, 2, 8, 8]
It was >=17, so returned:  21
It was < 17, so returned:  13
It was < 17, so returned:  5
It was < 17, so returned:  3
<class 'int'>
3
Ataxias
  • 1,085
  • 13
  • 23