diff --git a/sizebot/lib/digidecimal.py b/sizebot/lib/digidecimal.py index ee10b74d..70fcfa5c 100644 --- a/sizebot/lib/digidecimal.py +++ b/sizebot/lib/digidecimal.py @@ -16,7 +16,7 @@ # local copy of utils.minmax to prevent circular import -def minmax(first: Decimal, second: Decimal) -> tuple[Decimal, Decimal]: +def _minmax(first: Decimal, second: Decimal) -> tuple[Decimal, Decimal]: """Return a tuple where item 0 is the smaller value, and item 1 is the larger value.""" small, big = first, second if small > big: @@ -34,22 +34,20 @@ def minmax(first: Decimal, second: Decimal) -> tuple[Decimal, Decimal]: # get the values for magic methods, instead of the objects -def values(fn: Callable) -> Callable: +def _values(fn: Callable) -> Callable: def wrapped(*args) -> Any: - valargs = [unwrapDecimal(a) for a in args] + valargs = [_unwrap_decimal(a) for a in args] return fn(*valargs) return wrapped -# TODO: CamelCase -def clampInf(value: RawDecimal, limit: RawDecimal) -> RawDecimal: +def _clamp_inf(value: RawDecimal, limit: RawDecimal) -> RawDecimal: if limit and abs(value) >= limit: value = RawDecimal("infinity") * int(math.copysign(1, value)) return value -# TODO: CamelCase -def unwrapDecimal(value: Decimal) -> RawDecimal: +def _unwrap_decimal(value: Decimal) -> RawDecimal: if isinstance(value, Decimal): value = value._rawvalue return value @@ -62,7 +60,7 @@ class Decimal(): def __init__(self, value: Decimal): # initialize from Decimal - rawvalue = unwrapDecimal(value) + rawvalue = _unwrap_decimal(value) if isinstance(rawvalue, str): if rawvalue == "∞": rawvalue = "infinity" @@ -72,8 +70,8 @@ def __init__(self, value: Decimal): values = rawvalue.split("/") if len(values) == 2: numberator, denominator = values - rawvalue = unwrapDecimal(Decimal(numberator) / Decimal(denominator)) - self._rawvalue = clampInf(RawDecimal(rawvalue), unwrapDecimal(self._infinity)) + rawvalue = _unwrap_decimal(Decimal(numberator) / Decimal(denominator)) + self._rawvalue = _clamp_inf(RawDecimal(rawvalue), _unwrap_decimal(self._infinity)) def __format__(self, spec: str) -> str: if self.is_infinite(): @@ -82,21 +80,21 @@ def __format__(self, spec: str) -> str: value = self rounded = value - dSpec = DecimalSpec.parse(spec) + d_spec = DecimalSpec.parse(spec) - fractional = dSpec.fractional - dSpec.fractional = None + fractional = d_spec.fractional + d_spec.fractional = None - accuracy = dSpec.accuracy - dSpec.accuracy = None + accuracy = d_spec.accuracy + d_spec.accuracy = None precision = 2 - if dSpec.precision is not None: - precision = int(dSpec.precision) + if d_spec.precision is not None: + precision = int(d_spec.precision) if (Decimal("10") ** -(precision + 1)) < abs(value) < Decimal("1e10") or value == 0: - dSpec.type = "f" - dSpec.precision = None + d_spec.type = "f" + d_spec.precision = None if fractional: try: denom = int(fractional[1]) @@ -106,31 +104,31 @@ def __format__(self, spec: str) -> str: else: rounded = round(value, precision) else: - dSpec.type = "e" - dSpec.precision = str(precision) + d_spec.type = "e" + d_spec.precision = str(precision) - numspec = str(dSpec) + numspec = str(d_spec) if fractional: whole = rounded.to_integral_value(ROUND_DOWN) - rawwhole = fix_zeroes(whole._rawvalue) + rawwhole = _fix_zeroes(whole._rawvalue) formatted = format(rawwhole, numspec) part = abs(whole - rounded) - fraction = format_fraction(part) + fraction = _format_fraction(part) if fraction: if formatted == "0": formatted = "" formatted += fraction else: - rawvalue = fix_zeroes(rounded._rawvalue) + rawvalue = _fix_zeroes(rounded._rawvalue) formatted = format(rawvalue, numspec) - if dSpec.type == "f": + if d_spec.type == "f": if accuracy: try: roundamount = int(accuracy[1]) except IndexError: roundamount = 0 - small, big = minmax(rounded, value) + small, big = _minmax(rounded, value) printacc = round((abs(small / big) * 100), roundamount) formatted += f" (~{printacc}% accurate)" @@ -142,52 +140,52 @@ def __str__(self) -> str: def __repr__(self) -> str: return f"Decimal('{self}')" - @values + @_values def __bool__(value) -> bool: return bool(value) - @values + @_values def __hash__(value) -> int: return hash(value) # Math Methods - @values + @_values def __eq__(value, other: Any) -> bool: return value == other - @values + @_values def __lt__(value, other: Any) -> bool: return value < other - @values + @_values def __add__(value, other: Any) -> Decimal: return Decimal(value + other) def __radd__(self, other: Any) -> Decimal: return Decimal.__add__(other, self) - @values + @_values def __sub__(value, other: Any) -> Decimal: return Decimal(value - other) def __rsub__(self, other: Any) -> Decimal: return Decimal.__sub__(other, self) - @values + @_values def __mul__(value, other: Any) -> Decimal: return Decimal(value * other) def __rmul__(self, other: Any) -> Decimal: return Decimal.__mul__(other, self) - @values + @_values def __matmul__(value, other: Any) -> Decimal: return Decimal(value @ other) def __rmatmul__(self, other: Any) -> Decimal: return Decimal.__matmul__(other, self) - @values + @_values def __truediv__(value, other: Any) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite() and isinstance(other, RawDecimal) and other.is_infinite(): raise decimal.InvalidOperation @@ -200,7 +198,7 @@ def __truediv__(value, other: Any) -> Decimal: def __rtruediv__(self, other: Any) -> Decimal: return Decimal.__truediv__(other, self) - @values + @_values def __floordiv__(value, other: Any) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite() and isinstance(other, RawDecimal) and other.is_infinite(): raise decimal.InvalidOperation @@ -213,7 +211,7 @@ def __floordiv__(value, other: Any) -> Decimal: def __rfloordiv__(self, other: Any) -> Decimal: return Decimal.__floordiv__(other, self) - @values + @_values def __mod__(value, other: Any) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return Decimal(0) @@ -232,29 +230,29 @@ def __divmod__(self, other: Any) -> tuple[Decimal, Decimal]: def __rdivmod__(self, other: Any) -> tuple[Decimal, Decimal]: return Decimal.__divmod__(other, self) - @values + @_values def __pow__(value, other: Any) -> Decimal: return Decimal(value ** other) - @values + @_values def __rpow__(value, other: Any) -> Decimal: return Decimal(other ** value) - @values + @_values def __lshift__(value, other: Any) -> Decimal: return Decimal.__mul__(value, Decimal.__pow__(Decimal(2), other)) def __rlshift__(self, other: Any) -> Decimal: return Decimal.__lshift__(other, self) - @values + @_values def __rshift__(value, other: Any) -> Decimal: return Decimal.__floordiv__(value, Decimal.__pow__(Decimal(2), other)) def __rrshift__(self, other: Any) -> Decimal: return Decimal.__rshift__(other, self) - @values + @_values def __and__(value, other: Any) -> Decimal: if (isinstance(value, RawDecimal) and value.is_infinite()): return other @@ -265,7 +263,7 @@ def __and__(value, other: Any) -> Decimal: def __rand__(self, other: Any) -> Decimal: return Decimal.__and__(other, self) - @values + @_values def __xor__(value, other: Any) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return Decimal.__invert__(other) @@ -276,7 +274,7 @@ def __xor__(value, other: Any) -> Decimal: def __rxor__(self, other: Any) -> Decimal: return Decimal.__xor__(other, self) - @values + @_values def __or__(value, other: Any) -> Decimal: if (isinstance(value, RawDecimal) and value.is_infinite()) or (isinstance(other, RawDecimal) and other.is_infinite()): return Decimal("infinity") @@ -285,33 +283,33 @@ def __or__(value, other: Any) -> Decimal: def __ror__(self, other: Any) -> Decimal: return Decimal.__or__(other, self) - @values + @_values def __neg__(value) -> Decimal: return Decimal(-value) - @values + @_values def __pos__(value) -> Decimal: return Decimal(+value) - @values + @_values def __abs__(value) -> Decimal: return Decimal(abs(value)) - @values + @_values def __invert__(value) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return -value return Decimal(~value) - @values + @_values def __complex__(value) -> complex: return complex(value) - @values + @_values def __int__(value) -> int: return int(value) - @values + @_values def __float__(value) -> float: return float(value) @@ -321,51 +319,51 @@ def __round__(value, ndigits: int = 0) -> Decimal: exp = Decimal(10) ** -ndigits return value.quantize(exp) - @values + @_values def __trunc__(value) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return value return Decimal(math.trunc(value)) - @values + @_values def __floor__(value) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return value return Decimal(math.floor(value)) - @values + @_values def __ceil__(value) -> Decimal: if isinstance(value, RawDecimal) and value.is_infinite(): return value return Decimal(math.ceil(value)) - @values + @_values def quantize(value, exp: Decimal) -> Decimal: return Decimal(value.quantize(exp)) - @values + @_values def is_infinite(value) -> bool: return value.is_infinite() - @values + @_values def is_signed(value) -> bool: return value.is_signed() @property - @values + @_values def sign(value) -> str: return "-" if value.is_signed() else "" def to_integral_value(self, *args, **kwargs) -> Decimal: return Decimal(self._rawvalue.to_integral_value(*args, **kwargs)) - @values + @_values def log10(value) -> Decimal: return Decimal(value.log10()) class DecimalSpec: - formatSpecRe = re.compile(r"""\A + re_format_spec = re.compile(r"""\A (?: (?P.)? (?P[<>=^]) @@ -381,25 +379,25 @@ class DecimalSpec: \Z """, re.VERBOSE) - def __init__(self, formatDict: dict[str, Any]): - self.align = formatDict["align"] - self.fill = formatDict["fill"] - self.sign = formatDict["sign"] - self.zeropad = formatDict["zeropad"] - self.minimumwidth = formatDict["minimumwidth"] - self.thousands_sep = formatDict["thousands_sep"] - self.precision = formatDict["precision"] - self.type = formatDict["type"] - self.fractional = formatDict["fractional"] - self.accuracy = formatDict["accuracy"] + def __init__(self, format_dict: dict[str, Any]): + self.align = format_dict["align"] + self.fill = format_dict["fill"] + self.sign = format_dict["sign"] + self.zeropad = format_dict["zeropad"] + self.minimumwidth = format_dict["minimumwidth"] + self.thousands_sep = format_dict["thousands_sep"] + self.precision = format_dict["precision"] + self.type = format_dict["type"] + self.fractional = format_dict["fractional"] + self.accuracy = format_dict["accuracy"] @classmethod def parse(cls, spec: str) -> DecimalSpec: - m = cls.formatSpecRe.match(spec) + m = cls.re_format_spec.match(spec) if m is None: raise ValueError("Invalid format specifier: " + spec) - formatDict = m.groupdict() - return cls(formatDict) + format_dict = m.groupdict() + return cls(format_dict) def __str__(self) -> str: spec = "" @@ -426,7 +424,7 @@ def __str__(self) -> str: return spec -def round_decimal(d: Decimal, accuracy: int = 0) -> Decimal: +def _round_decimal(d: Decimal, accuracy: int = 0) -> Decimal: if d.is_infinite(): return d places = Decimal(10) ** -accuracy @@ -438,26 +436,26 @@ def round_fraction(number: Decimal, denominator: Decimal) -> Decimal: return rounded -def format_fraction(value: Decimal) -> str: +def _format_fraction(value: Decimal) -> str: if value is None: return None - fractionStrings = ["", "⅛", "¼", "⅜", "½", "⅝", "¾", "⅞"] + fraction_strings = ["", "⅛", "¼", "⅜", "½", "⅝", "¾", "⅞"] part = round_fraction(value % 1, 8) - index = int(part * len(fractionStrings)) % len(fractionStrings) + index = int(part * len(fraction_strings)) % len(fraction_strings) try: - fraction = fractionStrings[index] + fraction = fraction_strings[index] except IndexError as e: logger.error("Weird fraction IndexError:\n" - f"fractionStrings = {fractionStrings!r}\n" - f"len(fractionStrings) = {len(fractionStrings)!r}\n" + f"fraction_strings = {fraction_strings!r}\n" + f"len(fraction_strings) = {len(fraction_strings)!r}\n" f"value = {value._rawvalue}\n" f"part = {part!r}\n" - f"int(part * len(fractionStrings)) = {int(part * len(fractionStrings))}") + f"int(part * len(fraction_strings)) = {int(part * len(fraction_strings))}") raise e return fraction -def fix_zeroes(d: Decimal) -> Decimal: +def _fix_zeroes(d: Decimal) -> Decimal: """Reset the precision of a Decimal to avoid values that use exponents like '1e3' and values with trailing zeroes like '100.000' fixZeroes(Decimal('1e3')) -> Decimal('100')