Skip to content

Everyday pocket-sized Python functions for you to copy or import.

License

Notifications You must be signed in to change notification settings

dmyersturnbull/pocketutils

Repository files navigation

pocketutils

Version status License Python version compatibility Version on Docker Hub Version on Github Version on PyPi Build (Actions) Documentation status Coverage (coveralls) Maintainability (Code Climate) Scrutinizer Code Quality

Adorable little Python functions for you to copy or import, Apache-licensed.

pip install pocketutils[compression,encoding,formats,units,misc]

Basic usage

import sys
from datetime import timedelta
from pocketutils import Tools, SmartIo, FrozeList, FrozeSet, FrozeDict

my_dict = FrozeDict({"5": "10"})
hash(my_dict)
assert my_dict == my_dict
assert not (my_dict < my_dict)  # orderable!
inside_a_set = {my_dict}  # hashable!

SmartIo.read_bytes("compressed.xz")  # infers compress by filename extension
data = SmartIo.read_text("text.zst")  # zstd, lz4, brotli, snappy, xz, ...
SmartIo.write(data, "compressed.zst", atomic=True)  # atomic requires it to finish

Tools.zip_strict([1, 2, 3], [5, 6])  # error <-- lengths must match
Tools.strip_brackets("( (xy)")  # "(xy" <-- strips paired only
Tools.sanitize_path("x\ty")  # "xy"  <-- very robust cross-platform sanitization
Tools.delete_surefire("my_file")  # <-- Attempts to fix permissions if needed
Tools.git_description("my_repo")  # <-- get git repo info
Tools.pretty_function(lambda s: None)  # "<λ(1)> <-- decent name for any object
Tools.roman_to_arabic("XIV")  # 14  <-- inverse function too
Tools.pretty_timedelta(delta_sec=timedelta(seconds=60 * 2 + 5))  # "02:05"  <-- handles days too
Tools.round_to_sigfigs(135.3, 2)  # "140"  <-- rounding to sigfigs
Tools.pretty_float(-float("-inf"))  # "−∞"  <-- proper unicode, no trailing 0s
Tools.stream_cmd_call(["cat", "big-file"])  # <-- buffer never fills
Tools.strip_quotes("'hello'")  # "hello"
Tools.truncate("looong string", n=10)  # "looong st…"
Tools.parse_bool("true")  # True
Tools.parse_bool_flex("yes")  # True
Tools.look(item, "purchase.buyer.first_name")  # None if purchase or buyer is None
Tools.friendly_size(n_bytes=2 * 14)  # "16.38 kb"
Tools.is_probable_null("NaN")  # True
Tools.is_true_iterable("kitten")  # False
Tools.or_null(lambda: None)  # None if it fails
Tools.trash("unwanted_file.txt")  # move to os-specific trash
Tools.pretty_dict({"contents": {"greeting": "hi"}})  # indented
Tools.save_diagnostics(Tools.get_env_info())  # record diagnostic info
Tools.is_lambda(lambda: None)  # True
Tools.longest(["a", "a+b"])  # "a+b"  # anything with len
Tools.only([1, 2])  # error -- multiple items
Tools.first(iter([]))  # None <-- better than try: next(iter(x)) except:...
Tools.trace_signals(sink=sys.stderr)  # log traceback on all signals
Tools.trace_exit(sink=sys.stderr)  # log traceback on exit
Tools.required_args(lambda a, b, c: None)  # reflection
# lots of others

Better yet, import specific sets of tools; e.g.:

from pocketutils import FilesysTools

FilesysTools.delete_surefire("bad-path")

See the docs 📚, or just browse the code. New issues and pull requests are welcome. Please refer to the contributing guide and security policy. Generated with tyrannosaurus: tyrannosaurus new tyrannosaurus