17db96d56Sopenharmony_ci# Copyright 2007 Google, Inc. All Rights Reserved. 27db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement. 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141. 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciTODO: Fill out more detailed documentation on the operators.""" 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_cifrom abc import ABCMeta, abstractmethod 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ciclass Number(metaclass=ABCMeta): 137db96d56Sopenharmony_ci """All numbers inherit from this class. 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci If you just want to check if an argument x is a number, without 167db96d56Sopenharmony_ci caring what kind, use isinstance(x, Number). 177db96d56Sopenharmony_ci """ 187db96d56Sopenharmony_ci __slots__ = () 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci # Concrete numeric types must provide their own hash implementation 217db96d56Sopenharmony_ci __hash__ = None 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci## Notes on Decimal 257db96d56Sopenharmony_ci## ---------------- 267db96d56Sopenharmony_ci## Decimal has all of the methods specified by the Real abc, but it should 277db96d56Sopenharmony_ci## not be registered as a Real because decimals do not interoperate with 287db96d56Sopenharmony_ci## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, 297db96d56Sopenharmony_ci## abstract reals are expected to interoperate (i.e. R1 + R2 should be 307db96d56Sopenharmony_ci## expected to work if R1 and R2 are both Reals). 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ciclass Complex(Number): 337db96d56Sopenharmony_ci """Complex defines the operations that work on the builtin complex type. 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci In short, those are: a conversion to complex, .real, .imag, +, -, 367db96d56Sopenharmony_ci *, /, **, abs(), .conjugate, ==, and !=. 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci If it is given heterogeneous arguments, and doesn't have special 397db96d56Sopenharmony_ci knowledge about them, it should fall back to the builtin complex 407db96d56Sopenharmony_ci type as described below. 417db96d56Sopenharmony_ci """ 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci __slots__ = () 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci @abstractmethod 467db96d56Sopenharmony_ci def __complex__(self): 477db96d56Sopenharmony_ci """Return a builtin complex instance. Called for complex(self).""" 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci def __bool__(self): 507db96d56Sopenharmony_ci """True if self != 0. Called for bool(self).""" 517db96d56Sopenharmony_ci return self != 0 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci @property 547db96d56Sopenharmony_ci @abstractmethod 557db96d56Sopenharmony_ci def real(self): 567db96d56Sopenharmony_ci """Retrieve the real component of this number. 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci This should subclass Real. 597db96d56Sopenharmony_ci """ 607db96d56Sopenharmony_ci raise NotImplementedError 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci @property 637db96d56Sopenharmony_ci @abstractmethod 647db96d56Sopenharmony_ci def imag(self): 657db96d56Sopenharmony_ci """Retrieve the imaginary component of this number. 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci This should subclass Real. 687db96d56Sopenharmony_ci """ 697db96d56Sopenharmony_ci raise NotImplementedError 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci @abstractmethod 727db96d56Sopenharmony_ci def __add__(self, other): 737db96d56Sopenharmony_ci """self + other""" 747db96d56Sopenharmony_ci raise NotImplementedError 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci @abstractmethod 777db96d56Sopenharmony_ci def __radd__(self, other): 787db96d56Sopenharmony_ci """other + self""" 797db96d56Sopenharmony_ci raise NotImplementedError 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci @abstractmethod 827db96d56Sopenharmony_ci def __neg__(self): 837db96d56Sopenharmony_ci """-self""" 847db96d56Sopenharmony_ci raise NotImplementedError 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci @abstractmethod 877db96d56Sopenharmony_ci def __pos__(self): 887db96d56Sopenharmony_ci """+self""" 897db96d56Sopenharmony_ci raise NotImplementedError 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci def __sub__(self, other): 927db96d56Sopenharmony_ci """self - other""" 937db96d56Sopenharmony_ci return self + -other 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci def __rsub__(self, other): 967db96d56Sopenharmony_ci """other - self""" 977db96d56Sopenharmony_ci return -self + other 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci @abstractmethod 1007db96d56Sopenharmony_ci def __mul__(self, other): 1017db96d56Sopenharmony_ci """self * other""" 1027db96d56Sopenharmony_ci raise NotImplementedError 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci @abstractmethod 1057db96d56Sopenharmony_ci def __rmul__(self, other): 1067db96d56Sopenharmony_ci """other * self""" 1077db96d56Sopenharmony_ci raise NotImplementedError 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci @abstractmethod 1107db96d56Sopenharmony_ci def __truediv__(self, other): 1117db96d56Sopenharmony_ci """self / other: Should promote to float when necessary.""" 1127db96d56Sopenharmony_ci raise NotImplementedError 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci @abstractmethod 1157db96d56Sopenharmony_ci def __rtruediv__(self, other): 1167db96d56Sopenharmony_ci """other / self""" 1177db96d56Sopenharmony_ci raise NotImplementedError 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci @abstractmethod 1207db96d56Sopenharmony_ci def __pow__(self, exponent): 1217db96d56Sopenharmony_ci """self**exponent; should promote to float or complex when necessary.""" 1227db96d56Sopenharmony_ci raise NotImplementedError 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci @abstractmethod 1257db96d56Sopenharmony_ci def __rpow__(self, base): 1267db96d56Sopenharmony_ci """base ** self""" 1277db96d56Sopenharmony_ci raise NotImplementedError 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci @abstractmethod 1307db96d56Sopenharmony_ci def __abs__(self): 1317db96d56Sopenharmony_ci """Returns the Real distance from 0. Called for abs(self).""" 1327db96d56Sopenharmony_ci raise NotImplementedError 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci @abstractmethod 1357db96d56Sopenharmony_ci def conjugate(self): 1367db96d56Sopenharmony_ci """(x+y*i).conjugate() returns (x-y*i).""" 1377db96d56Sopenharmony_ci raise NotImplementedError 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci @abstractmethod 1407db96d56Sopenharmony_ci def __eq__(self, other): 1417db96d56Sopenharmony_ci """self == other""" 1427db96d56Sopenharmony_ci raise NotImplementedError 1437db96d56Sopenharmony_ci 1447db96d56Sopenharmony_ciComplex.register(complex) 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ciclass Real(Complex): 1487db96d56Sopenharmony_ci """To Complex, Real adds the operations that work on real numbers. 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci In short, those are: a conversion to float, trunc(), divmod, 1517db96d56Sopenharmony_ci %, <, <=, >, and >=. 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci Real also provides defaults for the derived operations. 1547db96d56Sopenharmony_ci """ 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci __slots__ = () 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci @abstractmethod 1597db96d56Sopenharmony_ci def __float__(self): 1607db96d56Sopenharmony_ci """Any Real can be converted to a native float object. 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci Called for float(self).""" 1637db96d56Sopenharmony_ci raise NotImplementedError 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci @abstractmethod 1667db96d56Sopenharmony_ci def __trunc__(self): 1677db96d56Sopenharmony_ci """trunc(self): Truncates self to an Integral. 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci Returns an Integral i such that: 1707db96d56Sopenharmony_ci * i>0 iff self>0; 1717db96d56Sopenharmony_ci * abs(i) <= abs(self); 1727db96d56Sopenharmony_ci * for any Integral j satisfying the first two conditions, 1737db96d56Sopenharmony_ci abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. 1747db96d56Sopenharmony_ci i.e. "truncate towards 0". 1757db96d56Sopenharmony_ci """ 1767db96d56Sopenharmony_ci raise NotImplementedError 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci @abstractmethod 1797db96d56Sopenharmony_ci def __floor__(self): 1807db96d56Sopenharmony_ci """Finds the greatest Integral <= self.""" 1817db96d56Sopenharmony_ci raise NotImplementedError 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci @abstractmethod 1847db96d56Sopenharmony_ci def __ceil__(self): 1857db96d56Sopenharmony_ci """Finds the least Integral >= self.""" 1867db96d56Sopenharmony_ci raise NotImplementedError 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci @abstractmethod 1897db96d56Sopenharmony_ci def __round__(self, ndigits=None): 1907db96d56Sopenharmony_ci """Rounds self to ndigits decimal places, defaulting to 0. 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci If ndigits is omitted or None, returns an Integral, otherwise 1937db96d56Sopenharmony_ci returns a Real. Rounds half toward even. 1947db96d56Sopenharmony_ci """ 1957db96d56Sopenharmony_ci raise NotImplementedError 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci def __divmod__(self, other): 1987db96d56Sopenharmony_ci """divmod(self, other): The pair (self // other, self % other). 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci Sometimes this can be computed faster than the pair of 2017db96d56Sopenharmony_ci operations. 2027db96d56Sopenharmony_ci """ 2037db96d56Sopenharmony_ci return (self // other, self % other) 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci def __rdivmod__(self, other): 2067db96d56Sopenharmony_ci """divmod(other, self): The pair (self // other, self % other). 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci Sometimes this can be computed faster than the pair of 2097db96d56Sopenharmony_ci operations. 2107db96d56Sopenharmony_ci """ 2117db96d56Sopenharmony_ci return (other // self, other % self) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci @abstractmethod 2147db96d56Sopenharmony_ci def __floordiv__(self, other): 2157db96d56Sopenharmony_ci """self // other: The floor() of self/other.""" 2167db96d56Sopenharmony_ci raise NotImplementedError 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci @abstractmethod 2197db96d56Sopenharmony_ci def __rfloordiv__(self, other): 2207db96d56Sopenharmony_ci """other // self: The floor() of other/self.""" 2217db96d56Sopenharmony_ci raise NotImplementedError 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci @abstractmethod 2247db96d56Sopenharmony_ci def __mod__(self, other): 2257db96d56Sopenharmony_ci """self % other""" 2267db96d56Sopenharmony_ci raise NotImplementedError 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci @abstractmethod 2297db96d56Sopenharmony_ci def __rmod__(self, other): 2307db96d56Sopenharmony_ci """other % self""" 2317db96d56Sopenharmony_ci raise NotImplementedError 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci @abstractmethod 2347db96d56Sopenharmony_ci def __lt__(self, other): 2357db96d56Sopenharmony_ci """self < other 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci < on Reals defines a total ordering, except perhaps for NaN.""" 2387db96d56Sopenharmony_ci raise NotImplementedError 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci @abstractmethod 2417db96d56Sopenharmony_ci def __le__(self, other): 2427db96d56Sopenharmony_ci """self <= other""" 2437db96d56Sopenharmony_ci raise NotImplementedError 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci # Concrete implementations of Complex abstract methods. 2467db96d56Sopenharmony_ci def __complex__(self): 2477db96d56Sopenharmony_ci """complex(self) == complex(float(self), 0)""" 2487db96d56Sopenharmony_ci return complex(float(self)) 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_ci @property 2517db96d56Sopenharmony_ci def real(self): 2527db96d56Sopenharmony_ci """Real numbers are their real component.""" 2537db96d56Sopenharmony_ci return +self 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci @property 2567db96d56Sopenharmony_ci def imag(self): 2577db96d56Sopenharmony_ci """Real numbers have no imaginary component.""" 2587db96d56Sopenharmony_ci return 0 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci def conjugate(self): 2617db96d56Sopenharmony_ci """Conjugate is a no-op for Reals.""" 2627db96d56Sopenharmony_ci return +self 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_ciReal.register(float) 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ciclass Rational(Real): 2687db96d56Sopenharmony_ci """.numerator and .denominator should be in lowest terms.""" 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_ci __slots__ = () 2717db96d56Sopenharmony_ci 2727db96d56Sopenharmony_ci @property 2737db96d56Sopenharmony_ci @abstractmethod 2747db96d56Sopenharmony_ci def numerator(self): 2757db96d56Sopenharmony_ci raise NotImplementedError 2767db96d56Sopenharmony_ci 2777db96d56Sopenharmony_ci @property 2787db96d56Sopenharmony_ci @abstractmethod 2797db96d56Sopenharmony_ci def denominator(self): 2807db96d56Sopenharmony_ci raise NotImplementedError 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci # Concrete implementation of Real's conversion to float. 2837db96d56Sopenharmony_ci def __float__(self): 2847db96d56Sopenharmony_ci """float(self) = self.numerator / self.denominator 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci It's important that this conversion use the integer's "true" 2877db96d56Sopenharmony_ci division rather than casting one side to float before dividing 2887db96d56Sopenharmony_ci so that ratios of huge integers convert without overflowing. 2897db96d56Sopenharmony_ci 2907db96d56Sopenharmony_ci """ 2917db96d56Sopenharmony_ci return int(self.numerator) / int(self.denominator) 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ci 2947db96d56Sopenharmony_ciclass Integral(Rational): 2957db96d56Sopenharmony_ci """Integral adds methods that work on integral numbers. 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ci In short, these are conversion to int, pow with modulus, and the 2987db96d56Sopenharmony_ci bit-string operations. 2997db96d56Sopenharmony_ci """ 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci __slots__ = () 3027db96d56Sopenharmony_ci 3037db96d56Sopenharmony_ci @abstractmethod 3047db96d56Sopenharmony_ci def __int__(self): 3057db96d56Sopenharmony_ci """int(self)""" 3067db96d56Sopenharmony_ci raise NotImplementedError 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci def __index__(self): 3097db96d56Sopenharmony_ci """Called whenever an index is needed, such as in slicing""" 3107db96d56Sopenharmony_ci return int(self) 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ci @abstractmethod 3137db96d56Sopenharmony_ci def __pow__(self, exponent, modulus=None): 3147db96d56Sopenharmony_ci """self ** exponent % modulus, but maybe faster. 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci Accept the modulus argument if you want to support the 3177db96d56Sopenharmony_ci 3-argument version of pow(). Raise a TypeError if exponent < 0 3187db96d56Sopenharmony_ci or any argument isn't Integral. Otherwise, just implement the 3197db96d56Sopenharmony_ci 2-argument version described in Complex. 3207db96d56Sopenharmony_ci """ 3217db96d56Sopenharmony_ci raise NotImplementedError 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci @abstractmethod 3247db96d56Sopenharmony_ci def __lshift__(self, other): 3257db96d56Sopenharmony_ci """self << other""" 3267db96d56Sopenharmony_ci raise NotImplementedError 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci @abstractmethod 3297db96d56Sopenharmony_ci def __rlshift__(self, other): 3307db96d56Sopenharmony_ci """other << self""" 3317db96d56Sopenharmony_ci raise NotImplementedError 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci @abstractmethod 3347db96d56Sopenharmony_ci def __rshift__(self, other): 3357db96d56Sopenharmony_ci """self >> other""" 3367db96d56Sopenharmony_ci raise NotImplementedError 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ci @abstractmethod 3397db96d56Sopenharmony_ci def __rrshift__(self, other): 3407db96d56Sopenharmony_ci """other >> self""" 3417db96d56Sopenharmony_ci raise NotImplementedError 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci @abstractmethod 3447db96d56Sopenharmony_ci def __and__(self, other): 3457db96d56Sopenharmony_ci """self & other""" 3467db96d56Sopenharmony_ci raise NotImplementedError 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci @abstractmethod 3497db96d56Sopenharmony_ci def __rand__(self, other): 3507db96d56Sopenharmony_ci """other & self""" 3517db96d56Sopenharmony_ci raise NotImplementedError 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci @abstractmethod 3547db96d56Sopenharmony_ci def __xor__(self, other): 3557db96d56Sopenharmony_ci """self ^ other""" 3567db96d56Sopenharmony_ci raise NotImplementedError 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci @abstractmethod 3597db96d56Sopenharmony_ci def __rxor__(self, other): 3607db96d56Sopenharmony_ci """other ^ self""" 3617db96d56Sopenharmony_ci raise NotImplementedError 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_ci @abstractmethod 3647db96d56Sopenharmony_ci def __or__(self, other): 3657db96d56Sopenharmony_ci """self | other""" 3667db96d56Sopenharmony_ci raise NotImplementedError 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci @abstractmethod 3697db96d56Sopenharmony_ci def __ror__(self, other): 3707db96d56Sopenharmony_ci """other | self""" 3717db96d56Sopenharmony_ci raise NotImplementedError 3727db96d56Sopenharmony_ci 3737db96d56Sopenharmony_ci @abstractmethod 3747db96d56Sopenharmony_ci def __invert__(self): 3757db96d56Sopenharmony_ci """~self""" 3767db96d56Sopenharmony_ci raise NotImplementedError 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci # Concrete implementations of Rational and Real abstract methods. 3797db96d56Sopenharmony_ci def __float__(self): 3807db96d56Sopenharmony_ci """float(self) == float(int(self))""" 3817db96d56Sopenharmony_ci return float(int(self)) 3827db96d56Sopenharmony_ci 3837db96d56Sopenharmony_ci @property 3847db96d56Sopenharmony_ci def numerator(self): 3857db96d56Sopenharmony_ci """Integers are their own numerators.""" 3867db96d56Sopenharmony_ci return +self 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci @property 3897db96d56Sopenharmony_ci def denominator(self): 3907db96d56Sopenharmony_ci """Integers have a denominator of 1.""" 3917db96d56Sopenharmony_ci return 1 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ciIntegral.register(int) 394