8/17/2013

Ruby Warrior - Game Emulation

Emulating the black box behavior allows us to build tests that prove your code works, as long, as the emulation remains close to the real thing. The Ruby Warrior runtime has features within it, that I do not know yet since I am still at level 7.

The output from my game emulator looks nice and allows me to great new alternative levels that exercise all the features of my player that I wish to.

GAME START
| ^     >|
|  ^    >|
|   ^   >|
|    ^  >|
|     ^ >|
|      ^>|
|       ^|
GAME OVER: ALIVE
GAME START
| ^ C   >|
|  ^C   >|
|  ^    >|
|   ^   >|
|    ^  >|
|     ^ >|
|      ^>|
|       ^|
GAME OVER: ALIVE
GAME START
| ^ S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^S   >|
|  ^    >|
|   ^   >|
|    ^  >|
|     ^ >|
|      ^>|
|       ^|
GAME OVER: ALIVE

A simple rspec runner of these game layouts and a way to encode the game boards makes setup easy.

 describe "Game" do  
  let(:player) { Player.new }  
  
  it "plays empty board" do  
   game = Game.new("    >")  
   game.play(player)  
   
   player.should be_alive  
  end  
   
  it "rescues a sad caged pair of eyes" do  
   game = Game.new("  C  >")  
   game.play(player)  
   
   player.should be_alive  
  end  
   
  it "attacks some sludge" do  
   game = Game.new("  S  >")  
   game.play(player)  
   
   player.should be_alive  
  end  
 end  
   

The simple Game runner.

 class Game  
  def initialize(pieces)  
   @pieces = pieces  
  end  
   
  def play(player)  
   warrior = Warrior.new  
   warrior.board = Board.new(@pieces)  
   
   puts "GAME START"  
   while (warrior.alive? && warrior.on_board?) do  
    puts warrior.board.with_player_at(warrior.position)  
    player.play_turn(warrior)  
   end  
   puts "GAME OVER: #{warrior.alive? ? 'ALIVE' : 'DEAD' }"  
   
   warrior.alive?  
  end  
 end  
   

Ruby Warrior - Trying Again

It is clear that a solution to a problem like this can't just be imagined out of thin air. I am just not that smart. Just writing if statements was satisfying and productive to start with but once level 7 hit and I had to change direction there was no alternative but to throw everything away and start again.

This time, I decided to create a fake warrior implementation, an write some rspec tests to ensure that the actions I chose were appropriate. Then "release" (copy) that code to "production" (paste) to see if it worked there as well.

With this approach, I am making headway but can only solve level 2 because I haven't reimplemented the resting process yet.

Warrior Fake

class Warrior
  attr_accessor :position
  attr_accessor :board
  def self.at_position_1
    warrior = Warrior.new
    warrior.position = 1
    warrior
  end
  def self.next_to_sludge
    warrior = Warrior.at_position_1
    warrior.board = [:sludge]
    warrior
  end
  def initialize
    @position = 1 #zero based
    @attacked = false
    @board = []
  end
  def walk!
    @position += 1
  end
  def attack!
    @attacked = true
  end
  def has_attacked?
    @attacked
  end
  def feel
    @board
  end
end

Player Implementation

require './warrior_fake'
class Context
end
class Action
  def self.choose(warrior, context)
    if !warrior.feel.empty?
      Attack.new
    else
      Walk.new
    end
  end
end
class Walk
  def run(warrior)
    warrior.walk!
    warrior
  end
end
class Attack
  def run(warrior)
    warrior.attack!
    warrior
  end
end
class Player
  def initialize
    @context = Context.new
  end
  def play_turn(warrior)
    action = Action.choose(warrior, @context)
    action.run(warrior)
    warrior
  end
end

Specs

require './spec_helper'
require './warrior_fake'
require './warrior'
describe Player do
  let(:player) { Player.new }
  context "walking" do
    it "moves forward" do
      warrior = player.play_turn(Warrior.at_position_1)
      warrior.position.should == 2
    end
  end
  context "sludge" do
    it "notices sludge" do
      warrior = player.play_turn(Warrior.next_to_sludge)
      warrior.should have_attacked
    end
  end
end
describe Action do
  let(:context) { Context.new }
  let(:warrior) { Warrior.at_position_1 }

  context "construction" do
    it "walks forward" do
      action = Action.choose(warrior, context)
      action.should be_a Walk
    end
  end
end
describe Walk do
  it "forward" do
    walk = Walk.new
    warrior = walk.run(Warrior.at_position_1)
    warrior.position.should == 2
  end
end
describe Attack do
  it "forward" do
    attack = Attack.new
    warrior = attack.run(Warrior.next_to_sludge)
    warrior.should have_attacked
  end
end


Thank-you Ruby Warrior

I just ventured into the dungeons of the Ruby Warrior and spent an hour of my life that I can not get back, but would like to if that is at all possible. What a great time to be writing ruby, to program a knight, in a live dungeon.


I made it to Level 7 before my code was so complex that refactoring is inevitable. I count at least infinity code smells in this. Flags, single method, no intentional behavior, no single responsibility. I am considering some UI testing tool to prove that I can pass each level with the same codebase.

Good times.

class Player
  def play_turn(warrior)
    if !warrior.feel(:backward).empty?
      if warrior.feel(:backward).captive?
        warrior.rescue! :backward
        @saved_captive = true
      else
        warrior.attack! :backward
      end
    elsif !warrior.feel.empty?
      if warrior.feel.captive?
        warrior.rescue!
        @saved_captive = true
      else
        warrior.attack!
      end
    elsif warrior.health < 20
      if warrior.health < @health
        if warrior.health < 12
          warrior.walk! :backward
        else
          warrior.walk!
        end
      else
        warrior.rest!
      end
    else
      if @saved_captive
        warrior.walk!
      else
        warrior.walk! :backward
      end
    end
    @health = warrior.health
  end
end

8/03/2013

Waterfall Disease - Symtoms, History and a Cure

It is easy to spot the symptoms in aggressive cases but can present in subtle ways as well. It effects individuals and teams and is communicable. The cure is long and slow but the young heal much faster. If you have been infected with this disease for more than 20 years, the chances of a full recovery is slim.

Symptoms

A programmer feels the strong urge to open a documentation tool before a code editor. This is not a guarantee of infection but a strong indicator.


An infected team will wait for a task to be given to them and then talk about how it is the wrong task or how long it will take to implement. Similarly infected product owners will first ask how long before asking what should be accomplished.

A programmer will, when asked what it would take to implement a feature, answers in terms of the complexity and duration. For example, "OH that would be difficult, we would even have to change the code", or "We would have to talk to that other team, so that will take much longer".

An infected team or programmer assumes that the deadline means they will have to hack in a bad fix, even when there is no stated deadline. These individuals just assume that they will be pushed to make bad decisions so make them as the default, as thought there is no other approach.

A team member states "that is his responsibility", or makes a suggestion or proposal for a change like "I think we should do X". Each of these forms of communication relinquishes responsibility to others, ensuring that the team member does not have to take ownership of the idea they are sharing.

A team member will hand-off a task with the statement "you need to do X so that we can accomplish goal Y". This team member will, and watch for this for it is quick, turn on their heals quicker than normal, and walk away with a slight smile believing they have helped but actually are just passed the blame.

An infected team member will act out, taking actions in direct opposition to the teams goals, and other infected members will watch as though they have no control. They are thinking that the boss should fire that person, not realizing that they should also be considered.


History

Waterfall disease has been with us for decades. Until the late 1990's it was thought of as normal, even part of the best practice of what a programmer was. Only as the year 2000 approached and the new Agile medicine was introduced to the market did everyone start thinking that there might be another way.

Unfortunately, this Agile medicine tastes very bad and patients remain in denial of the problems, just because of that possible bad taste. It is not uncommon for teams, thrashing uncontrollably and screaming about the unacceptability of their plight, to also state that "the medicine will never work" and refuse to sign-up for the treatment program.

Cure

The treatment for waterfall disease is not easy and takes time. Unfortunately, this conflicts directly with the infected parties who have no patience for change.

The cure comes in 3 main phases: a strict diet of learning, combined with the constant guidance of mentors to re-map the brain pathways and finally a change inoculation.

The learning pills must be dosed carefully across time to avoid overload. An ideal learning pill regimen might look like this though results may vary depending on how acute the infection is.

  • Complete removal from the environment that promotes the infection. This might mean leaving the programming environment, the building where re-contamination is possible or even, in the most aggressive cases, leaving the company that actively promotes the disease, is the only way to avoid a relapse.
  • Daily doses of TDD to begin with interspersed with insights into why the current feelings they are experiencing are actually not normal. Knowing that they have a problem is an excellent step toward recovery but do not expect this to occur in these first rounds. Continue this repetitively for 2 weeks switching from a training environment to a practice environment until you start seeing the natural antibodies of the human body kick into gear. These changes show themselves in the form of surprised questions like "so this actually means I don't have to fix bugs anymore"?. Be gentle with the initial naive questions for the physical changes that are underway are only loosely bonded.
  • At some point a sense of wonder, and excitement about the future starts to seep in. Recognizing these moments is key to cementing the changes and reducing the possibility of relapse. Show your excitement about the future and talk of your new life, clean of disease.
  • Once two "sense of wonder" moments have passed it is time to move to the next phase of treatment. Collect one or more of these patients into a team and task them with a green field solution. The use of a green field solution simplifies the continuing diagnostic work that is going to be necessary as the work progresses. This also starts the mentoring phase of the cure.
The mentoring must be administered throughout the process for at any time, day or night, an infected individual will take an action that completely undermines their cure. Examples, might be:
  • Mid-night implementation of a new feature. Attempted under the guise of improving the teams velocity (and they will use that word even if they do not understand it), but actually, this action is driving a sense of self-congratulatory excitement of achieving goals without the mentor's gaze and without tests. Protect against this with early investment in fully automated functional tests. The next days failing build will identify the culprit and allow the mentoring to focus appropriate action.
  • Active creation of cliques, through a sub-team secret design sessions that can then be presented as great successes to the team, when in-fact, they serve more to isolate and inject mistrust amongst the team members.
  • Little code changes without tests will leak into the codebase, often with a source control comment unrelated to the change or misdirecting the mentor to a larger change. When challenged the response will likely be a sheepish grin, as though that still works now that they are fully grown up adults, and the statement like "that was just a one character change", or "its only in a tool, not the real app". These are actions that must be stopped, in group therapy sessions, to ensure that everyone agrees that they want to be cured.
The change inoculation is where most of the physical and mental pain is experienced. Analysis of relapsed patients bring to light complaints about the deep personal loss of family pictures and the requirement to move that caused discomfort. Screen sizes, keyboard types and strange IDE's are many of the hurdles that patients must push through. Also they will attempt apparently logical arguments explaining why sending an email is fare faster than walking 10 feet; "plus they have a record of the conversation don't they? Perhaps they want to refer back to it later? They won't have to come and ask me again? Just consider the time savings of not having to move."

This phase should not be trivialized. Your patients complaints will seem small and full of self-interest but they are one of the biggest drivers of resistance to the medication. Failure to attend to these details will initiate a slow drift back to habits that are more comfortable. Many retrograde steps will be subtle, almost imperceptible; a head turned to the floor during a standup, an extra second of reluctance to approach the board and be part of the team. The feelings of isolation, and failure will compound this situation accelerating the relapse.

The inoculation itself can take many forms but centers around making change the norm through the use of intentional disruption. For example,
  • Throw away all desktop computers and replace them with laptops to promote movement. In the same vein, ensure that wireless network access is available and the old wire is disconnected.
  • Interrupt the team with cake but do not take it to their desks. Instead, place it 20 feet from them so that they are encouraged to move. Repeating this makes movement more normal and bridges the gap to a time when movement to communicate with team members is the new habit.
  • Mandate pair programming and make sure that it is with new people all the time. Having to work with team mates ensure that they know each other's names and start gaining insight into other cube silo's.
  • More radical, but utterly required to ensure success, is the removal of cubical sitting structures. Some powerful conversations with CIO's will be necessary to drive this kind of medication. 
  • Disabling email for periods of time forces movement for simple conversations, changing the quality of communication so much that teams will start experiencing a high velocity team feature known as "common thought". At first this is startling, and must be called out by mentors as a healing step, but will soon become the natural order in which simple 30-second exchanges can accomplish what was once days worth of drifting, misinterpreted email exchanges.
The change inoculation is fraught with complaints like "but I liked my privacy" and I would rely on your mentor to resolutely and clearly state the futility of these gestures. Perhaps offer "we could build you your own office if you like" or "aren't we all so lucky to have private homes to go to". Lean on the emotional content of these interactions, logic is not as effective in this inoculation process. Only the emotions of team membership and commitment to common goals will drive the lackadaisical thoughts from the air. These thoughts are drivers of relapse so be attentive in all locations: sit with the team in the team areas, be there in break rooms, and accompany likely offenders during the walk to their car, especially if they are accompanied. Contamination is an ever present threat.

This cure is a 3 to 6 month process and after the 6 months is over the need to continue to encourage advanced learning is critical to maintaining the positive progress.

Waterfall disease shares a similar trait to alcoholism. Once infected, you will always carry the old urges. Even well established mentors have been known to succumb to the comfortable old habits of believing their code actually works without tests. Why just yesterday, I was party to the disabling of thousands of distributed machines because I knew of a change being made and said nothing about it not being tested.

Yes, I have waterfall disease.

10/07/2012

Ruby, SSL and Untrusted Certs

It has been a long time since focusing exclusively on writing Ruby code. So much fun.

The last two years have been groovy only which is a great language but there is something pure and simple about Ruby that just takes your breath away.

Enough of the emotional stuff, why, on earth, is it so hard to disable SSL cert trust verification. Such a common problem, google is full of Rails ActionMailer solutions but of coarse that doesn't help the rest of us.

Ruby 1.8.7

I approached the problem from Net:HTTP library makes it pretty easy. You just have to remember to require the correct classes and note that you are not disabling SSL just the trust verification part. # irb(main):001:0> require "net/https" # => true # irb(main):020:0> h = Net::HTTP.new("YOUR_SSL_SERVER",443) # => #<Net::HTTP YOUR_SSL_SERVER:443 open=false> # irb(main):021:0> h.use_ssl = true # => true # irb(main):022:0> h.verify_mode = OpenSSL::SSL::VERIFY_NONE # => 0 # irb(main):023:0> h.get("/") # => #<Net::HTTPOK 200 OK readbody=true>

My actual goal was to access a WSDL, over SSL, with an untrusted cert. This was not so easy. Took me about 5 hours to work out this solution. Expensive.

I used the Soap4R gem and since performance is not an issue I figured the dynamic proxy from the WSDL parsing would be the way to go:

factory = SOAP::WSDLDriverFactory.new("#{@url}?WSDL")

The problem was that there is no simple API to set the verify_mode of the connection so you have to root around in the code until you find where to monkey patch. This is what I came up with.

# # Monkey Patch HTTP Client # Sets SSL verify mode to NONE so that we can connect to an SSL server # that does not have a trusted certificate. # class HTTPAccess2::Client def initialize(*args) super(args[0], args[1]) @session_manager.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE end end

If someone has a cleaner solution I would love to hear it.

Ruby 1.9.3

Upgrading to 1.9.3 broke my Monkey Patch as expected so here is the updated one that handles both for the time being:

# # Monkey Patch HTTP Client # Sets SSL verify mode to NONE so that we can connect to an SSL server # that does not have a trusted certificate. # # The 1.8.7 patch adds a new constructor. # The 1.9.3 patch intercepts the existing constructor now that the class # name has changed. if RUBY_VERSION == "1.8.7" class HTTPAccess2::Client def initialize(*args) super(args[0], args[1]) @session_manager.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE #@session_manager.debug_dev = STDOUT end end else # > 1.8.7 class HTTPClient alias_method :original_initialize, :initialize def initialize(*args) original_initialize(args[0], args[1]) @session_manager.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE #@session_manager.debug_dev = STDOUT end end end

10/25/2010

Southwest Ohio Give Camp - Review

Ending with the demo of the charities new sites and the excitement on their faces as they looked up at the giant screen, was certainly the best thanks we could have received.


Moments.

Arriving back at the MUVOALC early Sunday morning to find volunteers outside banging on the doors and windows trying to get in. Six a.m. days are no match for these awesome people.

The 10 year old son of one of the volunteers asking how he can help. Dropping the xbox controller to rush off to notify the teams that more pizza had arrived.

The quiet that descended on the team rooms as everyone focused on doing their best work.

Team leads complaining that they don't want to wait 15 seconds for a standup to start because they have customers waiting.

Volunteers with decades of experience reveling in talking about what their young team members have been producing.

The worry expressed by people that working till 3am would not be enough and would the charity like what they have done.

Hearing the charities talking about "their developers", bringing then brownies and taking group photo shots.

10 Charities, 10 Solutions


Conclusion

As much as we were thanked for this one weekend, it is clear that the charities themselves have 51 others this year to do their work. These are the true champions of this weekend. It has been a privilege to get to know them and offer a small amount of assistance.

7/16/2010

Southwest Ohio Give Camp



On October 22 through 24th we are running a Give Camp located in Southwest Ohio. Collect your project manager and developer friends and we will connect you with a team to help out a Charity for one weekend. This is a great way to use my professional skills for a good cause.



We have an awesome group of volunteers putting the event together. We are organized into 6 teams to ensure we have a focus on the various areas that have to be worked on.

The Charity team focuses on identifying Charities, collecting the details about what they need. Our goal was to support 10 charities and we already have 20 submitted proposals. This team is comprised of Andy Erickson (@axerickson), Eric Schwartz (@SchwartzE), Darrell Hulshult (@dhulshult) and Andy Douglas (@GoodPiper) all doing an amazing job pulling together all these organizations to coordinate so many successful projects. Just imagine the problem of running 10 projects simultaneously in one weekend.

The Developer team focuses on setting up the website and attracting all the tallent that will work on the Charities products. With a goal of 50 people, to give us 5 person teams for each Charity, we are now at 37 with 3 months to go. With this kind of ramp-up we may have to consider expanding our goals. This team is made up of Ernie Stormann (@EStormann), Jennifer Griffin (@jengriff), Bill Barnett (@agilous) and Matt Brewer (@MattBrewer).

The Facilities team is responsible for finding the location for the event and managing the setup and orchestration of the event over the weekend. This is a mammoth task, to plan, find and acquire food for everyone, to manage the registration and leading of people to their work environments, and ensuring that everyone is getting everything they need. The idea of 100 people descending on a single location for two days is going to be quite an experience. Fortunately, the team is incredible, made up of Ryan Cromwell (@cromwellryan), Matt Brewer (@MattBrewer) and Sandi Sumerfield. They found a fabulous facility in the Miami University Voice of America location which has the most up-to-date and state-of-the-art video, network and teaching facilities I have ever seen. This building is basically being donated to us for this event because Miami University is so invested in helping the charities in this community.



The Finance team is just me but I am fortunate to have made contact with some great partners to help me through this process and so many generous sponsors. However, I am learning that the financing of charity events is much harder than for-profit events. It seems that the word Charity discourages companies from sponsoring it. If anyone is interested in donating please let me know.



The Marketing team is a combination of people from all teams since each team has requirements to reach the people they need to reach. I just manage it but everyone contributes what they need. Andrea N. Brady from The Marketing Shop Consultants has been a great help, donating her time to craft articles for publishing.

The process for putting this together starts with lots of enthusiastic smiles and then you start to realize all the details that are involved. The key to success rests on the team you choose. it's the Charities that need to win, not us.

4/15/2010

Cincinnati Day of Agile - Registration Opens Today

Registration opens TODAY at noon. Seating for this event is very limited and this event is going to quickly sell out. Do not wait - register today at http://cincydayofagile.eventbrite.com/.

What is Cincinnati Day of Agile?

As the Agile project management process sweeps across the software industry, businesses not understanding the details are being left behind. The Cincinnati Day of Agile is an opportunity to understand what Agile is all about and hear from people that have used it, succeeded with it and have the results to prove it.

At this one day event on Saturday, May 15th, a host of industry experts will be on hand to offer their hard won experiences. By bringing together a mix of developers, managers, Agile professionals, and technologists, the Cincinnati Day of Agile also provides excellent networking opportunities for its attendees. We hope you will join us to learn how Agile can make your software development process more effective, productive, and profitable.

More about the event can be found at http://cincydayofagile.org/.

12/06/2009

Kanban - A small practice project

A few months ago I completed my first Kanban project. The team was small and the introduction informal but it went well.

Kanban Board

Background

The team comprised 5 people. A technical manager, 3 web developers and me. They managed many projects simultaneously which resulted in a great deal of task switching for the developers.

There were no detailed plans and few team planning sessions. The technical manager was able to keep track of the teams goals on the fly. As tasks and priorities changed, the team would be notified.

Three of the team members had experienced a full agile project in the past which resulted in the team continuing daily stand-up meetings. They stated that they wanted to continue using TDD but that hadn't persisted as strongly. While one of the developers had used TDD in the past, they did not use it consistently, and the rest of the team did not have any training on the technique.

Project

The project was estimated at 2 weeks and involved a UI replacement of an existing web application. A couple of minor business flows were going to change but essentially it was just large segments of the site getting new HTML/CSS. All HTML/CSS was developed by a 3rd Party design company so the in-house work was limited to verifying what was delivered and implementing the designs.

Process

We started with a little presentation on what Kanban is. Ran through some examples of how a project might be run with a focus on software projects. The whole team was in attendance along with a couple from other teams and a Director.

Feedback seemed good with statements like "We need something like this" and "I wish we could get all teams to do this".

From there we got the team together to chunk up the tasks and played Planning Poker to come up with some high level estimates on how long it would take. Each task was written on a post-it note and stuck on a white board in the left hand column ready to be pulled forward into the work in progress.

The columns we started with were:

o Backlog
o Work in progress
o QA
o Complete

Even though "everything had to be done" it was agreed that some were more important than others so a loose prioritization scheme was devised that ensured that the correct post-its were pulled forward first. The manager took on the role of adding priorities to post-its in the Backlog column when needed.

Results

Team members initially needed some encouragement to move the post-its on their own. This soon past as they were offered the opportunity to take control of the work they were going to do.

By the end of the first day we had blocked tasks. We started adding red stickies to the post-its but eventually moved them to a new blocked column between the Backlog and Work in Progress columns.

When asked, the team said they liked the process because it helped them see what was needed and completed.

A great indicator of the teams investment was the exclaimation "Wow, look how much we have got done" as they looked at the completed column full of post-its.

Since the team was switched to and from other projects the estimated two weeks was not an elapsed time but the project was released before the business needed it.

Comparison with Agile

We did take the time to estimate the stories which wouldn't necessarily be part of a Kanban project. However, there was concern about the completion time which needed some up front guestimates to allow the team size to be predicted.

Beyond release estimating, no time was spent planning what tasks should be worked in the first iteration. While it was only a two week project, in a Scrum or XP project we might have tried for 2 one week iterations. Not doing this did save us a little time and since the Kanban board continued to show tasks getting completed there was always a clear understanding that things that were getting completed.

Additionally, without iterations we didn't ever ask ourselves about what to do if we had not finished the estimated work in the iteration. Instead we maintained the column constraints and monitored how long items stayed there.

If this team ran all their projects using Kanban, the lack of planned iterations might allow some projects too fall through the net. This can be handled with simple organizational changes so shouldn't be a risk.

11/21/2009

Grand Rapids Give Camp - Cincinnati Satelite - Retrospective

What an excellent time, hanging with friends, meeting new people and the opportunity to help out some charities at the same time.

Grand Rapids Give Camp

I first heard about Give Camp when Mike Wood published his involvement at one of last years events. When Mike mentioned Grand Rapids I knew it was something I wanted to be involved with. Only a 5 hour drive from Cincinnati but it turned out that the drive was not going to be possible. Fortunately, with some great support and nagging from friends I decided we needed to organize a Cincinnati based satellite to see if we could help out.

Now that it is over, everyone is talking about doing our own in Cincinnati next year so here are some memories to remind us.

Over the coarse of the of the weekend twelve local developers volunteered their time and were able to contribute to 5 different projects with their Rails, PHP (Joomla/Drupal) and .Net (dotNetNuke) experience. A great diversity of skills allowed this group to really make a difference.

Thanks everyone, you rock, Rob Biedenharn, Brad Leydorf, Phil Japikse, Mark Haskamp, Frank Glandorf, Kevin Longshore, Bill Barnett, Gerard Sychay, Sunil Kommirshetty, Brian Harwell, Andy Douglas.

It was great working with the Grand Rapids team, Chris Woodruff, Ryan Montgomery, Carl Furrow, Luke Rumley, Emily Stoddard and an apparent endless list of others that I never got to talk to.

However, as with all experience, it wasn't just buttercups and blue bells. As a remote team we experienced the usual problems that distributed developers face. We had a hard time connecting with the teams in Grand Rapids. To make Give Camp Satellites more effective they really need full Voice/IM connections with the teams they work with.

On the first night Luke took on the the role of runner and was great at matching the experiences we had in Cincinnati with the work opportunities up there.

The second day involved us bugging people we learned about on the first day to see if we could help. We heard that they were mostly involved with design work and we were not UI people so the pickings were lean to start with. As the day rolled on we started getting more hits and ended up being able to make some real connections and contributing some positive changes.

The last day left us with one, particularly difficult, bug to address which ended up taking input from 5 developers, over 7 hours, to find the eventual 2 character fix. Oh Safari, the pain you put us through.

As the closing ceremony started in Grand Rapids, we had our own celebration with the most popular food of the weekend, a giant bag of M&M's and promises to work on a Cincinnati Give Camp next year.


EdgeCase Software Artisans Thanks to EdgeCase for donating their Cincinnati office space, and for those that work there, letting us use their desks and plug-in to their monitors.

Thanks to Finagilous for supplying food.

Some pictures:

EdgeCase Office
All Volunteers waiting for work
Bill, Frank and Mark
Rob and Bill
Kevin, Ed and Andy
Bill and Rob

6/27/2009

Security and Quality through Testing or Process?

As an Agile software developer I talk alot about testing. I promote and teach Test Driven Development and push to change the habits of developers to encourage quality traits that make the software we produce just work.

I want to draw a distinction between the understanding that I am "testing" and the fact that I am following a "process". This may be moot in the grand scheme of things but it strikes me as important because of a sentence I was about to make to a security professional.

Consider this:

As a software developer, my primary goal is to make software work.

A QA developer is focused on making software NOT work.

This is why I am not capable of testing.

Similar logic demands that
I am not capable of producing secure code.


The problem with this logic is that is contradicts everything I teach. Test, test, test but, oh by the way, you are not capable of succeeding.

So, perhaps I should describe TDD as a development process that improves quality instead of a process that tests code. While the eventual result is a set of tests that verify features of code, the developer gets there by following the TDD process, not by trying to make things break.

This is not a statement of whether TDD is a design process or not. Different discussion. I am addressing developer intent, not defining the outcome of the TDD process.

In TDD we first follow a simple mantra:

Run the Test,
Change the Test,
Change the Code,
Repeat every 60 seconds.

Step two of this process could be argued to be an attempt to break code. However, this is not true since all we are doing is writing tests that will break because the functionality is not implemented yet.

TDD offers us a process to ensure that we end up with a suite of testing code that matches our running code. So TDD is not a testing process, just a development process that encourages a higher quality of working code than other processes.

From a higher level, the software development process we use already "values" a Quality Assurance team that double checks the work that we do. These people focus on breaking our code and do a really good job at it. They are a critical step to producing reliable software.

Another important role that software developers are unable to be good at is producing secure code. While we can learn the best practices and gain an understanding of the OWASP Top 10 attacks we are still trying to make software work for the business, we are not trying to prevent customers from attacking it.

Even with this problem, the software development process doesn't "value" a security organization reviewing the product that is produced.

Our industry is just starting to learn how to integrate security intelligence into the software build process and, to date, we software developers do not have a Security Driven Development process to improve our odd for success.

Scott Ambler's 2003 article predicted its creation in 2004 but his predicted internet shutdown wasn't as impressive a game changer as he thought. Unfortunately, that remains a learning curve in our future.

6/19/2009

Dynamic vs Static Typing: An Observation



This is a dynamically typed language


pron. This v. is prep. a adj. statically n. typed n. language



3/13/2009

Careful, Java Programmers going to Ruby

Good evening everyone, I am a Java programmer.
It happened quickly, I didn't even notice.
One day I was merrily strncpy'ing and the next it was immutable.


We joke about languages of old while new shinny languages are paraded in front of us, but in the end they all teach us something and make us forget other things.

Today I came across the first serious change that the Java world thrust upon my weak mind. I am working a Ruby project, a great new shinny language which is lots of fun to learn and work with.

When working in Java I use the usual Agile development process; write your test, write some code and repeat. As I progress, my code, and indeed the API design, evolve into a nice usable, stable set of libraries.

Working in Java, with Eclipse, the simplest technique is to start by writing your test, reference a public method, press a key to create it and flush out the implementation. As you go, you will naturally refactor pieces of code into new methods to keep it simple.

Well, this is where things get a little too easy for Java developers in Eclipse. To refactor a block of code into a new method just select it, press a couple of keys and Eclipse creates the new method for you. A new private method in the same class.

Sounds good right? Well it is, except, that you have now learned to not thing about the scoping your your methods when you create them. Your first is always public or protected because your test is driving it and subsequent methods are private by default as created by the IDE. It's a beautiful system.

Now you switch to Ruby.

You write your test and implement your public method, you refactor with the cut/paste/rename/suffle and low and behold, because you have learned not to think about it, you have loads of public methods in your class.

The project I am working on takes it one step further and has tests for every method, examining all its nuances, mocking all its dependencies and going to town making the implementation as couple to the test as possible. It's easy to do, they are all public, what else is a programmer to do?

Unit testing philosophy does vary depending on who you talk to but my basic goal is to:

  • Test all public methods,

  • Test all protected methods,

  • If a private method is particularly complex make it protected and test it,

  • If I have loads of "untested" private methods I need to move some to new classes and make them public. I leave it to you to quantify "loads".

  • Trust your coverage tool to tell you the private code you never use and delete it.


So, starting tomorrow, I change my Ruby development process and consider all new methods private unless part of a test driven process. This will do lots of things to improve the final product:

  1. Simplify the test/code dependencies making the tests less brittle.

  2. Prevent call sequence bugs where you have to call one method before another or it all falls over. Too many publics will do that you know.

  3. Make the calling conventions exposed by the class easier to grok by new programmers reading the code.

  4. Improve Class API design which is one of the primary benefits of TDD, lost to the lazy public manic people like me.



Oh, yes, an stop putting java semicolons in Ruby code. That really upsets the Ruby people.

Tests and Blank Lines

Add blank lines please.

This might sound stupid and, indeed, alternate DSL's for unit testing are making this less of an issue but there are still a lot of the old XUnit frameworks that prevent isolation of the 3 areas of your tests.

Every test you have needs to be setup, executed and validated. Let's start with a Java example.

public static void testSomething()
{
Address address = new Address();
address.setName("The House");
address.setLine1("1234 Street Ave");
address.setCity("Cityville");
address.setCountry("US");
address = dao.geocode(address);
assert_equals(-86.234, address.getLatitude());
assert_equals(46.234, address.getLongitude());
}


What does this test do? Which lines of code are being tested? Ok, lets try again with blank lines.

public static void testSomething()
{
Address address = new Address();
address.setName("The House");
address.setLine1("1234 Street Ave");
address.setCity("Cityville");
address.setCountry("US");

address = dao.geocode(address);

assert_equals(-86.234, address.getLatitude());
assert_equals(46.234, address.getLongitude());
}


Doesn't that help? A simple change and you can clearly see the three areas of your code.

I hear you shout "setup method", I know but junit sucks in that the only way to write enough tests with enough setup's is to have lots of separate test classes. Certainly go that way if you have a complex class to test but simpler stuff can be done in one class with a little setup and tests with blank lines.

OK, what is the future of these blank lines? Well, Ruby has unit test libraries like Shoulda that make these concepts easy to express.

context "an address" do

setup do
@address = Address.new(
:name => "The House",
:line1 => "1234 Street Ave",
:city => "Cityville",
:country => "US"
)
end

should "be geocoded to a specific lat and long" do

@address = @address.geocode

assert -86.234, @address.latitude
assert 46.234, @address.longitude
end
end


This allows us to separate and describe the areas of our tests, however, common usage has taken this API to the next level which, I think speaks to the need for the original idea behind the blank lines.

context "an address" do

setup do
@address = Address.new(
:name => "The House",
:line1 => "1234 Street Ave",
:city => "Cityville",
:country => "US"
)
end

context "when geocoded" do

setup do
@address = @address.geocode
end

should "have a specific latitude" do
assert -86.234, @address.latitude
end

should "have a specific longitude" do
assert 46.234, @address.longitude
end
end
end


As you can see, the use of the sub-context for each "test" and the use of the setup method to actually run the test, allows us to isolate the specifics of what the test is all about and describe each area.

3/11/2009

Extreme Arguments and the Slippery Slope

So often we hear doubters ripping into ideas for their "potential" for destroying the world we know. Why the crazy extreme?

Most recently it was argued that code refactoring was bad because a programmer will spend so much time "perfecting" the code that they will never finish the project.

Another, states that we spend so much time unit testing that we don't write production code.

Another that you have to "corrupt" your beautiful domain design so much to make it testable that it makes OO irrelevant.

The Republicans are doing with the whole stimulus thing. A few billion spent means that we are on the slippery slope that results in the government owning every house in the country.

The "Slipper Slope" argument is the favorite argument of the person that doesn't have an argument for the proposal on the table.

Perhaps we should attempt assess the benefits of a proposal based on the proposal.

If you don't understand why something is bad you should not announce your opinion about your fears of what it might lead to. If it ends up leading there, announce away, until then, lets improve our world one step at a time.

Sticking to the facts is the single hardest thing we do. Especially, since facts can be a little slippery themselves.

2/02/2009

Garmin nuvi 760

I had a Gadget Frenzy this morning that worked out quite well. This years birthday produced a Garmin nuvi 760 which will prevent me from getting lost unless I am too busy playing with its features to notice the turns it is telling me about.

Oh, by the way, don't play with your Garmin while driving. This is the first and largest warning the device gives you, even ahead of the one about how the device may, or may not, get you where you want to go.

This device also includes an SD Card slot and mp3 player, plus Bluetooth phone headset connectivity, an FM transmitter and an audio jack. Oh, and a picture viewer, but what on early is the point if that.

Unfortunately the FM transmitter is no use in Cincinnati because all the radio stations are too close and powerful, however, the audio jack and an audio cassette adapter work wonderfully.

So, imagine the scene. Car stereo blaring but with no sound, just yet, a fresh set of podcasts loaded onto the SD Card and a willingness to connect as many pieces simultaneously as possible.

Select the media player on the Garmin, create a play list and hit play for the latest episode of Furled Sails sailing podcast.

Hit Back and select "Where To" enter my work address and press Go. The mp3 pauses and a nice lady with British accent says, "Please drive to the beginning of the route" and back to the sailing adventures. She even says route like the Brits say it, root, I had forgotten, how sweet.

My Treo 650 Bluetooth has already synced with the Garmin so if someone would call me, please, we can have all three audio streams passing through this device, hopefully, appropriately paused.

So my problem now is, do I continue listening to the Sailing podcast or switch over to my His Excellency: George Washington audio CD. Either way, I should arrive at my destination, precisely at 8:29am.

2/01/2009

Wordle - like a tag cloud but wordier

A Wordle creates a word cloud of your blog




Wordle: esumerfield.blogspot.com


or capture the state of the world at a single instant.




Wordle: cnn.com Feb 01, 2009

1/29/2009

Prototype Ajax Responders - Disabling

The Prototype Ajax API allows us to make requests to our web servers very easily. It also supports Responders that allow you to declare standard behaviors to occur before and after your Ajax calls, like show the spinning ball and dim the page and fun things like that.

The nice thing about this approach is that you don't have to worry about setting up these behaviors around your send and receive methods for each call. Instead, they just work, until you don't want them to.

I have a session timeout popup that needs to submit an Ajax request to tickle the server session stopping it from timing out. I do not want my standard behaviors occurring since this is not a modal interaction like all my other Ajax calls.

What I need to do is let my "responders" know that this is not a call that I want handled. This is my standard Ajax API that wraps the prototype call. As you can see, I am enforcing a json interface to the callback supplied by my application.

var Url = Class.create(
{
get: function(a_url, a_callback)
{
new Ajax.Request(a_url,
{
method :'get',
onSuccess : function(a_transport)
{
var json = eval(a_transport.responseText);
a_callback(a_transport, json);
}
});
}
});

The behaviors I am using are simple dimming of the background and the usual spinner image.

Ajax.Responders.register(
{
onCreate : function(a_request)
{
if (Ajax.activeRequestCount >= 1)
{
document.body.addClassName('ajax-processing');
new Popup('spinning_wait',null,
{
position: 'screen',
modal:true,
effect: 'blink'
}).show();
}
},
onComplete : function(a_request)
{
if (Ajax.activeRequestCount == 0)
{
$('spinning_wait').popup.hide();
document.body.removeClassName('ajax-processing');
}
}
});

So the problem is how do I specify, at call time, whether a specific Ajax call should be modal or not. Fortunately, the Prototype library passes the options to your Responders so that you can push in variables as you like.

To do this add your own options to your Prototype Ajax call.

new Ajax.Request(a_url,
{
my_custom_modal_option: true,
...
});

And in your handlers you can access this custom option.

onCreate : function(a_request)
{
if (a_request.options.my_custom_modal_option)
{
...
}
}

You can of coarse pass in any property name to drive any kind of behavior you like.

1/24/2009

2D, 3D and 4D Languages

If you are looking for something about graphics, then go away. Nothing of interest here.

I want to coin some terms that allow us to describe the languages we use. Nothing fancy but we might find it useful to limit the pro/con discussions and abstract them to something simpler.

We have talked bout 3rd Generation and 4th Generation languages to allow us to conceptualize the abstractions at the language level as opposed the class level. 4G languages are still being sold by those after some money but continue to be generally despised by programmers that can't make them do what they need.

OK, so why add the concept of a dimension here? Well, it probably has something to do with how my mind works and is not necessarily anything anyone else might share but when you say "refactor these lines into another method" I see that as a vertical or horizontal shift in behavior. Perhaps they are being generalized into a base class, vertical obviously, or moved into a delegate class that would be a right shift. These are 2D movements performed in all languages but C, for example, is limited to these kinds of adjustments.

Some languages are able to move along the Z axis. Object Oriented languages add to the 2D shifts the ability to distribute behaviors across instances, while not being able to vary behavior along this axis they are varying state and therefore execution paths vary by vertical plane. Each layer represents a keenly scoped set of behaviors driven by the state passed in. These are cones of execution, from a single method entry point at the tip of the cone, the state is distributed out across a set of associated instances to apply the appropriate behavior.

These 3D models become more complicated when you consider how some line of code inside a cone might throw an exception that provides a pipe to some layer of your application, in-front-of and left-of the throw point. It produces a hole in the side of the cone where flow can pass to another location.

Cones are contained within other cones of coarse, the applications main method being the pointy end of the outer cone. The API design rules we apply like no globals, no leaky abstractions, scope actions on state within their own class, all go to explain why no cone sides should ever intersect.

If you are still with me, then on we move to the 4th Dimension. I don't know how you conceive this in real space but I tend to look at the time dimension as a set of invisibility cloaks. As you move forward throw the cloaks, the last set of 3D stuff you were looking at disappears and another set appears. Presumably, we could move backwards to start seeing back in time.

Well Ruby, and other dynamic languages, have started playing with this dimension. Each instance, executing it's methods in it's cone, can be changed at runtime. A call to File.new here is different from the same call there. This allows us to evolve what is being executed based on state, time or idle whim. Code is data, data is code.

Now these concepts have some evolution ahead of them since these changes are made at "indiscreet points" at the moment. So I have to make the change and then execute that change. I can't encapsulate a change and an execution into a single language concept but these are just the semantics we play with today.

Behind each invisibility cloak is a 3D model of a runtime. Each model contains a set of finite behaviors and their changing state. Any statement that mutates it's own behavior, creates an invisibility cloak.

Don't confuse these with threads. Threads are shiny, sparkly little stars, like the sparklers from fireworks night, that run around your 3D cones doing stuff. There may be many of these things in a single 2D or 3D model, all buzzy and excitable. Some running around the same cone, trying to find your threading bugs for you but as long as your cones don't have cracks you will be fine.

When you hear Ruby programmers arguing about that there are no static methods in Ruby, what they are saying is that Ruby is a 4D language and the person they are arguing with only knows 3D languages. It's just like the old arguments that prompted 2D experienced people to say that we could do anything in C that you could do in C++. Yes, I used to argue that one back in the day. Fundamentally true only because it's also true that you can build a house with matchsticks if you really, really wanted to.

Ruby offers far more than just it's 4D features. Open classes, modules and closures are different ways to describe static, 3D concepts. A language becomes 4D when it can vary it's behavior at runtime. This isn't a new concept on it's own. I used to write basic programs that added code as it ran 20 years ago but this is more than this simple concept.

When we look at programming we talk less about the detailed syntax of how features are coded and more at the best constructs that survive change and optimize re-usability. We don't have many strategies defining how to mutate code as it runs to augment the runtime model that is executing.

The best proof that I don't know what I am doing in 4D is to look at the invisible cloak. I think this shape needs to change to better describe the scoped change that a piece of behavior might adopt.

I wonder what 5D means?

1/22/2009

BDD test framework Shoulda

Behavior Driven Development is an interesting slant on testing. There appear to be many opinions on its advantages and disadvantages. At the end of the day, if you are testing, you have already won.

So, the question is, how can you tweak your method to improve on your bugs-per-line-of-code metric. This post isn't about that because I have no idea if BDD or Shoulda will help.

Shoulda is an alternative BDD framework to RSpec that has been argued about for so long. I can't help you with that either.

Instead, I just started using Shoulda in a Rails app so thought I would share some complaints, because being constructive is just too much work.

I switch a simple controller test over to Shoulda and it ran and passed but the original 3 tests that used to pass are now reported as "0 tests, 0 failures, 0 errors". While I proved that if there was an error it did explain precisely what was wrong to me, this 0 tests thing is severely demotivating. It is amazing how watching the number of tests grow in your project can encourage you to continue to strive for perfection.

IDE integration is always a problem with new stuff. NetBeans allows me to run a single test case with ctrl-shift F6 which is convenient if you have few that are suddenly failing. No such luck with the Shoulda version, all tests all the time.

However, all this is trivia compared to being able to do something like this:

require 'test/unit'
require 'shoulda'

class Lion
def speak
"rarrrr hickup"
end
end

class TestLion < Test::Unit::TestCase

context "the lion" do
setup do
@lion = Lion.new
end

should "say rarrr" do
assert_equal "rarrr", @lion.speak
end
end
end

and get this explanation of what you did wrong.

1) Failure:
test: the lion should say rarrr. (TestLion):
<"rarrrr"> expected but was <"rarrr hickup">.

Craft your feedback as carefully as you craft your output.