An aggregated feed of all of my posts

616 posts latest post 2026-10-06
Publishing rhythm
Jun 2026 | 3 posts

Unpacking iterables in python with * is a pretty handy trick for writing code that is just a tiny bit more pythonic than not.

arr: Tuple[Union[int, str]] = (1, 2, 3, 'a', 'b', 'c')


print(arr)
>>> (1, 2, 3, 'a', 'b', 'c')

# the * unpacks the tuple into the individual elements
print(*arr)
>>> 1, 2, 3, 'a', 'b', 'c'

x, y, z, *alphas = arr

# x = 1, y = 2, z = 3
# alphas = [ 'a', 'b', 'c' ]

But @Ned Batchelder showed me via Twitter than you can arbitrarily unpack arguments based on position - it doesn’t have to be done at the beginning or the end!

x, y, *mixed, alpha = arr

# x = 1, y = 2
# mixed = [3, 'a', 'b']
# alpha = 'c'

I’m not entirely sure when I’ll need this but it definitley shows me another example of how flexible python is!

htop is a common command line tool for seeing interactive output of your system resource utilization, running processes, etc.

I’ve always been super confused about htop showing seemingly the same process several times though…

The Fix… #

Just hit H…. makes the view a lot nicer 😀

Pipx

is a tool I’ve been using to solve a few problems of mine… pinning formatting tools like,,, etc. to the same version for all my projects keeping virtual environments clean of things like python utilities I want system wide but not in the global environment, like What is it? # itself is just a package manager like,, etc. But it is tied to a python environment. If you aren’t using a virtual environment then will operate inside the global installation of python. Operating within that environment has burned me several times and now I have a strict virtual environment usage policy. But there are still things I don’t want to have to put in every virtual environment - enter What’s it do? # When you a stand alone virtual environment gets created (by default in). THen you can install extra dependencies with ex. After in order to open Excel files you need to In the example with, I can then use it anywhere, in any project, without re-installing with in every env. Also for the formatting tools - I…

fx is an interactaive JSON viewer for the terminal.

It’s a simple tool built with Charmcli’s Bubble Tea.

Installation #

The installation with go was broken for me - both via the link and direct from the repo. Now I’m not a gopher so I don’t really know how to fix that.

Luckily npm install fx also works and got me what I needed!

Usage #

Usage is simple… fx <json file>. The Github has a few other ways such as curl ... | fx etc.

Jellyfin-Media-Players

I use Jellyfin at home for serving up most of our media - movies and shows etc. My dream is to have a GPU capable of transcoding any and all of our media for smooth playback on any device… Now, I thought I’d have that by now with my Nvidia Quadro P400 however I have issues left and right with 4k content. What can I do to still use Jellyfin but get smooth playback? THe first answer is figure out why I suck with GPUs, but pausing that there’s shorter solutions -> namely, use a media player that’s compatabile with the encoded content! VLC # I’ll keep this one short - VLC is great and if you don’t need a netflix like experience, I’d recommend just using it to browse your network drives and play whatever you have Jellyfin Web Player # This is the reason I’m writing this post… the web player is great but not everything is supported on all devices Jellyfin MPV Shim # This cross-platform cast client is my answer now. You can find the project here The installation instrauctions are super straig…

Type hinting has helped me write code almost as much, if not more, than unit testing.

One thing I love is that with complete type hinting you get a lot more out of your LSP. Typing dictionaries can be tricky and I recently learned about TypedDict to do exactly what I needed!

The Problem #

It might not be straight up obvious what the problem is, especially if you don’t utilize tools like mypy or flake8 in your development.

My handy-dandy nvim-lsp gives me a lot of feedback when I’m coding and it’s immensely helpful.

So with the LSP giving me constant feedback here’s the issue:

from typing import Dict, List, Union

my_dict: Dict[str, Union[List[str], str]] = {
    "key_1": "val_1",
    "key_2": ["ls_1", "ls_2"],
}

my_dict["key_2"].pop()

With the above script you’ll get an annoying warning about using pop on key_2.

typeddict

The Solution #

Maybe you can stomach getting yelled at by your LSP but I like complete silence if at all possible.

TypedDict was the saving grace.

from typing import TypedDict

MyDict = TypedDict("MyDict", {"key_1": str, "key_2": List[str]})

my_typed_dict: MyDict = {
    "key_1": "val_1",
    "key_2": ["ls_1", "ls_2"],
}


my_typed_dict["key_2"].pop()
typeddict

I was able to import TypedDict from typing, mypy_extensions, and typing_extensions

With TypedDict you define your custom type, match the first argument to TypedDict with the name of the variable (idk why), then type hint each key you expect in the dict! It’s super easy and I think puts you into a position of being extremely explicit with your dictionary variables. This isn’t always desired or appropriate but in most of my use cases it is.

RTFM #

There’s other implementation of TypedDict and while writing this I saw that most of the docs define a class for the type like this:

from typing import TypedDict
class MyDict(TypedDict):
    key_1: str
    key_2: List[str]

my_dict : MyDict = {'key_1': 'val_1', 'key_2': ["ls_1", "ls_2"]}

pep docs

mypy docs

And-vs-&

I often struggle to remember the correct way to do type comparisons when working in pandas. I remember learning long long ago that and are different, the former being lazy boolean evaluation whereas the latter is a bitwise operation. I learned a lot from this SO post Lists # Python objects can contain unlike elements - ie. is a valid list with booleans, strings, integers, and another list. Because of this, we can’t use to compare two lists since they can’t be combined in a consistent and meaningful way. However we can use since it doesn’t do bitwise operations, it just evaluates the boolean value of the list (basically if it’s non-empty then evaluates to) Here’s an example: If we compare with using then the comparision will go: Let’s see another example: evaluated to, and also evaluated to even though it’s full of values because the object is non-empty. So using in this case results in a conditional, so the statement is executed. Feels kind of counter-intuitive at first glance, to me a…

I have a specific need for counting the number of lines in a file quickly. At work we use S3 for data storage during our Kedro pipeline development, and in the development process we may end up orphaning several datasets. In order to keep our workspace clean I have a short utility that compares the datasets in a Kedro DataCatalog with the files in the relevant S3 location.

To get that list I run an internal tool like this:

kedro our-liter | grep s3 >> orphaned_datasets.txt

This simply parses our internal linter for the lines releated to my s3 linter utility and pipes those lines to a file.

To get a quick idea of how out of wack a pipeline is I could open the text file in vim, git it with the G and see what line number I’m on but I’m way too lazy for that…

AWK #

awk 'END {print NR}' orphaned_datasets.txt gives me the number of lines and I can alias this to whatever feels appropriate in my zshrc!

built-ins for the win!

Ipython-Prompt

I have a post on starship where I have some notes on how I use starship to make my zsh experience great with a sweet terminal prompt. Now… I spend quite a bit of time in ipython every day and I got kind of sick of the vanilla experience and wanted something that more closely matched my starship prompt. There’s more to customizing ipython I know for sure but here’s 2 things I have going for me… I use authored by @ Will McGugan which makes much of my ipython experience great. I won’t write about that here but you can find my config here I used to customize the ipython prompt with my and a startup script, next to my one, called. The scripts inside are executed in lexigraphical order, so it’s nice to name things in the 10’s to give room for adding scripts in between others down the line. My prompt # My zsh prompt looks a little something like this: And after my ipython customiztion it currently (subject to much change but this is as of my dotfiles commit #d22088f6be81a58b5f7dfb73b7a4088cbd…

Did you know you can spell check in Vim?!

Vim Spell check

Without... #

Here is a missspelled word.

  <h3>With!</h3>
  <p>Here is a <u>missspelled</u> word.</p>

What is this magic??? #

set: spell spelllang=en_us

Custom words? #

Sometimes there’s things that are words to you but not the default spell checker…

Common example: package names!

plotly, streamlit, psutil, etc etc…

You can easily add these to your vim config by hitting zw ontop of the word!