4.1. Duplicate Code

The most common code smell is duplicate code. Duplicate code is any source code that you could have created by copying and pasting some other code into your program. For example, this short program contains duplicate code. Notice that it asks how the user is feeling three times:

>>> print('Good morning!')
>>> print('How are you feeling?')
>>> feeling = input()
>>> print('I am happy to hear that you are feeling ' + feeling + '.')
>>> print('Good afternoon!')
>>> print('How are you feeling?')
>>> feeling = input()
>>> print('I am happy to hear that you are feeling ' + feeling + '.')
>>> print('Good evening!')
>>> print('How are you feeling?')
>>> feeling = input()
>>> print('I am happy to hear that you are feeling ' + feeling + '.')
Good morning!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good afternoon!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good evening!
How are you feeling?
ok
I am happy to hear that you are feeling ok.

Duplicate code is a problem because it makes changing the code diffi- cult; a change you make to one copy of the duplicate code must be made to every copy of it in the program. If you forget to make a change somewhere, or if you make different changes to different copies, your program will likely end up with bugs.

The solution to duplicate code is to deduplicate it; that is, make it appear once in your program by placing the code in a function or loop. In the fol- lowing example, I’ve moved the duplicate code into a function and then repeatedly called that function:

>>> def askFeeling():
>>>     print('How are you feeling?')
>>>     feeling = input()
>>>     print('I am happy to hear that you are feeling ' + feeling + '.')
>>> print('Good morning!')
>>> askFeeling()
>>> print('Good afternoon!')
>>> askFeeling()
>>> print('Good evening!')
>>> askFeeling()
Good morning!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good afternoon!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good evening!
How are you feeling?
ok
I am happy to hear that you are feeling ok.

In this next example, I’ve moved the duplicate code into a loop:

>>> for timeOfDay in ['morning', 'afternoon', 'evening']:
>>>     print('Good ' + timeOfDay + '!')
>>>     print('How are you feeling?')
>>>     feeling = input()
>>>     print('I am happy to hear that you are feeling ' + feeling + '.')
Good morning!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good afternoon!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good evening!
How are you feeling?
ok
I am happy to hear that you are feeling ok.

You could also combine these two techniques and use a function and a loop:

>>> def askFeeling(timeOfDay):
>>>     print('Good ' + timeOfDay + '!')
>>>     print('How are you feeling?')
>>>     feeling = input()
>>>     print('I am happy to hear that you are feeling ' + feeling + '.')
>>>
>>> for timeOfDay in ['morning', 'afternoon', 'evening']:
>>>     askFeeling(timeOfDay)
Good morning!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good afternoon!
How are you feeling?
ok
I am happy to hear that you are feeling ok.
Good evening!
How are you feeling?
ok
I am happy to hear that you are feeling ok.

Notice that the code that produces the “Good morning/afternoon/ evening!” messages is similar but not identical. In the third improvement to the program, I parameterized the code to deduplicate the identical parts. Meanwhile, the timeOfDay parameter and timeOfDay loop variable replace the parts that differ. Now that I’ve deduplicated this code by removing the extra copies, I only need to make any necessary changes in one place.

As with all code smells, avoiding duplicate code isn’t a hard-and-fast rule you must always follow. In general, the longer the duplicate code sec- tion or the more duplicate copies that appear in your program, the stronger the case for deduplicating it. I don’t mind copying and pasting code once or even twice. But I generally start to consider deduplicating code when three or four copies exist in my program.

Sometimes, code is just not worth the trouble of deduplicating. Compare the first code example in this section to the most recent one. Although the duplicate code is longer, it’s simple and straightforward. The deduplicated example does the same thing but involves a loop, a new timeOfDay loop vari- able, and a new function with a parameter that is also named timeOfDay .

Duplicate code is a code smell because it makes your code harder to change consistently. If several duplicates are in your program, the solution is to place code inside a function or loop so it appears only once.