1

I started to learn coding with python couple days ago. I dont have any previous coding experience so im a total beginner. Im watching youtube tutorials and every time i learn something new, i try to play with those learnt things. Now i tried to make kind of a guess game and im having a problem with it. (jokingly first question is asking "are you idiot" lol).

I tried to make it so that you have 3 lives per question (there will be multiple questions which are just copies of this code with different questions and answers) Once you run out of lives, it asks if you want to start over and if answered yes, it starts from the question number 1. The problem is if you answer "yes", it starts over but it does not give the lives back and even if you answer correctly, it says game over. However if you answer correctly the first time without restarting, it works just fine and continues to the next question.

What am i missing here? Thanks for the answers!

def question1():
    secret_word = "yes"
    guess = ""
    guess_count = 0
    guess_limit = 3
    out_of_guesses = False
    game_over_question = ""
    while guess != secret_word and not out_of_guesses:
        if guess_count < guess_limit:
            guess = input("Are you idiot?: ").lower()
            if guess == secret_word:
                print("correct! Next question:")
            else:
                guess_count += 1
                if guess_count <= 2:
                    print("Try again")

        else:
            out_of_guesses = True
            if out_of_guesses:
                while game_over_question not in ("yes", "no"):
                    answer = input("Game over, want to start over?: ")
                    if answer == "yes":
                        question1()
                    elif answer == "no":
                        exit()
                    else:
                        print("Its yes or no.")


question1()
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Loss1
  • 35
  • 3
  • 1
    Generally, probably avoid recursion inside a function. If the function runs for a long time, the code will run out of memory even though it is working completely correctly because it needs to remember what to return from the function which called itself which called itself which called itself which ... – tripleee Dec 02 '21 at 14:05
  • In pseudo code, while the user has not asked the program to stop, while you have lives left, ask a question, then when you run out of lives, ask whether to stop. – tripleee Dec 02 '21 at 14:07
  • I don't see question2 in this code. Why not make question1 return True for a succesful guess and False for out of goes, then put the logic outside, and have a new function for question2? – doctorlove Dec 02 '21 at 14:08
  • @tripleee: I disagree with the duplicate. The problem is not with asking until they give a valid response. The problem is in making a recursive call and understanding call stacks. It's a matter of debugging skills (using a debugger) and recognizing that the code flow continues after the recursive call later – Thomas Weller Dec 02 '21 at 14:10
  • 1
    @ThomasWeller Reopened; thanks for the feedback. Still probably a duplicate of other questions and/or too broad, but if you have the time to dissect it, feel free. – tripleee Dec 02 '21 at 14:13
  • Sorry Loss1, I think it's a good question at this stage in your Python learning career. NOW is the right time to learn about a debugger. Use an IDE that has a built-in debugger (like PyCharm). Set a red breakpoint on the left of the line of code. Don't use the Play icon but use the Bug icon to start the application. Knowing how to use a debugger will make you a 10x better programmer than you are now – Thomas Weller Dec 02 '21 at 14:14
  • @tripleee: the problem with generic debugging duplicates is that people will hardly be able to apply the strategy to their own code, because it's too many things at once. I posted an answer now. Let me know if you think it was worth reopening for this answer or not. Thanks. – Thomas Weller Dec 02 '21 at 14:55
  • There is an opposite problem with questions which are too specific; the effort you put into the answer is unlikely to help future visitors if it covers too many unrelated problems, especially when many of them have been covered many times before. That's why we ask visitors to reduce their debugging questions to a [mre], – tripleee Dec 02 '21 at 15:13
  • First of all, thanks a lot for the answers! I'm still learning basic things so even some of your answers make me scratch my head haha. I finally managed to fix the problem and it was bit stupid... the "game_over_question" variable was pointless in the code and i replaced it with "answer" in lines 7 and 21 and now the code works like it should. Special thanks to @ThomasWeller for such a precise guide of using the debugger, i have'nt even heard of that earlier and i can see why it's such a useful tool! – Loss1 Dec 03 '21 at 16:02

1 Answers1

0

To understand this, you best use a debugger. To use a debugger, you need an IDE that has one, e.g. PyCharm. The screenshots in this question are from PyCharm. Other IDEs (like Visual Studio Code) will differ in usability but the concept will be the same.

Some background on using a debugger

When debugging, you set breakpoints, typically by clicking on the left of the line of code, e.g. like so:

Breakpoint definition

With breakpoints enabled, you use the Bug icon instead of the Play icon.

Bug and play icons

The flow of execution will stop whenever the code hits a line with a breakpoint. You can then choose how to go on using these icons:

Debug icons

  • Step over this line of code
  • Step into this line (if there's a method call)
  • Step into (my code)
  • Step out (run the function until the end)
  • Run to cursor

Debugging your code

In your case, let's set a breakpoint on line 24. In this case I chose it, because it's the beginning of a recursion. However, I doubt that you have heard that term before. Without knowing it, it'll be hard to find a good line. Finding a good line for a breakpoint is a skill that develops over time.

Next, enter whatever is needed to reproduce the problem. On my machine, it looks like this:

Input until breakpoint is hit

Now, the breakpoint is hit and interesting stuff will happen.

Before that interesing stuff happens, let's look at the state of your program. As we have the call stack frames and variables:

Call stack and variables

One important thing to notice: your code is currently running line 31 (the actual method call) and while running that line, it is now running line 24.

Debugging the recursion

Now click the "Step into" button once. Note how the call stack changed and all variables seem to be lost.

Three stack frames now

We see that the same method ("question1") is called again. That's what programmers call a recursion.

Also: the variables are not lost, they are just "local" to that method. If you select the method from before, the variables will still be there:

Local variables

Now, click "Step over" a few times, until you're asked for input again.

Enter "yes" as you did before.

Then, click "Step over" once. You are inside if guess == secret_word: at the print statement now.

Then, click "Step over" once. The text was printed and you are at the while loop.

In the next step, the condition guess != secret_word will no longer be met and the code will continue after the while loop, which is where the method ends.

Call stack before exiting the recursion

Hitting "Step over" one more time will bring you back to where the method was before, your code has left the recursion:

Recursion left

Your code is back in line 24, within the while loop that asks you if you want to start over again.

Now that you understand what your code does, it should be possible to find a fix.

Takeaways

Typically it's not the computer who doesn't understand your code. It's you who doesn't understand your code :-)

A debugger will help you understanding what you told the computer. If there is a method on the call stack, then you called that method. Cool thing: you can look at each method and their variables and that'll allow you to make conclusions on how it arrived there.

Even cooler: you could change the values of these variables in order to play a "what-if" scenario.

IMHO, real debugging is more powerful than printf debugging (but still, a log file is an important concept of its own).

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222