Last active
November 16, 2019 17:57
-
-
Save ptmcg/86a3f26fb03fe521ceb43dceb8439f89 to your computer and use it in GitHub Desktop.
classmethod to validate mix-and-match kwargs
This file contains hidden or 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
""" | |
https://chat.stackoverflow.com/transcript/message/47865711#47865711 | |
Well it's mainly "utility functions", ie I need to define a (keplerian) orbit. Which is normally done by giving | |
semi-major axis, eccentricity, inclination, argument periapsis and longitude ascending node. However there are lots | |
of "variations": ie for parabolic orbits the semi major axis is replaced by semi latus rectum. Or you can just use | |
state variables at a point (position + velocity in 3 dimensions). Or you could replace the semi major axis + | |
eccentricity by peri + apo apsis. | |
""" | |
class Orbit: | |
def __init__(self, | |
_validated=False, | |
semi_major_axis=None, | |
eccentrity=None, | |
inclination=None, | |
periapsis=None, | |
longitude_ascending_node=None, | |
semi_latus_rectum=None, | |
init_position=None, | |
init_velocity=None, | |
peri_apsis=None, | |
apo_apsis=None, | |
): | |
if not _validated: | |
raise TypeError("do not use default constructor for Orbit, use Orbit.make_orbit") | |
@classmethod | |
def make_orbit(cls, **kwargs): | |
valid_kwarg_combs = [ | |
'semi_major_axis eccentricity inclination periapsis longitude_ascending_node'.split(), | |
'semi_latus_rectum eccentricity inclination periapsis longitude_ascending_node'.split(), | |
'init_position init_velocity'.split(), | |
'peri_apsis apo_apsis inclination periapsis longitude_ascending_node'.split(), | |
] | |
for kwargs_comb in valid_kwarg_combs: | |
if set(kwargs_comb) == set(kwargs): | |
return cls(_validated=True, **kwargs) | |
raise TypeError("improper kwargs combination") | |
# a legit construction | |
o = Orbit.make_orbit(init_position=[1,2,3], init_velocity=[4,5,6]) | |
# raises a TypeError | |
o = Orbit.make_orbit(init_position=[1,2,3]) | |
# also raises a TypeError - don't call the constructor directly | |
o = Orbit(init_position=[1,2,3], init_velocity=[4,5,6]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment