-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ENH: _StringFuncParser to get numerical functions callables from strings #7464
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
Changes from 1 commit
0ad3710
509ed9f
bb042f6
4fa16f3
c5770fd
69f2a04
94a1af0
331d5d3
a45f217
3bd901e
c143e75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -517,3 +517,36 @@ def test_flatiter(): | |
|
||
assert 0 == next(it) | ||
assert 1 == next(it) | ||
|
||
|
||
class TestFuncParser(object): | ||
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. if you insist on writing your own lambdas instead of using numpy, then please test that the lambda functions are correct (no stray typos or the like) 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. There is a parametric test for each possible case, and it tests both the direct and the inverse, so it should be ok. |
||
x_test = np.linspace(0.01, 0.5, 3) | ||
validstrings = ['linear', 'quadratic', 'cubic', 'sqrt', 'cbrt', | ||
'log', 'log10', 'power{1.5}', 'root{2.5}', | ||
'log(x+{0.5})', 'log10(x+{0.1})'] | ||
results = [(lambda x: x), | ||
(lambda x: x**2), | ||
(lambda x: x**3), | ||
(lambda x: x**(1. / 2)), | ||
(lambda x: x**(1. / 3)), | ||
(lambda x: np.log(x)), | ||
(lambda x: np.log10(x)), | ||
(lambda x: x**1.5), | ||
(lambda x: x**(1 / 2.5)), | ||
(lambda x: np.log(x + 0.5)), | ||
(lambda x: np.log10(x + 0.1))] | ||
|
||
@pytest.mark.parametrize("string", validstrings, ids=validstrings) | ||
def test_inverse(self, string): | ||
func_parser = cbook._StringFuncParser(string) | ||
f = func_parser.get_func() | ||
finv = func_parser.get_invfunc() | ||
assert_array_almost_equal(finv(f(self.x_test)), self.x_test) | ||
|
||
@pytest.mark.parametrize("string, func", | ||
zip(validstrings, results), | ||
ids=validstrings) | ||
def test_values(self, string, func): | ||
func_parser = cbook._StringFuncParser(string) | ||
f = func_parser.get_func() | ||
assert_array_almost_equal(f(self.x_test), func(self.x_test)) |
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.
You should raise KeyError if you're explicitly catching the KeyError, otherwise I don't see the point in differentiating the value errors.
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.
Well, actually from the point of view of the dictionary it is a key error, but from the point of view of the user, it may be seen as a value error in one of the input arguments, as he does not need to know that this is stored in a dictionary and access with the string as a key. In any case, I am happy to switch to KeyError.
The reason I have two cases was to differentiate from TypeError, because in this case it may not be as safe to cast the input as a string for printing the error message. The way the code is now there is no chance it will not be a string, so yes, I am happy to just have a single except.
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 yeah, then I vote for use one for now and split if a need arises.