diff --git a/chepy/core.py b/chepy/core.py index 4dc8678..bbd1110 100644 --- a/chepy/core.py +++ b/chepy/core.py @@ -103,6 +103,8 @@ def __init__(self, *data): self.log_format = "%(levelname)-2s - %(message)s" logging.getLogger().setLevel(self.log_level) logging.basicConfig(format=self.log_format) + # logger + self._log = logging @property def recipe(self) -> List[Dict[str, Union[str, Dict[str, Any]]]]: diff --git a/chepy/core.pyi b/chepy/core.pyi index 31ffbec..a532c0b 100644 --- a/chepy/core.pyi +++ b/chepy/core.pyi @@ -1,3 +1,4 @@ +import logging from typing import Any, List, Mapping, Tuple, Union, TypeVar, Literal, Callable, Dict jsonpickle: Any @@ -19,6 +20,7 @@ class ChepyCore: read_file: Any = ... log_level: Any = ... log_format: str = ... + _log: logging.Logger = ... def __init__(self, *data: Any) -> None: ... def _convert_to_bytes(self) -> bytes: ... def _to_bytes(self, data: Any) -> bytes: ... diff --git a/chepy/modules/aritmeticlogic.py b/chepy/modules/aritmeticlogic.py index 52a2df2..696136b 100644 --- a/chepy/modules/aritmeticlogic.py +++ b/chepy/modules/aritmeticlogic.py @@ -39,14 +39,34 @@ def add(self, n: int) -> AritmeticLogicT: """Add a number to the state Args: - n (int): Number to add with + n (int): Number to add with. Can be decimal or hex string without 0x Returns: Chepy: The Chepy object. """ - if not isinstance(self.state, int): - self.state = self.__hex_to_int(self.state) - self.state = self.state + n + # Determine the base of the key (hexadecimal or decimal) + if isinstance(n, int): + # Try converting to decimal + key_int = n + else: + try: + # Try converting to hexadecimal + key_int = int(n, 16) + except ValueError: # pragma: no cover + self._log.error( + "Invalid key format. Must be a decimal or hexadecimal string." + ) + return self + + hold = b"" + for char_code in self._convert_to_bytes(): + # Add the key to the integer and take the result modulo 255 + result_code = (char_code + key_int) % 256 + + # Convert the result back to a byte + hold += result_code.to_bytes(1, byteorder="big") + + self.state = hold return self @ChepyDecorators.call_stack @@ -59,9 +79,29 @@ def subtract(self, n: int) -> AritmeticLogicT: Returns: Chepy: The Chepy object. """ - if not isinstance(self.state, int): - self.state = self.__hex_to_int(self.state) - self.state = self.state - n + # Determine the base of the key (hexadecimal or decimal) + if isinstance(n, int): + # Try converting to decimal + key_int = n + else: + try: + # Try converting to hexadecimal + key_int = int(n, 16) + except ValueError: # pragma: no cover + self._log.error( + "Invalid key format. Must be a decimal or hexadecimal string." + ) + return self + + hold = b"" + for char_code in self._convert_to_bytes(): + # Add the key to the integer and take the result modulo 255 + result_code = (char_code - key_int) % 256 + + # Convert the result back to a byte + hold += result_code.to_bytes(1, byteorder="big") + + self.state = hold return self @ChepyDecorators.call_stack @@ -81,8 +121,8 @@ def multiply(self, n: int) -> AritmeticLogicT: @ChepyDecorators.call_stack def divide(self, n: int) -> AritmeticLogicT: - """Divide a number to the state. Chepy is not optimized for float math. - Subsequent methods may fail. + """Divide a number to the state. Chepy is not optimized for float math. + Subsequent methods may fail. Args: n (int): Number to divide with @@ -107,7 +147,7 @@ def power(self, n: int) -> AritmeticLogicT: """ if not isinstance(self.state, int): self.state = self.__hex_to_int(self.state) - self.state = self.state ** n + self.state = self.state**n return self @ChepyDecorators.call_stack @@ -149,7 +189,7 @@ def median(self) -> AritmeticLogicT: @ChepyDecorators.call_stack def int_to_base(self, base: Union[int, str]) -> AritmeticLogicT: """Convert the state to a different base - + Args: base (int): Base to convert to diff --git a/chepy/modules/aritmeticlogic.pyi b/chepy/modules/aritmeticlogic.pyi index 6aea86f..8e38f9e 100644 --- a/chepy/modules/aritmeticlogic.pyi +++ b/chepy/modules/aritmeticlogic.pyi @@ -7,8 +7,8 @@ class AritmeticLogic(ChepyCore): def __init__(self, *data: Any) -> None: ... state: Any = ... def str_bit_shift_right(self: AritmeticLogicT, amount: int) -> AritmeticLogicT: ... - def add(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ... - def subtract(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ... + def add(self: AritmeticLogicT, n: Union[int, str]) -> AritmeticLogicT: ... + def subtract(self: AritmeticLogicT, n: Union[int, str]) -> AritmeticLogicT: ... def multiply(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ... def divide(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ... def power(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ... diff --git a/tests/test_aritmeticlogic.py b/tests/test_aritmeticlogic.py index 5a08592..6397a06 100644 --- a/tests/test_aritmeticlogic.py +++ b/tests/test_aritmeticlogic.py @@ -6,7 +6,9 @@ def test_bit_shift_right(): def test_add(): - assert Chepy("0x40").add(1).o == 65 + assert Chepy("40").add(1).to_int().o == 51 + assert Chepy("hello").add('ff').o == b'gdkkn' + assert Chepy(9).add('01').o == b':' def test_multiply(): @@ -37,7 +39,10 @@ def test_median(): def test_subtract(): - assert Chepy(["0x02", "0x04"]).loop_list("subtract", {"n": 1}).o == [1, 3] + assert Chepy("40").subtract(1).o == b'3/' + assert Chepy("hello").subtract('10').o == b'XU\\\\_' + assert Chepy("hello").subtract(10).o == b'^[bbe' + # assert Chepy(9).add('01').o == b':' def test_int_to_base():