Standing desk: A 1-year retrospective

In February, 2014, I started working >50% at a proper standing desk at my house. In the year prior, I occasionally worked at a make-shift standing desk in my kitchen, which comprised standing at the island and resting my laptop on a flimsy Disney Princess art tray. The ergonomics were obviously terrible, so I only did that for a short spell.

I had become enamored with the $22 standing desk and started planning my own. The final component was a proper monitor, which my employer provided in February. I followed the instructions to build the monitor / keyboard stand, and in no time I was in business.

Note: while the research on the negative effects of sitting all day is pretty convincing, I could not find much actual evidence that standing all day is healthy, either. Anecdotally it seems that at best, standing mitigates some of the problems associated with sitting all day, but there may be downsides, as well.

 

home_office

 

Retrospective

  1. A mat is essential. I bought this one for $50 bucks, and it’s served well. At some point I may consider a higher-quality mat of the type hairdressers use, which generally cost hundreds of dollars
  2. Using a wood(ish) stand on a glass desk immediately surfaced (bad pun) a problem: the monitor stand would slip around on the glass desk, sometimes nearly falling off. My wife fixed this with a simple $2 solution: anti-slip furniture pads, like these. After sticking those to the bottom of the stand, it hasn’t budged
  3. I move around, a lot. I stretch, I pace around the house, both inside and out. I do not stand still for hours at a time
  4. Although I’ve incentivized standing by making it the only way I can conveniently use the Thunderbolt monitor, if I am tired or want to sit, I have no problem unplugging from the monitor and sitting. In fact, I have a very comfortable chair just a few feet away, and if my body says sit, I sit
  5. A fair bit of my day is spent on phone calls and teleconference meetings where I don’t need to be in front of a large screen. I sometimes sit or walk during those times, such that my standing time is for actual work. In other words, I optimize my standing time for work where I’ll benefit from the large monitor
  6. I stand less in the summer, because I work outside at least half a day on most days. I tend to work outside till noon, take a bike ride, then come inside and stand for the afternoon when it’s uncomfortably hot outside
  7. Working from home can be isolating, and so positioning my desk to face a large bank of windows works wonders. I am constantly surrounded by natural light
  8. On the advice of a twitter friend, I am trying out compression socks to help alleviate the inevitable fatigue on the calves and ankles. I’m not wearing them every day, but I have noticed that my legs feel better in them. Psychological, perhaps. I’m going to experiment with different types of compression socks, as well

As for how it’s affected my health, I frankly can’t say. Despite standing for a year and riding my bike nearly year round now, including training for and completing 2 full centuries, I didn’t experience “weight loss for free.” Nor can I say that I focus better now, probably because for me focus while working remotely has never been a problem. Perhaps the most noticeable effect is simply that I have no problem standing for 6-8 hours a day. If the practical benefit of standing for a year is getting better at standing, I’ll take it.

Making it habitual

Going from full-time sitting to part-time standing is hard. To make it stick — to make it a habit — I had to make the reward of standing immediate and meaningful, not just the hope of potential health benefits that are still not definitive. The keys for me, mentioned above but emphasized here, were:

  1. If I stand, I get to use a large monitor; if I sit, I am stuck with a 13″ screen
  2. Position the desk so that I am always looking out a window and not at a wall

I realize that both of those are a result of incredible privilege. I think I could’ve made it stick without those, but it would have required a lot more grit and willpower, for me.

I’m glad I started standing, I’m proud I stuck with it, and I’m certain I’ll keep doing it. I’ve gotten to the point where standing for work is just… the way I work now.

At the end of the day, shut it down

This is a story about habit change, told via two recent examples related to work/life balance. I’ll conclude with some recommendations on how to apply this to your own life.

The setup

To improve at “living in the moment,” to be more present during non-work hours, and to more effectively balance work and life, I’m working to eliminate two small bad habits:

  1. checking work email off hours
  2. using my work laptop to do, well, work, during off hours

Important detail: I work from home, so leaving work devices at the office isn’t an option. Now then:

I initially thought a few small tweaks and a good dose of self control would do it. First, I shut off the audible alarm on my phone when emails arrived. Second, I shut down the laptop lid and disconnected it from the external monitor. Neither worked, at all.

I’ve been reading  the excellent “Thinking, Fast and Slow” to learn more about why we make the judgments and decisions that we make. And while reading, I learned that our willpower is at our weakest when our energy is drained (not the stuff of rocket surgery, surely). It’s no surprise, then, I’ve been having trouble breaking habits through willpower when it’s at my lowest energy times of day that these behaviors emerge. In addition, I needed to ferret out the cues that trigger these habits, and either eliminate the cue or replace it with a new response.

To change these behaviors, I needed to stop relying on self control and instead remove the need for it in the first place.

When work is finished, it’s finished

When starting my current job in January, 2013, I was issued a phone and a Mac. The phone simplifies checking email, and the Mac is generally a fine developer machine — largely thanks to iTerm and homebrew — especially compared with my personal Windows laptop. More on that later.

Shut off the phone

nobbImage credit

I always keep the work phone turned on, and I noticed that several times a night after work, and several times a day on weekends, I’d find myself checking it for email. “Why would I do this?” I’d ask myself. I had no idea. Not infrequently, the result of checking would be some email that would add intellectual or emotional burden off-hours until I could deal with it when I logged back in during the next work day.

So, time for a new habit: Every day, when I finish working, I shut off the phone. Simple, effective. It adds just enough friction, making it easier to achieve the behavior I want, which is stop checking work email off hours.

By removing the cue — the beep or red blinking light of an unread email, or even simply being near the device — I short-circuited the habit loop. By creating an environment where checking email would actually require energy and patience during a time of day when they’re in short supply, and not just a mindless tap-tap-tap, I removed the reliance on willpower.

The year of Linux on the laptop

tuxImage credit

The second habit I needed to break was using my work Mac for personal stuff, namely evening and weekend web browsing and personal coding. I noticed that I’d sit down to read something, learn something, or do some play coding, and a half hour later I was logged in to the work VPN, checking GitHub pull requests, looking at Jenkins jobs, or glancing at Graphite graphs of a production environment. It’s not that I needed to do this off hours as part of my job duties; rather, by simply being on the machine, it was easy to do so, and usually enjoyable. For example, if I had a fun coding or system configuration problem to solve that went uncompleted by end of day Friday, it was common for me to inadvertently find myself working on it Saturday morning. It looks like this:

  1. Fill up coffee cup (just like any work day)
  2. Open work computer (again, like any work day)
  3. Browse the news (like any work day… see a pattern?)
  4. Oh, look, there’s the Jenkins tab I had open Friday afternoon… I’ll spend 5 minutes on that
  5. 1 hour later….

Just in that small set of steps, you see the classic patterns of habit that Charles Duhigg describes in The Power Of Habit: Cue, Response, Reward.

In the case above — which is representative of so much of my heretofore off-hours time spent on my work Mac — the cue is a morning routine (coffee, computer), the response is “work on problem”, the reward is “solve problem, yay!”

The thing is this: Because I have my development environment set up just so on the Mac, it’s much easier to do personal development / learning on it. A large part of that is that most non-Windows tech stacks are much simpler to install and use on Linux environments. Enough so that after just a few months on the Mac, I quit using my personal computers for new development (freelancing excepted) because the Windows experience was so suboptimal in comparison.

Breaking the work-Mac habit started with this question: what is it about developing on a Mac that is so enjoyable? And then, how can I get that on my current Windows laptop? In other words, if the cue to doing off-hours work stuff on the Mac is “open Mac,” how can I avoid doing so in the first place?

The answer was to make it more enjoyable to work on my personal laptop than it is to work on my work Mac. Considering that my personal laptop is a much bigger 17″ Samsung Chronos with much more screen real estate and is arguably more powerful than the 13″ Air, it came down to operating system. My personal laptop is Windows, and that had to change. Considering that when I’m on a Mac my most used apps are iTerm, Intellij Idea, and a browser, I figured: it’s not OSX per se that I like; rather, it’s a solid terminal and great package management (i.e., homebrew). The natural choice then was, of course, Linux.

You’re laughing at me. You’ve been running *nix on your personal machines since 1969. I know. Moving on…

I started by using Vagrant and an Ubuntu VM, but that didn’t stick. I wanted a full desktop experience, not a mediated one.

After asking around for opinions, I then settled on Ubuntu Gnome installed side-by-side on my current laptop. Installation was painless, and the dual-boot experience works great. In addition, Ubuntu Gnome has proven to be intuitive and just works.

Consequently, because the development environment on my personal machine is now more enjoyable than on the work-Mac, I no longer use the Mac for non-work activities. As a result of shutting off the phone, and not being incentivized to use the work computer, when work is finished for the day or week, it’s finished.

Without the tiny but noticeable distractions that pull one out of presence — the blink of a new email on the phone, the ease of a work-related eye-catching distraction whilest doing personal development on the work computer — it’s easier to truly disconnect from work for essential recharge.

Learn more on habit change

This sounds so simple, doesn’t it? To the point where any reader would be right to ask: “Why in the hell are you writing about this?” Here’s the point: these same mechanisms — the habit loop, willpower, self-control — are at the heart of behavior change for everything as small as not checking work email off hours to as large breaking cycles of addiction. They are not the whole story, but they’re an important component. Note: this is not easy! Well, shutting off a phone is. But that is about the simplest case you could wish for. Changing ingrained habits can be seemingly impossible, even when you understand the cue-response-reward habit loop. If you’re interested in learning more, I strongly recommend The Power Of Habit and Thinking, Fast and Slow.

Start with a small habit you’d like to break. Find a way to remove the habit cue entirely, as I did, or change some other part of the cue-response-reward cycle. And find ways to remove the need to rely on willpower. Like most things, habit change can benefit from practice. And by practicing the mechanics of behavior change on even the tiniest habits, we better prepare ourselves for more difficult ones.

Go: Working effectively with database nulls

This post covers how to marshall null values from a database into a Go struct type and how to save nulls back to the database. I’ll cover the standard library’s sql.NullString, NullInt64, NullFloat64, etc types — which I’ll refer to as sql.NullXYZ when indicating the collection of types and not a specific Null type — important methods on those types, telltale errors, and some helpers for working with values coming from form posts.

This code uses SQL and the standard library.

Takeaways

  • In structs, use sql.NullString, sql.NullInt64, and its ilk instead of string and int for fields that persist to a database and are nullable
  • For display, use type.Field.Value instead of type.Field.String/type.Field.Int64/etc
  • Use helper functions to populate sql.NullXYZ types from strings

Telltale error

sql: Scan error on column index 1: unsupported driver -> Scan pair: <nil> -> *string

Given a type Member and a function for fetching data:

type Member struct {
	Username                string
	SomethingOptional       string
	SomethingOptionalInt    int64
}

func (s *MemberService) GetMembers() []Member {
	memberRows, err := s.DB.Query(`select username, somethingoptional from members;`)
	PanicIf(err)
	defer memberRows.Close()
	members := []Member{}
	for memberRows.Next() {
		m := Member{}
		err = memberRows.Scan(&m.Username, &m.SomethingOptional)
		PanicIf(err)
		members = append(members, m)
	}
	return members
}

The Scan error ... Scan pair... is coming from memberRows.Scan(&m.Username, &m.SomethingOptional) and indicates that the database driver isn’t sure how to stuff a nil into a *string. Note that the loop above may work fine for a few iterations but will issue this error as soon as it hits a row where the nullable (“somethingoptional”) column has a null value.

sql.NullXYZ types

To remedy this, in the struct replace string with sql.NullString. See the docs for the handful of NullXYZ types.

Your code will now look like:

type Member struct {
	Username                string
	SomethingOptional       sql.NullString
	SomethingOptionalInt    sql.NullInt64
}

With that one change, the error should be resolved.

Displaying sql.NullXYZ types

The sql.NullXYZ types have two fields: a typed value and a boolean Valid. You can use the typed value to get either the value that’s been set, or the type’s “zero value” if it hasn’t been set. For example, on field with type sql.NullInt64, you can use SomethingOptionalInt.Int64 to get a number that’s been set, or 0 if it hasn’t.

However, when displaying those fields, you often don’t want the zero value if it’s not set. In Go templates, use Value:

  Some optional int: {{.Member.SomethingOptionalInt.Value}}

Saving sql.NullXYZ types

As with SELECT, your INSERT and UPDATE SQL won’t change as a result of using sql.NullXYZ types. However, there is a gotcha.

Given the following code:

_, err := s.DB.Exec(`Update members set somethingoptional=$2, somethingoptionalint=$3 where id=$1`,
		member.ID, member.SomethingOptional, member.SomethingOptionalInt)

The driver calls the type’s Value() method, which in turn checks first if Valid is false. If false, it returns nil for the value, and consequently the column will be NULLed.

For inserting and updating these types, to ensure null values are set when the type has its “zero value”, you must ensure that the Valid field is set to false. When you do that, DB.Exec() calls will work as expected.

Creating a new instance of the type thus looks like:

member := Member{Username:"banjer", SomethingOptional:sql.NullString{String:"Pickin", Valid:true}, SomethingOptionalInt:sql.NullInt64{Int64:0, Valid:false}}

The tedious part comes when changing one of those NullXYZ fields from valid to invalid, and vice-versa:

member.SomethingOptional = sql.NullString{String:"", Valid:false}
member.SomethingOptionalInt = sql.NullInt64{Int64:42, Valid:true}

Helpers for sql.NullXYZ types

Ensuring that Valid is set appropriately will get tiresome after about 1 form field, so use helpers to avoid duplication. Something like this will get you started:

//ToNullString invalidates a sql.NullString if empty, validates if not empty
func ToNullString(s string) sql.NullString {
  return sql.NullString{String : s, Valid : s != ""}
}
//ToNullInt64 validates a sql.NullInt64 if incoming string evaluates to an integer, invalidates if it does not
 func ToNullInt64(s string) sql.NullInt64 {
   i, err := strconv.Atoi(s)
   return sql.NullInt64{Int64 : int64(i), Valid : err == nil}
 }

Working with Queue and Stack people

My colleague and friend Clinton told me once about himself (I’m paraphrasing): “I’m a stack, not a queue”.

This is not a post about queue and stack data structures, but about people and their behavior biases toward task management. I’m focusing this discussion on tasks that represent defects to be fixed, quick-win feature additions, and other short-term tasks. These are tasks that can probably be completed in a few hours to a few days.

I’ll describe these biases and how they manifest for different types of people in their emotional and behavioral responses to incoming tasks. I’ll also describe how these different responses can create conflict on teams, with a goal toward helping managers and colleagues understand the behavior, how to work well with people of different task management bias, and how to create conditions for success for these different types. My audience comprises coworkers, managers, and project managers on software teams, although this probably applies to other fields.

Until Clinton described himself as more of a stack, I hadn’t thought of people’s dispositions toward task management in that way. Importantly, and I hope obviously, these are not rigid slots into which people fall; rather, they’re biases or defaults, and people distribute across the spectrum.

We can use these biases as a lens through which to view how new tasks cause joy and pain for queue and stack people.

Disclosures

  1. I consider myself a queue person, though certainly for much of my career as a programmer I treated all production bugs as stop-the-world events
  2. The behaviors described here are amplified for clarity

Queues and Stacks

When you’re standing in line to order coffee… that’s a queue: first come, first served. If you have a long, narrow, single-door, multi-car garage that fits a single-file line of cars… that’s a stack: last in, first out.

In the context of task management behaviors, queue and stack people respond differently to a new incoming task that meets the criteria described above (think: fast food, not catered wedding), both emotionally and behaviorally.

When a new task comes in, a queue person prefers to quickly prioritize and position the task in the list of work to be done, or leave it unprioritized and put it at the end of the list for future prioritization and eventual completion. In terms of emotional response, a queue person is generally comfortable leaving new work undone.

stack person, on the other hand, treats incoming tasks differently. Instead, new tasks must be dealt with swiftly. A stack person is generally uncomfortable — sometimes greatly so — leaving new work undone.

We all seek joy and avoid pain; let’s look at how that plays out in the context of queue and stack people at work.

Shared motivations

It’s obvious, but probably bears repeating: very few people actually enjoy a constant barrage of critical production bugs. Some might thrive in this environment, but they’re outliers.

By and large, most people derive joy by delivering high value, not fixing broken things under pressure. Both queues and stacks share this positive motivation. Delivering value by executing on a prioritized list motivates queues and stacks alike.

Queue Motivations

Queue people are pained by seemingly important tasks that languish for months or years. They want to see important tasks get their fair shake and are frustrated when other tasks “butt in line”, especially at the front. Constantly shifting priorities infuriate queue people. Queue people are generally pained, not pleasured, by firefighting emergencies.

Stack Motivations

Most of the above motivations apply to stack people, as well. The differences are that stack people are either particularly pained by, or derive significant joy from completing, new tasks that, as I wrote earlier, represent defect or quick-win. For the former, they’d rather alleviate the pain of the new task as quickly as possible, so that they can get back to deriving joy from whatever they were working on. In a bad case, this person gets hit with multiple new tasks, and spends hours or days trying to end the pain.

For the latter type, new tasks often represent a quick opportunity to accomplish something. Whereas a queue person might prefer to hold off on the quick win in favor of completing the currently highest-priority task, a stack person is more willing to stop the current work and get the quick win because it’s incredibly satisfying (I suspect there’s a chemical component… adrenaline rush, for example).

How queues frustrate stacks

Queue people frustrate stack people when a queue person doesn’t drop what they’re doing to attend to some new problem. It plays out like this:

Stack: “Hey, we have a problem. We should not have this problem.”

Queue person responds by trying to determine the urgency of this problem. Is anyone dying or at risk of death or imminent harm? What is the consequence of not working on this problem right now? Upon determining life and liberty are not at risk: “OK. File an issue and we’ll prioritize it and deal with it when it’s appropriate to do so”

Stack: “But it’s a problem now! It’ll just take a few minutes to fix it. We shouldn’t let these kinds of broken windows stay broken. Paint over the graffiti. Avoid the technical debt! We’re better than this! Be brave! Be bold!”

Another way this might play out is in the arrival of a quick-win opportunity.

Stack: “Hey, check out this awesome thing we can do to increase performance by 25%!”

Queue person knows that any performance boost is welcome, but it’s not really urgent right now and so is willing to backlog it. Queue might also be thinking about all the implications of the fix, the testing effort, and so forth. That kind of trepidation is particularly relevant in less mature, more brittle production environments where the risk of deployment is higher. “That’s great! It’s not urgent right now but it’s great you’ve identified a win. Let’s talk about it next sprint”

Stack: “But I can fix it in a few hours!”

Stacks can perceive queues as lazy, risk-averse, timid or even cowardly, unresponsive, slow, and unconcerned about the present, sometimes failing to seize opportunity, with their eyes so far down the road that they don’t see the bear that just jumped out in front of them.

How stacks frustrate queues

Stack people frustrate queue people when a stack person drops what they’re doing to attend to some new problem, especially when that problem is not urgent.

Queue: “Hey, we have a problem. We should not have this problem. But it’s not urgent, so I filed an issue and we’ll prioritize it during our next team planning session.”

Stack person looks at the new task, knows exactly how to fix it, knows it won’t take long. Stack person responds several hours later: “I fixed that problem.”

Queue person is now conflicted, because the problem being gone is certainly a good thing. However, it came at the expense of whatever the stack was currently tasked with, and that task was probably agreed on by the team as high priority. In this case, the queue is frustrated because a lower priority task was worked instead of a high priority one.

Another form of conflict arises when a stack delivers a quick-win, especially when it benefits the queue coworker. In this case, the queue is obviously grateful for the stack’s work, but knows it came at the expense of something else. The queue person also might feel envious or left out because he had hoped to work on that task when the time was right.

Another way stacks frustrate queues is by pestering the queue to deal with an issue that the queue has decided is not a priority.

Queues can perceive stacks as unfocused, reckless, too eager to please, wanna-be heroes who focus on short-term tasks at the expense of long-term goals. Stacks can also be perceived as miracle workers.

Implications for teams

Knowing that a coworker has a different bias toward task management is probably the first step toward developing empathy for that person’s response to new tasks.

Queue people need to understand that a new task, for a stack person, represents considerable potential pain or joy. For tasks that represent pain that must be immediately alleviated, it’s not that the stack feels I must fix it; rather, this must be fixed. The task is painful not because the stack must fix it, but because it exists, period. In software, this typically manifests as bugs in production or as a new-found opportunity to improve some broken or suboptimal thing. When that production bug comes in, the pain is particularly acute when there’s simply no one else to solve the problem. A stack person will have a hard time doing anything else until they fix it. Regardless of whether the pain is emotional or  physical (pit in the stomach, headache, etc), it’s very much real. A well-staffed, diverse team is a great defense here. If the stack person knows it’s Johnny’s week for triaging production bugs, that’s probably good enough for this problem to not be such a painful distraction.

Stack people need to understand that a new task, for a queue person, will put their current prioritized task at risk if they drop it and attend to the new thing. Stacks must understand that queues derive joy from working on prioritized, long-term goals and are pained by any new thing that interferes with its completion.

What are teams to do when staffed with a mix of these personality types? How does a team deal with the potential conflict?

Some ideas:

  • Building large blocks of time, uninterrupted by meetings, into team members’ schedules
    • This is especially helpful for giving stack people enough time to get so far into a challenging problem that a new task’s potential pain/joy is less than the joy derived from solving the current challenge
    • Likewise, it benefits queue people by giving enough time to make good progress on tasks that take days/weeks to complete
  • Rotating bug triage and collectively sharing bug fixing
  • A separate, rotating team of people whose purpose is to respond quickly to new tasks
  • Bug reporting mechanisms that don’t immediately put bugs on the team’s windshield (i.e. goes to manager or support team first for classification, prioritization, even assignment)
  • Building time into software schedules for fixing broken windows / paying down technical debt
    • These are all helpful for stack people who either must alleviate the pain of new tasks and who derive joy from quick-win improvements
  • Strong team leads whose priorities don’t shift with the wind
    • This is especially helpful for queue people pained by constantly being bandied about
  • Having these different working styles pair on quick-win tasks can help queues alleviate their frustration at a stack who otherwise would’ve done the work on his own; this pairing also helps the stack get insight into what the queue considers valuable
  • Also for quick-win tasks, when possible seek alignment with longer-term goals. It’s often easier for a team to absorb the absence of a stack who spends a few hours or a day getting a quick win if they know it will pay off on something that is already prioritized
  • Delegating both urgent bugs and quick wins to junior staff when possible, or at least as triage. This helps develop talent and trust, helps keep queue people focused and stack people not driven mad.
  • Driving down the risk of deploying quick wins.

The subject of heroics deserves closer inspection. A toxic work culture encourages and even rewards team members for prolonged or frequent engagement in the unhealthy behavior of “going the extra mile”. Tally up the extra nights and weekends worked over the course of months, and you’ll get a quick gauge of this in a team. Occasionally this is necessary, but when it’s a pattern, it’s cancerous. You see these patterns in teams that are either constantly fighting production fires or trying to get new features out the door ASAP for deadlines real and imagined. See http://burnout.io/ for help.

Organizations should discourage this heroic behavior. But there’s an implication here especially for stacks. Clinton tells me about himself, “I love being the hero.” I do not believe this means “teams should encourage unhealthy behavior to give others an opportunity to be heroes”, and I don’t think Clinton meant that, either. For stacks in particular, wiggle room is helpful and motivating as long as it doesn’t turn into a pattern of disruption. For example, if a new quick-win task comes in that a stack is psyched about, and which delivers value in some way to the team / product / customer, healthy teams should build enough wiggle room in the schedule that, in consultation with the team / project manager, the stack is cleared to work on that quick win. High fives all around and back to business.

The risk here is that it becomes pattern or disruptive. High-trust, high-communication team culture is essential for striking the balance. For example, I need to be able to say to a stack, “I know you’re jazzed about XYZ that just came in, but we really need to ship the feature we’ve been working on for a few days. After that, we’ll revisit XYZ.” The stack needs to trust that XYZ will not fall into a hole, too. Another risk here is that too much of this — especially with praise for these types of tasks that is not equal to praise for daily gittin-it-done, can pressure queues to start engaging in more quick-win seeking because that’s where the rewards lie.

Simple structure may be the best guardrail here. For example, allocate a certain number of hours or points per sprint / time period for quick win features and paying down technical debt.

In short, provide wiggle room for quick wins but tread carefully and warily and monitor impact on the team.

All of these will probably seem obvious. I think it’s interesting to look at them from the perspective how they help address the needs of queue and stack people.

Implications for managers

Managers must be aware of these different task biases and how they motivate people, but especially when it comes to performance reviews, ratings, incentives and reward structures, and so forth. A manager who generally tends to reward heroics and quick completion of new tasks, or who doesn’t empower people to say “No” to incoming tasks, for example, puts queue people at a  disadvantage.

Likewise, managers must understand for stack people just how debilitating the effect on morale and job satisfaction can be if the environment is one where all things must be dropped to deal with every production bug. Whereas some are content with backlogging noncritical bugs, a manager who expects that all production bugs get addressed immediately will wear the team out in no time, and the stacks will likely bear the brunt because they are traditionally the ones hailed as the go-to fix it people. Just because a person frequently saves the day doesn’t mean they like it or that it creates an environment in which they want to work.

If job satisfaction is a top predictor of a high-performing team, then managers will do well to understand the motivations of queue and stack people and how to create conditions for both types to be comfortable and successful.

Thanks

Special thanks to Clinton Dreisbach for critical feedback.

Intellij IDEA: Running your own Go programs against editor text

In this post, I’ll describe one approach to running programs written in Go against text in the IDEA editor. This same approach applies to any Jetbrains IDE, such as PyCharm or WebStorm.

Admittedly, this is niche.

Tracking time at work

Number 1: Every few weeks, I need to submit a virtual time card. If I work over 40 hours, I need to note that for comp time. If I work under 40 hours, I need to fill it in with PTO.

Number 2: I work on several projects, and I need to track what percentage of my time I devote to those projects. This isn’t for a boss or paperwork: this is for me. I compare the percent of time I know I’m supposed to work on a project with the amount of time I actually spend, and I adjust accordingly.

Solving both of these problems hinges on tracking time accurately. If I have an accurate record of my time, then I can update a spreadsheet at the end of the day that keeps track of percent time spent on each project and also shows total hours each day, with a weekly summary. With that weekly summary, updating a time card website is trivial. Consequently, the ease of solving these problems directly correlates with the ease of updating the spreadsheet.

At the end of the week, the spreadsheet looks like this:

Screen Shot 2014-04-29 at 8.02.02 AM

Unfortunately, counting up time spent on each project at the end of the day, and then updating the spreadsheet, is annoying and time-consuming and I’d prefer not to do it. That’s where Go comes in.

How I track time

I rather obsessively track, to about 15 minutes of granularity, what I work on, slotting the tasks into predefined categories (projects).

When I’m not on the phone or in meetings, I spend the rest of my day either in a terminal or some Jetbrains IDE. Since I spend a lot of time in an IDE, that’s the natural place for me to track time.

At the start of each day, I roughly plan the day. This is typically aspirational, but at least it’s a guide to help me visualize how I’ll spend my time. On my file system, I have a directory called “memory_hole” where I keep personal stuff like this, and I have a single file called “where_the_time_goes.md”. If Intellij is open, that file is open, and I use it to guide my weeks and days. Yes… I track my time in markdown.

A block of time looks something like this after planning the day:

 - 615 - 645: RM: respond to last night's emails
 - 8 - 915: RM: Prep for presentation
 - 915 - 930: CFG: Standup
 - 930 - 1130: RM: Start FAQ
 - 1 - 4: CFG: Pick a bug and fix it
 - 4 - 415: CFG: submit CR for deploy user

The format is:

- from_time - to_time: category_abbreviation: details

As I work throughout the day, the times change, things drop off, things get added… how life works. At the end of the day, I have a final list that shows what time was spent on which categories. It looks exactly like the markdown list above, except that it is final and accurate for that day.

How I use Go to tally time

I wrote a Go program named sumday that takes as its input a block of text like the one described above and returns a map, keyed on category, of time spent on that category. Its output is trivial. For the above chunk of time, it will emit:

map[rm:3.75 cfg:3.5]

With that map, I can then go update my spreadsheet, finding each corresponding category and plopping in the number.

Still, that’s tedious. And also: how do I even feed that chunk of time into the program in the first place?

The solution: Clipboard!

In addition to the sumday program that tallies time, I have a command that uses this great little Go package to read from the system clipboard and write to it.

If I can get that block of time onto the system clipboard, then I can run sumday, have it read the system clipboard for its input, and it can do its thing. That simply means highlighting a block of text in my editor, copying it, and then going to a shell and running sumday and then looking at its output.

Still, it’s annoying to read the map that sumday emits and then go plug in the numbers into the spreadsheet. Consequently, I use the clipboard package to have sumday emit a string, onto the clipboard, formatted in such a way that I can just put my cursor into a single spreadsheet cell (see screenshot above), hit paste, and populate the entire row.

Bottom line: in my editor, I can highlight the block of time, copy it to clipboard, run sumday in a shell, and then go back to Excel and paste in the string that sumday stuck back onto the clipboard. It’s a lot of moving around, though it only takes a few seconds in practice.

Still, it can be better.

How I wire this into Intellij

Since the block of text is in Intellij, it’d be nice to simply highlight it and then somehow run sumday right from within Intellij, via a keyboard shortcut, such that I can cut out the middle-man steps of copying text and then running sumday in a shell.

This involves 3 steps:

  1. Create a new External Tool that points to sumday
  2. Create  a macro that copies whatever chunk of text is selected in the editor and runs that External Tool
  3. Assign a keyboard shortcut to that macro

This 3-step process is nearly identical to the one describing how to run goimports on file save and so I won’t repeat it here.

With all this in place, at the end of the day I simply highlight my block of time, hit my key combo (splat-alt-S), and then go paste the clipboard into the spreadsheet.

Conclusion

This all started with an annoying problem and a desire to solve it, though all of this might seem like building a faster horse (or a process that should be taken out back and shot!). I’ve tried a few online time tracking apps, but none so far have suited me. (yeah yeah, I know… time tracking in markdown… get off my lawn). If you have a preferred time tracking app with support for categories, weekly rollups, percent-time-per-category, please let me know about it.

I used Go because that’s the language I’m learning at the moment and I quite enjoy programming in it. I wired it into Intellij because it was logical to do so.

With this one program, in addition to solving a problem, I learned:

  1. Go’s excellent Duration type
  2. Ginkgo and Gomega for BDD in  Go
  3. How to use clipboard to bus stuff back and forth between the IDE and a Go program