Skip to content

Instantly share code, notes, and snippets.

@xflr6
xflr6 / iso639p3.py
Last active August 16, 2022 19:44
Download and parse ISO 639-3 code tables from sil.org
"""Download and parse ISO 639-3 code tables from https://www.sil.org."""
from __future__ import annotations
from collections.abc import Iterable, Iterator, Mapping
import contextlib
import csv
import enum
import fnmatch
import functools
@xflr6
xflr6 / urlretrieve.py
Last active June 20, 2023 15:11
Replacement for urllib.urlretrieve(url, filename) using the requests library
"""Implement `urllib.urlretrieve(url, filename)` with requests library."""
import contextlib
import os
import urllib
import requests
def urlretrieve(url: str,
@xflr6
xflr6 / ethnologue.py
Last active August 16, 2022 19:44
Download and parse ethnologue.com language code tables
"""Download and parse https://www.ethnologue.com code files."""
from __future__ import annotations
from collections.abc import Iterable, Iterator, Mapping
import contextlib
import csv
import enum
import fnmatch
import functools
@xflr6
xflr6 / common_prefix.py
Last active December 22, 2021 23:43
Case-insensitive longest common prefix of two strings
"""Longest common prefix."""
import itertools
def common_prefix(left: str, right: str) -> str:
"""Return the case-insensitive longest common prefix of two strings.
>>> common_prefix('spam', 'spameggs')
'spam'
@xflr6
xflr6 / pearsonr.py
Last active June 4, 2022 15:32
Pure Python replacement for scipy.stats.pearsonr
"""Pure-python replacement for scipy.stats.pearsonr."""
from collections.abc import Sequence
import itertools
import math
import operator
def pearsonr(X: Sequence[int], Y: Sequence[int]) -> float:
"""Return the correlation coefficient between the variable sequences X and Y.
@xflr6
xflr6 / sedlike.py
Last active June 4, 2022 09:33
Make Python regex search/replace functions from sed-like s/old/new/g strings
"""Search/replace func from string roughly like 'sed -r s/old/new/g'."""
from collections.abc import Callable
import functools
def search_replace(cmd: str, *, _cache={}) -> Callable[[str], str]:
"""Return a callable from sed/Perl-style search-replace pattern string.
>>> search_replace('s/ham/spam/g')('ham-eggs-ham')
@xflr6
xflr6 / replace.py
Last active June 4, 2022 09:29
Apply multiple search-replace rules to a string with a combined regex
"""Apply search-replace rules with re."""
from collections.abc import Iterable
import re
class Replace:
"""Multiple search-replace with first-matching regex."""
def __init__(self, pairs: Iterable[tuple[str, str]]) -> None:
@xflr6
xflr6 / ordered.py
Last active June 4, 2022 09:26
Iterate over dictionaries with variable keys in predefined order
"""Iterate over dicts with variable keys in predefined order."""
from __future__ import annotations
from collections.abc import Iterable
class KeyOrder(dict):
"""Key -> index mapping for iterating over dicts (unknown keys last)."""
@xflr6
xflr6 / memorymapped.py
Last active June 4, 2022 18:12
More convenient context manager for mmap.mmap
"""More convenient context manager for mmap.mmap."""
from collections.abc import Iterator
import contextlib
import mmap
import os
@contextlib.contextmanager
def memorymapped_compat(path: os.PathLike | str) -> Iterator[mmap.mmap]:
@xflr6
xflr6 / subclasses.py
Last active June 4, 2022 10:54
Find all subclasses of a given class
"""Find all subclasses of a class with queue or stack."""
import collections
from collections.abc import Collection, Iterator
def itersubclasses(parent: type, *,
proper: bool = True,
exclude: Collection[type] = (type,)) -> Iterator[type]:
"""Yield `parent` subclasses recursively in breadth-first order."""