Tyrel's Blog

Code, Flying, Tech, Automation

Oct 15, 2023

Djangocon 2023

I am at DjangoCon 2023 this year!

I live in Durham, NC and have been avoiding conferences for the past few years because of Covid and not wanting to travel. This year for, what ever reason, they picked Durham!

So I am breaking my "Don't go to conferences" for multiple reasons.

  1. The DSF has pretty great Covid rules, and mask requirements.
  2. Testing requirements.
  3. It's local, so I get to sleep in my own bed.

I'm not guaranteed to get to see my daughter, but I hope she knows I still love her even if I'm not around. I'm leaving at 7:30 tomorrow as I'm biking in, and she may be asleep.

Already I've gone to one of the local breweries I haven't gone to yet (See above: Covid), and met some great people, can't wait for the rest of the week.

While technically a "Tech Blog" I am by no means a great note taker, so don't expect any quality information from me in blog form, I'm mostly going for the HallwayTrack, and to watch talks.

 · · ·  django  conferences

Oct 03, 2023

Rotate a Matrix in Python

I've been doing Advent of Code for a few years now, and every year I do it in my favorite language, Python. One thing that comes up a lot, is rotating matrices.

One way to do this, is to use Numpy, using np.rot90(mat), but not everyone wants to install Numpy just to do one small task. I know I don't always.

The way I always do it, that will support non-square matrixes, is to use zip.

>>> matrix = [
 [1,2,3],
 [4,5,6],
 [7,8,9]
]
>>> rotated = list(zip(*matrix[::-1]))
# And result is
[[7, 4, 1],
 [8, 5, 2],
 [9, 6, 3]]

We can break this down bit by bit.

This will copy the list, with a -1 step, resulting in a reverse order

>>> matrix[::-1]
[[7,8,9],
 [4,5,6],
 [1,2,3]]

Next we need to call zip in order to get the x-th item from each inner list, but first, we need to unpack it. If you'll notice, the unpacked version isn't wrapped with another list, which is what zip needs from us.

# Too many lists
>>> print(matrix[::-1])
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]

# Just right
>>> print(*matrix[::-1])
[7, 8, 9] [4, 5, 6] [1, 2, 3]

From there, we can pass this unpacked list of - in our case - three lists, to zip (and in Python 3 this returns a generator, so we need to call list again on it, or just use it)

>>> # Again, we get the rotated matrix
>>> list(zip(*matrix[::-1]))
[[7, 4, 1],
 [8, 5, 2],
 [9, 6, 3]]

Notes

Small note: If you run this, you will actually get a list of tuples, so you can map those back to a list, if you need to update them for any reason. I just wanted square brackets in my examples.

# This is just messy looking, so I didn't mention it until now
>>> list(map(list, zip(*matrix[::-1])))

As I mentioned, due to using zip this will work with non-square examples as well.

>>> matrix = [
... [1,2,3,4,5,6,7,8,9],
... [9,8,7,6,5,4,3,2,1],
... ]
>>> print(list(zip(*matrix[::-1])))
[(9, 1),
 (8, 2),
 (7, 3),
 (6, 4),
 (5, 5),
 (4, 6),
 (3, 7),
 (2, 8),
 (1, 9)]
 · · ·  python

Sep 26, 2023

Which which is which?

I had a bit of a "Tyrel you know nothing" moment today with some commandline tooling.

I have been an avid user of ZSH for a decade now, but recently I tried to swap to fish shell. Along the years, I've maintained a lot of different iterations of dotfiles, and shell aliases/functions. I was talking to a friend [citation needed] about updating from exa to eza and then noticed I didn't have my aliases loaded, so I was still using ls directly, as I have alias ls="exa -lhFgxUm --git --time-style long-iso --group-directories-first" in my .shell_aliases file.

I did this by showing the following output:

$ which ls
/usr/bin/ls

Because I expected it to show me which alias was being pointed to by ls.

My friend pointed out that "Which doesn't show aliases, it only points to files" to which I replied along the lines of "What? No way, I've used which to show me aliases and functions loads of times."

And promptly sent a screenshot of my system NOT showing that for other aliases I have set up. Things then got conversational and me being confused, to the point of me questioning if "Had I ever successfully done that? Maybe my macbook is set up differrently" and went and grabbed that.

Friend then looked at the man page for which, and noticed that there's the --read-alias and --read-functions flags on which, and I didn't have those set. I then swapped over to bash "Maybe it's a bash thing only? I'm using Fish".

Nope, still nothing! Then went to google, and it turns out that ZSH is what has this setup by default. Thank you "Althorion" from Stackoverflow for settling my "Yes you've done this before" confusion.

It turns out that ZSH's which is equivalent to the ZSH shell built-in whence -c which shows aliases and functions.

After running /usr/bin/zsh and sourcing my aliases (I don't have a zshrc file anymore, I need to set that back up), I was able to settle my fears and prove to myself that I wasn't making things up. There is a which which shows you which aliases you have set up, which is default for ZSH.

$ which ls
ls: aliased to exa -lhFgxUm --git --time-style long-iso --group-directories-first
 · · ·  linux  macos  zsh

Jun 19, 2023

Jun 08, 2023

Netgear WAC104

I recently bought four Netgear WAC104 devices, and am flashing OpenWRT onto them. I have struggled a lot to get the firmware on, due to the not great interface they provide.

The issue is, that it prompts you to change the password, but then when you change it on the page you land on, nothing connects anymore and you can't access the router.

The solution is to click "Set Password" in the Administration menu on the left, and set it there. Even though there is a prompt to set the password on every page, that will change other settings too and break things.

The router isn't great, and the software is awful so thats why I'm installing OpenWRT anyway.

Two down, two more to go!

 · · ·  networking

Jun 07, 2023

pfSense

This week I finally got a machine that is solely to run pfSense. I didn't want to spend _too_ much money so I bought a $200.00 Qotom Firewall Q330G4. This was great and easy to set up.

First I bought a Netgear WAC104 and installed OpenWRT on it. Simple enough. Then I put that into bridge mode, so it's just an Access Point and not a "smart" router too.

Then I put my Linksys EA9300 into bridge mode and behind the pfSense machine (into a switch) and couldn't access any of my server's sites.

After futzing with that for a couple days, I finally figured out the problem. I thought I was behind a double NAT, but I wasn't. When I moved my EA9300 from my sole WiFi router, to behind the pfSense machine, I neglected to change some settings on my AT&T modem.

You see — dear reader— when I set up this network on my AT&T Modem, I had to enable Passthrough mode. This, was set to a MAC Address, not an IP Address. So when I was making sure to keep my IP network on the same 192.168.1.1/24, I thought that was all I needed.

Alas, there's a dropdown to pick the MAC address of the machine that everything passes through. I can now access my bookmarks, notes, ebooks, and plex server!

Thanks to my friend Daniel (@sanitybit) - who was a great rubber duck and gave me some pointers when I was debugging, and also helped me find the hardware for the pfSense box!

 · · ·  networking

May 26, 2023

Emulation

I haven't had much time lately for blog posts, I've been dealing with bed time routines with my newborn, and once those are done, I get a few hours of alone time for computer things.

Lately I've been toying around with Amiga OS, FreeDOS, Windows 95, and Apple IIe things.

I got a raspberry pi and installed Pimiga, got a fun set up and that was neat. I then installed Amiberry on my macbook, with some remote hard drive images on my samba share, and I have a consistent setup for Amiga on any machine in the house or on tailscale.

I then decided to install FreeDOS to a barely used Dell Vostro 1720 and install to that. It works great, I have WordStar, TurboC, and more installed and it's fun to get back to my roots in that way.

After that I decided to install Windows 95 with 86Box, did the same with remote hard disk images, and got that running. Been toying around in Visual Basic 6, Oh the memories!! I installed that so I could play Lego City, but having voodoo graphics errors I need to figure out before I can play.

I also ordered an Apple IIe emulator machine that runs on an Esp8266 from CT6502 and it works great. So cool just tossing a disk image on the MicroSD card and loading it up. The downside to this is I can't figure out how to swap disks in realtime, so I can't play Ultima, or any multi disk games. I can however load .hdv files so if something comes with a hard disk image.

Not really much for a tech post, and nothing to share codewise, but thought I'd break some radio silence. I also imported my flying blog here, so I added the Flying category/tags.

 · · ·  emulation

May 26, 2023

Neovim, Nix, Telescope, Tree-sitter, Mason

I made a mistake with not reading CHANGELOGs for all my packages in Neovim this week. This sent me down a small rabbit hole trying to fix all the things.

What happened is I ran :PackerUpdate which, pulls the latest version of Packer packages, good, updates! But... Telescope has a new requirement on main branch that requires Neovim 0.9.0. The problem is that the latest NixPkgs for Neovim right now is 0.8.1. I ran to google, tried to set an overlay to use neovim-nightly, but that didn't work. If you recall in Dotfiles - My 2022 Way I'm not actually using NixOS so (please correct me if I'm wrong) overlays don't work. I tried specifing a version in my programs.nix, I tried a bunch of other things at 1AM that I don't remember anymore.

Almost ripped it all out just to use Nvim 0.9.0 on this machine until NixPkgs has updated the repo. I decided that was the wrong idea, and went to sleep.

Tonight, I was able to figure out that in Packer, you can pin a commit!

It's clear in the docs, but I was trying to fix it at the Nix level, so I didn't immediately think of this, even though at my last job, Tidelift, I was doing package pinning analysis! Derp.

So, I added commit="c1a2af0" to my use statment in plugins.lua and Telescope started working again without a warning, or issue. Commit.

That wasn't the only problem though. In my infinite wisdom, I followed some reddit posts that I won't link to, that suggested deleting ~/.local/share/nvim and rerunning PackerInstall, the problem there -- my tree-sitter configs are in my nix files.

This is an issue I need to look at later, but in my programs.nix file, I some reason have two entries of plugins =. I had to uncomment the first one where I inject tree-sitter, and comment out the second setting. Then rebuild my nix flakes.

After that,I had to comment the first, uncomment the second, and rebuild with withAllGrammars config.

This worked, I had my rust tree-sitter configs working, but was missing rust-analyzer.

That's in Mason! So I ran :Mason, found rust-analyzer slapped that i button, and I finally had my system back after 2 days of issues.

This was mostly a blogpost so I can reference back to it in the future, but hopefully at least _someone_ learns to pin your dang nvim Packages!

 · · ·  nix  nvim  rust

May 26, 2023

Set Environment Variables with LastPass

I have to use LastPass at work, and I store some API keys in there. Rather than copy/paste and have the actual api key on my terminal, I like to use read -rs ENV_VAR_NAME to set environment variables, so they are hidden from scrollback.

Recently my coworker set something up that we need an environment variable set up for running some Terraform commands. I don't feel like pasting it in every time from LastPass, so I figured out how to set this up and automate it. I'm sure I've already talked a lot about how I love direnv and I maintain a lot of different .envrc files for work things. For my last team I had one per repo! Well direnv comes to the rescue again.

  • The first step is installing the lastpass-cli.
  • Then you need to set it up so you log in, how you do that is up to you. I have lpass checking status, and if it exits nonzero, then running lpass login again in my direnv.
  • After that you can use lpass show and capture that in a variable to export your API key as an environment variable.
lpass status
if [ $? -ne 0 ]; then
    lpass login email@address.com
fi
export API_KEY=$(lpass show "Secret-Name-Here" --password)

Example .envrc file.

I love automating things, and when a coworker says "oh no we have to do this"... I run to automate it!

 · · ·  bash  automation  work

Jan 31, 2023

6502 NES Course by Pikuma

As I mentioned in my December post I'm doing a 6502 course on Pikuma.

I'm about 75% of the way done, and I think I need to circle back to some earlier stuff about how the PPU works, but it's super fun.

Over the holidays I was able to stop at my father's and pick up my old NES. I swapped out the ZIF connector for a new one, and cleaned up some contacts on the RCA ports, and it works great! Once I found out that it was working - I played Sesame Street ABC 123, as that's the only one I had up in my office - I ordered an EverDrive N8. That came last week.

The pictures are tall due to how I took them, so sorry I'll attach them at the end of the post.

Once I got the EverDrive N8 I made sure it worked by playing a Battletoads ROM. Battletoad tested - I then copied Atlantico.NES to my Everdrive. Atlantico is the game that Gustavo is walking us through making in the current part of the course - not a real published game. I loaded it up and HOLY COW - something I actually wrote in Assembly is running on real hardware.

If you want to watch the video, it's very simplistic at the 75% mark, this was before the Collisions chapter, and no sound yet.

The feeling of getting something running, locally, and seeing it working on screen, despite being a programmer for ~~20 years, is AMAZING. Writing code that executes on the system you grew up playing the early 90's, wow.

I do wish the CRT TV my wife had was square, things get cut off on it. I even got a remote, so I could try to fix that in the menu, alas, only picture option is brightness. (Not that I realistically thought I could scale it, CRT Pixels are only Pixels.


 · · ·  6502  assembly  NES
Next → Page 1 of 4