how to sleep just one function of the code in python? - python

i am writing a code in python and i just want one function to sleep not the whole code in time.sleep(). but i couldn't find a way.
my code:
from time import sleep
a = int()
def calc(a,b):
while True:
a=a*b
if a >> 12:
sleep(12)
#i just want this func to sleep here.
def print(msg):
while True:
msg = a
print(msg)
#i don't want this func to sleep
what should i do?

Use asyncio
import asyncio
async def calc(a,b):
while True:
a=a*b
if a >> 12:
await asyncio.sleep(12)

I think You need to read a little about the function time.sleep. Here's what the documentation says about it:
Suspend execution of the calling thread for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.
The function pauses the program at the desired place, if you call it. It does not stop the other function.

code inside f1() function will be executed 2 seconds after running the code, but in that time f2() function will be executed.
from time import time, sleep
def f1():
print("Function1")
def f2():
print("Function2")
t1 = time() # Stores current system time in seconds
print(t1)
time_to_delay_f1 = 2
while True:
if time()-t1 > time_to_delay_f1: # time()-t1 is the time passed after assigning t1 = time(), [see before 2 lines]
f1()
else:
f2()

Related

Execute a method only when two seconds have elapsed from last execution time

I have a while loop which executes two methods. I want the functionB() to execute only EVERY 2 seconds.
I know there are solutions which can use the thread to use a timer to execute it every two seconds, but that is something that I DO NOT want to use. I want both methods to run on the MAIN thread.
def functionA():
# Code goes here
def functionB():
# Code goes here
while True:
# Execute function A
functionA()
# Periodically execute functionB every 2 seconds
functionB()
I am not sure on how to calculate the difference between the last time it executed and the current time. I search online for a few examples but they seem to confuse me more.
Any help would be appreciated.
get the timestamp in seconds and check if 2 or more seconds have passed since the last execution.
import time
def functionA():
# Code goes here
def functionB():
# Code goes here
lastExec = 0
while True:
# Execute function A
functionA()
now = time.time()
if now - lastExec >= 2:
# Periodically execute functionB every 2 seconds
functionB()
lastExec = now

I have some code and I would like some troubleshooting on it

My timer won't work properly, since it keeps printing forever, not what I want.
I've already tried re-organizing the script in many ways, but the result is always the same.
import time
CommandInput = input()
#execution [uptime]
def uptime(y):
while 1 == 1:
if (CommandInput == "uptime"):
print(y, " seconds")
y = y + 1
time.sleep(1)
uptime(9)
I wanted to make some sort of "background timer" that kept running from when the script was executed up to when it was closed, and if I typed a certain line in the input it would show the current number it is in. The problem is that it keeps printing the timer forever, for every single number it counts. I wanted to do a one-time thing, where you could wait as much as you want and type the input, which would show the number the timer is in.
Your current program has to wait for input() to finish. The compiler does not move past the second line until the user hits enter. Thus the functions starts once the input is finished.
This timer could be done several way, such as threading or timers. There are some examples of that here and here. For threading, you need one process for user inputs and one for timers. But the better and easier way is to to use a timer and store the current time. I believe the following code is somewhat similar to what you want:
import time
start_time = time.time()
def get_time():
current_time = time.time()
total = current_time - start_time
return total
while True:
CommandInput = input()
if CommandInput == "uptime":
y = get_time()
print(str(round(y)) + " seconds")
The variable start_time records the current time at the start. time.time() gets the current time in seconds on the computer. The get_time function is called after an input and sees how much time has pasted by subtracting the current time minus the start time. This way the you do not need multiple loops.
The while True loops just waits for the user input and then prints the time. This then repeats until the program is exited.
To write a script like that you would need to look into a module called asyncio (https://docs.python.org/3/library/asyncio.html), which would allow you to run multiple things at the same time.
Here is a asyncio hello world:
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
# Python 3.7+
asyncio.run(main())

Sleeping for the remaining time

I'm trying to run a method every minute.
The method does some operations on the internet so it might take anywhere from 1 second to 30 seconds.
What I want to do is calculate the time spent by this method and then sleep for the remaining time, to make sure that the method itself runs every minute.
Currently my code looks like this:
def do_operation():
access_db()
sleep(60)
As you can see this does not take into account the delay whatsoever, and although it works, it will at some point fail and skip a minute completely, which should never happen.
import time
def do_operation():
start = time.time()
access_db()
time.sleep(60-time.time()+start)
This code will allow you to run a callable in defined intervals:
import time
import random
def recurring(interval, callable):
i = 0
start = time.time()
while True:
i += 1
callable()
remaining_delay = max(start + (i * interval) - time.time(), 0)
time.sleep(remaining_delay)
def tick_delay():
print('tick start')
time.sleep(random.randrange(1, 4))
print('tick end')
recurring(5, tick_delay)
Notes
The function tick_delay sleeps for some seconds to simulate a function which can take an undefined amount of time.
If the callable takes longer than the defined loop interval, the next iteration will be scheduled immediately after the last ended. To have the callable run in parallel you need to use threading or asyncio

timer interrupt thread python

I've been trying to make a precise timer in python, or as precise a OS allows it to be. But It seems to be more complicated than I initially thought.
This is how I would like it to work:
from time import sleep
from threading import Timer
def do_this():
print ("hello, world")
t = Timer(4, do_this)
t.start()
sleep(20)
t.cancel()
Where during 20 seconds I would execute 'do_this' every fourth second. However 'do_this' executes once then the script terminates after 20 seconds.
Another way would be to create a thread with a while loop.
import time
import threading
import datetime
shutdown_event = threading.Event()
def dowork():
while not shutdown_event.is_set():
print(datetime.datetime.now())
time.sleep(1.0)
def main():
t = threading.Thread(target=dowork, args=(), name='worker')
t.start()
print("Instance started")
try:
while t.isAlive():
t.join(timeout=1.0)
except (KeyboardInterrupt, SystemExit):
shutdown_event.set()
pass
if __name__ == '__main__':
main()
This thread executes as expected but I get a timing drift. In this case have to compensate for the time it takes to execute the code in the while loop by adjusting the sleep accordingly.
Is there a simple way in python to execute a timer every second (or any interval) without introducing a drift compared to the system time without having to compensate the sleep(n) parameter?
Thanks for helping,
/Anders
If dowork() always runs in less time than your intervals, you can spawn a new thread every 4 seconds in a loop:
def dowork():
wlen = random.random()
sleep(wlen) # Emulate doing some work
print 'work done in %0.2f seconds' % wlen
def main():
while 1:
t = threading.Thread(target=dowork)
time.sleep(4)
If dowork() could potentially run for more than 4 seconds, then in your main loop you want to make sure the previous job is finished before spawning a new one.
However, time.sleep() can itself drift because no guarantees are made on how long the thread will actually be suspended. The correct way of doing it would be to figure out how long the job took and sleep for the remaining of the interval. I think this is how UI and game rendering engines work, where they have to display fixed number of frames per second at fixed times and rendering each frame could take different length of time to complete.

How do I make a time delay? [duplicate]

This question already has answers here:
How do I get my program to sleep for 50 milliseconds?
(6 answers)
Closed 3 years ago.
How do I put a time delay in a Python script?
This delays for 2.5 seconds:
import time
time.sleep(2.5)
Here is another example where something is run approximately once a minute:
import time
while True:
print("This prints once a minute.")
time.sleep(60) # Delay for 1 minute (60 seconds).
Use sleep() from the time module. It can take a float argument for sub-second resolution.
from time import sleep
sleep(0.1) # Time in seconds
How can I make a time delay in Python?
In a single thread I suggest the sleep function:
>>> from time import sleep
>>> sleep(4)
This function actually suspends the processing of the thread in which it is called by the operating system, allowing other threads and processes to execute while it sleeps.
Use it for that purpose, or simply to delay a function from executing. For example:
>>> def party_time():
... print('hooray!')
...
>>> sleep(3); party_time()
hooray!
"hooray!" is printed 3 seconds after I hit Enter.
Example using sleep with multiple threads and processes
Again, sleep suspends your thread - it uses next to zero processing power.
To demonstrate, create a script like this (I first attempted this in an interactive Python 3.5 shell, but sub-processes can't find the party_later function for some reason):
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed
from time import sleep, time
def party_later(kind='', n=''):
sleep(3)
return kind + n + ' party time!: ' + __name__
def main():
with ProcessPoolExecutor() as proc_executor:
with ThreadPoolExecutor() as thread_executor:
start_time = time()
proc_future1 = proc_executor.submit(party_later, kind='proc', n='1')
proc_future2 = proc_executor.submit(party_later, kind='proc', n='2')
thread_future1 = thread_executor.submit(party_later, kind='thread', n='1')
thread_future2 = thread_executor.submit(party_later, kind='thread', n='2')
for f in as_completed([
proc_future1, proc_future2, thread_future1, thread_future2,]):
print(f.result())
end_time = time()
print('total time to execute four 3-sec functions:', end_time - start_time)
if __name__ == '__main__':
main()
Example output from this script:
thread1 party time!: __main__
thread2 party time!: __main__
proc1 party time!: __mp_main__
proc2 party time!: __mp_main__
total time to execute four 3-sec functions: 3.4519670009613037
Multithreading
You can trigger a function to be called at a later time in a separate thread with the Timer threading object:
>>> from threading import Timer
>>> t = Timer(3, party_time, args=None, kwargs=None)
>>> t.start()
>>>
>>> hooray!
>>>
The blank line illustrates that the function printed to my standard output, and I had to hit Enter to ensure I was on a prompt.
The upside of this method is that while the Timer thread was waiting, I was able to do other things, in this case, hitting Enter one time - before the function executed (see the first empty prompt).
There isn't a respective object in the multiprocessing library. You can create one, but it probably doesn't exist for a reason. A sub-thread makes a lot more sense for a simple timer than a whole new subprocess.
Delays can be also implemented by using the following methods.
The first method:
import time
time.sleep(5) # Delay for 5 seconds.
The second method to delay would be using the implicit wait method:
driver.implicitly_wait(5)
The third method is more useful when you have to wait until a particular action is completed or until an element is found:
self.wait.until(EC.presence_of_element_located((By.ID, 'UserName'))
There are five methods which I know: time.sleep(), pygame.time.wait(), matplotlib's pyplot.pause(), .after(), and asyncio.sleep().
time.sleep() example (do not use if using tkinter):
import time
print('Hello')
time.sleep(5) # Number of seconds
print('Bye')
pygame.time.wait() example (not recommended if you are not using the pygame window, but you could exit the window instantly):
import pygame
# If you are going to use the time module
# don't do "from pygame import *"
pygame.init()
print('Hello')
pygame.time.wait(5000) # Milliseconds
print('Bye')
matplotlib's function pyplot.pause() example (not recommended if you are not using the graph, but you could exit the graph instantly):
import matplotlib
print('Hello')
matplotlib.pyplot.pause(5) # Seconds
print('Bye')
The .after() method (best with Tkinter):
import tkinter as tk # Tkinter for Python 2
root = tk.Tk()
print('Hello')
def ohhi():
print('Oh, hi!')
root.after(5000, ohhi) # Milliseconds and then a function
print('Bye')
Finally, the asyncio.sleep() method (has to be in an async loop):
await asyncio.sleep(5)
A bit of fun with a sleepy generator.
The question is about time delay. It can be fixed time, but in some cases we might need a delay measured since last time. Here is one possible solution:
Delay measured since last time (waking up regularly)
The situation can be, we want to do something as regularly as possible and we do not want to bother with all the last_time, next_time stuff all around our code.
Buzzer generator
The following code (sleepy.py) defines a buzzergen generator:
import time
from itertools import count
def buzzergen(period):
nexttime = time.time() + period
for i in count():
now = time.time()
tosleep = nexttime - now
if tosleep > 0:
time.sleep(tosleep)
nexttime += period
else:
nexttime = now + period
yield i, nexttime
Invoking regular buzzergen
from sleepy import buzzergen
import time
buzzer = buzzergen(3) # Planning to wake up each 3 seconds
print time.time()
buzzer.next()
print time.time()
time.sleep(2)
buzzer.next()
print time.time()
time.sleep(5) # Sleeping a bit longer than usually
buzzer.next()
print time.time()
buzzer.next()
print time.time()
And running it we see:
1400102636.46
1400102639.46
1400102642.46
1400102647.47
1400102650.47
We can also use it directly in a loop:
import random
for ring in buzzergen(3):
print "now", time.time()
print "ring", ring
time.sleep(random.choice([0, 2, 4, 6]))
And running it we might see:
now 1400102751.46
ring (0, 1400102754.461676)
now 1400102754.46
ring (1, 1400102757.461676)
now 1400102757.46
ring (2, 1400102760.461676)
now 1400102760.46
ring (3, 1400102763.461676)
now 1400102766.47
ring (4, 1400102769.47115)
now 1400102769.47
ring (5, 1400102772.47115)
now 1400102772.47
ring (6, 1400102775.47115)
now 1400102775.47
ring (7, 1400102778.47115)
As we see, this buzzer is not too rigid and allow us to catch up with regular sleepy intervals even if we oversleep and get out of regular schedule.
The Tkinter library in the Python standard library is an interactive tool which you can import. Basically, you can create buttons and boxes and popups and stuff that appear as windows which you manipulate with code.
If you use Tkinter, do not use time.sleep(), because it will muck up your program. This happened to me. Instead, use root.after() and replace the values for however many seconds, with a milliseconds. For example, time.sleep(1) is equivalent to root.after(1000) in Tkinter.
Otherwise, time.sleep(), which many answers have pointed out, which is the way to go.
Delays are done with the time library, specifically the time.sleep() function.
To just make it wait for a second:
from time import sleep
sleep(1)
This works because by doing:
from time import sleep
You extract the sleep function only from the time library, which means you can just call it with:
sleep(seconds)
Rather than having to type out
time.sleep()
Which is awkwardly long to type.
With this method, you wouldn't get access to the other features of the time library and you can't have a variable called sleep. But you could create a variable called time.
Doing from [library] import [function] (, [function2]) is great if you just want certain parts of a module.
You could equally do it as:
import time
time.sleep(1)
and you would have access to the other features of the time library like time.clock() as long as you type time.[function](), but you couldn't create the variable time because it would overwrite the import. A solution to this to do
import time as t
which would allow you to reference the time library as t, allowing you to do:
t.sleep()
This works on any library.
If you would like to put a time delay in a Python script:
Use time.sleep or Event().wait like this:
from threading import Event
from time import sleep
delay_in_sec = 2
# Use time.sleep like this
sleep(delay_in_sec) # Returns None
print(f'slept for {delay_in_sec} seconds')
# Or use Event().wait like this
Event().wait(delay_in_sec) # Returns False
print(f'waited for {delay_in_sec} seconds')
However, if you want to delay the execution of a function do this:
Use threading.Timer like this:
from threading import Timer
delay_in_sec = 2
def hello(delay_in_sec):
print(f'function called after {delay_in_sec} seconds')
t = Timer(delay_in_sec, hello, [delay_in_sec]) # Hello function will be called 2 seconds later with [delay_in_sec] as the *args parameter
t.start() # Returns None
print("Started")
Outputs:
Started
function called after 2 seconds
Why use the later approach?
It does not stop execution of the whole script (except for the function you pass it).
After starting the timer you can also stop it by doing timer_obj.cancel().
asyncio.sleep
Notice in recent Python versions (Python 3.4 or higher) you can use asyncio.sleep. It's related to asynchronous programming and asyncio. Check out next example:
import asyncio
from datetime import datetime
#asyncio.coroutine
def countdown(iteration_name, countdown_sec):
"""
Just count for some countdown_sec seconds and do nothing else
"""
while countdown_sec > 0:
print(f'{iteration_name} iterates: {countdown_sec} seconds')
yield from asyncio.sleep(1)
countdown_sec -= 1
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(countdown('First Count', 2)),
asyncio.ensure_future(countdown('Second Count', 3))]
start_time = datetime.utcnow()
# Run both methods. How much time will both run...?
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
print(f'total running time: {datetime.utcnow() - start_time}')
We may think it will "sleep" for 2 seconds for first method and then 3 seconds in the second method, a total of 5 seconds running time of this code. But it will print:
total_running_time: 0:00:03.01286
It is recommended to read asyncio official documentation for more details.
While everyone else has suggested the de facto time module, I thought I'd share a different method using matplotlib's pyplot function, pause.
An example
from matplotlib import pyplot as plt
plt.pause(5) # Pauses the program for 5 seconds
Typically this is used to prevent the plot from disappearing as soon as it is plotted or to make crude animations.
This would save you an import if you already have matplotlib imported.
This is an easy example of a time delay:
import time
def delay(period='5'):
# If the user enters nothing, it'll wait 5 seconds
try:
# If the user not enters a int, I'll just return ''
time.sleep(period)
except:
return ''
Another, in Tkinter:
import tkinter
def tick():
pass
root = Tk()
delay = 100 # Time in milliseconds
root.after(delay, tick)
root.mainloop()
You also can try this:
import time
# The time now
start = time.time()
while time.time() - start < 10: # Run 1- seconds
pass
# Do the job
Now the shell will not crash or not react.

Categories