Skip to content

Commit b38e6fc

Browse files
committed
sync to Atlas repo
1 parent 2f49562 commit b38e6fc

File tree

7 files changed

+71
-42
lines changed

7 files changed

+71
-42
lines changed

dicts/strkeydict.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
"""StrKeyDict always converts non-string keys to `str`
22
3+
Test for initializer: keys are converted to `str`.
4+
5+
>>> d = StrKeyDict([(2, 'two'), ('4', 'four')])
6+
>>> sorted(d.keys())
7+
['2', '4']
8+
39
Tests for item retrieval using `d[key]` notation::
410
5-
>>> d = StrKeyDict([('2', 'two'), ('4', 'four')])
611
>>> d['2']
712
'two'
813
>>> d[4]
@@ -12,6 +17,15 @@
1217
...
1318
KeyError: '1'
1419
20+
Tests for item retrieval using `d.get(key)` notation::
21+
22+
>>> d.get('2')
23+
'two'
24+
>>> d.get(4)
25+
'four'
26+
>>> d.get(1, 'N/A')
27+
'N/A'
28+
1529
Tests for the `in` operator::
1630
1731
>>> 2 in d

dicts/strkeydict0.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
...
1515
KeyError: '1'
1616
17+
Tests for item retrieval using `d.get(key)` notation::
18+
19+
>>> d.get('2')
20+
'two'
21+
>>> d.get(4)
22+
'four'
23+
>>> d.get(1, 'N/A')
24+
'N/A'
25+
26+
1727
Tests for the `in` operator::
1828
1929
>>> 2 in d
@@ -24,16 +34,22 @@
2434
# END STRKEYDICT0_TESTS
2535
"""
2636

27-
# BEGIN STRKEYDICT0
2837

38+
# BEGIN STRKEYDICT0
2939
class StrKeyDict0(dict): # <1>
3040

3141
def __missing__(self, key):
3242
if isinstance(key, str): # <2>
3343
raise KeyError(key)
3444
return self[str(key)] # <3>
3545

46+
def get(self, key, default=None):
47+
try:
48+
return self[key] # <4>
49+
except KeyError:
50+
return default # <5>
51+
3652
def __contains__(self, key):
37-
return key in self.keys() or str(key) in self.keys() # <4>
53+
return key in self.keys() or str(key) in self.keys() # <6>
3854

39-
# END STRKEYDICT0
55+
# END STRKEYDICT0

interfaces/tombola.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
from abc import ABC, abstractmethod
1+
import abc
22

3+
class Tombola(abc.ABC): # <1>
34

4-
class Tombola(ABC): # <1>
5-
6-
@abstractmethod
7-
def __init__(self, iterable): # <2>
8-
"""New instance is loaded from an iterable."""
9-
10-
@abstractmethod
11-
def load(self, iterable):
5+
@abc.abstractmethod
6+
def load(self, iterable): # <2>
127
"""Add items from an iterable."""
138

14-
@abstractmethod
9+
@abc.abstractmethod
1510
def pick(self): # <3>
1611
"""Remove item at random, returning it.
1712

interfaces/tombola_runner.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
import sys
2-
import importlib
1+
# BEGIN TOMBOLA_RUNNER
32
import doctest
43

54
from tombola import Tombola
65

6+
# modules to test
7+
import bingo, lotto, tombolist, drum # <1>
8+
79
TEST_FILE = 'tombola_tests.rst'
8-
MODULE_NAMES = 'bingo lotto tombolist drum'.split()
910
TEST_MSG = '{0:16} {1.attempted:2} tests, {1.failed:2} failed - {2}'
1011

1112

12-
def test(cls, verbose=False):
13-
14-
res = doctest.testfile(TEST_FILE,
15-
globs={'TombolaUnderTest': cls},
16-
verbose=verbose,
17-
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
18-
tag = 'FAIL' if res.failed else 'OK'
19-
print(TEST_MSG.format(cls.__name__, res, tag))
13+
def main(argv):
14+
verbose = '-v' in argv
15+
real_subclasses = Tombola.__subclasses__() # <2>
16+
virtual_subclasses = list(Tombola._abc_registry) # <3>
2017

18+
for cls in real_subclasses + virtual_subclasses: # <4>
19+
test(cls, verbose)
2120

22-
if __name__ == '__main__':
2321

24-
for name in MODULE_NAMES: # import modules to test, by name
25-
importlib.import_module(name)
22+
def test(cls, verbose=False):
2623

27-
verbose = '-v' in sys.argv
24+
res = doctest.testfile(
25+
TEST_FILE,
26+
globs={'ConcreteTombola': cls}, # <5>
27+
verbose=verbose,
28+
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
29+
tag = 'FAIL' if res.failed else 'OK'
30+
print(TEST_MSG.format(cls.__name__, res, tag)) # <6>
2831

29-
real_subclasses = Tombola.__subclasses__()
30-
virtual_subclasses = list(Tombola._abc_registry)
3132

32-
for cls in real_subclasses + virtual_subclasses:
33-
test(cls, verbose)
33+
if __name__ == '__main__':
34+
import sys
35+
main(sys.argv)
36+
# END TOMBOLA_RUNNER

interfaces/tombola_tests.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Every concrete subclass of Tombola should pass these tests.
88
Create and load instance from iterable::
99

1010
>>> balls = list(range(3))
11-
>>> globe = TombolaUnderTest(balls)
11+
>>> globe = ConcreteTombola(balls)
1212
>>> globe.loaded()
1313
True
1414

@@ -42,7 +42,7 @@ Reload::
4242
Check that `LookupError` (or a subclass) is the exception
4343
thrown when the device is empty::
4444

45-
>>> globe = TombolaUnderTest([])
45+
>>> globe = ConcreteTombola([])
4646
>>> try:
4747
... globe.pick()
4848
... except LookupError as exc:
@@ -53,7 +53,7 @@ thrown when the device is empty::
5353
Load and pick 100 balls to verify that they are all come out::
5454

5555
>>> balls = list(range(100))
56-
>>> globe = TombolaUnderTest(balls)
56+
>>> globe = ConcreteTombola(balls)
5757
>>> picks = []
5858
>>> while globe.loaded():
5959
... picks.append(globe.pick())
@@ -75,3 +75,6 @@ even if the implementation is OK. The probability of the 100
7575
balls coming out, by chance, in the order they were loaded is
7676
1/100!, or approximately 1.07e-158. It's much easier to win the
7777
Lotto or to become a billionaire working as a programmer.
78+
79+
THE END
80+

interfaces/tombolist.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@ def load(self, iterable): self.extend(iterable) # <5>
1616

1717
def loaded(self): return bool(self) # <6>
1818

19-
"""
20-
Tombola.register(TomboList) # <- Python 3.2 or earlier
21-
"""
19+
# Tombola.register(TomboList) # <- Python 3.2 or earlier

sequences/sentence.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ class Sentence:
1212

1313
def __init__(self, text):
1414
self.text = text
15-
self.words = RE_WORD.findall(text) #<1>
15+
self.words = RE_WORD.findall(text) # <1>
1616

1717
def __getitem__(self, index):
18-
return self.words[index] #<2>
18+
return self.words[index] # <2>
1919

2020
def __repr__(self):
21-
return 'Sentence(%s)' % reprlib.repr(self.text) #<3>
21+
return 'Sentence(%s)' % reprlib.repr(self.text) # <3>

0 commit comments

Comments
 (0)