Skip to content

Commit 8f9fb36

Browse files
authored
Add named attributes to the text template strings (#25)
1 parent 04754ef commit 8f9fb36

File tree

4 files changed

+92
-2
lines changed

4 files changed

+92
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
The format is based on [Keep a Changelog](https://keepachangelog1.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Attributes that can be referenced in the `text` template string (suggested by [@mlisovyi](https://github.com/mlisovyi) in [#24]).
13+
1014
### Changed
1115

1216
- `Timer.timers` changed from regular to `dict` to a custom dictionary supporting basic statistics for named timers.

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,38 @@ You can use `codetiming.Timer` in several different ways:
5757

5858
You can turn off explicit reporting of the elapsed time by setting `logger=None`.
5959

60+
In the template text, you can also use explicit attributes to refer to the `name` of the timer, or log the elapsed time in `milliseconds`, `seconds` (the default), or `minutes`. For example:
61+
62+
```python
63+
t1 = Timer(name="NamedTimer", text="{name}: {minutes:.1f} minutes")
64+
t2 = Timer(text="Elapsed time: {milliseconds:.0f} ms")
65+
```
66+
67+
Note that the strings used by `text` are **not** f-strings. Instead they are used as templates that will be populated using `.format()` behind the scenes. If you want to combine the `text` template with an f-string, you need to use double braces for the template values:
68+
69+
```python
70+
t = Timer(text=f"{__file__}: {{:.4f}}")
71+
```
72+
73+
74+
## Capturing the Elapsed Time
75+
6076
When using `Timer` as a class, you can capture the elapsed time when calling `.stop()`:
6177

6278
```python
6379
elapsed_time = t.stop()
6480
```
6581

82+
You can also find the last measured elapsed time in the `.last` attribute. The following code will have the same effect as the previous example:
83+
84+
```python
85+
t.stop()
86+
elapsed_time = t.last
87+
```
88+
89+
90+
## Named Timers
91+
6692
Named timers are made available in the class dictionary `Timer.timers`. The elapsed time will accumulate if the same name or same timer is used several times. Consider the following example:
6793

6894
```python
@@ -87,6 +113,21 @@ WARNING:root:Time spent: 1.73
87113

88114
The example shows how you can redirect the timer output to the logging module. Note that the elapsed time spent in the two different uses of `t` has been accumulated in `Timer.timers`.
89115

116+
You can also get simple statistics about your named timers. Continuing from the example above:
117+
118+
```python
119+
>>> Timer.timers.max("example")
120+
3.5836678670002584
121+
122+
>>> Timer.timers.mean("example")
123+
2.6563487200000964
124+
125+
>>> Timer.timers.stdev("example")
126+
1.311427314335879
127+
```
128+
129+
`timers` support `.count()`, `.total()`, `.min()`, `.max()`, `.mean()`, `.median()`, and `.stdev()`.
130+
90131

91132
## Acknowledgements
92133

codetiming/_timer.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ def stop(self) -> float:
4848

4949
# Report elapsed time
5050
if self.logger:
51-
self.logger(self.text.format(self.last))
51+
attributes = {
52+
"name": self.name,
53+
"milliseconds": self.last * 1000,
54+
"seconds": self.last,
55+
"minutes": self.last / 60,
56+
}
57+
self.logger(self.text.format(self.last, **attributes))
5258
if self.name:
5359
self.timers.add(self.name, self.last)
5460

tests/test_codetiming.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,45 @@ def test_timer_sets_last():
186186
assert t.last >= 0.02
187187

188188

189+
def test_using_name_in_text_without_explicit_timer(capsys):
190+
"""Test that the name of the timer can be referenced in the text"""
191+
name = "NamedTimer"
192+
with Timer(name=name, text="{name}: {:.2f}"):
193+
waste_time()
194+
195+
stdout, stderr = capsys.readouterr()
196+
assert re.match(f"{name}: " + r"0\.\d{2}", stdout)
197+
198+
199+
def test_using_name_in_text_with_explicit_timer(capsys):
200+
"""Test that the name of the timer and the seconds attribute can be referenced in the text"""
201+
name = "NamedTimer"
202+
with Timer(name=name, text="{name}: {seconds:.2f}"):
203+
waste_time()
204+
205+
stdout, stderr = capsys.readouterr()
206+
assert re.match(f"{name}: " + r"0\.\d{2}", stdout.strip())
207+
208+
209+
def test_using_minutes_attribute_in_text(capsys):
210+
"""Test that timer can report its duration in minutes"""
211+
with Timer(text="{minutes:.1f} minutes"):
212+
waste_time()
213+
214+
stdout, stderr = capsys.readouterr()
215+
assert stdout.strip() == "0.0 minutes"
216+
217+
218+
def test_using_milliseconds_attribute_in_text(capsys):
219+
"""Test that timer can report its duration in milliseconds"""
220+
with Timer(text="{milliseconds:.0f} {seconds:.3f}"):
221+
waste_time()
222+
223+
stdout, stderr = capsys.readouterr()
224+
milliseconds, _, seconds = stdout.partition(" ")
225+
assert int(milliseconds) == round(float(seconds) * 1000)
226+
227+
189228
def test_timers_cleared():
190229
"""Test that timers can be cleared"""
191230
with Timer(name="timer_to_be_cleared"):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy