Reducing the cyclomatic complexity - Coding in style - Episode 9

Welcome to Coding in style, a series of short videos about how to improve  our coding.

This is Dragos and you are watching the Episode number 9 where we talk about how to reduce the complexity of a program.

What if you asked somebody the following question: how can I get to the downtown? And the answer was: You take the bus 102 or 103. If you take the 102, you go for two blocks and get off. Then, if it’s morning, you take 104 bus, if it’s evening and during a weekday you take 105. If it’s weekend you take 106. If you take 104, you get off after 3 blocks, if you take 105 after 5 blocks. Nobody can remember such a thing. But, lots of times, we write code like this.

As you know, the developing process does not end when you finish a task. It does not end when you launch the product or when you fix a bug. It finishes only when the code and the product are trashed and erased from existence. Until then, every little piece of code you write has a big chance to be visited again and changed.

Because of that, it is good idea to write awesome code every step of the way. Do to others as you would have them do to you can be translated, in this case, write your code as you would like others to write the code for you. In a good style, that is.

Maybe one of the most important qualities some code has is to be easy to understand. If nobody can understand our code, it does not mean we are very smart and the code is awesome. No, no, no. On the contrary. It means our brain is so complicated, that we are not able to write simple code.

There is one measure for the complexity of the code. It is called cyclomatic complexity.

The cyclomatic complexity defines the number of possible paths a piece of code can follow. It can be defined for a whole app or for a function.

For example:

//Example 1

func printHello() {

   print("Hello")

}

There is only one option of execution, so the complexity is 1.

The following function has complexity 2, as there are two possible paths:

//Example 2

func checkIfTeenager(age:Int) {

   if age < 13 {

       print("not teenager")

   } else {

       print("teenager")

   }

}

While there is some debate about what complexity should be maximum, it is clear that the smaller the better.

Here are some suggestions to reduce it.

//Example 3

func checkIfPositive(n:Int) -> Bool {

   if n > 0 {

       return true

   } else {

       return false

   }

}

The function has the complexity 2 as there are two different paths. The more if-s one adds the bigger the complexity is.

We can eliminate the if statement, and thus reducing the complexity, by returning directly the Boolean:

func checkIfPositive1(n:Int) -> Bool {

   return (n > 0)

}

//Example 4

func convertToString(n:Int) -> String {

   switch n {

       case 0:

           return "zero"

       case 1:

           return "one"

       case 2:

           return "two"

       case 3:

           return "three"

       case 4:

           return "four"

       case 5:

           return "five"

       case 6:

           return "six"

       case 7:

           return "seven"

       case 8:

           return "eight"

       case 9:

           return "nine"

       default:

           return "unknown"

   }

}

This ugly function has complexity 11. It also has ugliness 1000, but that is not a measure that is invented yet.

What to do?

We can replace the ugly function with:

func convertToString1(n:Int) -> String {

   if (n>=0) && (n<=9) {

       let numberAsString = ["zero", "one", "two", "three", "four", "five",

"six", "seven", "eight", "nine"]

       return numberAsString[n]

   } else {

       return "unknown"

   }

}

In this case, the complexity is down to 2.

Let’s check another example, for formatting an address:

//Example 5

func formatAddress(street: String, city:String, country:String) -> String {

   if street == "" {

       if city == "" {

           if country == "" {

               return ""

           } else {

               return country

           }

       } else {

           if country == "" {

               return city

           } else {

               return city + "," + country

           }

       }

   } else {

       if city == "" {

           if country == "" {

               return street

           } else {

               return street + "," + country

           }

       } else {

           if country == "" {

               return street + "," + city

           } else {

               return street + "," + city + ", " + country

           }

       }

   }

}

Not only it is a solution that does not look nice, it is also error prone. Also, it is long. And it has the complexity of 8, which is pretty big.

We can reduce the complexity by writing a helper function that just adds a command to an item:

func appendItem(item:String) -> String {

   if item == "" {

       return ""

   } else {

       return item + ","

   }

}

Then we can format the address by appending all the elements to each other:

func formatAddress1(street: String, city:String, country:String) -> String {

   var result = appendItem(item: street)

+ appendItem(item: city)

+ appendItem(item: country)

   if result.hasSuffix(",") {

       result.remove(at: result.index(before: result.endIndex))

   }

   return result

}

That is about it for today. We talked about reducing the complexity of the code. While it might seem awesome that one is able to write complex code, the reality is the another way round. The smarter one developer is, the simpler and easier to understood code he writes.

What do you think about the topic? What are the ways you like to simplify your code? Feel free to leave a message to the video or send me an email.

Do you have any idea for a topic, send me a message as well!

That’s about it for now. See you next time!

To view or add a comment, sign in

More articles by Dragos Ionel

  • AIGeeks 2019 in review, plans for 2020

    As we’re wrapping 2019 up, we have high hopes for how AI will improve our lives in 2020. This year, we organized and…

    2 Comments
  • How can AIGeeks help you?

    As you know AIGeeks is a Non Profit trying to improve our world around us using AI. Other than organizing the meetup…

  • Be cautious with the ternary operator

    The operators in a programming language, in general, and in Swift, in particular, are of three types: Unary - that…

    2 Comments
  • Use long names when writting your code

    Unfortunately, we have been used to the fact that a name has nothing to do with the object it names. John, Mary, and…

  • Write tests

    Welcome to another post about how to improve our code. Today we are trying to prove that the quality of the code…

    4 Comments
  • How to name a function - Coding in Style - episode 11

    Welcome to Coding in style, a series of short videos about how to improve our code. This is Dragos and you are watching…

  • To comment or not to comment

    Welcome to Coding in Style, a series of short videos about how we can improve our code. This is the episode 6 where we…

    2 Comments
  • Coding in style in 60 seconds - Comments

    Welcome to Coding in Style in 60 seconds. This is Dragos and you are watching a series of short videos about how we can…

  • Get smart by being stupid

    Do you know why programming is the best job ever? From the thousands and thousands of possible jobs out there…

  • Coding in style in 60 seconds - capitalization

    Welcome to “Coding in Style in 60 seconds”, a collection of short videos about how we can improve our code in simple…

Others also viewed

Explore content categories