About hiring programmers and Asperger’s syndrome

Managers in software teams are often confronted with highly intelligent programmers; programmers that all suffer in some extent from Asperger’s syndrome. These people are very intelligent, question authority and do not do what is told unless they are satisfied with the reasons why. They have a low social sensibility and love endless discussions about principles. They like to stick to rules onces they are settled, can focus for hours on single pieces of code, love to be fully focused and hate it to be disturbed.

Am I generalizing? Yes, you bet I am, but I am sure: If you are a programmer you will recognize some of it.

“Managing programmers is like herding cats” – Meilir Page-Jones

I love that quote, because it holds so much value. Some say it only applies to senior programmers. But that leads to the following dilemma: hire easy-to-steer junior programmers that may have little or negative contribution to the software you are building or hire hard-to-steer seniors that can bring big value. Whether it is true or not, I think the latter is preferable.

Dealing with senior programmers is hard and I believe it is a challenge that does not have its match in other industries. One of the factors that is making matters worse is the global lack of senior programmers. These programmers can afford to behave arrogantly and non-compliant because the software business needs them so badly. They can always find another well-paying job. All they have to do is mention on their social media profile that they are “available” and it will rain job offers on them.

One of the methods I see that people use to get a grip on their developers, is to pay them above average or get them secondary benefits that are so good they cannot be matched elsewhere. But then again, you must be careful this does not lead to arrogance, lack of self-criticism and a feeling of superiority. These are definitely enemies of a good working team, so this cure may be worse than the disease.

Further reading on Asperger’s syndrome

The following links give some more insight into Asperger’s syndrome:

  1. http://archive.wired.com/wired/archive/9.12/aspergers_pr.html
  2. http://www.dailymail.co.uk/home/you/article-2557765/Is-man-wired-differently.html
  3. http://www.healthcentral.com/autism/c/1443/153287/asperger-difficulty/
  4. http://edition.cnn.com/2013/04/11/health/aspergers-work-irpt/

About software development methods, case tools and functional design

In 1998, I started my career as a functional designer in a large company, designing all kinds of new functionality for large and complex systems. We used MS Word to document the customer requirements. We were free to decide how to do this.

A simple case tool (named SDW) was used to document the functional designs. These designs contained a description of the system functionality, as well as data structure/relationships from a logical point of view. The projects were based on the Waterfall method.

Nowadays, designers use all kind of sophisticated methods and techniques to improve speed, quality, maintainability, etc. I’ve worked in many organizations using methods like RUP, Agile and Scrum, to name a few!

All kinds of expensive tools were used, such as Enterprise Architect, Rational Rose, alongside use cases to document the functional designs. But never have I experienced the level of professionalism as during the ‘Waterfall and MS Office’ period at my first employment.

Why? I’ve been asking myself that question.

Why is it nowadays that Waterfall is often considered as a ‘bad method’? Why do functional designers use these newer design techniques like use cases? Were the classic ones not sufficient? Are these newer techniques better?

Waterfall vs. iterative methods

Waterfall is a relatively simple method for system development. It is a sequential method, that starts with defining all the requirements, then creating the functional design, which is then followed by development and testing. Each stage handles all requirements and has to be finished/approved before the next stage can be started.

The main disadvantage is that the requirements that arise at a later stage are often difficult to include in the scope. Sometimes it simply doesn’t fit the architecture. Or sometimes a chosen solution that is already programmed should be reverted before the new solution can be implemented. So adding or changing requirements at a later stage can be difficult.

A solution for this is to use an iterative method, like RUP. These methods can handle ‘progressive insight’ better than Waterfall because the changes are divided into chunks, which are implemented in phases. So the requirements do not need to be defined in an extensive way, as is done in the Waterfall method at the very beginning of the project.

But iterative methods are usually harder to manage because you have to do parallel planning, manage multiple disciplines at the same time, (re)define the stages and priorities during the whole project. Also iterative methods can lead to constantly changing requirements during the project, because the stakeholders are involved throughout the whole process. New requirements are being added regularly, or changed due to ‘progressive insight’, which makes it very hard for an inexperienced project manager to manage properly.

To sum things up…

Waterfall is relatively easy to use but is too rigid to deal with new insights. This could be an issue in fast changing markets/environments, especially when dealing with larger projects where these risks are higher. But if the requirements at the beginning are solid and usable in the long-term (compared to the project term) then Waterfall could be very suitable.

Iterative methods are harder to manage, but provide flexibility for the stakeholders to (re)define the requirements.

Office tools vs. sophisticated case tools

Case tools are very effective for performing impact analyses, drawing mock-ups, describing functionalities, and creating diagrams. But when the quality from functional design is poor, then a case tool will not improve it, if you would compare it with a text editor like MS Word, for instance.

A functional design needs to be correct, complete, and clear (CCC). As an analyst, developer, or tester, one needs to trust the information it contains. But for this CCC, you do not need a case tool, however, it might help.

So a case tool could be very beneficial when it is used properly.

But sometimes as a designer you are expected to be pragmatic (because of deadlines, for example). In this case, a designer won’t be able to deliver a full blown design. And sometime no designs are made at all, when the changes are communicated orally. This will result in the already existing design being incomplete and even more inconsistent. In this case, the benefit for case tools will not be significantly greater, if compared to a good text editor. On the other hand, an existing and complete design in a case tool will make analysis and maintenance much easier.

However, case tools will not deliver the most visually creative designs as designers are limited in their creativity. This is because of the rules upon the shared use that are agreed with other colleges. The case tool itself also demands that the design are created a certain way (according to a specific structure). But this could also be considered as an advantage because the case tool will guide a designer, making it easier to create the respective design(s).

So a case tool can deliver many advantages, but should be used properly to justify the investment (money, learning time, set up, integration, etc.).

Traditional designing vs. use case

With traditional design techniques you describe the functionalities of a system. You describe what a system does from a system perspective, as well as the logic to achieve this.

Nowadays, use cases have become a very popular method to replace the traditional designing method. There is only one problem. Use cases do not describe the system functionality. But they are used to describe the interaction between systems and actors. So you often still need to design the system logic. But the ‘problem’ is that many designers aren’t aware of this and consider the use cases as the final stage for designing. It is very helpful for work-flow and/or a scenario driven system, and in many cases offer enough information for the developers. But it is not practical to always use use cases. Try to design Excel by using use cases, for instance. That just doesn’t work.

There is also another problem. Readers need to be familiar with use cases, so you need to learn to read them. Designers often undergo training to learn to this method. The readers (customers, testers, developers) do not. There are also many interpretations about how to create a use case properly. For instance, include and exclude relations between use cases. These are very much debated (also on the Internet). This can lead to ambiguous designs. One can guess the consequences.

But under the right circumstances, it is a very powerful method for designers to describe the functionalities (from actor’s perspective), especially when combined with a case tool.


All these new methods, techniques, and tools can be helpful. But this doesn’t mean the old ones aren’t sufficient anymore. Depending on the situation, the right method has to be chosen.

Some things to consider…

Define the requirements for the requirements. In other words, what do you need to gather and document the requirements in the most efficient way.

Investigate the environment:

  • Is the environment fast changing or not?
  • Consider the level of IT expertise within the company. Do the developers/testers/stakeholders understand use cases. How experienced are the project managers?
  • Consider the company culture. How much does the business control the IT department? Does the company demand that everything is documented or do they prefer not to document too much?
  • What are the needs? Speed above quality or vice versa.

Then make the right decision. BUT use the advanced one properly, or otherwise keep it simple.


There is no Silver Bullet like ‘Rush code to live’

There is no Silver Bullet for software development, as you can read in Fred Brooks epic 1975 book about software development titled “The Mythical Man-Month“. But if I have to come up with any Silver Bullet it would be: ‘Rush code to live’. This is a theoretical model for doing software development, which follows the DevOps model. Since it is a ‘Silver Bullet’ it claims to be a revolutionary way to produce software much faster and cheaper.

SaaS needs a rush

In a Software-as-a-Service (SaaS) landscape you need to keep your customers happy by continuous, incremental improvements of the software, which follow an organic growth model. By doing big bulky updates, the user will have to wait a long time before anything changes and the user experience will suddenly change, which might alienate your users. Apart from that: 1) the moving target kicks in; 2) risks grow, since reverting will be increasingly difficult; 3) it is unclear what needs to be tested; 4) and users lose confidence when you keep moving the deadline for the next version.

Organize carefully

So take SCRUM, with a product owner and everything that comes with it. Now split your big software team of into small expert groups of 2-3 people that own a specific part of the code. Increased feeling of ownership encourages responsible behavior. Next is to make sure every group has one natural leader (a more senior developer), to avoid unproductive coding style/architecture discussions. Let the programmers develop blocks of code that are as small as possible, but can be brought to live individually. This would make them work for 2-3 days on a single small feature. If a feature is too big, simply cut it up into parts to make it smaller. Test the feature and bring it to live by the next day, when the code is still ‘top of mind’ and bugs can be fixed fast and easy. It is important the testing is done together with some other developers in demo-like sessions to avoid blind spots and encourage competition and enthusiasm.

Testing and deployment

When bringing the code to live, make sure this is done carefully by only the best developers. Do it when usage is low and do not tell customers about your ‘Ninja deployment’, since this may increase the expectations and thus the bug costs. When bringing code to live, your monitoring must be top-notch and you must be able to revert fast (only to fix bugs and redeploy). This means that if something fails, it will always be the new feature and only a limited set of customers will notice. If you can, bring the feature live for only a subset of the customers first. Both of these measures help further reduce the risk and positively influence the test (test vs. bug costs) trade-off on which you decide the amount of testing effort. Do not hesitate to bring code to live that does not add value. Even if it only provides part of a feature and must therefor be hidden, you should still deploy it.

Change your thinking

Now think outside the box and consider the truth of the following ‘Rush code to live’ principle:

Every 10 lines of code written but not brought live (into production) will cost you one extra man-hour every day.

Reasons it might be true? Only after code is running flawlessly on live will people stop discussing, changing, arguing and worrying about it. Note that I only have a gut feeling to back this claim up, and is not based on any research whatsoever. Still, I believe the cost of unreleased code is way higher than anyone can imagine, so ‘Rush your code to live’ for fun and profit!


Waterfall versus Agile – comparing software development methodologies

One of the first decisions you need to make as a project manager before starting a project implementation is: Which development methodology should I use? There are several methodologies you can use to manage a project. This blog contains reasons and information about two methodologies which can help you make this decision.

What is Waterfall?


The Waterfall model is a sequential design process, often used in software development processes, in which progress is seen as flowing steadily downwards (like a waterfall) through the phases of Conception, Initiation, Analysis, Design, Construction, Testing, Production/Implementation, and Maintenance. This means that when each of the eight stages are completed the developers move on to the next step. Once a step has been completed developers can’t go back to a previous step without reviewing the whole project and starting from the beginning. There is few room for changes or errors, so a project outcome and an extensive plan must be set in the beginning and then followed carefully.

What is Agile?


Instead of a sequential design process the Agile methodology follows an incremental team based approach. Developers start with a minimalistic project design, and then begin to work on small modules (sprints with a defined duration and a running list of deliverables planned one sprint in advance). The deliverables are prioritized by business value as determined by the customer. At the end of each sprint project priorities are evaluated and tests are run. These sprints allow bugs to be discovered in an early stage and customer feedback can easily be included into the design before the next sprint is run.

Comparison between Waterfall and Agile

In this picture you can see the differences between both methodologies at a glance.


Image source: Waterfall versus Agile

Advantages and disadvantages of both methodologies

Advantages Disadvantages
  • The customer knows what to expect in size, costs and timeline
  • Minimal impact in case of employee turnover due to strong documentation
  • Developers and customers agree on what will be delivered up front
  • Progress is more easily measured, as the full scope is known in advance
  • Team members can work on different projects simultaneously
  • Customer presence isn’t strictly required after the requirements phase
  • Makes it easier when multiple software components must be designed for integration with external systems due to early known design
  • Once a step has been completed, developers can’t easily go back to a previous stage and make changes
  • The initial requirements can’t be changed without heavy impact
  • Testing the whole product at the end is risky due to finding bugs in early written code
  • A customer’s evolving needs are not taken into account. When changes are demanded this will impact the deadlines and budget
  • Possibility of a dissatisfied customer with their delivered software product due to not seeing the product until it is almost finished
  • Value is added every sprint
  • Easier to add features that are up-to-date with the latest industry developments
  • Project priorities are set before every sprint and evaluated after each sprint
  • Customer feedback is allowed and will contribute to the final end product
  • Testing each sprint (also by the customer) ensures no surprises at the end
  • High level of customer involvement (strong sense of ownership)
  • Short time to market: quickly produce a basic version of working software
  • Transparency is high
  • Deviations on the final product can arise due to no existence of a definitive plan
  • Customers need to have the time for the high degree of involvement otherwise the product will not match their requirements
  • Additional sprints could be added due to added requirements, because not all these requirements are clear during the start of the sprints, this may increase costs for the customer
  • The iterative nature may lead to a reduction in overall system quality, as there is less emphasis on understanding the finished system as a whole early in the project


After putting the information together, what can we conclude from all this? Both methodologies have their own strengths and weaknesses. The choice of methodology really depends on the goals you want to achieve. This all comes down to the context of a project. In fact, will it not be better to combine aspects from both methodologies to make the best possible software development process for the project?

When should you use the Waterfall methodology?

  1. When customers will not have the ability to change the scope of the project once it has begun
  2. When a clear image of what the final product should be must be worked out in advance
  3. When definition and quality are the keys to success instead of fast delivery

When should you use the Agile methodology?

  1. When customers need to be able to change the scope of the project
  2. When there isn’t a clear picture of what the final product should look like
  3. When quick production is more important than the quality of the product
  4. When the product is intended for an industry with fast changing standards, like software development
  5. When you have skilled developers available who are adaptable and able to think independently

Ultimately, although the way in which you do your work is important, most important is delivering a solid and supportable product that satisfies the customer’s needs!


Learn Python: Automate your routine with a python script

In two of the previous posts, show Git branch on your Linux prompt and Git colored output, we’ve learned how to make work on your Debian/Ubuntu Linux with Git more usable.  It would be useful to have some script that does this for you to save you or someone else some time in the future. My idea is to script it with Python!

This article is a tutorial with an example of the usage of various basic Python modules. You can use parts of it as building blocks for your own automation needs.

Step 1: Create dist files to append .bashrc and .gitconfig

First, we need to create two empty files and put in a few lines of code:

# Add git branch if its present to PS1
parse_git_branch() {
 git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
if [ "$color_prompt" = yes ]; then
 PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;31m\] $(parse_git_branch)\[\033[00m\]\$ '
 PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w $(parse_git_branch)\$ '

bashrc.dist – to display Git branch name on your command prompt.

lg=log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative


[color "branch"]
current=yellow reverse

[color "diff"]
meta=yellow bold
frag=magenta bold
old=red bold
new=green bold

[color "status"]

gitconfig.dist – to use shorter commands when operating Git.

Step 2: Display Git branch on command prompt

Let’s write a simple Python script. We will read/write files, search with regular expressions  and install package (colordiff) using three modules: os (miscellaneous operating system interfaces)re (regular expressions) and subprocess (subprocess management) .

The example below displays the first task for script. It opens your local .bashrc (if it exists), executes method show_branch_in_shell , which modifies bashrc content with code we stored in bashrc.dist beforehand. If any content changes, the script will overwrite the existing file.

#!/usr/bin/python -tt

import re
import os
import subprocess

# get user home directory
home_dir = os.path.expanduser('~')
# path to distfiles
bashrc_dist_filename = 'bashrc.dist'
gitconfig_dist_filename = 'gitconfig.dist'
# We will identify if our addon exists by this comment
git_prompt_regexp = r'# Add git branch if its present to PS1'
# flag for content change
content_changed = False

def show_branch_in_shell(bashrc_content):
    global content_changed

    # modify bashrc_conent only if regexp is not match
    if not re.search(git_prompt_regexp, bashrc_content):
        bashrc_dist_handler = open(bashrc_dist_filename, 'r')
        dist_content = bashrc_dist_handler.read()
        bashrc_content = bashrc_content + '\n' + dist_content
        content_changed = True

    return bashrc_content

def main():
    path_bash = os.path.join(home_dir, '.bashrc')
    if not os.path.isfile(path_bash):
        print('bashrc is not found')

    # read local .bashrc file
    file_handler = open(path_bash, 'rU')
    bashrc_content = file_handler.read()

    # execute changes
    bashrc_content = show_branch_in_shell(basrc_content)

    if content_changed:
        # save changed bashrc
        file_handler = open(path_bash, 'w')
if __name__ == '__main__':

Step 3: Enable Git color output

Now we have script with one method implemented. Our next step is to enable color prompt in bashrc. You can do it manually by setting the force_color_prompt parameter value to ‘yes’. Let’s modify our script. It is good to use regular expressions to find if it is enabled or not:

def color_prompt_enable(bashrc_content):
    # Searches for commented out "force_color_prompt" and enables it
    return re.sub(r'#\s*force_color_prompt\s*=\s*yes', r'force_color_prompt=yes', bashrc_content)

After that, we need to have colordiff package installed on our Linux. Here is implementation of install_colordiff method:

def install_colordiff():
    # check if colordiff is installed
    out = subprocess.check_output(['apt-cache', 'policy', 'colordiff'])

    if re.search(r'Installed:\s*\(none\)', str(out)):
        # install with "sudo" if not exists
        subprocess.call(['sudo', 'apt-get', 'install', 'colordiff'])
        print('colordiff has been installed')

Step 4: Add useful Git aliases

We’re almost finished. Last step is to add a few useful Git aliases. For this, we will need to read content from our gitconfig.dist and append it in your ~/.gitconfig file.

def add_git_aliases():
    # make absolute path for new .gitconfig in user home directory
    home_gitconfig_path = os.path.join(home_dir, '.gitconfig')
    if not os.path.exists(home_gitconfig_path):
        # create .gitconfig file if it doesn't exists
        subprocess.call(['cp', gitconfig_dist_filename, home_gitconfig_path])
        print('.gitconfig file has been created')

In this example, I assume I do not have ~/.gitconfig or have it empty. You might want to perform additional logic to merge ditconfig.dist with your existing config. In this case we will use Python module called configparser (configuration file parser). Let’s import this module to our script and modify add_git_aliases() function:

# in case of using Python2 use ConfigParser instead of configparser
import configparser

def add_git_aliases():
    # make absolute path for new .gitconfig in user home directory
    home_gitconfig_path = os.path.join(home_dir, '.gitconfig')
    if not os.path.exists(home_gitconfig_path):
        # create .gitconfig file if it doesn't exists
        subprocess.call(['cp', gitconfig_dist_filename, home_gitconfig_path])
        print('.gitconfig file has been created')

    # optional (if exists, merge 2 configs and write the result)
    config = configparser.ConfigParser()

    # set up config file name
    config.filename = '.gitconfig'

    # write merged config to disk
    file_handler = open(home_gitconfig_path, 'w')

    print('.gitconfig file has been updated\n')

Step 5: Complete script

Now we have all the methods implemented we need to finish the script. Add those methods in a sequence execution and it is complete.

# execute changes
bashrc_content = show_branch_in_shell(

Basic implementation is now finished. Feel free to add your own improvements to the script, such as more Linux distributives support, version control, custom useful aliases, and share this experience with other users!

With you newly gained knowledge and experience in Python you can now create your own Linux system administration scripts. Let me know what you came up with, please share them using the comments.

Source references:

  1. Script source on GitHub
  2. Python operating system interfaces module documentation
  3. Python regular expressions module documentation
  4. Python subprocess module documentation
  5. Python configparser module documentation