Time¶
This module contains classes that handle time : either measure it, wait or even control it !
Timer¶
Timer
pause your script for the given number of seconds. With quite
the same design as wheel, you may add a message next to the timer.
from pyux.time import Timer
# A timer for 3 seconds with a message
Timer(delay = 3, message = 'Pausing 3 secs, tired')
# A timer with no message
Timer(delay = 3)
The timer can also be used as an iterable’s decoration within a for statement,
when you repeatedly have to await the same delay at each iteration.
Specifying overwrite = True
allows each iteration to be
rewritten on the same line, which is advised when used in that case.
Note that the first argument to Timer
is iterable
and not delay
, and
all of them have default values, so Timer(5)
won’t have the expected
behaviour !
By default, a timer in a for loop prints the iteration index next to the timer.
Use pattern
argument to specify a prefix to add to the default iteration
index (default to ''
), or print_value
to print the iteration
value rather than the index.
from pyux.time import Timer
for fruit in Timer(['banana', 'apple', 'tomato'], delay = 3, print_value = True):
pass
Again, the Timer.close()
makes the counter go to zero included and flushes
a new line. It is called automatically when used as a loop decoration.
Wait¶
Use wait
to decorate a function that you want to pause for a given amount of
time before or after each execution. It can be useful for API calls in loops
where you have await a certain time between each API call. The pause can be made
before or after the function call, and Timer
can be used instead of the built-in
sleep
function with timer = True
.
from pyux.time import wait
@wait(delay = 3, before = True)
def do_nothing():
return
do_nothing()
timeout¶
timeout
decorates a function that you want to timeout after a given delay.
from pyux.time import timeout
@timeout(delay = 5)
def unstopable_function():
i = 0
while i >= 0:
i += 1
return i
unstopable_function() # timeout stops execution after 5 seconds
Chronos¶
Use Chronos
to measure user execution time, for a script or a loop.
It works as a stopwatch : rather than wrapping around and timing an
expression, it triggers at start, then the method Chronos.lap()
records time with timeit.default_timer()
each time it is called (thus
resembling a lap button on a stopwatch).
from time import sleep
from pyux.time import Chronos
chrono = Chronos()
print('Step one with duration approx. 1.512 secs')
sleep(1.512)
chrono.lap(name = 'step 1')
print('Step two with duration approx. 1.834 secs')
sleep(1.834)
chrono.lap(name = 'step 2')
chrono.compute_durations(ms = True)
print('\nNow printing durations :')
for name, time in chrono.durations.items():
print('Time for step %s : %d ms' % (name, time))
Durations can be written in a tsv file with Chronos.write_tsv()
.
The method uses an append mode, so you can append times from different runs
to the same tracking file, for instance. Argument run_name
in that method
allows you to give a name to a run especially for that purpose (the name appears
as the first column of the written file).
Three columns are written, with default names Execution
(the one
presented just above), Step
and Duration (secs)
. These names
can be changed with argument col_names
.
If you want to time iterations in a for loop, you can use it as a decoration for the iterable. Since you won’t be able to assign the object back when the loop finishes, you can choose to print durations in console, or write them into a tsv file.
from pyux.time import Chronos
from pyux.time import Timer
for index, value in enumerate(Chronos(range(1, 4), console_print = True, ms = True)):
Timer(delay = value, message = 'At iteration %d' % index, overwrite = True)
Depending on the number of arguments you provide, declaration in the for statement can become rather verbose. Feel free to initiate the chrono outside of the loop, in which case, the object remains available after the loop (if you need to add steps from the rest of the code afterwards, for instance).
from pyux.time import Chronos
from time import sleep
from os import unlink
timed_iterable = Chronos(
iterable = range(25),
console_print = True,
write_tsv = True,
run_name = 'verbose_declaration',
path = 'example_times.tsv',
col_names = ('run', 'lap', 'duration (msecs)'),
ms = True
)
for value in timed_iterable:
sleep(value / 1000)
# unlink('example_times.tsv')
Detailed documentation¶
-
class
pyux.time.
Chronos
(iterable=None, console_print: bool = False, pattern: str = 'iteration ', write_tsv: bool = False, run_name: str = 'default', path: str = None, col_names=None, ms: bool = False)¶ Bases:
object
Time chunks of code in a script.
The class works as a stopwatch during a race on track : after starting it, for each lap, a button is pushed that records time at this moment, using
timeit.default_timer()
.Parameters: - iterable (iterable or int) – default
None
: for decorator use only : an iterable, or an integer for standardrange(n)
values. - ms (bool) – default
False
: compute durations in milliseconds - console_print (bool) – default
False
: for decorator use only : print durations in tsv format in console when loop is finished - pattern (str) – default
'iteration '
: for decorator use only : pattern for naming laps, will be suffixed with the iteration number - write_tsv (bool) – default
False
: for decorator use only : write out tsv file end loop is finished - run_name (str) – default
'default'
: for decorator use only : name to give to execution for column Execution - path (str) – default
None
: for decorator use only : full path to file to write - col_names (tuple) – default
None
: for decorator use only : column names (length 3)
Recorded times do not have a meaning by themselves since they do not correspond to durations and depends on the previous recorded times. When you want to know duration of recorded laps, use
compute_durations()
, which gives durations for each lap and total duration.Chronos can be used as a decorator in a for loop. In that case, it records duration for each iteration. Since you cannot get the object back, you can either print the values to console (in tsv format) or write out the values in a tsv file.
Specifying an
iterable
argument while callingChronos()
outside of a for statement has no effect. In that case, you can still use it manually, as if you entered nothing for that argument.Results can be exported in a tsv file with
write_tsv()
.Example: >>> from time import sleep >>> chrono = Chronos() >>> sleep(2) >>> chrono.lap(name = 'lap 1') >>> sleep(5) >>> chrono.lap(name = 'lap 2') >>> chrono.compute_durations().durations >>> # In a for loop >>> for index in Chronos(10, console_print = True, write_tsv = False): >>> pass
-
compute_durations
(ms: bool = False)¶ Compute laps durations.
Duration is the difference between two adjacent laps. Results are stored in
self.durations
, in seconds by default. They can be stored in milliseconds. The total duration is also calculated.Parameters: ms (bool) – express durations in milliseconds rather than seconds Returns: self
-
lap
(name: str)¶ Record time for this lap; a name must be provided.
-
write_tsv
(run_name: str, path: str, col_names: tuple = None)¶ Export durations in a tsv file.
Write three columns, the first containing
run_name
: a string describing which execution the durations came from. This way you can append several execution times to the same file.Default values for column names are : Execution, Step, Duration (secs)
Parameters: - run_name (str) – name to give to execution for column Execution
- path (str) – full path to file to write
- col_names (tuple) – default
None
: column names of length 3
Returns: self
- iterable (iterable or int) – default
-
class
pyux.time.
Timer
(iterable=None, delay: int = None, message: str = '', ms: bool = False, pattern: str = '', print_value: bool = False, overwrite: bool = False)¶ Bases:
object
Print a descending timer for a given delay.
A message can be printed next to the timer. The class can be used on the iterable of a for loop to wait the same amount of time at each iteration.
Parameters: - iterable (iterable or int) – default
None
: for decorator use only : an iterable, or an integer for standardrange(n)
values - delay (int) – default
None
: time to wait, must be provided. Default to seconds, can be milliseconds withms = True
- message (str) – default
''
: message to print when used manually - ms (bool) – default
False
: use a delay in milliseconds - pattern (str) – default
''
: for decorator use only : prefix to print before iterated value when used as a loop decorator andprint_value = False
- print_value (bool) – default
False
: for decorator use only : Print running value of the iterable when used to decorate a loop instead of iteration index - overwrite (bool) – default
False
: do not print a new line when the timer is finished (useful almost only when used within a loop)
When used within a for loop, the default behavior is to print the iteration index next to the timer. You can add a constant string prefix to it using the argument
pattern
(which is not used otherwise), or useprint_value = True
to print the running value of the iterable.Specifying a value for
iterable
while callingTimer()
outside of a for statement will have no effect (except if you use the result in a for statement afterwards, obviously).Raises: DelayTypeError
if no or wrong type delay is givenExample: >>> # One-shot usage >>> Timer(delay = 10, message = "Waiting for 10 seconds") >>> # Usage as a decorator >>> for index in Timer(3, delay = 3): >>> pass
-
close
(message: str, overwrite: bool) → None¶ Print
'0'
when time has passed (last iteration is1
).
-
static
print
(time: str, message: str) → None¶ Print the counter for a given time, counter and message.
- iterable (iterable or int) – default
-
pyux.time.
timeout
(delay: float)¶ Stop a function if running time exceeds delay (seconds).
To be used as a decorator.
Parameters: delay (float) – time in seconds before stopping running function Example: >>> @timeout(delay = 10) >>> def infinite_fun(): >>> while True: >>> pass
-
pyux.time.
wait
(delay: float, before: bool = True, timer: bool = False, **timer_args)¶ Wait a given delay before or after a function call.
The function is used as a target function’s decoration. With default values nothing is printed during pause, but a
Timer
can be printed instead.Parameters: - delay (float) – time to wait (in seconds)
- before (bool) – default
True
: pause before function execution - timer (bool) – default
False
: print a timer during pause - timer_args (see
Timer
) – keyword arguments forTimer
whentimer = True
Returns: a function decorated with a timer
Example: >>> @wait(delay = 3) >>> def print_hello(): >>> print('hello') >>> print_hello()