Skip to content
Snippets Groups Projects
Commit ba82c571 authored by Christof Schulze's avatar Christof Schulze :sunglasses:
Browse files

added missing functions for CLI and Environment parsing

parent 686a8a4f
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ammsml. If not, see <http://www.gnu.org/licenses/>.
from collections.abc import Sequence
from collections.abc import Sequence, Mapping, Hashable
def is_string(seq):
......@@ -55,11 +56,14 @@ def count(seq):
Resembles the `collections.Counter` class functionality, which is deprecated
since version 3.3, will be removed in version 3.9
It is meant to be replaced when the we find something equivalent in maybe collections.abc
It is meant to be replaced when we find something equivalent in maybe collections.abc
this code also runs on Python 2.6.* where collections.Counter is not available.
:param seq:
:return:
"""
if not is_iterable(seq):
raise Exception('Argument provided is not an iterable')
......@@ -69,3 +73,49 @@ def count(seq):
for elem in seq:
counters[elem] = counters.get(elem, 0) + 1
return counters
class ImmutableDict(Hashable, Mapping):
"""
Dictionary that cannot be updated
"""
def __init__(self, *args, **kwargs):
self._store = dict(*args, **kwargs)
def __getitem__(self, key):
return self._store[key]
def __iter__(self):
return self._store.__iter__()
def __len__(self):
return self._store.__len__()
def __hash__(self):
return hash(frozenset(self.items()))
def __repr__(self):
return 'ImmutableDict({0})'.format(repr(self._store))
def union(self, overriding_mapping):
"""
Create an ImmutableDict as a combination of the original and overriding_mapping
:param overriding_mapping: A Mapping of replacement and additional items
:return: A copy of the ImmutableDict with key-value pairs from the overriding_mapping added
If any of the keys in overriding_mapping are already present in the original ImmutableDict,
the overriding_mapping item replaces the one in the original ImmutableDict.
"""
return ImmutableDict(self._store, **overriding_mapping)
def difference(self, subtractive_iterable):
"""
Create an ImmutableDict as a combination of the original minus keys in subtractive_iterable
:param subtractive_iterable: Any iterable containing keys that should not be present in the new ImmutableDict
:return: A copy of the ImmutableDict with keys from the subtractive_iterable removed
"""
remove_keys = frozenset(subtractive_iterable)
keys = (k for k in self._store.keys() if k not in remove_keys)
return ImmutableDict((k, self._store[k]) for k in keys)
......@@ -79,6 +79,20 @@ def is_quoted(data):
return len(data) > 1 and data[0] == data[-1] and data[0] in ('"', "'") and data[-2] != '\\'
def humanize_time(d) -> str:
"""
Return a human-friendly description of elapsed time
:param d:
:return:
"""
human = ""
if d >= 3600:
human += "%dh" % (int(d) // 3600)
d %= 3600
if d >= 60:
human += "%dm" % (int(d) // 60)
d %= 60
human += ("%.3fs" % d)
return human
......@@ -57,3 +57,18 @@ def with_metaclass(meta, *bases):
def __prepare__(cls, name, this_bases):
return meta.__prepare__(name, bases)
return type.__new__(metaclass, 'temporary_class', (), {})
def add_metaclass(metaclass):
"""Class decorator for creating a class with a metaclass."""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
\ No newline at end of file
import unittest
from ammsml.utils.parsing import humanize_time
class Test_humanize_time(unittest.TestCase):
def test_something(self):
self.assertEqual(True, False)
# TODO
if __name__ == '__main__':
unittest.main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment