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

DM-12102: add input validation for SpherePoint(double, double, AngleUnits) constructor #283

Merged
merged 3 commits into from Oct 4, 2017

Conversation

r-owen
Copy link
Contributor

@r-owen r-owen commented Oct 4, 2017

No description provided.

Copy link
Member

@kfindeisen kfindeisen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better, but the test coverage of testDoubleDoubleUnitsConstructor is still relatively sparse. Can you at least check that getLongitude gives an in-range value for weird constructor arguments?

with self.assertRaises(pexEx.InvalidParameterError):
SpherePoint(-42.0, 91.0, degrees) # latitude out of range
with self.assertRaises(pexEx.InvalidParameterError):
SpherePoint(-42.0, -91.0, degrees) # latitude out of range
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add a test that e.g. negative longitudes get wrapped correctly? (Possibly as part of testGetLongitudeValue rather than here, since that's where the tests are done for the original constructor).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if you want the other tests from testInit2ArgErrors, like infinite latitude.

@r-owen
Copy link
Contributor Author

r-owen commented Oct 4, 2017

I greatly expanded the testing of the new SpherePoint(double, double, AngleUnit) constructor and integrated it into testing of the SpherePoint(Angle, Angle) constructor. I also took the liberty of switching to the new constructor in some places where it made the test easier to read. Please have another look.

Copy link
Member

@kfindeisen kfindeisen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Some code cleanup suggestions. Only thing that really bothers me is the long nested check... methods, but maybe those look more readable to a Python programmer.

"""
# Latitude should be checked for out-of-range.
for lat in self._poleLatitudes:
with self.assertRaises(pexEx.InvalidParameterError):
SpherePoint(0.0*degrees, self.nextUp(lat))
with self.assertRaises(pexEx.InvalidParameterError):
SpherePoint(0.0, self.nextUp(lat).asDegrees(), degrees)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be cleaner to call np.nextafter directly, or modify nextUp and nextDown to work on floating-point numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code is a bit clumsy but is obviously the same test, which I think is worth the clumsiness. I like the fact that nextUp works on Angles and am reluctant to change that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant "in addition to Angles", but ok.

@@ -155,8 +154,7 @@ def testInitNArgFail(self):
def testGetLongitudeValue(self):
"""Test if getLongitude() returns the expected value.
"""
for lon, lat in self._dataset:
point = SpherePoint(lon, lat)
def checkGetLongitudeValue(point, lon, lat):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bit too long to treat as a lambda. Consider making a private member of SpherePointTestSuite for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically that this is not a "lambda", since Python uses the keyword lambda for those. But I understand and will make them methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted all the new in-line functions and am using better iteration instead. This really cleans up the code.

@@ -191,8 +193,7 @@ def testTicket1394(self):
def testGetLatitudeValue(self):
"""Test if getLatitude() returns the expected value.
"""
for lon, lat in self._dataset:
point = SpherePoint(lon, lat)
def checkGetLatitudeValue(point, lon, lat):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, having this in checkGetLatitudeValue breaks up the flow of the code.

self.assertAlmostEqual(newLat.asDegrees(), lat.asDegrees())

for lonLatDeg, vector in pointList:
# Convert to Point3D.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this comment belong inside checkGetVector?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea. It's gone now.

for lonLat, vector in pointList:
# Convert to Point3D.
point = SpherePoint(lonLat[0]*degrees, lonLat[1]*degrees)
def checkGetVector(point, lon, lat, vector):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long lambda.

[SpherePoint(42.0*degrees, lat) for lat in self._poleLatitudes] + \
[SpherePoint(42.0, lat.asDegrees(), degrees) for lat in self._poleLatitudes] + \
[SpherePoint(42.0*degrees, 0.0*radians - lat) for lat in self._poleLatitudes] + \
[SpherePoint(42.0, (0.0*radians - lat).asDegrees(), degrees) for lat in self._poleLatitudes] + \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-lat.asDegrees() would be more concise.

Actually, since I added a negation operator to Angle, all the references to 0.0*radians can probably be removed.

@@ -333,8 +360,7 @@ def testGetItemError(self):
def testGetItemValue(self):
"""Test if indexing returns the expected value.
"""
for lon, lat in self._dataset:
point = SpherePoint(lon, lat)
def checkGetItemValue(point, lon, lat):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long lambda.

for oldElement, newElement in zip(vector, newVector):
self.assertAlmostEqual(oldElement, newElement)

# Convert back to spherical.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're removing the "Convert to Point3D" comment, you might remove this one as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I thought I had reverted the other comment to its original place but maybe not. I'll remove both of them as I don't think they add much.

Copy link
Member

@kfindeisen kfindeisen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, there's just a few places where you duplicate the try-all-constructors logic from pointSet.

SpherePoint(lon, lat),
SpherePoint(lon.asDegrees(), lat.asDegrees(), degrees),
SpherePoint(lon.asRadians(), lat.asRadians(), radians),
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very thorough!

SpherePoint(lon, lat),
SpherePoint(lon.asDegrees(), lat.asDegrees(), degrees),
SpherePoint(lon.asRadians(), lat.asRadians(), radians),
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use self.pointSet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do this in two places because in those places the test needs the input longitude or latitude and pointSet does not provide them. I considered a property pointLonLatSet but I felt it was excessive clutter for just two tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. A comment explaining that might be helpful, though.

SpherePoint(lon, lat),
SpherePoint(lon.asDegrees(), lat.asDegrees(), degrees),
SpherePoint(lon.asRadians(), lat.asRadians(), radians),
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, use self.pointSet instead of a double loop.

Check longitude in new SpherePoint(double, double, AngleUnit)
constructor.
and use that constructor where it makes more sense in existing tests
@r-owen r-owen merged commit 112e94a into master Oct 4, 2017
@ktlim ktlim deleted the tickets/DM-12102 branch August 25, 2018 06:44
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 this pull request may close these issues.

None yet

2 participants