Skip to content

Instantly share code, notes, and snippets.

Avatar

Malcolm Greaves malcolmgreaves

View GitHub Profile
@malcolmgreaves
malcolmgreaves / exit_code_preseving_trap_and_access.sh
Created Apr 26, 2022
A bash script showing how to set up an exit trap that (1) preserves the exit code of the trap's trigger and (2) allows you to inspect the trigger's exit code within the trap.
View exit_code_preseving_trap_and_access.sh
#!/usr/bin/env bash
cleanup() {
E=$?
trap 'exit 0' EXIT
echo "cleanup, E=$E"
}
echo 'setting'
@malcolmgreaves
malcolmgreaves / get_args_improved.py
Created Apr 19, 2022
Allows one to obtain all concrete generic type arguments for any Python type.
View get_args_improved.py
from typing import List, Sequence, get_args
def get_args_all(t: type) -> List[type]:
all_args: List[type] = []
all_args.extend(get_args(t))
try:
orig_bases = t.__orig_bases__
except AttributeError:
pass
@malcolmgreaves
malcolmgreaves / access_dict_recursively.py
Created Mar 8, 2022
Function to support recursively accessing key-value pairs from a nested dictionary.
View access_dict_recursively.py
from typing import Any, Dict, Optional
def access(d: Dict[str, Any], *keys) -> Optional[Any]:
return reduce(dict.get, keys, d)
#
# Use as:
# >>>> access({"hello": {"world": {"how": "are you today?"}}}, "hello")
@malcolmgreaves
malcolmgreaves / celery_task_handling_failure.py
Created Mar 5, 2022
Example showing how to add setting of custom state with Celery Tasks that have status="FAILURE".
View celery_task_handling_failure.py
import json
from typing import Any, Dict
from celery import Task, states
def raw_celery_response(backend, task_id: str) -> Dict[str, Any]:
key_info: str = backend.get_key_for_task(task_id)
info_as_str: str = backend.get(key_info)
info: dict = json.loads(info_as_str)
@malcolmgreaves
malcolmgreaves / deprecation_warning_log.py
Created Feb 14, 2022
Convenience function for a deprecation warning. Logs a message both as a warning as well as using the `warnings` package's `DeprecationWarning`.
View deprecation_warning_log.py
import logging
import warnings
def deprecation_warning(logger: logging.Logger, msg: str) -> None:
"""Creates a deprecation warning log event with given the message and logger.
Convenience function for a deprecation warning. Logs a message both as a warning
as well as using the `warnings` package's `DeprecationWarning`.
"""
@malcolmgreaves
malcolmgreaves / env_var_context.py
Created Feb 9, 2022
A context manager for temporarily setting environment variables. Handles resetting all env vars to their previous values.
View env_var_context.py
import os
from typing import ContextManager, Dict, Optional, Union
class environment(ContextManager):
"""Context manager for temporarily setting environment variables. Resets env var state on completion.
**WARNING**: Mutates the `os.environ` environment variable mapping in the :func:`__enter__`
and :func:`__exit__` methods. Every `__enter__` **MUST** be followed-up by an `__exit__`.
@malcolmgreaves
malcolmgreaves / git_init_default_branch_warning.sh
Created Feb 8, 2022
Great example of how to introduce changes in convention.
View git_init_default_branch_warning.sh
$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
@malcolmgreaves
malcolmgreaves / clip_number.py
Last active Feb 5, 2022
Generic number clipping function. Works with mypy type annotations.
View clip_number.py
from numbers import Number
from typing import TypeVar
N = TypeVar("N", bound=Number)
"""A number; e.g. either float or int.
"""
def clip(value: N, minimum: N, maximum: N) -> N:
@malcolmgreaves
malcolmgreaves / re_sort.py
Created Jan 21, 2022
Re-sort any list given a list of new index positions.
View re_sort.py
from typing import TypeVar
from toolz import first, second
T = TypeVar('T')
def align(new_positions: List[int], items: List[T]) -> List[T]:
"""Re-sort any list given a list of new index positions.
@malcolmgreaves
malcolmgreaves / torch_model_cmp.py
Last active Dec 8, 2021
Compare two `torch.nn.module` instances together, yielding a list of mismatched layers.
View torch_model_cmp.py
from dataclasses import dataclass
from typing import Optional, Iterator, Collection, Dict
import torch
@dataclass(frozen=True)
class Mismatch:
message: str
err: Optional[Exception] = None