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?