ncdulo / suppylement

Quick & easy to use nutritional supplement tracking software.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filters from `Application.display` should migrate to `Data`

ncdulo opened this issue · comments

Is your feature request related to a problem? Please describe.
Our current implementation to handle filtering arguments (--more, --before, --name, etc) is by filtering our copy of the data using if blocks to iteratively filter our data. This approach works, and it works well -- within Application.display. Those same arguments and filters are also desired in other modes. To repeat the code in each place would be an unnecessary burden and leave much more room for bugs & errors.

Describe the solution you'd like
The statements which actually perform the filtering can be made more general-purpose and broken down into individual members of Data. To do so, would allow us to re-use the same set of filtering logic throughout Application without repeating in each location.

I propose a set of filtering methods added in to Data that will accept a filter criteria and apply that filter onto the instance's copy of Data._data. Methods such as Data.amount_less_than, Data.date_before, and Date.new_equal are envisioned here. They can probably be made even more general purpose to handle any column, or set of criteria. That may not be a bad idea to prevent another refactor in the future and allow far greater extensibility.

Because we will be applying the filters to an internal copy of the data, we need to consider how we actually access pieces of that data from within Application. Data._data is not intended to be directly accessed and the changes proposed here may effect how methods such as Application.display work.

I would also like to update Arguments so that we do not need to re-create the same sets of sub-parsers, or arguments for each mode where we want to re-use the data filters we create. However, that is getting a bit out of scope and would best serve in it's own issue.

Describe alternatives you've considered
I have briefly considered the implementation above using two separate copies of the data. Data._data and Data._display_data. The latter being used when applying sort or filtering operations so that we can write back to disk without worry of losing data. This is not being further considered because I feel it would just create complexity where none is needed.

As long as any write operations follow the format: read, apply, write; there should be no issues with data loss. At least due to this, anyway. Plenty of other ways to watch out for!

Additional context
No additional context required at this time.

Quick Shower Thought: We can create a generic Data.filer_data(filters_to_apply) method, where filters_to_apply is a dictionary of the desired filters. The dictionary should use the filter action as the key, and the filter amount/search term as the value. Alternatively, we can use nested dictionaries to separate filter column from filter action/term. Something like below seems like a solid place to start.

# Example of dictionary passed into Data.filter_data()
filters_to_apply = {
    'amount': {
        'less_than': 2500,
        'more_than': 2000,
    },
    'date': {
        'equal_to': '2020-02-25',
        'before': '2020-02-10',
    },
}

Note that we will need to consider how the dictionary is assembled. The presence or absence of arguments, or default values should be taken into account during object creation. Ideally, we will only have the values we wish to filter by included in the dictionary. The only thing Data.filter_data() should need to check for, is out-of-bounds. The Application only determines if it is a valid argument, then passes in to the dictionary for processing.

This way, we can use one set of generic filters and filtering logic, and Application only creates the dictionary and sticks it in. We may be onto something! Those couple days break may have paid off!

Work on this issue has begun in the feature/data_filters branch. Not quite ready for a pull request, not by a long shot. Soon! 😄

https://github.com/ncdulo/suppylement/tree/feature/data_filters