Skip to content

Instantly share code, notes, and snippets.

Last active November 16, 2019 17:57
Show Gist options
  • 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
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,
if not _validated:
raise TypeError("do not use default constructor for Orbit, use Orbit.make_orbit")
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