One of my favorite tools is ngrok (pronounced en-grok, presumably referencing Stranger in a Strange Land, a book I read as a freshman in high school when I was far too young to appreciate it). If you need to get a locally-running service on the Internet, ngrok can do it in seconds with a single command. I use it all the time when experimenting with and debugging APIs, such as this weekend’s foray into LangChain.
Supposedly it can do a bang-up job of fronting production services also, but I’ve never tried it for that use case. Perhaps someday? In any case, I’m truly grateful it exists.
I don’t pretend to know everything that’s going on over at OpenAI, nor all the eventual lessons that will come from it, but unlike most tech-elite brouhahas this one might actually matter, as there’s a strong possibility taming artificial intelligence is “the final boss of humanity” (as one of the players in the ongoing saga has said).
Played around some yesterday with ChatGPT’s voice chats, and can totally see how we’re not far from deepening the emotional attachments to our devices. Her has never felt more prescient or likely. It’s mandatory viewing.
It’s inevitable that over time I’m going to repeat myself here (includingposttitles). When I’m aware of potential similarities, I try to embed links back to those prior posts. A while back I noted an idea of building a thematic map of all my posts, but I wasn’t sure how to go about doing so. Now that I’ve learned some about embeddings, it was time to try my hand at it.
First, I had to actually fetch all the post content. I briefly toyed with the WordPress REST API, but couldn’t figure out how to enable it. No worries, though, RSS to the rescue! Unfortunately it’s XML, and I fiddled a bit with using lxml to parse the it, but stumbled upon feedparser which abstracted the details. Awesome!
Since it’s the de facto standard for Python data science, I loaded the posts into a pandas DataFrame. I’m still working on my fluency with pandas, numpy, scikit, and matlibplot, amongst other common tools, and I’m grateful for any opportunity to get their power under my fingers.
To compute embeddings for each post, I used the OpenAI API with the text-embedding-ada-002 model. It’s not good to store API keys in code; for local scripts I store all mine in the MacOS keychain using keyring. Nice and easy.
Since OpenAI usage costs money, I don’t want to repeatedly call the API with identical inputs if I don’t have to. That’s where cachier comes in (a library I help maintain) so results can be transparently saved to disk for subsequent use.
Once I had the embeddings, I used K-means clustering to group posts into common themes, and then t-SNE to reduce the dimensionality and produce a visualization of the clusters. To produce a summary of the theme of each cluster I took a sample of posts from each and shoved them into GPT4.
To start I tried using 2 clusters, which produced the following distribution:
Pretty interesting that there’s a natural grouping going on. Here’s the themes and sample posts:
Blue Posts
The theme of these posts is the author’s personal and professional experiences with technology, education, open-source contributions, ethical considerations, and the impact of travel and diversity on personal growth and the tech industry.
The theme of these posts revolves around the reflections, experiences, and insights of a software developer navigating the challenges and nuances of the tech industry.
Of course I had to try with a variety of different numbers of clusters, so I reran with 3, 5, and 8 clusters as well (anyone see a pattern there?)
Of those graphs, to my eye the 5 cluster one seemed the best balance between having enough distinct themes without starting to look too arbitrary. Here’s the summarizations for it:
Blue Posts
The theme of these posts is the author’s personal and professional experiences, challenges, and insights related to technology, software development, and working within the tech industry.
The theme of these posts is the multifaceted nature of software development, encompassing the importance of maintaining code quality, the broad skill set required for effective development, and the challenges and responsibilities that come with the profession.
The theme of these posts is the reflection on and sharing of personal experiences, insights, and best practices related to software development, including contributing to communities, understanding abstractions, effective communication, and professional growth within the tech industry.
The theme of these posts is the author’s personal reflections on their experiences, interests, and philosophies related to their career, hobbies, and life choices.
What’s next? I’d like a quantitative way to evaluate the quality of the theme clustering and summaries produced. There’s a lot of non-determinism in the functions used here, and with some twiddling I bet I can produce improved results. I’ve got some ideas, but will save them for a future post.
I’m sure there’s research out there that says people do better work when they’re happy. But anecdotally, it’s an obvious truth. Of course there are limits (“fun with respect to work” will almost always be “work with respect to fun”). But in general, fostering a positive work environment and encouraging employees to take care of themselves is good business.
Last week a colleague of mine was revising the spreadsheet we use for high-level estimation, and as part of her adjustments added a few splashes of color. The highlights had a functional purpose, yes, but they were also simply more pleasant to look at. It made me want to work on the spreadsheet at a subconscious level.
Isn’t that nice? I suppose the 49″ ultrawide monitor doesn’t hurt either. 😛
Another obvious example of this phenomenon is font quality and syntax highlighting. Take a look at the following “identical” code samples; which one would you rather work with?
Literally as I was drafting this blog I learned about Monaspace. Taking code aesthetics to the next level, I dig it. Describing the process of adjusting glyph widths as “texture healing” is an especially humanizing touch. Happiness matters!
As a tech discussion grows longer, the probability of a mention of Generative AI approaches one. It definitely happened at today’s 4S Tech meetup; we didn’t even make it all the way through the introductions.
Additional common topics: biometrics, productivity hacking, ways to get funding, something someone heard on a podcast.
So you want to become (or have been told you now are) a technical team lead? Awesome, congratulations! You’re in for an excellent adventure. But if you’re wondering where to begin, and what’s going to change, lucky for you I’ve been there myself, helped several others through this transition, and have captured some lessons you can apply:
First, make sure everyone on the project knows you’re the technical lead. This isn’t about ego or power, it’s about clarity of function and accepting responsibility. With that comes the need to be responsive; availability for conversation is now part of your job.
Next, get to know the team personally and earn their trust though human connection. You cannot be everywhere all the time, so you need people who are comfortable coming to you with challenges both technical and otherwise. If there are folks involved external to your organization this is doubly-important. Identify a go-to person on that external team and engage with them regularly one-on-one.
Get to know the team professionally as well. What are each individual’s strengths and weaknesses? What technical skills do they have, and what parts of the system need those skills applied? What are their communication styles and ways of being motivated? Personalize your approach with everyone; it’s your role to put them where they can thrive, which in turn maximizes collective success.
Have a generalist mindset. Get to debugging level competency across the entire tech stack, no excuses. You don’t need to be the best at everything, in fact you shouldn’t be, but you should know what good looks like so you can ensure it’s happening.
There’s one area, though, where your knowledge should be unrivaled, and that is understanding your customer and the business case you are there to solve. Get familiar with their requirements and deadlines. Stay connected to your stakeholders, listen, ask questions, and then push their objectives down to the people in your charge. Once again, this is especially important if there are subcontractors who have a limited view of the big picture.
Make yourself present in meetings, erring on the side of being overly-present (especially at first). Requirements gathering session? You gotta be there. Sprint planning and backlog grooming? Not optional. But that deep dive on a bug or tricky technical problem? Maybe let your tactical experts handle it, or at least have them gather the data and come to you if they run stuck or need a decision.
Speaking of decisions, apply wisdom to the ones you can delegate and ones you cannot. Specifics will vary project to project, but in general the more reversible a decision is, the less important it is you make it. Another rule of thumb: as soon as you know how to do something well, it’s time to teach someone else to do it, while you take up the next challenge no one else is equipped to solve. Fail at security and you fail full stop, so keep your eyes on anything that could jeopardize it.
High-level architecture and technology choices will matter more in the long run than anything decided in a code review, so keep your nitpicks to yourself. Speaking of code reviews, their value mostly comes in peer to peer cross-checks. If you think you have to approve every line of code yourself, you’re doing it wrong. Treat your attention like the precious commodity it is.
Your good intentions of ensuring quality code and other deliverables won’t be enough. Establish quality mechanisms: automated linting and security scans. Automated testing. Continuous deployment. These are your eyes and ears, and more important for you to establish and monitor than you building features at their expense.
Take failure personally. Things will go wrong; the minute you blame those under your charge, you’ve lost. Instead, turn your gaze inward to what you could have done better. When you hold yourself to the highest standard, it calls others to do the same.
Finally, don’t stop listening and learning. Get feedback, even when it’s hard to hear, and act on it. Also, there’s tons more out there on being a tech lead, go do some searches and read up. Perhaps you’ll even (gasp) find counterpoints to my above arguments. That’s great! Ultimately you’re a technical lead to serve and empower, and that requires judgment on when to follow the rules and when to toss them and do what’s gotta be done, because no job is below you. Be the person who brings the coffee and donuts, orders the pizza, serves the drinks, and cleans the conference room afterwards.
Sound hard? It is. It’s gonna take a different set of skills and a significant amount of time. You’re going to have to let go of some things you’re used to doing and some things you’re good at (and probably enjoy doing) to find that time. But when a team you’ve led accomplishes more than you could ever do on your own it’s a unique kind of reward.
Open rebuke is better than secret love. Faithful are the wounds of a friend.
We’re in the midst of performance review season, a process I enjoy. Really! Of course performance conversations can happen throughout the year, but there’s something especially valuable about a concentrated time of reflection and intense discussion. Describing strengths, celebrating successes, identifying growth opportunities, rooting out behaviors that are holding someone back; these are all reasons I became a manager in the first place.
This responsibility can feel like a chore, if not a terrible annoyance. Pointing out shortcomings or negative behaviors in colleagues is uncomfortable at best, and if not done with grace and from a foundation of trust, can be damaging and career limiting. But when the feedback is honest, timely, actionable, and includes both positives and critiques, it is a great gift to the receiver. An act of love, even. We don’t use that word often in the workplace, and that’s unfortunate. Genuine human connection is the foundation of anything worth doing. It’s good for you, it’s good for your colleagues, and it’s also good business.
If you don’t know where to begin giving feedback, I recommend the SBI framework for guidance. And no matter if you discuss in person or provide in writing, you should give your feedback some thought ahead of time (and maybe take a few notes). I promise that it gets easier the more experiences you have giving it, though it will always be an emotional process, and that’s a good thing.