Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Compare 2 or more box #144

Closed
hitengajjar opened this issue Mar 25, 2020 · 3 comments · Fixed by #145
Closed

Feature: Compare 2 or more box #144

hitengajjar opened this issue Mar 25, 2020 · 3 comments · Fixed by #145

Comments

@hitengajjar
Copy link

hitengajjar commented Mar 25, 2020

I tried and failed to look to have a compare functionality that can provide a report of what's different between 2 boxes. I notice I can compare 2 Boxes with a comparison operator e.g. Box(a=1, b=dict(c=1)) == Box(a=1, b=dict(c=1)) however it would be nice to have a special Box.compare(box2,...) method that also generates a report (maybe a Box object itself)

@cdgriffith
Copy link
Owner

cdgriffith commented Mar 25, 2020

That is a great idea. I would want to avoid adding another method, especially with that common of a word, however I think it might be good to just have a - minus ability, like it currently has the addition ability.

rough mockup would look like:

    def __sub__(self, other):
        output = self.__class__(**self.__box_config())
        for item in self:
            if item not in other:
                output[item] = self[item]
            elif isinstance(self.get(item), dict) and isinstance(other.get(item), dict):
                output[item] = self[item] - other[item]
        return output

Returning something like:

from box import Box
box_1 = Box(a={'1': 1, '2': '2'}, b='b', c='c')
box_2 = Box(a={'1': 'different_value'}, b='b')
box_1 - box_2
# Out[2]: <Box: {'a': {'2': '2'}, 'c': 'c'}>

This would all be key based. To do a compare that checked actual value differences will have to think of some way to be able to present that information back. Possibly putting conflicting values into a namedtuple or something.

@hitengajjar
Copy link
Author

Hey Chris, Thanks for considering this as a feature. Though your suggestion looks reasonable, still it doesn't exactly provide a report on what's the exact difference between 2 or more boxes (and think this is unique feature that doesn't exist in other dict based libraries I know).

Just to be sure you mean - operator will act as it works on set(). Is that correct?
If yes, then I don't think value difference should be presented in tuple form. Maybe, in such case output key-value pair from the first box in operation.

@cdgriffith
Copy link
Owner

Just found a dictionary comparison solution exists called dictdiffer (readthedocs for it) in case you were looking for a fast solution.

Quick test run with box seems fine:

In [5]: from dictdiffer import diff

In [6]: a = Box(test_dict)

In [7]: b = Box(test_dict, another_key=2)

In [8]: diff(a, b)
Out[8]: <generator object diff.<locals>._diff_recursive at 0x077735F0>

In [10]: list(diff(a,b))
Out[10]: [('add', '', [('another_key', 2)])]

In [11]: b
Out[11]: <Box: {'key1': 'value1', 'not$allowed': 'fine_value', 'BigCamel': 'hi', 'alist': [{'a': 1}], 'Key 2': {'Key 3': 'Value 3', 'Key4': {'Key5': 'Value5'}}, 'another_key': 2}>

In [12]: b.key1 = 5

In [13]: list(diff(a,b))
Out[13]: [('change', 'key1', ('value1', 5)), ('add', '', [('another_key', 2)])]

cdgriffith added a commit that referenced this issue Jul 12, 2020
* Adding support for msgpack converters `to_msgpack` and `from_msgpack`
* Adding support for comparision of `Box` to other boxes or dicts via the `-` sub operator #144 (thanks to Hitz)
* Adding support to `|` union boxes like will come default in Python 3.9 from PEP 0584
* Adding `mypy` type checking, `black` formatting and other checks on commit
* Adding new parameter `box_class` for cleaner inheritance #148 (thanks to David Aronchick)
* Adding `dotted` option for `keys` method to return box_dots style keys (thanks to ipcoder)
* Fixing box_dots to properly delete items from lists
* Fixing box_dots to properly find items with dots in their key
* Fixing that recast of subclassses of `Box` or `BoxList` were not fed box properties (thanks to Alexander Kapustin)
* Changing that sub boxes are always created to properly propagate settings and copy objects #150 (thanks to ipcoder)
* Changing that default_box will not raise key errors on `pop` #67 (thanks to Patrock)
* Changing `to_csv` and `from_csv` to have same string and filename options as all other transforms
* Changing back to no required external imports, instead have extra requires like [all] (thanks to wim glenn)
* Changing from putting all details in README.rst to a github wiki at https://github.com/cdgriffith/Box/wiki
* Changing `BoxList.box_class` to be stored in `BoxList.box_options` dict as `box_class`
* Changing `del` will raise `BoxKeyError`, subclass of both `KeyError` and `BoxError`
* Removing support for single level circular references
* Removing readthedocs generation
* Removing overrides for `keys`, `values` and `items` which will return views again
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants