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
Preprocessor refactor #1232
Merged
Merged
Preprocessor refactor #1232
Changes from 14 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1df41c6
Removed Rename and Group preprocessors
jlstevens 990ef5e
Removed the preprocessors argument from Stream constructor
jlstevens 0935110
Added rename argument and method to Stream class
jlstevens 9e7b787
Added validation for rename mapping
jlstevens 7b1d8a6
Removed the Preprocessor class from streams.py
jlstevens 383f73d
Defined Stream.preprocess method which can be overwritten by subclasses
jlstevens d0e8c8a
Removed TestPreprocessors from teststreams.py
jlstevens 2e9e9b8
Replaced preprocess with transfrom method applied in update
jlstevens 68fe6ee
Implemented PlotSize transform according to scale parameter
jlstevens 71a9b43
Added test to ensure all stream parameters are declared constant
jlstevens 009ede7
Declared index parameter of Selection1D stream as constant
jlstevens 09d51a5
Added six unit tests for stream parameter renaming
jlstevens 8784e6e
Fixed bug in PlotSize.transform method
jlstevens 32a1e6d
Added 4 unit tests of the PlotSize scale transform
jlstevens 65131a2
Updated docstrings of Stream class and rename method
jlstevens File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,60 +10,6 @@ | |
from .core import util | ||
|
||
|
||
class Preprocessor(param.Parameterized): | ||
""" | ||
A Preprocessor is a callable that takes a dictionary as an argument | ||
and returns a dictionary. Where possible, Preprocessors should have | ||
valid reprs that can be evaluated. | ||
|
||
Preprocessors are used to set the contents of a stream based on the | ||
parameter values. They may be used for debugging purposes or to | ||
remap or repack parameter values before they are passed onto to the | ||
subscribers. | ||
""" | ||
|
||
def __call__(self, params): | ||
return params | ||
|
||
|
||
|
||
class Rename(Preprocessor): | ||
""" | ||
A preprocessor used to rename parameter values. | ||
""" | ||
|
||
mapping = param.Dict(default={}, doc=""" | ||
The mapping from the parameter names to the designated names""") | ||
|
||
def __init__(self, **mapping): | ||
super(Rename, self).__init__(mapping=mapping) | ||
|
||
def __call__(self, params): | ||
return {self.mapping.get(k,k):v for (k,v) in params.items()} | ||
|
||
def __repr__(self): | ||
keywords = ','.join('%s=%r' % (k,v) for (k,v) in sorted(self.mapping.items())) | ||
return 'Rename(%s)' % keywords | ||
|
||
|
||
|
||
class Group(Preprocessor): | ||
""" | ||
A preprocessor that keeps the parameter dictionary together, | ||
supplying it as a value associated with the given key. | ||
""" | ||
|
||
def __init__(self, key): | ||
super(Group, self).__init__(key=key) | ||
|
||
def __call__(self, params): | ||
return {self.key:params} | ||
|
||
def __repr__(self): | ||
return 'Group(%r)' % self.key | ||
|
||
|
||
|
||
class Stream(param.Parameterized): | ||
""" | ||
A Stream is simply a parameterized object with parameters that | ||
|
@@ -115,7 +61,7 @@ def trigger(cls, streams): | |
stream.deactivate() | ||
|
||
|
||
def __init__(self, preprocessors=[], source=None, subscribers=[], | ||
def __init__(self, rename={}, source=None, subscribers=[], | ||
linked=True, **params): | ||
""" | ||
Mapping allows multiple streams with similar event state to be | ||
|
@@ -130,9 +76,9 @@ def __init__(self, preprocessors=[], source=None, subscribers=[], | |
""" | ||
self._source = source | ||
self.subscribers = subscribers | ||
self.preprocessors = preprocessors | ||
self._hidden_subscribers = [] | ||
self.linked = linked | ||
self._rename = self._validate_rename(rename) | ||
|
||
# The metadata may provide information about the currently | ||
# active event, i.e. the source of the stream values may | ||
|
@@ -143,6 +89,23 @@ def __init__(self, preprocessors=[], source=None, subscribers=[], | |
if source: | ||
self.registry[id(source)].append(self) | ||
|
||
def _validate_rename(self, mapping): | ||
param_names = [k for k in self.params().keys() if k != 'name'] | ||
for k,v in mapping.items(): | ||
if k not in param_names: | ||
raise KeyError('Cannot rename %r as it is not a stream parameter' % k) | ||
if v in param_names: | ||
raise KeyError('Cannot rename to %r as it clashes with a ' | ||
'stream parameter of the same name' % v) | ||
return mapping | ||
|
||
def rename(self, **mapping): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add docstring. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 65131a2 |
||
params = {k:v for k,v in self.get_param_values() if k != 'name'} | ||
return self.__class__(rename=mapping, | ||
source=self._source, | ||
subscribers=self.subscribers, | ||
linked=self.linked, **params) | ||
|
||
|
||
def deactivate(self): | ||
""" | ||
|
@@ -164,21 +127,24 @@ def source(self, source): | |
self.registry[id(source)].append(self) | ||
|
||
|
||
def transform(self): | ||
""" | ||
Method that can be overwritten by subclasses to process the | ||
parameter values before renaming is applied. Returns a | ||
dictionary of transformed parameters. | ||
""" | ||
return {} | ||
|
||
@property | ||
def contents(self): | ||
remapped = {k:v for k,v in self.get_param_values() if k!= 'name' } | ||
for preprocessor in self.preprocessors: | ||
remapped = preprocessor(remapped) | ||
return remapped | ||
filtered = {k:v for k,v in self.get_param_values() if k!= 'name' } | ||
return {self._rename.get(k,k):v for (k,v) in filtered.items()} | ||
|
||
|
||
def update(self, trigger=True, **kwargs): | ||
def _set_stream_parameters(self, **kwargs): | ||
""" | ||
The update method updates the stream parameters in response to | ||
some event. | ||
|
||
If trigger is enabled, the trigger classmethod is invoked on | ||
this particular Stream instance. | ||
Sets the stream parameters which are expected to be declared | ||
constant. | ||
""" | ||
params = self.params().values() | ||
constants = [p.constant for p in params] | ||
|
@@ -188,6 +154,19 @@ def update(self, trigger=True, **kwargs): | |
for (param, const) in zip(params, constants): | ||
param.constant = const | ||
|
||
def update(self, trigger=True, **kwargs): | ||
""" | ||
The update method updates the stream parameters in response to | ||
some event. If the stream has a custom transform method, this | ||
is applied to transform the parameter values accordingly. | ||
|
||
If trigger is enabled, the trigger classmethod is invoked on | ||
this particular Stream instance. | ||
""" | ||
self._set_stream_parameters(**kwargs) | ||
transformed = self.transform() | ||
if transformed: | ||
self._set_stream_parameters(**transformed) | ||
if trigger: | ||
self.trigger([self]) | ||
|
||
|
@@ -196,10 +175,11 @@ def __repr__(self): | |
cls_name = self.__class__.__name__ | ||
kwargs = ','.join('%s=%r' % (k,v) | ||
for (k,v) in self.get_param_values() if k != 'name') | ||
if not self.preprocessors: | ||
if not self._rename: | ||
return '%s(%s)' % (cls_name, kwargs) | ||
else: | ||
return '%s(%r, %s)' % (cls_name, self.preprocessors, kwargs) | ||
return '%s(%r, %s)' % (cls_name, self._rename, kwargs) | ||
|
||
|
||
|
||
def __str__(self): | ||
|
@@ -276,9 +256,16 @@ class PlotSize(Stream): | |
Returns the dimensions of a plot once it has been displayed. | ||
""" | ||
|
||
width = param.Integer(300, doc="The width of the plot in pixels") | ||
width = param.Integer(300, constant=True, doc="The width of the plot in pixels") | ||
|
||
height = param.Integer(300, constant=True, doc="The height of the plot in pixels") | ||
|
||
height = param.Integer(300, doc="The height of the plot in pixels") | ||
scale = param.Number(default=1.0, constant=True, doc=""" | ||
Scale factor to scale width and height values reported by the stream""") | ||
|
||
def transform(self): | ||
return {'width': int(self.width * self.scale), | ||
'height': int(self.height * self.scale)} | ||
|
||
|
||
class RangeXY(Stream): | ||
|
@@ -327,7 +314,7 @@ class Selection1D(Stream): | |
A stream representing a 1D selection of objects by their index. | ||
""" | ||
|
||
index = param.List(default=[], doc=""" | ||
index = param.List(default=[], constant=True, doc=""" | ||
Indices into a 1D datastructure.""") | ||
|
||
|
||
|
@@ -353,9 +340,6 @@ def contents(self): | |
for k in self._obj.params().keys() if k!= 'name'} | ||
else: | ||
remapped={k:v for k,v in self._obj.get_param_values() if k!= 'name'} | ||
|
||
for preprocessor in self.preprocessors: | ||
remapped = preprocessor(remapped) | ||
return remapped | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Did none of the docstrings mention preprocessors? Either way docstrings should now mention the rename argument.
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.
Fixed in 65131a2