Skip to content
cpwillisPublic

About

A collection of utilities, scripts, and code snippets that are too small to warrant their own repository.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tools

Snippets I keep re-copying between projects: a Jinja extension, two Python decorators, a shell helper, an editor config. Nothing here is a package. Copy the file or the block you want into your own tree. No install, no build, no tests.

Python

Jinja extension that wraps each rendered template in start/end comments naming the source file, so view-source tells you which template produced which chunk of output.

.html.j2 gets <!-- TEMPLATE START: name -->, .css.j2 and .js.j2 get /* ... */, anything else passes through untouched. It writes comments into rendered output, so gate it behind a dev-only flag.

from jinja2 import Environment
from wrap_templates_extension import WrapTemplatesWithNames

env = Environment(loader=..., extensions=[WrapTemplatesWithNames])
# or on an env you already have: env.add_extension(WrapTemplatesWithNames)

@profileme runs the function under cProfile and writes sorted stats to <module>.<function>.profile, beside the file that defines the function (not the one being run).

@profileme
def slow(): ...

@profileme(directory="./profiles", sortby="tottime")
def also_slow(): ...

directory must already exist, otherwise ValueError on the first call. sortby is any pstats sort key, default cumulative. Every call rewrites the file.

@log_start_end logs one line either side of a Click command.

Not runnable as pasted. xxx is a placeholder: point from xxx.log import get_logger at your own logger, and replace the Blueprint("xxx", __name__) line with the blueprint the command really lives on. As written the blueprint is constructed inside the decorator, so the name it logs is always the literal xxx.

Abbreviate large numbers

No file for this one, copy the block. Only "clean" round numbers abbreviate: 2000000 becomes 2m, but 1500 stays 1,500 and 1500000 comes out as 1500k. Zero returns the string "None".

def format_abbreviated_number(value: int) -> str:
    """
    Convert a number to a human-readable string:
    - Abbreviates clean round numbers in thousands (k), millions (m), billions (b), etc.
    - Uses comma formatting for numbers with variations or smaller values.
    - Returns the original value if it's not an integer or cannot be converted to one.
    - Returns "None" if the value is zero.
    """

    # Check if the value is an integer
    if not isinstance(value, int):
        return str(value)

    # Check if the value is zero
    if value == 0:
        return "None"

    # Check if a number is followed by all zeros
    # Without this the modulus check mis-abbreviates eg 10022000 as 10022k instead of
    # 10,022,000 (it is incorrectly divisible by 1000).
    def is_clean_multiple(value):
        return value % 10 ** len(str(value).rstrip("0")) == 0

    # Check for clean multiples and abbreviate them
    if is_clean_multiple(value):
        if value % 1_000_000_000_000_000 == 0:
            return f"{value // 1_000_000_000_000_000}q"  # Quadrillion
        elif value % 1_000_000_000_000 == 0:
            return f"{value // 1_000_000_000_000}t"  # Trillion
        elif value % 1_000_000_000 == 0:
            return f"{value // 1_000_000_000}b"  # Billion
        elif value % 1_000_000 == 0:
            return f"{value // 1_000_000}m"  # Million
        elif value % 1_000 == 0:
            return f"{value // 1_000}k"  # Thousand

    # If the number is not a clean multiple, return the full value with commas
    return f"{value:,.0f}"

Shell

Source it, then cecho "msg" "$colour". Defines black red green yellow blue magenta cyan white and reset.

source shell/colour_echo.sh
cecho "I'm an example." "$red"

Needs $TERM set. Without it tput complains on stderr and the colour variables come out empty; the text still prints, just uncoloured.

VSCode

Keyword colours for TODO Highlight, covering TODO, FIXME, BUG, NOTE and MISC. Paste it into your VS Code settings.json: the file is a single settings key, not a standalone JSON document, so it will not parse on its own. Reference colours.

About

A collection of utilities, scripts, and code snippets that are too small to warrant their own repository.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages