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.
- The DSF has pretty great Covid rules, and mask requirements.
- Testing requirements.
- 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.
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 = [
>>> 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
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
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]
# Just right
[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
[[7, 4, 1],
[8, 5, 2],
[9, 6, 3]]
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 = [
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  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:
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
Trying to write a more prose version of my Resume.
Kind of a living post about my life in the Software Engineering World.
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.
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.
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.
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.
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
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.
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!