markhneedham/blog huggingface dataset:
Increasing team sizes: Collective unresponsibility
Date: 2011-02-16 18:00:52

After a few recent conversations with colleagues as well as my observations of several projects I'm coming to the conclusion that the way that people react in situations often differs significantly depending on whether they're working in a large or small team.

One of the most obvious ways that this manifests itself is when there comes a need for someone to volunteer to take care of something - be it a particular functional area, communication with the onshore team or something else.

In larger teams there often seems to be a noticeable silence as no-one or one of a very few people offer to do it.

There seem to be two theories about why this happens:

* People assume that because the team is so big someone else will almost certainly take care of it so they needn't bother.
* People assume that because the team is so big someone else is probably better placed than them to take care of it.

The problem that arises from people not taking care of things is that *they don't tend to feel as if they're an important part of the team which invariably means that they don't contribute as much as they could*.

From what I've noticed this type of thing doesn't seem to happen as much on on smaller teams - there are just things to do and they tend to get distributed amongst the people on the team.

The concept/stigma of 'volunteering' to do something isn't there.

I recently came across http://en.wikipedia.org/wiki/Lewin's_Equation[Lewin's Equation] which suggests the following:

____
Lewin's Equation, B=ƒ(P,E), is [\...] a heuristic designed by psychologist Kurt Lewin. It states that *Behavior is a function of the Person and his or her Environment*.
____

I think this is reasonably accurate and I've noticed people who were fairly anonymous in larger teams become amazingly effective when they were put on a much smaller one.

The 'agile' approach to software delivery tends to encourage smaller team sizes and the idea of creating collective responsibility seems to be a key part of why you'd want to do that.

A typical approach to achieving that would be to split the building of a system into smaller teams where each covered a specific stream of work.

The collective team will still need to work together at some stage to build the entire system but at least within their streams they can feel a sense of ownership.

From my experience it can sometimes be quite difficult to do that because it seems that all the streams of work are tightly coupled.

I think we need to really endeavour to find a way to break them up though because it will lead to a much happier team and most likely a more productive one.
ThoughtWorks University: Balancing helping and learning
Date: 2011-02-19 15:15:59

6 months after my first attempt to train one of the http://www.thoughtworks.com/thoughtworks-university[ThoughtWorks University] batches was cut short I'm back in Bangalore again and spent the first few days of this week pairing with the grads.

It's been interesting for me trying to balance how much I help and suggest ideas while still allowing them to learn at the same time.

At the moment I think I'm leaning too far towards helping and not realising until later on that my colleague hadn't quite understood why I'd suggested what I did and therefore *hadn't learnt anything from my suggestion*.

In one case we came across a similar problem later on in the day and I realised my colleague hadn't understood exactly what I meant before.

This time I let them run with it for a bit until they came to the realisation that their approach probably wasn't going to work.

They were then able to come to the solution that I'd been thinking about originally by themselves which I think is much more valuable than me telling them it up front.

A couple of times I've made the mistake of saying 'yeh I know' when they've pointed out that their approach isn't going to work but hopefully I'm getting better at being less smug and keeping my mouth shut!

The other interesting thing about letting them run with it for a bit even when I think I know better is that there have been occasions where I was wrong and we ended up with a better solution through their exploration.

We've got a few weeks until the next ThoughtWorks University starts but hopefully then I'll get even more chances to find the right balance between these two things.
Pair Programming: Doodling
Date: 2011-02-26 05:20:32

Another interesting pair programming 'technique' which I rediscovered while pairing with http://twitter.com/#!/priyaaank[Priyank] is that of doodling or drawing various parts of the solution when your pair is writing code.
image:{{<siteurl>}}/uploads/2011/02/doodling.jpg[Doodling,330]
I find that  this helps to stop my brain wondering off and lets me reflect on what we're doing from a higher level.

As an added bonus it also seems to allow me to http://www.markhneedham.com/blog/2011/02/20/communication-listening/[listen more effectively] to my pair.

From what I've noticed it works most effectively when the other person is reasonably comfortable with the code base and language which was certainly the case when I was pairing with Priyank.

I guess they also have to be reasonably comfortable with the idea that you're still listening even though you're not necessarily looking at everything that they type.

It doesn't work quite as well in other situations where you're playing more of a coaching role because you need to be more focused on the code that's being written and provide help with respect to syntax, libraries or context on the code base.

I don't remember noticing many other people doing this so though maybe this is just a solution for my http://en.wikipedia.org/wiki/Attention_deficit_hyperactivity_disorder[ADHD].
Books: Know why you're reading it 
Date: 2011-02-26 03:06:48

Something which I frequently forget while reading books is that it's actually quite useful to know exactly why you're reading it i.e. *what knowledge are you trying to gain by doing so*.

I noticed this again recently while reading http://www.pragprog.com/titles/jtrap/the-agile-samurai[The Agile Samurai] - it's one of the books we ask http://www.thoughtworks.com/thoughtworks-university[ThoughtWorks University] participants to read before they come to India.

Implicitly I knew that I just wanted to get a rough idea of what sort of things it's telling people but I somewhat foolishly just started reading it cover to cover.

I only realised that I'd been doing this when I'd got a third of the way through and realised that I hadn't really learnt that much since the book effectively describes the way that ThoughtWorks delivers projects.

In http://www.markhneedham.com/blog/2008/10/06/pragmatic-learning-and-thinking-book-review/[Pragmatic Learning and Thinking] Andy Hunt suggests the http://www.ic.arizona.edu/ic/wrightr/other/sq3r.html[SQ3R] reading comprehension method which I always forget about!

* Survey -- scan the table of contents and chapter summaries
* Question -- note any questions you have
* Read -- read in entirety
* Recite -- Summarise and take notes in your own words
* Review -- Re-read, expand notes, discuss with colleagues

I don't think it always needs to be quite as organised as this but I've certainly found it useful to scan the chapter headings and see which ones interest me and then skip the ones which don't seem worth reading.

When reading http://www.faqs.org/docs/artu/[The Art of Unix Programming] I felt that I was learning a lot of different things for the first ten chapters or so but then it started to get quite boring for me so I skimmed the rest of the book and ended up reading just half of the chapters completely.

The amusing thing for me is that I knew about this technique a couple of years ago but I still don't use it which I think that comes down to having a bit of a psychological thing about needing to finish books.

At the moment I have around 15 books which I've partially read and at the back of my mind I know that I want to go and read the rest of them even though there will undoubtably be varying returns from doing that!

I need to just let them go...
University coding
Date: 2011-02-06 16:57:14

We went to do some university recruitment recently and pairing with some of the students  reminded me of some things that I've started doing better since I started working professionally.

I wanted to note them down so that I'm more aware that these might be common areas to improve on for university graduates that I work with in the future.

== Naming of things

I don't remember there being that much focus on naming variables/methods/classes in any of the programming courses that I studied.

It seemed the same for the students I paired with and I therefore found it quite difficult to understand some of the code that they'd written.

A typical example would be a method which had variables 'x', 'y', 'num' and 'a' and was named in a way which suggested it was a command when in fact it was a query.

A couple of colleagues I paired with at the end of 2007/beginning of 2008 showed me the value of naming things expressively in terms of how much easier it makes a program to read.

Sometimes there's a bit of a tendency to try and shorten variable names which tends not to work that well from my experience.

If we can use the same language in our code as we do when speaking about a problem then we're doing reasonably well.

== Solving problems in one go

This is something that I'm still sometimes guilty off although I think I'm getting better at spotting when I'm doing it.

At university on the other hand I had the tendency to try and write the whole solution to a problem in one go without ever actually running it until I thought I'd finished.

As you might imagine those programs never worked first time around and resulted in hours of debugging to try and work out what had gone wrong.

Incremental development certainly seems to work out much better for me these days.

== Using Google

One thing I noticed was that the searches being done on Google were written in natural language which meant that the results weren't particularly helpful.

Google seems to work well if you've narrowed in a bit on what it is you want to know how to do.

I think the development of that 'skill' comes through practice but it's certainly something that I used to struggle with a few years ago as well.
Feedback: Making the request specific
Date: 2011-02-06 15:47:30

My colleagues in Pune have been collecting feedback over the past week as part of the quarterly feedback cycle and it's got me thinking about the way that people ask for the feedback.

The most popular way is to ask for general feedback which answers questions like this:

* What are the things that the individual has done well?
* What are the things that the individual has not done well and/or needs more focus/improvement?
* Suggestions for future directions.

The problem I have with this is that it's extremely generic and *it's much easier to drift towards giving evaluative feedback* where you judge the person against some perception of what they 'should' be doing.

On the other hand  I find it's much easier to give people feedback if I know them a bit more and have some rough idea of what exactly they want to achieve or which things they are particularly passionate about.

Knowing this information helps to put us in a more supportive mindset and I feel the feedback you come up with in this mindset is more likely to be helpful to the person and will help them get better.

As I mentioned earlier a lot of the time the request for feedback will be general so we'll need to ask questions to try and elicit the goal the person is currently trying to achieve:

Some examples of goals that I've heard about could be:

* Learning how to drive pieces of functionality to completion
* Learning a language/framework
* Learning how to effectively lead a team
* Learning how to take more responsibility for the success of a team

Some of these are still a bit general so we can then ask further questions to understand what the person has tried already around this and then if possible give some suggestions on approaches that might work better.

That's what works for me anyway. YMMV.
Pair Programming: "What are you trying to learn?"
Date: 2011-02-23 02:58:51

I've noticed recently that while pairing with various different people that I frequently ask my pair what they're trying to learn through the approach that they're about to take.

I tend to use it when I don't really understand what my pair is doing and want to find out so that I can stay engaged.

It seems to be a more effective and less confrontational way of finding out than saying "What are you doing?" or "I don't understand what you're doing".

There tend to be two outcomes from asking the question:

* We were about to go on a yak shaving mission and that's not been averted.
* My pair was ahead of me, knew something that I didn't and is now able to teach me that.

The following are some recent examples I can remember asking the question:

* My pair was googling how to do something which didn't seem directly related to what we were doing.
* My pair was scrolling around files fairly rapidly and I wasn't able to follow what they were doing

Of course this question is unnecessary if http://www.markhneedham.com/blog/2009/08/24/pair-programming-keeping-both-people-engaged/[the driver is providing constant commentary] about what they're doing but it's easy to forget that you have someone alongside you when you're solving a problem.

Asking this question seems to be a reasonably effective way of keeping the pairing collaborative.
Espoused theory, theory in action & hypocrisy 
Date: 2011-02-23 01:34:47

Earlier in the year I wrote about http://www.markhneedham.com/blog/2011/01/13/chris-argyris-espoused-theory-vs-theory-in-action/[Chris Argyris' espoused theory and theory in action] and one of the interesting aspects to it which I hadn't previously considered is how we treat people when their espoused theory and theory in action don't match.

My tendency is to think that these people are hypocrites but http://blog.benjaminm.net/[Benjamin Mitchell] pointed out in a conversation on twitter that it's not really helpful to think that way:

http://twitter.com/benjaminm/status/38306821919883264[Benjamin]:

____
I find it hard to accept that other's can't see the 'obvious' gap I can between what they say and what they do (cf fund. attribution error)
____

http://twitter.com/markhneedham/status/38989664471748608[Me]:

____
@benjaminm I have the tendency to believe they are a hypocrite but I think it's just an espoused theory/theory in action gap
____

http://twitter.com/benjaminm/status/38990938936180737[Benjamin]:

____
@markhneedham I think that's the challenge I'm finding: allowing that people have a gap they are blind to, and not punishing them for it
____

A typical example where I've seen this happen is where someone (we'll call them person A) teaches a group of people how to give effective feedback, probably by following some of the ideas from Pat Kua's 'http://www.slideshare.net/thekua/tightening-the-feedback-loop[Tightening the feedback loop]' presentation.

The implicit assumption in the people being taught is that since person A taught them how to give feedback, person A should be able to give feedback perfectly every time.

Almost inevitably that tends not to be the case and there will be a time when person A ends up giving feedback which isn't effective and is more a reflection of them than the person they're supposedly trying to help!

If person A is working in a reflective mindset then hopefully they'll realise their mistake and work on closing the gap between their espoused theory and theory in action.

If that doesn't seem to be happening then we need to describe our observations to person A, discuss those observations and help person A improve.

A substantial part of William Noonan's 'http://www.amazon.com/Discussing-Undiscussable-Overcoming-Jossey-Bass-Management/dp/0787986321/ref=sr_1_1?ie=UTF8&s=books&qid=1298424594&sr=8-1[Discussing the Undiscussable]' is devoted to coming up with ways that we can deal with these conversations more effectively.

The learning from this for me is that *just because someone teaches you something or talks about a topic very passionately that doesn't mean that they've have to be perfect at it*!
CouchDB: 'badmatch' when executing view
Date: 2011-02-12 18:03:53

I've been playing around with http://couchdb.apache.org/[CouchDB] again in my annual attempt to capture the links appearing on my twitter stream and I managed to create the following error for myself:

[source,text]
----

$ curl http://127.0.0.1:5984/twitter_links/_design/cleanup/_view/find_broken_links
{"error":"badmatch","reason":"{\n   \"find_broken_links\": {\n       \"map\": \"function(doc) {   \nvar prefix = doc.actual_link.match(/.*/);            \n  if(true) {                  emit(doc.actual_link, null);                }              }\"\n   }\n}"}
----

It turns out this error is because I've managed to create new line characters in the view while editing it inside http://janl.github.com/couchdbx/[CouchDBX]. D'oh!

A better way is to edit the view in a text editor and then send it to CouchDB using curl.

The http://wiki.apache.org/couchdb/HTTP_Document_API?action=show&redirect=HttpDocumentApi#PUT[proper way] to update a view would be to add a '_rev' property to the body of the JSON document but I find it annoying to go and edit the document so I've just been deleting and then recreating my views.

[source,text]
----

$ curl -X GET http://127.0.0.1:5984/twitter_links/_design/cleanup/
{"_id":"_design/cleanup","_rev":"1-8be14d29f183b61f1ade160badef3f75","views"...}
----

[source,text]
----

$ curl -X DELETE http://127.0.0.1:5984/twitter_links/_design/cleanup?rev=1-8be14d29f183b61f1ade160badef3f75
{"ok":true,"id":"_design/cleanup","rev":"2-9fa15c1fdbb7cbaa659d623bc897b9da"}
----

[source,text]
----

$ curl -X PUT http://127.0.0.1:5984/twitter_links/_design/cleanup -d @cleanup.json
{"ok":true,"id":"_design/cleanup","rev":"17-b0763381b79f3fda843f57a7dcc842e1"}
----

I guess there's probably a library somewhere which would encapsulate all that for me but I'm just hacking around at the moment.

It's interesting to to see how you interact differently with a document database compared to what you'd do with a relational one with respect to optimistic concurrency.
Vim: Copying to and retrieving from the clipboard
Date: 2011-02-14 14:13:56

My memory when it comes to remembering how to get text to and from Vim via the clipboard is pretty bad so I thought I'd try summarising what I know and see if that works out any better.

We can access the system clipboard via the '+' buffer so the commands revolve around that.

== Copying to the clipboard

To copy the whole file to the clipboard we can use this command:

[source,text]
----

:%y+
----

Or if we want to get the data between lines 4 and 10 then we could do:

[source,text]
----

:4,10y+
----

If we want just the current line the following will work:

[source,text]
----

:.y+
----

If we want to copy lines via visual mode, we would use 'v' to go into that and select which lines we want to copy followed by:

[source,text]
----

"+y
----

== Retrieving from the clipboard

Retrieving data from the clipboard is a case of accessing the '+' buffer.

Therefore to paste whatever's in the clipboard into a file we'd do this:

[source,text]
----

"+p
----

If we wanted to paste it just before the current position of the cursor then we'd do this instead:

[source,text]
----

"+P
----
fgrep: Searching for a list of identifiers
Date: 2011-11-10 23:37:36

We had a problem to solve earlier in the week where we wanted to try and find out which files we had ingested into our database based on a unique identifier.

We had a few hundred thousand files to search through to try and find the ones where around 50,000 identifiers were mentioned so that we could re-ingest them.

Running a normal grep for each identifier individually took a ridiculously long time so we needed to find a way to search for all of the identifiers at the same time to speed up the process.

Luckily my colleague knew about +++<cite>+++http://ss64.com/bash/fgrep.html[fgrep]+++</cite>+++ which allowed us to do this.

____
fgrep is essentially grep (or egrep) with no special characters. If you want to search for a simple string without wild cards, use fgrep. The fgrep version of grep is optimized to search for strings as they appear on the command line, so it doesn't treat any characters as special.
____

We created a file containing all the identifiers:

identifiers.txt

[source,text]
----

identifier1
identifier2
identifier3
----

And then created the following command to identify which files those identifiers existed in:

[source,text]
----

fgrep -Rl -f identifiers.txt .
----

We passed the '-l' flag because we don't care where in the file the identifier matches, we just care that it exists in the file.

If we only have a few different things to search for then we could supply those directly to 'fgrep' without the file:

[source,text]
----

fgrep -Rl -e "identifier1" -e "identifier2" -e "identifier3" .
----

I haven't used 'fgrep' before but it came in quite useful for us here. I also came across http://www.kingcomputerservices.com/unix_101/grep_this.htm[this article] which explains the different variants of grep in more details.
Scala: Setting default argument for function parameter
Date: 2011-11-08 22:46:47

Yesterday I wrote about a problem we've been having with http://www.markhneedham.com/blog/2011/11/06/scala-which-implicit-conversion-is-being-used/[trying to work out how to default a function parameter that we have in one of our methods].

Our current version of the code defines the function parameter as implicit which means that if it isn't passed in it defaults to +++<cite>+++http://www.scala-lang.org/api/current/index.html#scala.Predef$$$less$colon$less[Predef.conforms()]+++</cite>+++:

[source,scala]
----

def foo[T](bar: String)(implicit blah:(String => T)) = {
  println(blah(bar));
  bar
}
----

It's not entirely clear just from reading the code where the implicit value is coming from so we want to try and make the code a bit more expressive.

The way we wanted to do this was by making 'blah' have a default value rather than making it implicit.

Our equivalent to +++<cite>+++Predef.conforms()+++</cite>+++ is the +++<cite>+++http://stackoverflow.com/questions/1797502/is-there-a-scala-identity-function[identity]+++</cite>+++ function and our first attempt at defaulting the parameter looked like this:

[source,scala]
----

def foo[T](bar: String, blah:(String => T) = identity _) = {
  println(blah(bar));
  bar
}
----

Unfortunately when we try to use that function without providing the second argument we get the following exception:

[source,text]
----

scala> foo("mark")
<console>:18: error: polymorphic expression cannot be instantiated to expected type;
 found   : [T](Nothing) => Nothing
 required: (String) => ?
Error occurred in an application involving default arguments.
       foo("mark")
----

From what I understand the compiler is unable to infer the type of the input parameter, a problem we can fix by explicitly specifying that:

[source,scala]
----

def foo[T](bar: String, blah:(String => T) = identity[String] _) = { println(blah(bar)); bar }
----

We can then either choose to provide a function:

[source,scala]
----

scala> foo("mark", _ + "needham")
markneedham
res17: String = mark
----

...or not:
[source,scala]
----

scala> foo("mark")
mark
res16: String = mark
----

This solves the problem for this simple example but an interesting problem that we then ran into is that we actually had overloaded versions of the method in question and only one overload is allowed to specify default arguments http://www.scala-lang.org/sites/default/files/sids/rytz/Mon,%202009-11-09,%2017:29/named-args.pdf[as per the spec].

Each overload actually takes in different parameter types so one way to get around this problem would be to make some of the parameters optional and then default them to None.

At the moment we've ended up leaving the implicit conversion in because the change is a bit bigger in nature than antiticpated.