Saturday, March 14, 2020

On Prioritization: Your Team Structure Articulates Your Goals

Of the three legged stool that defines the controllable outputs of development of a software system
  • Features
  • Performance
  • Stability
it's self evident that everything comes at a cost; you have to employ prioritization to determine what gets the most focus.

More time spent on features equals less time spent on performance and stability, and vice-versa.

Imagine having a development team that has 1,000 hours of capacity. How do you split the time? 333 1/3 hours per output? Are you feature driven: 600 hours spent on features, 350 on performance and 50 on stability?

Everything is a choice.

Note, I'm specifically avoiding what might be called Engineering as a controlled output. Mostly, customers don't directly notice Engineering - they can't tell if my interfaces are clean, if I'm employing a single responsibility principle, or my code is a spaghetti mess of variables named x1, x2, x3, ... x999 looking like it was produced by a poorly written minifier.

Certainly Engineering is indirectly noticed, as poorly Engineered software requires more resources to add Features, is less likely to be Stable, etc. That frequently manifests over the software system's lifetime.

So, we have our software system, and we've made our choices about who is working on what, and for how much time.

Easy peasy, right?

Maybe. Maybe not. There are other inputs to this problem. 

Regardless of the time allocation, how have you segmented your development teams? 

If your teams are aligned around a Feature, they're going to have a Feature mindset. They will communicate with other teammates about Feature implmentation. Regardless of direction around resource allocation, Features will be artifically weighted.

I'm being delibarately provocotive here. Many of us, myself included, are used to teams with Feature segmentation. For developing a software system of any complexity, it just makes sense - separate into feature based bounded contexts, and throw a team on each context.

I challenge myself to not default to that muscle memory way of team creation, and to be considerate to organizational structure when laying out goals. 

Pasta de Olio and Mushrooms

crazy easy


  1. make pasta
  2. olive oil glug
  3. garlic, pepper, italian spices (bonus points for fresh basil)
  4. cook a bit
  5. chopped mushrooms, big dollop of butter
  6. cook a bit more, throw on some salt
  7. small dollop of pesto
  8. cook a bit more
  9. stir in cooked pasta to lap up all the good bits

Sunday, March 8, 2020

Effective Online Meetings

As more employers are contemplating work from home due to concerns around spreading coronovirus, I want to share some of my random throughts around how to have an effective online meeting, regardless of underlying technology (Microsoft Teams, Cisco Webex, Zoom, etc.)

I've been primarily working from home for the past 13 years, so I've gotten a lot of practical experience.

  1. Use your camera (assuming bandwidth supports it). It's better to see faces and pick up on the nonverbal cues that we use for communication.
  2. Mute and unmute quickly. This will limit background noise and allow the speaker to be more focused. My tech (Microsoft Teams) has a software mute button, but I prefer the hardware mute button on my headset, because I can quickly press it, share my thoughts, and then mute myself without much effort of reaching for the mouse. 
  3. Keep it light. Meetings are less effective when people go in scared to contribute. I like to start things off light (a couple of bad dad jokes maybe), introductions to participants that I don't know or don't know each other, and then try to get into a groove of productivity.
  4. Give time back. If you've accomplished what you need to accomplish, no need to stay on for the entirety of the scheduled time. People are busy. Give them time back to do their things.
  5. Consider recording. Generally, recording is cheap / free. If anything about the meeting feels relevant to others, start off by recording (I like to announce the date & subject at the beginning). This can be a tough one, as recording can make some less likely to contribute. Also, recording should not take the place of good note taking with action items. I'd rather browse a well written set of notes than sit through a 30m recording to discover outcomes.
  6. Play. The underyling tech is your tool. Learn how to use your tool. Learn how to screen share, learn how to record, etc. I will sometimes grab coworkers that are friends and (if they are not busy) have them join an impromptu meeting where we play with features of the meeting tech. Play yeilds familiarity, where you can use these tools effectively and be a tech leader in your organization.
  7. Phrase questions in the negative. When I assume that everybody understands what I've been talking about, I will say "shout if you don't understand", and then give a healthy pause. I don't get visual cues about understanding like I do with a real life conversation, and having everybody vocally assert the positive ("yes, I get it") gives a lot of unnecessary cross talk.
  8. Pause. There is a sub 100 millisecond delay that we have online that we don't get in real life. Account for that by communicating an idea, and, especially if it's controversial or tough, give a healthy pause for others to participate.
  9. Enable participation. If there is cross talk with different people trying to talk at the same time, the meeting organizer should be the "switchboard operator" and let each of them go in turn. If you have cross talk with somebody else, do the polite thing, and let them go first. For some of my regularly scheduled meetings, I also like to force participation: everybody talks (gives a status). 
  10. Focus. I have 4 monitors in front of me. They can be very distracting, and meetings are not the place to multi-task. I like to minimize all other windows, have one monitor dedicated to whatever is screen shared, and one monitor dedicated to the participants view. The more focused, the faster we can accomplish what we need, and the faster we can get out.  

Thursday, April 11, 2019

Cardamom rice

I am in a Indian cooking mode right now, doing a ton of chana (chickpea) dishes.

This is my current favorite "base", just a simple rice.

Full vegan (but still, no crossfit).


  1. Throw a small dollap of coconut oil in a saucepan, medium heat
  2. 1 cup Jasmine rice in said saucepan. It's a whole new world
  3. 1 tablespoon garlic in there as well.
  4. 1 teaspoon ginger. My local schmaldi sold ginger-in-a-tube and I bought all of them. This has been transformative to my cooking, as cutting ginger into appropriate sizes is a PITA to me (but I still do it. Ginger, I can't quit you).
  5. Healthy shake of ground cardamom. Maybe someday I use real cardamom pods. One can dream...
  6. Some season salt.
  7. Stir a bit, Let cook for 2-3 minutes. Burn rice, BURN! (I kind of like the blackened bits when all is said and done).
  8. Put in 1.5 cups of water. Stir, so the blackened bits at the bottom are not fully stuck to the pan.
  9. Jack up the heat to boil
  10. When full rolling boil, turn down the heat to simmer, 1 final stir & cover.
  11. Ask Amanda to set a 20 minute rice timer.
  12. When done, uncover, stir, enjoy!
This worked really well with my lunch chana masala yesterday. The kinder devoured it as well, with fake Doritos.

Tuesday, April 9, 2019

Vegan avocado cream sauce

Old joke: If you were a vegan who did crossfit, what would you talk about first?
I'm neither, but found this recipe delicious. The kinder devoured it as well.
  1. 1 large avocado
  2. tablespoon of garlic
  3. tablespoon of basil pesto
  4. small handful of cherry tomatoes
  5. healthy squirt of lemon juice
  6. salt, pepper, Italian seasoning
  7. glug of olive oil
Throw in a food processor & puree. Chunks of tomato will be left over. Admire their redness.

Toss over some pasta. Throw some Parmesan cheese on top. 

I haven't tried it yet, but I bet this would be lovely with some toasted pine nuts

or (better yet) saute some asparagus in butter just enough so that it's still crispy, toss pasta over the asparagus and then throw on the creme sauce.

Totally vegan, so +100 points from those who are keeping score.

Friday, April 5, 2019

The quest for the perfect hard egg

I love hard eggs. I'm a 49 year old man, and I love hard eggs. I have one for breakfast every damn morning. Along with French press coffee. So much French press coffee...

Notice, that I said hard eggs. Not hard boiled. I take great delight in annoying those around me (especially my wife) in my quest for precise language. I was going through a period where my hard eggs were done in my bamboo steamer, after I breakfast on a trip to Guangzhou. Thus, hard eggs, with no unnecessary information about how the hardness is achieved.

Sadly, I burned the hell out of my steamer (I need to pick another one up, loved that thing). No amount of staples could bring it back to life, so into the garbage it went.

Anyway, I'm still on a quest for the perfect hard egg. My current quest has me at

https://food-hacks.wonderhowto.com/how-to/make-amazing-hard-boiled-eggs-are-easy-peel-0154519/

where I'm picking and choosing what parts I of the recipe I want to follow based on just how lazy I am.

Trying

  1. Splash of baking soda. Not a teaspoon like mentioned. I'm seriously too lazy to measure that, or anything else, to be honest. In my mind, this is "half a glug". 
  2. I didn't warm my eggs. I can see future Kevin doing that, as he is informed by historical Kevin.
  3. Now that we have a functioning refrigerator with an ice maker, I don't feel like I'm wasting valuable resources making an ice bath (like a frickin' Rockefeller). So we do that too.
I'm not shaking an egg or otherwise centering a yolk. I'm not doing any pinprick crap. Ain't nobody got time for that.

Here's hoping for the perfect egg.

Thursday, April 4, 2019

Tidying up a project - safe refactoring rules

With 6 kids (!) that I love with every fiber of my being, I'm used to rooms being a bit of a mess when I enter. Therefore, I try to lead by example and:
"Make the space better for me having been there"
Which means, depending on where I am, I wipe down the sink in the bathroom, put a dish or two in the dishwasher, etc. Of course, any child within earshot, when appropriate, gets a "everything on pause, come help me with this..."

And, like all rules, there is nuance. When we're out the door for a thing in 2 minutes, I don't do this. Everybody needs to stay on task. I'm not going to distract from the shoe tying & coat buttoning to get "the dang toys off of Bruce (our table, don't ask) and into a bin!"

Likewise, when I open up a C# programming project - .sln in Visual Studio - to do a thing, I will accompany that thing with some refactorings that feel generally safe.

Nuance: I calculate the days to when this code will hit my production environment (the bake time). If we're below my comfort zone, I do not do any of these steps. I don't have a hard cutoff for comfort zone, and much of it depends on the project. When we're talking hours to prod and not days or weeks, my comfort zone is a little on edge, so I say skip these. From one of my favorite writings
"vi. Break any of these rules sooner than say anything outright barbarous." - George Orwell
Ok, enough with the boring. Onto my rules
NOTE: I'm nowhere near as good of a C# developer as I am C++. These rules are going to change for me over time. Also, the point of this is to not proscribe a set of rules for the reader, but to get you thinking in terms of what are YOUR safe refactoring rules.

My Safe Refactoring Rules


Definitions

  • TEST projects are C# projects (.csproj) that contain the unit tests, integration tests, smoke tests, whatever tests. The build artifacts produced do NOT run on production. The build artifacts produced by a TEST project are used to exercise the artifacts that DO run on production. 
  • PRODUCTION projects are the C# projects that produce build artifacts that DO run on production.

Rules

  1. Validate that all TEST projects are on the latest department accepted version of the .NET Framework
  2. Make sure that all projects are configured so that StyleCop style violations are errors, not warnings.
  3. Update all NuGet packages in TEST projects, except for the department documented "don't update" packages.
  4. For each .cs file that is modified, make sure that unnecessary using statements are removed.
    • Visual Studio has a function under Edit / IntelliSense / Organize Usings / Remove Unnecessary Usings. I have muscle memory around alt e i o r.
  5. For each .cs file that is modified, sort your using statements.
    • Visual Studio has a function under Edit / IntelliSense / Organize Usings / Sort Usings. I have muscle memory around alt e i o s.
  6. If your PRODUCTION projects are developing NuGet packages, avoid updating dependent NuGet packages unless absolutely necessary.
    • Final choice of the proper version consumed should be up to the application, not the NuGet package.
    • NuGet package dependencies here are an expression of "what interface do I expect."

Deets

I want to go into a bit of detail about each of the choices.

1. Update .NET Framework

Developers should be familiar with how to update the target .NET Framework and not allow code to languish on an old framework version, like some kind of an animal. Tools like the Target Framework Migrator can help tremendously. 

2. StyleCop

While I can be annoyed at StyleCop, it's an "eat your broccoli" to me, as I think projects are generally better with StyleCop than without. 

I like StyleCop.Error.MSBuild to turn StyleCop warnings into errors, although it needs a hand modification to your packages.config file to turn it into a development dependency

<package id="StyleCop.MSBuild" version="5.0.0" targetFramework="net461" developmentDependency="true" />
lest a build choice on a package be injected into a downstream consumer that is not quite ready for it.

Sometimes this choice can cause me to have to fix more warnings-turned-errors than I'm comfortable with, so it may turn into scheduled work for the future.

3. Update all NuGet packages in TEST projects

Developers should be "watching the skies" for updates to NuGet packages, as stale packages can cause bugs (been there, done that). 

By doing this in a safe manner, where the only thing you may break are your tests (which would reject your build because you gate, right, RIGHT?) gets you in a good mindset.

If your department does not have a documented list of "don't update these" packages, then demand one. Better yet, create & champion one.

4. & 5. Fix yer usings

Using statements are happier when they are organized this way; I've spoken to them.

6. Be careful with package to package dependencies

While this feels like a weird one, as it's not a "do this" rule, but an "avoid this", I thought it was important to call out the difference between what a package dependency represents when developing a NuGet package and what a package dependency represents when developing an application.

While developing a NuGet package, you're selecting an expected interface by the version choices of your package dependencies.

If you find bugs with particular releases of your dependencies, then by all means, express that in your dependency ("Anybody that uses package FOOBAR version 3.1.5 or below is a FOOL and will get the BAZ race condition bug - Minimum expected version is 3.1.6").

Other than bugs, you should let the application be the final arbiter of what version of package they are dependent upon. When wearing the NuGet package developer hat, you can't determine the full context in which your package will be used, and the application may be combining your package with other packages written by other developers in interesting ways that require more control over dependencies.

Being as flexible as possible over dependent versions helps here.

Conclusion

Again, these are my rules, not yours. My rules will change over time as I get more seasoned in C#. The purpose of this is to get you thinking about what your "tidying up" rules might be so your projects stay fresh and moving forward.