'1 day, and 10 minutes'
"""
- return describe_duration(delta.total_seconds())
+ return describe_duration(int(delta.total_seconds())) # Note: drops milliseconds
def describe_duration_briefly(seconds: int, *, include_seconds=False) -> str:
'1d 10m'
"""
- return describe_duration_briefly(delta.total_seconds())
+ return describe_duration_briefly(
+ int(delta.total_seconds())
+ ) # Note: drops milliseconds
if __name__ == '__main__':
return lst
-def population_counts(lst: List[Any]) -> Mapping[Any, int]:
+def population_counts(lst: List[Any]) -> Counter:
"""
Return a population count mapping for the list (i.e. the keys are
list items and the values are the number of occurrances of that
yield lst[i : i + n]
-def permute(seq: Sequence[Any]):
+def permute(seq: str):
"""
- Returns all permutations of a sequence; takes O(N^2) time.
+ Returns all permutations of a sequence; takes O(N!) time.
>>> for x in permute('cat'):
... print(x)
yield from _permute(seq, "")
-def _permute(seq: Sequence[Any], path):
- if len(seq) == 0:
+def _permute(seq: str, path: str):
+ seq_len = len(seq)
+ if seq_len == 0:
yield path
- for i in range(len(seq)):
+ for i in range(seq_len):
car = seq[i]
left = seq[0:i]
right = seq[i + 1 :]
"""
import base64
-import contextlib
+import contextlib # type: ignore
import datetime
import io
from itertools import zip_longest
def __init__(self) -> None:
self.destination = io.StringIO()
- self.recorder = None
+ self.recorder: contextlib.redirect_stdout
def __enter__(self) -> Callable[[], str]:
self.recorder = contextlib.redirect_stdout(self.destination)
def shuffle_columns_into_list(
- input_lines: Iterable[str], column_specs: Iterable[Iterable[int]], delim=''
+ input_lines: Sequence[str], column_specs: Iterable[Iterable[int]], delim=''
) -> Iterable[str]:
"""Helper to shuffle / parse columnar data and return the results as a
list. The column_specs argument is an iterable collection of
def shuffle_columns_into_dict(
- input_lines: Iterable[str],
+ input_lines: Sequence[str],
column_specs: Iterable[Tuple[str, Iterable[int]]],
delim='',
) -> Dict[str, str]:
raise Exception('to_ascii works with strings and bytes')
-def to_base64(txt: str, *, encoding='utf-8', errors='surrogatepass') -> str:
+def to_base64(txt: str, *, encoding='utf-8', errors='surrogatepass') -> bytes:
"""Encode txt and then encode the bytes with a 64-character
alphabet. This is compatible with uudecode.
return True
-def from_base64(b64: str, encoding='utf-8', errors='surrogatepass') -> str:
+def from_base64(b64: bytes, encoding='utf-8', errors='surrogatepass') -> str:
"""Convert base64 encoded string back to normal strings.
>>> from_base64(b'aGVsbG8/\\n')
return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode(encoding, errors) or '\0'
-def ip_v4_sort_key(txt: str) -> Tuple[int]:
+def ip_v4_sort_key(txt: str) -> Optional[Tuple[int, ...]]:
"""Turn an IPv4 address into a tuple for sorting purposes.
>>> ip_v4_sort_key('10.0.0.18')
return tuple([int(x) for x in txt.split('.')])
-def path_ancestors_before_descendants_sort_key(volume: str) -> Tuple[str]:
+def path_ancestors_before_descendants_sort_key(volume: str) -> Tuple[str, ...]:
"""Chunk up a file path so that parent/ancestor paths sort before
children/descendant paths.