Tyrel's Blog

Code, Flying, Tech, Automation

Dec 05, 2024

New Job

After a year at my previous place, I felt it was time to move on. I just wrapped up my first month at Mango Voice and it's been great!

Mango Voice is a voip company for dental offices. They provide phones, sms, faxing, scheduling, etc... for a lot of dentists (mine uses it!).

I'm on a team that's responsible for the API, a switchboard, and some other small things. They're doing Domain driven teams, so each team is responsible for each of our _domains_ on all our codebases.

Still doing Django, and a lot of python. This time at a place that uses Django Rest Framework, again! It's definitely been a minute since I've used it, but I'm remembering a lot of DRF. I definitely see merits to things I've used in the interim - fastapi being one of them - but it's fine so far.

I also had to do some TypeScript recently - really earning my TypeScript pillow I got a few years ago, ha! There's some legacy PHP code, which It's probably been 18 years since I've touched PHP, but luckily no new development is happening on that codebase.

Apr 17, 2024

What I've been up to since October

Since my last post, about Djangocon I've been pretty MIA. I think I mentioned I got a job, at REDLattice. I've been doing some Django, and other misc programming, and it's been pretty neat. It's a security company, so I haven't really been able to talk about what I've been doing.

It's nice to be back where I'm comfortable, in my tech stack.

I also have been picking up some side projects again, taking some classes, running, and more.

I ran a 5k last month that was on a runway (KGSO) - that was fun. I got sub 30 minutes, but my heart rate spiked REALLY high because it was cold and rainy, not a pleasant race. I really need to work on my running, my average is usually 185, which for a 36yo is awful. I was running slowly for a bit and got it down to a 165 average, but took a week off from runnning because of hurting my foot with a cut.

Gustavo Pezzi released another course on his Pikuma platform - this time it's Playstation 1 programming in C and MIPS. I don't really have the best foundation in C despite doing C++ a lot in college and before - so I've picked up his Graphics Programming from Scratch course. I really enjoy the way he teaches, he never rushes ahead thinking you know something.

One thing I realized is in college I never really did much advanced algebra, so I've decided to also take a Linear Alebra course from MIT's Open Courseware MIT 18.06. Reading math text books is definitely different than I remember, but it might just be this professor. I wish I had some friends doing this course with me, I need to be held accountable.

For other projects I've gotten some new wood tools lately - I traded a watch for them - so I have some ideas in mind now that I have a planer.

Other than that, my daughter turned ONE last month! The day before I turned 36. We had a big party for me, her, and our niece. The party was fun, but I def am not the best party host.

We're taking our first flight as a family next week, hopefully Astrid's not too loud. I was this age when I flew down to Florida and we found out I had hearing issues, so I'm worried for that.

Not much else is new, but felt like it's been time for a blog post recently, even if it's just a personal post.

 · · ·  personal

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

Aug 24, 2023

My Life Story

Trying to write a more prose version of my Resume. Kind of a living post about my life in the Software Engineering World.

Early Life

I started programming with Visual Basic in the 90s on a laptop in my father's car. Parents had just divorced and the drive to his new place every other weekend was two hours, so I had a lot of downtime going through the Visual Basic 5 and 6 books we had. After that, I started trying to program chat bots for Starcraft Battle.net, and irc bots. In highschool I started taking more Visual Basic courses, mostly because that's all that my teachers had for classes. Senior year I took some Early Education courses at the local college, and then went to that college (Keene State) for my Computer Science Degree. At Keene State, I took a lot of Java classes, that was the core curriculum. I also took some more Visual Basic courses, some C++ and web design courses as well.

After college, I thought I'd be working Java again, but I got a referral from one of my favorite professors to this company called Appropriate Solutions Inc, and started working in Python/Django. I had never touched Python outside of OpenRPG - and even then it was just installing the interpretor so I could run the game.

Appropriate Solutions Inc

At Appropriate Solutions I worked on maybe ten different projects. The first thing I worked on was an Hour Tracker to learn how Django works, it worked great, but definitley didn't look too flashy. From there, I went on to work on a Real Estate Website, a Bus tracking/mapping system for a school district, a Pinterest Clone, and some more GIS mapping things. One of our projects was with HubSpot, and I went to one of their hackathons, and a couple conferences in Boston. I had a lot of friends in Boston, so I decided to move there mid 2012.

Propel Marketing

I got my first Boston job in Quincy, MA - working at a startup called Propel Marketing. This was also a Python/Django role, but had more front end work. While there I worked on their internal CMS tooling for selling white labeld websites to clients. I worked on a lot of internal tooling, one that would pull leads from our system, and then upload to a lot of different vendor tooling. A couple of Python PIL tools that would generate facebook and twitter banners, but a lot of the work there was learning and writing tests in Python.

Akamai

From there, I started a six month contract at Akamai, working for their Tech Marketing team on a couple tools. This later got extended another three months, until the team ran out of budget for contractors. I worked on their "Spinning Globe" which was really fun. Some internal dashboards, and a couple email tools that worked with SalesForce.

Addgene

In 2015 I then landed a spot at Addgene - a nonprofit biotech! This is where my career really started taking off. I started to lead projects, do more valuable research and go to conferences. The company itself was - for my tenure there - two Django Projects and some jQuery/Bootstrap. The "core" site was the ecommerce and research site. Buying, selling, research on Plasmids and Viruses. The back end was the inventory management system.

While there, I also lead the charge on a couple projects. We were migrating to AWS - from an in house rackmount server, so we needed to get a lot of data on S3. Testing at Addgene was fickle, as everything was stored in tsv files and reloaded in memory. I developed a python package that would save thousands of dollars of S3 costs, while still making the file upload process in testing seamless. Django DBFileStorage was born.

Another charge I lead was helping Celigo alpha test Integrator.IO - working on building an integration of a lot of our sales data into netsuite/salesforce (I forget which one) by working with the Celigo API. This was a fun project - as when I was done with this, we got to archive an old Java repo that was barely hanging on, and had no bugfixes in years.

While at Addgene, I also started the "Teaching Scientists How To Program" lunch and learn club. We would have meetings where anyone from the Scientist team could come, ask questions about Python, and work through any of the problems they were having with our Jupyter Notebooks we set up that they could run. This was great, I helped foster some friendships that I believe will last a lifetime, helped people transition into actual programmers, and helped the company save a lot of time by helping more people learn.

Tidelift

After Addgene, in 2018 I joined an early stage startup called Tidelift. I was one of the first engineers there, so I got to help lead a lot of early shaping of the company. I started with working on a lot of the Lifter focused side of the site. Helping create tasks the lifters could complete so they could get paid. From there working on the Subscriber side of things where the paying clients would get information about their dependencies. I have an upcoming blog post about some work there, so I won't go into too much details. I did help start the Tidelift CLI though. A tool written in Go, it was a CI/CD tool to analyze software dependencies for security/licensing problems

EverQuote

After Tidelift, I started at EverQuote in 2022. My longtime friend Sam was a Director leading a team that was working on replatforming a monolith and needed to backfill a python role. I had been asking him for years when he would work on Python stuff, as he had only been working at Ruby companies for the past few years, so this caught my ear and I started there.

The first project was replatforming a Python 2.7 monolith - with code from as far back as 2010 - to micro services. These were mainly FastAPI services, that communicted amongst eachother with kafka. Some of them would read from the database, and send events into the kafka stream. Some would read from the stream, and write to the database. Others would read from database or kafka, and then communicate with a third party system.

All of these had Grafana (and later NewRelic) metrics attached. Every server had at least one dashboard, with many graphs, event logs and charts. These were all deployed using kubernetes, terraform, AWS. I can't speak to the specifics about past there - as there was another dedicated ops team.

Some other projects I worked on there were really fun. One of the analysts used to maintain her daily workflow in a google doc, and I helped lead a project that took that apart and worked on it programatically. This was then turned into a five part rebalancing, reweighting, and email route manipulating script - that ran daily using Cron, and saved that team over fourteen hours a week.

The Remarketing team came to an end, and there was a small re-org and we merged with another team and became the Consumer Engagement team. This dealt with Calls, SMS, Email, and working with the Sales Reps.

We started a project using Go and React that would pull users from the database and show a script for the Sales rep to read to the client on the phone, with specific information about what plans were available. Other projects on that team, which is what I spent most of my time on, was porting CI/CD processes from Atlassian Bamboo, to GitHub Actions.

During this time, I took a couple months of paternity leave, and a few weeks after I came back there was a major reduction in force and I was laid off.

After EverQuote

Since leaving EQ, I have been on the job hunt. If you know anything about tech in 2023, a LOT of people are job hunting right now. I'm excited that this happened at a time in my daughter's life where I can spend SO MUCH more time with her than some fathers can. That's the good side of things. I hope I get a job soon though, as the sole earner in my family.

If you've made it this far, please check out my Resume in the sidebar, and contact me if you have anything you think would be a fit. Who knows, I might delete this last section once I get a job!

 · · ·  life

Aug 23, 2023

General Job Search Update

As mentioned in a previous post, I'm on the job hunt again. I got laid off in June with a 30% Reduction In Force.

I've been searching primarily for Python and Go roles, but I'm not having a lot of luck right now - seems everyone else also got laid off is who I am competing against. (That said, go hire my friend Nik! He's fantastic!) I've had a lot of job opportunity people ghost me. Gotten through a few late rounds, only to never hear from the company again. Even if I have emailed them a thank you letter for the interviews, to express my interest.

I've been around professionally for thirteen years. Over those years, I have picked up mostly back end skills. I have eight solid years of Django experience. Four years of Ruby on Rails experience. A couple years of Flask, FastAPI, and other smaller Python Frameworks mixed in.

I'm looking for an IC role, where I can move into a Tech Lead role. I want to eventually some day be a Staff/Principal role, but I don't have that on paper to show I can do it, so trying to get in somewhere new with an IC role.

 · · ·  work

Jun 19, 2023

Jun 16, 2023

Laid Off - 2023 Edition!

"Hey Tyrel, I put a meeting on your calendar, let me know if you can make it." The last words you want to hear from your manager.

Well it happened again, and I got caught in some layoffs from work and am on the job hunt again. I did want to be able to spend more time with Astrid, but not like this!

After the call with HR and them all explaining what was happening, and panic texting my wife and some friends. I emailed the recruiters I've been working with for a few weeks back, and all day today I've been appling to a lot of places.

There are a LOT of jobs out there I'm not interested in, a lot of Ruby on Rails jobs, crypto companies, etc. But I am finding a LOT of Python or Go jobs I'm applying to. I'd love to get a job doing rust and firmware work, but that's unlikely as I want to stay remote, and I have very minimal Rust experience.

What worries me is finding health insurance, because America ties it to work... my wife is unemployed and now we have to cancel a few appointments for us the next few weeks. Still going to keep Astrids 4mo vaccinations though. Those I'll be okay paying out of pocket for.

I just ended the day applying to twelve jobs, hopefully one pans out!

If anyone needs any Python consultation, let me know too! Thanks!

 · · ·  work

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
Next → Page 1 of 7