Schedule Python - Overlapping functions - python

I am trying to run 2 functions at different times, one after another.
The first function contains while loop in it (without break, since I want to keep it running until the next function comes)
However, when the next schedule comes, it doesn't run the second function and stuck in the 1st one.
I have tried to add sys.exit() but it doesn't even go into that function
import schedule
import sys
import time
def do_complete_automation():
while True:
print()
print("do_complete_automation()")
time.sleep(5)
def exit1():
print("exit")
sys.exit()
schedule.every().sunday.at('16:42').do(do_complete_automation)
schedule.every().sunday.at('16:42:30').do(exit1)
schedule.every().sunday.at('16:42:35').do(do_complete_automation)
while True:
schedule.run_pending()
time.sleep(1)
It should print "exit"

Related

How to pause only one part of the script in Python

I have some issues with time.sleep() management in Python. I would like to use some values in a second part of the script, but they have to be delayed 300 ms one from another and I want to delay only that part of the script and not all the rest. These values are the X coordinates of an object detected by a camera. The script is something like this:
while True:
if condition is True:
print(xvalues)
time.sleep(0.3)
if another_condition is True:
#do other stuff and:
np.savetxt('Xvalues.txt', xvalues)
In the second part of the script (#do other stuff), I will write G-code lines with the X-coordinate detected and send them to a CNC machine. If I write a time.sleep() in that position of the script, everything in the while loop will be delayed.
How can I extract some values sampled 300ms a time without influencing the rest of the script?
from threading import Thread
class sleeper(Thread):
if condition is True:
print(xvalues)
time.sleep(0.3)
class worker(Thread):
if another_condition is True:
#do other stuff and:
np.savetxt('Xvalues.txt', xvalues)
def run():
sleeper().start()
worker().start()
You can include the 300ms checking as part of handling condition.
The first time you detect condition, get and remember the current time in a variable.
The next time condition is true again, check that it's more than 300ms from the last time the condition was true.
Something like this:
last_condition_time=None
while True:
if condition is True:
if not last_condition_time or more_than_300ms_ago(last_condition_time):
print(xvalues)
last_condition_time = get_current_time()
if another_condition is True:
#do other stuff and:
np.savetxt('Xvalues.txt', xvalues)

I am trying to execute my code at a certain time every day and its not working

Am I doing something completely wrong. I've been trying to fix this for so long. it prints once and then keeps running but doesn't print anything else.
import schedule
import time
def bot():
schedule.every(1).day.at("6:41").do(bot)
print("ya")
while True:
schedule.run_pending()
time.sleep(1)
Check out the documentation here for a good example of how this should work
Simple answer is your bot() is trying to recursively execute itself, but the only thing that happens when it runs itself is that it tells itself to run itself again in one day at 6:41...meanwhile no print() statement is executed because it doesn't exist inside the bot() function.
Your code executes the print() statement once because it runs it immediately after defines bot().
You never call bot() in this code, so that function never actually does anything.
Easy solution is to put your desired functionality in your bot() function and then add it to the schedule like so:
import schedule
import time
def bot():
print("ya")
schedule.every(1).day.at("6:41").do(bot)
while True:
schedule.run_pending()
time.sleep(1)

Python Stopping a program at any point in an if command

I currently have a program that I am working on that requires the user to input some parameters, and then press a button to start the main part of the program.
After the start button is pressed, the if loop executes a sequential order of commands (around 20) and then stops.
I want to be able to stop this sequence of commands at any time during the code using a separate 'stop' button, but I am not sure how. I am more interested in a method of doing this than GUI syntax.
Any help is appreciated.
Example code:
if (start_button_is_pressed):
#do thing a
#do thing b
#do thing c
...
#do thing z
# i want to be able to stop from any point a-z
You can use a loop and break execution at any point. If you want only a single pass through the steps, add a final break at the end.
jump_out = False
while not jump_out:
step_1()
if (jump_out):
break
step_2()
if (jump_out):
break
# and so on
step_n()
break # add unconditional break for single-pass execution
you can use a break statement inside the loop. Set an event such that when the stop button is pressed, it triggers a certain value and this value alters the loop. Sample process below
stop = False
if stop_button_is_pressed:
stop = True
for a in b:
if stop == True:
break
print(a)
print("Stopped")
You could use multiprocessing.Process to terminate() the process/function my_process_function() whenever you please... Run it as script to get outputs.
import multiprocessing
def my_process_function():
for i in range (100):
print(i)
time.sleep(1)
print("my_process end")
if __name__ == "__main__":
x = multiprocessing.Process(target=my_process_function())
x.start()
print("Stop thread?")
a=input()
if (a=="y"):
x.terminate()

Python: display dynamic information on user input

I would like to be able to receive command line input from user in a python script, and at the same time display to the user some dynamic information.
The user should be able to enter text, but this should not block the displaying of information.
My goal is to create a game, where I show users a countdown while they still have time to enter an answer.
Is this achievable?
Yeah. To create a countdown in the console, you could do something like this:
from time import sleep
for num in reversed(range(0,11)):
print(num)
sleep(1.0)
or
from time import sleep
time = 10
while time != 0:
print(time)
time = time - 1
sleep(1.0)
Either will countdown from 10 to 0 with a second in between each number. Since you might want the user to be able to enter answers as quickly or slowly as like before reaching 0... you might want to look into running two loops concurrently. this thread might be helpful for that. You'll want to figure out how to break out of both loops if the user gets the right answer (and have something come up that says they got the right answer) or if the user runs out of time.
Well sounded like an interesting thing to look into so I did, ran into a few problems pretty soon.
First, I was able to make a running counter but the problem is, since it is a loop, the next layer the counter loop will reset everything you've answered on the previous layer unless you've pressed enter to input answer(answer + enter , during that 1 second period).
if you are making reflex based thing that you only need to press single keys you might be able to succeed with my code by using module getch.
There were few modules that I could use for making the timer and program run at the same time, threading and multiprocessing(better results with threading).
It's basically a working thing if you just remove the counter function which adds the loop, but you won't see the timer.
Pygame might be a good thing to do this with, haven't used it myself but I'd presume so.
here is my code
import time
import threading
import os
timel = 5
def question():
q = input("",)
print(q)
if q == "2":
print("\nCorrect")
else:
exit("\nFalse, You lose!!")
def counter():
timel = 5
for i in range(0, timel):
print("How much is 1+1?", timel)
timel -= 1
time.sleep(1)
os.system("cls")
def timer(seconds):
time.sleep(seconds)
exit("\nTIMES UP, You lose!!")
def exit(msg):
print(msg)
os._exit(1)
def main():
thread = threading.Thread(target=timer, args=(int("{}".format(timel)),))
thread2 = threading.Thread(target=counter)
thread.start()
thread2.start()
question()
if __name__ == "__main__":
main()

Ask input once then wait for response

I'm a total newbie and I have question about asking about input while the loop is working.
Lets pretend that i have simple loop.
x = 1
y = 1
while x == 1:
y += 1
print(y)
And now i want user input to stop this script but only if he types cancel and the loop is supposed to run while python is waiting for input.
As I mentioned in the comments you can achieve "running the loop while waiting for input" using threads from the threading module.
The idea is to have two threads that will run in parallel (ie at the same time) and each of them will do its own thing. The first one will do only one thing : wait for input. The second one will do the work that you would have put in the loop, and only check at the start of each loop if it should stop or not according to the information it gets from the first thread.
The following code illustrate this (note this requires python3):
from threading import Thread
import time
class Input_thread(Thread):
def __init__(self):
Thread.__init__(self)
self.keep_working = True
def run(self):
while True:
a = input("Type *cancel* and press Enter at anytime to cancel \n")
print("You typed "+a)
if a == "cancel":
self.keep_working = False
return
else:
pass
class Work_thread(Thread):
def __init__(self, other_thread):
Thread.__init__(self)
self.other_thread = other_thread
def run(self):
while True:
if self.other_thread.keep_working is True:
print("I'm working")
time.sleep(2)
else :
print("I'm done")
return
# Creating threads
input_thread = Input_thread()
work_thread = Work_thread(input_thread)
# Lanching threads
input_thread.start()
work_thread.start()
# Waiting for threads to end
input_thread.join()
work_thread.join()
As you can see using threading isn't trivial and requires some knowledge about classes.
A way of achieving something similar in a slightly simpler way would be to use the python's exception called KeyboardInterrupt. If you are not familiar with exceptions : there are python's way of handling errors in your code, that means if at some point in your code Python finds a line it can't run, it will raise an exception, and if nothing was planned to deal with that error (aka if you don't catch the exception with the try/except syntax), python stops running and display that exception and the traceback in the terminal window.
Now the thing is when you press Ctrl-c (same as the copy shortcut) in the terminal window while your program runs, it will automaticaly raise an exception called KeyboardInterupt in your program, and you can catch it to use it as way to send cancel to your program.
See that code for an example of how to do that :
import time
y=1
try:
while True:
y+=1
print(y)
time.sleep(1)
except KeyboardInterrupt:
print("User pressed Ctrl-c, I will now exit gracefully")
print("Done")

Categories

Resources