Tag: Are Right A Lot

No Easy Answers

No Easy Answers

I’ve been managing technical people for a while now, but when it comes to asking good questions and listening well, I’m always learning. One thing I’ve discovered is that questions needn’t be complex to be effective. Here’s three I use regularly:

How do you feel about that?

Giving someone space to express their emotions is usually a good place to start when beginning a conversation. This is doubly true in the workplace, where there’s a misperception that feelings have no place. But we’re all human, and our effectiveness is predicated on aligning our emotions to the task at hand.

What could you do about that?

Once a person feels safe describing how they feel about a situation, it’s time to explore options for how to move forward. The word could here is critical, it’s a word about possibilities. Usually with just a little nudge, people will be able to come up with a variety of potential solutions on their own.

What do you want to do about that?

Too often people are asked to consider all sorts of factors when weighing options, but never their own desires. And especially not just surface desires, but what they truly want based on their own complex (and often competing and contradictory) web of values. It’s a powerful question; simple to ask, but hard to answer truthfully. Though once it is, I’ve found one often has all the data at hand to make a high quality decision.

Irreduceable Complexity

Irreduceable Complexity

“Make everything as simple as possible, but not simpler.” – Albert Einstein

In any technical discussion, beware when someone says something is simple. Things are rarely as simple as their marketing materials claim, and there is a vast gulf between a quickly-constructed proof of concept and a production-ready solution.

Even concepts that might seem straightforward at first glance have considerable potential for edge cases and other gotchas. Consider the following as canonical examples:

A corollary to the above: there is no such thing as a “5 minute task” in technology. When you hear such a claim, mentally multiply by 10.

Jud Flow

Jud Flow

Keeping a nice and tidy code repository makes me happy. Here’s the typical process I use to avoid messes:

  1. Create my-sweet-new-feature branch from main
  2. Make some awesome code edits, then commit them
  3. Make some slightly less awesome edits, commit them also
  4. Run some tests, nothing works; debug and commit the fix
  5. Decide my originally awesome code isn’t so awesome; rewrite the whole feature and commit
  6. Tests pass locally, yay! Push my-sweet-new-feature to Github and create a pull request
  7. Hrm, tests fail in pipeline; whoops, forgot a file; commit and repush
  8. Okay, tests pass now, so message team for review
  9. That’s a reasonable request, change made and committed
  10. Fine, we’ll use your naming convention; change made and committed
  11. Ugh, made a spelling error; committed
  12. Fixed moar typos
  13. Uggggggh, one last commit to fix spacing; pushed to Github
  14. Wha? Tests failing? :facepalm: forgot a file again
  15. Commit that file and push one last time for realz
  16. Tests pass, team reviews and approves, we’re good to go
  17. Pull an update of the main branch
  18. Come back to my-sweet-new-feature and rewrite all the commits on top of updated main; group edits into a clean subset of logical changes, one per commit, that makes it look like I wrote the code perfectly the first time, with nicely crafted commit messages that will mean something to some poor future developer that has to maintain my code ten years from now
  19. Run tests to ensure everything still passes; it does
  20. Force push to the pull request, obliterating all those ugly prior commits with these nice clean ones
  21. Try to merge the branch to main with fast-forward only option, forget that Github doesn’t support it (curse you Github! even flipping CodeCommit supports fast-forward only merging)
  22. Fast-forward merge my-sweet-new-feature to main locally so my final commit signatures are preserved
  23. Try to push main to Github, but it fails because the branch is protected
  24. Unprotect main temporarily, repush
  25. Dang it, someone merged new changes since step 17; repull main and rebase my branch
  26. Re-push my final changes and re-protect main

See how easy that is? No excuses moving forward, my friends!

Gut Check

Gut Check

It’s that time again: New Year’s resolutions! Per my meta-resolution, this year’s book reading target is 44, but I wanted to add a twist to it.

Leaders who are right a lot “seek diverse perspectives and work to disconfirm their beliefs.” In 2022, 16 of the 45 books I read in were by authors who were either not male or not white. That’s 36%, a sizable fraction; in line with what I did in 2021 (33%) and 2020 (38%), and much better than my rates in 2019 (18%) and 2018 (15%).

But none of those metrics are anywhere close to reality: about 91% of the world’s population is either not male or not white. That’s a lot of valuable perspectives I’m missing out on.

Given my backlog and some strategic book choices I have lined up, getting all the way to 40 out of 44 isn’t realistic, but I can still do better than my recent history. So in 2023, my plan is to double last year’s fraction to 32 out of 44 (73%). Ambitious but doable. And I can’t wait.

Already finished my first one, in fact: Radical Candor. And I’m a chapter into The Analects, by Confucius. It’s embarrassing that I’ve never read anything by this giant of ancient wisdom. Already found a couple sayings that stand out:

The Master acquires his information by being affable, kind, and respectful, and by showing restraint in his action and a willingness to yield. The way the Master asks for information is different from that of other people.

Do not worry that other people do not know you. But be concerned that you do not know them.

Good stuff!

Welcome Robot Overlords

Welcome Robot Overlords

Maybe I don’t actually need to learn a new programming language?

Naturally, I’ll have more to say on this soon. But I figured I’d also ask ChatGPT its opinion on the question:

It depends on what you want to do with programming. If you are just starting out with programming and don’t have any specific goals in mind, you may want to start with a general-purpose programming language like Python or Java. These languages are widely used and have a large community of users, so you can find a lot of resources to help you learn and get started.

If you have specific goals in mind, such as building web applications or mobile apps, you may need to learn a language that is more specialized for those purposes. For example, if you want to build web applications, you may want to learn HTML, CSS, and JavaScript. If you want to build mobile apps, you may want to learn a language like Swift (for iOS) or Java (for Android).

In general, it’s a good idea to start with a general-purpose language and then learn additional languages as needed to achieve your goals. This will give you a strong foundation in programming concepts that you can apply to any language you learn in the future.

That’s pretty solid advice for a newbie, but I’m far from that. Perhaps the human touch is still needed?

Zeros And Ones

Zeros And Ones

If you’ve never heard of Benford’s Law, it’s worth reading about this nifty statistical fact. The gist is that for certain types of data sets, the frequency of the leading digit follows a predictable pattern (with 1 being the most frequent by far). I decided to put it to the test by analyzing the total view counts for each post on this blog.

Leading DigitActual RatePredicted Rate
131.3%30.1%
227.7%17.6%
317.5%12.5%
47.8%9.7%
55.4%7.9%
62.4%6.7%
71.2%5.8%
84.2%5.1%
92.4%4.6%

I guess that’s why they call it a law, because the actual digit rates match up pretty well.

Speaking of which, apparently I also have a thing for named laws. If you do too, the article is worth it for this side note:

The fact that things are often named for someone who didn’t discover it first is common. In fact, there is a name for this, Stigler’s Law of Eponymy. It was proposed by the American statistics professor Stephen Stigler in 1980 when he wrote that no scientific discovery is named after its original discoverer. In an ironic twist, Stigler acknowledged that the American sociologist Robert Merton had previously discovered “Stigler’s Law”.

You Are Not Alone

You Are Not Alone

Every new beginning comes from some other beginning’s end.

It’s been a strange season for tech work, with the boom of the last few years (decades even?) feeling like it’s coming to a screeching halt. A lot of people suddenly finding themselves out of a job, wondering what’s next.

While I’m relieved not to have been affected this time, I’ve been laid off before, and I remember the feeling of helplessness. Of wondering if I should have known better or cut and run before things got bad. And most of all (though it took me some time to name it): loneliness. All the relationships I’d built up at the workplace, while not my best friends, were a large part of my social life, and to have them ripped away with no warning took quite a toll.

For those in that boat right now, know that it’s not your fault. Really, it’s not your fault. Take it from someone who’s been there (on both sides of the table): it’s not your fault. Take time to acknowledge your feelings. And while I can’t promise you that something better is just over the horizon, there might be! And that is an encouraging thought.

Kindness Trumps Rightness

Kindness Trumps Rightness

Regularly I’ll hear people claim “I don’t care what anyone says about me.” While I appreciate the sentiment of confidence such a statement is intended to communicate, I believe it’s unhelpful, for several reasons.

First, I don’t believe it’s possible. Humans are social creatures, and much of our mental software is set up to be concerned with our standing with other people. Some of us perhaps more so than others can set that aside at times, but no one can turn it off completely.

Second, living with disregard for others’ perspectives on your own life and actions deprives you of valuable wisdom. Of course one shouldn’t take all opinions equally, and one must discern how to synthesize the input of others with your own evaluations. But more data is rarely a bad thing. Listen, then decide.

Most importantly, however, is that knowing how those you come in contact with feel about you is a healthy way to measure if you’re having a positive influence on them. At the end of the day I want every person I interact with to come away feeling that their lives are better for having known me. That’s more valuable than pretty much any other measure of impact I can imagine, and it’s true both personally and professionally. Absolutely nothing is more important to your career than being kind. Not education. Not skill. Not drive. Nothing.

So yes, I care what everyone says about me. And you should too.

Meta Post

Meta Post

Really enjoyed Two Heads Are Better Than One, a discussion of the various ways technology has allowed humans to have “second brains.” I realized in some ways this blog is one such implementation; it’s a place I can capture thoughts and stories so that I can recall them later without keeping them in working memory.

As a bonus, via the article I discovered Obsidian, which I’m now dying to try out. I’m a sucker for Markdown and the power of plain text processing tools.

Expect The Unexpected

Expect The Unexpected

Like many other languages, Python has the notion of default values for function parameters, for example:

def compute_final_price(cost, sales_tax_rate=0.08):
    return cost * (1.0 + sales_tax_rate)

This code behaves as you would expect:

compute_final_price(10.0, 0.07)  # returns 10.7
compute_final_price(10.0)  # returns 10.8

However, interesting things happen in more complex cases, because the default value is evaluated once, at the time the function is defined, and not when it’s executed.

my_rate = 0.05

def compute_final_price(cost, sales_tax_rate=my_rate):
    return cost * (1.0 + sales_tax_rate)

compute_final_price(10.0)  # returns 10.5
my_rate = 0.06
compute_final_price(10.0)  # still returns 10.5

You can prove to yourself the value is evaluated at definition time by running help(compute_final_price), and you’ll notice the default value has already been computed:

Help on function compute_final_price in module __main__:

compute_final_price(cost, sales_tax_rate=0.05)

The above can be pernicious if the default value is an object that’s modified inside the function:

def add_to_list(item, my_list=[]):
    my_list.append(item)
    return my_list

add_to_list(4, [1, 2, 3])  # returns [1, 2, 3, 4]
add_to_list(1)  # returns [1]
add_to_list(1)  # returns [1, 1]

A common workaround for the above is to do the following:

def add_to_list(item, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(item)
    return my_list

add_to_list(1)  # returns [1]
add_to_list(1)  # returns [1]

I’ve encountered folks that insist one should never use default values except for None and the above pattern, but I’ve found most of the time I’m not mutating such defaults, and the behavior described here is fine. But still, the more you know.