Module digint.digint
digint
Holds the main digitwise intiger classes digint
module.
Classes
class ExtendedBasedIntiger (value: Union[int, str, Iterable[Union[int, str]]] = 0, base: int = 10, *, notation_format: Optional[NotationFormat] = NotationFormat(value_symbols=('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'), undefined_symbol='?', positive_symbol='+', negative_symbol='-', radix_point_symbol='.', group_split_symbol=None, group_split_count=0, implicit_positive=True, implicit_negative=False))
-
A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set.
Supports any initger base starting at (and including) base 1. The base is presumed to be in the traditional place value format of
value == d[x] * (base ** x)
wherevalue
is the value the digit holds in the intiger,d
is a single digit value form a sequence of digits,base
is the base, andx
is the specific index in question of the intiger.However, base 1 produces inconsistencies with this specific format. Using this logic, one would also presume that the only digit in base 1 is
0
(or whatever relevant "naught" character would be used). This is why the extention of base 1 functionality is done in a child class ofPositionalBasedIntiger
.Base 1, as implemented here, uses both the "naught" (with a value of
0
) and "unity" (with a value of '1') digits, but in a tally system. This also means that the value of any given index of a digit means very little without the context of the rest of the defined digits as well. It is also implemented in such a way that the set digits will always be grouped together, ie. all "unity" digits will be grouped together, starting at the first digit and remaining completely set all the way to the digits index that matches the value of the number represented.For these reason base 1 will have not functionality for functions that set or unset digits, as setting and unsetting digits are not relevant in unary. Attempting to do so will raise either a
BaseInvalidOpperationError
or aBaseValueError
. Deleting digits are still possible, however.Unary numbers are also fully compatible with negative values.
ex.
1111111111 (base 1) == 10 (base 10) 11111 (base 1) == 5 (base 10) 111111 (base 1) == 11 (base 2) 1101101 (base 1) == IMPOSSIBLE (the are unset digits in between the set digits) ^ ^ 000111000 (base 1) == IMPOSSIBLE (the first set digit is not the first digit in the number) ^^^
Effectively: base 1 (uniary) notation treates the value of the number as a sequence of a single type of digit that when counted add up to the value of the number.
NOTE: No functionality of any higher base is nor will modified in this class, making this class a superset of all proper positional based intiger notation formats and uniary.
Also supports customizable notation formats with the optional
notation_format
attribute, including unary.Expand source code
class ExtendedBasedIntiger(PositionalBasedIntiger): """ `ExtendedBasedIntiger` A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set. Supports any initger base starting at (and including) base 1. The base is presumed to be in the traditional place value format of `value == d[x] * (base ** x)` where `value` is the value the digit holds in the intiger, `d` is a single digit value form a sequence of digits, `base` is the base, and `x` is the specific index in question of the intiger. However, base 1 produces inconsistencies with this specific format. Using this logic, one would also presume that the only digit in base 1 is `0` (or whatever relevant "naught" character would be used). This is why the extention of base 1 functionality is done in a child class of `PositionalBasedIntiger`. Base 1, as implemented here, uses both the "naught" (with a value of `0`) and "unity" (with a value of '1') digits, but in a tally system. This also means that the value of any given index of a digit means very little without the context of the rest of the defined digits as well. It is also implemented in such a way that the set digits will always be grouped together, ie. all "unity" digits will be grouped together, starting at the first digit and remaining completely set all the way to the digits index that matches the value of the number represented. For these reason base 1 will have not functionality for functions that set or unset digits, as setting and unsetting digits are not relevant in unary. Attempting to do so will raise either a `BaseInvalidOpperationError` or a `BaseValueError`. Deleting digits are still possible, however. Unary numbers are also fully compatible with negative values. ex. ``` 1111111111 (base 1) == 10 (base 10) 11111 (base 1) == 5 (base 10) 111111 (base 1) == 11 (base 2) 1101101 (base 1) == IMPOSSIBLE (the are unset digits in between the set digits) ^ ^ 000111000 (base 1) == IMPOSSIBLE (the first set digit is not the first digit in the number) ^^^ ``` Effectively: base 1 (uniary) notation treates the value of the number as a sequence of a single type of digit that when counted add up to the value of the number. NOTE: No functionality of any higher base is nor will modified in this class, making this class a superset of all proper positional based intiger notation formats and uniary. Also supports customizable notation formats with the optional `notation_format` attribute, including unary. """ @override def __init__(self, value:Union[int, str, Iterable[Union[int, str]]] = 0, base:int = 10, *, notation_format:Optional[NotationFormat] = DEFAULT_FORMAT ): self.__base:int = 2 super().__init__(0 if base == 1 else value, base, notation_format=notation_format) if base == 1: self.base = 1 if isinstance(value, int): self.x = value elif isinstance(value, str): value = value.lstrip("0") if not all(c == "1" for c in value): raise BaseValueError(f"{value} cannot be represented in base 1") self.x = len(value) @override def copy(self, value:Optional[Union[int, str]] = None, base:Optional[int] = None, notation_format_override:Optional[NotationFormat] = None ) -> 'ExtendedBasedIntiger': """ `copy` Creates a shallow copy of this object. Keyword Arguments: `value` -- When not `None`, will overrides the `x` value of the copy. `base` -- When not `None`, will overrides the `base` of the copy. `notation_format_override` -- When not `None`, will overrides the `notation_format` of the copy. Returns: The copy of the object. """ if notation_format_override is not None: notation_format_override = self.notation_format return ExtendedBasedIntiger(value if value is not None else self.x, base if base is not None else self.base, notation_format = notation_format_override ) __copy__ = copy @override def __deepcopy__(self, _ = None) -> 'ExtendedBasedIntiger': return self.copy(None, None, None if self.notation_format is None else self.notation_format.copy() ) @property @override def base(self) -> int: """ `base` The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases. """ return self.__base @base.setter @override def base(self, value:int): if value <= 0: raise BaseValueError() self.__base = value @override def _get_single_digit(self, index:int) -> int: if self.base == 1: index = absindex(index, self.digit_length()) return 1 if index < abs(self.x) else 0 else: return super()._get_single_digit(index) @override def _pop_first(self) -> int: if self.base == 1: self.x -= 1 return 1 else: return super()._pop_first() @override def _mask_value_continuous(self, dindex: int, count: int = 1) -> int: if count <= 0: raise IndexError("The length of a continuous mask must be at least 1") if self.base == 1: return min(abs(self.x) - dindex, count) else: return super()._mask_value_continuous(dindex, count) @override def notate(self, notation_format:Optional[NotationFormat] = None) -> str: if self.base >= 2: return super().notate(notation_format) if notation_format is None: notation_format = self.notation_format if notation_format is None: raise BaseInvalidOpperationError("No format set, cannot notate") relevant_sign = "" if self.x < 0 and not notation_format.implicit_negative: if notation_format.negative_symbol is None: raise ValueError("Explicit negative values require a negative symbol") else: relevant_sign = notation_format.negative_symbol elif self.x > 0 and not notation_format.implicit_positive: if notation_format.positive_symbol is None: raise ValueError("Explicit positive values require a positive symbol") else: relevant_sign = notation_format.positive_symbol if notation_format.unity is None: raise NotationError("Cannot notate base 1 without a digit for unity") return relevant_sign + ((notation_format.unity) * self.x) @overload @override def set_digit(self, index:int, value:Union[int,str]): ... @overload @override def set_digit(self, index:Union[slice,range,Iterable[int]], value:Iterable[Union[int,str]]): ... @override # noqa:301 def set_digit(self, index:Union[int,slice,range,Iterable[int]], value:Union[int,str,Iterable[Union[int,str]]] ): if self.base == 1: raise BaseInvalidOpperationError("Digits cannot be set in base 1") super().set_digit(index, value) # type:ignore[reportCallIssue] @override def unset_digit(self, index:Union[int,slice,range,Iterable[int]]): if self.base == 1: raise BaseInvalidOpperationError("Cannot unset digits in base 1") return super().unset_digit(index) # NOTE: just like python handles it in bit_length, a value of 0 will always have no digits @override def digit_length(self) -> int: if self.base == 1: return abs(self.x) return super().digit_length() @override def insert(self, index:int, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError(f"Cannot insert digits into a base {self.base} number") super().insert(index, value) @override def pop(self, index:int = -1) -> int: if self.base == 1: index = absindex(index, self.digit_length()) self.x -= 1 return 1 else: return super().pop(index) # returns the count of non-zero (non-unset) digits @override def digit_count(self) -> int: if self.base == 1: return abs(self.x) return super().digit_count() @override def digit_shift_left(self, amount:int = 1): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be shifted") super().digit_shift_left(amount) @override def digit_shift_right(self, amount:int = 1): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be shifted") super().digit_shift_right(amount) @override def rstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().rstrip(value) @override def lstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().lstrip(value) @override def strip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().strip(value) @override def contains(self, value:Union[int, str]) -> bool: if self.base == 1: value = self._ensure_unnotated(value) return (value == 1 and self.x != 0) or (value == 0 and self.x == 0) return super().contains(value)
Ancestors
- PositionalBasedIntiger
- ExtendedUserInt
- UserInt
- typing.SupportsInt
- typing.SupportsFloat
- typing.SupportsAbs
- typing.SupportsComplex
- typing.SupportsRound
- typing.SupportsIndex
- typing.Protocol
- typing.Generic
- collections.abc.Hashable
- collections.abc.MutableSequence
- collections.abc.Sequence
- collections.abc.Reversible
- collections.abc.Collection
- collections.abc.Sized
- collections.abc.Iterable
- collections.abc.Container
Instance variables
prop base : int
-
base
The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases.
Expand source code
@property @override def base(self) -> int: """ `base` The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases. """ return self.__base
Methods
def contains(self, value: Union[int, str]) ‑> bool
-
contains
Returns true if the digit value appears anywhere in this digit sequence. This will not include leading 0s, but will return true if the tested digit value is
0
and this intiger's value is also 0.Arguments
value – The value to check for.
def copy(self, value: Union[int, str, ForwardRef(None)] = None, base: Optional[int] = None, notation_format_override: Optional[NotationFormat] = None) ‑> ExtendedBasedIntiger
-
copy
Creates a shallow copy of this object.
Keyword Arguments:
value
– When notNone
, will overrides thex
value of the copy.base
– When notNone
, will overrides thebase
of the copy.notation_format_override
– When notNone
, will overrides thenotation_format
of the copy.Returns
The copy of the object.
def digit_count(self) ‑> int
-
digit_count
Similar to
bit_count
, but relitive to the currentbase
. Not to be confused withdigit_length
.Returns
The amount of non-zero (non-unset) digits in the value.
def digit_length(self) ‑> int
-
digit_length
Similar to
bit_length
, but relitive to the currentbase
. Not to be confused withdigit_count
.Returns
The minimum necessary about of digits needed to display the number in full.
def digit_shift_left(self, amount: int = 1)
-
digit_shift_left
Similar to a binary shift left, shifts the value left according to the set base.
Arguments
amount – The amount to shift left. Will shift right when negative.
def digit_shift_right(self, amount: int = 1)
-
digit_shift_right
Similar to a binary shift right, shifts the value right according to the set base.
Arguments
amount – The amount to shift right. Will shift left when negative.
def insert(self, index: int, value: Union[int, str, Iterable[Union[int, str]]])
-
insert
Inserts the given value (or values, following the order in which they are supplied) before the given index. When given multiple values, each value will be inserted before the given index in order.
Arguments
index
– The index (or indexes) to be inserted before.value
– The value (or values) to insert. def lstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from the left hand (greatest place value) spot. Works similarly to
str.lstrip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading0
digit values, as these are already not notated by default nor would effect the digit length of this intiger.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def notate(self, notation_format: Optional[NotationFormat] = None) ‑> str
-
notate
Notates the intiger, using the given notation format if possible, or thenotation_format
set in the object's attributes if the paramater is not set.Keyword Arguments: notation_format – A notation format to use over the one set in
self.notation_format
, if notNone
.Raises
NotationError
- Raised when both the argument and attribute
notation_format
areNone
; or when other errors are raised during notation.
Returns
The final notation of the intiger.
def pop(self, index: int = -1) ‑> int
-
pop
Gets the value at the given index while popping it.
Keyword Arguments: index – The target index to pop. Defaults to -1.
Returns
The value at the given index before removal.
def rstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from the right hand (units) spot. Works similarly to
str.rstrip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def set_digit(self, index: Union[int, slice, range, Iterable[int]], value: Union[int, str, Iterable[Union[int, str]]])
-
set_digit
Sets the digit (or digits) at the given index (or indexes) to the given value (or values). With multiple indexes and, there must be a matching quantity of values to set at those indexes.
Arguments
index
– The index (or indexes) to set.value
– The value (or values) to set the index (or indexes) to.Raises
ValueError
: Raised when the given value is out of bounds of the currentbase
. def strip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from both sides. Works similarly to
str.strip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading0
digit values, as these are already not notated by default nor would effect the digit length of this intiger.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def unset_digit(self, index: Union[int, slice, range, Iterable[int]])
-
unset_digit
Unsets (set to 0) the value at the given index (or indexes).
Arguments
index
– The index (or indexes) digit to be unset.
class digitint (value: Union[int, str, Iterable[Union[int, str]]] = 0, base: int = 10, *, notation_format: Optional[NotationFormat] = NotationFormat(value_symbols=('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'), undefined_symbol='?', positive_symbol='+', negative_symbol='-', radix_point_symbol='.', group_split_symbol=None, group_split_count=0, implicit_positive=True, implicit_negative=False))
-
A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set.
Supports any initger base starting at (and including) base 1. The base is presumed to be in the traditional place value format of
value == d[x] * (base ** x)
wherevalue
is the value the digit holds in the intiger,d
is a single digit value form a sequence of digits,base
is the base, andx
is the specific index in question of the intiger.However, base 1 produces inconsistencies with this specific format. Using this logic, one would also presume that the only digit in base 1 is
0
(or whatever relevant "naught" character would be used). This is why the extention of base 1 functionality is done in a child class ofPositionalBasedIntiger
.Base 1, as implemented here, uses both the "naught" (with a value of
0
) and "unity" (with a value of '1') digits, but in a tally system. This also means that the value of any given index of a digit means very little without the context of the rest of the defined digits as well. It is also implemented in such a way that the set digits will always be grouped together, ie. all "unity" digits will be grouped together, starting at the first digit and remaining completely set all the way to the digits index that matches the value of the number represented.For these reason base 1 will have not functionality for functions that set or unset digits, as setting and unsetting digits are not relevant in unary. Attempting to do so will raise either a
BaseInvalidOpperationError
or aBaseValueError
. Deleting digits are still possible, however.Unary numbers are also fully compatible with negative values.
ex.
1111111111 (base 1) == 10 (base 10) 11111 (base 1) == 5 (base 10) 111111 (base 1) == 11 (base 2) 1101101 (base 1) == IMPOSSIBLE (the are unset digits in between the set digits) ^ ^ 000111000 (base 1) == IMPOSSIBLE (the first set digit is not the first digit in the number) ^^^
Effectively: base 1 (uniary) notation treates the value of the number as a sequence of a single type of digit that when counted add up to the value of the number.
NOTE: No functionality of any higher base is nor will modified in this class, making this class a superset of all proper positional based intiger notation formats and uniary.
Also supports customizable notation formats with the optional
notation_format
attribute, including unary.Expand source code
class ExtendedBasedIntiger(PositionalBasedIntiger): """ `ExtendedBasedIntiger` A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set. Supports any initger base starting at (and including) base 1. The base is presumed to be in the traditional place value format of `value == d[x] * (base ** x)` where `value` is the value the digit holds in the intiger, `d` is a single digit value form a sequence of digits, `base` is the base, and `x` is the specific index in question of the intiger. However, base 1 produces inconsistencies with this specific format. Using this logic, one would also presume that the only digit in base 1 is `0` (or whatever relevant "naught" character would be used). This is why the extention of base 1 functionality is done in a child class of `PositionalBasedIntiger`. Base 1, as implemented here, uses both the "naught" (with a value of `0`) and "unity" (with a value of '1') digits, but in a tally system. This also means that the value of any given index of a digit means very little without the context of the rest of the defined digits as well. It is also implemented in such a way that the set digits will always be grouped together, ie. all "unity" digits will be grouped together, starting at the first digit and remaining completely set all the way to the digits index that matches the value of the number represented. For these reason base 1 will have not functionality for functions that set or unset digits, as setting and unsetting digits are not relevant in unary. Attempting to do so will raise either a `BaseInvalidOpperationError` or a `BaseValueError`. Deleting digits are still possible, however. Unary numbers are also fully compatible with negative values. ex. ``` 1111111111 (base 1) == 10 (base 10) 11111 (base 1) == 5 (base 10) 111111 (base 1) == 11 (base 2) 1101101 (base 1) == IMPOSSIBLE (the are unset digits in between the set digits) ^ ^ 000111000 (base 1) == IMPOSSIBLE (the first set digit is not the first digit in the number) ^^^ ``` Effectively: base 1 (uniary) notation treates the value of the number as a sequence of a single type of digit that when counted add up to the value of the number. NOTE: No functionality of any higher base is nor will modified in this class, making this class a superset of all proper positional based intiger notation formats and uniary. Also supports customizable notation formats with the optional `notation_format` attribute, including unary. """ @override def __init__(self, value:Union[int, str, Iterable[Union[int, str]]] = 0, base:int = 10, *, notation_format:Optional[NotationFormat] = DEFAULT_FORMAT ): self.__base:int = 2 super().__init__(0 if base == 1 else value, base, notation_format=notation_format) if base == 1: self.base = 1 if isinstance(value, int): self.x = value elif isinstance(value, str): value = value.lstrip("0") if not all(c == "1" for c in value): raise BaseValueError(f"{value} cannot be represented in base 1") self.x = len(value) @override def copy(self, value:Optional[Union[int, str]] = None, base:Optional[int] = None, notation_format_override:Optional[NotationFormat] = None ) -> 'ExtendedBasedIntiger': """ `copy` Creates a shallow copy of this object. Keyword Arguments: `value` -- When not `None`, will overrides the `x` value of the copy. `base` -- When not `None`, will overrides the `base` of the copy. `notation_format_override` -- When not `None`, will overrides the `notation_format` of the copy. Returns: The copy of the object. """ if notation_format_override is not None: notation_format_override = self.notation_format return ExtendedBasedIntiger(value if value is not None else self.x, base if base is not None else self.base, notation_format = notation_format_override ) __copy__ = copy @override def __deepcopy__(self, _ = None) -> 'ExtendedBasedIntiger': return self.copy(None, None, None if self.notation_format is None else self.notation_format.copy() ) @property @override def base(self) -> int: """ `base` The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases. """ return self.__base @base.setter @override def base(self, value:int): if value <= 0: raise BaseValueError() self.__base = value @override def _get_single_digit(self, index:int) -> int: if self.base == 1: index = absindex(index, self.digit_length()) return 1 if index < abs(self.x) else 0 else: return super()._get_single_digit(index) @override def _pop_first(self) -> int: if self.base == 1: self.x -= 1 return 1 else: return super()._pop_first() @override def _mask_value_continuous(self, dindex: int, count: int = 1) -> int: if count <= 0: raise IndexError("The length of a continuous mask must be at least 1") if self.base == 1: return min(abs(self.x) - dindex, count) else: return super()._mask_value_continuous(dindex, count) @override def notate(self, notation_format:Optional[NotationFormat] = None) -> str: if self.base >= 2: return super().notate(notation_format) if notation_format is None: notation_format = self.notation_format if notation_format is None: raise BaseInvalidOpperationError("No format set, cannot notate") relevant_sign = "" if self.x < 0 and not notation_format.implicit_negative: if notation_format.negative_symbol is None: raise ValueError("Explicit negative values require a negative symbol") else: relevant_sign = notation_format.negative_symbol elif self.x > 0 and not notation_format.implicit_positive: if notation_format.positive_symbol is None: raise ValueError("Explicit positive values require a positive symbol") else: relevant_sign = notation_format.positive_symbol if notation_format.unity is None: raise NotationError("Cannot notate base 1 without a digit for unity") return relevant_sign + ((notation_format.unity) * self.x) @overload @override def set_digit(self, index:int, value:Union[int,str]): ... @overload @override def set_digit(self, index:Union[slice,range,Iterable[int]], value:Iterable[Union[int,str]]): ... @override # noqa:301 def set_digit(self, index:Union[int,slice,range,Iterable[int]], value:Union[int,str,Iterable[Union[int,str]]] ): if self.base == 1: raise BaseInvalidOpperationError("Digits cannot be set in base 1") super().set_digit(index, value) # type:ignore[reportCallIssue] @override def unset_digit(self, index:Union[int,slice,range,Iterable[int]]): if self.base == 1: raise BaseInvalidOpperationError("Cannot unset digits in base 1") return super().unset_digit(index) # NOTE: just like python handles it in bit_length, a value of 0 will always have no digits @override def digit_length(self) -> int: if self.base == 1: return abs(self.x) return super().digit_length() @override def insert(self, index:int, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError(f"Cannot insert digits into a base {self.base} number") super().insert(index, value) @override def pop(self, index:int = -1) -> int: if self.base == 1: index = absindex(index, self.digit_length()) self.x -= 1 return 1 else: return super().pop(index) # returns the count of non-zero (non-unset) digits @override def digit_count(self) -> int: if self.base == 1: return abs(self.x) return super().digit_count() @override def digit_shift_left(self, amount:int = 1): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be shifted") super().digit_shift_left(amount) @override def digit_shift_right(self, amount:int = 1): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be shifted") super().digit_shift_right(amount) @override def rstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().rstrip(value) @override def lstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().lstrip(value) @override def strip(self, value:Union[int,str,Iterable[Union[int,str]]]): if self.base == 1: raise BaseInvalidOpperationError("This base cannot be stripped") super().strip(value) @override def contains(self, value:Union[int, str]) -> bool: if self.base == 1: value = self._ensure_unnotated(value) return (value == 1 and self.x != 0) or (value == 0 and self.x == 0) return super().contains(value)
Ancestors
- PositionalBasedIntiger
- ExtendedUserInt
- UserInt
- typing.SupportsInt
- typing.SupportsFloat
- typing.SupportsAbs
- typing.SupportsComplex
- typing.SupportsRound
- typing.SupportsIndex
- typing.Protocol
- typing.Generic
- collections.abc.Hashable
- collections.abc.MutableSequence
- collections.abc.Sequence
- collections.abc.Reversible
- collections.abc.Collection
- collections.abc.Sized
- collections.abc.Iterable
- collections.abc.Container
Instance variables
prop base : int
-
base
The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases.
Expand source code
@property @override def base(self) -> int: """ `base` The base of this number. Must be greater than 0. Base 1 is handled particularly differently than other bases. """ return self.__base
prop limit_high : Optional[int]
-
Inherited from:
PositionalBasedIntiger
.limit_high
limit_high …
prop limit_low : Optional[int]
-
Inherited from:
PositionalBasedIntiger
.limit_low
limit_low …
var on_changed
-
Inherited from:
PositionalBasedIntiger
.on_changed
on_changed
… prop radix : int
-
Inherited from:
PositionalBasedIntiger
.radix
radix …
prop sign : int
-
Inherited from:
PositionalBasedIntiger
.sign
sign
… prop x : int
-
Inherited from:
PositionalBasedIntiger
.x
x
…
Methods
def bit_count(self) ‑> int
-
Inherited from:
PositionalBasedIntiger
.bit_count
bit_count
… def bit_length(self) ‑> int
-
Inherited from:
PositionalBasedIntiger
.bit_length
bit_count
… def contains(self, value: Union[int, str]) ‑> bool
-
Inherited from:
PositionalBasedIntiger
.contains
contains
… def copy(self, value: Union[int, str, ForwardRef(None)] = None, base: Optional[int] = None, notation_format_override: Optional[NotationFormat] = None) ‑> ExtendedBasedIntiger
-
copy
Creates a shallow copy of this object.
Keyword Arguments:
value
– When notNone
, will overrides thex
value of the copy.base
– When notNone
, will overrides thebase
of the copy.notation_format_override
– When notNone
, will overrides thenotation_format
of the copy.Returns
The copy of the object.
def delete_digit(self, index: Union[int, slice, range, Iterable[int]])
-
Inherited from:
PositionalBasedIntiger
.delete_digit
delete_digit
… def digit_count(self) ‑> int
-
Inherited from:
PositionalBasedIntiger
.digit_count
digit_count
… def digit_length(self) ‑> int
-
Inherited from:
PositionalBasedIntiger
.digit_length
digit_length
… def digit_rotate_left(self, amount: int = 1)
-
Inherited from:
PositionalBasedIntiger
.digit_rotate_left
digit_rotate_left
… def digit_rotate_right(self, amount: int = 1)
-
Inherited from:
PositionalBasedIntiger
.digit_rotate_right
digit_rotate_right
… def digit_shift_left(self, amount: int = 1)
-
Inherited from:
PositionalBasedIntiger
.digit_shift_left
digit_shift_left
… def digit_shift_right(self, amount: int = 1)
-
Inherited from:
PositionalBasedIntiger
.digit_shift_right
digit_shift_right
… def fixed_sign_and(self, value: int) ‑> int
-
Inherited from:
PositionalBasedIntiger
.fixed_sign_and
fixed_sign_and
… def fixed_sign_invert(self) ‑> int
-
Inherited from:
PositionalBasedIntiger
.fixed_sign_invert
fixed_sign_invert
… def fixed_sign_or(self, value: int) ‑> int
-
Inherited from:
PositionalBasedIntiger
.fixed_sign_or
fixed_sign_or
… def fixed_sign_xor(self, value: int) ‑> int
-
Inherited from:
PositionalBasedIntiger
.fixed_sign_xor
fixed_sign_xor
… def get_digit(self, index: Union[int, slice, range, Iterable[int]]) ‑> Union[int, List[int]]
-
Inherited from:
PositionalBasedIntiger
.get_digit
get_digit
… def insert(self, index: int, value: Union[int, str, Iterable[Union[int, str]]])
-
Inherited from:
PositionalBasedIntiger
.insert
insert
… def is_integer(self) ‑> bool
-
Inherited from:
PositionalBasedIntiger
.is_integer
is_integer
… def iter_digits(self, at_least: int = 0) ‑> Iterator[int]
-
Inherited from:
PositionalBasedIntiger
.iter_digits
iter_digits
Returns an iterable that iterates through the digit values of the integer, starting at the units spot. Will iterate 0 when all other … def iter_symbols(self, at_least: int = 1) ‑> Iterator[str]
-
Inherited from:
PositionalBasedIntiger
.iter_symbols
iter_symbols
… def lstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
Inherited from:
PositionalBasedIntiger
.lstrip
rstrip
… def mask(self, index: Union[int, slice, range, Iterable[int]]) ‑> int
-
Inherited from:
PositionalBasedIntiger
.mask
mask
… def notate(self, notation_format: Optional[NotationFormat] = None) ‑> str
-
Inherited from:
PositionalBasedIntiger
.notate
notate
Notates the intiger, using the given notation format if possible, or thenotation_format
set in the object's attributes if the paramater is … def pop(self, index: int = -1) ‑> int
-
Inherited from:
PositionalBasedIntiger
.pop
pop
… def reversed_iter_digits(self, at_least: int = 0) ‑> Iterator[int]
-
Inherited from:
PositionalBasedIntiger
.reversed_iter_digits
reversed_iter_digits
Returns an iterable that iterates through the digit values of the integer, ending at the units spot. Will iterate 0 when all … def reversed_iter_symbols(self, at_least: int = 1) ‑> Iterator[str]
-
Inherited from:
PositionalBasedIntiger
.reversed_iter_symbols
reversed_iter_symbols
… def rstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
Inherited from:
PositionalBasedIntiger
.rstrip
rstrip
… def set_digit(self, index: Union[int, slice, range, Iterable[int]], value: Union[int, str, Iterable[Union[int, str]]])
-
Inherited from:
PositionalBasedIntiger
.set_digit
set_digit
… def strip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
Inherited from:
PositionalBasedIntiger
.strip
rstrip
… def to_bytes(self, length:
, byteorder: Literal['little', 'big'], *, signed: bool = False) ‑> bytes -
Inherited from:
PositionalBasedIntiger
.to_bytes
to_bytes
… def unset_digit(self, index: Union[int, slice, range, Iterable[int]])
-
Inherited from:
PositionalBasedIntiger
.unset_digit
unset_digit
…
class PositionalBasedIntiger (value: Union[int, str, Iterable[Union[int, str]], bytes, bytearray, memoryview] = 0, base: int = 10, *, notation_format: Optional[NotationFormat] = NotationFormat(value_symbols=('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'), undefined_symbol='?', positive_symbol='+', negative_symbol='-', radix_point_symbol='.', group_split_symbol=None, group_split_count=0, implicit_positive=True, implicit_negative=False))
-
A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set.
Supports any initger base starting at binary (base 2). These bases are presumed to be in the traditional place value format of
value == d[x] * (base ** x)
wherevalue
is the value the digit holds in the intiger,d
is a single digit value form a sequence of digits,base
is the base, andx
is the specific index in question of the intiger.Supports many operators and methods that built in integers suport, casting the type back into a default intiger type when possible.
Also supports customizable notation formats with the optional
notation_format
attribute.Expand source code
class PositionalBasedIntiger(*tuple(__POSITIONAL_BASED_INT_BASES)): """ `PositionalBasedIntiger` A mutable sequence type of intiger that has a explicitly set base, allowing for specific digit values to be get and set. Supports any initger base starting at binary (base 2). These bases are presumed to be in the traditional place value format of `value == d[x] * (base ** x)` where `value` is the value the digit holds in the intiger, `d` is a single digit value form a sequence of digits, `base` is the base, and `x` is the specific index in question of the intiger. Supports many operators and methods that built in integers suport, casting the type back into a default intiger type when possible. Also supports customizable notation formats with the optional `notation_format` attribute. """ def __init__(self, value:Union[int, str, Iterable[Union[int, str]], bytes, bytearray, memoryview] = 0, base:int = 10, *, notation_format:Optional[NotationFormat] = DEFAULT_FORMAT ): super().__init__(0) self.__base:int = 2 self.x = 0 self.base = base self.notation_format:Optional[NotationFormat] = notation_format if isinstance(value, int): self.x = value elif isinstance(value, str): self.x = int(value, base) else: for digit_value in value: digit_value = self._ensure_unnotated(digit_value) if digit_value >= base: raise ValueError(f"Digit of value {digit_value} isn't possible in base {base}") self.x = (self.x * base) + digit_value def copy(self, value:Optional[Union[int, str]] = None, base:Optional[int] = None, notation_format_override:Optional[NotationFormat] = None ) -> 'PositionalBasedIntiger': """ `copy` Creates a shallow copy of this object. Keyword Arguments: value -- When not `None`, will overrides the `x` value of the copy. base -- When not `None`, will overrides the `base` of the copy. notation_format_override -- When not `None`, will overrides the `notation_format` of the copy. Returns: The copy of the object. """ if notation_format_override is not None: notation_format_override = self.notation_format return PositionalBasedIntiger(value if value is not None else self.x, base if base is not None else self.base, notation_format = notation_format_override ) __copy__ = copy def __deepcopy__(self, _ = None) -> 'PositionalBasedIntiger': return self.copy(None, None, None if self.notation_format is None else self.notation_format.copy() ) @property def base(self) -> int: """ `base` The base of the intiger. Must be at or above 2, as this class does not support any non-standard bases. """ return self.__base @base.setter def base(self, value:int): if value < 2: raise ValueError("Invalid base", value) self.__base = value @property def radix(self) -> int: """ radix Returns: The absolute value of the base. Will always return `base` when used in a `PositionalBasedIntiger`, but may differ when using with a extended type. """ return abs(self.base) def _ensure_notated(self, value:Union[int,str]) -> str: if self.notation_format is None: raise NotationError("Cannot reference a symbol without a notation format") if isinstance(value, str): return value else: dig = self.notation_format.get_digit(value) if dig is None: raise NotationError(f"Could not find digit for {value} in current notation format") return dig def _ensure_unnotated(self, value:Union[int,str]) -> int: if self.notation_format is None: raise NotationError("Cannot reference a symbol without a notation format") if isinstance(value, int): return value v = self.notation_format.get_value(value) if v is None: raise NotationError(f"Given symbol '{value}' not found in current notation format") return v def _get_single_digit(self, index:int) -> int: index = absindex(index, self.digit_length()) if self.base == 2: return (abs(self.x) >> index) % (0b1 << 1) else: return (abs(self.x) // (self.base ** index)) % self.base # this pops the digit in the units spot, # effectively shifts left once while returning units shifted out # slightly faster than the arbitrary pop method def _pop_first(self) -> int: dm = divmod(self.x, self.base) self.x = dm[0] return dm[1] # this pushes a value into the units place # effectively shifts right while appending a new value to the units # slightly faster than the arbitrary insert method def _prepend(self, value:Union[int,str]): value = self._ensure_unnotated(value) if value < 0 or value >= self.base: raise ValueError("Digit value out of bounds of base") if self.sign == -1: value *= -1 self.x = (self.x * self.base) + value # effectively, this returns a continuous sequence # form the intiger with its place value still intact def _mask_value_continuous(self, dindex:int, count:int = 1) -> int: if count <= 0: raise IndexError("The length of a continuous mask must be at least 1") dindex = absindex(dindex, self.digit_length()) if self.base == 2: # binary optimisable return abs(self.x) & (((0b1 << (count - 1)) - 1) << dindex) else: pv1 = self.base ** dindex pv2 = pv1 * (self.base ** count) # aka ```self.base ** (dindex + count)``` return (abs(self.x) % pv2) - (abs(self.x) % pv1) def iter_digits(self, at_least:int = 0) -> Iterator[int]: """ `iter_digits` Returns an iterable that iterates through the digit values of the integer, starting at the units spot. Will iterate 0 when all other digits are already iterated. Keyword Arguments: `at_least` -- Ensures that at least the given amount of digits are iterated, if above 1. Returns: An iterator that returns the digit values, starting at the units spot. Yields: The digits of the intiger, starting at the units spot. """ indexes = range(max(self.digit_length(), at_least)) return (self._get_single_digit(i) for i in indexes) __iter__ = iter_digits def reversed_iter_digits(self, at_least:int = 0) -> Iterator[int]: """ `reversed_iter_digits` Returns an iterable that iterates through the digit values of the integer, ending at the units spot. Will iterate 0 when all other digits are already iterated. Keyword Arguments: `at_least` -- Ensures that at least the given amount of digits are iterated, if above 1. Returns: An iterator that returns the digit values, ending at the units spot. Yields: The digits of the intiger, ending at the units spot. """ indexes = range(max(self.digit_length(), at_least)-1, -1, -1) return (self._get_single_digit(i) for i in indexes) __reverse__ = reversed_iter_digits def __bytes__(self): return bytes(self.iter_digits(0)) def iter_symbols(self, at_least:int = 1) -> Iterator[str]: """ `iter_symbols` Iterate the digit symbols starting at the units spot. When intending to use iteration for notation, it's suggested to use `reversed_iter_symbols` to avoid odering errors. Keyword Arguments: `at_least` -- ensures that at least the given amount of symbols are returned. Defaults to 1. Returns: An iterator of symbols. Yields: Digit symdols, starting at the units spot. """ return (self._ensure_notated(x) for x in self.iter_digits(at_least)) def reversed_iter_symbols(self, at_least:int = 1) -> Iterator[str]: """ `reversed_iter_symbols` Iterate the digit symbols ending at the units spot. Intending to be used for notation purposes, as the ordering for string notation is correct. Keyword Arguments: `at_least` -- ensures that at least the given amount of symbols are returned. Defaults to 1. Returns: An iterator of symbols. Yields: Digit symdols, ending at the units spot. """ return (self._ensure_notated(x) for x in self.reversed_iter_digits(at_least)) def notate(self, notation_format:Optional[NotationFormat] = None) -> str: """ `notate` Notates the intiger, using the given notation format if possible, or the `notation_format` set in the object's attributes if the paramater is not set. Keyword Arguments: notation_format -- A notation format to use over the one set in `self.notation_format`, if not `None`. Raises: NotationError: Raised when both the argument and attribute `notation_format` are `None`; or when other errors are raised during notation. Returns: The final notation of the intiger. """ if notation_format is None: notation_format = self.notation_format if notation_format is None: raise NotationError("No format set, cannot notate") relevant_sign = "" if self.x < 0 and not notation_format.implicit_negative: if notation_format.negative_symbol is None: raise NotationError("Explicit negative values require a negative symbol") else: relevant_sign = notation_format.negative_symbol elif self.x > 0 and not notation_format.implicit_positive: if notation_format.positive_symbol is None: raise NotationError("Explicit positive values require a positive symbol") else: relevant_sign = notation_format.positive_symbol group_joint = "" if notation_format.group_split_symbol is not None: group_joint = notation_format.group_split_symbol group_count = notation_format.group_split_count if group_joint != "" and group_count > 0: groups = list(self.iter_symbols()) group_indexes = range(0, self.digit_length(), group_count) groups = [''.join(groups[i:i+group_count])[::-1] for i in group_indexes] groups = groups[::-1] else: groups = self.reversed_iter_symbols() return relevant_sign + group_joint.join(groups) __str__ = notate __repr__ = notate @overload def get_digit(self, index:int) -> int: ... @overload def get_digit(self, index:Union[slice,range,Iterable[int]]) -> List[int]: ... def get_digit(self, # noqa:301 index:Union[int,slice,range,Iterable[int]] ) -> Union[int,List[int]]: """ `get_digit` Gets the specific digit's (or digits's) value at the specific index (or indexes). Arguments: `index` -- The index (or indexes) in question. Returns: The value (or values, contained in a `List`) found at the index. """ if isinstance(index, int): return self._get_single_digit(index) if isinstance(index, slice): index = slice_to_range(index, self.digit_length()) return list(self._get_single_digit(absindex(i, self.digit_length())) for i in index) __getitem__ = get_digit @overload def set_digit(self, index:int, value:Union[int,str]): ... @overload def set_digit(self, index:Union[slice,range,Iterable[int]], value:Iterable[Union[int,str]]): ... def set_digit(self, # noqa:301 index:Union[int,slice,range,Iterable[int]], value:Union[int,str,Iterable[Union[int,str]]] ): """ `set_digit` Sets the digit (or digits) at the given index (or indexes) to the given value (or values). With multiple indexes and, there must be a matching quantity of values to set at those indexes. Arguments: `index` -- The index (or indexes) to set. `value` -- The value (or values) to set the index (or indexes) to. Raises: `ValueError`: Raised when the given value is out of bounds of the current `base`. """ if isinstance(value, Iterable): value = (self._ensure_unnotated(v) for v in value) else: value = self._ensure_unnotated(value) if isinstance(value, int): value = [value] else: value = cast(List[int], list(value)) if isinstance(index, int): index = (index, ) elif isinstance(index, slice): index = slice_to_range(index, self.digit_length()) sign = self.sign self.x = abs(self.x) for i, v in zip(index, value): if v < 0 or v >= self.base: raise ValueError("Digit value out of bounds of base") i = absindex(i, self.digit_length()) if self.base == 2: # binary optimisable if v == 1: self.x |= (0b1 << i) else: self.x &= ~(0b1 << i) else: pv = self.base ** i mask = self._mask_value_continuous(i) self.x = (self.x - mask) + (v * pv) if sign != 0: self.x *= sign __setitem__ = set_digit def delete_digit(self, index:Union[int,slice,range,Iterable[int]]): """ `delete_digit` Removes the value at the given index (or indexes). Arguments: `index` -- The index (or indexes) digit to be removed. """ if isinstance(index, slice): index = slice_to_range(index, self.digit_length()) if isinstance(index, int): index = (index, ) for i in sorted(index, reverse=True): self.pop(i) __delitem__ = delete_digit def unset_digit(self, index:Union[int,slice,range,Iterable[int]]): """ `unset_digit` Unsets (set to 0) the value at the given index (or indexes). Arguments: `index` -- The index (or indexes) digit to be unset. """ if isinstance(index, slice): index = slice_to_range(index, self.digit_length()) if isinstance(index, int): index = (index, ) sign = self.sign self.x = abs(self.x) if self.base == 2: # binary optimization for i in index: i = absindex(i, self.digit_length()) self.x = (self.x >> 1) << 1 else: for i in index: i = absindex(i, self.digit_length()) self.x -= self._mask_value_continuous(i) if sign != 0: self.x *= sign # NOTE: just like python handles it in bit_length, a value of 0 will always have no digits def digit_length(self) -> int: """ `digit_length` Similar to `bit_length`, but relitive to the current `base`. Not to be confused with `digit_count`. Returns: The minimum necessary about of digits needed to display the number in full. """ if self.x == 0: return 0 if self.base == 2: return abs(self.x).bit_length() else: c = 0 v = abs(self.x) while v != 0: c += 1 v //= self.base return c __len__ = digit_length def insert(self, index:int, value:Union[int,str,Iterable[Union[int,str]]]): """ `insert` Inserts the given value (or values, following the order in which they are supplied) before the given index. When given multiple values, each value will be inserted before the given index in order. Arguments: `index` -- The index (or indexes) to be inserted before. `value` -- The value (or values) to insert. """ # not the current length, but the length this will have after the insert index = absindex(index, self.digit_length() + 1) if isinstance(value, Iterable): value = (self._ensure_unnotated(v) for v in value) else: value = self._ensure_unnotated(value) if isinstance(value, int): value = (value, ) for v in value: if v < 0 or v >= self.base: raise ValueError("Digit value out of bounds of base") restore_sign = self.sign self.x = abs(self.x) if index == 0: self._prepend(v) continue high = self.copy() high.unset_digit(slice(0, index)) if high.x != 0: self.x -= high.x high.x *= high.base self.x += high.x v = self.copy(v) v.x *= (v.base ** (index)) self.x += v.x self.x *= restore_sign def pop(self, index:int = -1) -> int: """ `pop` Gets the value at the given index while popping it. Keyword Arguments: index -- The target index to pop. Defaults to -1. Returns: The value at the given index before removal. """ index = absindex(index, self.digit_length()) if index == 0: return self._pop_first() popped = self._get_single_digit(index) high = self.copy() self.unset_digit(range(index, len(self))) high.unset_digit(range(0, index+1)) if int(high) != 0: high.x //= high.base self.x += int(high) return popped def digit_count(self) -> int: """ `digit_count` Similar to `bit_count`, but relitive to the current `base`. Not to be confused with `digit_length`. Returns: The amount of non-zero (non-unset) digits in the value. """ if self.x == 0: return 0 if self.base == 2: return abs(self.x).bit_count() else: c = 0 v = abs(self.x) while v != 0: if v % self.base != 0: c += 1 v //= self.base return c # gets the specified digits with their place value as an int # a higher level implementation of the concept of bit masking done with binary numbers def mask(self, index:Union[int,slice,range,Iterable[int]]) -> int: """ `mask` Similar to the concept of a 'bit mask', but on a arbitrary base. Returns a value with all digits unset except for the given index (or indexes). Arguments: index -- The index (or indexes) to mask the digits of. Returns: The value with all digits unset except for the given index (or indexes). """ if isinstance(index, int): return self._mask_value_continuous(index) slices = [] if isinstance(index, slice) and index.step == 1: slices = [index] else: if isinstance(index, slice): index = slice_to_range(index, self.digit_length()) slices = iter_to_slices(cast(Iterable[int], index), self.digit_length()) return sum(self._mask_value_continuous(s.start, s.stop - s.start) for s in slices) def digit_shift_left(self, amount:int = 1): """ `digit_shift_left` Similar to a binary shift left, shifts the value left according to the set base. Arguments: amount -- The amount to shift left. Will shift right when negative. """ if amount < 0: self.digit_shift_right(-amount) return if self.base == 2: self.x = (abs(self.x) << amount) * self.sign else: self.x *= (self.base**amount) def digit_shift_right(self, amount:int = 1): """ `digit_shift_right` Similar to a binary shift right, shifts the value right according to the set base. Arguments: amount -- The amount to shift right. Will shift left when negative. """ if amount < 0: self.digit_shift_left(-amount) return if self.base == 2: self.x = (abs(self.x) >> amount) * self.sign else: self.x //= (self.base**amount) def digit_rotate_left(self, amount:int = 1): """ `digit_rotate_left` Similar to a binary rotate left, rotates the value left according to the set base. This will pop the digit at the largest signifiant place value and inserts it at the smallest place value spot. Arguments: amount -- The amount to rotate left. Will rotate right when negative. """ if amount < 0: self.digit_rotate_right(-amount) for _ in range(amount): popped = self.pop(-1) self.digit_shift_left(1) self.x += popped def digit_rotate_right(self, amount:int = 1): """ `digit_rotate_right` Similar to a binary rotate right, rotates the value right according to the set base. This will pop the digit at the smallest signifiant place value and inserts it at the largest place value spot. Arguments: amount -- The amount to rotate right. Will rotate left when negative. """ if amount < 0: self.digit_rotate_left(-amount) for _ in range(amount): popped = self.pop(0) self.digit_shift_right(1) self.append(popped) def rstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): """ `rstrip` Removes the given digit (or digits) from the right hand (units) spot. Works similarly to ``str.rstrip``, except for the fact that when ``value`` is a single string (**not** a iterable of strings) it will be treated as a single digit instead of a iterable of digits. Arguments: value -- The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit. """ if isinstance(value, Iterable): value = tuple(self._ensure_unnotated(v) for v in value) else: value = (self._ensure_unnotated(value), ) if len(value) == 0: return while self.x != 0 and self._get_single_digit(0) in value: self._pop_first() def lstrip(self, value:Union[int,str,Iterable[Union[int,str]]]): """ `rstrip` Removes the given digit (or digits) from the left hand (greatest place value) spot. Works similarly to ``str.lstrip``, except for the fact that when ``value`` is a single string (**not** a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading `0` digit values, as these are already not notated by default nor would effect the digit length of this intiger. Arguments: value -- The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit. """ if isinstance(value, Iterable): value = [self._ensure_unnotated(v) for v in value] else: value = [self._ensure_unnotated(value)] value.remove(0) if len(value) == 0: return while self.x != 0 and self._get_single_digit(-1) in value: self.pop(-1) def strip(self, value:Union[int,str,Iterable[Union[int,str]]]): """ `rstrip` Removes the given digit (or digits) from both sides. Works similarly to ``str.strip``, except for the fact that when ``value`` is a single string (**not** a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading `0` digit values, as these are already not notated by default nor would effect the digit length of this intiger. Arguments: value -- The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit. """ self.rstrip(value) self.lstrip(value) def contains(self, value:Union[int, str]) -> bool: """ `contains` Returns true if the digit value appears anywhere in this digit sequence. This will not include leading 0s, but will return true if the tested digit value is `0` and this intiger's value is also 0. Arguments: value -- The value to check for. """ value = self._ensure_unnotated(value) if self.x == 0: return value == 0 working_value = abs(self.x) while working_value > 0: if self.base == 2: if working_value & 0b1 == value: return True working_value >>= 1 else: if working_value % self.base == value: return True working_value //= self.base return False __contains__ = contains
Ancestors
- ExtendedUserInt
- UserInt
- typing.SupportsInt
- typing.SupportsFloat
- typing.SupportsAbs
- typing.SupportsComplex
- typing.SupportsRound
- typing.SupportsIndex
- typing.Protocol
- typing.Generic
- collections.abc.Hashable
- collections.abc.MutableSequence
- collections.abc.Sequence
- collections.abc.Reversible
- collections.abc.Collection
- collections.abc.Sized
- collections.abc.Iterable
- collections.abc.Container
Subclasses
Instance variables
prop base : int
-
base
The base of the intiger. Must be at or above 2, as this class does not support any non-standard bases.
Expand source code
@property def base(self) -> int: """ `base` The base of the intiger. Must be at or above 2, as this class does not support any non-standard bases. """ return self.__base
prop limit_high : Optional[int]
-
Inherited from:
ExtendedUserInt
.limit_high
limit_high …
prop limit_low : Optional[int]
-
Inherited from:
ExtendedUserInt
.limit_low
limit_low …
var on_changed
-
Inherited from:
ExtendedUserInt
.on_changed
on_changed
… prop radix : int
-
radix
Returns
The absolute value of the base. Will always return
base
when used in aPositionalBasedIntiger
, but may differ when using with a extended type.Expand source code
@property def radix(self) -> int: """ radix Returns: The absolute value of the base. Will always return `base` when used in a `PositionalBasedIntiger`, but may differ when using with a extended type. """ return abs(self.base)
prop sign : int
-
Inherited from:
ExtendedUserInt
.sign
sign
… prop x : int
-
Inherited from:
ExtendedUserInt
.x
x
…
Methods
def bit_count(self) ‑> int
-
Inherited from:
ExtendedUserInt
.bit_count
bit_count
… def bit_length(self) ‑> int
-
Inherited from:
ExtendedUserInt
.bit_length
bit_count
… def contains(self, value: Union[int, str]) ‑> bool
-
contains
Returns true if the digit value appears anywhere in this digit sequence. This will not include leading 0s, but will return true if the tested digit value is
0
and this intiger's value is also 0.Arguments
value – The value to check for.
def copy(self, value: Union[int, str, ForwardRef(None)] = None, base: Optional[int] = None, notation_format_override: Optional[NotationFormat] = None) ‑> PositionalBasedIntiger
-
copy
Creates a shallow copy of this object.
Keyword Arguments: value – When not
None
, will overrides thex
value of the copy. base – When notNone
, will overrides thebase
of the copy. notation_format_override – When notNone
, will overrides thenotation_format
of the copy.Returns
The copy of the object.
def delete_digit(self, index: Union[int, slice, range, Iterable[int]])
-
delete_digit
Removes the value at the given index (or indexes).
Arguments
index
– The index (or indexes) digit to be removed. def digit_count(self) ‑> int
-
digit_count
Similar to
bit_count
, but relitive to the currentbase
. Not to be confused withdigit_length
.Returns
The amount of non-zero (non-unset) digits in the value.
def digit_length(self) ‑> int
-
digit_length
Similar to
bit_length
, but relitive to the currentbase
. Not to be confused withdigit_count
.Returns
The minimum necessary about of digits needed to display the number in full.
def digit_rotate_left(self, amount: int = 1)
-
digit_rotate_left
Similar to a binary rotate left, rotates the value left according to the set base. This will pop the digit at the largest signifiant place value and inserts it at the smallest place value spot.
Arguments
amount – The amount to rotate left. Will rotate right when negative.
def digit_rotate_right(self, amount: int = 1)
-
digit_rotate_right
Similar to a binary rotate right, rotates the value right according to the set base. This will pop the digit at the smallest signifiant place value and inserts it at the largest place value spot.
Arguments
amount – The amount to rotate right. Will rotate left when negative.
def digit_shift_left(self, amount: int = 1)
-
digit_shift_left
Similar to a binary shift left, shifts the value left according to the set base.
Arguments
amount – The amount to shift left. Will shift right when negative.
def digit_shift_right(self, amount: int = 1)
-
digit_shift_right
Similar to a binary shift right, shifts the value right according to the set base.
Arguments
amount – The amount to shift right. Will shift left when negative.
def fixed_sign_and(self, value: int) ‑> int
-
Inherited from:
ExtendedUserInt
.fixed_sign_and
fixed_sign_and
… def fixed_sign_invert(self) ‑> int
-
Inherited from:
ExtendedUserInt
.fixed_sign_invert
fixed_sign_invert
… def fixed_sign_or(self, value: int) ‑> int
-
Inherited from:
ExtendedUserInt
.fixed_sign_or
fixed_sign_or
… def fixed_sign_xor(self, value: int) ‑> int
-
Inherited from:
ExtendedUserInt
.fixed_sign_xor
fixed_sign_xor
… def get_digit(self, index: Union[int, slice, range, Iterable[int]]) ‑> Union[int, List[int]]
-
get_digit
Gets the specific digit's (or digits's) value at the specific index (or indexes).
Arguments
index
– The index (or indexes) in question.Returns
The value (or values, contained in a
List
) found at the index. def insert(self, index: int, value: Union[int, str, Iterable[Union[int, str]]])
-
insert
Inserts the given value (or values, following the order in which they are supplied) before the given index. When given multiple values, each value will be inserted before the given index in order.
Arguments
index
– The index (or indexes) to be inserted before.value
– The value (or values) to insert. def is_integer(self) ‑> bool
-
Inherited from:
ExtendedUserInt
.is_integer
is_integer
… def iter_digits(self, at_least: int = 0) ‑> Iterator[int]
-
iter_digits
Returns an iterable that iterates through the digit values of the integer, starting at the units spot. Will iterate 0 when all other digits are already iterated.Keyword Arguments:
at_least
– Ensures that at least the given amount of digits are iterated, if above 1.Returns
An iterator that returns the digit values, starting at the units spot.
Yields
The digits of the intiger, starting at the units spot.
def iter_symbols(self, at_least: int = 1) ‑> Iterator[str]
-
iter_symbols
Iterate the digit symbols starting at the units spot. When intending to use iteration for notation, it's suggested to use
reversed_iter_symbols
to avoid odering errors.Keyword Arguments:
at_least
– ensures that at least the given amount of symbols are returned. Defaults to 1.Returns
An iterator of symbols.
Yields
Digit symdols, starting at the units spot.
def lstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from the left hand (greatest place value) spot. Works similarly to
str.lstrip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading0
digit values, as these are already not notated by default nor would effect the digit length of this intiger.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def mask(self, index: Union[int, slice, range, Iterable[int]]) ‑> int
-
mask
Similar to the concept of a 'bit mask', but on a arbitrary base. Returns a value with all digits unset except for the given index (or indexes).
Arguments
index – The index (or indexes) to mask the digits of.
Returns
The value with all digits unset except for the given index (or indexes).
def notate(self, notation_format: Optional[NotationFormat] = None) ‑> str
-
notate
Notates the intiger, using the given notation format if possible, or thenotation_format
set in the object's attributes if the paramater is not set.Keyword Arguments: notation_format – A notation format to use over the one set in
self.notation_format
, if notNone
.Raises
NotationError
- Raised when both the argument and attribute
notation_format
areNone
; or when other errors are raised during notation.
Returns
The final notation of the intiger.
def pop(self, index: int = -1) ‑> int
-
pop
Gets the value at the given index while popping it.
Keyword Arguments: index – The target index to pop. Defaults to -1.
Returns
The value at the given index before removal.
def reversed_iter_digits(self, at_least: int = 0) ‑> Iterator[int]
-
reversed_iter_digits
Returns an iterable that iterates through the digit values of the integer, ending at the units spot. Will iterate 0 when all other digits are already iterated.Keyword Arguments:
at_least
– Ensures that at least the given amount of digits are iterated, if above 1.Returns
An iterator that returns the digit values, ending at the units spot.
Yields
The digits of the intiger, ending at the units spot.
def reversed_iter_symbols(self, at_least: int = 1) ‑> Iterator[str]
-
reversed_iter_symbols
Iterate the digit symbols ending at the units spot. Intending to be used for notation purposes, as the ordering for string notation is correct.
Keyword Arguments:
at_least
– ensures that at least the given amount of symbols are returned. Defaults to 1.Returns
An iterator of symbols.
Yields
Digit symdols, ending at the units spot.
def rstrip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from the right hand (units) spot. Works similarly to
str.rstrip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def set_digit(self, index: Union[int, slice, range, Iterable[int]], value: Union[int, str, Iterable[Union[int, str]]])
-
set_digit
Sets the digit (or digits) at the given index (or indexes) to the given value (or values). With multiple indexes and, there must be a matching quantity of values to set at those indexes.
Arguments
index
– The index (or indexes) to set.value
– The value (or values) to set the index (or indexes) to.Raises
ValueError
: Raised when the given value is out of bounds of the currentbase
. def strip(self, value: Union[int, str, Iterable[Union[int, str]]])
-
rstrip
Removes the given digit (or digits) from both sides. Works similarly to
str.strip
, except for the fact that whenvalue
is a single string (not a iterable of strings) it will be treated as a single digit instead of a iterable of digits. This will not strip any leading0
digit values, as these are already not notated by default nor would effect the digit length of this intiger.Arguments
value – The value (or iterable of values) to strip. Can be either a intiger digit value, or a string corelating to a single digit.
def to_bytes(self, length:
, byteorder: Literal['little', 'big'], *, signed: bool = False) ‑> bytes -
Inherited from:
ExtendedUserInt
.to_bytes
to_bytes
… def unset_digit(self, index: Union[int, slice, range, Iterable[int]])
-
unset_digit
Unsets (set to 0) the value at the given index (or indexes).
Arguments
index
– The index (or indexes) digit to be unset.