Posts tagged: tech

All posts with the tag "tech"

186 posts latest post 2026-10-06
Publishing rhythm
May 2026 | 3 posts

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

Home-Server-Refactor

My current homelab setup is not great but it works… Proxmox on PowerEdge R610 I boot off an SD card and have 1 SSD and 5 HDDs configured as a JBOD array using a Dell H700 SAS controller. I cannot boot from a disk using this controller and I can’t get the firmware configured in a way to allow it. So I have 1 SSD as a ZFS array that I’ve been putting my VM images on, and the 5 HDDs are passed through to a TrueNAS VM where I handle all the ZFS stuff there… kind of meta because I then attached those drives to Proxmox as a CIFS share. TrueNAS on dedicated box I have an on-prem backup that is just an old desktop running TrueNAS I regularly backup the 5 disk RAIDZ2 array from my Proxmox host (managed by a TrueNAS VM) to this backup box Currently there is nothing else running on this machine since it’s my “backup” Jellyfin I was HWA for Jellyfin, but hardware passthrough on the R610 is finicky or broken so Jellyfin is running on an Ubuntu host. I could put UBuntu on the R610 and give up “true…

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!

Polybar-01

polybar is an awesome and super customizable status bar for your desktop environment. I use it with i3-gaps on Ubuntu for work and it makes my day just that much better to have a clean and elegant bar with the things in it that I care about. The GitHub has all the instructions you’d need to install and get started with an example. I want to make some notes about how I use polybar and customize it. Organization # First of all, I recently moved my polybar config out of one config file into a modular structure that keeps my config files small and easiser to edit. You can find my config here The apps or services you put into polybar are called. I have moved all of my modules into their own config files and I source them with one centralized config. This separation also makes it easier for me to keep my home and work polybars as in sync as possible without duplicating a ton of config! To break this down there are several configs to see: is what you’d expect - a set of defined colors like,,…

I am working on a project to create a small system monitoring dashboard using the python psutil library.

The repo is here (if you want actual system monitoring please use netdata).

I’m using streamlit and plotly for the webserver, design, and plotting at the moment.

My Use Case #

I needed a way to refresh my plotly charts with a fixed window of time so that I’m able to just see relevant recent data instead of cramming all data for all time into one plot that’s 500 pixels wide…

Checking the length of arrays or lists every time I get a new piece of data feels kind of dumb and I thought “python must have a way to do this”…

“This” meaning, update values in a fixed length array without reallocating memory or recreating a copy of the list

Deques #

Enter the deque. It means “double ended queue” and is in general an Iterable that you can append values to either side or pop values from either side.

The init signature is straightforward enough and I’m sure there’s more to them than I know yet but here’s how I use it…

from collections import deque

my_deque = deque([1,2,3])

This gives us my_deque, created from an iterable, with several familiar methods like index, extend, append, etc. However there’s some new ones too such as appendleft and popleft.

my_deque.appendleft('a')
print(my_dequqe)
>>> deque(['a', 1, 2, 3])

my_deque.popleft()
>>> 'a'

<!--markata-attribution-->
print(my_deque)
>>> deque([1, 2, 3])

These are handy ways to manipulate the iterable that I needed for the arrays I plot with plotly!

See my follow-up to this on using Deques with plotly and streamlit to create a quick “dashboard” with live streaming data!

follow-up