# Cyclomatic complexity vs repeated code

we've a python function that can be achieved in 2 ways 1st method

``````def complexity_1(x, y):
if 2 == x and 3 == y:
a=3
b=4
c = a + b
elif 2 == x and not 3 == y:
a = 3
b = 5
c = a + b
else:
c=5
return c
``````

2nd method

``````def complexity_2(x, y):
if 2 == x:
a=3
if y==3:
b=4
else:
b=5

c = a + b
else:
c=5
return c
``````

Which is the better way to do it the first one east to understand and reduces cyclomatic complexity but you're having duplicated code `c=a+b` and `a=3` twice, but in the 2nd method you don't have that duplication but hard to go through the logic which one is better and right way to do?

• Does this answer your question? How would you know if you've written readable and easily maintainable code?
– gnat
Jul 10, 2020 at 6:10
• If your measurement tool isn't measuring the thing you want, it's a bad tool. Jul 10, 2020 at 10:23
• I like Kain0_0's answer but think both of those examples have the same cyclomatic complexity which is simply the number of paths through the function. I count 3 in both cases. Jul 10, 2020 at 18:48

``````def complexity_3(x, y):
if 2 != x:
return 5

return (7 if (3 == y) else 8)
``````

Don't be afraid to exit a function from multiple locations. That advice was specific to assembly, and means always return to the caller that called you. This is (excluding some safe compiler optimisations) enforced by functions and return.

Also don't sweat cyclomatic complexity. Its a way of calculating branching, nothing more. Only the most uninteresting pieces of code that do not change their own behaviour, do not branch. Everything else necessarily must branch. Of course if the branching becomes too high (say spaghetti code) then yes some cleanup is required.

And finally code should be written to be maintainable. And by maintainable I mean very readable, because that is the single slowest thing this code will ever do. There are many ways to try and achieve this. The simplest way is to get the new guy on the team to read it. The next best way is to just get someone else to read it the longer they take/more questions they have, the harder the code is to read.

• I like your answer but in the `return (7 if (3 == y) else 8)` for simplicity I replaced with constants but how would you deal with a variable? ex: ``` def complexity_2(x, y,z): if 2 == x: a=3 if y==3: b=z else: b=z+2 c = a + b else: c=5 return c ``` Jul 10, 2020 at 2:19
• Push and Pull. Identify the common parts and either push or pull them into another scope. You have two concerns floating in this code, the calculation itself, and what parameters to pass to it. So the complicated calc `a+b` might be pushed down to `def calc(a, b): return a + b`. The setup for the cal is then `if (cond): return calc(x,6) else return calc(y, z - x)` style. Perhaps the decision about the content of `c` being `z*2 - x` or `x * cos(z)` could be pulled up and passed in as another argument. Jul 10, 2020 at 3:21
• This is a great answer. I think it's helpful to know that a lot of tools calculate cyclomatic complexity incorrectly but counting every return as another path. So while I think this has the same complexity as the other examples (3), a tool might incorrectly report this as having a complexity of 4. What's even more annoying is that because these tools do this, a fair amount of people believe that's the right way to calculate it. Jul 10, 2020 at 18:55
• What's the quickest way to distract a developer? Give them a metric to optimise. What's the quickest way to make awful code? Give the developer an awful metric. Cyclomatic Complexity (correctly implemented) is a way to get a qualitative feel, in no way should it represent a goal. Jul 12, 2020 at 23:27