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. ;-)
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).
I'm a beginner at Python and coding in general, and I've been primarily using the trinket interpreter to work out some of my scripts. I was just trying to get used to defining a function with if and elif lines alongside the return command.
The code I'm trying to run is a pretty simple one, but when I run it regularly nothing shows up. However, when I run it through the console it
comes out fine. What am I doing wrong?
def the_line(text):
if text == ("just a boy"):
phrase = ("I fly alone")
elif text == "syndrome":
phrase = ("darn you syndrome")
return phrase
the_line("just a boy")
The first picture is what happens when I run it regularly and the second is through the console.
In the console, when you run a statement but don't assign it to anything, the shell will print the resulting object. You call the function but don't save it in a variable, so it is displayed. The "console" in your IDE is also called a Read, Evaluate and Print Loop (REPL).
But your code really just discarded that return value. That's what you see in the first case, the returned object wasn't assigned to anything and the object was deleted. You could assign it to a variable and print, if you want to see it.
def the_line(text):
if text == ("just a boy"):
phrase = ("I fly alone")
elif text == "syndrome":
phrase = ("darn you syndrome")
return phrase
foo = the_line("just a boy")
print(foo)
(As a side note, 4 spaces for indents please. We are not running out of spaces).
This is very clearly explained in Think Python's section 2.4. It has everything to do with the Read-Eval-Print-Loop (REPL) concept.
Briefly, the console is a REPL, so you see the output because it Prints what it Evaluated after Reading something (and then it prompts again for you to input something, that's the loop part). When you run the way you call "regularly", you are in what is called "script mode" (as in Think Python). Script mode simply Reads and Evaluates, there is not the Print-Loop part. A REPL is also called "interactive mode".
One could say that a REPL is very useful for prototyping and testing things out, but script mode is more useful for automation.
What you need to see the output would be like
print(the_line("just a boy"))
for line number 9.
I am writing a game, similar to mastermind, and I want a choice bewteen an easy or hard version. I'm not sure how to do this as I need the question before the actual game starts but then there's an error because the function is being called to run before it has been assigned.
def difficulty():
difficulty = input("would you like to the easy or hard version?")
if difficulty == ("easy"):
easy()
elif difficulty == ("hard"):
hard()
difficulty()
This is the start then after is the function with the harder game code then the easier game code. I am trying to run the easy if they request easy and vice versa but the easy () and hard() don't run the code as it isn't assigned yet. I think this is because python reads the code from top to bottom and stops when it finds an error but not sure.
I have never used this before so I apologise if things are unclear or I have done some things wrong.
I am also relatively new to python.
If anybody could help me I would greatly apprectiate it.
Python is quite smart when it comes to identifying functions inside a module. For instance you could do this:
def x():
y()
def y():
print("Y")
x()
and it would execute correctly.
You are right about the execution of a code block that happens from top to bottom, as well as the definitions of those functions will also be constructed top to button, but executed afterwards.
I see some issues in your code.
you do difficulty = input("would you like to the easy or hard version?") but at the same time you have a function called def difficulty. There is a conflict there, try to rename that variable.
you don't need to do ("easy"), it's overkill, you can compare directly to "easy".
I'm struggling to troubleshoot a strange problem I've been having since starting to use Sikuli over multiple projects. I've been using the IDE and later tried to branch out due to having strange things happening with code. If I were to debug code earlier with popups, I can save the code, even restart my pc, even check the code in other text editors but the now non-existent popups (and old code) sometimes, well, pop up. In the end normally I end up ditching original files, and having to sometimes strangely comment out lines and re-add them one at a time (even though in the grand scale of things the end script was the same as before i did all that). I'm at a real loss for words.
It's making me struggle to differentiate between bad code and something going wrong elsewhere. Does anyone know what might cause this "phantom code"? Because I'm really at a loss.
And i would like advice as to what's going wrong with the while i < (inputvariable). I can't figure out what might be going wrong at all, am i over looking something?
I'm running all scripts through Sikuli IDE at the moment. I did want to learn how to write scripts and include sikuli hoping i could package it neatly but i couldn't seem to wrap my head around it.
For the while loop, where it's being compared to "SSLoops" i can't see why it's not breaking out of the loop when the criteria is met. (prints out above and beyond the number.)
I've had to do strange workarounds such as commenting out whole sections of code, trying to get it to work, and then slowly one by one reintroduce it till it matched the old script entirely. If I copied the script to a new file to make a cleaner copy, in hopes that if there is some sort of caching issue(?) it'd resolve, but I'd normally have to tinker around with it again.
BP = getBundlePath()
print(BP)
setBundlePath(BP + "\images")
BP2 = getBundlePath()
print(BP2)
# Regions
gameRegion = Region(230, 138, 1442, 875)
matchSpeedRegion = Region(1282, 920, 162, 91)
rewardRegion = Region()
def main():
SSLoops = input("How many times would you like to run Super Smash?")
SuperSmash(SSLoops)
def SuperSmash(SSLoops):
print(SSLoops)
i = 1
while i < SSLoops:
print(i)
print(SSLoops)
if exists("btnEnterSuperSmash.PNG"):
click("btnEnterSuperSmash.PNG")
while True:
if exists("btnReward.png"):
print("Completed! On to Rewards.")
#selectRewards()
break
else:
pass
if matchSpeedRegion.exists("btnStart.png"):
matchSpeedRegion.click("btnStart.png")
matchSpeedRegion.wait("btnRetreat.png", 3600)
if matchSpeedRegion.exists("btnSpeedUp.png"):
matchSpeedRegion.click("btnSpeedUp.png")
print("clicked x1")
print("clicking retreat")
matchSpeedRegion.click("btnRetreat.png")
matchSpeedRegion.wait(Pattern("btnRetreat.png").similar(0.65), 3600)
print("clicking okay")
gameRegion.click("btnOK.png")
wait(2)
gameRegion.wait("btnOK.png", 3600)
gameRegion.click("btnOK.png")
print("Completed!")
i = i + 1
if __name__ == '__main__':
main()
I have been getting popups saying "hey" because i had a loop in while true btnRewards to run a function to say "hey" - this would have hopefully on on to pick a reward out of 5 images in the end. But after removing it, as i'm trying to trouble shoot the main loop, it still pops up.
The loop that compares the user input variable to i just keeps on increasing. The indentation looks okay to me? but i must be wrong? or is something else making it go wrong?
I've been making the program run on a folder so the pictures to break the loop are immediately up, so it should have theoretically ran the amount of times inputted without anything else (1). Any help is deeply appreciated.
====
1
1
1
[log] CLICK on L[889,656]#S(0) (568 msec)
Completed! On to Rewards.
Completed!
2
1
[log] CLICK on L[889,656]#S(0) (565 msec)
Completed! On to Rewards.
Completed!
3
1
[log] CLICK on L[889,656]#S(0) (584 msec)
Completed! On to Rewards.
Completed!
4
1
====
Your problem: input() returns a string like so "4"
you then compare it using
while i < SSLoops:
which is always True and hence the loop does not end.
using
SSLoops = int(input("How many times would you like to run Super Smash?")) will solve your problem.
Be aware: this will crash if the given input cannot be converted to an integer value.
Suggestion: debug prints should look like so:
print "SSLoops =", SSLoops
so the output is better readable.
RaiMan from SikuliX (greetings to your cat ;-)
def you ():
gi=input("what up")
if gi in ["Nothing much", "nothing much", "nothing"]:
print("cool")
you()
elif gi in ["stuff"]:
print("sounds good")
I apparently cannot do this, however In a bigger program I am working on, I have a function that is used twice, however based of the user input, different results happen, so I tried to include my large function, and like the above program have an if else be continued throughout the function, because there are different options for user input, based on where the person is in the program.
I am just trying to figure out a good way to run a game, where the beginning is the same (function), however the game can progress in different ways, therefore a function won't work for all of it, so I just want to know if I can have an if else statement run through a function like in the small example above?
As James already said, no you cannot continue an if statement outside of a function. Referring to your question if functions are useful in a larger program: yes they are. You can use data generated in functions in your main program or other functions by returning your results. For instance:
def you ():
gi=input("what up")
return gi
result = you()
if result in ["Nothing much", "nothing much", "nothing"]:
print("cool")
elif result in ["stuff"]:
print("sounds good")