<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Leveling Up</title>
		<description>Programming, learning and generally getting better</description>
		<link>http://billgathen.com</link>
		<atom:link href="http://billgathen.com/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>We Are A Service Industry</title>
				<description>&lt;h1 id=&quot;we-are-a-service-industry&quot;&gt;We Are A Service Industry&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;May 2015 - Grand Rapids&lt;/p&gt;

&lt;h2 id=&quot;why-we-code&quot;&gt;Why We Code&lt;/h2&gt;

&lt;p&gt;I got into programming because I liked messing with computers and thought it would be a more-reliable career than writing fiction, which was my passion.&lt;/p&gt;

&lt;p&gt;This is probably the most-common reason people are encouraged to try programming as a career: it pays well and we enjoy messing with computers.&lt;/p&gt;

&lt;p&gt;It was a good fit for me. I enjoy learning new languages, new techniques, new ways of thinking about programming.&lt;/p&gt;

&lt;p&gt;More importantly, I enjoy solving problems with code.&lt;/p&gt;

&lt;h2 id=&quot;who-we-code-for&quot;&gt;Who We Code For&lt;/h2&gt;

&lt;p&gt;But whose problems? Not mine. Most of my difficulties have already been solved by other people’s programs.&lt;/p&gt;

&lt;p&gt;I solve &lt;em&gt;other people’s&lt;/em&gt; problems. Put more dramatically, &lt;strong&gt;I give people superpowers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If one of my account managers needs to change the data for a thousand items at once, it is simply not possible given the UI for our third-party system. It would take too long, be too vulnerable to human error, and it would be &lt;em&gt;boring&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But I can write a program that gives them power beyond that of ordinary mortals. The ability to make sweeping changes they couldn’t imagine before. The ability to remake their world in a way that matters.&lt;/p&gt;

&lt;h2 id=&quot;we-are-a-service-industry-1&quot;&gt;We Are A Service Industry&lt;/h2&gt;

&lt;p&gt;Some coders hate their users. “If the darned users would just stay out of the system, everything would be fine!”&lt;/p&gt;

&lt;p&gt;Bug tickets, feature requests and questions, questions, questions… Users are a distraction from building that perfect ivory-tower application that makes all other coders bow down before our awesomeness.&lt;/p&gt;

&lt;p&gt;Perfect. And perfectly irrelevant.&lt;/p&gt;

&lt;p&gt;A program that doesn’t make our users’ lives better doesn’t deserve to be written. A program that confuses our users or doesn’t allow them to achieve their goals is a bad program, no matter how many patterns and architectures and brilliant hacks are under the hood.&lt;/p&gt;

&lt;p&gt;Kathy Sierra talks about &lt;a href=&quot;https://vimeo.com/54469442&quot;&gt;making our users more badass&lt;/a&gt;. To do that, we start by taking the focus away from ourselves and what we want to write, so we can concentrate on what our users need and how they think.&lt;/p&gt;

&lt;h2 id=&quot;codenewbies&quot;&gt;Codenewbies&lt;/h2&gt;

&lt;p&gt;I haven’t blogged here much recently, mainly because I’ve been writing guest blogs for &lt;a href=&quot;http://codenewbie.org/blog&quot;&gt;Codenewbies&lt;/a&gt;: a website, forum and podcast from &lt;a href=&quot;http://twitter.com/saronyitbarek&quot;&gt;Saron Yitbarek&lt;/a&gt; with service firmly in the forefront of its attention.&lt;/p&gt;

&lt;p&gt;If you’re new to the coding world, CodeNewbie wants to give you superpowers. If you’re more experienced – even just a little – CodeNewbie is an opportunity.&lt;/p&gt;

&lt;p&gt;Join the &lt;a href=&quot;https://twitter.com/search?f=realtime&amp;amp;q=%23CodeNewbie&quot;&gt;Twitterchat&lt;/a&gt;. Post an answer on the forums. Write a blog post. Be a friendly voice from out of the darkness. Take this chance to be helpful to people you’ve never met, to ease the struggle of someone on the path to their dreams of programming.&lt;/p&gt;

&lt;p&gt;Ask yourself that all-important question: how can I be of service?&lt;/p&gt;
</description>
				<pubDate>Sat, 16 May 2015 00:00:00 -0400</pubDate>
				<link>http://billgathen.com/2015/05/16/service.html</link>
				<guid isPermaLink="true">http://billgathen.com/2015/05/16/service.html</guid>
			</item>
		
			<item>
				<title>Year of Kindness, Year of Harmony</title>
				<description>&lt;h1 id=&quot;year-of-kindness-year-of-harmony&quot;&gt;Year of Kindness, Year of Harmony&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;January 2015 - Grand Rapids&lt;/p&gt;

&lt;h2 id=&quot;one-word&quot;&gt;One Word&lt;/h2&gt;

&lt;p&gt;Just before Christmas of 2013, my lovely wife bought me a copy of a book called &lt;a href=&quot;http://getoneword.com/&quot;&gt;One Word That Will Change Your Life&lt;/a&gt;. The concept is simple: pick a single word you will use as the focus of the next 12 months.&lt;/p&gt;

&lt;p&gt;At first I thought it was ridiculous. I’m a complex, mercurial person… how can just one word sum up my goals for a whole year? Every option I thought of was too small, too confining. I want to grow, to teach, to learn, to laugh, to be strong and fast and healthy and capable and loving…&lt;/p&gt;

&lt;p&gt;Until one day in the checkout line at a local bookstore I saw a magnet that said “Be Kind. No Exceptions.”&lt;/p&gt;

&lt;p&gt;Kindness. That’s a word big enough to encapsulate a life, to fill up a year.&lt;/p&gt;

&lt;p&gt;I bought the magnet.&lt;/p&gt;

&lt;h2 id=&quot;kindness&quot;&gt;Kindness&lt;/h2&gt;

&lt;p&gt;I resolved to be kind in my everyday interactions: the random, ordinary conversations that make up a life. If we interacted this year and you feel I failed in this, I apologize. I probably agree with you and have felt bad about it ever since.&lt;/p&gt;

&lt;p&gt;Even after a year of practice I’m not perfect, but the world around me was improved by the fact that I made the effort. I can easily be too blunt, typically when I forget that the people around me are in fact &lt;em&gt;people&lt;/em&gt; with feelings and lives and dignity.&lt;/p&gt;

&lt;p&gt;But that wasn’t enough. I made it my goal to view every decision – personal, familial, social and professional – through the lens of kindness. “Of these two choices, which one brings more happiness to the world?” If I do something for me, how can I expand it to benefit others too?&lt;/p&gt;

&lt;p&gt;Now when I learn something, I find someone to teach it to. If I discover something amazing, I share. I give credit where it’s due. I focus on the positive. When I build an app I think hard on how it can empower my users to do more and be more. I like to say I write apps that give people superpowers.&lt;/p&gt;

&lt;p&gt;When it came time to &lt;a href=&quot;http://localhost:4000/2014/12/14/generosity_gives_back.html&quot;&gt;go to RubyConf&lt;/a&gt; again, I decided it would be a pointless trip if I was the only one who benefited, so I submitted a conference talk. When that didn’t work out, I volunteered as a guide. When &lt;strong&gt;that&lt;/strong&gt; didn’t work out, I led a workshop. I was tenacious. Once I decided I was going to help, it was reduced to a question of how.&lt;/p&gt;

&lt;p&gt;Focusing on kindness helped the people around me, but it helped me, as well. It is the only thing that has helped me beat impostor syndrome and reminded me that I’m here for a reason that has nothing to do with winning or losing or having the newest toy. It’s about creating the most joy.&lt;/p&gt;

&lt;h2 id=&quot;another-word&quot;&gt;Another Word&lt;/h2&gt;

&lt;p&gt;2014 is over. I certainly intend to continue being kind, but how to move forward into the new year?&lt;/p&gt;

&lt;p&gt;My wife and I debated if I should keep the same word, or try a synonym, since the year had gone so well. I wanted to stretch, to expand my kindness with a new word, but nothing came to mind. It didn’t help that this all occurred to me on New Year’s Eve, when I was busy with family and food and laziness.&lt;/p&gt;

&lt;p&gt;I was sorely tempted to look inward, to find a word that would focus more on &lt;strong&gt;me&lt;/strong&gt;, after a whole year of looking outward.&lt;/p&gt;

&lt;h2 id=&quot;music&quot;&gt;Music?&lt;/h2&gt;

&lt;p&gt;I’ve been a music nut my whole life: played a variety of instruments half-competently, listened to every genre of music I could find. My playlists are so diverse they border on random. My children are beginning to explore music and I want to share that with them. The idea of devoting a year to really leveling-up my musical life was exciting.&lt;/p&gt;

&lt;p&gt;On the &lt;a href=&quot;http://codenewbie.org&quot;&gt;CodeNewbie&lt;/a&gt; Twitterchat, I said&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Learn-to-code goal for 2015 is music. Make music with code, teach code with music, learn from musicians, live life as a song.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I liked those ideas. I still do. But is music big enough? Is it something I can apply to every decision I make? “Of these two choices, which one brings more music to the world?” How to blend music and kindness? How to learn and grow from something I’ve pursued my entire life?&lt;/p&gt;

&lt;p&gt;The next day, beside the cash register of a hospital gift shop, sat a bowl of shiny stones with a single words on each. On top rested one in midnight blue that said “Harmony”.&lt;/p&gt;

&lt;p&gt;I bought the stone.&lt;/p&gt;

&lt;h2 id=&quot;harmony&quot;&gt;Harmony&lt;/h2&gt;

&lt;p&gt;In music, harmony means the relationship between multiple pitches sounding at the same time, whether on a single instrument like a piano or across many instruments like in a band or orchestra. It’s about different notes working together to make music.&lt;/p&gt;

&lt;p&gt;Harmony is about connection. It’s about leveraging differences. It’s about joining together to make something great. It’s about all of us together being better than any of us alone. It’s a celebration of diversity.&lt;/p&gt;

&lt;p&gt;Music depends on harmony, but so does coding, and so does life. They can learn so much from each other.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;What do musicians know about learning new things? About communicating? About working in a team?&lt;/li&gt;
  &lt;li&gt;How do conductors bring their players together in a great performance?&lt;/li&gt;
  &lt;li&gt;How do songwriters continue to create in the face of indifference or outright hostility? How do they find the courage to show their work to the world and say “I think this will make you happy”?&lt;/li&gt;
  &lt;li&gt;Is it possible to compose software the way a composer creates a symphony?&lt;/li&gt;
  &lt;li&gt;Is it possible to learn music and coding &lt;a href=&quot;http://sonic-pi.net/&quot;&gt;at the same time&lt;/a&gt;?&lt;/li&gt;
  &lt;li&gt;What is it about music that fills our hearts, and how do we find those things in our lives and our careers?&lt;/li&gt;
  &lt;li&gt;What would it mean to live your life as a song?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don’t know. But I intend to find out.&lt;/p&gt;
</description>
				<pubDate>Sun, 11 Jan 2015 00:00:00 -0500</pubDate>
				<link>http://billgathen.com/2015/01/11/year_of_kindness_year_of_harmony.html</link>
				<guid isPermaLink="true">http://billgathen.com/2015/01/11/year_of_kindness_year_of_harmony.html</guid>
			</item>
		
			<item>
				<title>Generosity Gives Back - RubyConf 2014</title>
				<description>&lt;h1 id=&quot;generosity-gives-back---rubyconf-2014&quot;&gt;Generosity Gives Back - RubyConf 2014&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;December 2014 - Grand Rapids&lt;/p&gt;

&lt;p&gt;I was failing at &lt;a href=&quot;http://rubyconf.org&quot;&gt;RubyConf&lt;/a&gt;. I was one of “those guys”: white dude in jeans, t-shirt and hoodie, walking down the middle of the hallway staring at my phone in order to avoid eye contact.&lt;/p&gt;

&lt;p&gt;I knew I was failing. The voice in my head screamed at me “you’re blowing it!” every time a took a step, which made me feel more like a loser and less able to step outside my comfort zone and really get some benefit from this conference I’d flown the width of the country to attend.&lt;/p&gt;

&lt;p&gt;The “hallway track” is the one part of a tech conference you can’t &lt;a href=&quot;http://confreaks.com/events/RubyConf2014&quot;&gt;watch online from home&lt;/a&gt;. It’s the place for cross-pollination, where you meet people from different places with different problems and skillsets and backgrounds and interests. People that aren’t exactly like you. The ones that can expand your mind and make you think about things in a novel way. The ones that remind you that your world isn’t the whole world.&lt;/p&gt;

&lt;h2 id=&quot;outside-my-comfort-zone&quot;&gt;Outside My Comfort Zone&lt;/h2&gt;

&lt;p&gt;Long before the conf, in the comfort of my cubicle, I’d decided to be bold. To stretch outside my comfort zone and not just &lt;strong&gt;take&lt;/strong&gt; from the conference: I wanted to contribute. I’d been to &lt;a href=&quot;http://confreaks.com/events/rubyconf2012&quot;&gt;RubyConf in 2012&lt;/a&gt;, so this time I needed to level up and submit a talk. I picked a subject near and dear to my heart, poured all my energy into putting together what I thought was a kick-ass proposal and sent it off, heart pounding in my chest.&lt;/p&gt;

&lt;p&gt;It was rejected. Which sucked. I knew there was only an outside chance my first talk submission would be accepted, but it stung. More importantly, it meant I needed to find some other way to contribute.&lt;/p&gt;

&lt;p&gt;A few weeks before the conf, I signed-up to be a &lt;a href=&quot;http://rubyconf.org/scholarship&quot;&gt;Guide&lt;/a&gt; for one of the Opportunity Scholars the conf sponsored. As a friendly face to talk to and answer questions, I could make a first-time attendee feel welcome. It would be a win-win: I can be much more confident and outgoing if it’s to someone else’s benefit instead of my own.&lt;/p&gt;

&lt;p&gt;In the end, that didn’t work out either, because I never got to meet my Scholar. I missed the “meet and greet” event due to a delayed flight, and they apparently decided they were fine facing the conf on their own.&lt;/p&gt;

&lt;p&gt;Strike two.&lt;/p&gt;

&lt;h2 id=&quot;beginners&quot;&gt;Beginners&lt;/h2&gt;

&lt;p&gt;When I thought I’d be guiding a newbie through the conf, I figured the “Beginner Track” would be the most beneficial to my Scholar. This worked out great, because it was the track I was most interested in anyway.&lt;/p&gt;

&lt;p&gt;It was terrific. I’m not a beginner, but the topics on that track had broad utility outside that narrow definition. Kerri Miller’s &lt;a href=&quot;http://confreaks.com/videos/5128-RubyConf2014-5-things-i-wish-someone-had-told-me-about-programming-before-i-started&quot;&gt;“Five Things”&lt;/a&gt; talk and Abraham Sangha’s &lt;a href=&quot;http://confreaks.com/videos/5069-RubyConf2014-tdd-for-your-soul-virtue-and-software-engineering&quot;&gt;“TDD For Your Soul”&lt;/a&gt; in particular should be required watching for every developer.&lt;/p&gt;

&lt;p&gt;And though it wasn’t technically on the “Beginner Track”, &lt;a href=&quot;http://confreaks.com/videos/4868-RubyConf2014-good-luck-with-that-tag-teaming-civic-data&quot;&gt;“Good Luck With That: Tag Teaming Civic Data”&lt;/a&gt; from Hsing-Hui Hsu and Liz Rush was possibly the most inspiring conf talk I’ve ever seen. These two “novices” exemplify everything a world-class developer should be: tenacious, creative, cooperative, learning-focused and dedicated to helping people with tech. My notes from that talk are one word: wow.&lt;/p&gt;

&lt;h2 id=&quot;birds-of-a-feather-bof&quot;&gt;Birds of a Feather (BOF)&lt;/h2&gt;

&lt;p&gt;During her talk, Kerri challenged all of us to think of a lightning talk to give at the end of Day 2, and said she would help us any way she could, even offering up her super-duper remote control if we needed it. Lightning talks are five-minute mini-talks on any topic the presenter likes. They’re a great on-ramp to giving a full-length talk in the future.&lt;/p&gt;

&lt;p&gt;I considered doing an abbreviated version of my talk – and in retrospect missed a &lt;strong&gt;golden&lt;/strong&gt; opportunity to talk about Saron Yitbarek’s fantastic &lt;a href=&quot;http://codenewbie.org&quot;&gt;CodeNewbie&lt;/a&gt; project – but instead decided to stretch in a different direction and host a “Birds of a Feather” session.&lt;/p&gt;

&lt;p&gt;BOFs are evening sessions anyone can host on any subject they like. I picked “Pair Programming” because I wanted an activity that would help people engage in the very way I’d failed to the first day of the conf. With a common goal to occupy our minds, we could forget we were shy and drowning in impostor syndrome.&lt;/p&gt;

&lt;p&gt;I want to emphasize that I didn’t pick this topic because I’m &lt;a href=&quot;http://articles.coreyhaines.com/posts/thoughts-on-pair-programming&quot;&gt;an expert in pair programming&lt;/a&gt;: I’m not. I’ve done a few hours of it, but my main goal was to draw in people who do it all day, every day and match them with people like myself who want to do it more but lack the practical experience.&lt;/p&gt;

&lt;p&gt;That’s how I pitched it to everyone I met on Day 2: come help me, because I don’t know what I’m doing. In fact, knowing that I needed people to come to my session – I couldn’t pair by myself – helped me talk to way more people on Day 2. The “social distraction” theory proved itself: my goal of recruiting helped me forget that I wasn’t comfortable talking to strangers.&lt;/p&gt;

&lt;p&gt;The session itself was a mixed-bag: there was a lot I could have done better. But I accomplished my overall goal of drawing in coders with extensive pairing experience – &lt;a href=&quot;http://resume.livingston-gray.com&quot;&gt;Sam Livingston-Gray&lt;/a&gt; and &lt;a href=&quot;https://github.com/baccigalupi&quot;&gt;Kane Baccigalupi&lt;/a&gt; – and picking their brains about how to do pairing better. Several other newbies like myself came and benefited as well, so I’d call the session my first actual success of the conf.&lt;/p&gt;

&lt;h2 id=&quot;hallway-track-my-way&quot;&gt;Hallway Track My Way&lt;/h2&gt;

&lt;p&gt;Once I’d “opened the floodgates” hosting the BOF, I finally started to come out of my shell and had several amazing conversations with developers from radically-different environments.&lt;/p&gt;

&lt;p&gt;I talked until the wee hours of the morning with Yunlei, a dev from California whose heavily-structured corporate world is the polar opposite of my experience in nearly every way.&lt;/p&gt;

&lt;p&gt;I actually left the BOF for a few minutes to help Hugo – a dev from Sao Paolo, Brazil – who was having trouble finding the session he was looking for. We had a long conversation that ended with him recruiting me to come give my talk in Brazil! I doubt my boss would foot the bill for that, but it was certainly a tempting offer.&lt;/p&gt;

&lt;p&gt;Even though I never actually met my Scholar, I went to the “retrospective” lunch on Day 3 anyway and ended up sitting next to &lt;a href=&quot;http://kerrizor.com/&quot;&gt;Kerri Miller&lt;/a&gt;. I took the opportunity to gush about how great her talk was and raved about the “Good Luck With That” talk, since both presenters had come through &lt;a href=&quot;http://adadevelopersacademy.org&quot;&gt;Ada Developers Academy&lt;/a&gt;, where Kerri teaches. Top-notch students plus top-notch instruction is a potent combination.&lt;/p&gt;

&lt;p&gt;I met a lot of nice people at RubyConf – I’d say the percentage was at least 95% – but Kerri really stands out. She has a gentle grace and encouraging nature that makes anything seem possible. It comes through in her talk, but was even more pronounced in one-on-one conversation. She asked about my conf talk and said the magic words “Let me know when you give that talk. I’d really like to see it.”&lt;/p&gt;

&lt;h2 id=&quot;generosity-driven-development&quot;&gt;Generosity-Driven Development&lt;/h2&gt;

&lt;p&gt;I’ve mentioned my talk proposal several times, so I should probably tell you the topic: Generosity-Driven Development.&lt;/p&gt;

&lt;p&gt;I believe it’s human nature to get caught up in what we need. How will these blogs/talks/confs/people help &lt;strong&gt;me&lt;/strong&gt;? Will they help me get a better job or a promotion? Will they help me solve a problem I’m struggling with? Will they help me be happy? Turning inward appeals to our intellects, but doesn’t help us be the best versions of ourselves.&lt;/p&gt;

&lt;p&gt;Being generous means turning outward: how can we contribute, whose problems can we help solve, what pain can we ease? Software development is a &lt;strong&gt;service&lt;/strong&gt; industry and putting service at the forefront of our minds maximizes the positive impact we can have on our team, our community and our world.&lt;/p&gt;

&lt;h2 id=&quot;generosity-gives-back&quot;&gt;Generosity Gives Back&lt;/h2&gt;

&lt;p&gt;My talk focused on the importance of benefiting others, but there’s a secret I wanted to save until last: generosity gives back.&lt;/p&gt;

&lt;p&gt;My RubyConf story bears this out. When I arrived, walking the halls and staring at my phone, I was obsessed with all the personal benefits I was missing by not “networking” with all these “resources”.&lt;/p&gt;

&lt;p&gt;But once Kerri’s talk helped me turn my attention outward again – to hosting the pairing session with an intent to help others – it brought me out of my shell. I talked to the people I couldn’t talk to before, because I wanted to ensure that anyone else as shy as me would have a safe opportunity to make a connection with other developers and become part of the Ruby community.&lt;/p&gt;

&lt;p&gt;Volunteering as a guide is what got me to the lunch where I spoke to Kerri. Helping search for the other BOF session got me talking to Hugo. Hosting the BOF got me talking to Sam and Kane. Wanting to make sure my Scholar got useful information from the sessions got me onto the beginner track, where I saw my favorite talks.&lt;/p&gt;

&lt;p&gt;In the end, almost everything good that happened to me in San Diego came as a result of something I did to try and help others with no thought of how it would benefit me.&lt;/p&gt;

&lt;p&gt;Hmm. I guess I really should give that talk.&lt;/p&gt;
</description>
				<pubDate>Sun, 14 Dec 2014 00:00:00 -0500</pubDate>
				<link>http://billgathen.com/2014/12/14/generosity_gives_back.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/12/14/generosity_gives_back.html</guid>
			</item>
		
			<item>
				<title>Diversity is a Superpower</title>
				<description>&lt;h1 id=&quot;diversity-is-a-superpower&quot;&gt;Diversity is a Superpower&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;September 2014 - Grand Rapids&lt;/p&gt;

&lt;h2 id=&quot;find-the-fail&quot;&gt;Find the fail&lt;/h2&gt;

&lt;p&gt;Pop quiz: Where is the fail in this sentence?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;My dev team is all-white and all-male.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’ve been paying attention the last few years, you realize
there’s a problem there, but it might not be exactly where you think.&lt;/p&gt;

&lt;p&gt;The fail is in the word &lt;strong&gt;all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An article in Scientific American called &lt;a href=&quot;http://www.scientificamerican.com/article/how-diversity-makes-us-smarter/&quot;&gt;“How Diversity Makes Us Smarter”&lt;/a&gt;
by Professor Katherine W. Phillips eloquently-demonstrates a
perspective on diversity that had completely gone under my radar.
If this has been obvious to you for years, my apologies: I’m doing my best.&lt;/p&gt;

&lt;p&gt;My #1 reason for being pro-diversity is that problem-solving ability
and intelligence don’t vary across race, gender, ethnicity, sexual-orientation or
nationality, and someone being shoved out of an opportunity
(actively or passively) on those criteria is just plain wrong.&lt;/p&gt;

&lt;p&gt;Reason #2 is that anyone in a minority position in a competitive field 
has had to work harder, tolerate more and sacrifice more
than their majority colleagues, which means they are stronger, more
resilient and have more grit given a similar level of experience and
education.&lt;/p&gt;

&lt;p&gt;I still stand by both of these.&lt;/p&gt;

&lt;p&gt;But if neither of those are sentiments you’re willing to risk your company
on, Professor Phillips points
out competitive advantages that have nothing to do with either.&lt;/p&gt;

&lt;h2 id=&quot;an-embarrassing-history-lesson&quot;&gt;An embarrassing history lesson&lt;/h2&gt;

&lt;p&gt;The current mostly-white, mostly-male tech world we live in is a direct
consequence of the mostly-white, mostly-male business world that existed when
computers were invented. It’s a self-fulfilling prophecy: we tend to
gather around us people who look like us. People who don’t look like
the person in the hiring chair are automatically at a disadvantage,
even when the hirer consciously-attempts to be “unbiased”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is laziness. This is fear. This is killing our teams.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What about the alternative? Professor Phillips says it’s not all rainbows and unicorns:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Research has shown that social diversity in a group can cause discomfort,
rougher interactions, a lack of trust, greater perceived interpersonal conflict,
lower communication, less cohesion, more concern about disrespect, and other problems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some accolade for diversity, huh? But what if we phrased it this way?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diversity makes us less-comfortable, more self-conscious and more careful
how we treat others.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That’s not quite so scary. Maybe more work than we’d like, but not completely unacceptable.&lt;/p&gt;

&lt;p&gt;And we’re close now… Very close. This is the paragraph that blew my tiny little mind:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The groups with racial diversity significantly outperformed the groups
with no racial diversity. Being with similar others leads us to think
we all hold the same information and share the same perspective.
This perspective, which stopped the all-white groups from effectively
processing the information, is what hinders creativity and innovation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There’s the secret sauce, right there in the middle:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Being with similar others leads us to think we
all hold the same information and share the same perspective.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;This&lt;/strong&gt; is the competitive failure of non-diverse teams: we presume that a person who looks like us
also thinks like us, has similar experiences and a similar level of expertise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why in the world would we ask a person like that for help? Or a second
opinion? Or to check our sanity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We simply assume they will agree. (I’ll let you fill in the rest of that joke)&lt;/p&gt;

&lt;p&gt;In short, being surrounded by people we perceive as exactly like us turns us into idiots.
(Which frankly explains a lot about why the internet is the way it is, but that’s for
 another day)&lt;/p&gt;

&lt;h2 id=&quot;leveraging-our-own-idiocy&quot;&gt;Leveraging our own idiocy&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Diversity is not only about bringing different perspectives to the table.
Simply adding social diversity to a group makes people believe that differences
of perspective might exist among them and that belief makes people change their behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The power of diversity is that this prejudice cuts both ways. Apparently we also presume that a
person that &lt;strong&gt;doesn’t&lt;/strong&gt; look like us has different thoughts, experiences and
levels of expertise. &lt;strong&gt;Which is always the truth, no matter which two people
you compare.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;BTW, If you’re a member of that dying breed that assumes those thoughts, experiences
and expertise are &lt;strong&gt;inferior&lt;/strong&gt; to yours until proven differently, might I suggest
you consider the old saying “better to keep silent and be thought a fool than to
speak and remove all doubt”?&lt;/p&gt;

&lt;p&gt;Professor Phillips has more good news:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When disagreement comes from a socially different person, we are prompted
to work harder. Diversity jolts us into cognitive action in ways that
homogeneity simply does not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sadly, when we are surrounded by clones (our own personal echo chamber!), we don’t
bother making sure our arguments are air-tight and that we’ve done our homework
properly, because we assume everyone will hear our idea, recognize its genius
and high-five us enthusiastically. Which means when our half-baked solution
starts throwing harsh reality at us, we’ll be completely blindsided, while the
diverse team noticed and fixed it 2 months ago.&lt;/p&gt;

&lt;h2 id=&quot;change-your-perspective-change-your-world&quot;&gt;Change your perspective, change your world&lt;/h2&gt;

&lt;p&gt;Ok, let’s sum up. Diversity:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Increases the quantity and improves the quality of team communication&lt;/li&gt;
  &lt;li&gt;Constantly encourages individual team members to do their best&lt;/li&gt;
  &lt;li&gt;Guarantees a broader selection of ideas and solutions&lt;/li&gt;
  &lt;li&gt;Keeps us from making fools of ourselves in production and the marketplace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, prejudice exists. But it doesn’t have to be a failing. We merely have
to translate the outdated assumption that “different” equals “inferior” into
a realization that “different” equals “competitive advantage”.&lt;/p&gt;

&lt;p&gt;Alan Kay famously said “a change in perspective is worth 80 IQ points”. By that
reckoning, a five-person team with average skills and 100% diversity is the equivalent of
two “genius” coders who look exactly alike (and is probably easier to deal with).&lt;/p&gt;

&lt;p&gt;Let’s start viewing diversity as not just a balancing of the cosmic scales
of justice, but also a source of tremendous power in every challenge we face.&lt;/p&gt;

&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The more differences you perceive between yourself and another person, the
more powerful and productive your interactions with them can be, even if
the differences aren’t directly relevant to the task you’re solving.&lt;/li&gt;
  &lt;li&gt;Visual diversity of any kind is a constant reminder that we are all individuals,
with unique contributions to make.&lt;/li&gt;
  &lt;li&gt;Expecting to have to defend our decisions makes us do our best, and a diverse
group leverages a weakness in our evolution to keep us doing that every day.&lt;/li&gt;
  &lt;li&gt;I believe in you&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Mon, 22 Sep 2014 00:00:00 -0400</pubDate>
				<link>http://billgathen.com/2014/09/22/diversity_is_a_superpower.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/09/22/diversity_is_a_superpower.html</guid>
			</item>
		
			<item>
				<title>What Programming Language Should I Learn?</title>
				<description>&lt;h1 id=&quot;what-programming-language-should-i-learn&quot;&gt;What Programming Language Should I Learn?&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;September 2014 - Grand Rapids&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Read on if: you want to get a coding job now and/or have a coding career later&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you’re not satisfied with being a consumer of
technology and want to become a producer, too? Or you’ve heard about the boom
of tech job opportunities and you think this might be a way to make a good living
doing something that challenges you? Or you’re already skilled in some other area
but believe an ability to code would help you further your cause/hobby/business?&lt;/p&gt;

&lt;p&gt;Those are all radically-different reasons for learning to code and will lead you
down very different paths when choosing a language.&lt;/p&gt;

&lt;h2 id=&quot;is-this-your-first-language&quot;&gt;Is This Your First Language?&lt;/h2&gt;

&lt;p&gt;I believe that with persistence, adequate resources and a
learning mindset, anyone can learn any language and be successful
coding in it. Having said that, all languages are &lt;strong&gt;not&lt;/strong&gt; created equal. I can’t
tell you how many people have told me over the years “Yeah, I did some programming
in college, but then I took a C++ class and I quit.”&lt;/p&gt;

&lt;p&gt;Some languages were designed to be easy to learn: Python are Ruby are good
examples. They don’t have &lt;em&gt;too many&lt;/em&gt; cryptic bits of syntax and are both powerful
general-purpose languages that can accomplish many of the things you might want to
code.&lt;/p&gt;

&lt;p&gt;Other languages don’t care much about ease of use on the part of the user: they
make themselves easy for the computer to understand. Most of the C-based languages
fall victim to this: C, C++, Java.&lt;/p&gt;

&lt;p&gt;Then there are languages that seem to be designed explicitly to keep people
out by being incredibly odd and full of bizarre (though powerful) concepts. Haskell,
Clojure and Erlang are examples of these. Don’t get me wrong: once you’ve figured these
languages out you can do &lt;strong&gt;amazing&lt;/strong&gt; things, but they’re certainly not a good place
to start.&lt;/p&gt;

&lt;p&gt;JavaScript (the only language that runs in a web browser and therefore the most
wide-spread language in the world) strangely has a foot in every one of these camps.
Some of it is delightfully-easy to use, especially when combined with the jQuery
library for interacting with the browser. It’s also surprisingly-elegant and powerful,
but there are odd corners that cause all sorts of obscure bugs for the unwary.
If ever there was a bipolar programming language, JavaScript is it. The JS community
is equal parts love and loathing, sometimes by the same coder on the same day!&lt;/p&gt;

&lt;h2 id=&quot;what-do-you-want-to-do-with-it&quot;&gt;What Do You Want To Do With It?&lt;/h2&gt;

&lt;p&gt;If you simply want to explore programming and expand your mind, pick a language
that looks fun and has a vibrant community around it. If you’re not getting paid,
you won’t want to spend much (or anything) on learning resources, so choose something
with lots of free ones. Three that come to mind and are all reasonable “gateway”
languages are &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript&quot;&gt;JavaScript&lt;/a&gt;, &lt;a href=&quot;http://python.org&quot;&gt;Python&lt;/a&gt; and &lt;a href=&quot;http://ruby-lang.org&quot;&gt;Ruby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to code in support of your cause, your business or your hobby, you’re
probably talking about getting a site up on the web, so try &lt;a href=&quot;http://wordpress.org/&quot;&gt;Wordpress&lt;/a&gt; if you’re
planning a blog and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web&quot;&gt;HTML/CSS/JavaScript&lt;/a&gt; if you’re planning a full-blown site.
An actual web application will require a back-end (i.e., code that runs on the
web server instead of your user’s browser) solution as well, and currently
JavaScript, Python and Ruby are reasonable choices for this, too.&lt;/p&gt;

&lt;p&gt;Freelancing is an option, if you like to hustle and interacting with
new people. Most of the freelancers I know set up blogs or web sites for smaller companies
that want one but don’t want to hire a full-timer to build/maintain it, so all
the previous choices are perfectly valid. There are some freelancers that contract 
to build bigger apps using tools like &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt;, but the blog/web site avenue is
probably an easier on-ramp.&lt;/p&gt;

&lt;p&gt;If you want to work in a small business such as a startup, you are clearly a
risk-taker, so I’d suggest finding a bunch of startups that are doing interesting
work you’d like to be involved in, then find out what technologies they’re building
their business around. Some startups (well, businesses of any size) can fall prey
to the “we only hire rockstars” mentality. Avoid these, which will be easy since
they only tend to hire their friends anyway. But some startups have a “build,
don’t buy” mindset when it comes to coders and are willing to hire you as a junior
dev and then make sure you level up rapidly. Just make sure they don’t intend to
work you to death in the meantime. Startups will likely be more receptive to
(or even started by!) graduates of the new hacker schools and dev boot camps.&lt;/p&gt;

&lt;p&gt;Very large companies tend to be more conservative with their language choices,
relying on “proven” languages that aim themselves at the enterprise, typically
&lt;a href=&quot;https://www.java.com/en/&quot;&gt;Java&lt;/a&gt; and &lt;a href=&quot;http://www.microsoft.com/net&quot;&gt;.NET&lt;/a&gt;.
However, this is changing, especially with so many web-based
companies dominating the landscape. While both of those languages can be used
to build the web, they are by no means the default choice, so keep an open mind and do your
research before committing.&lt;/p&gt;

&lt;p&gt;And of course I have to mention the exploding “mobile app” community:
over 50% of all internet activity is conducted over mobile, and that’s only likely to increase.
Many people build apps that run either on iOS (which is transitioning from
&lt;a href=&quot;https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html&quot;&gt;Objective C&lt;/a&gt;
to Apple’s &lt;a href=&quot;https://developer.apple.com/swift/&quot;&gt;Swift&lt;/a&gt; language) or &lt;a href=&quot;https://developer.android.com/guide/index.html&quot;&gt;Android&lt;/a&gt;,
which uses Java. Apps built on one will not run on the other, so choose wisely.
Also, this may be the most glutted area of coding, with millions of apps fighting
for attention in the respective app stores, so consider that carefully before
jumping into the ring because it seems like “the obvious choice”.&lt;/p&gt;

&lt;h2 id=&quot;no-silver-bullets&quot;&gt;No Silver Bullets&lt;/h2&gt;

&lt;p&gt;An important side note is that there is no “guaranteed good choice”. If the company
you want to work for doesn’t use the language you learned, it doesn’t matter if it’s
“the industry standard”. For my current job, I decided to use an obscure-but-promising
language which has become popular in the subsequent 5 years (Ruby). I was lucky
that my boss didn’t care about what I used as long as I got the work done, which
is unbelievably-valuable. Full disclosure: this is the only job I’ve ever had where
I got that luxury. :-)&lt;/p&gt;

&lt;p&gt;Also, as I mentioned in the section on mobile app development, make sure
to consider the “talent pool” of the language. If there are 1,000 Java jobs
and 100,000 Java coders, that’s not a promising equation. It’s like trying to use
the restroom at half-time of the football game. The same is true of picking only
enterprise companies to work for “because they’re a safe bet”. Smaller companies
get a &lt;strong&gt;much&lt;/strong&gt; smaller pool of applicants, so they might be a better option for
someone trying to break in. Even if they go under in a year, then you’ll be looking
for a job &lt;strong&gt;with a year of professional experience&lt;/strong&gt;!&lt;/p&gt;

&lt;h2 id=&quot;who-can-help-you-learn-it&quot;&gt;Who Can Help You Learn It?&lt;/h2&gt;

&lt;p&gt;The rise of hacker schools and dev boot camps offer an opportunity for immersive
learning in one set of technologies or another, but being such a new situation your mileage will
likely vary, even presuming you have the funds and the available time to dedicate
the weeks and months required to cram all that information into your brain.&lt;/p&gt;

&lt;p&gt;If that’s not an option (which it isn’t for many of us), learning languages simply
must become your new hobby. I define a hobby as anything you do that steals time
from the tasks you are required to do in your daily life, like hold down a job,
raise children, cook, clean, etc. I chose that word specifically, as well. You
can’t &lt;strong&gt;find&lt;/strong&gt; time, you can only &lt;strong&gt;steal&lt;/strong&gt; time, and the more things you are
willing to let slip (TV, exercise, socializing, Twitter), the more learning you can do.&lt;/p&gt;

&lt;p&gt;So presuming you’re on your own, what resources are available? It’s tempting to buy
a 700-page “Java In 30 Days”-type book and slog through it, but I’ve never managed to
complete one of those monsters and you’re really only getting one person’s thoughts
on the subject. Instead, I diversify my sources and leverage all of the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Following/interacting with knowledgeable people on Twitter&lt;/li&gt;
  &lt;li&gt;Local user groups in your area or language (my local Ruby group didn’t have a training program, so I started one!)&lt;/li&gt;
  &lt;li&gt;Locate relevant podcasts like &lt;a href=&quot;http://rubyrogues.com&quot;&gt;The Ruby Rogues&lt;/a&gt; and &lt;a href=&quot;http://javascriptjabber.com&quot;&gt;JavaScript Jabber&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;YouTube (search on the language/tech you’re looking for: many conference videos here)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://confreaks.com&quot;&gt;Confreaks&lt;/a&gt; (a &lt;strong&gt;goldmine&lt;/strong&gt; of videos from conferences you couldn’t
afford to go to)&lt;/li&gt;
  &lt;li&gt;Tech blogs&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com&quot;&gt;Stack Overflow&lt;/a&gt; (&lt;strong&gt;the&lt;/strong&gt; clearinghouse for questions and answers about everything tech)&lt;/li&gt;
  &lt;li&gt;Ebooks from &lt;a href=&quot;http://pragprog.com&quot;&gt;PragProg&lt;/a&gt; and &lt;a href=&quot;http://oreilly.com/&quot;&gt;O’Reilly&lt;/a&gt;
  (cheaper and easier to get hold of than “dead-trees” books. PROTIP: these are often
  cheaper on Amazon than directly from the publisher’s website, though the publisher
  typically gives you free updates when they fix errata)&lt;/li&gt;
  &lt;li&gt;Mailing lists (&lt;a href=&quot;https://cooperpress.com/&quot;&gt;Peter Cooper&lt;/a&gt; is a great source of these)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The community that comes with the language you choose will impact your quality of
life on a daily basis, so give it serious consideration and do your best to be the
sort of member that benefits everyone and moves the entire tech community forward.&lt;/p&gt;

&lt;h2 id=&quot;ok-ive-made-my-choice-now-what&quot;&gt;OK, I’ve Made My Choice: Now What?&lt;/h2&gt;

&lt;p&gt;No matter what you’ve decided on, it’s important to realize that this is not &lt;strong&gt;your&lt;/strong&gt;
language, it’s your &lt;strong&gt;first&lt;/strong&gt; language. Times change: I’ve written production code in
Cobol, Informix, Perl, Java, C++ Ruby and JavaScript in my career and I’m constantly
learning new languages, frameworks and paradigms. Partly because I enjoy it, partly because it forces me to
think in new ways, but mainly because &lt;strong&gt;the world doesn’t stand still&lt;/strong&gt;. What seems
the “obvious” choice today may seem quaint in five years. Also, the more tools in
your toolbox, the more options you have, both for solving problems and for moving
on to better things when your current situation becomes unbearable.&lt;/p&gt;

&lt;p&gt;Being a lifelong learner is the only way to have a sustained career in tech: if you
can learn to love learning, you can do this job. Two tremendous resources in the
“learning to learn” genre are &lt;a href=&quot;https://pragprog.com/book/tpp/the-pragmatic-programmer&quot;&gt;The Pragmatic Programmer&lt;/a&gt;
and &lt;a href=&quot;https://pragprog.com/book/ahptl/pragmatic-thinking-and-learning&quot;&gt;Pragmatic Thinking and Learning&lt;/a&gt;,
both from the &lt;a href=&quot;http://pragprog.com&quot;&gt;Pragmatic Programmers&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Pick a language that helps you learn it, not one that actively hinders you&lt;/li&gt;
  &lt;li&gt;Match your language choice with the arena you want to enter&lt;/li&gt;
  &lt;li&gt;Leverage many different types of resources: don’t just buy one book.&lt;/li&gt;
  &lt;li&gt;Whatever you choose, it’s only your &lt;strong&gt;first&lt;/strong&gt; language. &lt;strong&gt;Keep learning.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;I believe in you&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Wed, 10 Sep 2014 00:00:00 -0400</pubDate>
				<link>http://billgathen.com/2014/09/10/what_programming_language.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/09/10/what_programming_language.html</guid>
			</item>
		
			<item>
				<title>My Two Keys to Getting Hired</title>
				<description>&lt;h1 id=&quot;my-two-keys-to-getting-hired&quot;&gt;My Two Keys to Getting Hired&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;September 2014 - Grand Rapids&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Read on if: you’re looking to hire or get hired&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, a confession… I’m not in charge of hiring for my company and I’m not looking for a job.
However, when my boss asks me what I’m looking for in a new member of our team, my
only two criteria are &lt;strong&gt;enthusiasm&lt;/strong&gt; and &lt;strong&gt;attention to detail&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;why-tech-skills-arent-enough&quot;&gt;Why tech skills aren’t enough&lt;/h2&gt;

&lt;p&gt;There may be some coders taking issue with me on this already. “Don’t you want a &lt;strong&gt;rock star&lt;/strong&gt;?
Or a &lt;strong&gt;ninja&lt;/strong&gt;? My coding skills are so awesome they make up for any shortcomings in my
personality.”&lt;/p&gt;

&lt;p&gt;No, no I don’t. Rock stars and ninjas aren’t terribly good at playing well with others
and even if their coding skils are exceptional, if the rest of the team (or their boss,
or their user base) wants to choke them unconscious on a daily basis, it’s not a net win
for the organization.&lt;/p&gt;

&lt;p&gt;Don’t try and paint over a sullen and hostile attitude with technical prowess. There are
too many social, considerate experts in your field who will gladly take your seat
and benefits package, and the web makes them entirely too easy to find. The days of the
“irreplaceable loose cannon” are over, if they were ever real to begin with.&lt;/p&gt;

&lt;h2 id=&quot;enthusiasm-a-how-to&quot;&gt;Enthusiasm: A How To&lt;/h2&gt;

&lt;p&gt;When I say enthusiasm, I don’t mean the motivational-speaker style “rah rah rah” or
cheerleader “let’s go team!” I mean a willingness to get excited about whatever task
you’re allowed to do, whether it’s writing another mind-numbing report app, reading
documentation or finding a bug.&lt;/p&gt;

&lt;p&gt;On the subject of reading documentation, this is one of enthusiasm’s hidden benefits.
Most people that are forced to learn something will do the absolute minimum they think
they can get away with and then forge ahead, leaving a string of time-wasting blind alleys and bugs
in their wake. A typical manifestation is someone who watches an intro screencast on YouTube
for some hot new tech and then tries to rebuild the entire business around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be the exception.&lt;/strong&gt; Read the docs (horrible as they might be). Read the code, if it’s
open source. Not every line of every file, but take a tour and see what is available beyond
the demo. Build toy apps before you touch production code. If you want to sound all
hacker-ish, call them “spikes” instead of “toy apps”. ;-)&lt;/p&gt;

&lt;p&gt;Be quick and be efficient: this is a constant juggling act. But be as prepared
as the situation allows.&lt;/p&gt;

&lt;h2 id=&quot;attention-to-detial&quot;&gt;Attention to Detial&lt;/h2&gt;

&lt;p&gt;If the typo in that heading makes you &lt;strong&gt;crazy&lt;/strong&gt;, then you’re the sort of person that will be
an asset to every team or app you work on. Again, most people settle for “close enough”.
Your boss gives vague instructions and expects you to be smart enough to fill in the gaps
and make any peripheral decisions they’re too busy (or underinformed) to make themselves.
People write emails full of typos and rambling digressions because they know you’ll re-read
it 5 times to get the actual meaning out of it.&lt;/p&gt;

&lt;p&gt;Computers are not like that. Computers require perfection or they will misbehave (perfectly).&lt;/p&gt;

&lt;p&gt;This carries over into your communication skills as well. If someone asks a question, give
an accurate answer, so they will have all the information they need to make an accurate
decision. If the boss says “how often does it crash?”, a normal person might say “not too
often” but a coder will say “I ran it twenty times and it failed twice with a ‘connection
refused’ error.” &lt;strong&gt;Be the exception.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;enthusiasm--details--remarkable&quot;&gt;Enthusiasm + Details = Remarkable&lt;/h2&gt;

&lt;p&gt;I’ve already said it twice, but I’ll emphasize it this time. The fundamental element of being
exceptional (and therefore valuable) is &lt;strong&gt;being the exception&lt;/strong&gt;. Do everything in your
power to go the extra mile, cover all of your bases, see what the people around you don’t
see because they’re too rushed or tired or burned-out. What important things (good and bad)
aren’t being talked about and might help us make a better decision?&lt;/p&gt;

&lt;p&gt;This starts with your portfolio, your online presence, your open-source projects, how you
dress, speak, email or tweet. Don’t wear a tuxedo or an evening gown to your interview,
but give your future employer (or business partner) the best impression of the real you.&lt;/p&gt;

&lt;p&gt;Seth Godin’s advice on creating a successful product (in this case, you) is
&lt;a href=&quot;http://sethgodin.typepad.com/seths_blog/2007/01/how_to_be_remar.html&quot;&gt;be remarkable&lt;/a&gt;.
Don’t do the things everyone else does (if your portfolio app is a to-do list, try again).
Being remarkable means doing something other people will discuss even when you’re not
around because it’s fun or inspiring or just plain impressive.&lt;/p&gt;

&lt;p&gt;On your own time, you’re the boss, so tackle the problems no one else seems to be tackling
and you will never get lost in the shuffle.&lt;/p&gt;

&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Enthusiasm means a curiosity and willingness to explore and take on challenges: be willing
to tackle anything they’ll let you.&lt;/li&gt;
  &lt;li&gt;Attention to detail extends to every aspect of your job/life: if you “don’t sweat the
small stuff” maybe this isn’t the career for you.&lt;/li&gt;
  &lt;li&gt;To be exceptional, be the exception.&lt;/li&gt;
  &lt;li&gt;Be remarkable.&lt;/li&gt;
  &lt;li&gt;I believe in you.&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Mon, 08 Sep 2014 00:00:00 -0400</pubDate>
				<link>http://billgathen.com/2014/09/08/two_keys_to_getting_hired.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/09/08/two_keys_to_getting_hired.html</guid>
			</item>
		
			<item>
				<title>Intention-Revealing Methods Can Save Your App</title>
				<description>&lt;h1 id=&quot;intention-revealing-methods-can-save-your-app&quot;&gt;Intention-Revealing Methods Can Save Your App&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;May 2014 - Grand Rapids&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Read on if: your methods are huge, buggy, hard to read/fix/change or painful to test.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We&apos;ve all written code like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def process_data
  raw_data = load_data()
  clean_data = raw_data.map do |row|
    %w{ name address phone email }.each do |field|
      if (row[field].nil? || row[field] == &quot;&quot;)
        row[field] = &quot;Unknown&quot;
      end
    end
    row
  end
  persist(clean_data)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&apos;ve got some data, we know we need to clean it up before we
can safely persist it, so we just clean it at the point
we need it cleaned. It&apos;s the simplest thing to do.&lt;/p&gt;

&lt;p&gt;The problem is that in order to realize that we&apos;re
cleaning (the variable name does give a hint), or to
understand what &quot;cleaning&quot; means (when we want to change it
or fix a bug) we have to analyze the code to discover
that &quot;this is the bit that guarantees all required fields
have a reasonable value in them.&quot;&lt;/p&gt;

&lt;p&gt;Also, cleaning in-place obscures the overall behavior of
&lt;code&gt;process_data&lt;/code&gt;, which is: load, clean, persist.&lt;/p&gt;

&lt;p&gt;What if we did this instead?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def process_data
  raw_data = load_data()
  clean_data = raw_data.map { |row| fill_in_required_fields(row) }
  persist(clean_data)
end

def fill_in_required_fields row
  %w{ name address phone email }.each do |field|
    if (row[field].nil? || row[field] == &quot;&quot;)
      row[field] = &quot;Unknown&quot;
    end
  end
  row
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wrapping the ugly bit in a method whose name explains
its purpose makes the code self-documenting and cleans-up
the calling method. We call this pattern &quot;Intention-Revealing
Method&quot;.&lt;/p&gt;

&lt;p&gt;Let&apos;s not kid ourselves: all the complexity of filling-in
fields is still there, but it&apos;s been moved to a method
that &lt;strong&gt;only&lt;/strong&gt; fills-in fields for a single row, which is easier
to think about because we can ignore everything else
that &lt;code&gt;process_data&lt;/code&gt; is doing.&lt;/p&gt;

&lt;p&gt;It gets even better when there are multiple steps to get
a &quot;clean&quot; row.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def process_data
  raw_data = load_data()
  clean_data = raw_data.
    select{ |row| not_in_system(row) }.
    select{ |row| is_active(row) }.
    map{ |row| fill_in_required_fields(row) }.
    map{ |row| only_relevant_fields(row) }
  persist(clean_data)
end

# ...all support methods
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Imagine how large and difficult-to-read the last
example would be if all the logic was implemented at the
point of use! Now we can see the &quot;big picture&quot; view of
the &lt;code&gt;process_data&lt;/code&gt; behavior and if we&apos;re
interested in any of the specific aspects, we can jump
to the method that implements it.&lt;/p&gt;

&lt;p&gt;We&apos;ve also created new testing opportunities:
we can pass a sample row object into any of those methods
and ask &quot;does this particular bit work?&quot; without worrying
about any of the other bits messing up our results.&lt;/p&gt;

&lt;p&gt;Let&apos;s take the final step.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def process_data
  raw_data = load_data()
  clean_data = DataCleaner.clean(raw_data)
  persist(clean_data)
end

module DataCleaner
  def self.clean data
    data.
      select{ |row| not_in_system(row) }.
      select{ |row| is_active(row) }.
      map{ |row| fill_in_required_fields(row) }.
      map{ |row| only_relevant_fields(row) }
  end

  # ...all the supporting methods
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now &lt;code&gt;process_data&lt;/code&gt; is distilled down to its
essence (load, clean, persist) and the details of what it
means to clean data is neatly gathered in a dedicated module
called &lt;code&gt;DataCleaner&lt;/code&gt; which can be extended and tested
independently of &lt;code&gt;process_data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DataCleaner&lt;/code&gt; knows nothing about getting or persisting
data and the only thing &lt;code&gt;process_data&lt;/code&gt; knows about &quot;cleaning&quot;
is that &lt;code&gt;DataCleaner.clean&lt;/code&gt; knows how to do
it. &lt;code&gt;DataCleaner&lt;/code&gt; can be tested with any data we
can fake up and doesn&apos;t require it to be loaded or persisted,
greatly-simplifying our setup and results-checking.&lt;/p&gt;

&lt;h2 id=&quot;choosing-good-names&quot;&gt;Choosing good names&lt;/h2&gt;

&lt;p&gt;Of course, it&apos;s still possible to ruin all our good work by choosing
names that are brittle, misleading or not helpful.&lt;/p&gt;

&lt;p&gt;Good names describe &lt;strong&gt;what&lt;/strong&gt; we need done, not &lt;strong&gt;how&lt;/strong&gt; to do it.
Keeping this in mind leads us to names that are
&quot;future-proofed&quot;: they won&apos;t have to
change if the underlying code changes.&lt;/p&gt;

&lt;p&gt;Good name: &lt;code&gt;not_in_system&lt;/code&gt;&lt;br /&gt;
Bad name: &lt;code&gt;cant_find_id_in_mysql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The bad name breaks if we change how we determine a row is
missing, or if we switch from mysql to postgres or redis.&lt;/p&gt;

&lt;p&gt;Good name: &lt;code&gt;fill_in_required_fields&lt;/code&gt;&lt;br /&gt;
Bad name: &lt;code&gt;fill_in_name_and_address&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The bad name breaks if we add/remove required fields.&lt;/p&gt;

&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;When you realize you need a bit of behavior at a certain spot,
write something to do it for you (a method or even a
class/module)
with a name explaining the behavior, then call that thing
from the spot you need it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When choosing a name, explain the behavior in terms of
&quot;what&quot; and not &quot;how&quot; in order to future-proof your code.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Sun, 25 May 2014 00:00:00 -0400</pubDate>
				<link>http://billgathen.com/2014/05/25/intention_revealing_methods.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/05/25/intention_revealing_methods.html</guid>
			</item>
		
			<item>
				<title>Learning Is A Circuit - A Year of Teaching</title>
				<description>&lt;h1 id=&quot;learning-is-a-circuit---a-year-of-teaching&quot;&gt;Learning Is A Circuit - A Year of Teaching&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;Feb 2014 - Grand Rapids&lt;/p&gt;

&lt;p&gt;In December 2012, &lt;a href=&quot;http://twitter.com/coderbydesign&quot;&gt;Keith Walsh&lt;/a&gt; and I started the training arm of our &lt;a href=&quot;http://meetup.com/mi-ruby&quot;&gt;local Ruby User Group&lt;/a&gt;, dubbed “Get Your Hands Dirty With Ruby”. The third Monday of every month, an ever-shifting group of rubyists and aspiring rubyists shows up to hack on variations of the &lt;a href=&quot;/2013/01/18/7_degrees_of_fizzbuzz.html&quot;&gt;7 Degrees of FizzBuzz&lt;/a&gt; challenge that is plastered all over this site. I’d like to reflect a bit on my first year in the teaching game.&lt;/p&gt;

&lt;h2 id=&quot;i-dont-have-heroes-i-have-role-models&quot;&gt;I Don’t Have Heroes, I Have Role Models&lt;/h2&gt;

&lt;p&gt;I got fired up (Keith and I use the surfer term “feeling the stoke”) after extended conversations with and/or presentations from &lt;a href=&quot;http://twitter.com/j3&quot;&gt;Jeff Casimir&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/noelrap&quot;&gt;Noel Rappin&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/kerrizor&quot;&gt;Kerri Miller&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/r00k&quot;&gt;Ben Orenstein&lt;/a&gt; at &lt;a href=&quot;http://www.confreaks.com/events/rubyconf2012&quot;&gt;RubyConf 2012&lt;/a&gt;. Their passion and talent for teaching made me want to “give back” to my local community the way they did on a national level.&lt;/p&gt;

&lt;p&gt;When I got back to my hotel room on the first night, I started this blog and decided to start going to my local RUG. At the first meeting I went to, 8 of the 12 attendees had never written a line of Ruby. I asked my boss for use of our office space in the evenings, he offered to spring for the pizza, and we were off to the races.&lt;/p&gt;

&lt;h2 id=&quot;the-teachers-are-also-students&quot;&gt;The Teachers Are Also Students&lt;/h2&gt;

&lt;p&gt;Prior to our first meeting, I put a page up on with a few programming &lt;a href=&quot;/ruby_challenges.html&quot;&gt;challenges&lt;/a&gt;, with the idea that they could pair up and help each other through them. We let people make their own choices and then just wandered among them “facilitating” when challenge gave way to frustration.&lt;/p&gt;

&lt;p&gt;We had some limited success, but it was clear that the challenges needed to be a bit more nuts-and-bolts, and that there was a large group that would need extensive hand-holding for their first time through. I created the &lt;a href=&quot;/2013/01/18/7_degrees_of_fizzbuzz.html&quot;&gt;7 Degrees&lt;/a&gt; curriculum with the idea that by the time a student had worked through all those challenges, they would be familiar enough with the Ruby ecosystem to explore on their own.&lt;/p&gt;

&lt;h2 id=&quot;graduation-challenges&quot;&gt;“Graduation” challenges&lt;/h2&gt;

&lt;p&gt;After four or five months, when our entire group of very bright, enthusiastic people were still slogging through the first four steps of FizzBuzz, we hit on the idea of a “graduation from fizzbuzz” challenge. If you could do the first four steps “live” with an instructor verifying each step, you “graduated” and never had to do the challenge again.&lt;/p&gt;

&lt;p&gt;The effect was &lt;strong&gt;galvanizing&lt;/strong&gt;: the following month we had four people meet the challenge and now over a dozen have “moved on”. We added a similar challenge for the “RSpec track” and are now putting together a curriculum for Git.&lt;/p&gt;

&lt;h2 id=&quot;pairing-ftw&quot;&gt;Pairing FTW&lt;/h2&gt;

&lt;p&gt;Our biggest success has been a strong (some would say obnoxious) emphasis on pair programming. Alan Kay’s quote about “a different perspective is worth 80 IQ points” is certainly true in our case, but the positive effect on the community feeling in the group has been the most important side-effect, especially since programmers tend to be on the introverted side. Several of our students have grouped together on the side to hack on their own projects, pinging the instructors when they get stuck. It’s working!&lt;/p&gt;

&lt;p&gt;It’s too easy as a coder to put your head down and &lt;strong&gt;hack&lt;/strong&gt;, ignoring everything around you. With a pair, you get much-needed practice interacting with another like-minded human being who may be at a radically-different level of skill and/or experience. We’re as much about community-building and “soft skills” as we are about teaching the proper use of “.map”.&lt;/p&gt;

&lt;h2 id=&quot;i-heart-n00bs&quot;&gt;I Heart N00bs&lt;/h2&gt;

&lt;p&gt;Since we have had first-timers every month since we started, I’ve become the “newbie” track leader and Keith takes the intermediate track (which focuses on testing with RSpec). The more advanced students nudge us for help when they get stuck.&lt;/p&gt;

&lt;p&gt;As it turns out, I love newbies. I love the challenge of translating computer concepts into real-world examples and watching their eyes light up when they get something for the first time.&lt;/p&gt;

&lt;p&gt;For me, coding is about empowerment. We write apps that allow our users to do things they couldn’t do otherwise. I like to say “I give people superpowers”. When I teach, I’m giving the students that ability as well. “Go forth and do good!”&lt;/p&gt;

&lt;h2 id=&quot;learning-is-a-circuit&quot;&gt;Learning Is A Circuit&lt;/h2&gt;

&lt;p&gt;The mantra I probably get the most mileage out of is “we don’t learn with our eyes and our ears, we learn with our fingers”. That’s why every time we complete a bit of functionality on the newbie track, we pass the keyboard to our pair. Lots of newbies feel like they need to know what they’re doing before they touch the keyboard (I hear “No, that’s OK, I’ll just watch” &lt;strong&gt;a lot&lt;/strong&gt;), but that’s completely backwards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning is a circuit&lt;/strong&gt;: you take in the information, process it through your brain and then “ground it” by sending it back out through the keyboard into the world. It’s only when that circuit completes that we’ve learned something.&lt;/p&gt;

&lt;h2 id=&quot;once-a-month-aint-enough&quot;&gt;Once A Month Ain’t Enough&lt;/h2&gt;

&lt;p&gt;We only have our students 2 hours per month, as well as some interaction through our GitHub Organization. That’s not enough to teach much. In order to achieve what our students have (and some raw newbies from a year ago are full-time Ruby programmers now), they need to put in lots of time between classes with their hands on the keyboard and their head in the game.&lt;/p&gt;

&lt;p&gt;Coders are auto-didacts: even people with full-on CS degrees readily admit they learned far more after finishing school than they did during, and many of us had little to no formal CS education at all and still accomplish some pretty cool stuff that makes a difference in our little corner of the world.&lt;/p&gt;

&lt;p&gt;But with that mindset, the desire to challenge yourself, and the wealth of &lt;a href=&quot;http://billgathen.com/ruby_resources.html&quot;&gt;readily-available information from the tremendously-generous Ruby community&lt;/a&gt;, &lt;strong&gt;anyone&lt;/strong&gt; can code.&lt;/p&gt;

&lt;p&gt;But don’t take my word for it: try it for yourself.&lt;/p&gt;
</description>
				<pubDate>Wed, 05 Feb 2014 00:00:00 -0500</pubDate>
				<link>http://billgathen.com/2014/02/05/learning_is_a_circuit.html</link>
				<guid isPermaLink="true">http://billgathen.com/2014/02/05/learning_is_a_circuit.html</guid>
			</item>
		
			<item>
				<title>Teaching, Targeting and Nudging at GiveCamp</title>
				<description>&lt;h1 id=&quot;teaching-targeting-and-nudging-at-givecamp&quot;&gt;Teaching, Targeting and Nudging at GiveCamp&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;Nov 2013 - Grand Rapids&lt;/p&gt;

&lt;p&gt;I’m a coder. I cut code all day, every day. I learn new languages and programming paradigms for fun at night and on weekends. My favorite days are spent hacking in silence, with only a Skype window connecting me to other techies doing the same thing I’m doing: solving problems and making people’s lives more awesome with code.&lt;/p&gt;

&lt;p&gt;I spent the weekend of November 8-10, 2013 contributing to the 2013 &lt;a href=&quot;http://grgivecamp.org/&quot;&gt;Grand Rapids GiveCamp&lt;/a&gt; and in two full days didn’t write a single line of code.&lt;/p&gt;

&lt;p&gt;GiveCamp pairs local charity organizations who need technical assistance (building/revamping web sites, building donor databases, offering online organizational tools) with local techies who can solve those problems. Our team, made up of &lt;a href=&quot;http://twitter.com/shekibobo&quot;&gt;Joshua Kovach&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/HarrisonMiracle&quot;&gt;Harrison Miracle&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/indstry&quot;&gt;Mike Elston&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/thomasjbush&quot;&gt;Thomas Joseph Bush&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/bramanga&quot;&gt;Greg Braman&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/matthewpische&quot;&gt;Matthew Pische&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/coderbydesign&quot;&gt;Keith Walsh&lt;/a&gt; and myself, did a ground-up rebuild of the website and donation engine for &lt;a href=&quot;http://haitineedsyou.com&quot;&gt;Haiti Needs You&lt;/a&gt; for Tim Ryan, who does multiple medical/dental relief missions to Haiti every year to help improve and extend the lives of Haiti’s “poorest of the poor”.&lt;/p&gt;

&lt;p&gt;So what &lt;strong&gt;did&lt;/strong&gt; I do in those two days? I fell into the role of project manager. I’d like to talk a bit about how/why that happened and what a dyed-in-the-wool coder learned from the experience.&lt;/p&gt;

&lt;h2 id=&quot;project-manager-wat&quot;&gt;Project manager? Wat?&lt;/h2&gt;

&lt;p&gt;How did this happen? Anybody who’s worked with me knows I don’t delegate: why would I voluntarily end up in a role where I can’t actually &lt;em&gt;control&lt;/em&gt; anything?&lt;/p&gt;

&lt;p&gt;It came down to three things: I have a big mouth, I’m very good at asking revealing questions, and I was not the best in the room.&lt;/p&gt;

&lt;h3 id=&quot;no-authority-except-what-you-take&quot;&gt;No authority except what you take&lt;/h3&gt;

&lt;p&gt;This was an open-source project, at least in development style: flat hierarchy and a wild mix of skills and levels of expertise made up mostly of strangers. When Tim, the stakeholder, walked in the room, I started talking with him to make him feel more comfortable and find out what he actually needed from us, and I never really stopped. I had no &lt;em&gt;right&lt;/em&gt; to dominate the conversation, but nobody else stepped up so I never stepped down. It’s more or less how I ended up coaching my son’s soccer team for three years. :-)&lt;/p&gt;

&lt;h3 id=&quot;nobody-needs-a-website&quot;&gt;Nobody “needs” a website&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://twitter.com/seriouspony&quot;&gt;Kathy Sierra&lt;/a&gt; is at the forefront of what she calls “post-UX” thought. Don’t think about how to make your app/site awesome, think of how your app/site can make your &lt;strong&gt;user&lt;/strong&gt; awesome. I think of it as “nobody needs a website”: what they &lt;strong&gt;need&lt;/strong&gt; is assistance improving their life in the real world. A website can be a tool to do that, but if it’s not, don’t bother building it.&lt;/p&gt;

&lt;p&gt;That’s where I focused my questions. What does your organization do? What resources are required? What would help you level up? We burned it down to three things: collect donations, sign up volunteers and distribute information about the missions themselves (mainly via a mailing list). In that order. If these three things were as easy as we could make them, we had a shot at making a real impact on Tim’s efforts.&lt;/p&gt;

&lt;p&gt;Find the important questions in order to get the important answers, and then focus single-mindedly on those answers. This was a challenge throughout the weekend, so we’ll revisit it later.&lt;/p&gt;

&lt;h3 id=&quot;i-was-not-the-best-in-the-room&quot;&gt;I was not the best in the room&lt;/h3&gt;

&lt;p&gt;I’m a back-back-end coder. Usually when people divide themselves into front-end/back-end, “front-end” things happen in the browser and “back-end” things happen on the server. What I specialize in is pure business logic. I build interfaces to external resources with disastrous APIs. I write heinous calculation logic and fiendish workflows. That’s where I live. Then I wrap a Rails app around it and put some front-end goodies on top. But I’m only truly powerful 100 feet underground where I’m digging with my fingernails and everything is pitch-black.&lt;/p&gt;

&lt;p&gt;I don’t have all the Rails components and generators memorized. I have only a basic grasp of design principles. I test enthusiastically but know I could do so much better.&lt;/p&gt;

&lt;p&gt;And I was surrounded by rock stars. People who used the gems, services and design tools we would need for this project daily in their paid work. There was none of the deep, dark, convoluted, one-off craziness where I can shine. If I’d tried to actively drive any of the features we needed, it would only slow everything down.&lt;/p&gt;

&lt;p&gt;So I took a step back. In order for the experts to go heads-down and do their voodoo, I needed to stay heads-up and hands-off. That was hard, and humbling, but the project was undeniably better for it.&lt;/p&gt;

&lt;h2 id=&quot;teach-target-and-nudge&quot;&gt;Teach, Target and Nudge&lt;/h2&gt;

&lt;p&gt;So what did I do for two solid days? The short answer is “anything to keep the features coming”. I can talk and I can improvise. I asked a lot of questions, begged favors from people I’d never met, and a bunch of other random things I have little to no experience at. The measure of whether I did these things well was if the rest of the team kept making progress.&lt;/p&gt;

&lt;p&gt;The long answer breaks down into three things: teaching, targeting and nudging.&lt;/p&gt;

&lt;h3 id=&quot;teaching&quot;&gt;Teaching&lt;/h3&gt;

&lt;p&gt;Teaching is one of my great joys. I’ve said I was not the best at any particular thing among the group, but as Alan Kay famously said &lt;a href=&quot;https://en.wikiquote.org/wiki/Alan_Kay&quot;&gt;“A change in perspective is worth 80 IQ points”&lt;/a&gt;. Just having someone looking over your shoulder is like having a syntactically-aware spell-checker.&lt;/p&gt;

&lt;p&gt;Our backgrounds differed radically, so our strengths often overlapped with each other’s weaknesses in specific areas that would help us get “unstuck”, supporting Eric Raymond’s theory that “given enough eyeballs, all bugs are shallow”. Several of the developers were new to &lt;a href=&quot;http://try.github.io&quot;&gt;git&lt;/a&gt;, for instance (my favorite source code control system but notoriously difficult for newbies) which gave me the chance to explain things like how to create a tracking branch. It might have only happened a dozen times over the weekend, but every little bit helps.&lt;/p&gt;

&lt;p&gt;It’s important to remember that getting stuck is emotionally difficult, especially in time-pressured, public situations where you’re supposed to “know what you’re doing”. Asking for help is an admission that you’re not perfect, and the social pressure to be flawless is everywhere in modern society. It shouldn’t be: none of us knows everything about anything. But we’ve all been there. To their credit, all the coders took each other’s input in stride, and developed more respect for each other as a result.&lt;/p&gt;

&lt;p&gt;We had one member who was new to programming in general and not sure how much value he could add to the mix, but since there were a number of APIs to interface with in ways none of us had dealt with before, he spent a large chunk of time doing research that increased velocity once the coding effort for the component began. A side benefit is that he learned a great deal about APIs in general and looked at a lot of Ruby code. A win for both sides.&lt;/p&gt;

&lt;h3 id=&quot;targeting&quot;&gt;Targeting&lt;/h3&gt;

&lt;p&gt;I mentioned at the outset working with Tim to establish how his ideal website would help his organization: donating money or service and keeping people informed about their efforts. We started our initial effort divided into groups along those lines in order to reduce code conflicts, but almost immediately we started saying “You know what we really need? X.”&lt;/p&gt;

&lt;p&gt;My response was usually along the lines of “That would be nice, but if we had to go live without it, would the site still support the core features?” and the answer was almost always of the form “Well, if at some point he wanted to do Y, he’d need it.” The technical term for this is &lt;a href=&quot;https://en.wikipedia.org/wiki/You_ain&apos;t_gonna_need_it&quot;&gt;YAGNI: You Ain’t Gonna Need It&lt;/a&gt; and I think all of us succumbed to at some point over the weekend.&lt;/p&gt;

&lt;p&gt;I followed up with “Why don’t we put that in the second wave and we’ll tackle it as soon as we get the main features launched?” and everyone was agreeable. Of course, we never got to the list, which I think everyone realized from the start, but it’s easier to swallow than just shouting “YAGNI!” The suggestions were all valid and should have been captured in the source code somewhere so they could be addressed in the future, but I think we dropped the ball on that.&lt;/p&gt;

&lt;p&gt;To keep my courage up I mentally repeated the mantra from the trench scene in Star Wars: “Stay on target… Stay on target!” Of course, that pilot got blown to smithereens, so it’s probably good I didn’t think the analogy all the way through. ;-)&lt;/p&gt;

&lt;h3 id=&quot;nudging&quot;&gt;Nudging&lt;/h3&gt;

&lt;p&gt;This is one area I always struggle with and I fell down multiple times over the weekend. I wasn’t anybody’s “boss” and where there were conflicting opinions (some of them on fairly-abstract coding architectures) I let the “Nope. That’s wrong” slip out before I converted into the more-respectful “I think we might get some other benefits from trying it this way.” One of my personal blind-spots is letting my passion for the technical subject blind me to the fact that these are human beings I’m dealing with and they deserve respect and consideration. The old adage “pick your battles” often translates perfectly as “don’t be such a control freak”. There’s also a world of difference between a nudge and a push.&lt;/p&gt;

&lt;p&gt;I did better during the multiple occasions where someone would throw up their hands and say “Looks like you can’t do that” with respect to some external resource we couldn’t control. By not just accepting that at face value but engaging the whole group in coming up with creative paths around the obstruction, we managed to beat almost every one.&lt;/p&gt;

&lt;p&gt;Another area I constantly worked on was getting people into compatible pairs, even when they felt confident of handling the problem on their own. We’ve found such benefit in pairing during our monthly Ruby training that I knew even if the technical benefit wasn’t obvious, the effect on the team dynamic would be worth it. Plus it meant no one felt underutilized or began work on a “second wave” feature “because I don’t have anything else to work on at the moment”.&lt;/p&gt;

&lt;h2 id=&quot;about-fear&quot;&gt;About Fear&lt;/h2&gt;

&lt;p&gt;I can’t in fairness end this without talking about fear. I worried constantly all weekend. I worried even the three features we’d committed to were more than we’d get to in the alloted time. I worried that the decisions I lobbied for would cause more trouble than they were worth. I worried that all the “contributions” I thought I was making were secretly alienating the entire team and they were all whispering “when is Loud Mouth going to go home so we can get some work done?”&lt;/p&gt;

&lt;p&gt;In the end, we did hit the deadline and everyone was still speaking to me (we even drummed up more interest in our Ruby training), so I sincerely hope none of those fears had a basis in reality. If they did and I was too thick to notice, I apologize. In either case, I spent a lot of time and wasted a lot of energy wondering. &lt;a href=&quot;https://en.wikipedia.org/wiki/Imposter_syndrome&quot;&gt;Imposter Syndrome&lt;/a&gt; appears to be widespread in our industry and probably many others, so if you experience this too, you’re not alone.&lt;/p&gt;

&lt;p&gt;To be honest, after the first night I was so nervous I had already caused irreversible damage that I contemplated not even returning. I came back anyway because I had committed to helping a worthy cause and I owed it to Tim to be of any benefit I could, even if that was just undoing the damage I’d done the first night.&lt;/p&gt;

&lt;p&gt;It didn’t turn out that way: the second day we really got our feet under us and everyone showed a passion and work ethic that was infectious. By the third day, they were locked in and turning out features at a mind-blowing pace. We demoed along with everyone else at the closing ceremonies and Tim seemed very pleased with what we’d created. The updated site went live less than 24 hours later.&lt;/p&gt;

&lt;p&gt;When Tim and I shook hands and said goodbye, I expressed my final fear.  I said, “I hope the website helps you. I hope it brings in more money and new resources and spreads the word about your organization so you can do more good in the world. Because if it doesn’t do that, then we’ve failed.”&lt;/p&gt;

&lt;p&gt;I sincerely hope that fear proves as groundless as the others. We did our best. And &lt;a href=&quot;http://haitineedsyou.com&quot;&gt;Haiti Needs You&lt;/a&gt;.&lt;/p&gt;
</description>
				<pubDate>Mon, 11 Nov 2013 00:00:00 -0500</pubDate>
				<link>http://billgathen.com/2013/11/11/lessons_from_givecamp.html</link>
				<guid isPermaLink="true">http://billgathen.com/2013/11/11/lessons_from_givecamp.html</guid>
			</item>
		
			<item>
				<title>The Three-Legged Stool -- Testing, Refactoring and Design</title>
				<description>&lt;h1 id=&quot;the-three-legged-stool--testing-refactoring-and-design&quot;&gt;The Three-Legged Stool – Testing, Refactoring and Design&lt;/h1&gt;

&lt;p class=&quot;meta&quot;&gt;Feb 2013 - Grand Rapids&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You’ve mentioned testing and refactoring, but there’s a third leg to the stool: that’s design.” - &lt;a href=&quot;http://www.continuousthinking.com/&quot;&gt;Zach Dennis&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Much has been said in the Ruby community about the importance of testing, the power of refactoring to improve design, and the importance of understanding software design itself, but as Michael Feathers pointed out in &lt;a href=&quot;http://vimeo.com/15007792&quot;&gt;The Deep Synergy Between Testability and Good Design&lt;/a&gt;, they are most powerful – indeed, only really understandable – when treated as a team. Or in Zach’s terms, the three legs of the stool.&lt;/p&gt;

&lt;p&gt;I enjoy teaching Ruby, and most of my students are relatively-new to the language. The center of our curriculum is &lt;a href=&quot;/2013/01/18/7_degrees_of_fizzbuzz.html&quot;&gt;7 Degrees of FizzBuzz&lt;/a&gt;: we squeeze every last drop of knowledge out of it in order to introduce ourselves to the language, to pair-programming, and to thinking like programmers.&lt;/p&gt;

&lt;p&gt;Let’s examine the testing section of that exercise through the lens of Zach’s “Three-Legged Stool”, but in the interest of the beginners among us we’re going to use only one example of each. For testing, the &lt;strong&gt;unit test&lt;/strong&gt;. For refactoring, &lt;strong&gt;extract method&lt;/strong&gt;. And for design, the principle of &lt;strong&gt;composition&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;first-make-a-mess&quot;&gt;First, Make a Mess&lt;/h2&gt;

&lt;p&gt;Here’s the version of FizzBuzz we’re going to use, hacked together in a white heat and without a thought for tomorrow:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz last_num
  (1..last_num).map do |n|
    if n % 3 &amp;amp;&amp;amp; n % 5
      &quot;FizzBuzz&quot;
    elsif n % 5
      &quot;Buzz&quot;
    elsif n % 3
      &quot;Fizz&quot;
    end
  end
end

puts fizzbuzz(30).join(&quot; &quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Beautiful, isn’t it? Clear, elegant – assuming you understand syntax details like ranges, mapping and how the join operator affects an array – and fairly concise. It’s even got a bit of the first leg of our stool: composition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Composition means assembling something out of component parts.&lt;/strong&gt; An engine is composed of gears, belts, pistons, etc: these pieces work together to convert gasoline and a bit of electricity into motive power. The basic level of composition in computer programs is the method, and we have one here: &lt;code&gt;fizzbuzz&lt;/code&gt;. It takes an argument of the upper bound of our range and returns a set of values for the caller to do things with.&lt;/p&gt;

&lt;p&gt;Breaking a problem into small components allows us to think about each one individually, which is generally easier than thinking of the whole construction at once. We’re fine as long as the pieces plug together: piece A generates something that piece B needs in the correct format. Which means we can create, test and debug each part by itself and put them together when we’re confident they work in isolation.&lt;/p&gt;

&lt;p&gt;Now that we’ve written our neat little &lt;code&gt;fizzbuzz&lt;/code&gt; method we can add it to any application that needs fizzbuzzing. There’s only one problem: the code is wrong.&lt;/p&gt;

&lt;p&gt;Run it, and we get this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz FizzBuzz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which brings us to our second leg: testing.&lt;/p&gt;

&lt;h2 id=&quot;then-make-it-right&quot;&gt;Then Make It Right&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Testing means exercising program code in order to prove it functions as expected in all the important ways it might be used or abused.&lt;/strong&gt; To do this, we employ a test framework which offers a variety of ways to say “under these conditions, this method should behave this way”. The most basic sort of testing is unit testing, which typically exercises a single method.&lt;/p&gt;

&lt;p&gt;So how might we write a test for this method? Using &lt;a href=&quot;http://relishapp.com/rspec&quot;&gt;RSpec&lt;/a&gt; – the most popular Ruby test framework – we could do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe &apos;fizzbuzz&apos; do
  it &apos;works to 30&apos; do
    fizzbuzz(30).should == %w{ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Buzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz }
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if we run it, we’ve proven that the code is misbehaving…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rspec stool_spec.rb 
F

Failures:

  1) fizzbuzz works to 30
     Failure/Error: fizzbuzz(30).should == %w{ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Buzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz }
       expected: [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;Fizz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;Buzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;Fizz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;Fizz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;]
            got: [&quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;, &quot;FizzBuzz&quot;] (using ==)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, yeah, we’re testing. But… yuck.&lt;/p&gt;

&lt;p&gt;First off, it’s hideously-long, as is the error output: we’re forced to visually-match every single value in both arrays to find out what’s wrong. There’s also a bunch of repetition: we test whether the “Fizz” logic works 8 times!&lt;/p&gt;

&lt;p&gt;But it’s a test. When it succeeds, we’ll know the code’s right. And that’s perfectly valid. But we can do better. And we need to do better, because &lt;strong&gt;writing tests like that all day long is one of the reasons people give up testing: it’s exhausting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After a few minutes of looking, we realize we forgot the &lt;code&gt;== 0&lt;/code&gt; after each conditional. Notice that the test itself doesn’t help us at all in this search: it just sits there being broken. We fix our code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz last_num
  (1..last_num).map do |n|
    if n % 3 == 0 &amp;amp;&amp;amp; n % 5 == 0
      &quot;FizzBuzz&quot;
    elsif n % 5 == 0
      &quot;Buzz&quot;
    elsif n % 3 == 0
      &quot;Fizz&quot;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…and run it again.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rspec stool_spec.rb 
F

Failures:

  1) fizzbuzz works to 30
       Failure/Error: fizzbuzz(30).should == %w{ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Buzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz }
              expected: [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;Fizz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;Buzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;Fizz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;Fizz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;]
                   got: [nil, nil, &quot;Fizz&quot;, nil, &quot;Buzz&quot;, &quot;Fizz&quot;, nil, nil, &quot;Fizz&quot;, &quot;Buzz&quot;, nil, &quot;Fizz&quot;, nil, nil, &quot;FizzBuzz&quot;, nil, nil, &quot;Fizz&quot;, nil, &quot;Buzz&quot;, &quot;Fizz&quot;, nil, nil, &quot;Fizz&quot;, &quot;Buzz&quot;, nil, &quot;Fizz&quot;, nil, nil, &quot;FizzBuzz&quot;] (using ==)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hmm… Clearly we fixed something, but not everything. Even through the noise, we can see all those nils poking out. Oops, forgot our else case!&lt;/p&gt;

&lt;p&gt;We change the code again:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz last_num
  (1..last_num).map do |n|
    if n % 3 == 0 &amp;amp;&amp;amp; n % 5 == 0
      &quot;FizzBuzz&quot;
    elsif n % 5 == 0
      &quot;Buzz&quot;
    elsif n % 3 == 0
      &quot;Fizz&quot;
    else
      n.to_s
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…and run it again.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rspec stool_spec.rb 
F

Failures:

  1) fizzbuzz works to 30
     Failure/Error: fizzbuzz(30).should == %w{ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Buzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz }
       expected: [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;Fizz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;Buzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;Fizz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;Fizz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;]
            got: [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;Fizz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;FizzBuzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;Fizz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;Fizz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;] (using ==)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this brings us to &lt;strong&gt;the second reason people give up on testing: we have a bug in our test&lt;/strong&gt;. After monkey-walking through the outputs in parallel, we see that although 15 should appear as “FizzBuzz” I accidentally typed “Buzz” because it was divisible by 5. We fix that, and now our test passes.&lt;/p&gt;

&lt;p&gt;There is &lt;strong&gt;nothing&lt;/strong&gt; more infuriating than writing a piece of code in 5 minutes then spending 2 hours beating your head against a testing framework trying to prove you were right all along. This is why your tests should be as simple as possible, because you can’t wrap tests around your tests!&lt;/p&gt;

&lt;p&gt;Here’s the test I would &lt;strong&gt;like&lt;/strong&gt; to write to prove our fizzbuzz algorithm works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe &apos;fizzbuzz&apos; do
  it &apos;a single number&apos; do
    fizzbuzz_a_number(9).should == &quot;Fizz&quot;
    fizzbuzz_a_number(10).should == &quot;Buzz&quot;
    fizzbuzz_a_number(11).should == &quot;11&quot;
    fizzbuzz_a_number(30).should == &quot;FizzBuzz&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In fact, If I’d been doing Test-Driven Development I probably would have started here and saved myself a lot of hair-pulling. Live and learn…&lt;/p&gt;

&lt;p&gt;The “dream test” proves the algorithm works correctly in each of its four states, without all the repetition and noise. Since I picked multiples of our base numbers, I even covered the bug where we say &lt;code&gt;n == 3&lt;/code&gt; instead of &lt;code&gt;n % 3 == 0&lt;/code&gt; without having to write more test cases. It was a lot easier to write correctly the first time, and the output is more readable. Only one problem: we can’t run this code, because the &lt;code&gt;fizzbuzz_a_number&lt;/code&gt; method doesn’t exist.&lt;/p&gt;

&lt;p&gt;It doesn’t exist because the &lt;code&gt;fizzbuzz&lt;/code&gt; method actually doesn’t have &lt;strong&gt;enough&lt;/strong&gt; composition. It’s doing two distinct things: it’s iterating over an array, and the conditionals are doing the actual fizzbuzzing.&lt;/p&gt;

&lt;p&gt;So how do we improve the composition of our method and get to run our dream test? We refactor.&lt;/p&gt;

&lt;h2 id=&quot;then-make-it-easy&quot;&gt;Then Make It Easy&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Refactoring means improving the structure of code without changing its external behavior.&lt;/strong&gt; We typically refactor for one of two reasons: to improve the clarity of the code and make it easier to think about, or to make it easier to add a feature. If it’s hard to add a feature to your codebase, try refactoring your existing code into something that makes the feature easier to implement. Now that we have a test covering &lt;code&gt;fizzbuzz&lt;/code&gt; we can be confident our changes won’t break logic that was working when we started.&lt;/p&gt;

&lt;p&gt;The feature we want to implement is being able to use our awesome new test, so we’ll refactor to make it possible, using one of the most common refactorings: &lt;strong&gt;Extract Method&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Martin Fowler’s book &lt;a href=&quot;http://martinfowler.com/books/refactoring.html&quot;&gt;Refactoring&lt;/a&gt; – with examples in Java, though there’s now a &lt;a href=&quot;http://www.martinfowler.com/books/refactoringRubyEd.html&quot;&gt;Ruby version&lt;/a&gt; – introduced a disciplined, meticulous approach to changing code, so even this simple one has several steps.&lt;/p&gt;

&lt;p&gt;First we copy the relevant bit of code into a new method with an “intention-revealing” name. Good variable and method names go a long way toward making code self-commenting:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz_a_number
  if n % 3 == 0 &amp;amp;&amp;amp; n % 5 == 0
    &quot;FizzBuzz&quot;
  elsif n % 5 == 0
    &quot;Buzz&quot;
  elsif n % 3 == 0
    &quot;Fizz&quot;
  else
    n.to_s
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next we look for variables created outside our new method but used inside it. We have only one: &lt;code&gt;n&lt;/code&gt;. We can get it into the method by adding it as an argument:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz_a_number n
  if n % 3 == 0 &amp;amp;&amp;amp; n % 5 == 0
    &quot;FizzBuzz&quot;
  elsif n % 5 == 0
    &quot;Buzz&quot;
  elsif n % 3 == 0
    &quot;Fizz&quot;
  else
    n.to_s
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We then look for any variables modified or created inside this method but used outside it. In this case, the only one is the implicit return value and that takes care of itself.&lt;/p&gt;

&lt;p&gt;Now we can run our dream test and it passes right away:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rspec stool_spec.rb 
..

Finished in 0.00051 seconds
2 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Naturally the original test still passes because we haven’t touched &lt;code&gt;fizzbuzz&lt;/code&gt; yet. If we decided at this point to abandon the effort, we could delete our new method and everything would be as it was: no harm, no foul.&lt;/p&gt;

&lt;p&gt;But we like our new code, so we complete the refactoring by replacing the original instance of the code with a call to the new method, passing along the argument:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fizzbuzz_a_number n
  if n % 3 == 0 &amp;amp;&amp;amp; n % 5 == 0
    &quot;FizzBuzz&quot;
  elsif n % 5 == 0
    &quot;Buzz&quot;
  elsif n % 3 == 0
    &quot;Fizz&quot;
  else
    n.to_s
  end
end

def fizzbuzz last_num
  (1..last_num).map do |n|
    fizzbuzz_a_number(n)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The tests still run, and all is right with the world.&lt;/p&gt;

&lt;p&gt;So big deal: now we have &lt;strong&gt;two&lt;/strong&gt; tests that prove the same thing… Until we re-introduce one of our bugs by accidentally removing one of the &lt;code&gt;== 0&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if n % 3 == 0 &amp;amp;&amp;amp; n % 5
  &quot;FizzBuzz&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…and rerun our tests:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rspec stool_spec.rb 
FF

Failures:

  1) fizzbuzz a single number
     Failure/Error: fizzbuzz_a_number(9).should == &quot;Fizz&quot;
       expected: &quot;Fizz&quot;
            got: &quot;FizzBuzz&quot; (using ==)
     # ./stool_spec.rb:23:in `block (2 levels) in &amp;lt;top (required)&amp;gt;&apos;

  2) fizzbuzz works to 30
     Failure/Error: fizzbuzz(30).should == %w{ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz }
       expected: [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;Fizz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;FizzBuzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;Fizz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;Fizz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;]
            got: [&quot;1&quot;, &quot;2&quot;, &quot;FizzBuzz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;FizzBuzz&quot;, &quot;7&quot;, &quot;8&quot;, &quot;FizzBuzz&quot;, &quot;Buzz&quot;, &quot;11&quot;, &quot;FizzBuzz&quot;, &quot;13&quot;, &quot;14&quot;, &quot;FizzBuzz&quot;, &quot;16&quot;, &quot;17&quot;, &quot;FizzBuzz&quot;, &quot;19&quot;, &quot;Buzz&quot;, &quot;FizzBuzz&quot;, &quot;22&quot;, &quot;23&quot;, &quot;FizzBuzz&quot;, &quot;Buzz&quot;, &quot;26&quot;, &quot;FizzBuzz&quot;, &quot;28&quot;, &quot;29&quot;, &quot;FizzBuzz&quot;] (using ==)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the difference? The more-specific test shines a spotlight on the code that’s failing – we gave it a 9 and got FizzBuzz – making it a simple matter to fix the problem. The original one still gives me scroll-blindness and is not pulling its diagnostic weight, so I delete it with relief. There are still tests left to write – see the &lt;a href=&quot;/2013/01/18/7_degrees_of_fizzbuzz.html&quot;&gt;original post&lt;/a&gt; for examples – but we’ve made huge strides toward improving this code and its tests.&lt;/p&gt;

&lt;h2 id=&quot;deep-synergy&quot;&gt;Deep Synergy&lt;/h2&gt;

&lt;p&gt;Do you see how the 3 legs collaborate to hold up the stool? We can’t prove our program works without tests, but we can’t write high-quality tests unless we design for testability. We can’t design for testability without understanding basic design concepts and knowing how to refactor to them. All this gives us the tools we need to turn the “first draft” version we hacked together to hit a deadline into code we can live with for the long haul.&lt;/p&gt;
</description>
				<pubDate>Fri, 15 Feb 2013 00:00:00 -0500</pubDate>
				<link>http://billgathen.com/2013/02/15/3_legged_stool.html</link>
				<guid isPermaLink="true">http://billgathen.com/2013/02/15/3_legged_stool.html</guid>
			</item>
		
	</channel>
</rss>
