MathEXLab / PySPOD

A Python package for spectral proper orthogonal decomposition (SPOD).
https://mathexlab.github.io/PySPOD/
MIT License
97 stars 29 forks source link

Duplicated and unnecessary code #8

Closed jdmoorman closed 3 years ago

jdmoorman commented 3 years ago

There are large amounts of duplicated or unnecessary code throughout the codebase. Some particular examples are

mengaldo commented 3 years ago

@jdmoorman Thank you, very useful insights! I should have addressed the majority of them, except a few. Below some comments regarding the ones not fixed.

Q.) "The init() function can be omitted from the classes SPOD_streaming, SPOD_low_ram, and SPOD_low_storage since it just calls super().init() in all three cases."
A.) How do you suggest to modify the code here?

Q.) "The majority of spod_low_ram.py and spod_low_storage.py are the same with minor differences for data management. The two can be combined or the shared/equivalent portions can be abstracted into separate functions." A.) I would like to maintain readability of the two while accepting some code duplication. Do you have any specific suggestions?

Q.) "Lines 9-16 of init.py can likely be deleted." A.) I would keep them such that if a user wants to run the library from source this maintains paths consistency and inclusion.

Q.) "In init.py, you can provide direct access to the classes SPOD_base, etc by changing" A.) For some reasons I did not manage to make it work. I got a circular dependency error.

jdmoorman commented 3 years ago

Q.) "The init() function can be omitted from the classes SPOD_streaming, SPOD_low_ram, and SPOD_low_storage since it just calls super().init() in all three cases." A.) How do you suggest to modify the code here?

Get rid of the __init__() method of SPOD_streaming, SPOD_low_ram, and SPOD_low_storage. i.e. Delete

Q.) "The majority of spod_low_ram.py and spod_low_storage.py are the same with minor differences for data management. The two can be combined or the shared/equivalent portions can be abstracted into separate functions." A.) I would like to maintain readability of the two while accepting some code duplication. Do you have any specific suggestions?

I suggest creating a class called e.g. SPOD_traditional_base which implements the parts of SPOD_low_ram and SPOD_low_storage that are duplicated, and have SPOD_low_ram and SPOD_low_storage inherit from SPOD_traditional_base. You can abstract any blocks of code that differ between SPOD_low_ram and SPOD_low_storage into virtual methods in SPOD_traditional_base which are overridden by methods in SPOD_low_ram and SPOD_low_storage.

Q.) "Lines 9-16 of init.py can likely be deleted." A.) I would keep them such that if a user wants to run the library from source this maintains paths consistency and inclusion.

This is not necessary for any user who follows your installation instructions from the readme. Do you work with such users? What is the benefit of running the library without installing it properly?

Q.) "In init.py, you can provide direct access to the classes SPOD_base, etc by changing" A.) For some reasons I did not manage to make it work. I got a circular dependency error.

I cannot reproduce your issue. Please provide the example you ran that resulted in such an error.

mengaldo commented 3 years ago

Q.) This is not necessary for any user who follows your installation instructions from the readme. Do you work with such users? What is the benefit of running the library without installing it properly? A.) I work with such users, but I am actively developing some additional functionalities and would prefer those lines. I do not think they create a critical issue within the library.

Q.) I suggest creating a class called e.g. SPOD_traditional_base which implements the parts of SPOD_low_ram and SPOD_low_storage that are duplicated, and have SPOD_low_ram and SPOD_low_storage inherit from SPOD_traditional_base. You can abstract any blocks of code that differ between SPOD_low_ram and SPOD_low_storage into virtual methods in SPOD_traditional_base which are overridden by methods in SPOD_low_ram and SPOD_low_storage.

A.) This will require some time.

Q.) I cannot reproduce your issue. Please provide the example you ran that resulted in such an error. A.) I changed the piece of code you suggested:

"""PySPOD init"""
# __all__ = ['spod_base', 'spod_low_storage', 'spod_low_ram', 'spod_streaming']
__all__ = ['SPOD_base', 'SPOD_low_storage', 'SPOD_low_ram', 'SPOD_streaming']

# from .spod_base        import SPOD_base
# from .spod_low_storage import SPOD_low_storage
# from .spod_low_ram     import SPOD_low_ram
# from .spod_streaming   import SPOD_streaming
from pyspod import SPOD_low_storage, SPOD_low_ram, SPOD_streaming

And here is what I get.

python test_basic.py 
Traceback (most recent call last):
  File "test_basic.py", line 15, in <module>
    from pyspod.spod_low_storage import SPOD_low_storage
  File "/Users/gian/GIT-GM/pyspod-review/tests/../pyspod/__init__.py", line 9, in <module>
    from pyspod import SPOD_low_storage, SPOD_low_ram, SPOD_streaming
ImportError: cannot import name 'SPOD_low_storage' from partially initialized module 'pyspod' (most likely due to a circular import) (/Users/gian/GIT-GM/pyspod-review/tests/../pyspod/__init__.py)
mengaldo commented 3 years ago

@jdmoorman Duplicated code shared by SPOD_low_ram and SPOD_low_storage has now been addressed. I added three common methods, compute_blocks, compute_standard_spod, and store_and_save, in SPOD_base. Thank you.