Pages

Saturday, December 4, 2010

On Giving Useful Feedback

Successful agile teams do well, in part, because of the types and amount of communication they use. One place where communication is most important and comes with significant risk is giving "constructive criticism" or "corrective" feedback. I've noticed two patterns of feedback that don't work well: indirect or soft feedback, focused on not hurting the recipient's feelings and unnecessarily frank, or even blunt feedback given with little regard for the recipient's feelings. The first pattern tends to communicate insufficient information and the second pattern, while containing full information, is not presented in a manner that that is often met with defensiveness.

A friend told me about a pattern of giving feedback that I think does a good job of avoiding the pitfalls of the first two patterns. I didn't ask him where he learned it, and I could only find one reference to it: http://bit.ly/dEwGw4 The pattern is called "what-what-why" and it works like this:
  • Tell what you didn't/don't like or what you think didn't/doesn't work well
  • Tell what you would like instead
  • Tell why you think your suggestion would be more effective
For example:
  • I don't like how our team is spread out and in individual cubicles
  • I'd like it if we moved into one room and sat at a cluster of tables
  • We'd "overhear" important information and there would be fewer barriers to asking each other questions.
Or:
  • One thing that didn't work for me in the retrospective was when you would say something before someone else was finished speaking
  • I'd like it if you allow other people to finish their point and then add yours
  • I think the meeting would flow more smoothly and everyone would that they would get their chance to be fully heard.
There are a couple things I really like about giving feedback this way. First, it makes it clear that this is what I don't like and what I want instead. If I were to instead say: "You know, it might be better if you let people finish their point..." or "Don't interrupt people...", I'm not really owning that this feedback is coming from me. Second, it focuses on the desired benefit instead of focusing on anything about the person, making it less likely that they will take what I am saying personally and become defensive. And finally, I don't have to spend a lot of time thinking about how I am going to give feedback or worry much about how the person might take it. As soon as I see something that I'd like to be different, I can give the what-what-why and address the issue right away. This is great because communication is most effective when it happens early.

I recognize, however, that not all feedback is intended to cause a different outcome. Sometimes someone is doing something that I like or that I think is working well and I want to let that person know. In that situation, I use a "what-why" pattern:
  • Tell what you like/liked or what you think works/worked well
  • Tell why you like it or think it works well
For instance:
  • On the story wall, I like how you've given each team member a tag that they can put on the story that they are working on.
  • Not only does it let everyone know what everyone else is working on, but it's a good way of reminding people to only work on one story at a time.
Like what-what-why, this pattern lets me own that this is my viewpoint, it focuses on the process and outcome rather than the person, and it's a template that lets me communicate as soon as I recognize that I want to.

If you try what-what-why or what-why, I'd be interested to hear your results. Do you have similar feedback patterns that you find useful?

Sunday, October 24, 2010

Another Thought on Certification

Yesterday at 1DevDayDetroit, Virender Ajmani gave a very interesting talk about Google Map mashups. (If you missed his talk, check out his blog or download his slides.

Besides his very interesting content, he mentioned something that else that caught my attention - the Google Qualified Developer program. It's a different approach to the question of developer certification (which I know is a hot topic in the Agile world in general and at the Agile Skills Project in particular). Google's program is free, and it focuses on accomplishments, references, community participation, and knowledge. If you become certified, you get a badge for your blog.

To be certified in a particular Google API (Chrome extensions, Maps, etc.), a developer must earn at least 3000 of the available 5000 points towards that API in any. She/he can earn points in the following ways:
- showing proof of their work (working code) - up to 1000 points
- providing references (from paying clients) - up to 1000 points
- demonstrate community participation - up to 1000 points
- take the online exam - up to 2000 points

What I like about this approach is that no one type of mastery is enough to earn certification. For instance, a developer who aces the exam can not be certified without other evidence of their competence.

I wonder what an Agile badge in this style would be like.

There are already Scrum exams. Perhaps taking one of them would earn some points. There would be a cap on how many points could be earned through exams, and exam points might expire after a certain time.

I'm not sure how working code is necessarily any indication of someone's skill in Agile, so I think we'd have to come up with something else.

Attending certain classes might be worth points. I know there's been a lot of talk about how taking a class doesn't necessarily mean a person learned anything, and I agree. So perhaps any given class would be only worth a small amount, say 200-300 points, and it would only count if you had taken the course in the past year, and only 1000 points could be earned by attending classes.

Certainly some Agile developers could provide references from customers, and capping the number of points from references would reduce the chance and affect of quid pro quo referrals. Developers who don't have professional references could earn their points in some of the other ways.

And maybe book quests or webinar quests could provide a few points, perhaps with a fairly low cap.

I know there's a non-trivial amount of administration that would be required to manage a program like this. Please join the discussion on the Agile Skills Project Google Group.

Wednesday, September 8, 2010

Scrum Developer Certification is Now Real

Just over a week ago, I got the following email from Chet Hendrickson:

Hello ADS Course Participants,

The mechanism for applying for the Scrum Alliance Scrum
Developer Certification is now available.
The Agile Developer
Skills course you took with us satisfies
the Basic Developer Skills
portion of
the certification requirement. If you also hold a
Certified ScrumMaster (CSM) certification you may now apply
for the
CSD.

The application can be found at:
http://www.scrumalliance.org/resources/1809


So whatever your view about the value of certification, it's happening. As for me, I'm not a CSM, so I won't be applying for a CSD any time soon.

Wednesday, May 19, 2010

Thoughts on my experiences at the second Scrum Alliance CSD course.

Dave Nicolette recently blogged about how he has joined the ranks of the Certified Scrum Developers, by being a CSM and completing the Scrum Alliance CSD course taught in Cleveland by Ron Jeffries and Chet Hendrickson. I took the same course one week later in Ann Arbor. Unlike Dave, I'm not a CSM yet, so I don't qualify as a Certified Scrum Developer - I'm not going to weigh in on the pros and cons of "certification".

Even though the CSM was offered the two days immediately before the CSD course, I chose to only take the CSD course right now. My current focus is on improving my development skills, and the CSD course fits right in with that. It was a great opportunity to practice TDD, Pair Programming, and Scrum under Ron and Chet's observing eyes.

Unlike the Cleveland class, the Ann Arbor only had a few "known" participants. Present were Rich Garzaniti, a long-time eXtreme Programmer and member of the Chrysler Comprehensive Compensation project (C3) and Nayan Hajratwala, agile and lean coach and speaker. Dianne Marsh, co-founder of SRT Solutions, was also present, although she does not specifically focus her work on agile. The rest of us are seasoned developers with agile experience that ranged from never having done TDD to actively learning TDD outside of work and in the early stages of trying to introduce small agile practices into their workplace. I'm a long-time developer, involved in the Agile Skills Project, a rabid Code Retreat attendee, but I have little agile experience on the job.

Like the Cleveland class, we had difficulty with infrastructure that held us back, and as Dave said, that's not unexpected. Still, one team spent basically an entire 4-hour iteration (the course only scheduled 3 iterations in all) on infrastructure problems. The team I was on only spent half of an iteration on infrastructure problems (Without Nayan's familiarity with Maven, Hudson, Eclipse, and FitNesse, I suspect it would have also taken us a whole iteration too). In our class retrospective, we decided that there was some merit in having infrastructure issues as part of the class, as it gives a taste of what it really takes to set up tools for an agile project. We also decided that whatever steps are taken to reduce such issues, there will always be some, and they may provide enough learning.

In contrast to Ron's assessment that the Cleveland class produced the least results he'd ever seen (the CSD course is based on Ron & Chet's ADS course), Ron said that we, the Ann Arbor class produced the most "done" code he'd ever seen. In Dave's blog post, he gives an extended analysis of his class's results. I won't be discussing our results in that level of detail. Briefly, I attribute our success to having executed agile practices well. Here is a list of some things I think we did well:
  • Sprint planning meetings that involved a PO
  • TDD that focused on results and had a good balance of strong assertions and deferring to the other partner
  • Frequent Pair Rotation
  • Communication between pairs
  • Hourly Standup Meetings (remember, iterations were 4 hours)
  • Retrospectives that produced actual to-do items for improving our process
  • Doing the things from our retrospectives that we said we'd do
  • Lots of time with Ron & Chet as POs.
While we certainly were not immune from making assumptions about stories, we did ask a lot of questions about the cards during our planning meetings. When the Ron or Chet gave high priority to stories that we thought would take a lot of time, we suggested other stories that we thought would generate some value more quickly or we requested that some stories be split. We were conservative with our commitments.

Additionally, I think the goals the Ann Arbor participants had for the class were well suited to creating "done" stories. While I think Rich and Nayan wanted to refine their already strong agile craft, the rest of us seemed to be experienced developers who either want to become agile or to become more agile. While Nayan seemed to play a dual role as contributing developer and coach on my team, I think we all took responsibility for delivering quality results and improving our process.

All of that is not to say that we didn't have our share of problems. We realized late in the course that we would have saved some time talking in circles if we had drawn simple design ideas on a white board. Additionally, my team might have been able to show more value to the POs if we had implemented fewer file operations and left IO as an abstraction. In our code review, our team found some early design decisions that would have caused difficulties later, were we to have continued developing the product.


There's an old saw that says we learn more from failure than we do from success. That feels true for me regarding this course. I'm struggling to find any real "gems" of learning. For me, the biggest benefit of the course was the practicing - practicing technical tasks and practicing improving our process. Since I don't pair at my current job, the course gave me a good chance to look at how I pair and think about ways that I can be a better pair. And I did learn to use FitNesse and Hudson, which I had not used before.

And finally, I left the class with a renewed hope for our profession and my career. Being in a class of developers who seem really committed to delivering value and improving their craft was tonic for the pain and exasperation that I've experienced in past projects that had all the classic failures.

Monday, March 29, 2010

My Venture into JBehave via Conway's Game of Life

Having used Conway's Game of Life (CGoL) at several CodeRetreats* to practice Test Driven Design (TDD), I thought I would revisit it when I took my first steps into Behavior Driven Development (BDD) with JBehave.

I downloaded JBehave 2.5 and refreshed my memory of the GoL rules:
  1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
  2. Any live cell with more than three live neighbours dies, as if by overcrowding.
  3. Any live cell with two or three live neighbours lives on to the next generation.
  4. Any dead cell with exactly three live neighbours becomes a live cell.
What I love about using GoL for learning BDD is that the rules are practically already written as Given-When-Then scenarios. Just minor tweaks (including changing to the US spelling of neighbor) gave me:
  1. Given a live cell with fewer than two live neighbors, Then the cell is dead.
  2. Given a live cell with more than three live neighbors, Then the cell is dead.
  3. Given a live cell with two or three live neighbors, Then the cell is dead.
  4. Given a dead cell with exactly three live neighbors, Then the cell is alive.
All that's missing is a "When". All 4 rules have the same "When", which is "When I calculate the next generation". Taking that into account, I get:
  1. Given a live cell with fewer than two live neighbors, When I calculate the next generation, Then the cell is dead.
  2. Given a live cell with more than three live neighbors, When I calculate the next generation, Then the cell is dead.
  3. Given a live cell with two or three live neighbors, When I calculate the next generation, Then the cell is dead.
  4. Given a dead cell with exactly three live neighbors, When I calculate the next generation, Then the cell is alive.
Since any given rule could only have 9 different cases (0-8 alive neighbors) I decided that, rather than deal with the logic of "less than"/"fewer than"/"exactly", I would spell out every specific condition that meets a rule.

JBehave expects scenarios to have separate lines for Given, When, and Then. Rule #1 can be completely expressed as:

Scenario:
Given Rule 1: alive cell with 0 neighbors
When I calculate the next generation
Then the cell should be dead

Scenario
Given Rule 1: alive cell with 0 neighbors
When I calculate the next generation
Then the cell should be dead

I've written the variables in the scenario in bold here. That will become more clear later. I inserted "Rule 1" into the given just to make it easier to know what rule I'm on when a scenario fails.

I wrote scenarios for every condition for all 4 rules (it came out to 18) and put them in a file named "i_can_calculate_the_next_generation". JBehave requires scenarios be named all lower case with words separated by underscores. You can see all the scenarios and all the source code in my github repo for this project.

(If you're a Windows developer and you don't like the idea of files without extensions, I found a blog post that showed a customization that allowed JBehave to read ".scenario" files instead of files with no extension, but I decided not to bother with that for this first experiment.)

Once I have my scenarios written, it's time to code. JBehave requires that the class corresponding to the scenarios be the same words, but camel-case, and without underscores, so I created ICanCalculateTheNextGeneration.java

The entire class is:
import org.jbehave.scenario.Scenario;

public class ICanCalculateTheNextGeneration extends Scenario {
public ICanCalculateTheNextGeneration(){
super(new RuleEngineSteps());
}
}
Now for the meat of the code, starting with the implementation of RuleEngineSteps:

@Given("Rule $ruleNum: $aliveVal cell with $aliveCount neighbors")
public void aliveOrDeadCellWithPossiblySomeAliveNeighbors(int ruleNum, String initialLiveState, int numberOfAliveNeighbors){
ruleEngine = new ConwayRuleEngine();
cell = new Cell(initialLiveState.equals("alive"), numberOfAliveNeighbors);
}

@When ("I calculate the next generation")
public void iCalculateTheNextGeneration() {
ruleEngine.CalculateTheNextGeneration(cell);
}

@Then ("the cell should be $resultingAliveState")
public void theCellShouldBe(String expectedAliveState){
String actualAliveState = "alive";
if (!cell.isAlive()){
actualAliveState = "dead";
}
Assert.assertEquals(expectedAliveState, actualAliveState);
}


Look for a moment at how variables are used between the scenarios and the code. Remember I had: "Then the cell should be dead"? Look at the corresponding @Then in the code:
@Then ("the cell should be $resultingAliveState")
public void theCellShouldBe(String expectedAliveState){
Whatever I want as variable in the scenario, for example dead above, I name a variable starting with "$" in the attribute line and use the same name (without "$") as the parameter to the method.

Cell.java is basically only setters and getters. ConwayRuleEngine.java is where the business logic lives (Excuse the pun). Initially, CalculateTheNextGeneration() will do nothing.

When I run ICanCalculateTheNextGeneration.java as a JUnit test in Eclipse. I get a red bar. In the console I see:
(i_can_calculate_the_next_generation)
Scenario:
Given Rule 1: alive cell with 0 neighbors
When I calculate the next generation
Then the cell should be dead (FAILED)
and other failures. All that's left is the implementation of the business logic, which I'll leave as an exercise for you. (Or you can look at my code).

Once I got my code working, I refactored it. I've tried to reduce duplication and make the code very clean. I'd appreciate any comments you have.

Finally, I invite you to check out the Agile Skills Project, a non-commercial, community-based project which aims to establish a common baseline of the skills an Agile developer needs to have, skills possibly including TDD and BDD.

---------------------------
*A plug for CodeRetreat if you're not familiar with it: Patrick Welsh and Corey Haines have created a kind of one-day coding dojo that gives software developers who want to improve their craft a chance to practice agile skills like Pair Programming and TDD. We do 40 minute iterations on Conway's Game of Life, have mini-retrospectives, throw out our code before the next iteration, and have a retrospective of the whole event at the end of the day. CodeRetreats have been held in Java and Ruby (that I know of) and in several countries. If you haven't been to one, I encourage you to go to one.



Wednesday, March 3, 2010

Why do we Pair Program?

One of the most controversial agile practices has to be Pair Programming. Matt Wynne has a blog post that lists several personae and why they don't want to pair program. It's a preview of what he presented at Agile 2009.

Other people have written about the benefits of successful pair programming, which is an after-the-fact analysis. Right now I'm going to look at why we pair program, which is about intention

I recently started thinking about why we pair program. What is our intention in using this practice? I came to the conclusion that Pair Programming promotes many of the Seven Skill Pillars named by the Agile Skills Project.

Pillar: Collaboration
Pair programming is specifically listed as a skill of the Collaboration pillar, but it also supports Collective Ownership by preventing silos of knowledge (technical or domain knowledge) from forming.

Pillar: Technical Excellence
Working directly with another developer reinforces good development practices, and two sets of eyes on code lets fewer mistakes make their way into the product.

Pillar: Self Improvement
Pair programming sets a tone for a culture of continuous learning by creating ongoing opportunities for co-mentoring.

Pillar: Supportive Culture
The transparency around each developer's skill level that comes from programming in front of each other gives a developer an opportunity to be tolerant and encouraging, knowing they will receive the same treatment in return.

Pillar: Confidence
By supporting each other in the practices of Continous Integration and Test-Driven Design, and by having a design and implementation that is jointly created, a pair can know they are producing quality code.

Saturday, January 16, 2010

CodeMash Precompiler Session # 1 - Ruby Koans

As I mentioned in my last post, I recently returned from CodeMash 2010, where I attended two PreCompiler sessions. For the morning session, I attended "The Ruby Koans, Learning Ruby One Test at a Time with Joe O'Brien and Jim Weirich" which taught Ruby syntax and how to write tests in Ruby. (Joe also gave an excellent and extremely popular talk called: "Refactoring the Programmer"

The word "koan" comes from Zen Buddhism. As I understand it, Jim and Joe called their talk "Ruby Koans" because of their unique style of teaching that relies as much on mystery and intuition as it does on rational thinking.

Jim has asked participants in the CodeMash session to show the koans to someone else, so I encourage you to look at them. You can try the koans yourself as follows:

(1) Have a working version of Ruby:
- Windows: Install from: http://rubyforge.org/frs/download.php/66871/rubyinstaller-1.8.6-p383-rc1.exe
- Macs: OS X comes preloaded on Macs so you are ready to go.
- Linux Users: Use apt-get, or whatever is appropriate for your system

(2) Download the Ruby Koans and install into a working directory:
- http://cloud.github.com/downloads/edgecase/ruby_koans/rubykoans.zip

The file README.rdoc is a text file that explains the concept, tells how to get started, and gives contact information.

To set up for the exercise: unzip the koans, open a command-prompt, and cd to the directory containing the koans. The exercise starts at the most simple level possible, but if you complete the koans, you will learn most of the Ruby syntax and see examples of how Ruby behaves at edge cases.

To start the exersise, give the command:
ruby path_to_enlightenment.rb
You should see the following result:

Thinking AboutAsserts
test_assert_truth has damaged your karma.

You have not yet reached enlightenment ...
is not true.

Please meditate on the following code:
./about_asserts.rb:10:in `test_assert_truth'
path_to_enlightenment.rb:28
The line " is not true." gives a hint as to why the test failed.
The line after the "Please meditate..." line tells what line of code the test failed on.

Looking in the file about_asserts.rb around line 10, we see:
def test_assert_truth
assert false # This should be true
end
In Ruby, def/end declares a method, and the word: "test_" at the start of the method name declares it as a test. The comment is a hint from Joe that the test fails, in this case rather obviously, because it is asserting false. So this koan demonstrates the a test in its simplest form, one that asserts a boolean condition. If you change false to true and run "ruby path_to_enlightenment.rb" again, that test will pass and the error you will see:
Thinking AboutAsserts
test_assert_truth has expanded your awareness.
test_assert_with_message has damaged your karma.

You have not yet reached enlightenment ...
This should be true -- Please fix this.
is not true.

Please meditate on the following code:
./about_asserts.rb:16:in `test_assert_with_message'
path_to_enlightenment.rb:28

So now the test_assert_truth test passes and the test_assert_with_message test is failing. The code for the second test is:
def test_assert_with_message
assert false, "This should be true -- Please fix this"
end
and we see where the "This should be true..." message comes from. Joe has now shown us what an assertion with an error message looks like. Again change false to true, rerun the ruby command and you'll see the next failing test.

The koans go on to present illustrations of control statements, hashes, scope, strings, arrays, inheritance, iteration and others language details. I don't think anyone at the PreCompiler finished all the exercises during that session - I sure didn't - but it's clear that I will know a lot about Ruby syntax when I do.


Finally if you have questions about the koans, you can reach Jim at his website http://onestepback.org/ or @jimweirich on Twitter. Or you can reach Joe at his website http://objo.com or @objo on Twitter

Back from CodeMash 2010

I just got back from a great experience at CodeMash 2010. This was my first CodeMash, and it will certainly not be my last. If you're a software developer and you've never gone to a CodeMash, I can't recommend it enough. (If you're a developer and you've already gone, I don't have to say anything because I know you'll be going back.) Besides all the technical goodness, there was lots of fun!

If you're not familiar with CodeMash, its home page describes it as a unique two (or optionally three) day event:
"... that will educate developers on current practices, methodologies and technology trends in variety of platforms and development languages such as Java, .NET, Ruby and PHP. Held [in] January, at the lush Kalahari Resort in Sandusky, Ohio, attendees will be able to attend a world-class technical conference amid Ohio's largest indoor waterpark.
There were also sessions on career development, TDD/BDD, Agile/Lean/Kanban methodologies, dynamic languages like F# and Scheme, development for mobile platforms like iPhone and Android, and too many more for me to list here. See the session list for more, and for detailed writeups and presenter bios.

This year, there were three keynote addresses and loads of software-development-related sponsors, the likes of Microsoft, Amazon, Compuware, RedGate, and ComponentOne gave talks, demonstrations, held raffles and gave away lots of swag.

But some of the most valuable experiences come from talking with other developers in the hallways, between sessions, at open space meetings organized by participants based on their interests, in the Coding Dojo room, and at the cocktail party.

I mentioned that CodeMash is two or optionally three days. They call the optional third day events, held the day before the official conference opens, the PreCompiler. The PreCompiler Sessions are 4 hour, hands-on, interactive labs. That's not to say that if you only attend the main conference you won't have a chance to sit down at a machine and try somethings out, but interactive sessions at the main conference are shorter (only about an hour) and tended to be less in-depth.

I attended 2 PreCompiler sessions, "The Ruby Koans, Learning Ruby One Test at a Time with Joe O'Brien and Jim Weirich" and "Practical T/BDD - Half Day Hands-on Lab with Phil Japikse"

I'll tell about these in subsequent blog posts.

Monday, January 11, 2010

Grand Rapids CodeRetreat ... but it's in Ruby

I'm a big fan of CodeRetreat. Besides being a fun day, it's a great way to practice agile things like: pair programming, supportive environment, software craftsmanship, TDD, retrospectives, courage, and so on. I think they are great events for both aspiring Agilists and experienced Agilists.

I read Jeremy Anderson's blog post about an upcoming CodeRetreat in Grand Rapids. I was all set to go when I read that it will be held in Ruby, and since I haven't used Ruby, I was discouraged. As much as I'd like to try it, I'm not sure how much time I'll have in my schedule before then.

Then I found TryRuby. It offers an interactive Ruby prompt and a follow-along tutorial, right in your browser! And there's another tutorial I found, Ruby in Twenty Minutes .

So I guess I'll have to revisit the sessions I planned to attend this week at CodeMash 2010 and see if there are beginner Ruby sessions. Perhaps, between them and some extra work during downtime, I'll pick up enough Ruby to feel comfortable attending the Grand Rapids Code Mash next month.