-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Selector accept int string #2894
Conversation
Do we want something like:
to raise ValueError or just return an empty generator? |
I think a ValueError or whatever the equivalent error you'd get from |
That doesn't throw an error either, it also just returns an empty generator. So throwing an error in this case might actually break the API. |
So other than the uncertainty surrounding raising an error or not, this PR can be reviewed 👍 |
@jonmmease can you give this PR a sanity-check, implementation-wise, please? |
The behaviour seems like what I want :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionality and tests look good!
I left a few comments/suggestions on design.
""" | ||
|
||
# if selector is not an int, we call it on each trace to test it for selection | ||
if type(selector) != type(int()): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's a reason not to, I'd recommend if not isinstance(selector, int):
for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, along with all the other similar issues flagged by flake8
|
||
@staticmethod | ||
def _selector_matches(obj, selector): | ||
if selector is None: | ||
return True | ||
# If selector is a string then put it at the 'type' key of a dictionary | ||
# to select objects where "type":selector | ||
if type(selector) == type(str()): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's a reason not to, I'd recommend if not isinstance(selector, six.string_types):
for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
_natural_sort_strings(list(self.layout)), | ||
) | ||
layout_objs = [self.layout[k] for k in layout_keys] | ||
return _generator(self._filter_by_selector(layout_objs, [], selector)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reduction over filters approach is clever, but I think it's a bit more opaque than the current paradigm.
Also, before it returns anything this method traverses the full layout and creates several fully instantiated lists and then converts the final list to a generator. While performance probably isn't a major factor here, the original design avoids the creation of any of these lists, and it returns results one at a time as matches are found.
Refactoring stuff into functions is fine, but I'd prefer to keep the original overall structure of:
layout_keys = _natural_sort_strings(list(self.layout))
for k in layout_keys:
# filter and continue on stuff that doesn't pass filter
yield self.layout[k]
and (cur[0]["y"][1] == cur[1]), | ||
zip(trs, [10, 20]), | ||
True, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this check would be a lot clearer using a comprehension inside all
instead reduce
.
Something like
all(trace["type"] == "bar" and trace["y"][1] == y
for trace, y in zip(trc, [10, 20]))
If selector is string, transformed to dict(type=selector), if selector is int, indexes the resulting list of objects filtered down by row, col and secondary y.
if selector is string, it is converted to dict(type=selector)
e.g., select_xaxes uses this selector note: need to test new selector argument that is integer or string
string doesn't make sense in this case as they don't have a "type" key.
e.g., select_xaxes
d247ab4
to
e33e10b
Compare
closes #2891