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
[MRG] ENH: Added instance type check for plot_dipole function and also a test for it #606
[MRG] ENH: Added instance type check for plot_dipole function and also a test for it #606
Conversation
I have removed the flake8 errors |
hnn_core/viz.py
Outdated
else: | ||
if not isinstance(dpl, Dipole): |
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.
do you need to nest here? Zen of Python:
Flat is better than nested
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.
do you ever enter this condition? See above in L271 ... it is turned into a list
hnn_core/viz.py
Outdated
@@ -273,6 +273,18 @@ def plot_dipole(dpl, tmin=None, tmax=None, ax=None, layer='agg', decim=None, | |||
elif average: | |||
dpl = dpl + [average_dipoles(dpl)] | |||
|
|||
if type(dpl) == list: |
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.
use isinstance
for type checks ... and in any case object equality is not done using ==
. You should use is
.
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.
Sorry @jasmainak , I missed the L271. This condition is redundant and also the else block. I have updated the changes. Please check them
You should use the phrase "closes #511", otherwise the linked PR will not get closed when this PR is merged. See: |
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more @@ Coverage Diff @@
## master #606 +/- ##
==========================================
- Coverage 92.19% 92.12% -0.07%
==========================================
Files 22 22
Lines 4229 4231 +2
==========================================
- Hits 3899 3898 -1
- Misses 330 333 +3
... and 1 file with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
hnn_core/viz.py
Outdated
@@ -273,6 +273,11 @@ def plot_dipole(dpl, tmin=None, tmax=None, ax=None, layer='agg', decim=None, | |||
elif average: | |||
dpl = dpl + [average_dipoles(dpl)] | |||
|
|||
for single_dpl in dpl: | |||
if not isinstance(single_dpl, Dipole): | |||
raise ValueError('Arg 1 should be of type dipole or list of dipol' |
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.
say dpl
instead of Arg 1
since that's what we call it in the function signature. And nitpick but dipole -> Dipole since class names are always capitalized in PEP convention
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.
Sure will make these changes
Can you update |
Should I update in Current Changelog in whats_new.rst? |
doc/whats_new.rst
Outdated
@@ -32,6 +32,9 @@ Changelog | |||
- Add ability to record voltages and synaptic currents from all sections in :class:`~hnn_core.CellResponse`, | |||
by `Nick Tolley`_ in :gh:`502`. | |||
|
|||
- Add ability to check instance type of Dipole in :func:`~hnn_core.viz.plot_dipole`, |
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 is more of a bugfix I would say ... but this will not get rendered properly. Did you check how to build the documentation in the contributing guide:
https://jonescompneurolab.github.io/hnn-core/dev/contributing.html
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.
Sure I will put it in bugfix and check the rendering properly
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.
Yes, look at the bottom of the page. See also: https://sublime-and-sphinx-guide.readthedocs.io/en/latest/references.html#links-to-external-web-pages
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.
Hey @jasmainak I made all changes. Please check them once
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.
hnn_core/viz.py
Outdated
raise ValueError('dpl should be of type Dipole or list of Dipole, ' | ||
f'but {single_dpl} is a {type(single_dpl)}') |
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.
If single_dpl
happens to be a list or ndarray, this error message will be long and potentially hard to read.
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.
What alternative do you suggest moving forward here?
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.
raise ValueError('dpl should be of type Dipole or list of Dipole, ' | |
f'but {single_dpl} is a {type(single_dpl)}') | |
raise ValueError('dpl should be of type Dipole or list of Dipole ' | |
f'but is of type {type(single_dpl)}') |
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.
We just don't want the traceback to be huge if the user accidentally enters dpl
as a list of list
or ndarray
.
Also, you'll need to rebase @raj1701. Let me know if you need help with this. |
I can give it a shot. I'll contact you if I get stuck. |
@rythorpe I thinks I was successful with the rebase. Please check once. Thanks |
hnn_core/viz.py
Outdated
raise ValueError('dpl should be of type Dipole, ' | ||
f'but {single_dpl } is a {type(single_dpl )}') |
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.
raise ValueError('dpl should be of type Dipole, ' | |
f'but {single_dpl } is a {type(single_dpl )}') | |
raise ValueError('dpl should be of type Dipole or list of Dipole, ' | |
f'but is a list containing type {type(single_dpl)}') |
You're almost done @raj1701, just a minor adjustment to the warning message! |
hnn_core/viz.py
Outdated
if not isinstance(single_dpl, Dipole): | ||
raise ValueError('dpl should be of type Dipole or list of ' | ||
'Dipole, but is a list containing ' | ||
f'type {type(single_dpl )}') |
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.
f'type {type(single_dpl )}') | |
f'type {type(single_dpl)}') |
This is nitpicky, but we really want to keep the code as clean and readable as possible.
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.
Removed extra spaces
hnn_core/viz.py
Outdated
dpl = dpl + [average_dipoles(dpl)] | ||
else: | ||
raise ValueError('dpl should be of type Dipole, ' | ||
f'but is a type {type(dpl )}') |
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.
f'but is a type {type(dpl )}') | |
f'but is a type {type(dpl)}') |
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.
Also, I guess we should update this one to say "dpl should be of type Dipole or list of Dipole[...]" as we do above so that users don't get conflicting messages when errors pop up.
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.
Actually, I just realized why don't we use _validate_type
here like in the rest of the codebase? So we're not reinventing the wheel
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.
So instead of using isinstance()
, _validate_type
should be used ?
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.
those are mostly doing other operations than type-checks after the isinstance
... in general, the smaller your diff is, the better. Larger diff and logic means we have to check carefully to make sure there are no corner cases. In this case, if _validate_type
works, you should use it. It is also more DRY
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.
+1 for _validate_type
- I totally forgot about that function.
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.
Ok will add _validate_type
in the code
hnn_core/viz.py
Outdated
elif isinstance(dpl, list): | ||
for single_dpl in dpl: | ||
_validate_type(single_dpl, Dipole, 'dpl', 'Dipole, list of Dipole') | ||
if average: | ||
dpl = dpl + [average_dipoles(dpl)] | ||
else: | ||
_validate_type(dpl, Dipole, 'dpl', 'Dipole, list of Dipole') |
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.
do you even need to do this? Can't you just do:
_validate_type(dpl, Dipole, 'Dipole, list of Dipole')
?
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.
In the earlier code, there already was a else if ladder :
if isinstance(dpl, Dipole):
dpl = [dpl]
elif average:
dpl = dpl + [average_dipoles(dpl)]
-Now the 'dpl' can be of type Dipole or list of Dipole.
- I think if we can pass multiple types to
_validate_type()
then we can do type checking in one go else we will be needing a similar else-if code. - Therefore I merged the two together.
- The line 279 code is simply to point error. If the control reaches line 279, the type passed is always invalid. It is just a corner case where type error needs to be raised. eg- dpl is an integer 10 then control will reach line 279
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.
I can try passing dipole and list of Dipole as types to _validate_type()
like this
_validate_type(dpl,[Dipole, [Dipole]],'Dipole, list of Dipole'))
.
I will try this and let you know the results.
If there is some other way then please let me know
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.
I can pass types = [Dipole,list]
only. Is there a way to pass list of Dipoles as an argument? I tried with [Dipole]
and list(Dipole)
but both didn't work
I think its correct and much more simplified. Now I get what you were trying to convey @jasmainak. |
hnn_core/viz.py
Outdated
_validate_type(this_dpl, Dipole, 'dpl', 'Dipole, list of Dipole') | ||
|
||
if average: | ||
dpl = dpl + [average_dipoles(dpl)] |
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.
@jasmainak what if someone happens to pass in a numpy array of Dipole objects? This would be an easy mistake to make and would pass all of our checks, but would get weird on L277 when the averaging step assumes dpl + [average_dioles(dpl)]
is an appending operation.
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.
@rythorpe good catch! How about making use of duck typing? Unfortunately the numpy
append does not work the same way as a list ... it does not work in-place. In MNE, we start most functions by saying arr = np.array(arr)
to normalize lists and arrays, and then work pretending it's an array. That ship seems to have sailed here though. I could also place an explicit error if you prefer.
Fixed errors Fixed rebase errors
194ca10
to
efd4d04
Compare
@raj1701 try not to make too many commits for a simple change. It will make your life difficult with respect to rebasing. Make use of |
efd4d04
to
fc1e84c
Compare
Are we ready to rebase and merge @raj1701 @jasmainak? |
Yes will remember this. I faced many rebase errors here also. |
Yep, I changed the PR to MRG. Please squash and merge @rythorpe ! |
Thanks @raj1701 and @jasmainak! |
Closes #511
I made changes in plot_dipole function in viz.py to type of argument 1. Iteration is used when a list of dipoles is passed. I have included a test in test_dipole.py where [dipole, integer] is passed as an argument to plot_dipole() and the appropriate error message is checked using pytest.