0

I am developing a program that I plan to distribute to multiple users. This consists of a folder containing the following files:

  • convert_units.py
  • fit_parameters.py
  • plot_results.py
  • top_level_module.py

The purpose of "top_level_module.py" is to import the other modules and call them as needed, as shown below:

from convert_units import convert_units
from fit_parameters import fit_parameters
from plot_results import plot_results

input_data = "somefile.csv"
intermediate_result = convert_units(input_data)
final_result = fit_parameters(intermediate_result)
plot_results(final_result)

The goal of naming the above file "top_level_module" is to help users who wish to inspect the code. Specifically, my hope is that when users see this filename they will immediately realise that this is the highest level module, and hence the correct file to read first. However, the name "top_level_module" seems verbose, and I am wondering if another name is already in common use for this purpose.

So my question is: Does anyone know if there is a convention for naming the top level module? Or if any other name would be more widely intuitive?

Appguy1
  • 33
  • 5

1 Answers1

0

One way that is used often, is to have a folder named after your module with the submoduls (convert_units.py etc.) as files in that folder and an __init__.py-file where you put your code from the main-module instead of in a separate top_level_module.py-file.

Your submoduls can even have their own submoduls and so on for bigger projects. For this you'd have e.g. instead of the convert_units.py-file a convert_units-folder again containing an __init__.py-file with the module-level code and other files or folders for the submoduls of this submodule convert_units.

Your file-structure could in the end look something like this.

my_fancy_library  # name folder after what you want to call your module
├── __init__.py  # module-level code goes here (<- top_level_module.py)
├── fit_parameters.py  # smaller submodul that fits inside one file
├── plot_results.py
├── convert_units  # bigger submodul with own submodules
│   ├── __init__.py  # module-level code of submodule
│   ├── validator.py
│   ├── custom_exceptions.py
...

Your __init__.py-file of your main-module then can look like this to implement your example:

from .convert_units import convert_units
from .fit_parameters import fit_parameters
from .plot_results import plot_results


def fit_data_and_plot(input_data):
    intermediate_result = convert_units(input_data)
    final_result = fit_parameters(intermediate_result)
    plot_results(final_result)

Better to wrap your code inside a function, or otherwise it will be executed during the import. You then use this function in another module by importing it from my_fancy_library import fit_data_and_plot and calling it with the input-path fit_data_and_plot(input_data).

You can also look at the source-code of other libraries too, to get an idea. This can be really confusing for bigger libraries like numpy, so I would start with a smaller example like dateutil.

MangoNrFive
  • 1,541
  • 1
  • 10
  • 23
  • Thanks so much for giving this suggestion. I will need to give this some consideration because the users of this program are not familiar with programming so this may be too complex for them. But it is great to know that this convention exists, and I will look into it. – Appguy1 Jul 27 '22 at 12:42
  • I would be drawn to the `__init__.py`-file first, as this is the root that is imported first and manages how the rest of the module is imported and exposed to the user. If you don't want that, you can add documentation e.g. a README.md-file to guide the user (you should do that anyway) this is the first file I would look at, this would be the same for a non programming-user I guess as README.md is a very clear message to anyone. – MangoNrFive Jul 27 '22 at 13:17
  • If you want to have a python-file that screams look at me first, you could use main.py (more generally used for the main-function inside a module so that could be confusing) or my_fancy_library.py (same name as the module itself). You'd then have to do `from my_fancy_library import my_fancy_library` or you could do `from .my_fancy_library import *` in your `__init__.py` so you can just use `import my_fancy_library` and get access to the namespace of `my_fancy_library.py`. Take all this with a grain of salt though! I'd be happy to here a second opinion. – MangoNrFive Jul 27 '22 at 13:20