Kitchen Ah Has

Some incredibly useful forehead-slappers I have learned from Mr. Alton Brown...

Heat-proof gloves for oven mitts: Go to the hardware store and look for welding gloves. They're leather, far more protective than kitchen-type oven mitts, and they have fingers, so you can wrangle hot, difficult things like an evolved primate.

#16 ice-cream scoop for muffins: In art, my medium is muffins. Scooping the batter into the muffin tins is always the most difficult step: time-consuming, likely to spill on the counter, wispy scraps of batter around the outsides of the tin burn and affect the flavor, and you need to do it fast so you don't lose all the fluff from your baking powder. Enter: ice-cream scoop. A #16 is the perfect volume, and the thumb trigger dumps the batter right on target.

Egg slicer, with blades, for mushrooms, strawberries, what-have-you: I used to think egg slicers were a unitasker, but I just wasn't thinking creatively enough. If you get one with metal blades instead of wimpy wires, you can quickly slice anything small and squishy. Which includes the tips of three fingers in one efficient pass, so watch yourself. *sniff*

Cast iron skillet: Somehow I took it into my head that cast iron is difficult to clean or care for or cook with. I don't know where I got these ideas, because they are completely wrong. My cast iron skillet is the most used thing in my kitchen. Okay, to clean and care for: Follow Lodge's instructions to season it once; from then on, clean only with water and a scrubbie, dry it right away, and coat it from time to time with a little fat (cooking spray, butter, or... bacon!). The easiest way to clean it is to dump water in it right after you take food out of it (deglazing, the foodies call this), scrape off the bits with your spatula, and dump the water out. The heat of the pan will probably dry it in a hurry, or you can wipe it with a towel if it has cooled. Then, as far as cooking goes: For nearly every application, the weight and heat inertia of a cast iron pan will make you so happy. With a wimpy aluminum pan, as soon as you add ingredients, you cool the pan way down. You'll never get a nice brown crust on a steak with an aluminum pan. And with teflon pans, you have to be so neurotic about which utensils you use and how you wield them. Mr. Cast Iron is not afraid of anything in my kitchen drawers.

I could watch Good Eats all day, and I have no self control when there are Alton Brown DVDs in the house. I like the nerdy food science, and I like his "Anyone can cook!" approach to cooking instruction, but my favorite parts are the world-altering revelations of new ways to use kitchen implements. "Holy cow, why didn't I think of that? This changes everything..."

Do you have any Ah Has?

What tools do you use?

I've been meeting with other teams at work who are curious about how my team is using scrum. The most common first question is: "What tools do you use?"

I've finally hit upon the answer. Previously, this question had been so daunting to answer because it is inherently the wrong question, when you're just starting out. At least, if you translate "tool" to mean "software application." eScrum or Mingle or VSTS does not make you agile. Your philosophies and your strategies make you agile.

Here are the tools that we use:
  1. The Agile Manifesto.
  2. Shared sense of ownership, where developers, testers, and business people have an equal stake in, and equal responsibility to, the success of the project. We're all pulling together.
  3. Rigorous software engineering practices, especially source control, continuous integration, readable (soluble? grokkable?) code, and automated unit tests.
  4. Communication. All the damn time. As much like face-to-face as you can manage. We do our best with a globe-spanning agile team; if your teammates all reside in the same city, then for goodness sake take advantage of that luxury and meet in person.
  5. Frequent feedback, in many different forms. CruiseControl always tells us the health of our build; testers are testing functionality every day; business partners are reviewing and providing corrections all the time. The elapsed time between making a change and knowing if it is good is as short as possible.
  6. Retrospectives, where the team talks honestly and candidly about what is going well and what could be improved, and then takes direct action on those improvements. Contrast this with end-of-waterfall "Lessons Learned" sessions; by the end of the project, it's too late, there's no point in trying to implement any changes because you won't be working with these people. Instead, meet every week or two weeks, or whatever works for your team, to decide what you want to do together to help your team.
  7. Empowered, self-directed team members, who collectively decide what fits best with their team. I'm happy to tell you which tools (from the "software application" sense of the word) we use and how long our sprints are and what processes we follow, but your team is best qualified to determine what will work for your team.

From this sense, what tools do you recommend?

Race, soon

In a week and a half, I'll be running in the Komen Race for the Cure again. I would gladly welcome your pledge to support breast cancer research.

Will you be there on race day?

Automate, Numb Bot.

The Pragmatic Programmer advises automating repetitive tasks—not just computer tasks but, y'know, everything.

Neal Ford made the point at No Fluff Just Stuff that you're not just automating to save time (because sometimes creating the automation takes more time than the repetitive task); no, instead he said: Repeating a task makes you dumber; automating a task makes you smarter. You will invariably learn something while figuring out the automation script. Even if not, you are using your brain, instead of dropping into numb bot mode.

I've noticed that if I am automating to save time, I will repeat a task until I notice that it's a recurring task and worked out the pattern for its repetition; then I will automate it. The more growthful pattern is to automate all kinds of tasks, and when I need to perform one of them again, adjust and generalize my automation to fit.

To support my point, a helpful example from XKCD: (I suppose it's safe for work, given that they're stick figures, but it does make mention of acts between consenting adults, so there you are. Also, I wouldn't have left, but that's why I married a geek.)

The elegance of Queues and Stacks

I've been meditating on the beauty of Queues and Stacks. Like Lists, they are collections of objects, but with their own special attributes.

Queues are like a line of customers: the first one in line is the first one you'll serve (FIFO, First In First Out). These could be used for queued up messages that you have to process in order.

Stacks are like a deck of playing cards: the last one you lay on the top will be the first one you draw off the top (LIFO, Last In First Out). These could be used for tracking a sequence of actions that you might need to undo.

You can Peek() at the top item in a Queue or a Stack, but you can't reference a specific item by index. You have access only to the First In or Last In (respectively), and can only add things to the next spot in line.

I like how Queue.Dequeue() and Stack.Pop() both return the next object and remove it from the collection. It seems tidy to do it all in one method. But you're not stuck with that; like I said, you can still Peek() if you just want to see what's next, but leave the object in place.

If you need to deal with your objects in an order relating to how you encountered them, as opposed to sorting by some attribute of the object, then a Queue or a Stack might be a better fit than a List.

Temporary Darkness

Sorry to go dark for a few days. I have more notes from Alt.Net plus some other things I've been doing that I look forward to sharing with you soon. But I'm caught up in a bit of plate-spinning at the moment, which is keeping me away from blogging.

Fail Fast, and Mind the Outs

I had a learning opportunity on two coding concepts (in C#) yesterday:
  • out parameters are tricksy and not to be trusted.
  • Fail fast. When the world starts getting uncertain and hairy, throw an exception and get out of there.

The setup: I'm retrieving app configuration values from the database, a minimum and maximum allowable threshold. The db table is generic, containing key/value pairs for many purposes, so the values are stored as varchars, but I want integers here. If I don't get a value, I have some defaults we should use. The colleague who would be reviewing my code has declared he is allergic to nested if/else blocks, so I need a direct path through this logic.

Too crufty: One might be tempted to think about the logic this way. If I get a value from the database, but it isn't an int, set it to the default; if I don't get a value from the database, set it to the default. When you say it in English, you can hear the repeated code, violating the DRY principle. It's a small repetition, and in a very localized piece of code, but still icky.

Tripping over outs: Since I didn't want to repeat that default value, and I wasn't happy with those elses, I tried this. The default value is 100; if you get a different integer from the database, use that. But I didn't get it quite right:

[using a data reader]
int max = 100;
if (dataReader.Read())
Int32.TryParse(dataReader.GetString(0), out max);
//This is wrong.
return max;

Can you see what I was thinking, though? "If you successfully parse the result into an integer, set 'max' to that value. Otherwise, leave it alone." That was my mistake. What actually happens is, if TryParse can't parse it into an integer, it makes it undefined. From an msdn article, "The value of an out argument will not be passed to the out parameter."

What I really needed to do there is, "if not int.tryparse, then set it to my default value." I should check the boolean return value whenever I use TryParse.

Hold on, cowboy: But what does it mean if the configuration value in my database isn't an integer? Somebody typed something screwy. And they probably did it by updating the database, not using the admin screen. The world is in an unknown state, society is breaking down—cats and dogs, living together...

I don't want to set any default value. I want to throw an exception and get the heck out of there. So the final version is:

[using a data reader]
int max = 100;
if (dataReader.Read())
max = Int32.Parse(dataReader.GetString(0));
//Fail fast and make your escape.
return max;

This achieves three design principles, which is why I wanted to write it down and reinforce my learning:
  1. Find the most direct path through the logic. Elses are a smell.
  2. Don't repeat yourself. Even though the repeating here was trivial, it caught my attention and made me think through what should really happen, which led me to...
  3. When you start getting unexpected behavior, hiding it and swallowing it will cause worse problems. If you get a "that can't happen" scenario, throw an exception.

Serving Kool-Aid

[From the Creating Passion, Spreading the Word session]

Tips collected from the discussion on spreading one's values into the rest of the organization...
  1. To convince someone of a solution, you need to help them first see that there is a problem.
  2. Pick your battles: Work on only the highest priority changes, to avoid overwhelming your audience.
  3. Build credibility. Start with a small change, and let its success build your argument for the next change.
  4. Start a forum where team members can share their ideas. Avoid being the lone pontificator on the mount, and instead create a lunch-n-learn atmosphere, where you can be one of many presenters.
  5. Lead not through addition (adding followers), but through multiplication (creating leaders).
  6. Experiment on your side projects. You'll never convince people to risk a wacky new methodology on their huge, stressful, already late, career-defining project.
  7. Build relationships first. Show that you care about the team's success, that you are a member of the team, in order to build trust. One-on-one contact can convey this valued trust—I want to share this with you.
  8. You've followed many steps to come to a conclusion. You need to help your audience down that path, too. Simply handing them the conclusion will not be compelling or convincing.
  9. Passion may start a revolution, but persistence and perseverance are required to see it through. You may get tired of fighting, but lasting change requires more time than you think, so you have to keep fighting.
  10. Remove friction to adoption. Make it easy to do the right thing.
  11. Let your audience ask for "what's next?" Give them a taste of it, and then step back and wait. Let the quest for improvement become their idea.
  12. Discuss ideas, not tools. Teach critical thinking.

Lessons at the End of my Rope

The universe was conspiring to prevent me from climbing tonight—and trying to demoralize me, to boot—but I would not be deterred. After the rather manful weekend of Alt.Net, I needed Ladies Night at the gym, to get some hang time with the girls and scuff a layer of skin off my callouses.

I am reminded of two lessons that will dog me until I learn them.

If I climb only once a week, I will never improve. Whether it's muscles or brain waves, repeated, consistent practice is the only way I'll advance. For strength training, this is intuitive, but it also applies to programming and any other cognitive skill.

A Radio Lab article on sleep explains that, while we sleep, our brains gently wash away the memories of the day, turning down the volume on all of them until only the loudest remain. The next time you practice a skill, you reinforce its memory, amplifying it back up. If you practice a whole lot on one day but then drop it for many days before your next practice session, the practice is all but washed away. If instead you invest a moderate amount of practice every day, you will be able to build on your previous practice.

Which is all a way of saying: I gotta hone my craft every day. And climb three days a week.

The second lesson is about fear. I am so frustrated with the limitations I let fear put on my abilities. To nail the last move on a route, I needed to launch myself, just jump for it, let both hands leave the wall and pop. My legs would not comply; I was holding back.

Why? Well, 30 feet up is part of why, but really. I was safe and capable, and had nothing to fear but a scrape or a wrench or a bruise. Just some "naw, I don't wanna" in the back of my head, until I got angry enough to lunge past it.

Scott Bellware suggested that what differentiates the Alt.Net mindset is a willingness to be comfortable with fear, in the interest of improving. This stuck with me because it let me be proud of my fear; instead of a weakness, it is the indicator that I'm pushing myself and growing.

It wasn't all suffering for my art, by the way. I totally kicked the ass of a project I've been working for weeks, after collaborating on it with two other ladies. (Collaboration? Another lesson here? Sheesh, enough already.) The answer lay in reaching around instead of over, that one inch making all the difference.

My arms are burning, my hands are raw, my cuticles are filthy, and I'm a little bit wiser. It was a good night.

BDD without Friction?

[From the Behavior-Driven Development session]

I could not discern a clear why from this session. Despite that, I think I agree with the tenets of capturing user stories using business-y language and executable code, at least to give your project an executable to-do list.

The debate swirled around whether codifying user stories was better than note cards, should replace note cards, or was just a way to translate human language into something developers could understand (which left me wondering what species developers are, then). I can't speak to BDD's relative merits, but I know a thing or two about having conversations with humans.

Above all, we want to avoid the scenario where the business user says they've changed their mind (their process, their requirements...), and we roll our eyes. We express frustration with their so-called indecisiveness because we're mentally translating that into a big pile of work. A note card has nothing invested in it—throw it away! whatever—but code, a test, a requirements doc, these things all introduce overhead. Overhead = friction = resistance to change = not building the highest priority thing. Your strategic advantage hinges on your ability to change.

Where is the middle ground here?

Because I can surmise benefits in favor of BDD. I love automated unit tests and the confidence they give me to refactor and create code with speed. I'm not alone in hating the maintenance of requirements docs, so they invariably become out-of-date and worse than useless. Executable requirements sound like an appealing alternative. Thinking in the business domain while coding, bringing code and user needs closer together, sound like important contributors to success. I get the impression that BDD brings a change in paradigm that is too subtle to explain to someone not experiencing it, but profound in the way it overhauls your perspective. But I just don't know yet.

Beginners, Speak Out

[From the Creating Passion session]

Beginners to a given topic (TDD, BDD, NHibernate, whatever) should recognize the value of their own voices on that topic.

Brad from University of Phoenix complimented Jean-Paul on the quality of one of his webcasts, but lamented that it was at such a high level. We need a more introductory overview of the concepts. I would suggest to Brad (if I could get a word in edgewise, but that's my own problem) that Brad should make such a webcast.

Those who have just learned a concept, or are exploring and actively learning a new concept, are uniquely qualified to explain it to other beginners. You're close to and you still remember what was challenging about learning it, and what concepts you needed presented to you in what order.

As someone else in the session mentioned, when you are well versed in a philosophy, are a believer in a concept, you followed many steps to reach those conclusions. When you are teaching someone else, you can't present the final synopsis and expect them to ingest it and agree. You need to lead them down the same path.

Those who have most recently walked that path have the best memory of the steps, twists and turns, and points of interest. Beginners have a valuable perspective, and should feel encouraged to toss their voices into the fray. I am reminding myself in this as much as anyone else.

Ladies Night at the Dev Con

Attended the kick-off and agenda-setting of the Alt.Net conference this evening, and I'm already enthusiastic. The guest list is such a who's-who of the development community, there are many topics I'm looking forward to, and the Open Spaces format affords interesting social observations.

I'm the only woman, out of 100+ attendees. I'm relatively used to these ratios—when you're a developer, a rock climber, and a sci-fi geek, you spend a lot of time with boys—but I'm still puzzled as to why. This evening was unusual because someone actually commented on the imbalance; it's usually the Awkward Unstated Obviousness that seems too gauche to acknowledge.

I've been formulating some guesses about why there are so few women at software conferences. Do you have any ideas?
  1. This was only the kick-off. Two or three more may show up tomorrow. This doesn't really change the point, though.
  2. The programmer community is not as gender-balanced as I had thought. The multitudes of women around my workplace are actually managers, project managers, business analysts, test leads, dev leads, and administrative assistants.
  3. Women don't hear about the conferences. (I'm only starting to tap into the info channels, myself.)
  4. Women feel less entitled to ask their employers to fly them to an expensive conference. (Although this one is free. But, in general.)
  5. It takes courage to jump in and be the only girl. When all of a conference's featured speakers are men, you know most of the attendees will be, too. (I was heartened to see Wendy Friedlander on the organizers list of Alt.Net; I hope I get to meet her.)
  6. Women prioritize relationship-building over career development or skills growth, and so do other things with their weekends.
  7. A roomful of men can be tiresome. They shout a lot, often fruitlessly and without seeming to listen to anyone else.
  8. Math is hard.
One nice thing about being a programmer: I can go to a large event and not have a line for the bathroom.

I don't blame the men. If anything, they are guilty only of being men. I always find them to be polite and inclusive. When they're shouty, it's because it's their nature to be shouty, and you need to shout right along with them (They like that.), or communicate with your own quiet confidence (They'll listen.). You don't have to be like a man to hang out with men. You don't have to be like a girl, either. You can just be a developer, be a thinking person with ideas, be yourself.

But you have to show up.