In an ideal world every software development team would be populated with PhD-level team members, all highly motivated and working in harmony.
But most businesses are not as well-funded and focused as, say, Google or Microsoft, and quite often a legacy of poor hiring practices means that a team of reasonable size (say 10 or more) will probably contain a few members that are distinctly average or below average.
I expect some will say "just fire them", but it's not usually that simple for reasons that are interesting but not immediately relevant to this question (mostly political).
Assuming that the team is bound to contain at least one or two of these below-average developers, what would you suggest is the best way to make the most of the situation?
EDIT: "50% of all programmers are below average"... not true! You could have 9 stars in a team and 1 donkey, but only the donkey would be below average.
EDIT: @Christophe Herreman makes an excellent distinction between below-average team members with potential and those without.
I think we should make a distinction between those who are below-average because they are still in the process of learning a new technology but are driven and the ones that are just not interested or even not smart enough to do this kind of job or work with a certain technology.
In the first case, you can quickly get a person up to speed by doing pair-programming, having code reviews, or sending them on a course. In the second case (I've been there), it is really hard to get them to be more productive or deliver higher quality code. My experience is that in the end, such a person has a negative impact on the overall functioning of the team and it is better to deal with that asap.
You should try to get them to feel responsible for the things they do. You could for instance set up a Continuous Integration system that notifies them (and the rest of the team) when they checked in untested code or if a code change breaks the build. If they don't feel the heat then, or still don't show any interest, I'm afraid the only thing left is to put them out of the team.
Hire for attitude, train for skills.
I'll try to summarize the good answers here in hope of a good & comprehensive answer, see if it works:
First, be sure about your definition of "below average" or, to put it less politely but more honestly, "bad performance". There's been plenty  of  articles  discussing how most performance metrics are of little use in our trade (and in knowledge-based organizations in general).
Also remember that it's the performance of the whole team that counts and if you have someone who doesn't get much code done but is a great guy and keeps morale high and everybody loves him, he is actually being productive. These things are practically impossible to measure and you need a very reliable "gut feeling" and a lot of very open and direct contact with your whole team.
Once you really have established that members of your team have a negative impact on productivity, it's important to find out why. Do they stay behind expectations because they (a) aren't smart enough, (b) are not yet experienced enough or (c) there are cultural or political issues in your team that get in the way or mess up motivation.
(b) is easy to fix, just arrange for proper mentoring and they'll be up to speed soon. (c) is harder but is also a very serious problem that management alone is responsible for and which should be addressed. (a) really means the tasks they are doing are too hard (yet). Find something easier to do and give them opportunity to expand their capabilities.
Firing people in teams of 10 is very, very expensive and might well have bad unexpected side effects, such as dragging down the morale of others. Although keeping bad performers on board although "everybody" knows they aren't contributing can also bring people's morale down, as Jeff Allen  rightly points out in the comments below:
Firing boat anchors is a critical part of respecting and nurturing your best performers. If everyone knows someone is not cutting it, seeing them cut loose can make the team fly.
I think, firing people is on the management scale very similar to rewriting code from scratch, it's very tempting (in the sense that it seems straightforward and liberating), but you just shouldn't do it . And then, sometimes, it still helps, which led me to add:
I basically copied FogCreek's recruiting strategy (apart from the limo at the airport, so far) for my own two companies and have been told by colleagues and friends also working in software development that
"you'll never get enough developers if you require them to in-place-reverse a string in C, on paper, during the interview - I don't know, if I could ... - I mean, who even still uses C, these days"
Which seems right, I never have enough developers. But I'm happy with those that I have, and I hope I'll always have to worry about getting more instead of getting rid of team members. http://www.joelonsoftware.com/items/2006/11/10b.html
I've had PhDs working in some teams and they were useless :-)
However, if you can control the workflow, just make sure each team member gets work suited to their level of competence. That's not hard; it's what team leadership is all about.
Of course, if one of my "minions" suggested that someone on the team was below par, I'd quickly make sure they could show
Technical skill is important but it's not the only consideration in running a team.
In the past, when I made such decisions, before seriously considering firing (which can be a highly destructive experience for the entire team) I would do three things:
Not that this always worked. Sometimes ya just gotta 'go nuclear'.
I think having a team consisting of below average or average developers/members is a normal scenario. It is a job the team lead/project manager to get the best out of everyone. Usually every body have some positives and negatives, a bad developer may be bad @ code but can have some other skills like documentation, testing, some other area of interest other than core development which may be useful for the project, etc. Sometimes having a chat with a team member about some lack or failure can make things lot better and produce positive results. Mentoring is also a good way to communicate best practices and overcoming shortfalls. Beside these, periodic code reviews and performance evaluations are a must to keep team running smoothly and mitigate any future concerns.
In general I've noticed several reasons for less-than-stellar performance and each needs to be handled differently.
First and easiest is the person who is still on a major learning curve. In this case, give him or her tasks with a little stretch to the current skill set but not so much that they can't succeed if they try. Provide them with training courses if you can and by all means pair them up with more-experienced programmers if you can. Pick out some things these people need to learn how to do and have them present training to the group on those topics. Make sure they participate in code reviews of more experienced programmers, so they can see how others handle the kind of problems they might see. Tell them clearly where you see that they are and where you want them to be.
Next is the person with the actual skills but who has decided to be an attitude problem. With these folks, clearly tell them what you expect and then expect it. Sometimes these are lazy people who have learned that if they cop an attitude, they will be expected to do less. Don't let them get away with it. Don't fix their mistakes either, send them back every time. Document it when the person doesn't follow directions and when you feel you have given them enough chances, let them go. If it is sudden change of attitude, try to find out why it happened, but my experience is that most of the time, this is a chronic problem and it is best to get them out of your team if you can. When I worked for the government, I worked with several of these people and they hated working for me because I wouldn't let them get away with anything. Even if you can't fire them, this approach often leads to them searching elsewhere for employment where they don't have to work so hard.
Next is the person who is a temporary problem due to some life issues (Grief, divorce, etc. come to mind). See if you can get them some help to deal with their personal problems if they are affecting the job. Make sure you tell that person that there is a problem and that it needs to be fixed. Sometimes all they need is a reminder to leave their personal problems at home. However for grief (especially if it was a spouse or child or other person they lived with), cut the person some slack (assign easier tasks for a little bit or estimate that tasks will take longer than they used to), performance will get back up to snuff as soon as the person can think clearly again.
Finally there is the person who just isn't suited to programming. No matter how hard this person tries to learn, he or she doesn't seem to manage it. Try to steer these people into another career field. This is another group where after giving sufficient chances to learn, you may just have to let them go. It seems cruel to do so (especially if the person has a good attitude and is trying), but getting them out of a field they will never succeed in may be the kindest thing you can do for them.
Remember, 50% of all programmers are below average :-)
I'll get my coat.
Personally I focus on two things:
I believe the first question to ask, in fact the first obligation of the "manager" is to determine what skills or capabilities your team members bring to the table. Find out what the below-par members can/want to do and try to design the work around them. If you try hard enough, there is usually is some solution that is good for both the team and the individual.
Everyone is on a learning curve. The 'perfect team' where everyone is at the top of their game, is probably the team that is heading over the top of the hill and on the path to dissolution. If you have longer term ambitions for your group, then you need to be focused on the learning and growth plans - for all team members. All that matters is that the members have potential - if not, for the good of all you should be looking to exit the individual soon.
Why are these members below average?
If they are below average because they are inexperienced, then try to arrange a mentoring experience for them. If they are below average because they are incompetent, the best option really is to fire them. Bad programmers frequently contribute negative productivity. You can't trust anything they do, and fixing their mistakes takes more work from others than you can get in useful work out of them.
If firing is not a politically acceptible option, then the first thing to try is to hope you can improve them. Make them read books, get mentored, etc. If that isn't working out, then do your best to find them something useless to do where they don't take up too much time and don't do harm. For instance locate a repetitive task that is within their abilities. (eg Running integration tests.) Or a task you can ignore. (eg Writing documentation for internal use, that you're sure nobody else will actually look at. Just be sure to have someone else write documentation for anything that is important.)
Depending on the persons that you have to work with, you might want to consider a good system for code-reviewing, where the code that they wrote will be reviewed by a more skilled person. This is a good practice for any team though, so doesn't go for just this case.
Another good way to deal with this is Pair Programming , where "One types in code while the other reviews each line of code as it's typed in. The person typing is called the driver. The person reviewing the code is called the observer or navigator. The two programmers switch roles frequently."
The website of Joel on Software had some article on it, discussing some of the positive and negative experiences with Pair Programming . http://en.wikipedia.org/wiki/Pair_programming
There can be a great deal of diversity to the work of a developer that I think shouldn't be lost here. Here are some of the roles I've had to play over the years:
Troubleshooting issues - Debugging problems to figure out why is something not working as expected. This doesn't require writing a lot of code usually, but there is a lot of investigative skills used here.
Solution design and planning - How to build big systems and structure projects can require a slightly different set of skills. While this is the next step after figuring out why something doesn't work, it requires some creativity and other skills.
Analysis of solutions - There is usually more than one way to do something and understanding the trade-offs for each isn't quite the same as merely pinpointing the issue. Also, interpreting designs can be important here as well.
Implementing a design - This is the actual writing of code, yes. Of course this should be in here somewhere.
Presentation skills - Sometimes one has to show to an end-user or tester that something was done or explain how a feature is to be used and this has its own separate skillset to bring in at times.
Most people will be good at some of the above, so it can be worthwhile having those strengths utilized as much as possible. Optimizing this isn't easy and is likely rare done.
Why does the worst team member's performance have to be considered bad? In a relative sense, yes there is someone that would be at the bottom usually. However, if that person's work is good and the employer is happy with the result, isn't that what counts at the end of the day?
Some below-average team members actually suck productivity out of their team-mates. Those developers can't even be safely assigned to minor tasks, because while they're getting a small thing done they'll keep people from doing the large things.
That calls for intensive counseling, and possibly firing if they can't improve.
If they're just slow workers, then the main problem is that they need greater supervision to get their work done, so they put a larger burden on the team's leadership. If you've got that bandwidth, you can just be careful how you schedule them and give them that extra supervision they need. The ones who are motivated and capable will quickly outgrow that need, so it's not a big deal.
We all want to work with the great people who make everyone around them more effective. The flip side is that we all need to avoid working with the people that make everyone less effective.
In an ideal development world the development team will not always work in harmony and be fully motivated. In order to handle the changing context in which the development has to take place, you need people in the team with different value systems and preferences.
It is unlikely that they will all be equally productive at the same time, but that is the overhead you need to accept and welcome in order to be able to better adapt to changes in the environment.
Take a look at Kolb's learning styles,
and Myers-Briggs Type Indicator
Take a look at Gerald M. Weinbergs books on Quality Software Management to see the relationship with conflict, blaming and change.
Not being a great programmer and needing constant attention is not always the same thing.
If a guy is not the best programmer he can still be useful working on the less critical components with a more experienced guy to help.
A programmer that sucks up other peoples effort on the projects might need to go.
This can also depend on the size of the project. In a team of 30 programmers a few bad apples is not a big problem because you can use a strong core team for the most important aspects. For a small team of 2 to 5 people a bad programmer can suck all of the energy out of the project.
i wont re-iterate what other people have said, no need. i will just add a few more tips to the buffet:
for starters, how did this guy even get into the organisation? were you doing programmer tests before hiring? (see: http://pm4web.blogspot.com/2008/08/hiring-programming-staff-part-1.html)
try 'goal settings' (from a book called The One Minute Manager). i have a white paper on how i use them: http://pm4web.blogspot.com/2008/08/one-minute-goal-settings.html
understand there is a difference between 'teaching' and 'coaching'. you arent so much trying to solve a person’s problems as 'build them up' (through encouragement, a documented concrete plan for development based on facts/measureable results). Manager Tools has a podcast on this: http://www.manager-tools.com/2005/08/the-art-of-coaching/
consider reducing the team-member's salary (e.g. by 10-20%). why? this will placate senior managements concerns that the person is a non-cost effective resource (i.e. "why are we paying for someone who cant do the job?"). the under-achiever may not be happy with his and leave (problem solved), if they do stay and tolerate it - its a good demonstration of a willingness to learn.
be careful not to remove 'catalysts' - this is someone who doesnt do much work himself, but helps others do theirs better (the whole is greater than the sum of its parts).
RE: dont fire - i 100% agree. firing someone for underperformance is a last resort. this is different from 'encouraging them to leave' though. imagine what the other team members will think if one of their own is fired? they could even start looking for jobs elsewhere because they see its an insecure environment, and you could potentially start losing the good programmers. on the other hand, if he leaves for a job elsewhere, well then, he is just moving onto greener pastures.
I find having a very strict set of rules help to reduce the problems low-skilled team members.
We do this by having: 1) a strict design pattern (eg: MVP) 2) strict check in policies (code analysis, code tracking, etc) 3) frequent scrums 4) extensive documentation
I recently headed up a large dev team which had 1 developer in it I had previously worked with who was definately below average, but by having the above in place his impact on the project was actually positive. His work wasn't the best, but it was not as bad as the previous outings from him.
Just fire them.