I am using time.sleep(10) in my program. Can display the countdown in the shell when I run my program?
>>>run_my_program()
tasks done, now sleeping for 10 seconds
and then I want it to do 10,9,8,7....
is this possible?
you could always do
#do some stuff
print 'tasks done, now sleeping for 10 seconds'
for i in xrange(10,0,-1):
time.sleep(1)
print i
This snippet has the slightly annoying feature that each number gets printed out on a newline. To avoid this, you can
import sys
import time
for i in xrange(10,0,-1):
sys.stdout.write(str(i)+' ')
sys.stdout.flush()
time.sleep(1)
This is the best way to display a timer in the console for Python 3.x:
import time
import sys
for remaining in range(10, 0, -1):
sys.stdout.write("\r")
sys.stdout.write("{:2d} seconds remaining.".format(remaining))
sys.stdout.flush()
time.sleep(1)
sys.stdout.write("\rComplete! \n")
This writes over the previous line on each cycle.
A simple solution that clears the last number from the console:
import time
for i in range(10,0,-1):
print(f"{i}", end="\r", flush=True)
time.sleep(1)
By default, the print function sets end="\n" which means subsequent calls to print will be printed on a new line. You can change this to end="\r" to replace the output after each call. (How does carriage return "\r" work in python).
Here f"{i}" is for printing single digit only. You can modify it based on number of digits.
e.g. Here it will work for two digits by just adding one space as a postfix- f"{i} "
Also, using flush means you don't have to worry about buffering issues. (What does print()'s flush do?)
This is how it looks:
You can do a countdown function like:
import sys
import time
def countdown(t, step=1, msg='sleeping'): # in seconds
pad_str = ' ' * len('%d' % step)
for i in range(t, 0, -step):
print '%s for the next %d seconds %s\r' % (msg, i, pad_str),
sys.stdout.flush()
time.sleep(step)
print 'Done %s for %d seconds! %s' % (msg, t, pad_str)
The carriage return \r and the comma , will keep the print in the same line (avoiding one line for each countdown value)
As the number of seconds decreases, the pad_str will ensure the last line is overwritten with spaces instead of leaving the last character(s) behind as the output shortens.
The final print overwrites the last status message with a done message and increments the output line, so there is evidence of the delay.
This is something that I've learned at one of my first python lessons, we played with ["/","-","|","\","|"] but the principle is the same:
import time
for i in reversed(range(0, 10)):
time.sleep(1)
print "%s\r" %i,
time.sleep() may return earlier if the sleep is interrupted by a signal or later (depends on the scheduling of other processes/threads by OS/the interpreter).
To improve accuracy over multiple iterations, to avoid drift for large number of iterations, the countdown may be locked with the clock:
#!/usr/bin/env python
import sys
import time
for i in reversed(range(1, 1001)):
time.sleep(1 - time.time() % 1) # sleep until a whole second boundary
sys.stderr.write('\r%4d' % i)
Here's one I did:
import time
a = input("How long is the countdown?")
while a != 0:
print a
time.sleep(1)
a = a-1
At the end if you and an else you can put an alarm or whatever.
Sure, just write a loop that prints 10 minus the iteration counter, then have it sleep 1 second each iteration and run for 10 iterations. Or, to be even more flexible:
def printer(v):
print v
def countdown_timer(duration, step=1, output_function=printer,
prompt='Waiting {duration} seconds.'):
output_function(prompt.format(duration=duration))
for i in xrange(duration/step):
output_function(duration - step * i)
Another easy way, without reinventing the wheel, is to use tqdm, which automatically displays a progress bar:
from time import sleep
from tqdm import tqdm
for _ in tqdm(range(10)):
sleep(1)
Optionally, you can then modify the display of the loading bar as you wish.
This one is subsecond precise:
print()
_k = 0.5 # ensure k != _k first time round (as k will be integer)
print('Starting in ')
while _k > 0:
k = round(event_timestamp - time())
if k != _k:
print(f'\r{k} ', end='', flush=True)
_k = k
sleep(0.1)
print('boom')
Notice the trailing space in f'\r{k} '. So if we go from 100 to 99 or 10 to 9 it clears the second digit.
Also it doesn't require import sys.
sleep(0.0003) if you want millisecond precision.
if you don't limit yourself to sleep, then (courtesy automatetheboringstuff), pyautogui has a nifty countdown function:
import pyautogui
print('Starting in ', end=''); pyautogui.countdown(3)
may be this will help
import turtle
for i in range(10):
t2 = turtle.Turtle()
t2.hideturtle()
t2.penup()
t2.goto(0,0)
t2.write(i,font=("Arial", 16, "normal"))
i-=1
sleep(1)
t2.clear()
Related
I am not yet familiar with Python, I've programmed this code from the documentation I read, but it does nothing, there is no output a all:
# -*- coding: latin_1 -*-
import time
from msvcrt import kbhit
Intervall = 1
mytime = int(time.time()) + Intervall
print (time.time ())
print (mytime)
while (kbhit() == False):
if (int(time.time ()) >= mytime):
# I want this to be done every second:
print (int(time.time ()), mytime)
mytime = int(time.time ()) + Intervall
# I want other things to be done here (outside the if statement)
If I comment out this line in the while loop:
mytime = int(time.time ()) + Intervall
it does what the code says but of course the print statement is executed in every loop run, which is not what I want.
Any help is welcome
(using Python 3.4.1. under Win 7)
Thanks,
Martin.
Stop coercing the result of time.time() to an integer, this may not be the problem, but it is unnecessary.
Stop busy-waiting on the key press, it is a great way to waste CPU. Try instead:
while not kbhit():
print('no kbhit at', time.time())
time.sleep(1) # do nothing for a second
You can also drop Interval1 and mytime as they are unneeded complexity.
I would like to measure the time elapsed to evaluate a block of code in a Python program,
possibly separating between user cpu time, system cpu time and elapsed time.
I know the timeit module, but I have many self-written functions and it is not very easy
to pass them in the setup process.
I would rather have something that could be used like:
#up to here I have done something....
start_counting() #or whatever command used to mark that I want to measure
#the time elapsed in the next rows
# code I want to evaluate
user,system,elapsed = stop_counting() #or whatever command says:
#stop the timer and return the times
The user and system CPU times are not essential (though I would like to measure them),
but for the elapsed time I would like to be able to do something like this,
rather than using complicated commands or modules.
To get the elapsed time in seconds, you can use timeit.default_timer():
import timeit
start_time = timeit.default_timer()
# code you want to evaluate
elapsed = timeit.default_timer() - start_time
timeit.default_timer() is used instead of time.time() or time.clock() because it will choose the timing function that has the higher resolution for any platform.
I always use a decorator to do some extra work for a existing function, including to get the execution time. It is pythonic and simple.
import time
def time_usage(func):
def wrapper(*args, **kwargs):
beg_ts = time.time()
retval = func(*args, **kwargs)
end_ts = time.time()
print("elapsed time: %f" % (end_ts - beg_ts))
return retval
return wrapper
#time_usage
def test():
for i in xrange(0, 10000):
pass
if __name__ == "__main__":
test()
I found myself solving this problem again and again, so I finally created a library for it. Install with pip install timer_cm. Then:
from time import sleep
from timer_cm import Timer
with Timer('Long task') as timer:
with timer.child('First step'):
sleep(1)
for _ in range(5):
with timer.child('Baby steps'):
sleep(.5)
Output:
Long task: 3.520s
Baby steps: 2.518s (71%)
First step: 1.001s (28%)
You can achieve this through the Context Manager, for example:
from contextlib import contextmanager
import time
import logging
#contextmanager
def _log_time_usage(prefix=""):
'''log the time usage in a code block
prefix: the prefix text to show
'''
start = time.time()
try:
yield
finally:
end = time.time()
elapsed_seconds = float("%.2f" % (end - start))
logging.debug('%s: elapsed seconds: %s', prefix, elapsed_seconds)
use example:
with _log_time_usage("sleep 1: "):
time.sleep(1)
There is one more option which i loves a lot now for simplicity - ipython. In ipython you got a lot of useful stuff plus:
%time <expression> - to get straight cpu and wall time on expression
%timeit <expression> - to get cpu and wall time in a loop of expression
Python 3 - Simple solution using standard library
Option 1: Triple quote the code
import inspect
import timeit
code_block = inspect.cleandoc("""
base = 123456789
exponent = 100
return base ** exponent
""")
print(f'\Code block: {timeit.timeit(code_block, number=1, globals=globals())} elapsed seconds')
inspect.cleandoc handles the removal of extra tabs and whitespace so that blocks of code can be copied and pasted without getting indentation errors.
Option 2: Place code block in a function
import timeit
def my_function():
base = 123456789
exponent = 100
return base ** exponent
if __name__ == '__main__':
print(f'With lambda wrapper: {timeit.timeit(lambda: my_function(), number=1)} elapsed seconds')
Note that a function call will add additional execution time versus timing the function body directly.
OK so two questions here.
First,I am trying to show start time. I am doing this with program_time. Second, I also want to show elapsed time. I would also like to show this in microseconds.
import time
a= time.time()
print a
while True:
program_time= time.time()
elapsed=program_time - a
for i in [program_time]:
print "%s\r" % i,
Thanks in advance.
Your code looks almost correct. This should show the start time, and each subsequent program time as the while loop proceeds (albeit very quickly). Perhaps you need to perform some calculation in the loop?
import time
a = time.time()
print "Starting time is %s" % str(a)
while True:
# Clear the screen each iteration to "recycle" the lines
print chr(27) + "[2J"
program_time = time.time();
elapsed = int(round((program_time - a) * 1000)) * 100
print "Start time is %s" % a
print "Elapsed time is %s" % elapsed
# Simulate some work
time.sleep(1)
Assuming your question is "why does my program output the current time instead of the elapsed time," the answer is "because program_time is being printed rather than elapsed."
I'm reading serial data with a while loop. However, I have no control over the sample rate.
The code itself seems to take 0.2s to run, so I know I won't be able to go any faster than that. But I would like to be able to control precisely how much slower I sample.
I feel like I could do it using 'sleep', but the problem is that there is potential that at different points the loop itself will take longer to read(depending on precisely what is being transmitted over serial data), so the code would have to make up the balance.
For example, let's say I want to sample every 1s, and the loop takes anywhere from 0.2s to 0.3s to run. My code needs to be smart enough to sleep for 0.8s (if the loop takes 0.2s) or 0.7s (if the loop takes 0.3s).
import serial
import csv
import time
#open serial stream
while True:
#read and print a line
sample_value=ser.readline()
sample_time=time.time()-zero
sample_line=str(sample_time)+','+str(sample_value)
outfile.write(sample_line)
print 'time: ',sample_time,', value: ',sample_value
Just measure the time running your code takes every iteration of the loop, and sleep accordingly:
import time
while True:
now = time.time() # get the time
do_something() # do your stuff
elapsed = time.time() - now # how long was it running?
time.sleep(1.-elapsed) # sleep accordingly so the full iteration takes 1 second
Of course not 100% perfect (maybe off one millisecond or another from time to time), but I guess it's good enough.
Another nice approach is using twisted's LoopingCall:
from twisted.internet import task
from twisted.internet import reactor
def do_something():
pass # do your work here
task.LoopingCall(do_something).start(1.0)
reactor.run()
An rather elegant method is you're working on UNIX : use the signal library
The code :
import signal
def _handle_timeout():
print "timeout hit" # Do nothing here
def second(count):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(1)
try:
count += 1 # put your function here
signal.pause()
finally:
signal.alarm(0)
return count
if __name__ == '__main__':
count = 0
count = second(count)
count = second(count)
count = second(count)
count = second(count)
count = second(count)
print count
And the timing :
georgesl#cleese:~/Bureau$ time python timer.py
5
real 0m5.081s
user 0m0.068s
sys 0m0.004s
Two caveats though : it only works on *nix, and it is not multithread-safe.
At the beginning of the loop check if the appropriate amount of time has passed. If it has not, sleep.
# Set up initial conditions for sample_time outside the loop
sample_period = ???
next_min_time = 0
while True:
sample_time = time.time() - zero
if sample_time < next_min_time:
time.sleep(next_min_time - sample_time)
continue
# read and print a line
sample_value = ser.readline()
sample_line = str(sample_time)+','+str(sample_value)
outfile.write(sample_line)
print 'time: {}, value: {}'.format(sample_time, sample_value)
next_min_time = sample_time + sample_period
I received the following script from a fellow programmer:
from time import *
start = strptime(asctime())
end = strptime(asctime())
print 'you took %i minutes' % (end[4] - start[4])
As you might already know, the script measures the time between the third and fourth line. However, it seems to measure it in minutes. How can I go about to measure it in seconds, with at least one decimal place (ex. 7.4 seconds).
Also, I would like to add one extra piece of functionality. Say the script runs, and I am asked by the program to type any word. At the end of my typing, I have to press the enter key to exit the program and measure the time from the first keystroke to the moment I press enter. How can I go about measuring this?
First, I would avoid using import * as it's considered bad practice. You can use time.time() to get more precision:
>>> import time
>>> start = time.time()
>>> end = time.time()
>>> end - start
5.504057168960571
You could also use datetime.datetime.now().
#source: http://docs.python.org/library/timeit.html
def test():
"""Stupid test function"""
L = []
for i in range(100):
L.append(i)
if __name__ == '__main__':
from timeit import Timer
t = Timer("test()", "from __main__ import test")
print t.timeit()
If you are trying to optimize a python web service call, you can do the following.
import time
In the beginning of the function, right
start = time.time()
in the line put (540 is the line number),
l540 = time.time()
print("--------l541 ------------")
print(l540 - start)
in the next line put (608 is the line number),
l608 = time.time()
print("-------- 609 ------------")
print(l608 - l540)
You can add as many as you want and it will tell you where exactly the program is taking time.