Skip to content

Instantly share code, notes, and snippets.

@ptmcg
Last active November 16, 2019 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptmcg/86a3f26fb03fe521ceb43dceb8439f89 to your computer and use it in GitHub Desktop.
Save ptmcg/86a3f26fb03fe521ceb43dceb8439f89 to your computer and use it in GitHub Desktop.
classmethod to validate mix-and-match kwargs
"""
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