Skip to content

Commit 47cafc8

Browse files
committed
ch11-24: clean up by @eumiro & sync with Atlas
1 parent 03ace4f commit 47cafc8

File tree

143 files changed

+21690
-61
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+21690
-61
lines changed

11-pythonic-obj/private/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.class
2+
.jython_cache/

13-protocol-abc/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Sample code for Chapter 11 - "Interfaces, protocols and ABCs"
2+
3+
From the book "Fluent Python" by Luciano Ramalho (O'Reilly, 2015)
4+
http://shop.oreilly.com/product/0636920032519.do

13-protocol-abc/bingo.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# tag::TOMBOLA_BINGO[]
2+
3+
import random
4+
5+
from tombola import Tombola
6+
7+
8+
class BingoCage(Tombola): # <1>
9+
10+
def __init__(self, items):
11+
self._randomizer = random.SystemRandom() # <2>
12+
self._items = []
13+
self.load(items) # <3>
14+
15+
def load(self, items):
16+
self._items.extend(items)
17+
self._randomizer.shuffle(self._items) # <4>
18+
19+
def pick(self): # <5>
20+
try:
21+
return self._items.pop()
22+
except IndexError:
23+
raise LookupError('pick from empty BingoCage')
24+
25+
def __call__(self): # <6>
26+
self.pick()
27+
28+
# end::TOMBOLA_BINGO[]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def double(x: object) -> object:
2+
return x * 2
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import TypeVar, Protocol
2+
3+
T = TypeVar('T') # <1>
4+
5+
class Repeatable(Protocol):
6+
def __mul__(self: T, repeat_count: int) -> T: ... # <2>
7+
8+
RT = TypeVar('RT', bound=Repeatable) # <3>
9+
10+
def double(x: RT) -> RT: # <4>
11+
return x * 2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from collections import abc
2+
from typing import Any
3+
4+
def double(x: abc.Sequence) -> Any:
5+
return x * 2
6+

13-protocol-abc/double/double_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from typing import TYPE_CHECKING
2+
import pytest
3+
from double_protocol import double
4+
5+
def test_double_int() -> None:
6+
given = 2
7+
result = double(given)
8+
assert result == given * 2
9+
if TYPE_CHECKING:
10+
reveal_type(given)
11+
reveal_type(result)
12+
13+
14+
def test_double_str() -> None:
15+
given = 'A'
16+
result = double(given)
17+
assert result == given * 2
18+
if TYPE_CHECKING:
19+
reveal_type(given)
20+
reveal_type(result)
21+
22+
23+
def test_double_fraction() -> None:
24+
from fractions import Fraction
25+
given = Fraction(2, 5)
26+
result = double(given)
27+
assert result == given * 2
28+
if TYPE_CHECKING:
29+
reveal_type(given)
30+
reveal_type(result)
31+
32+
33+
def test_double_array() -> None:
34+
from array import array
35+
given = array('d', [1.0, 2.0, 3.14])
36+
result = double(given)
37+
if TYPE_CHECKING:
38+
reveal_type(given)
39+
reveal_type(result)
40+
41+
42+
def test_double_nparray() -> None:
43+
import numpy as np # type: ignore
44+
given = np.array([[1, 2], [3, 4]])
45+
result = double(given)
46+
comparison = result == given * 2
47+
assert comparison.all()
48+
if TYPE_CHECKING:
49+
reveal_type(given)
50+
reveal_type(result)
51+
52+
53+
def test_double_none() -> None:
54+
given = None
55+
with pytest.raises(TypeError):
56+
result = double(given)

13-protocol-abc/drum.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from random import shuffle
2+
3+
from tombola import Tombola
4+
5+
6+
class TumblingDrum(Tombola):
7+
8+
def __init__(self, iterable):
9+
self._balls = []
10+
self.load(iterable)
11+
12+
def load(self, iterable):
13+
self._balls.extend(iterable)
14+
shuffle(self._balls)
15+
16+
def pick(self):
17+
return self._balls.pop()

13-protocol-abc/frenchdeck2.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import collections
2+
3+
Card = collections.namedtuple('Card', ['rank', 'suit'])
4+
5+
class FrenchDeck2(collections.MutableSequence):
6+
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
7+
suits = 'spades diamonds clubs hearts'.split()
8+
9+
def __init__(self):
10+
self._cards = [Card(rank, suit) for suit in self.suits
11+
for rank in self.ranks]
12+
13+
def __len__(self):
14+
return len(self._cards)
15+
16+
def __getitem__(self, position):
17+
return self._cards[position]
18+
19+
def __setitem__(self, position, value): # <1>
20+
self._cards[position] = value
21+
22+
def __delitem__(self, position): # <2>
23+
del self._cards[position]
24+
25+
def insert(self, position, value): # <3>
26+
self._cards.insert(position, value)

13-protocol-abc/lotto.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# tag::LOTTERY_BLOWER[]
2+
3+
import random
4+
5+
from tombola import Tombola
6+
7+
8+
class LotteryBlower(Tombola):
9+
10+
def __init__(self, iterable):
11+
self._balls = list(iterable) # <1>
12+
13+
def load(self, iterable):
14+
self._balls.extend(iterable)
15+
16+
def pick(self):
17+
try:
18+
position = random.randrange(len(self._balls)) # <2>
19+
except ValueError:
20+
raise LookupError('pick from empty BingoCage')
21+
return self._balls.pop(position) # <3>
22+
23+
def loaded(self): # <4>
24+
return bool(self._balls)
25+
26+
def inspect(self): # <5>
27+
return tuple(sorted(self._balls))
28+
29+
30+
# end::LOTTERY_BLOWER[]

0 commit comments

Comments
 (0)