Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
numbers.py428 linesDownload Raw Back to Lib
1# Copyright 2007 Google, Inc. All Rights Reserved.2# Licensed to PSF under a Contributor Agreement.3 4"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.5 6TODO: Fill out more detailed documentation on the operators."""7 8############ Maintenance notes #########################################9#10# ABCs are different from other standard library modules in that they11# specify compliance tests.  In general, once an ABC has been published,12# new methods (either abstract or concrete) cannot be added.13#14# Though classes that inherit from an ABC would automatically receive a15# new mixin method, registered classes would become non-compliant and16# violate the contract promised by ``isinstance(someobj, SomeABC)``.17#18# Though irritating, the correct procedure for adding new abstract or19# mixin methods is to create a new ABC as a subclass of the previous20# ABC.21#22# Because they are so hard to change, new ABCs should have their APIs23# carefully thought through prior to publication.24#25# Since ABCMeta only checks for the presence of methods, it is possible26# to alter the signature of a method by adding optional arguments27# or changing parameter names.  This is still a bit dubious but at28# least it won't cause isinstance() to return an incorrect result.29#30#31#######################################################################32 33from abc import ABCMeta, abstractmethod34 35__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]36 37class Number(metaclass=ABCMeta):38    """All numbers inherit from this class.39 40    If you just want to check if an argument x is a number, without41    caring what kind, use isinstance(x, Number).42    """43    __slots__ = ()44 45    # Concrete numeric types must provide their own hash implementation46    __hash__ = None47 48 49## Notes on Decimal50## ----------------51## Decimal has all of the methods specified by the Real abc, but it should52## not be registered as a Real because decimals do not interoperate with53## binary floats (i.e.  Decimal('3.14') + 2.71828 is undefined).  But,54## abstract reals are expected to interoperate (i.e. R1 + R2 should be55## expected to work if R1 and R2 are both Reals).56 57class Complex(Number):58    """Complex defines the operations that work on the builtin complex type.59 60    In short, those are: a conversion to complex, .real, .imag, +, -,61    *, /, **, abs(), .conjugate, ==, and !=.62 63    If it is given heterogeneous arguments, and doesn't have special64    knowledge about them, it should fall back to the builtin complex65    type as described below.66    """67 68    __slots__ = ()69 70    @abstractmethod71    def __complex__(self):72        """Return a builtin complex instance. Called for complex(self)."""73 74    def __bool__(self):75        """True if self != 0. Called for bool(self)."""76        return self != 077 78    @property79    @abstractmethod80    def real(self):81        """Retrieve the real component of this number.82 83        This should subclass Real.84        """85        raise NotImplementedError86 87    @property88    @abstractmethod89    def imag(self):90        """Retrieve the imaginary component of this number.91 92        This should subclass Real.93        """94        raise NotImplementedError95 96    @abstractmethod97    def __add__(self, other):98        """self + other"""99        raise NotImplementedError100 101    @abstractmethod102    def __radd__(self, other):103        """other + self"""104        raise NotImplementedError105 106    @abstractmethod107    def __neg__(self):108        """-self"""109        raise NotImplementedError110 111    @abstractmethod112    def __pos__(self):113        """+self"""114        raise NotImplementedError115 116    def __sub__(self, other):117        """self - other"""118        return self + -other119 120    def __rsub__(self, other):121        """other - self"""122        return -self + other123 124    @abstractmethod125    def __mul__(self, other):126        """self * other"""127        raise NotImplementedError128 129    @abstractmethod130    def __rmul__(self, other):131        """other * self"""132        raise NotImplementedError133 134    @abstractmethod135    def __truediv__(self, other):136        """self / other: Should promote to float when necessary."""137        raise NotImplementedError138 139    @abstractmethod140    def __rtruediv__(self, other):141        """other / self"""142        raise NotImplementedError143 144    @abstractmethod145    def __pow__(self, exponent):146        """self ** exponent; should promote to float or complex when necessary."""147        raise NotImplementedError148 149    @abstractmethod150    def __rpow__(self, base):151        """base ** self"""152        raise NotImplementedError153 154    @abstractmethod155    def __abs__(self):156        """Returns the Real distance from 0. Called for abs(self)."""157        raise NotImplementedError158 159    @abstractmethod160    def conjugate(self):161        """(x+y*i).conjugate() returns (x-y*i)."""162        raise NotImplementedError163 164    @abstractmethod165    def __eq__(self, other):166        """self == other"""167        raise NotImplementedError168 169Complex.register(complex)170 171 172class Real(Complex):173    """To Complex, Real adds the operations that work on real numbers.174 175    In short, those are: a conversion to float, trunc(), divmod,176    %, <, <=, >, and >=.177 178    Real also provides defaults for the derived operations.179    """180 181    __slots__ = ()182 183    @abstractmethod184    def __float__(self):185        """Any Real can be converted to a native float object.186 187        Called for float(self)."""188        raise NotImplementedError189 190    @abstractmethod191    def __trunc__(self):192        """trunc(self): Truncates self to an Integral.193 194        Returns an Integral i such that:195          * i > 0 iff self > 0;196          * abs(i) <= abs(self);197          * for any Integral j satisfying the first two conditions,198            abs(i) >= abs(j) [i.e. i has "maximal" abs among those].199        i.e. "truncate towards 0".200        """201        raise NotImplementedError202 203    @abstractmethod204    def __floor__(self):205        """Finds the greatest Integral <= self."""206        raise NotImplementedError207 208    @abstractmethod209    def __ceil__(self):210        """Finds the least Integral >= self."""211        raise NotImplementedError212 213    @abstractmethod214    def __round__(self, ndigits=None):215        """Rounds self to ndigits decimal places, defaulting to 0.216 217        If ndigits is omitted or None, returns an Integral, otherwise218        returns a Real. Rounds half toward even.219        """220        raise NotImplementedError221 222    def __divmod__(self, other):223        """divmod(self, other): The pair (self // other, self % other).224 225        Sometimes this can be computed faster than the pair of226        operations.227        """228        return (self // other, self % other)229 230    def __rdivmod__(self, other):231        """divmod(other, self): The pair (other // self, other % self).232 233        Sometimes this can be computed faster than the pair of234        operations.235        """236        return (other // self, other % self)237 238    @abstractmethod239    def __floordiv__(self, other):240        """self // other: The floor() of self/other."""241        raise NotImplementedError242 243    @abstractmethod244    def __rfloordiv__(self, other):245        """other // self: The floor() of other/self."""246        raise NotImplementedError247 248    @abstractmethod249    def __mod__(self, other):250        """self % other"""251        raise NotImplementedError252 253    @abstractmethod254    def __rmod__(self, other):255        """other % self"""256        raise NotImplementedError257 258    @abstractmethod259    def __lt__(self, other):260        """self < other261 262        < on Reals defines a total ordering, except perhaps for NaN."""263        raise NotImplementedError264 265    @abstractmethod266    def __le__(self, other):267        """self <= other"""268        raise NotImplementedError269 270    # Concrete implementations of Complex abstract methods.271    def __complex__(self):272        """complex(self) == complex(float(self), 0)"""273        return complex(float(self))274 275    @property276    def real(self):277        """Real numbers are their real component."""278        return +self279 280    @property281    def imag(self):282        """Real numbers have no imaginary component."""283        return 0284 285    def conjugate(self):286        """Conjugate is a no-op for Reals."""287        return +self288 289Real.register(float)290 291 292class Rational(Real):293    """To Real, Rational adds numerator and denominator properties.294 295    The numerator and denominator values should be in lowest terms,296    with a positive denominator.297    """298 299    __slots__ = ()300 301    @property302    @abstractmethod303    def numerator(self):304        """The numerator of a rational number in lowest terms."""305        raise NotImplementedError306 307    @property308    @abstractmethod309    def denominator(self):310        """The denominator of a rational number in lowest terms.311 312        This denominator should be positive.313        """314        raise NotImplementedError315 316    # Concrete implementation of Real's conversion to float.317    def __float__(self):318        """float(self) = self.numerator / self.denominator319 320        It's important that this conversion use the integer's "true"321        division rather than casting one side to float before dividing322        so that ratios of huge integers convert without overflowing.323 324        """325        return int(self.numerator) / int(self.denominator)326 327 328class Integral(Rational):329    """Integral adds methods that work on integral numbers.330 331    In short, these are conversion to int, pow with modulus, and the332    bit-string operations.333    """334 335    __slots__ = ()336 337    @abstractmethod338    def __int__(self):339        """int(self)"""340        raise NotImplementedError341 342    def __index__(self):343        """Called whenever an index is needed, such as in slicing"""344        return int(self)345 346    @abstractmethod347    def __pow__(self, exponent, modulus=None):348        """self ** exponent % modulus, but maybe faster.349 350        Accept the modulus argument if you want to support the351        3-argument version of pow(). Raise a TypeError if exponent < 0352        or any argument isn't Integral. Otherwise, just implement the353        2-argument version described in Complex.354        """355        raise NotImplementedError356 357    @abstractmethod358    def __lshift__(self, other):359        """self << other"""360        raise NotImplementedError361 362    @abstractmethod363    def __rlshift__(self, other):364        """other << self"""365        raise NotImplementedError366 367    @abstractmethod368    def __rshift__(self, other):369        """self >> other"""370        raise NotImplementedError371 372    @abstractmethod373    def __rrshift__(self, other):374        """other >> self"""375        raise NotImplementedError376 377    @abstractmethod378    def __and__(self, other):379        """self & other"""380        raise NotImplementedError381 382    @abstractmethod383    def __rand__(self, other):384        """other & self"""385        raise NotImplementedError386 387    @abstractmethod388    def __xor__(self, other):389        """self ^ other"""390        raise NotImplementedError391 392    @abstractmethod393    def __rxor__(self, other):394        """other ^ self"""395        raise NotImplementedError396 397    @abstractmethod398    def __or__(self, other):399        """self | other"""400        raise NotImplementedError401 402    @abstractmethod403    def __ror__(self, other):404        """other | self"""405        raise NotImplementedError406 407    @abstractmethod408    def __invert__(self):409        """~self"""410        raise NotImplementedError411 412    # Concrete implementations of Rational and Real abstract methods.413    def __float__(self):414        """float(self) == float(int(self))"""415        return float(int(self))416 417    @property418    def numerator(self):419        """Integers are their own numerators."""420        return +self421 422    @property423    def denominator(self):424        """Integers have a denominator of 1."""425        return 1426 427Integral.register(int)428 
codekingpro/portable-devtools · Team Ai