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.
Related
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).
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. ;-)
So, instead of Python basically following the cascading script as it usually does is it possible where it will never end unless you type "end" and you can ask it any question over & over again?
I'm basically creating a bot where you basically activate it by typing 'Cofo, activate' and it will reply 'Cofo activated, how may I help you today?' and from there you can ask it things like 'What's the weather today' and 'what's 9 + 4' etc, etc. A little like Jarvis but without actual speech, more text based.
Sorry I haven't given a very good explanation, I can't really explain what I want but hopefully you understand.
the way to do this with a while loop:
while True:
user_data = raw_input('What do you want? ')
if user_data == 'quit': break
else:
print 'I can\'t do "{}" yet.'.format(user_data)
All this script does is echo back your input, so ignore the details - the main thing is that the loop runs until the user enters 'quit' (or whatever word you want to specify).
As noted by #cricket_007, you need a while loop. Check the tutorial for a simple introduction and the docs for a formal syntax definition.
Asking indefinitely for user input is a common pattern, be sure to check out this canonical question about a related issue: asking for user input until a valid response is provided.
I would like to use win32 in python to create 2 functions... 1. A function that checks if a certain application is running. 2. A function that checks if an application is installed...
I have tried the following to check if something is running;
def IsRunning(ProgramName):
if win32ui.FindWindow(None, ProgramName):
print("its running")
return True
else:
print("its not running!")
but the findwindow always throws an error if the program is not running before my program ever gets to the else statement and I do not know how to bypass that....
I needed to pass it like this;
def IsRunning(WindowName):
try:
if win32ui.FindWindow(None, WindowName):
print("its running")
return True
except win32ui.error:
print("its not running!")
return False
You need to put the window title exactly for it to pass the test and return True...
The next thing I want to write is a similar function that uses regular expressions to find any part of a title name...
Brilliant!!! Happy now :)
The only thing with this, is that if the Applications creator decides to change the title of the main window of the program you are trying to test for, it will no longer work... I was hoping for a much more robust way of doing it... i.e. through some kind of unique process code!
in any case this will do for the time being, but if anyone has a more definitive answer please let me know...
I'm experimenting/having a little fun with wave robot python apiv2.
I made a little 8ball app for the robot which works fine, and now I'm trying to make a trivia app.
I've never programmed in Python but I'm pretty sure my syntax is correct. Here is the relevant code:
elif (bliptxt == "\n!strivia"):
reply = blip.reply()
if (triviaStatus != "playing"):
reply.append("Trivia Started!")
triviaStatus = "playing"
else:
reply.append("Trivia is already running!")
elif (bliptxt == "\n!etrivia"):
reply = blip.reply()
if (triviaStatus == "playing"):
reply.append("Trivia Ended!")
triviaStatus = "stopped"
else:
reply.append("Trivia is not running! To start trivia, type !strivia")
else: (snipped out)
Okay so basically I want it to work so that when someone blips "strivia" the bot recognizes that someone wants to play so it first checks a variable called triviaStatus to see if we are already playing and goes from there. Pretty simple stuff.
In order for this to work (and, actually, this code is really meant to test this question out) the variables would need to effectively be like the php $_SESSION variables - that is, it remembers the value of the variable every time someone blips and does not reset each time.
Nevertheless, whether or not that is the case (if it isn't then I assume I can do the same thing by saving variable settings in a txt file or something) I am baffled because the code above does not work at all. That is to say, the robot is not replying on !strivia or on !etrivia. If the variables didn't save then if anything the robot should just reply with "Trivia Started" or with "Trivia is not running!" each time. But it just does not reply at all.
If I remove the check for triviaStatus, the robot DOES reply. But then there's no logic and I can't test my question out.
I also tried making a !trivstatus where it would reply back with
"Trivia status is " + triviaStatus
but that ALSO choked up. Why is it that every time I want to USE triviaStatus, the bot just dies? Note that I am able to SET triviaStatus fine (I just can't ever check what the output is by replying with it....)
So, to sum this up...how come the above code does not work but the following code DOES work:
elif (bliptxt == "\n!strivia"):
reply = blip.reply()
reply.append("Trivia Started!")
trivia_status = "playing"
elif (bliptxt == "\n!etrivia"):
reply = blip.reply()
reply.append("Trivia Ended!")
trivia_status = "stopped"
Thanks!
It seems that you should rename triviaStatus to trivia_status and make sure that trivia_status has some value e.g., bind it to None before the first use. Otherwise your code might raise UnboundLocalError or NameError exceptions due to triviaStatus/trivia_status doesn't refer to any object.