Part 1. HARD Tips
Code review – for the benefit of the project
Code reviews are an extremely powerful way to maintain good code quality in a project. A fresh look from a more experienced project buddy will likely reveal some issues that escaped the eyes of an inexperienced developer during the implementation process. You should treat this process as an opportunity to learn something and understand your mistakes, and not be offended and upset. A good review is not only dry remarks “fix this and this”, but also an explanation of why it is worth doing this. True, the reviewer should refrain from too many minor quibbles, so as not to delay the process, and formulate, if possible, all the comments on the code base in one pass. Most of the minor caveats can be avoided with linters and auto-formatting, more on that later.
Tools for code review can be platforms GitHub, Bitbucket, Gitlab with their Pull / Merge Requests.
Design before implementation
Often, inexperienced and overconfident developers start coding without any attempt to design an application before starting to develop it. Over time, this will lead to the fact that there will not be a single standard / approach to the development of the same functionality. For example, without uniform standards, it may turn out that one endpoint is written by classes, another – by functions, the third – in some other way. During design, you should at least structurally outline the main application modules and the way they interact, define the application layers and the path of calls through them: from the entry point (endpoint) to low-level interaction with the data / base.
Draw.io and plant uml can be used as tools for drawing such structures to distribute to others in the process to set standards within a specific codebase.
Use boilerplate
If you are an inexperienced developer who has to deploy an application from scratch, you should use a ready-made boilerplate for the main framework chosen for development. It takes skills and experience to build a project from scratch, so ready-made templates written by experienced people are a good way to get started. They often have almost everything you need to start development with minimal settings: tests, linters, configuration, etc. As a template engine for projects, you can use the Cookiecutter, for which there are already many ready-made templates for different frameworks.
Monolith instead of microservices
If you had to start developing an application, immediately ditch the idea of making microservices. Make a monolith. With it, you, at least, will no longer need to maintain interservice communication, debugging will become much easier, and, in general, it will be easier for you to develop. No matter how hype and fashionable the words “microservices”, “serverless architecture” are, forget about them, most likely, you will get confused in them and at some point will not be able to support them normally. This does not mean that microservices or serverless architecture are bad, it just means that it is too early for you as a beginner to use them.
Apply tools to maintain code quality
Linter is your best friend
Python is a multi-paradigm language with a lot of liberties and assumptions. It is sometimes difficult for an inexperienced developer to resist the temptation to use a specific feature of the language in order to save a line or two, harming readability, support and along the way creating a couple of floating bugs without even knowing about it.
The static code analyzer is able to check the code for compliance with PEP8, check the syntax and identify some floating bugs even before launch (for example, using mutable types in the default parameters of keyword arguments), is able to point out potentially dangerous places in the code, report unused imports and much more. In general, this is an extremely useful tool for both beginners and experienced developers, allowing you to deprive the review of most of the minor comments on the quality of the code, and not the logic in general.
Tools: Flake8 or Pylint (I prefer flake8).
Advanced typing – assistant in debugging and project development
While Python is remarkably dynamic, duck typing can sometimes be confusing even for seasoned fighters. The absence of the need to write types, especially in non-obvious places, often after a couple of months leads to a misunderstanding of what the code is doing at all. The second line from PEP20 reads “Explicit is better than implicit”. Accordingly, nothing prevents us from making the behavior of our own code more explicit by adding types. At least, in all declarations of functions and methods, which will allow us to find out the return type of the function and the expected type of arguments for any call, either using IDE hints, or by looking at the declaration of this very function. Together with inline documentation, this will greatly increase the code readability, ease of reuse and debug. Moreover, it is possible to introduce static typing checking, which will force everyone to follow the typing.