Skip to content

Coding Best Practices

Yang Ding edited this page May 28, 2021 · 8 revisions

Unofficial Coding Style Guide (work in progress)

API code

  • API code should live in ivadomed/ivadomed.

  • Application code (code using the API) should preferably live in ivadomed/. For example, sample scripts should be in ivadomed/scripts/.

  • API code should be modularized properly. For example, a small module simple_module could be self-contained in ivadomed/ivadomed/simple_module.py whereas a larger, more complex module could be split in multiple files such as ivadomed/ivadomed/compled_module/part_1.py and ivadomed/ivadomed/compled_module/part_2.py, etc.

  • Application code imports API code via from ivadomed.example_module import stuff

  • API code should not import application code! API code can import other local modules using from ivadomed.example_module import stuff. Relative imports should be avoided (https://www.python.org/dev/peps/pep-0008/#imports).

  • API code should not print to the terminal. Use logging instead.

  • API code should avoid modifying the user's environment. For example don't use chdir().

  • API code responsible for processing/computation logic should avoid creating/deleting files or perform other unrelated IO stuff.

    Example: an API function responsible for converting an image from format_a to format_b. The function signature should be convert_image_from_a_to_b(img: AImage) -> BImage. The function accepts and image of type AImage and returns an image of type BImage. Since its responsibility lies in the conversion logic, it should not take paths or filenames as arguments nor create the converted image on disk. The class implementing AImage and BImage should have a function save(path: str) to save the image to disk

  • API code should stay generic and accept/return low-level objects. For example, API functions should take Images instead of paths to images (see point above).

Gotchas / Tips that will save you hours.

  • Many environment (macOS) require additional installation/dependencies that unless (and even if) you are using Conda, might reuqire MANUAL installation. Read ivadome.org installation guide TO THE LETTER. Then ask for help before opening issues.
  • PyTorch.Tensor exhibit some interesting behavior: Even though it is past by reference to functions/method post refactoring process, some operations apparently destroys the references unless returned so usually a return reference is REQUIRED. When in doubt, always return Tensor data type and do not rely on reference alone.
  • CI environments do not have GPU.
  • Just because unit tests past doesn't mean all edge cases are covered.
  • Sometimes, multiple bugs can work together to make the program work and leave you wonder how anything worked before when you only discover one bug of such bug network. Write a unit test for that bug network when encountered.
  • If using labmda expression, make sure the logic is VERY clear to novice.
  • Aim to write dumb, easy to follow, intention clear simple code that work together to do wonderful things.
  • Try to keep functions/methods/class short, not in terms of complicated one liner, elegant lambda expression, but in using more higher level functions that human with limited cognitive capacity (such as outside Ballmer's peak) can follow easily and call each other to work together.
  • Do not try to outsmart yourself because we are getter dumber daily, not smarter (calculated as: known knowledge / knowledge you aware of) and whatever cool tricks YOU try to pull NOW will stump future YOU into masochistic submissions of week long struggle trying to understand what you did before.