How to write code that is easy to understand and maintain without adding documentation.
In this post, I am going to share some tips and good practices to achieve what I and my colleagues used to call “Self Documenting Code ©”.
The examples used here are in the context of the Python programming language but the same can apply to other languages too.
Some of those tips may sound trivial and common sense but you’d be surprised how many people don’t follow those recommendations.
Use expressive variables and functions names
This is single-handedly the most important tip that can make your code much easier to read and understand.
It’s fine to use long variable names. Trust me, after a couple of months, it’s much better to have a bit bigger code files compared to spending hours trying to decrypt those 3 letters variables scattered everywhere.
Do not reuse variables
Self-explanatory. Reusing variables will not make your program use less memory in python. Maybe it’s the case in low-level languages like C but even if it’s the case, sacrificing a couple of bytes to remove any future confusion is definitely worth it.
Also, this is about reusing the actual variable, not the variable name. You can have different variables in different places with the same name if needed.
Avoid utils.py
Utils files have a tendency to grow from just an innocent collection of shared functions to a Frankenstein dump truck used to avoid the cognitive load needed to put functions and classes in the right place.
What to do then? Put them where they are mostly used. Or create a new module. Even if it’s a single function or class. This will increase readability and give you space to extend them in the future.
Do you really need to use OOP?
I am talking about small and medium-size projects. OOP encapsulation is a great tool in many cases but I noticed that many developers see it as an end-all-be-all must-do. Like the old saying: If the only tool you have is a hammer, you will start treating all your problems like a nail.
One tip that helps the decision to use or not use OOP is to ask the following question:
Does this problem benefit from OOP concepts: Encapsulation, Inheretence and/or, Polymorphisme?
Encapsulation, Inheritance, and Polymorphism are the main pillars of OOP. It only makes sense to questions the utility of those concepts for the specific problem before diving into OOP.
Small functions with no side effects:
I love the Unix philosophy: Do One Thing and Do It Well. I think that principle can also be applied when writing functions.
It can be implemented by writing small, well-bounded functions with clearly defined inputs and outputs. Function with Side effects should be kept to a minimum
Your code will not only be easier to read but also easier to test, troubleshoot and extend later which is a very welcome side effect.