Tag: Ownership

Better Together

Better Together

Today the United States celebrates its independence. Amongst the barbecues and fireworks, it’s worth taking a few minutes to reflect on the significance of this day in history. For me, I’m most thankful for the contributions of this country’s founders to the ideals of good government.

We’ve had no shortage of trouble in living up to those ideals, and I’m convinced that some considerable reforms are still needed given how the nation has evolved (see Breaking the Two-Party Doom Loop for my favorite take on that subject), but on the whole, the system of government we enjoy with its equal representation, checks and balances, and problem solving using negotiation and compromise vs violence, has promoted human flourishing both here and around the world (well, sometimes at least).

It’s been a privilege of mine to work in the public sector for most of my career, and I don’t expect that to change anytime soon, as I’ve doubled-down on situating myself at the intersection of tech and politics. I figure it’s how I can best honor those who got us this far; to continue the quest for developing better governmental systems and policy.

I’m not alone in that effort, as I’ve been able to meet a lot of great people along the way, dedicated public servants who really care about improving lives. Perhaps you too should consider joining our ranks? Governments are positioned to solve numerous problems both big and small, and they need the kind of smart problem-solvers that tech folks typically are. It may not be glamorous, but it’s desperately needed.

For All The World To See

For All The World To See

Want an amazing example of learning in public, far more comprehensive than anything I’ve described here? Look no further than the blog of Juraj Majerik, where he chronicles in a 34-part series building an Uber clone from the ground up. No detail is spared in his journey, including setting up automated deployments and detailed monitoring dashboards. I’ve never seen a learning project this thoroughly developed or documented. It puts a number of real products I’ve worked on to shame. And his claim of it requiring about 300 hours is impressive as well, I would have guessed higher.

I tip my hat to you, Juraj. May your example inspire many more to embark on such educational adventures.

Slow And Steady

Slow And Steady

As of today I have a backlog of 49 draft posts going back to 2017. A good chunk of this backlog, especially recently, centers around themes of maintenance, longevity, sustainability, and generally making sure that work outlasts oneself in some form or another. It’s obviously something on my mind.

So when I sit down to write, why do I most often start with something new instead of picking up an old draft? I suspect it has to do with a fresh take being more motivating. For today, that motivation was my completion of the La Jolla Half Marathon. It’s a race I’ve run before, though it’s been six years.

What’s the relevance to the theme that I mentioned earlier? It’s not only that I am still able to run it despite being in my mid-40s, but that I beat my prior time by over 10 minutes (today’s result was 1:56:05). Which means my years of running has created the kind of habits that enable successful long runs with little to no additional preparation (I only signed up for this race three weeks ago, and thus didn’t have much margin to do a ramp-up beyond my normal weekly miles).

Similarly, while I don’t code every single day (nor should I, it’s not the focus of my current role), I aim to do enough programming regularly so that I’m ready to do more if a situation calls for it.

There’s probably also something to learn here about the long-term benefits of keeping systems running that are doing their jobs as designed and continue to provide value, versus continually looking to replatform and rebuild.

In short: maintenance matters.

It’s Never Five Minutes

It’s Never Five Minutes

There’s no magic method to software estimation that produces perfect results. Nor is it a skill that’s easily taught. For the most part, you just have to start doing it, make a lot of mistakes, and gradually you’ll get better over time.

That being said, here are a couple articles on the topic worth reading:

My own two (or more) cents is that individual task estimates will always have considerable uncertainty, but that can be mitigated by quantity. As long as there’s no systemic bias, the sum of estimates across a set of tasks will become more accurate as the set of tasks itself grows. And any bias that might exist (a tendency to underestimate is most common) can be compensated for by a final multiplicative factor (1.25 is a useful starting point, but can be refined over time).

Further, a diversity of estimates per task also increases accuracy, and directly proportional to the diversity of perspectives brought to it. Have front-end folks contribute to back-end estimates and vice versa; get estimates from both senior and junior level engineers; include people that cut across multiple projects. If nothing else it will promote collaborative conversations.

Here’s a process I use to achieve the above diversifications. It’s most applicable when estimating a project, but could also be used for estimating large features, though it’d be overkill for a single task. It can be done either synchronously or (mostly) asynchronously, and doesn’t take more than a couple hours.

  1. Put together a team of three estimators, ideally with a variety of skills and experience relative to the project being scoped.
  2. Each person reads through whatever project materials have been assembled so far (descriptions of the work, details on the customer and industry, overall objectives, etc).
  3. On their own, each person independently writes down in a few sentences their understanding of the objective of the project. This description should be non-technical and describe business outcomes, not implementation details.
  4. The group comes together and synthesizes their separate descriptions into a unified paragraph they all agree accurately captures the project objectives.
  5. Each person independently puts together a list of tasks to be completed based on that description. These should include everything needed to get to done, including not only implementation but design time, testing, bug fixing, deployments, documentation, and so on.
  6. The group reassembles and synthesizes each list into a unified task list, removing duplicates as needed, and discussing any items that aren’t broadly understood, until everyone feels good that the list is as complete and detailed as possible.
  7. The scopers separate once again, and on their own each person comes up with an estimate for each task on the unified list. Scopers should not get hung up too long on each task; give it a few minutes thought, make a best effort (err on the high side), and capture any assumptions or unknowns.
  8. Once everyone has independently estimated, come together again, and compare estimates task by task (as well as any assumptions anyone captured for that task). If there’s little variance across the estimates on a task, use the average as a final value. If there is disagreement on the estimate, discuss until a common understanding is reached. Reword the task, or split it into multiple tasks if needed, and then estimate those subtasks. If a consensus final estimate cannot be reached after a reasonable amount of time, the largest original estimate for the task should be used.
  9. Sum the final estimates for each task to come up with a total estimate for the project. Each person gets a chance to share their feelings on this total: does it seem right in aggregate compared to the original description of work determined earlier? If so, excellent. If not, re-review the task list and iterate on estimates again, either as a group, or even going back separately.
  10. Collate the list of assumptions and unknowns and discuss. Based on what is identified, decide on a final uncertainty multiplier. As a general guidance, add 10% if the list is short and/or simple, 25% for “standard” assumptions, and up to 50% if there are large unknowns or significant anticipated complexities. There’s no hard rule here; apply professional judgment.
  11. Apply this multiplier to the task estimate sum to get a final estimate for the project. Share it with stakeholders along with the project description and list of assumptions. Be prepared to defend the value, but also be open to questions and challenges.

I haven’t met anyone who truly loves software estimation, but it’s critically important if you want to be successful beyond hobbyist level. Put in the effort as a team and reap the benefits.

Pro-Social Behavior

Pro-Social Behavior

As someone who tries to maintain a consistent and up-to-date, if atypical, online presence, it’s no small effort to update profiles and such when taking a new job. Here’s the list of the sites I’ve edited recently (documented here as a reference for next time I need to make such changes, if nothing else):

Besides the basic information, over time I’ve crafted a professional profile statement that I use to describe myself. It comes in three flavors depending on length required:

Technologist building systems and organizations that promote human flourishing.

Technologist building both systems and organizations that are secure, scaleable, cost-effective, and most of all, promote human flourishing.

Technologist building both systems and organizations that are secure, scaleable, cost-effective, and most of all, promote human flourishing. Well-versed in programming languages, cloud technologies, and people management. Experienced with the entire engineering lifecycle, from ideation and requirements design to architecture and implementation to sales and support. Also an avid runner, amateur musician, and owner of every iteration of the Raspberry Pi.

When I need a brief personal description, I use this:

husband, father, son, brother, musician, runner, and maker of things

I’ve also used a number of headshots through the years, here’s a couple of my favorites, in reverse chronological order:

Get In The Arena

Get In The Arena

Several months ago I had a need to cache function results across multiple executions of an API client. A quick web search revealed several solutions, the best fit being cachier. However, it was still missing a few important features I needed, and thinking it was the quickest solution, I wrote up a wrapper to implement these features and published it on PyPI.

One of the features was particularly tricky to get working without modifying cachier itself. Though I did get it working, I regretted not instead simply seeing if I could build my needed capabilities into that library itself and avoiding the wrapper altogether.

Turns out I had some additional free time, and took a crack at an integrated implementation of three key features, and turns out the maintainer of cachier was grateful for the contributions. I was also able to make additional improvements, which benefit all of cachier’s users, not just the one user (i.e. me) of a wrapper which is unlikely to get popular.

This experience was a good reminder that open source software is not built by a mysterious group of “other people” but by ordinary folks who graciously offer their limited time for the public good. Considering how much I’ve benefited from such generosity throughout my career, I’ve been thinking about what responsibility I have to the broader community. I’m not the only one. Do I have a professional obligation, or even a moral one, to contribute? Quite possibly, but either way, it’s something I’m going to do as long as I’m able.

Where My Mouth Is

Where My Mouth Is

As I get older, the more I’ve reflected on ways I can give back to organizations and communities that have had a big influence in my life. It’s why I contribute to open source projects. It’s why I respond to Stack Overflow posts (or at least try to periodically). And it’s why I give to the Wikimedia Foundation.

Despite it’s quirks and occasional inaccuracies, Wikipedia is a modern miracle of information that has shaped countless lives in inestimable ways. I find their mission statement a beautiful ideal: “a world in which every single human being can freely share in the sum of all knowledge.” Knowledge isn’t everything, but it’s a significant something; a necessary ingredient to human flourishing. And I’m happy to do my part to increase its presence in the world.

The Tie That Binds

The Tie That Binds

Read these two articles yesterday. On the surface they’re about different topics, but there’s a common thread: both call out an aspect of technical work that is often ignored, especially by the less-experienced.

The first tale, Our Company Fired the Best Developer and Project Manager, reminds us that “Getting your tasks done is half of the job. The other half is how you do it.” I’d go even further and say getting your tasks done is only a quarter of your job. The rest is how you do them, when you do them by, and most importantly, ensuring you understand why those are your tasks in the first place, and if perhaps you should be doing other tasks instead. Don’t climb the ladder only to find you leaned it against the wrong wall.

Coding Won’t Exist In 5 Years is yet another ChatGPT article, whose crux is the following: “Programming is the process of solving problems using a computer. Writing code is just one aspect of this process. It’s a necessary part, but it’s not the whole picture.” Yes, learn to write code well, but be aware you’re more valuable as an editor than as a drafter, and that’s only going to get more true as AI gets better.

That Personal Touch

That Personal Touch

Meeting regularly with your direct manager is an important mechanism for ensuring your work stays customer focused, getting actionable feedback and advice, and ultimately helping you achieve your career goals. This page captures a few of my thoughts on making them effective.

Firstly, you as an individual should own these conversations. Take the lead in setting an agenda, and come prepared with discussion topics. Your leadership has limited time, so use it wisely. Frequency and duration are up to you as well, though generally I’d say more frequent and shorter is better than one marathon session per month. However, there are times when longer discussions are needed, especially when goal setting and discussing performance.

Discussion topics can vary, though generally as a manager I’m less interested in discussing status on your day-to-day tasks and projects, unless you need advice or guidance on a specific issue you’re facing. I have other mechanisms to keep tabs on project health, so I’d much rather focus on personal development and goals. That being said, if you really want to give your manager a dump of what you’re working on (or just vent) that’s fine, but be careful not to use up all your time in this way.

Finally, I recommend taking notes during all 1-on-1 discussions, and especially having a mechanism for tracking action items for both yourself and your manager. I do that on my end for all my team, and share these notes in an email after each meeting, but using something more rigorous (like a ticketing system or task board) might be even better

Possible Agendas

Here is an example agenda I’ve used successfully:

  • Highlight / lowlight since we last talked
  • How can I help you this upcoming week?
  • What’s the status of your current annual goals?
  • Open discussion (you pick the topic)

And another agenda that also works well:

  • Personal check-in: how are you feeling?
  • Quick updates
    • Previous 1-on-1 action items
    • Tasks and projects
    • Current goals
  • Discuss current challenges and potential solutions
  • Recognize successes with gratitude
  • Create and review action items

And a third one:

  • Personal check-in
  • Task/project/goal progress
  • Review of priorities
  • Workload and expectations
  • Blockers
  • Feedback
  • Concerns

Discussion Questions

These are some questions I like to ask during a first 1-on-1 to learn more about how a person prefers to be managed:

  • What do you most need from me as a manager?
  • How do you prefer to receive feedback? In writing? In person? Another way?
  • How can I know when you’re struggling and need help?
  • Are there any manager behaviors that particularly bother you? If so, how can I avoid them?
  • What ongoing 1-on-1 cadence would be most helpful for you?

More generally, these are question I ask to help me as a manger how to make work more enjoyable:

  • What motivates you to perform at your best?
  • What do you wish you could spend more (or less) time doing?
  • At the end of the month/quarter/year, what would you like to say you’ve accomplished?
  • At the end of your career, what would you like to say you’ve accomplished?
  • If you could change one thing about work that would improve your life, what would it be?

These questions help me ascertain and guide someone’s career growth:

  • What impact do you think you’ve had so far? What additional impact would you like to have?
  • What aspects of your role do you love (or hate) and why?
  • What are you learning, and how are you growing here?
  • Is there a new project you’d like to work on? Or new goal you’d like to work towards?
  • What do you need training on? What do you need experience in?

Finally, these are question I ask to get feedback on my own performance as a manager:

  • How can the team improve its communication?
  • How can I help you be more successful?
  • How can we help you do more of what you enjoy?
  • How am I doing? What can I be doing better?
Automatic For The People

Automatic For The People

When I quit my first job after nearly 12 years, it was a shock to lose access to all the software I’d spent years developing. While I believe strongly in Egoless Programming, and resisting the notion of “my code”, so much reference material I’d built up was suddenly lost to me. I decided in that moment I needed to build up a portfolio that could not be taken away.

A few weeks ago I published Chrome Local Storage, a Python package that can read from and write to the Chrome’s browser’s internal storage, either one running locally or on an Android mobile device. The first draft didn’t have any CI/CD automation in place, but this weekend I fixed that.

It now automatically sets the version according to the git tag, runs some limited automated tests, runs a linter, scans both the code and dependencies for security vulnerabilities, and publishes builds to PyPI. All via Github Actions.

Did this project really need a complete pipeline? Not really, I doubt I’ll see much reason to modify it in the future. But I wanted to learn Github Actions, and I’d wanted to learn Poetry. Now I’ve done both, and have a publicly available reference to which I’ll always have access for when I need to build Python packages in the future. And if others need the same, they can use it as well.