title: How to pythonically have partially-mutually exclusive optional arguments?
body: <p>As a simple example, take a <code>class</code> <a href="https://en.wikipedia.org/wiki/Ellipse" rel="nofollow">Ellipse</a> that can return its properties such as area <code>A</code>, circumference <code>C</code>, major/minor axis <code>a/b</code>, eccentricity <code>e</code>etc. In order to get that, one obviously has to provide precisely two of its parameters to obtain all the other ones, though as a special case providing only one parameter should assume a circle. Three or more parameters that are consistent should yield a warning but work, otherwise obviously raise an exception.</p>
  
  <p>So some examples of valid <code>Ellipse</code>s are:</p>
  
  <pre><code>Ellipse(a=5, b=2)
  Ellipse(A=3)
  Ellipse(a=3, e=.1)
  Ellipse(a=3, b=3, A=9*math.pi)  # note the consistency
  </code></pre>
  
  <p>while invalid ones would be</p>
  
  <pre><code>Ellipse()
  Ellipse(a=3, b=3, A=7)
  </code></pre>
  
  <p>The constructor would therefore either contain many <code>=None</code> arguments,</p>
  
  <pre><code>class Ellipse(object):
      def __init__(self, a=None, b=None, A=None, C=None, ...):
  </code></pre>
  
  <p>or, probably more sensible, a simple <code>**kwargs</code>, maybe adding the option to provide <code>a,b</code> as positional arguments,</p>
  
  <pre><code>class Ellipse(object):
      def __init__(self, a=None, b=None, **kwargs):
          kwargs.update({key: value
                         for key, value in (('a', a), ('b', b))
                         if value is not None})
  </code></pre>
  
  <p>So far, so good. But now comes the actual implementation, i.e. figuring out which parameters were provided and which were not and determine all the others depending on them, or check for consistency if required.</p>
  
  <p>My first approach would be a simple yet tedious combination of many</p>
  
  <pre><code>if 'a' in kwargs:
      a = kwargs['a']
      if 'b' in kwargs:
          b = kwargs['b']
          A = kwargs['A'] = math.pi * a * b
          f = kwargs['f'] = math.sqrt(a**2 - b**2)
          ...
      elif 'f' in kwargs:
          f = kwargs['f']
          b = kwargs['b'] = math.sqrt(a**2 + f**2)
          A = kwargs['A'] = math.pi * a * b
          ...
      elif ...
  </code></pre>
  
  <p>and so on<sup>*</sup>. But is there no better way? Or is this class design totally bollocks and I should create constructors such as <code>Ellipse.create_from_a_b(a, b)</code>, despite that basically making the "provide three or more consistent parameters" option impossible?</p>
  
  <p>Bonus question: Since the <a href="https://en.wikipedia.org/wiki/Ellipse#Circumference" rel="nofollow">ellipse's circumference</a> involves elliptic integrals (or elliptic functions if the circumference is provided and the other parameters are to be obtained) which are not exactly computationally trivial, should those calculations actually be in the constructor or rather be put into the <code>@property Ellipse.C</code>?</p>
  
  <hr>
  
  <p><sup>*</sup> I guess at least one readability improvement would be always extracting <code>a</code> and <code>b</code> and calculating the rest from them but that means recalculating the values already provided, wasting both time and precision...</p>