So, Im coding a game, (just a simple text-based game, no fancy graphics or anything), but since im not good at coding professionally, I have everything done using functions, so that everything can call one another. this means that all functions and threads are always essentially 'loaded', I don't know the proper term.
essentially I want
def function():
print("Hello")
function()
to function as
def function():
print("Hello")
while True:
function()
but in my case, I can't do this, because I have many different functions being called from within each other in seemingly random patterns based on user input, and im worried at some point I'll hit a recursion wall, or stack overflow, or whatever it may be called.
AKA I can't use a loop because the order of the functions within the loop will vary from game to game
im pretty sure the only reason the stack overflow or whatever happens in the first scenario, is because the interpreter is yet to read any code after the function calls itself, as in if I had
def function():
print("Hello")
function()
print("goodbye")
the interpreter has yet to come back and print goodbye, therefore it gets stuck in memory
Call a function while ending the current function, and never return to read anything after
similar to I guess a "Break"
call a function and end the current function at the same time to save memory
As for me better to create some functions, and then create main function where that all will run:
def function1():
pass
def function2():
pass
def main():
print("function1")
function1()
print("function2")
function2()
if __name__ == "__main__":
main()
Related
I'm making a Discord bot with a lot of commands that take a while to finish (like loops) so I'd like to also have a command that stops any actively running code. I've tried sys.exit but I don't want to have to restart the program each time before it will take another input. Anyone know what I can do?
It will depend on the way your code is formatted, but you will probably want to use functions that utilize boolean or return statements:
def foo():
if end_this:
return
# stuff
If you have some tracking boolean end_this that is set to True, the function foo() will not execute everything below. Alternatively, you could use a while-loop with a break in your code:
def foo():
while True: # runs forever unless ended
# stuff
break
Now, foo() will continue indefinitely until the break statement is reached. An if-statement can enclose the break, setting some logic on when the break occurs. Again, this may require a main() function to handle the calls and ends of your previous functions, but it would allow following code/functions to execute.
I'm pretty new to Python, and coding in general, and currently working with Python 3.5. I wanted to learn to automate things that need text boxes filled to run. I experimented with the code below in a video game just as a way to learn.
I would like it to substitute different item numbers that are in a list into the consolecommand text.
Thank you for your time.
The code:
from pynput.keyboard import Key, Controller
import time
from keyboard import press
keyboard = Controller()
def submit():
press('enter')
def Keyboardpress1():
keyboard.press('/')
keyboard.release('/')
def waitone():
time.sleep(1)
def consolecommand():
keyboard.type("giveitem 172 49000")
def deepsix():
time.sleep(6)
def main():
deepsix()
submit()
waitone()
Keyboardpress1()
waitone()
consolecommand()
waitone()
submit()
deepsix()
if __name__ == '__main__':
main()
As you can see, the code is designed to hit a number to activate the command console in game, then type a command. The pauses between typing/keyboard are because the code doesn't run smoothly without them.
Thanks, appreciate any help.
Edit: I implemented fixes I learned from suggested resource materials. Now my problems are much fewer. Thank you, people of the comments section.
Edit1: I implemented new code to fix a previous problem. Now to get the consolecommand to change numbers.
#Connor Winterton, here's a very simplistic example of using a parameter to save repeating yourself. Consider func1() that performs a simple calculation and prints a hard-coded message. Consider func2() that is nearly the same except the message is different. By passing a parameter into func3() you can write just one function that will perform the task of both to reduce your code and clutter, and give you the ability to pass in any other messages you may want in the future:
def func1():
a = 1+2
print(a,'hello')
def func2():
a = 1+2
print(a,'goodbye')
def func3(my_msg):
a = 1+2
print(a,my_msg)
# call the hardcoded functions
func1()
func2()
# call the new versatile function
func3('hello')
func3('goodbye')
func3('See you later!')
Is it possible to return from a function and continue executing code from just under the function. I know that may sound vague but here is an example:
def sayhi():
print("hi")
continue_function() #makes this function continue below in stead of return
#the code continues here with execution and will print hey
print("hey")
sayhi()
when executing this the code should do this:
it prints "hey"
it calls the sayhi() function
it prints "hi"
it calls a function to make it continue after the function (in theory similar behavour could be achieve by using decorators)
it prints "hey" again
it calls sayhi() again
etc
i am fully aware of the fact that similar behaviour can be achieved by just using for loops but for the project i am working on this functionality is required and not achievable by using looping.
some solutions i have thought of (but i have no clue how i could execute them) are:
somehow clearing the stack python uses to return from one function to another
changing return values
changing python itself (just to make clear: it would solve the problem but it is something i do not want to do beacuse the project must be usable on non-altered versions of python
using some c extension to change python's behaviour from within python itself
Repetition without loops can be done with recursion:
def sayhi():
print("hey")
print("hi")
sayhi()
sayhi()
I assume you have some terminating condition to insert. If not, this code will give a RecursionError.
I am trying to quit a python program by calling sys.exit() but it does not seem to be working.
The program structure is something like:
def func2():
*does some scraping operations using scrapy*
def func1():
Request(urls, callbakc=func2)
So, here, func1 is requesting a list of URLs and the callback method, func2 is being called. I want to quit the execution of the program if something goes wrong in func2
On checking the type of the object in func1 I found its and http.Request object.
Also, since I am using scrapy, whenever I call sys.exit() in func2, the next url in the list is called and the program execution continues.
I have also tried to use a global variable to stop the execution but to no avail.
Where am I going wrong?
According to the How can I instruct a spider to stop itself?, you need to raise CloseSpider exception:
raise CloseSpider('Done web-scraping for now')
Also see:
Running Scrapy tasks in Python
sys.exit() would not work here since Scrapy is based on twisted.
Even if we don't know how to completely stop, Python's mutable-object default binding "gotcha" can help us skip all callbacks from a certain point on.
Here is what you can do:
First, create a function generating wrapping other callback functions with condition. It's second argument cont is going to be bound to a mutable object (list) so we can affect all callbacks after creating them.
def callback_gen(f, cont=[True]):
def c(response):
if cont[0]:
f(response, cont=cont)
else:
print "skipping" # possibly replace with pass
return c
Now make some testing functions:
def func2(response, cont=None):
print response
print cont
# this should prevent any following callback from running
cont[0]=False
def func3(response, cont=None):
print response
print cont
And now create two callbacks the first one is func2 which prevents the following ones from running.
f2 = callback_gen(func2)
f3 = callback_gen(func3)
f2("func2")
f3("func3")
I like it :)
I have got stuck with a problem.
It goes like this,
A function returns a single result normally. What I want is it to return continuous streams of result for a certain time frame(optional).
Is it feasible for a function to repeatedly return results for a single function call?
While browsing through the net I did come across gevent and threading. Will it work if so any heads up how to solve it?
I just need to call the function carry out the work and return results immediately after every task is completed.
Why you need this is not specified in the question, so it is hard to know what you need, but I will give you a general idea, and code too.
You could return in that way: return var1, var2, var3 (but that's not what you need I think)
You have multiple options: either blocking or non-blocking. Blocking means your code will no longer execute while you are calling the function. Non-blocking means that it will run in parallel. You should also know that you will definitely need to modify the code calling that function.
That's if you want it in a thread (non-blocking):
def your_function(callback):
# This is a function defined inside of it, just for convenience, it can be any function.
def what_it_is_doing(callback):
import time
total = 0
while True:
time.sleep(1)
total += 1
# Here it is a callback function, but if you are using a
# GUI application (not only) for example (wx, Qt, GTK, ...) they usually have
# events/signals, you should be using this system.
callback(time_spent=total)
import thread
thread.start_new_thread(what_it_is_doing, tuple(callback))
# The way you would use it:
def what_I_want_to_do_with_each_bit_of_result(time_spent):
print "Time is:", time_spent
your_function(what_I_want_to_do_with_each_bit_of_result)
# Continue your code normally
The other option (blocking) involves a special kind of functions generators which are technically treated as iterators. So you define it as a function and acts as an iterator. That's an example, using the same dummy function than the other one:
def my_generator():
import time
total = 0
while True:
time.sleep(1)
total += 1
yield total
# And here's how you use it:
# You need it to be in a loop !!
for time_spent in my_generator():
print "Time spent is:", time_spent
# Or, you could use it that way, and call .next() manually:
my_gen = my_generator()
# When you need something from it:
time_spent = my_gen.next()
Note that in the second example, the code would make no sense because it is not really called at 1 second intervals, because there's the other code running each time it yields something or .next is called, and that may take time. But I hope you got the point.
Again, it depends on what you are doing, if the app you are using has an "event" framework or similar you would need to use that, if you need it blocking/non-blocking, if time is important, how your calling code should manipulate the result...
Your gevent and threading are on the right track, because a function does what it is programmed to do, either accepting 1 var at a time or taking a set and returning either a set or a var. The function has to be called to return either result, and the continuous stream of processing is probably taking place already or else you are asking about a loop over a kernel pointer or something similar, which you are not, so ...
So, your calling code which encapsulates your function is important, the function, any function, eg, even a true/false boolean function only executes until it is done with its vars, so there muse be a calling function which listens indefinitely in your case. If it doesn't exist you should write one ;)
Calling code which encapsulates is certainly very important.
Folks aren't going to have enough info to help much, except in the super generic sense that we can tell you that you are or should be within in some framework's event loop, or other code's loop of some form already- and that is what you want to be listening to/ preparing data for.
I like "functional programming's," "map function," for this sort of thing. I think. I can't comment at my rep level or I would restrict my speculation to that. :)
To get a better answer from another person post some example code and reveal your API if possible.