Ternary what?
Ternary operators, also known as conditional expressions in Python, can be used to make our code shorter:
But i don't like them for two reasons:
1. They often go against the Zen of Python
If you don't know the Zen of Python, start a Python interpreter and type import this
. The Zen is a set of guiding principles for writing Python code.
Arguably, most of the time conditional expressions are likely to break 3 of these principles:
- Beautiful is better than ugly.
- E.g.:
'Odd' if n % 2 else 'Even'
is anything but beautiful
- E.g.:
- Sparse is better than dense.
- E.g.:
'Odd' if n % 2 else 'Even'
is more dense than an if/else statement
- E.g.:
- Readability counts.
- E.g.:
'Odd' if n % 2 else 'Even'
is not as readable as an if/else statement
- E.g.:
And, more importantly...
2. They often trick our test coverage
Conditional expressions may make us think that we've covered all possible branches with tests when we actually have not. Check the following example:
If I run the tests with coverage, this is the output:
According to the image, I covered 100% of the lines, without missing any branch. But looking again at the code, we can see that there is no test for months of the second semester of the year.
If I use the classic if statement instead, the lack of coverage will be correctly detected:
If I run the coverage exporting the results to HTML, I can actually see which statement was skipped and which branch was partially run during the test:
Now I know that I should write a test that calls semester
with a value greater than 6 if I want the function to be 100% covered.
Conclusion
These are the reasons why I avoid conditional expressions and advise people to avoid them too: they tend to break the Zen of Python and they can fool our code coverage tools.
Granted, not every piece of code does need to be 100% covered by tests, but the ones that do should be measurable in the best way possible, and we've just seen that conditional expressions can get in our way when we are pursuing that.
Top comments (2)
That's interesting about the code coverage problem with the Python ternary. I'm just starting to learn Python myself, and I'll admit their ternary was disappointing to learn. It's the same as the CoffeeScript ternary, which I'm also not a fan of.
Neat and informative post!
Thanks!