complete draft: update from Atlas

This commit is contained in:
Luciano Ramalho
2021-06-09 00:13:02 -03:00
parent 08a4001b43
commit 135eca25d9
43 changed files with 4705 additions and 3240 deletions

View File

@@ -0,0 +1,29 @@
import random
from collections.abc import Iterable
from typing import TypeVar, Generic
from tombola import Tombola
T = TypeVar('T')
class LottoBlower(Tombola, Generic[T]): # <1>
def __init__(self, items: Iterable[T]) -> None: # <2>
self._balls = list[T](items)
def load(self, items: Iterable[T]) -> None: # <3>
self._balls.extend(items)
def pick(self) -> T: # <4>
try:
position = random.randrange(len(self._balls))
except ValueError:
raise LookupError('pick from empty LottoBlower')
return self._balls.pop(position)
def loaded(self) -> bool: # <5>
return bool(self._balls)
def inspect(self) -> tuple[T, ...]: # <6>
return tuple(self._balls)

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python3
from typing import TYPE_CHECKING
# tag::LOTTO_USE[]
from generic_lotto import LottoBlower
machine = LottoBlower[int](range(1, 11)) # <1>
first = machine.pick() # <2>
remain = machine.inspect() # <3>
# end::LOTTO_USE[]
expected = set(i for i in range(1, 11) if i != first)
assert set(remain) == expected
print('picked:', first)
print('remain:', remain)
if TYPE_CHECKING:
reveal_type(first)
# Revealed type is 'builtins.int*'
if TYPE_CHECKING:
reveal_type(remain)
# Revealed type is 'builtins.tuple[builtins.int*]'

View File

@@ -0,0 +1,18 @@
from generic_lotto import LottoBlower
machine = LottoBlower[int]([1, .2])
## error: List item 1 has incompatible type "float"; # <1>
## expected "int"
machine = LottoBlower[int](range(1, 11))
machine.load('ABC')
## error: Argument 1 to "load" of "LottoBlower" # <2>
## has incompatible type "str";
## expected "Iterable[int]"
## note: Following member(s) of "str" have conflicts:
## note: Expected:
## note: def __iter__(self) -> Iterator[int]
## note: Got:
## note: def __iter__(self) -> Iterator[str]

View File

@@ -0,0 +1,34 @@
# tag::TOMBOLA_ABC[]
import abc
class Tombola(abc.ABC): # <1>
@abc.abstractmethod
def load(self, iterable): # <2>
"""Add items from an iterable."""
@abc.abstractmethod
def pick(self): # <3>
"""Remove item at random, returning it.
This method should raise `LookupError` when the instance is empty.
"""
def loaded(self): # <4>
"""Return `True` if there's at least 1 item, `False` otherwise."""
return bool(self.inspect()) # <5>
def inspect(self):
"""Return a sorted tuple with the items currently inside."""
items = []
while True: # <6>
try:
items.append(self.pick())
except LookupError:
break
self.load(items) # <7>
return tuple(items)
# end::TOMBOLA_ABC[]