-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dates
and dicts
for version 1.2.dev1
- Loading branch information
Showing
10 changed files
with
224 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from utools import dates as udates | ||
|
||
|
||
def test_timer(): | ||
|
||
timer = udates.timer() | ||
|
||
# no with block, the timer should not have started | ||
assert timer.get() == 0 | ||
assert not timer.ongoing() | ||
|
||
# a simple with block | ||
with timer: | ||
assert timer.ongoing() | ||
pass | ||
assert not timer.ongoing() | ||
assert timer.get() > 0 | ||
|
||
# a simple with block with an exception | ||
try: | ||
with timer: | ||
raise SystemError | ||
except SystemError: | ||
pass | ||
assert timer.get() > 0 | ||
assert timer.get() == timer.get() | ||
|
||
timer.reset() | ||
assert timer.get() == 0 | ||
assert not timer.ongoing() | ||
|
||
timer.start() | ||
assert timer.ongoing() | ||
assert timer.get() != timer.get() | ||
|
||
timer.stop() | ||
assert not timer.ongoing() | ||
assert timer.get() > 0 | ||
assert timer.get() == timer.get() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import pytest | ||
from utools import dicts as udicts | ||
|
||
|
||
# --- utools.dicts.deep_get --- | ||
def test_deep_get(): | ||
|
||
d = {"user": {"id": 1, "login": "foo"}, "date": "2016-04-27"} | ||
assert udicts.deep_get(d) == d | ||
assert udicts.deep_get(d, default=3) == d | ||
assert udicts.deep_get(d, "user", "login") == "foo" | ||
assert udicts.deep_get(d, "user") == {"id": 1, "login": "foo"} | ||
assert udicts.deep_get(d, "user", "name") is None | ||
assert udicts.deep_get(d, "user", "name", default="bar") == "bar" | ||
assert udicts.deep_get(d, "user", "login", default="bar") == "foo" | ||
|
||
# deep_get should also work with lists | ||
d = [[[3], 4]] | ||
assert udicts.deep_get(d, 0, 0, 0) == 3 | ||
assert udicts.deep_get(d, 0, 0) == [3] | ||
assert udicts.deep_get(d, 0, 1) == 4 | ||
assert udicts.deep_get(d, 0, 0, 0, 0) is None | ||
assert udicts.deep_get(d, 0, 3, 5, default=17) == 17 | ||
|
||
|
||
# deep_get should be safe and should never raise | ||
@pytest.mark.parametrize("d", [ | ||
1, | ||
"foo", | ||
{1, 2, 3}, | ||
object(), | ||
int, | ||
None | ||
]) | ||
def test_deep_get_with_safety(d): | ||
assert udicts.deep_get(d, "foo", 1, 4) is None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
__version__ = "1.1" | ||
__version__ = "1.2.dev1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" Useful functions to work with dates and durations | ||
""" | ||
|
||
from datetime import datetime | ||
|
||
|
||
class timer: | ||
""" Get the execution time of a block of code. | ||
Example: | ||
The easiest way to use the timer is inside a 'with' statement:: | ||
>>> import time | ||
>>> t = timer() | ||
>>> with t: | ||
... time.sleep(1) | ||
>>> t.get() | ||
1.001263 | ||
The timer class also provides methods to start and stop the timer when you want:: | ||
>>> t = timer() | ||
>>> t.get() | ||
0. | ||
>>> t.start() | ||
>>> t.get() | ||
1.425219 | ||
>>> t.stop() | ||
>>> t.get() | ||
2.636786 | ||
""" | ||
|
||
def __init__(self): | ||
self._start_time = None | ||
self._stop_time = None | ||
|
||
def __enter__(self): | ||
self.start() | ||
|
||
def __exit__(self, exc_type, exc_value, traceback): | ||
del exc_type, exc_value, traceback | ||
self.stop() | ||
|
||
def start(self): | ||
""" Start or restart the timer. | ||
""" | ||
self.reset() | ||
self._start_time = datetime.now() | ||
|
||
def stop(self): | ||
""" Stop the timer. | ||
""" | ||
if self.ongoing(): | ||
self._stop_time = datetime.now() | ||
|
||
def reset(self): | ||
""" Reset the timer. | ||
""" | ||
self._start_time = None | ||
self._stop_time = None | ||
|
||
def ongoing(self): | ||
""" Check if the timer is running. | ||
Returns: True if the timer is currently running, False otherwise | ||
""" | ||
return self._start_time is not None and self._stop_time is None | ||
|
||
def get(self): | ||
""" Get the current timer value in seconds. | ||
Returns: the elapsed time in seconds since the timer started or until the timer was stopped | ||
""" | ||
now = datetime.now() | ||
if self._start_time: | ||
if self._stop_time: | ||
return (self._stop_time - self._start_time).total_seconds() | ||
return (now - self._start_time).total_seconds() | ||
return 0. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" Useful functions to work with dictionaries. | ||
""" | ||
|
||
|
||
def deep_get(d, *keys, default=None): | ||
""" Recursive safe search in a dictionary of dictionaries. | ||
Args: | ||
d: the dictionary to work with | ||
*keys: the list of keys to work with | ||
default: the default value to return if the recursive search did not succeed | ||
Returns: | ||
The value wich was found recursively in d, or default if the search did not succeed | ||
Example: | ||
>>> d = {"user": {"id": 1, "login": "foo"}, "date": "2016-04-27"} | ||
>>> deep_get(d, "user", "login") | ||
"foo" | ||
>>> deep_get(d, "user") | ||
{"id": 1, "login": "foo"} | ||
>>> deep_get(d, "user", "name") | ||
None | ||
>>> deep_get(d, "user", "name", default="bar") | ||
"bar" | ||
""" | ||
|
||
for key in keys: | ||
try: | ||
d = d[key] | ||
except (KeyError, IndexError, TypeError): | ||
return default | ||
return d |