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:
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.
'Odd' if n % 2 else 'Even'is anything but beautiful
- Sparse is better than dense.
'Odd' if n % 2 else 'Even'is more dense than an if/else statement
- Readability counts.
'Odd' if n % 2 else 'Even'is not as readable as an if/else statement
And, more importantly...
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.
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.