Karate Chop Kata in Ruby

I have to admit, this was a lot more difficult than I originally anticipated. A binary sort seems simple enough. This is 101 stuff, right?

But my first couple of runs resulted in relatively long procedures with a lot of boundary checking. While my specs were passing, the smell of the code was really bothering me.

I found a reference implementation and gave it a run, but discovered that it failed my specs. After a double-check of the specs to confirm I didn't have something messed up, I decided to dump the RI and try it again.

Finally, the pieces fell together and I could see where most of the boundary checking fell out of the method as I changed the sequence of events.

The Code

class Chop
  def self.find(lookFor, lookIn, start_index=nil, end_index=nil)
    start_index ||= 0
    end_index ||= lookIn.length
    middle = (start_index + end_index)/2
    
    return middle if lookFor == lookIn[middle]
    return -1 if ((middle == start_index) || (middle == end_index))
    return find(lookFor, lookIn, start_index, middle) if lookFor < lookIn[middle]
    return find(lookFor, lookIn, middle, end_index) if lookFor > lookIn[middle]
  end
end


The Specs

require "spec"
require "karate_chop"

describe Chop do
  context "with an empty sorted array" do
    it "indicates item not found" do
      Chop.find(1, []).should == -1
    end
  end

  context "with search target not in array" do
    it "indicates item not found" do
      Chop.find(1, [0,2,3]).should == -1
    end
  end

  context "with search target in array" do
    it "provides the index of the located item when in the middle of the array" do
      Chop.find(1, [0,1,2,3]).should == 1
      Chop.find(4, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]).should == 4
    end

    it "provides the index of the located item when it is last in the array" do
      Chop.find(20, [5, 10, 15, 20]).should == 3
    end

    it "provides the index of the located item when it is first in the array" do
      Chop.find(20, [20,40,60,80]).should == 0
    end
  end

  context "with a large array" do
    it "locates the item" do
      search_in = Array(0..900)
      Chop.find(100, search_in).should == 100
    end
  end
end

I am looking for feedback on these. Please, feel free to let me know how I could improve my code or specs. Or share links to your own solutions.






Martin Fowler on Technical Debt

Martin Fowler just posted an article on Technical Debt in which he discusses the Technical Debt Metaphor. Fowler argues that the metaphor should (and does) include messy code. He talks about deliberate and inadvertent debt as well as reckless and prudent debt. Prudent and Deliberate is the most desirable. While Reckless and Inadvertent is the least desirable. He published the following quadrant to help explain his concept.

He concludes with a statement about the risks of using the debt metaphor for messy code; "However a problem with using the debt metaphor for this is that I can't conceive of a parallel with taking on a prudent-inadvertent financial debt. As a result I would think it would be difficult to explain to managers why this debt appeared. My view is this kind of debt is inevitable and thus should be expected. Even the best teams will have debt to deal with as a project goes on - even more reason not to recklessly overload it with crummy code."

I would argue that the worst form of debt under this definition is in fact Reckless and Deliberate. This has been the motivation behind my assertion that Messy Code should not be considered Technical Debt. It allows teams to hide messy code behind a comfortable metaphor. We, as programmers, need to hold our standards high. Our goal needs to be a clean code standard.

While I recognize that Messy Code happens inadvertently, I don't think it should happen deliberately without very clear communication to the customer. And when this conversation takes place, I think you need to say, "In order to meet the deadline, we need to write messy code that will cause us problems from here forth until it is cleaned up." rather than saying, "In order to meet the deadline, we need to take on some technical debt."







Practicing Your Craft Through Code Kata

I assume most of you are aware of code kata. For those who are not; a kata is a simple code exercise. The idea is to perform these exercises in a practice session with no interruptions and no pressure where you can try each as many times as necessary. The goal is to learn and to build the muscle memory necessary to perform these tasks flawlessly in pressure situations.

I am putting together a series of kata for your consideration. I will be certain to give attribution for each as most (if not all) will be exercises found on that thar InterWeb, written by others and plagiarized highlighted here.

For my first few, I plan to draw from the series available on the Pragmatic Programmer's site where, to date, Prag Dave has listed 21 kata.
For all kata, I will follow a Pomodoro style, using tomatoi.st as my timer. I will attempt to complete each exercise in a single 25 minute pomodoro. Most kata are achievable in this amount of time, but not necessarily on the first attempt.

I will post code snippets and might even get gutsy and put up a few screen casts if I get proficient enough at some of them. It is my intention to complete all kata in Ruby. I may opt to work them in Java, Scheme, C#, or javascript as well.

I welcome your feedback and constructive criticisms. I am looking to improve my craft through kata. If you see something I could be doing more efficiently or effectively, please let me know.






SDTConf Day Two

Day two started with another quick planning session. This one went a lot faster. We had fewer topics suggested and everyone was more familiar with the format. This allowed the first sessions of the day to get started a bit early. Of course, following the Rules of Open Space, "Whenever it starts is the right time." So I suppose everything started precisely on time.

I started the day with a session on refactoring. This was a good session; well attended and well presented, but I was in the mood for a little more interaction, so I followed the rule of two feet and wandered into a discussion on introducing Agile in a Hostile Environment. Right up my alley. I failed at this numerous times before my first successes, so I had plenty of experience to draw upon. The attendees were primarily developers and leads who were sold on Agile, but found it difficult to introduce into their teams. I could empathize with them. Each of their attempts was met with a lot of resistance.

We discussed approaches that involved avoiding too many buzz words, identifying one likely ally, or simply leading by example. But the best advice had little to do with Agile and more to do with simple human nature. Listen to your team. Get to understand their personal pain. And then help them relieve that pain. While you may genuinely believe that TDD will solve a lot of problems for the team, if their immediate pain is with the build, then get CI stood up first. People are usually far less resistant to change than we give them credit for. The problem is often that they are already uncomfortable. Sweeping change is too big, too vague, and too risky.

I do have another piece of advice for those we are struggling in environments that are highly resistant to change. Leave. Sometimes it is better to change the people you are around rather than try to change the people around you. I am not suggesting we all quit at the first sign of resistance. But sometimes there comes a point when one realizes they are merely tilting at windmills.



My next session was on User Experience and User Centered Design (UX/UCD) in an Agile environment. My objective for the discussion was to find practices that served UX/UCD well and mapped to iterations. The predominant thinking is that UX/UCD is an up-front activity that must be complete prior to development. I'd like us to continue to challenge that thinking.

A great deal of the early discussion was around Contextual Inquiry as a part of requirements gathering and User Testing during the development cycle. We shared stories of success, stories of near success, and stories of sheer frustration. But we struggled to come up with additional techniques or insights. I was enjoying the discussion, but felt the session was coming to an early end. We were covering the same ground with no new insight.

And then Jeff Patton spoke. Quiet. Unassuming. Jeff stated that there are essentially three facets to the user experience. He drew a pyramid and separated it into three horizontal sections. At the base, he wrote "Utility" and explained that this is what the system does. Contextual Inquiry helps us define this. In the center section, he wrote the word "Usability" and explained that this is how the system is used. User interviews help us define this. Finally, at the top he wrote "Aesthetics" and explained this is presentation. It is important to understand the practices and how and where they apply.

You need to have Utility covered first. This does not make it the most important, but if the application cannot perform the intended function, it is a failure. It does not matter how usable or pleasing it is.

You need to have usability covered next. If an application is capable of performing the task, but is difficult to use, you will have less success. If users have alternatives, you risk losing them to something easier to use. If your users are a captive audience, you will see increased costs in training and re-work or they will do everything they can to avoid using the software.

Finally, you need aesthetics. This is where the psychological aspect is most significant. If people are pleased with the interface, they may actually tolerate a lack of usability. Jeff used Apple as an example. Design (aesthetics) are very important at Apple. While their products are not always easier to use, you do not mind the minor inconvenience. You are pleased to use the iPhone. It is ok that you have to scroll over three pages to find the app. The WAY you scroll the pages is kinda fun.

There are plenty of applications that prove Utility and Usability are sufficient. Craig's List is so anti-aesthetically conscious, it seems the lack of design IS the design. People don't care that it is plain; it does exactly what they want and it is easy to use.

Jeff's points resonated with me. I knew these things, yet failed to consider them as I was looking for techniques that could be mapped to iterations. If you don't understand how the practice applies and why you're doing it then it doesn't much matter if you do it before, after, or during an iteration. You're probably going to get it wrong. Figure out what you're trying to achieve, then figure out how.



I really enjoy conferences like these. Low ceremony, high value.

There are three ways to learn; push, pull, and share.

Push is where you sit in a class or session and someone walks you through a lesson or seminar. This is typically low signal to noise. You are going to get a lot of information, only some of which you are currently interested in or can use.

Pull is where you seek out the data and gather it for yourself. This is better signal to noise. You can control the flow of information and can target the information to your specific interest or need.

Share is where two or more people freely exchange ideas. This is my favorite form of learning. Everyone learns and if the conversation is truly a balanced and free exchange, there is all signal and no noise.

SDTConf and other open spaces are Share learning.









SDTConf Day One

I really like the open space format. Simple rules. Maximum value.
  1. Whoever shows up is the right group of people.
  2. Whatever happens is the only thing that could have.
  3. Whenever it starts is the right time.
  4. When It is over, it is over.
We started the day with a round of introductions and then did a light-weight scheduling exercise to get the sessions for the day arranged. I was so enthralled with the other potential topics, that I pushed UX/UCD and how they map to Agile to on-deck for day two. I hope I don't regret that decision. Some folks are here for the one day.

The rule of two feet is a beautiful thing. This is not an explicit open space rule, but it certainly exists. The rule of two feet simply rephrased is, "You have two feet. If the session does not serve you, walk." It is not considered rude to leave a session in progress. To some extent, this is encouraged. It is considered rude to break wind and yell, "F you guys, I'm outta here!" I learned that the hard way.

I attended a number of excellent sessions today and participated in several very good hallway discussions as well.

We discussed the pros and cons of taking advantage of "others' code"; from frameworks to libraries to gems to simple copy/paste. We shared stories of pain and stories of success. In the end the general consensus was that frameworks are usually painful where libraries and more discrete items are easier to leverage with minimal risk. Ultimately, we agreed that the more discrete the component, the better the API, and the greater the intent of reuse, the more likely you are to be successful.

We evaluated roles and the sequence of steps in the overall development cycle. One conclusion drawn was that all involved in the delivery of software should be called developers. You may (or may not) have roles such as BA, programmer, and QA. But ALL of them are responsible for the successful development of code. There was lengthy discussion around the stages of development and while we all agreed that putting creation of tests in front of development of code, we also agreed that it is a complex cultural shift and will take time. We're not talking about just unit tests here. Acceptance tests; the specific criteria by which the story will be evaluated need to happen before code is written.

We discussed learning and the intimidating amount of knowledge a developer really needs to have in order to be a master in their domain. Hell , the intimidating amount of knowledge a developer really need to have in order to be a novice in their domain. How do we create a path to guide new developers? Are there a simple set of one dozen patterns, practices, and/or principles that every new developer should learn first? Is there a single pattern or principle (there can be only ONE) from which all others can be derived? It was a very good conversation and I look forward to the results of the discussion.

Dinner conversation was as interesting and educational as the conference discussions. At my end of the table, we discussed (among several topics), the long-term value of XP practices in a mature shop. Do highly skilled and experienced developers need to follow these practices or do they have enough experience that they no longer need the safety and guidance provided? Do these practices actually impede delivery once you've achieved a certain level of skill and proficiency?

While it was an interesting conversation, it concerned me, much like Spolsky's Duct Tape Programmer post. Let's assume the assertion is true. Developers reach a level of excellence where they no longer need to follow some of the practices that got them there. Here's my primary concern - How do you honestly know you are so good, you no longer need the safety net for performance? Our profession is riddled with a strong ignorance to ego cohesion. I hear story after story of developer who was absolutely certain they were awesome and correct in everything they did and they then stumbled (or were dragged kicking and screaming) into TDD and had an "aha" moment. Prior to the "aha" moment, the developer knew they were excellent and did not need those West Coast, touchy feely, hippie, group hug concepts1. There are far too many developers who are prior to their own "aha" moment. They may read the Duct Tape post or get involved in these conversations and conclude that they are one of those excellent developers who need not concern themselves with the "overhead" necessary only for lesser mortals.


I am looking forward to day two. It is a fantastic experience to spend time with professionals interested in their craft; those who see value in taking a weekend and spending time (and some money) on developing a deeper understanding and challenging their own current views.




1 - Special thanks to TB for this expressive description of Agile. I suspect TB is still sitting alone in his cubicle somewhere cranking out amazingly complex modules full of features nobody asked for, but he is absolutely confident they will need someday.





Craftsmanship

I have the profound and intimidating honor of being the fifth person to make note in the Wandering Book. To be honest, I'd hoped to be later in line. I'd hoped I could read numerous entries and ponder all the wisdom before it came my turn to write. As the fifth, I have to admit there is already a great deal of wisdom in the book. The four before me are remarkable people. And those who will follow me are surely remarkable as well.

Corey Haines talks about practice and learning. He talks about the path to mastery and ultimately, the role of the master as teacher.

Jason Gorman explains that Craftsmanship is not about practices or membership. It is about caring, learning, and practicing.

Dave Hoover ties the two prior entries together and stresses the need for more people to commit themselves to mastery.

Eric Smith tells a personal story of how the craftsmanship movement rekindled his passion for software development.

I've pondered these stories; these lessons; these words of wisdom. I've thought about my own journey. I've considered what it is that drives me. What it is that inspires me. Why I choose to be a software developer and what is important to me about my craft.

There is a simple, poignant, common thread throughout the book already. Learning, Practicing, and Sharing. Craftsmanship is about continual improvement. Craftsmanship is about applying the craft. Craftsmanship is about being your best and helping others to be their best. Craftsmanship is about the free exchange of ideas.

My journey has been long. I've been in the industry for over 20 years now. And I feel as though I am only at the beginning. But throughout the years, the most rewarding experiences have always been those where I worked closely with an open and honest team. And consistently, it is from those experiences that I learned the most and was able to share the most knowledge with others.


Craftsmanship is Learning, Practicing, and Sharing.






Running Developers Unite! - Update

I received a lot of positive response from the initial posts about getting a running group for developers started. After a bit of research, it seemed the fastest way to get something going, was to take advantage of www.dailymile.com and start a group.

I started the group about one week ago and we have 9 members so far. If you are interested, please visit the group and join us. There is no obligation. It's just a bunch of developer-types who also happen to run, whether it be casual, for fitness, or competitive.

http://www.dailymile.com/groups/595-test-code-run