Happy Little Trees

I wanted to give my parents a drawing for Christmas, and while I pondered what subject to use, Mom happened to send an email with a request. She had a photo of the woods on their property, beautiful with Pennsylvania fall colors, and would I consider making a painting that looks like a Japanese print. I decided not to learn woodblock printing that week, but watercolor would probably fit the bill. Of course, that meant I needed to learn watercolor, but at least that didn't require sharp tools.

These photos span December 6 to January 20. Watercolor painting involves a lot of watercolor waiting to dry.





This is my workspace. I taped a big piece of watercolor paper to my craft table, taped down to minimize the amount of warping as I applied paint. (I could have pre-wetted and stretched the paper, but I didn't really have the setup to do that well.)

You can see my tablet computer with the photo for reference, off to my right. I've laid in the sky visible above the hill, and the shorn corn field at the base of the hill. To capture the mottled look of the field, I scattered table salt on the wet paint, making the paint pull away from the salt.





The yellow leaves that blanket the hillside and the green underbrush, plus the farthest-away layer of foliage. I worked back to front, imagining the scene sliced into layers and starting from the back. I also had to let each layer dry.





The farthest-away trees, due to atmospheric perspective, are less saturated in color. I used a very dilute ink wash of sepia ink for the faintest trunks, then added a little more ink to that wash for the darker ones.





The next layer of trees. Ink doesn't flow like paint, so I couldn't use the ink for the big trunks. I even struggled with it on the smaller trees from the previous layer. It got a little dicey, so I knew I'd need paint for these big, close trees. Creating brown is stressful when your color vision is hampered by tritanomaly; there's always a risk I'm making purple. This is why I work in charcoal.





The closest trunks need to be dark and opaque, so I used a "burnt umber" watercolor pencil to color them in. Watercolor pencils are labeled, so I could be confident that one was brown. Working from left to right, I've done about half of the trunks here. Also in the middle, I tried a small experiment with very saturated paint to see if I could add leaves on top of the trunks that would really pop.





I finished coloring in the trunks, and then activated the watercolor pencil by painting over it with water. It reminds me of those paint-with-water books I had as a kid.





Cast shadows give you information about the object casting the shadow (tree trunks) and the object onto which the shadow is cast (the undulating hillside). With the shadows, it's starting to finally look like something.





Leaves.





Signed.





Liberated.





Framed.





Shipped.





Done.

Hello, That Conference Scientists!

Did you join us for Circuits in Play Dough? I'm glad you're here!

Keep in touch: Let's use #thatCircuits to tie our posts together.

Post your pictures: Please share your pictures from the workshop! You can use the #thatCircuits hashtag on your photo-sharing service. Add a comment here with the link to your photo set.

Review what we did: Here are the Circuits in Play Dough hand-outs that we used. This whole endeavor was inspired by AnnMarie Thomas's TED talk, "Hands-on science with squishy circuits," and the Squishy Circuits project at St. Thomas University.

Keep learning: If you want to understand why electronics work, chemistry is the science you want to explore. I learned so much from The Joy of Chemistry: The Amazing Science of Familiar Things. Ask your grown-up lab assistant to help you try out the experiments in this book.

Do more: If you learned about Scratch from Katelyn, you can apply programming to your electronics projects with the Hummingbird and Arduino microcontrollers. Make robots!

Give thanks: Thanks to Amy and Lance Larsen for bringing the bowls and spoons I needed to mix up a bunch of play dough in a hotel room. Thanks to my mom for making fond memories of sculpting play dough while it was still warm, and for showing me that girls are good at programming. Thanks to the TSA for not balking at a bag containing LEDs, wire cutters, and 80 9-volt batteries.

A Life Less Encumbered

My latest performance art project is "Discard Three Things." (You may have appreciated my previous pieces, "Girl Makes Robot (with skitchy arms)" and "A Dop Ting Kittens.") Okay actually, it's a game I'm playing with myself, and you're welcome to join in.

On January 2nd I thought idly, "I wonder if I can get rid of three things each day. When would that start to feel like progress?" The answer was "pretty much immediately."

Here are the rules I set for myself:
  1. Every day—every day—choose three things and discard, donate, recycle, or give them away.
  2. Not consumable stuff like "the box my tv dinner came in," but stuff that has been Sitting Around Forever to the point where it has become scenery.
  3. Merely earmarking something for donation does not count. "Stuff to Donate" has been its own kind of clutter.
  4. I tweet about it, somewhat poetically, using the hashtag #d3t. This makes it a game, and it also makes me do it every day. I'd be letting people down (even if no real people would notice, that imagined commitment keeps me honest).
  5. Adjust the rules to suit your life and keep you motivated.

Amusingly, people are joining in! Friends on Twitter became intrigued and decided it would work for them, too. My Tweetdeck now has a #d3t column, and I'm getting a kick out the sense of liberation their tweets convey. Do you want to try it, too?

This is working for me because three things is nothing. It takes five minutes. It's not scary, in the way that "I'll clean out the garage today" is scary. Kinda fun. The unexpected thing is that it builds a good bit of momentum. I'm usually pitching more than three—but I don't have to. I'm just allowed to. Once I've cleaned some stuff out of the way, it's then satisfying to carry on and neaten up the remaining stuff. Getting rid of clutter makes room for being neat.

It is not lost on me that "too much stuff" is the epitome of a First World Problem. But hoarding it doesn't help anybody, either. What I'd really like is to build a habit of acquiring less.

Folks have asked me when I'll stop. I haven't defined an end condition for myself. I could imagine people choosing something like "for 30 days," "when the kid's room is packed," "when there's room for a pinball table." I expect there will come a point where it cuts too dear, where I have a purpose or a love for each thing in my home. (Or, given prior habits, I will have acquired more crap to discard, and it will never really end.) If I ever do feel finished, there's plenty of drywall to patch and remodeling to do. Keep an eye out for my next art piece, "Watch Me Fix This Thing."

You don't have to be an expert to be a teacher

Just in time for my session at That Conference, benefit from my recent discovery: Pin 13 Considered Harmful.

I've heard folks tell me they're not ready to present at conferences, because they're not experts yet. I look at it the opposite way: I barely know electronics, yet I built a robot. I built a robot, and you can, too! Take inspiration by what I've achieved despite my lack of expertise.

You don't have to be an expert to inspire passion. You don't have to be an expert to teach. You just have to care.

And you can fix things with a follow-up blog post. Eheh.

Arduino-Powered Clank

I've often said, incorporating an Arduino microcontroller into your costume can open up all new kinds of fun. For Halloween, I dressed as Agatha Clay, Girl Genius (seemed fitting). I just created a better video of my little clank:



Photos of the construction.

Source code that drives it.

Finding Faith in a Fish Sandwich

I just met C. J., the Silver Fox. He "flies a sign" under the Burnet/183 bridge.

I was waiting for an inspection sticker at Sticker Stop, sitting outside because it was too nice to be confined in a gray box with other sullen mammals. He walked up, and my otherness detector pinged. Well, for one thing, he was at the Sticker Stop without a car.

I blew a bug off the page of my book. He mimicked the gesture. "There was a bug," I shrugged. "At least you didn't kill the damn bug," he replied, and I had to agree. He set an unlit cigarette and a large beverage can on the picnic table and went inside. I considered my options: Go inside for the safety of crowds, or sit pat.

When he returned, he sat on the table and asked if he could tell me a joke. I could use a little mirth these days, so I said yes. It was a good joke, and he told it well. I laughed. "It was a pretty good joke, right?" he asked. "No swear words or nothing." I told him it was, and then we were talking.

He holds a cardboard sign that says "Wife and dog kidnapped by ninjas. Saving up for karate lessons. I really want the dog back!" That one, he says, works better on women than on men. He told me, "If there are two girls in the front seat, they see that sign and laugh, I'm getting paid." His other sign says "You may live in a $200,000 house. I live under a $2M bridge. Need money for repairs—the roof leaks."

He asked me if I knew God, and some questions are easier to just say yes to. God looks out for him, he said. God provides. C. J. is an alcoholic (He just said it, so matter-of-factly.), yet God helps him cross that street so many times a day, and sees him safely through the night when he's too drunk to remember how he ended up there. Then he asked me if he could tell me something, and here I expected the hard sell. But no, he just told me his story.

Twelve years ago, his wife was killed by a drunk driver. "That's what landed me under that bridge." After that, he became really angry at God. Then, about five years ago, he had a transformative experience. A minister, after serving a dinner that fed 300 homeless people, brought a bag of food to C. J. and said, "This is for you. This is from God, for you." C. J. didn't want it, didn't want anything from God, he was angry with God.

Two hours elapsed before he grew hungry enough to look in the bag. It contained a fish sandwich, topped with a double serving of tartar sauce, plus an orange soda. It contained just what his childhood self would have called his favorite meal. How could that minister have known? He couldn't. This was God. C. J. told me, "This was God saying, 'I still care about you. Even though you're mad at me, I am not mad at you.'"

He said a friend chided him, "You found God in a Happy Meal?" We laughed together, me and C. J., and I thought maybe God could look out for me a little, too.

Then he stood up, picked up his can and the cigarette which he'd never lit, and shook my hand. I thanked him for talking with me, and he thanked me for being willing to listen, since most people aren't.

Hello, Arduino. Let's get started.

Hi, CodeMash! Here are resources to get you started with the Arduino microcontroller, a prototyping platform to build crafty electronics projects (electronicky craft projects?).

My clank

You need the Arduino IDE, the editor in which you'll write your sketches.

You need the microcontroller board. There are many form factors to choose from. I have an Arduino Uno, and that's a great default choice. You might want one with additional capabilities, such as Ethernet or the extra processing power of the Mega, or you might enjoy the LilyPad, designed for being incorporated into costumes and wearables.

Note that a "shield" is a thing that plugs into an Arduino, so it doesn't have any brains on its own. Feel free to pick up some shields, they're a hoot, but be aware that you still also need an Arduino board.

Sources to buy from: AdaFruit Industries, Sparkfun Electronics, Maker Shed, RadioShack.

The slides from my talk are on SlideShare, and the sketch for the robot is on GitHub (along with a number of other sketches).

Pictures of building the robot, the video game, my ambient clock, and the thing under your bed.

What are you going to make? Leave a comment here or send me a note on Twitter (@scichelli). I can't wait to hear about it!

Showdown at Unobtanium—for SCIENCE!

Hello, my fellow mad scientists. If you attended my talk at Showdown at Unobtanium, thank you for being part of a fantastic audience—the enthusiasm you fed back to me was infectious and inspiring. Make things and tell me about it!

Please join us at Polyglot Programmers of Austin,  our co-working study group for learning a new programming language (including your first). Breadboards are as welcome as keyboards. Also, I'll be there, happy to answer your Arduino questions.

Some details about my small robot friend, to amuse you. My costume was an homage to Agatha Clay (and her clank) of the Girl Genius comic book. I posted some pictures of the clank's construction process. What makes it fidget is a servo motor on its back, driven by an Arduino in my purse, running an Arduino sketch I wrote (source code).

You might appreciate the Nerd Nite wrapup from the last time I spoke on this topic. There are useful links in there, pertinent to the presentation you saw at the Showdown, specifically the slide deck that contains links to resources for learning more.

Some of you talked to me about presenting to your students at your schools. Yes, please! Get in touch.

Thanks for being awesome. Make fantastic things.

Hello, Nerds. Hello, World. Hello, Arduino.

Thank you to Nerd Nite Austin for a fantastic venue, and my thanks to all of you who were there, creating a palpable enthusiasm for Making Stuff! What a hoot. Resources for ya...

The slidedeck: Hello, Arduino

Samples of my Arduino code are on GitHub, because I like to think out loud in code.

A description of the blinky-eyeball Halloween costume

That "hang out and code with other people learning to code" study group is Polyglot Programmers of Austin, our next meeting is tomorrow, and you should totally join us.

Lest you need some motivation for making nerd presentations of your own, check this out. Some months back, I presented at a Dorkbot meeting at the ATX Hackerspace. Afterwards, someone approached me with "I don't know if you remember me, but..." And kapow! Timewarp! Here was my friend from nerd camp, whom I hadn't seen in 20 years! Wow! We've had a blast catching each other up. Then, I'm presenting at Nerd Nite tonight, and after that, another friend from nerd camp comes up and says hello.

Dude, I'm telling you. Take your awesome hobbies, go to nerdy things and present your awesomeness, and fantastic nerdy friends whom you miss will discover you and reconnect with your life. What a delightful unexpected benefit.

How to Poach an Egg Without Specialty Tools

I got to talking on Twitter (as you do) with Garann and Cecy about that most satisfying of snacks, the poached egg. They lamented the hassle and the need for weird tools (molds and frames and whatnot). I offered an alternative.

I've made a study and a practice of the poaching of eggs, and I've got it down. I also don't use anything more exotic than a slotted spoon. This wisdom is harvested from Alton Brown, The Joy of Cooking, Martha Stewart, daytime television, lots of experimentation, and my dear friend Adam, who cooked eggs Benedict for me on a New Year's Day in someone else's co-op in Boston, using a rapidly melting plastic cup as a poaching mold.

Photos and step-by-step instructions are all on Flickr: How to Poach an Egg
Poached egg

Sorry for the delay, ladies. I had to wait until I wanted an egg and cleaned the stove.

How about you: other tips for eggcellence?

Memo From My Future Self

As a goal-setting exercise, I got a jump on my year-end holiday letters, writing this one five-and-a-half years early. Listen in on this missive from the future. And if Future You has some news of her own, I'd love to hear from her.

Memo from my future self

December 31, 2017

Hello, my lovelies,

Bright blessings to you as the annum odometer rolls over another year. I continue to be amazed at how lucky I am to be able to count you among my friends. I am energized and inspired each time I meet one of you in person. Your energy, your passion; your sadnesses, your triumphs; the small doubting voices and the quiet pride in an accomplishent; your fears, your hearts, your courage: These are all beautiful to me. Rock on with your excellent selves.

I have so many stories to share with you. In no particular order...

Downloads of Fifty States, Fifty Stories continue at a moderate clip. Word is spreading, thanks to your help. Keep it up! As more people read it, more realize the strength and beauty of their own stories. Tell us your story. I'd love it if you came over to the website and shared your voice. I want to hear from you.

The most exciting outcome of the book for me, and it sounds like it was for many of you, too, is how much I learned writing "Appendix A: Puerto Rico." One enterprising reader was so moved, she has set up a foundation to effect change. Melissa Emory has a place for you on her team. If you also think we have important work to do there, go to her site and get involved.

The interview with Chana Joffe-Walt was too much fun. I even got to meet Ira Glass, and I can confirm: Yes, he is a nerd. I can't wait for you to hear the show. Look for This American Life episode 759, "Stories of the Storytellers." You'll find I'm in very good company, but that's all I'll say for now, terrible tease that I am.

Cities for 2018's Socketwrench Series are filling up. These classes are a blast—hands-on, high intensity coding, for those who want to truly understand what's going on. If you want me to teach a class in your town, get over there and tell me you're out there. And remember, computers are tools for our convenience. Don't let the robot overlords push you around. Come to a Socketwrench class and master the blighters.

Remember that conversation I had with the AlphaSmart people, about responsive keyboards and blogging from the road? Exciting projects are afoot. I wish I could tell you more, but I think this prototype would self-destruct in my hands. Oops!

Ha ha, guess that was okay. Not pushing my luck, though.

It has been an exciting year, and I thank each of you for your part in it. Keep being awesome.

See you on the flipside.
Love,
Sharon

On Thinking About Things

My house was burglarized last month. Thieves took pretty much anything I owned that could be sold via classified ad, plus a bunch of crap that is monetarily worthless and heart-rendingly irreplaceable. I've run out of swear words for these people. But it's got me thinking about things.

Some of it makes me laugh. For instance, the acoustic guitar, the electric bass and its amp, but not the French horn. Sheesh. Everybody's a critic. Or the smart phone that is actually a Windows Phone 7. Good luck with that, suckers. Or the earring from Dad. I'd lost one of a pair of earrings, and made the orphan into a necklace. The night before the break-in—I kid you not, the night before—I found the missing earring. They took the necklace.

Then there are the things that don't make me laugh. All my earrings. All my earrings that my grandmother had given me, a new pair for each play I performed in during high school, which she drove two hours to come up and see. All those. Not worth pennies to anybody, and memories I delighted in every morning as I got dressed. No hyperbole here; I knew who had gifted me each pair of earrings I had, and I thought of them as I selected something to complement my outfit. A little wave hello across time. These were hand-made by Leandra. Those were part of a set of five, owned by five different friends, all cut from the same tree branch. These were grown-up earrings entrusted to my young self by my mom's best friend. Those were Dad's way of saying I could get my ears pierced (finally!). These I made. Those were from the first boy I ever kissed.

They were all Really. Damn. Important.

So I'm thinking about things. I'm thinking, a bit frantically, what else did Grandma Sandy give me? No, I mean, what that can't be taken away did Grandma give me?

I remember lying with her on the big bed, under the afghan she had crocheted, while she read to me: Snipp, Snapp, and Snurr, with their buttered bread; The Wizard of Oz; Motherly Smith and Brother Bimbo, which I have since come to learn is the most boring book ever. I don't know how she put up with it, but I loved it, and I suspect she loved me.

Of course I remember her sweaters. Early in my life, they were all hand made. I remember a full-color rendering of the Wizard of Oz in yarn. It had Dorothy and Toto and the Lion on the front, and the Scarecrow and the Tin Man on the back, with the Wizard's balloon on one side and the Emerald City on the other, and the Yellow Brick Road running around the hem. I'm telling you: pictures in yarn. It was amazing. Later, as the family grew through marriages and children, the Christmas crunch became a drudgery, and she branched out into machine-assisted knitting. She designed the patterns on her computer.

I remember Thanksgivings with two pumpkin pies. One for the family, and one for me. Which I would also have for the following breakfast. With a mountain of Reddi-wip.

I remember going for walks around Arden, where I learned that when I grew up I wanted to live in a neighborhood where people waved to each other, which I have now done. I remember her flower gardens.

I also remember her work with the Civil Rights Movement, and raising my mom by herself in Philadelphia, and her pursuit of a Masters degree in sociology. She had a computer and an email address and knew how to use them. She was strong and funny and patient.

She taught me never to buy anything on credit. That right there is a hell of a gift.

I stood in the shadow of Venus

I also stood in a stairwell for a really long time, but that was fun, too. The UT astronomy club opened its rooftop to the public and recruited an army of volunteers, who were completely astonished by the size of the crowd.

I bumped into Brandon just as I arrived, and we entered the back of the line at the 7th floor. Luckily I was mistaken about how many floors there were—the flier mentioned a gathering place on the 13th floor, and that didn't sound so bad. Part way up I learned that the roof is above the 17th floor, but at that point I was well invested.

A stairwell full of people starts to smell like a stairwell full of people after a while. Each landing became a reprieve, a chance to catch some fresh air through the held-open doors (passed hand to hand, as we each climbed by) and, if you were quick, to dash out to a water fountain. An enterprising soul could set up a thriving business selling ball-park concessions to the people standing in line. It was the kind of line usually reserved for rock concerts. Which is why I love Austin.

Brandon got a call from a friend a few floors below us, and actually ceded his place in line to go join her. That left me to... shrug, talk to the people around me.

I met a bartender who said she received all kinds of verbal abuse as a bouncer but considerably more respect as a bartender. And no, people don't actually pour out their hearts to bartenders. I met a someday-med-student-but-currently-enterprise-support-agent who works at Dell. He camps under the awe-inspiringly dark skies in Big Bend, struck dumb by the sky-splitting blue gash of the Milky Way, and quieted by the realization that the mountains he could see from his cliff-side perch were in Mexico, 200 miles away. I met a photographer who got up at 2:30 this morning to capture time-lapse footage of the wheeling stars for his friends' film about the Bastrop wild fires. He went to space camp when he was in high school, so many years ago, and practiced a simulated space walk repairing the optics in the Hubble telescope.

So happy to burst out of the stairwell onto the 17th floor, and so resolved to stay chipper as we filed into a line that snaked down the hallway and back. We stood there for a while—at least it was air conditioned—until finally the mind starts to notice that the only movement is from the compression of the crowd. Cloud cover. They've halted the line to wait for clouds to clear. I wonder if we could all get on the roof and wave our arms to push the offending wisps out of the way. But I think about terms like "time invested" and "sunk cost," and waiting isn't so bad. Plus, we're talking about dark matter and SpaceX and deep-sky images, and I got to tell the story of visiting the Hobby Eberly Telescope, twice.

There is a time limit, though. You can't see Venus transit the face of the sun if the sun has set. 7:00 ticks by, which, rationally, I know is plenty of time, but I start to rehearse making the decision that night has fallen and it's time to go, having missed the whole thing while inside a windowless spiral of concrete.

But then the line moves, and we're up to the roof, and there are telescopes and people everywhere. And more lines, but at least there is air and sunlight. A volunteer with a basket of cardboard solar-viewing glasses gives me the chance to get my first look at Venus.

And, there it is! Plain as day, a disc in front of the red face of the sun. A shadow, interposed. Cheeky girl.

Spilling onto the sidewalk below, a fellow viewer said, "See you in 105 years." I replied, "I'll be there."

The Future of Blogging*

Here's how this is going to work. I have technical blogs on Los Techies and Headspring, but this here blog is the one with the cute domain name. Wondering what to do with Girl Writes Code, I remind myself that I enjoy writing about cooking and climbing and travel as much as I enjoy writing about code.

So I will continue to post technical content to those blogs, and this one will feature posts about the rest of my life, with pointers to the tech posts on the others. You can subscribe to either of those blogs, or to this one for the union of all three.



* on this blog

Running JavaScript... With Sneakers!

Code-review time. I haven't written significant JavaScript in forevs, but I hit upon a use case well suited to it, had a blast coding it up, and am confident that I'll be completely mystified by it three months from now. That is, unless we refactor it for maintainability (this is where you come in).

I'll explain the use case. The Couch-to-5K running plan is an excellent exercise regimen for learning to run. I followed it to successfully transform myself from sedentary software developer to 5K finisher. The runners among you know that five kilometers is a beginner-level distance; the sedentary software developers may find it as daunting as I once did. You train in intervals, alternating walking and running, gradually shifting the ratios to more running in successive workouts. If you can walk a moderate distance, following the program is totally doable (or modify it for easy walking/fast walking, if you're not up for jogging). Definitely check it out.

The thing is, timing the intervals—especially at the beginning, where you're alternating a minute of running with 90 seconds of walking—needs a complex timing device (a fancy runners watch), and if you're using a treadmill, it is really annoying to your fellow gym users, as your watch is beeping every minute or two. Or, well, maybe gym people don't care, but it's really annoying to me, since the dang thing is on my own wrist. For running indoors, I want a C25K timer that is tactile or visual. I've been thinking about an Arduino-powered timer that reads from a dip switch to determine which workout you're running and signals the changes with a vibration motor (like in a cell phone). Thinking, and not so much doing. Finally one Sunday I forced myself to focus on the problem: what do you have, with a visual display, that is really small and runs code?

My Nokia N810 internet tablet has a web browser that runs JavaScript, can open html files stored locally, and can do this while also playing a podcast. Win!

Here's what you can't do with JavaScript, though: Thread.Sleep(walkInterval). Instead, you use setTimeout() to say "execute this function after this interval," asynchronously. That's the part that currently works but I daren't touch it. In other words, that's the part that needs your code review advice. Remember that the intended scenario is to rest the tablet on the treadmill's magazine lip, so the app flashes the background of the page to catch my eye when I'm not looking directly at it. It's high-contrast because it isn't meant to be watched, just kept at hand, in my periphery.

If you choose to use the app (in addition to reviewing it), please only use it on a treadmill. Stay safe; don't try to wrangle something you need to look at while you're on the trail.

The Running Timer code is on github. A representative sample is below. How would you make it better?

var exercise = function(setup) {
 var workout = getWorkout(setup.week, setup.day);
 doExercise(workout, 0);
}

var cooldown = function() {
 walk('Cool Down');
 window.setTimeout(function() { transition(function() { walk('Done!'); })}, 
  minToMilli(RT.cooldownDuration));
}

var doExercise = function(workout, i) {
 workout[i].mode();
 if (i === workout.length - 1) {
  window.setTimeout(function() { transition(cooldown) }, 
   minToMilli(workout[i].minutes));
 } else {
  window.setTimeout(function() { transition(function() { doExercise(workout, i + 1); })}, 
   minToMilli(workout[i].minutes));
 }
}

var getWorkout = function(week, day) {
 return eval('C25K.W' + week + 'D' + day);
}

var transition = function(callback) {
 var indicatorDiv = $('.runCountdown');
 var body = $(document.body);
 transitionBlink(6, indicatorDiv, body, callback);
}

An Object Lesson in Binary Compatibility

A riddle for you, friends: When is changing a method from return void to return Something a breaking change?

If you already know the answer, then why hadn't you told me? Could've saved me a fair bit of embarrassment. Ah well, maybe I missed your call.

First, a story


I had the opportunity to contribute to the HtmlTags open-source project1. They needed some unit test coverage, and I <3 unit testing and wanted to try my hand at contributing to open-source software. As I got my bearings, I got more confident and started to reach beyond the unit test project into refactoring the application code.

That's when I found the AddStyle and AddJavaScript methods. Their friends returned an HtmlTag, but they returned void. They would be easier to test if they returned an HtmlTag, but that's not a good justification for changing a method. But they would be more consistent if they behaved like their neighbors, and that is a sufficient justification to consider it.

HtmlTags is a library meant to be consumed by other applications. It was already in use in the wild. Therefore, it was important not to change its API. It had to work like it always had, else we'd cause considerable grief to the developers using our code. I've been the consumer of a service that made breaking changes to its API, and I have choice things to say about the team that saddled me with that noise.

I thought really carefully. I was contemplating changing the return type of a public method in an in-use API. But all those uses would be calling it as if it returned nothing, and you can invoke a method without using its return value. This would be just like that. I asked a coder-buddy for advice. We convinced each other: What harm could it do?

What about the riddle?


Here we come to the answer to the riddle. If you're changing a library that will be called by other applications, then there are many seemingly harmless changes that are actually breaking changes, including changing a method's return type. When the consuming assembly is compiled, it is built with instructions to find a method named Whatever that returns void, but the changed assembly's manifest contains only a method named Whatever that returns string. No match.

Computers. They're so literal.

To fix it, you merely need to recompile the consuming application, but you don't discover the problem until assemblies are loaded at run-time, an annoying time to discover exceptions. I coded up a simple example that illustrates the problem. Feel free to follow along at home.

See the problem in action


Make two separate solutions, a class library called MessageOutputter and a console application called ConsoleMessager that references MessageOutputter. First, build MessageOutputter with a return void method.

namespace MessageOutputter
{
  public class Outputter
  {
    private string _message = "This is the outputter, version 1.";

    public string Emit()
    {
      return _message;
    }

    public void UpdateVersion(string versionNumber)
    {
      _message = string.Format("I've been altered by the UpdateVersion method. I am version {0}.", versionNumber);
    }
  }
}


UpdateVersion modifies a private field but does not return a value. Compile that solution and put its dll into a lib folder from which you will reference it in ConsoleMessager. Open the ConsoleMessager solution and add a reference to the MessageOutputter.dll. Write a method that uses the MessageOutputter.

namespace ConsoleMessager
{
  class Program
  {
    static void Main(string[] args)
    {
      var outputter = new MessageOutputter.Outputter();
      Console.WriteLine("Calling the outputter:");
      Console.WriteLine(outputter.Emit());
      Console.WriteLine("Asking the outputter to update, then calling it again.");
      outputter.UpdateVersion("Updated 1");
      Console.WriteLine(outputter.Emit());
      Console.Read();
    }
  }
}


The UpdateVersion method is called, not expecting a return value. Build and run the ConsoleMessager.



Return to the MessageOutputter solution and modify the UpdateVersion method to return the message after it modifies it.

namespace MessageOutputter
{
  public class Outputter
  {
    private string _message = "This is the outputter, version 2.";

    public string Emit()
    {
      return _message;
    }

    public string UpdateVersion(string versionNumber)
    {
      _message = string.Format("I've been altered by the UpdateVersion method. I am version {0}.", versionNumber);
      return _message;
    }
  }
}


Now UpdateVersion returns a string. Build the solution and copy its new dll back into the lib folder, and into the Debug or Release folder under ConsoleMessager/bin, so that the ConsoleMessager will run with your new version of the dll. Run ConsoleMessager and you will encounter the error:
Unhandled Exception: System.MissingMethodException: Method not found: 'Void MessageOutputter.Outputter.UpdateVersion(System.String)' at ConsoleMessager.Program.Main(String[] args)




The MissingMethodException indicates that ConsoleMessager, when looking within the MessageOutputter library, could not find an UpdateVersion method that returns void. Reopen the ConsoleMessager solution. Before you even build, IntelliSense will tell you that UpdateVersion returns a string now. Build ConsoleMessager and run it again, to see that it works successfully.



Wiser now


No one raked me over the coals—in fact, my intro-to-OSS experience was thoroughly positive, and I can't wait to do more—but I know I caused some time-consuming inconvenience to my fellow devs. I have now learned that Binary Compatibility is not the same as Source Compatibility. Conflating the two is like saying, "Works on my machine." I hope this write-up can help you avoid a similar goof.

1 The nice thing about open-source projects is that everyone has the opportunity to contribute. But I had the especially good fortune to have willing help from Josh Flanagan in finding my way through my first OSS pull request.

Using Syntax to Model the Domain

I'm fascinated by the small syntactic decisions that bring code closer to representing the business domain. Never mind the class inheritance examples from text books ("Dog IS-A Pet," which has nearly never been relevant), I mean using properties, methods, and constructors to let the compiler ensure your objects stay in a valid state. Linguistically, I think this is neat.

Not everything deserves a setter


Consider my Bacon class with an IsCooked property:

public class Bacon
{
  public bool IsCooked { get; set; }
}

To cook some bacon, I set IsCooked to true. Sure. But what if I set it to false? I just defied physics and the space-time continuum. Shucks.

IsCooked should be read-only, and I need a different way to change it in a one-way transition: I need a method. Bacon comes into my domain uncooked, so I'll set that property in its constructor.

public class Bacon
{
  public bool IsCooked { get; private set; }

  public Bacon()
  {
    IsCooked = false;
  }

  public void Cook()
  {
    IsCooked = true;
  }
}

The sanctity of thermodynamics is preserved. When the transitions get more interesting than a simple Boolean, you're looking at a state machine.

Polywhatism?


I encountered this example in the wild, but I've changed the domain to protect the innocent.

We're exploring a dungeon, and in our inventory we have items that affect our health:
  • amulets add a small amount to our health each day;
  • granola bars give us a lump-sum boost to our health the moment we eat them; and
  • cursed rings sap away our health each day until the curse runs out. (Why keep a cursed ring? How else would you command your army of winged monkeys?)

Here's a display of our inventory:

ItemDaily BoostTotal Remaining
Obsidian amulet150
Luck ring(25)375
Jasper amulet253
Granola of righteousness400


This was implemented as a collection of IHealthItem objects. Here's what I found:

public class Amulet : IHealthItem
{
  public int? DailyBoost { get; set; }

  public int? Total
  {
    get
    {
      return null;
    }
    set
    {
      throw new NotSupportedException(
           "Amulets do not have a total");
    }
  }
}

As if the cursed rings weren't bad enough, now there are properties we're not allowed to call, lurking, waiting to pounce on us with a run-time exception. The calling code, when working with an IHealthItem instance, is forced to make an "Is" check to determine the type, in order to know which properties are safe to use. Half the properties aren't relevant half the time. The DailyBoost property on CursedRing has an additional problem: Should you set it to a negative number, or assume it should be stored as an absolute value and multiplied by -1 when being used and displayed? The IHealthItem interface does not provide any abstraction.

In fact, these are not three variations of the same thing. The only quality they have in common is the user's desire to see them displayed in a table. (Further proof that they weren't related, in the real application, that table was labeled "Amulets/Granola Bars/Cursed Rings.") These concepts should have been modeled as three independent entities, keeping it unambiguous in the business layer how to use them to increment and decrement the adventurer's health. Only at the presentation (UI) layer, they could be projected into a display-only DTO (Data Transfer Object) or view model, using strings for all three properties.

Don't let me be uninitialized


If a property must be set for an object to be in a valid state, the class's constructor should require that value as an argument instead. That way, it's impossible to construct the object without also putting it into a valid state.

If a method, MethodB(), uses a private field and relies on another method, MethodA(), to be called first to set it, MethodB should take that value as a parameter instead. That way, MethodB can be called only after the result of MethodA has been determined; the correct order in which to call them is unambiguous.

These types of temporal coupling are illustrated nicely with examples and remedies on Mark Seemann's blog in "Design Smell: Temporal Coupling." (He has a whole series on encapsulation.)

Too, meaning drives syntax


When I find myself compelled to explain in comments, to write instructions ("make sure you set this before you call that") in the xml summary, to incorporate usage notes into method names, I pounce on that as a candidate for refactoring. Finicky methods and classes that require secret knowledge to use correctly are invitations for bugs. It's like when I'm editing the rules for one of Jon's games: every instance of the word "except" must justify its existence. Every special-case exception immediately draws my attention as a spot where the rules could be improved and streamlined. Similarly, when coding, certain behaviors draw my attention as opportunities for improvement. Hyper-explainy documentation is a big one.

Semantics is the study of meaning, and syntax is the study of structure. That distinction makes them sound like separate domains, but the two interpretations of "foreign car mechanic" stem from syntactic ambiguity. Each word still carries the same meaning, but in one case "foreign" modifies "car," and in the other, "foreign" modifies "mechanic." Syntax in natural languages certainly influences meaning, so why not in code, as well?

Diffing Files to Avoid Easy Goofs

A good habit learned at my last job has saved me a lot of embarrassment and bugs (same thing): Before committing a set of changes to source control, I look at the diff of each file. Look at the changes, read 'em over, look for misspellings and placeholder notes-to-self and files I hadn't intended to change; then make fixes and revert as needed. It's like proofreading. Polishing the fingerprints off a product before sending it into the world. Checking your knot.

Shortcuts for diffing files:
  • In TFS, Shift–double-click a file name in the Pending Changes window. (You can configure TFS's diff tool.)
  • In TortoiseSvn, double-click a file name in the "Changes made" panel of the Commit window.
  • In git and Hg... help me out here. I'm too used to a visual side-by-side. Recommend a nice explanation of getting the most from those in-line diff reports?

If that seems daunting because there are so many files to review, check in more often. I appreciate the mentors who have drilled into me: small, focused, atomic changes. It keeps me focused on what I'm doing. Make this one change, and every other stray thought that leaps to mind ("Ooh, I need to do this, too!") gets tossed in a running text file, to be addressed later. How small is small enough? When it no longer feels onerous to diff all your files before checking in. ;-) In addition to keeping my thought process on-track, this habit makes it easy to review, fix, unwind, and selectively pick certain changes when I need to.

Small check-ins are like the extract-method refactoring. In code, when you have a collection of statements that do something, you'd extract them into a method so that you can name the something. Similarly, a focused check-in can have a descriptive and useful check-in comment.

The three habits fit together: small check-ins targeting a focused goal, with a useful commit message, reviewing the changes before checking them in. Reduces the number of times I have to think "Who the heck did—?! Oh, me. Heh."

Microcontroller Projects and Source Code

Welcome, Ignite/Dorkbot Science Fair Party Goers. Here are details on the two projects I had with me at the Science Fair.

I used the open-source Arduino microcontroller. Arduino programs are called "sketches." I keep my Arduino sketches on the collaborative source-code repository GitHub, in my Arduino-Sketches repository. You can browse the code in a web browser without installing Git, so go check it out. And then learn Git and post your own sketches.

Ambient Clock

The Ambient Clock is an information radiator for the passage of time. It was written up on the Makezine blog. (pictures | program)


Blinky Eyeball Halloween Costume

The Blinky Eyeball Halloween Nightmare is, um, pretty self-describing. (write-up | pictures | program)

Hello World in C, Dev Setup

As mentioned, I'm learning C, and I've achieved hello-world, plus recursive calculations of factorials and some data structures. Whee. :) For those playing along at home, I'll describe my dev setup.

But first, an unexpected discovery: Counter to my intuition, there's a beneficial synergy between learning a new editor and learning a new language at the same time. I had thought it would be too many new things to take on at once. I've wanted to learn Vim for its beautiful efficiency, but its formidable learning curve repels all comers. I couldn't gain traction. When writing in a language with which I am comfortable (C#, English), my thoughts would run too fast, too far ahead of my rudimentary editor skills, ideas slipping out of my grasp as I stumbled around the text with j, k, h, and l (and never the one I meant). But in C, where I am carefully picking my way over unfamiliar terrain, my lines of code have slowed down to match my fingers. Because I am trying to hang onto only one edit at a time, I can spare a second to check that A will switch me to insert mode at the end of the current line. I recommend it: learning a new language is a good time to learn a new text editor.

Sandbox


I use VirtualBox to run virtual machines. VMs are excellent for experiment-based learning; think of it: a nice clean server that you can start up, poke and abuse, throw away and start again. If you start with the right VM image—for example, one configured for Ruby on Rails—you can jump right into the experimentation without all the installation hoop-jumping.

For this endeavor I chose TurnKey Linux's Core appliance because it's just Linux and not much else, following their instructions for installing a TurnKey appliance.

To install a compiler (later), I needed my VM to connect to the internet. In VirtualBox Settings > Network, I set "Attached to" to "Bridged Adapter," meaning the VM could use my laptop's connection, and the adapter's "Name" to my wireless card. (The other choice in the dropdown list is a PCI-E Fast Ethernet Controller, and that... didn't work.) With that set, I powered up the VM, which starts the webmin console. I let it automatically configure DHCP, and I was internet-ready.

Editor


Vim is already installed on the Core VM image, so I just needed to type "vim helloworld.c" to start stumbling around my new code file. I'm relying on the TuXfiles Vim cheat sheet.

Compiler


I chose GCC, the GNU Compiler Collection for my C compiler, and I needed to download and install it. Following TurnKey's apt-get instructions:
  • apt-get update (to update apt's list of modules)
  • apt-cache search gcc (to find modules for the gcc compiler - gcc-4.1 looked right.)
  • apt-cache show gcc-4.1 (to get info about it)
  • apt-get install gcc-4.1 (to install it)
  • gcc-4.1 myfile.c -o myexename (to compile and generate myexename executable)
  • ./myexename (to run my program)


Hello World


I followed a video that creates and compiles a C program using the GCC compiler. "Hello, World!" A simple phrase, profoundly satisfying.