Skip to content

Commit 38ad5d4

Browse files
committed
-
1 parent 8ffeac0 commit 38ad5d4

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

source_py2/python_toolbox/nifty_collections/frozen_counter.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,17 @@ def fromkeys(cls, iterable, v=None):
9595
def __repr__(self):
9696
if not self:
9797
return '%s()' % self.__class__.__name__
98-
items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
99-
return '%s({%s})' % (self.__class__.__name__, items)
98+
try:
99+
items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
100+
return '%s({%s})' % (self.__class__.__name__, items)
101+
except TypeError:
102+
# handle case where values are not orderable
103+
return '{0}({1!r})'.format(self.__class__.__name__, dict(self))
104+
105+
106+
__pos__ = lambda self: self
107+
__neg__ = lambda self: type(self)({key: -value for key, value
108+
in self.iteritems()})
100109

101110
# Multiset-style mathematical operations discussed in:
102111
# Knuth TAOCP Volume II section 4.6.3 exercise 19

source_py2/test_python_toolbox/test_nifty_collections/test_lazy_tuple/test_frozen_counter.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def test():
5757
frozen_counter & frozen_counter & frozen_counter == \
5858
frozen_counter
5959

60+
assert +frozen_counter == frozen_counter
61+
assert ---frozen_counter == -frozen_counter != \
62+
frozen_counter == --frozen_counter
63+
6064
assert FrozenCounter(frozen_counter.elements()) == frozen_counter
6165

6266
assert repr(frozen_counter).startswith('FrozenCounter(')

source_py3/python_toolbox/nifty_collections/frozen_counter.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88

99
from .frozen_dict import FrozenDict
1010

11+
try: # Load C helper function if available
12+
from _collections import _count_elements
13+
except ImportError:
14+
def _count_elements(mapping, iterable):
15+
'''Tally elements from the iterable.'''
16+
mapping_get = mapping.get
17+
for element in iterable:
18+
mapping[element] = mapping_get(element, 0) + 1
19+
1120

1221
class FrozenCounter(FrozenDict):
1322
'''
@@ -22,15 +31,13 @@ class FrozenCounter(FrozenDict):
2231
'''
2332

2433
def __init__(self, iterable=None, **kwargs):
25-
super(FrozenCounter, self).__init__()
34+
super().__init__()
2635

2736
if iterable is not None:
2837
if isinstance(iterable, collections.Mapping):
2938
self._dict.update(iterable)
3039
else:
31-
self_get = self._dict.get
32-
for element in iterable:
33-
self._dict[element] = self_get(element, 0) + 1
40+
_count_elements(self._dict, iterable)
3441
if kwargs:
3542
self._dict.update(kwargs)
3643

@@ -95,8 +102,17 @@ def fromkeys(cls, iterable, v=None):
95102
def __repr__(self):
96103
if not self:
97104
return '%s()' % self.__class__.__name__
98-
items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
99-
return '%s({%s})' % (self.__class__.__name__, items)
105+
try:
106+
items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
107+
return '%s({%s})' % (self.__class__.__name__, items)
108+
except TypeError:
109+
# handle case where values are not orderable
110+
return '{0}({1!r})'.format(self.__class__.__name__, dict(self))
111+
112+
113+
__pos__ = lambda self: self
114+
__neg__ = lambda self: type(self)({key: -value for key, value
115+
in self.items()})
100116

101117
# Multiset-style mathematical operations discussed in:
102118
# Knuth TAOCP Volume II section 4.6.3 exercise 19

source_py3/test_python_toolbox/test_nifty_collections/test_lazy_tuple/test_frozen_counter.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,8 @@ def test():
5757

5858
assert FrozenCounter(frozen_counter.elements()) == frozen_counter
5959

60+
assert +frozen_counter == frozen_counter
61+
assert ---frozen_counter == -frozen_counter != \
62+
frozen_counter == --frozen_counter
63+
6064
assert repr(frozen_counter).startswith('FrozenCounter(')

0 commit comments

Comments
 (0)