Liz Douglass

Archive for November 2009

Frenzy Fixtures in Scala

leave a comment »

Following on from my post about Friday Feedback Frenzies, Mark, Ben and I looked at how to work out frenzy pairs. The idea with the frenzies is that you exchange feedback with two people each week, and that you rotate the people that you do this with. When I have organised these previously I have generally just picked people at random. Mark, Ben and I decided to generate a frenzy fixture (if you will).

Mark came up with the idea of using something like a football/tennis game scheduling algorithm. We found a Round Robin cyclic algorithm to get us started. Our first step was to get this algorithm working in Scala:

      val numberOfPlayers = 12
      for (round <- 1 to 11) {
        for (court <- 1 to 6) {
          print((if(court == 1) 1 else (round + court - 2) % (numberOfPlayers - 1) + 2),
                (numberOfPlayers - 1 + round - court) % (numberOfPlayers - 1) + 2)
        }
        println()
      }

The output from this is below. Each row represents a round and each bracketed pair in a row represents a match-up of two players on a court.

(1,2)(3,12)(4,11)(5,10)(6,9)(7,8)
(1,3)(4,2)(5,12)(6,11)(7,10)(8,9)
(1,4)(5,3)(6,2)(7,12)(8,11)(9,10)
(1,5)(6,4)(7,3)(8,2)(9,12)(10,11)
(1,6)(7,5)(8,4)(9,3)(10,2)(11,12)
(1,7)(8,6)(9,5)(10,4)(11,3)(12,2)
(1,8)(9,7)(10,6)(11,5)(12,4)(2,3)
(1,9)(10,8)(11,7)(12,6)(2,5)(3,4)
(1,10)(11,9)(12,8)(2,7)(3,6)(4,5)
(1,11)(12,10)(2,9)(3,8)(4,7)(5,6)
(1,12)(2,11)(3,10)(4,9)(5,8)(6,7)

Next we moved from everything being 1 indexed to being 0 indexed. We also changed the fixed player, who always plays on court 0, to be the last one in the player list. This was done only because it made the loops more readable:

      val numberOfPlayers = 12
      for (round <- 0 to 10) {
        for (court <- 0 to numberOfPlayers/2 - 1) {
          print(((if(court == 0) numberOfPlayers - 1 else (court + round) % (numberOfPlayers - 1))),
                (((numberOfPlayers - 1) - court + round) % (numberOfPlayers - 1)))
        }
        println()
      }

Then the output was:

(11,0)(1,10)(2,9)(3,8)(4,7)(5,6)
(11,1)(2,0)(3,10)(4,9)(5,8)(6,7)
(11,2)(3,1)(4,0)(5,10)(6,9)(7,8)
(11,3)(4,2)(5,1)(6,0)(7,10)(8,9)
(11,4)(5,3)(6,2)(7,1)(8,0)(9,10)
(11,5)(6,4)(7,3)(8,2)(9,1)(10,0)
(11,6)(7,5)(8,4)(9,3)(10,2)(0,1)
(11,7)(8,6)(9,5)(10,4)(0,3)(1,2)
(11,8)(9,7)(10,6)(0,5)(1,4)(2,3)
(11,9)(10,8)(0,7)(1,6)(2,5)(3,4)
(11,10)(0,9)(1,8)(2,7)(3,6)(4,5)

Our next step was to switch domains from sports to feedback frenzies:

val participants = 12
val weeks = 10
for (frenzy <- 0 until weeks) {
  for (pair <- 0 until participants/2) {
    print(((if(pair == 0) participants - 1 else (pair + frenzy) % (participants - 1))),
          (((participants - 1) - pair + frenzy) % (participants - 1)))
  }
  println()
}

Then we changed to creating a collection of all the pairs:

      val participants = 12
      val weeks = 10
      val frenzyPairs = for {
        frenzy <- 0 until weeks
        pair <- 0 until participants/2
      } yield (((if(pair == 0) participants - 1 else (pair + frenzy) % (participants - 1))),
                (((participants - 1) - pair + frenzy) % (participants - 1)))
      frenzyPairs.foreach(print)
    }

And the output…

RangeM((11,0), (1,10), (2,9), (3,8), (4,7), (5,6))
RangeM((11,1), (2,0), (3,10), (4,9), (5,8), (6,7))
RangeM((11,2), (3,1), (4,0), (5,10), (6,9), (7,8))
RangeM((11,3), (4,2), (5,1), (6,0), (7,10), (8,9))
RangeM((11,4), (5,3), (6,2), (7,1), (8,0), (9,10))
RangeM((11,5), (6,4), (7,3), (8,2), (9,1), (10,0))
RangeM((11,6), (7,5), (8,4), (9,3), (10,2), (0,1))
RangeM((11,7), (8,6), (9,5), (10,4), (0,3), (1,2))
RangeM((11,8), (9,7), (10,6), (0,5), (1,4), (2,3))
RangeM((11,9), (10,8), (0,7), (1,6), (2,5), (3,4))

As Ben quite rightly pointed out if we take two rows a time, then each person will exchange feedback with two people in the same frenzy. Our final step was to group each pair of successive rows. To do this we first moved to having two nested for loops. We thought that this would make it easier to do the grouping, but it ended up being redundant. Here our final version of the frenzy fixture generator:

      val participants = 12
      val rounds = 10
      val frenzyPairs = for (frenzy <- 0 until rounds)
                      yield for(pair <- 0 until participants/2)
                            yield (((if(pair == 0) participants - 1 else (pair + frenzy) % (participants - 1))),
                                  (((participants - 1) - pair + frenzy) % (participants - 1)))

      val (evenOnes,oddOnes) = frenzyPairs.toList.zipWithIndex.partition(_._2%2 == 0)
      evenOnes.zip(oddOnes).foreach(println)

Our final output was:

((RangeM((11,0), (1,10), (2,9), (3,8), (4,7), (5,6)),0),(RangeM((11,1), (2,0), (3,10), (4,9), (5,8), (6,7)),1))
((RangeM((11,2), (3,1), (4,0), (5,10), (6,9), (7,8)),2),(RangeM((11,3), (4,2), (5,1), (6,0), (7,10), (8,9)),3))
((RangeM((11,4), (5,3), (6,2), (7,1), (8,0), (9,10)),4),(RangeM((11,5), (6,4), (7,3), (8,2), (9,1), (10,0)),5))
((RangeM((11,6), (7,5), (8,4), (9,3), (10,2), (0,1)),6),(RangeM((11,7), (8,6), (9,5), (10,4), (0,3), (1,2)),7))
((RangeM((11,8), (9,7), (10,6), (0,5), (1,4), (2,3)),8),(RangeM((11,9), (10,8), (0,7), (1,6), (2,5), (3,4)),9))

The end result could be tidied up a little but it does provide us with a frenzy fixture for a given number of participants. Given more time we would have used names for participants rather than just numbers.

Advertisements

Written by lizdouglass

November 18, 2009 at 11:52 am

Posted in Uncategorized

Tagged with ,

Friday Feedback Frenzies

with 5 comments

The Friday Feedback Frenzies (cheesy name I know) is something I introduced on our project team about 6 weeks ago. The idea is that on a Friday afternoon every week (or every other week) you give and receive feedback from a couple of people on the project team. Each week you rotate the people that you do this with.


Why frenzy?

In his first post about feedback Pat Kua discussed the idea that we should invite feedback. I agree with him on this. I also would like to add that we should invite feedback from everyone on the project team. The trouble is – and perhaps this is not true across all cultures (project or otherwise) – I’ve not seen this happen.

Not giving and receiving feedback costs teams and relationships in all sorts of ways. As a developer, the pair programming dynamic is one of the most obvious places where the impact of not giving feedback is evident. In my experience people that are finding pairing with a team member difficult opt for silence, passive aggressiveness or just plain ol’ aggressiveness. I’m the first to admit that I’ve done all of these things on occasion. I’ve found that regularly giving and receiving feedback is a much healthier alternative.


So how is it going (in my opinion)?

Overall the frenzies have been going well. One person in our team commented at our last retro that he thought team communication had improved since they started.


The mechanics…

We are still maturing the process of running the frenzies. Initially we began by exchanging feedback with the people that we had worked most closely with that week. This was ok but there was some hesitation in the group because people had to approach one another. We’ve since tried more of a speed dating style – everyone is given the names of two people that they will exchange feedback with the day before.
The effort and ceremony around participating in the frenzy is not supposed to be onerous – grab a meeting room or a bench in the kitchen area and have a quick chat one-on-one. I have tended to pre-prepare some dot points for each person that I am giving feedback to – some for strengthening confidence and some for improving effectiveness.


What’s going well?

  • One thing I really like about receiving feedback regularly is that it can be incorporated very quickly. It’s not as useful to get feedback on how you could improve after the project as finished at annual review time.
  • The feedback is more specific. How many times have you scratched your head trying to think of a good example to support your feedback? Feedback that covers a short window of a few days/weeks means that you can have conversations that include a lot of detail about specific events, like: ‘remember when we were pairing on story ABC and then….’.


What’s not going so well?

I think that there are two areas that we still need to work on in the near term:

  • First up, the feedback process seems to take a long time. I think this is partly related to the fact that some people have worked on the project for a few months and have not previously exchanged feedback.  I’ve not made attempts to curb the time because obviously there is a lot to cover. I think this will come down as the feedback cycle time decreases.
  • We have tended to skip the feedback sessions if there are other meetings on. I don’t think this is a good pattern and is related to the fact that our frenzies seem to be at a less-than-frenzied pace.

So why frenzy?
The idea of having a regular event is to make giving and receiving feedback something that is part of normal team life. I understand that having such a ritual may be seen as contrived and as adding process overhead. This is not the intention and my hope is that the ‘scheduled’ aspect disappears entirely over time as the team just does it naturally. This idea is to promote the feedback culture.

Written by lizdouglass

November 16, 2009 at 9:45 am

Posted in Uncategorized