Monthly Archives: June 2013

Building reputation on Stack Exchange sites

Gamification… is ADDICTIVE! I got hooked on basically “collecting meaningless points” on the Stack Exchange sites. As I was building up a “know-how” of doing this, I started drafting this post. Then I gave up actually posting it, thinking “what the hell do I know about this stuff anyway with my puny reputation”?

But then, what do you know, @DuncanLock who has similar reputation as me has posted his own take on the subject, and guess what, he got literally hundreds of good reactions, including high-profile Stack Exchange users, moderators, and even @codinghorror himself:

The Smart Guide to Stack Overflow: Zero to Hero

I commented on his blog a few extra tips of my own, but later I realized I still have some more to say. So here we go, my follow-up tips for building reputation on the Stack Exchange sites, on top of what Duncan already covered nicely.

Get the basics down first

informed1. Do read the entire About page. Carefully. It’s really important to understand the site. Plus you get the Informed badge as a reward! This page is also important to understand the counting of reputation: (especially the daily max 200 limit!)

2. Be patient. It takes time to build reputation. If this was easy within a matter of days the system would be meaningless.

3. Be civil and professional. Don’t lash out on poor quality questions/answers/comments. Vote down if you don’t like something and move on. Don’t take anything personal, be cool.

4. Be a good sportsman. If somebody else posted a better answer than yours, admit defeat and move on. If somebody answered first something just as good as yours, vote it up and move on.

Finding questions to answer

1. Look for questions in your favorite areas of expertise. There’s much more than, take a look around the many other Stack Exchange sites. If you’re a programmer, check out If you’re more of a sysadmin dude, head over to or If you’re a UNIX/Linux expert, you will enjoy There’s probably something for everyone.

2. Be selective when you pick a question to answer. Figuring out what the heck a poorly written question is supposed to mean might not be worth your time and effort. And if you are not 100% sure you have a great answer immediately, then somebody else will probably beat you to it. It’s often better to just move on.

3. Devise question hunting strategies and combine them efficiently. I use the following basic strategies:

  • Fast-read the newest tab (click on Questions if you don’t see it), fishing for easy questions and try to be the first to answer. New questions are very visible because they are on the front page. That also means you don’t have much time to research to give a good answer.
  • Search by tags to find questions in your strongest subjects. Sometimes there are easy questions that dropped off the front page of newest questions. This can be very lucrative, as you are looking at questions in your strong area, and you have more time to research and give a good answer.
  • Only open questions with 0 or 1 answer. Often the first answer is not that great, and it’s quite possible that you can do better. When there are 2 or more answers it becomes less and less likely that you can give a better answer.
  • If you are tired of one site, or while waiting for a new set of questions to accumulate, switch to another site.
  • Setup filters on and email notifications of new questions in your favorite areas. This is most useful for tags with only a few questions per day or less. This is not useful at all for highly active tags with many questions per hour.

Typically I quickly scan the new questions. Usually I find a few I might be able to answer, read them properly, and if enough time passed, then if I reload the page I see a completely new set of questions. If I don’t see anything suitable, then I check on my favorite tags for a few minutes, and switch back again to the first strategy. Or instead of checking on favorite tags, I can switch to another stack exchange site.

4. Something that helps me a lot answering questions well (= actually getting rewarded for it) is to hunt questions when I’m deeply into something. For example, after about a week of Android hacking, suddenly I can answer many questions well and fast, because I’m just really right in the middle of it. Not to mention that when deep into something I usually have my own questions, and very often find answers that almost work but not quite, which is another good opportunity to post my own.

Drawing attention

Sometimes your otherwise great answer might not be getting the attention it deserves… Luckily there are quite a few things you can do to improve that.

1. If you intend to answer or already answered a question, don’t vote it up immediately. After answering, give it a few days, and if there is no reaction on it, then come back to it and vote it up. Such activity will bring the question up to the front page again, becoming more visible again, especially to the poster who will receive a notification in his Inbox. And if your answer is accepted, then be a good citizen and vote up the question. (You should not answer questions you don’t like anyway.)

2. Share your answer (or question) on your social networks. It’s very easy to use the [share] link right under the question/answer. Same with voting up the question, do this after a few days if the question is inactive.

3. Improve your answers. From time to time review your answers with zero upvotes and see how they can be better. Perhaps they were not clear enough, or maybe you answered too quickly and misunderstood the question. If the answer is not something you can proudly show to your friends, then maybe it’s better to delete it.

Collecting badges

Badges are cool goodies, but they don’t get you any reputation. They sure look good in your profile though 🙂

civic-duty1. Personally I don’t hunt badges. I think you can just let them come to you naturally. For example, you get the Civic Duty badge if you voted 300 times. That’s so cool, I didn’t even know it existed, and one day I just got this in my Inbox, yeay!

electorate2. Some badges reward you for using the site in a sort of “balanced” way. For example, you get the Electorate badge if you voted on 600 questions and 25% or more of total votes are on questions. The site also warns you if you vote mostly on answers only, saying that questions need loving too 🙂

Becoming a seasoned veteran

profile for janos on Stack Exchange, a network of free, community-driven Q&A sites

1. Once you have built up some reputation, embed “a piece of valuable flair” on your website, for example:

2. Check out the Stack Overflow “leagues”:

You can see the heaviest hitters by week/month/quarter/year/all-time on all Stack Exchange sites, as well as your own rank.

Another interesting thing on your profile page on (different from is the reputation tab shows a graph of your reputation score changes, for example:

By the way, on your Stack Overflow profile homepage (not Stack Exchange), in the Reputation section you can see a link to the leagues, in a format like “top 3% this quarter”. The value shown can be about the quarter, week, month or year, depending on whichever is highest for you, and it takes you right to your position in the leagues.


3. See what privileges you can unlock by earning higher reputation: It’s really cool how more and more interesting features of the site start opening up gradually. In a way it’s like going deeper down in the rabbit hole. For example, after about 2000 you can start moderating various types of posts (new users, low quality, etc), which reward you with new badges.

4. It seems that if you are active on a Stack Exchange site, sooner or later you get invited to It’s a very cool site where you can list your competencies much better than on LinkedIn, for example. Not only you can showcase selected high-scoring questions and answers from Stack Exchange, you can also highlight your most interesting open-source projects on GitHub or other code hosting sites. (You can check out mine here for example:


At the end of the day, I’m not sure how much effort is worth investing in reputation building, so I leave that up to you 🙂 Answering questions is probably similar to teaching: you always learn something even while you teach, so if nothing else, at least you have that!

Add Disqus to your WordPress or other blog

I’ve seen a couple of blogs using Disqus to show comments, but never really cared enough to check it out. Until now, and it looks like a pretty good idea!

  • Readers can “login” to comment using their Twitter or other social accounts. They don’t need to enter the usual boring stuff like name, email, website address anymore.
  • It gives you much more granular control for managing your comments compared to native WordPress, and in general it’s jam-packed with features.

Mainly I’m counting on that switching to Disqus will attract more comments. I myself feel it off-putting when a website is asking my name and email instead of letting me authenticate with an OpenID provider or Twitter. Sadly this blog was doing that too… Not anymore! This is definitely a good improvement.

I’m still discovering this thing, but it looks really useful. I might post more details later to highlight the best features that really work for me.

To get started using Disqus on your blog:

  1. Create an account if you don’t have one already
  2. Register your site on and follow the steps for WordPress or whichever other publishing platform you use. At least with WordPress, the steps were very accurate and easy to follow, a smooth process. Disqus gives you a pretty cool dashboard with many interesting settings.
  3. You can import your existing comments, Disqus reminds you of this during setup

By default Disqus shows ads, supposedly for your benefit, which is not so cool. Luckily it’s easy enough to switch it off on the Disqus admin. In case Disqus doesn’t really work out, you can export comments and import to something else later (or back to your WordPress).

Cool features of GitHub

I put together a simple presentation about some of the amazing features of GitHub. I focus on stuff that can be very useful even for folks who might not know Git and GitHub very well, or not at all. The idea is that by starting to use GitHub, they just might actually get on the fast track to becoming full-time Git users, who knows…

It’s a presentation, so the slides are not really designed for reading, but here they are anyway:

Once again, I used many tips from Zach Holman’s blog to “design” the slides. I also shamelessly borrowed colors and fonts from his other fantastic slides, especially this one. (I hope he wouldn’t mind…)

I created the slides using Google Docs, and since it looks like the links didn’t come out right in the PDF export, here they are:

My book Bazaar Version Control is now published

I am happy to announce that my book “Bazaar Version Control” has been released, and it is now available in online stores:

The sample chapter (Chapter 2: Diving into Bazaar) is a FREE download. It includes the preface, which is a nice, short and sweet introduction of the book. The chapter reveals quite a lot: it explains all the basic operations of Bazaar using both the command line client and Bazaar Explorer. It is a good sample of the overall writing style in the book, and you should definitely read this first before buying.

If you find the cover familiar, it is based on Gource, a truly awesome VCS visualization tool that works transparently with Bazaar. I wanted to include a proper section featuring Gource somewhere in the book, unfortunately due to time and space constraints I was not able to do so in the end. So here goes my very special thanks to the author, Andrew Caudwell, of this fantastic open-source project.

ImproperlyConfigured: The SECRET_KEY setting must not be empty

I hit by a strange issue with Django. If I try to use a local configuration with

./ shell --settings=myproject.local_settings

I got the error:

ImproperlyConfigured: The SECRET_KEY setting must not be empty

Strange because SECRET_KEY is certainly set. No stack trace, just a single line of error.

The cause turned out to be that in the main file I imported a method from one of my apps like this:

from accounts.views import render_failure
OPENID_RENDER_FAILURE = render_failure

I don’t understand why exactly this is a problem, but removing the import solved the issue. On the other hand, I needed that import as the OPENID_RENDER_FAILURE setting of the django-openid-auth package takes a callable, giving it the absolute function name accounts.views.render_failure as a string doesn’t cut it. I worked around that like this:

def render_failure(*args, **kwargs):
    from accounts.views import render_failure
    return render_failure(*args, **kwargs)
OPENID_RENDER_FAILURE = render_failure

Now everything works fine.

Deploying new releases using Git and the post-receive hook

I used to deploy new versions of my websites like this:

  1. ssh to the server
  2. cd to the website project directory (under version control)
  3. Update from VCS to the latest version

Doing this a few times is ok, but if you want to release frequently it’s better to automate these steps. One way to do that is using the post-receive hook of Git like this:

  1. Setup a mirror repository on the server called “releases”, with a branch called “beta”
  2. Make the deployment directory track the “beta” branch of the “releases” repository
  3. Setup a post-receive hook in the “releases” repository to trigger a script that updates the deployment directory (perform a git pull or git checkout -f)

The goal of this setup is to simplify the deployment steps to a single git push command from my local development/test environment to the releases repository. Then thanks to the post-receive hook, the pushed changes will be automatically propagated to the deployment directory, without manually logging in to the server.

First I created the releases repository from my deployment directory:

Next I created the post-commit hook:

(Hook scripts are in the hooks/ directory of a Git repository, and must be executable.)

I typically use two branches: “beta” and “prod”, and reuse the same “releases” repository for these. The above hook script checks the branch that is being pushed to, and checks if an upgrade script exists with the filename in the format “”. The real upgrade scripts exist in my deployment directories, because I don’t want to have too much logic inside the Git repository directory, I prefer that to be together with the project itself. In the Git repository root I put only symlinks to the real upgrade scripts.

Writing an upgrade script depends on your project. Here’s an example from one of my Django sites:

The script is written in a way to be reusable in multiple of my Django sites, but you may need to adjust to match your typical deployment. The unset GIT_DIR is necessary, because it seems the variable is automatically set when the hook is executed, otherwise the git pull operation would result in the error:

remote: fatal: Not a git repository: '.'

Finally, I setup the releases remote in my local Git project:

# go to the directory of my local project
cd ~/project/dir

# add the "releases" remote
git remote add releases ssh://

With this setup in place, deploying a new version is as simple as:

git push releases master:beta

To make it even easier, I created aliases in my .gitconfig:

deploy-beta = push releases master:beta
deploy-prod = push releases master:prod

Debugging deprecation warnings in Django

Ever since switching to Django 1.5, I’ve been annoyed by this:

DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead

I’ve been annoyed because I duly made the necessary changes in my project and verified that I’m not using the old module anymore:

grep -rl django.conf.urls.defaults .

Yet I was still getting this warning… Finally I understood (thanks to some googling) that the cause is that one of the apps included in the project are still using the old module. To find out which one, here’s a really elegant solution:

python -W error runserver

This way deprecation warnings will raise an error and from the stack trace it’s easy to find the perpetrator. In my case it was django-openid-auth, which at version 0.5 is still using the old format. I recently learned about django-social-auth, probably I’ll be switching to that one in the near future.