Problem with restarting function over again - python

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()

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:
With breakpoints enabled, you use the Bug icon instead of the Play icon.
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:
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:
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:
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.
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:
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.
Hitting "Step over" one more time will bring you back to where the method was before, your code has left the recursion:
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).

Related

I just started programming and am having problem with both of these while loops

I've just starting a programming course and im making an adventure game.
I've gotten up to this "path" where the user must choose between the market or the blacksmith.
If they choose either they have two choices and if they dont say either choice I want to re-ask and go through the loop again. currently if I type everything in first try it works but if I fail to provide a valid answer it prompts to re-enter then doesn't go through the loop again.
How do I write this to take my:
else:
print ("Choice must be (Sword / Platemail)...")
answer = input ("").lower().strip()
and
else:
print ("Choice must be (Bread / Cabbage)...")
answer = input("").lower().strip()
return to the top of the loop with the "answer" in order to have the if and elif statments do what they need to do?
Any help recommendations would be amazing please keep in mind im brand new to programming.
Picture of code in question
The pattern is like this:
while True:
answer = input("Choice?").lower().strip()
if answer in ('sword','platemail'):
break
print("Choice must be Sword or Platemail")
For cleaner code, you might want to put this into a function, where you pass the possible answers and return the validated one.

What command do I do to make someone loop back to a specific place in my code? [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 1 year ago.
I am making a text based game. I am moving along, but I am stumped on how to make specific choices bring you back to where you need to make the choice. Currently, the current plan I am doing is to make the right answers bring you to the rest of the game, while the incorrect questions bring you nowhere, and you have to restart the program entirely, but it isn't very fun to have to slog through the parts I have already done every single time I get a wrong choice.
ruintalk = input ()
if ruintalk == '1':
print ('"Rude!" the old man shouts, "I knew you were just like the rest of them." The old man storms out as fast as his frail legs can take him. You never hear from him again and later die of lumbago and are buried in a paupers grave. Dont insult the old man or ask stupid questions. Hes kind of a dick so just roll with it and restart the game.')
What command should I put to bring me back to input()?
Loops are what can you help you with that. "while" loops particularly in this case. "while" loops keep iterating through a block of code till the condition is true.
Here is an example demonstrating their use -
while True:
ruintalk = input()
if ruintalk == correct_answer:
break # This will break the iteration
This block of code will keep iterating until break statement is called. Alternatively, what you can do is have a variable set as True and set it to false once the correct answer is entered. Here is an example showing this -
run = True
while run:
ruintalk = input()
if ruintalk == correct_answer:
run = False
If I understand what you're trying to build, you might want to make your input a function to be called. You can then build loops for different scenarios and your input will happen in a statement:
def userInput():
r = input()
r = r.lower() #I like doing this to simplify how I handle user input in the code
return(r)
while sceneComplete is False:
print("Something to setup the scene. What do you want to do, user??? (X/Y/Z)?")
action = userInput()
if action == "x":
do the x thing
elif action == "y":
do the y thing
elif action == "z":
sceneComplete = True
else:
print("You broke the rules and an ogre kills you ....")

I'm trying to find happy numbers but my program goes into an endless loop

I've done everything in my ability to try to do this without any functions and only while loops (as said by my teacher) please could you find out why, I even tried dry running but it should still work
p.s it doesn't work in either ways of using:
while c!=0 and f<50: or while c!0 or f<50:
happy_num=1
x= [0]*30
f=0
#f is a safety measure so that the program has a stop and doesnt go out of control
happynumbers=" "
number=int(input("input number "))
while happy_num!=31:
c=0
happy=number
while c!=1 or f<50:
integer=number
f=f+1
if integer<10:
a=number
b=0
d=0
elif integer<100:
a=number // 10
b=number % 10
d=0
else:
a=number // 10
bee=number % 100
b=bee // 10
d=number % 10
number=(a*a)+(b*b)+(d*d)
c=number
x[happy_num-1]=happy
if c==1:
happy_num+=1
elif f>49:
print("too many iterations program shutting down")
exit()
number=happy+1
print ("the happy numbers are: ", happynumbers)
Firstly, you say:
It doesn't work in either ways of using: while c!=1 and f<50: or while c!=1 or f<50
You should use the one with and (while c!=1 and f<50:), because otherwise it is useless as a failsafe. Right now your program gets stuck anyways so it might seem to you to not make a difference, I understand that. It's important in general that a failsafe is added with and, and not with or (because true or true == true and true or false == true, so when your loop is infinite, the f<50 failsafe will not make any difference to the truth value of the guard).
Adding print statements to your program, you can see that at around f=30 the program starts to become very slow, but this is not because of some infinite loop or anything; it's because the computations start to become very big at the line:
number=(a*a)+(b*b)+(d*d)
So f never actually reaches 50, because the program gets stuck trying to perform enormous multiplications. So much for your failsafe :/
I am not sure what algorithm you are using to find these happy numbers, but my guess it that there is something lacking in your guard of the inner loop, or some break statement missing. Do you account for the situation that the number isn't a happy number? Somehow you should also exit the loop in that situation. If you have some more background to what the program is supposed to do, that would be very helpful.
Edit: judging from the programming example on the Wikipedia page of happy numbers, you need some way to keep track of which numbers you've already 'visited' during your computations; that is the only way to know that some number is not a happy number.
plus the question i was given was to find the first 30 happy numbers, so the input would 1

Passing variables between functions in Python, then back to menu

Slowly progressing with my learning with Python and would love a little hand with some code I've tried to create.
I previously had this program running with Global Variables to get a proof of concept to learn about passing variables between functions. Fully worked fine. However, rather than running the function and returning to the menu, it will just stop where I return the value and not progress back to the main menu I created. It is at the point of "return AirportDetailsGlobal".
I'm sure its a simple one, and as said - still learning!
Really appreciate any help on this!
Full code is on pastebin for further reference - pastebin 89VqfwFV
print("\nEnter airport code for overseas")
osCode = input()
airports = airData
for line in airports:
if osCode in line:
print (osCode, "Found\n\n")
print("Airport Name:",line[1])
OverseaCodeGlobal = osCode
x = int(line[2])
AirDataGlobal = x #changed here
return AirportDetailsGlobal
break
else:
print('Incorrect Choice')
menu()
menu()
If you do a return then your code goes back to where it was called from. If it wasn't called from anywhere (ie. you just ran that script directly) then calling return is in most ways equivalent to calling sys.exit(), ie. the program terminates. It'll never hit your break, leave the loop, or hit your call to menu().
Also, your indentation as given there isn't right, the else is at the same level as the for, not the if. I don't think that's the problem but you might hit it next. ;-)

Need help to understand a peice of while loop code?

I am learning Python online on YouTube. And I have came across a piece of code that is confusing me. I would really appreciate if someone could help me out. Here is the code:
command = ""
started = False
while True:
command = input("> ").lower()
if command == "start":
if started:
print("car already started")
else:
started = True
print("car started")
What I didn't understand is how does Python execute double ifs? And how does it know it is already executed once and if typed start again it would give me another message. Any help would highly appreciated.
The ifs are nested. The second if and else are only checked if the first condition is true. This is apparent, since they are indented after the first if.
The first if checks if the command is to start. If it is, then it checks if the car has already been started. If it has, there is no need to start it again. If not, then it starts the car.
Here's an attempt to "transcribe" the code in English:
car has not started, no command received yet
start an infinite loop (meaning that the steps below will repeat forever, until you terminate/exit the program)
take a command from the user, turn it into lowercase, and store it
check the command entered by the user. If the command is "start", then check whether the car has started, and start it if it hasn't been already, then go back to step 3. If the user input is not "start", then don't check anything and return directly to step 3.

Categories