From f88e9e83dcd34d3883af4c0fa82b911ef452d9da Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sat, 15 Apr 2023 12:25:03 -0400 Subject: [PATCH 01/31] Added example for context managers --- src/feature-reef/enter_exit.py | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/feature-reef/enter_exit.py diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py new file mode 100644 index 0000000..639a11d --- /dev/null +++ b/src/feature-reef/enter_exit.py @@ -0,0 +1,97 @@ +# Dunders __enter__ and __exit__ + +from __future__ import annotations +from pathlib import Path +import os + + +class DocumentCollection: + paths: set[Path] = set() + invalid_paths: set[Path] = set() + unopenable_paths: set[Path] = set() + files = {} + files_are_being_opened: bool = False + + def __init__(self, paths: list[Path]): + for path in paths: + self.add_file(path) + + def add_file(self, path: Path) -> None: + path_is_file: bool = os.path.isfile(path) + path_exists: bool = os.path.exists(path) + path_already_added: bool = (path in self.paths + | self.invalid_paths + | self.unopenable_paths) + + if not path_already_added and path_exists and not path_is_file: + self.invalid_paths.add(path) + + if not path_already_added and path_is_file: + self.paths.add(path) + + if not path_already_added and not path_exists: + self.paths.add(path) + + if self.files_are_being_opened and path in self.paths: + self._open_file(path) + + def _open_file(self, path: Path) -> None: + assert self.files_are_being_opened and path in self.paths + + if not os.path.exists(path): + self.files[path] = open(path, "w") + + else: + match (os.access(path, os.W_OK), os.access(path, os.R_OK)): + case (_, False): + self.unopenable_paths.add(path) + + case (False, True): + self.files[path] = open(path, "r") + + case (True, True): + self.files[path] = open(path, "w") + + def open_all_files(self) -> None: + self.files_are_being_opened = True + + for path in self.paths: + self.add_file(path) + + def close_all_files(self) -> None: + for path, file in self.files.items(): + file.close() + + self.files_are_being_opened = False + self.files = {} + + def __enter__(self) -> None: + self.open_all_files() + + def __exit__( + self, exception_type, exception_value, + exception_traceback) -> None: + self.close_all_files() + + +def main() -> None: + documents = DocumentCollection(["doc1", "doc2", "doc3"]) + + with documents: + for path, document in documents.files.items(): + if document.writable(): + document.write("Hello, world!") + + documents.add_file("doc4") + + documents.files["doc4"].write("Important data!") + print(documents.files) + + documents.add_file("doc5") + + with documents: + print(documents.files.keys()) + + +if __name__ == "__main__": + main() From a84af66fe1750dda54624462743fe61dc7edfcc6 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sat, 15 Apr 2023 12:55:36 -0400 Subject: [PATCH 02/31] Simplified enter_exit.py --- src/feature-reef/enter_exit.py | 56 +++++----------------------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 639a11d..48ce978 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -1,78 +1,38 @@ # Dunders __enter__ and __exit__ from __future__ import annotations -from pathlib import Path -import os class DocumentCollection: - paths: set[Path] = set() - invalid_paths: set[Path] = set() - unopenable_paths: set[Path] = set() + paths: set[str] = set() files = {} files_are_being_opened: bool = False - def __init__(self, paths: list[Path]): + def __init__(self, paths: list[str]): for path in paths: self.add_file(path) - def add_file(self, path: Path) -> None: - path_is_file: bool = os.path.isfile(path) - path_exists: bool = os.path.exists(path) - path_already_added: bool = (path in self.paths - | self.invalid_paths - | self.unopenable_paths) - - if not path_already_added and path_exists and not path_is_file: - self.invalid_paths.add(path) - - if not path_already_added and path_is_file: - self.paths.add(path) - - if not path_already_added and not path_exists: - self.paths.add(path) + def add_file(self, path: str) -> None: + self.paths.add(path) if self.files_are_being_opened and path in self.paths: - self._open_file(path) - - def _open_file(self, path: Path) -> None: - assert self.files_are_being_opened and path in self.paths - - if not os.path.exists(path): self.files[path] = open(path, "w") - else: - match (os.access(path, os.W_OK), os.access(path, os.R_OK)): - case (_, False): - self.unopenable_paths.add(path) - - case (False, True): - self.files[path] = open(path, "r") - - case (True, True): - self.files[path] = open(path, "w") - - def open_all_files(self) -> None: + def __enter__(self) -> None: self.files_are_being_opened = True for path in self.paths: self.add_file(path) - def close_all_files(self) -> None: + def __exit__( + self, exception_type, exception_value, + exception_traceback) -> None: for path, file in self.files.items(): file.close() self.files_are_being_opened = False self.files = {} - def __enter__(self) -> None: - self.open_all_files() - - def __exit__( - self, exception_type, exception_value, - exception_traceback) -> None: - self.close_all_files() - def main() -> None: documents = DocumentCollection(["doc1", "doc2", "doc3"]) From a684f3c1a2494176f49052139f3096f75957209c Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sat, 15 Apr 2023 17:19:13 -0400 Subject: [PATCH 03/31] Rewrote example to include only dunders and exception handling --- src/feature-reef/enter_exit.py | 54 +++++++++++++--------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 48ce978..0cdb00c 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -3,54 +3,40 @@ from __future__ import annotations -class DocumentCollection: - paths: set[str] = set() - files = {} - files_are_being_opened: bool = False +def handle_error(exception): + ... - def __init__(self, paths: list[str]): - for path in paths: - self.add_file(path) - - def add_file(self, path: str) -> None: - self.paths.add(path) - - if self.files_are_being_opened and path in self.paths: - self.files[path] = open(path, "w") +class Something: def __enter__(self) -> None: - self.files_are_being_opened = True - - for path in self.paths: - self.add_file(path) + print("entering with block") def __exit__( self, exception_type, exception_value, exception_traceback) -> None: - for path, file in self.files.items(): - file.close() + print("exiting with block") - self.files_are_being_opened = False - self.files = {} + if (exception_value is not None): + print(f"exception '{exception_type}' " + f"occurred at line {exception_traceback.tb_lineno}: " + f"{exception_value}") + print("handling error") + handle_error(exception_value) -def main() -> None: - documents = DocumentCollection(["doc1", "doc2", "doc3"]) - - with documents: - for path, document in documents.files.items(): - if document.writable(): - document.write("Hello, world!") - documents.add_file("doc4") +def main() -> None: + doc = Something() - documents.files["doc4"].write("Important data!") - print(documents.files) + with doc: + print("\nExecuting fancy function\n") - documents.add_file("doc5") + try: + with doc: + raise Exception("error") - with documents: - print(documents.files.keys()) + except Exception: + pass if __name__ == "__main__": From 0d37d2c2db6cfdb24eaa0469eaed23f5c3d73999 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 16 Apr 2023 09:49:30 -0400 Subject: [PATCH 04/31] Renamed context class --- src/feature-reef/enter_exit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 0cdb00c..6453d6e 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -7,7 +7,7 @@ def handle_error(exception): ... -class Something: +class Context: def __enter__(self) -> None: print("entering with block") @@ -26,7 +26,7 @@ def __exit__( def main() -> None: - doc = Something() + doc = Context() with doc: print("\nExecuting fancy function\n") From 785ca036170cf5f4dc6ed5ac6775e0671d567f8a Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 16 Apr 2023 12:00:08 -0400 Subject: [PATCH 05/31] Added return to `__enter__` method --- src/feature-reef/enter_exit.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 6453d6e..1e8e54a 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -8,9 +8,11 @@ def handle_error(exception): class Context: - def __enter__(self) -> None: + def __enter__(self) -> Context: print("entering with block") + return self + def __exit__( self, exception_type, exception_value, exception_traceback) -> None: @@ -26,13 +28,11 @@ def __exit__( def main() -> None: - doc = Context() - - with doc: + with Context() as ctx: print("\nExecuting fancy function\n") try: - with doc: + with Context() as ctx: raise Exception("error") except Exception: From 2c5963ff9f964e3c9294ebf58ea70e91cd2c2c95 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 16 Apr 2023 17:41:30 -0400 Subject: [PATCH 06/31] Added usage of `ctx` within context --- src/feature-reef/enter_exit.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 1e8e54a..70377a2 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -8,6 +8,9 @@ def handle_error(exception): class Context: + def fancy_function(self) -> None: + print("executing fancy function") + def __enter__(self) -> Context: print("entering with block") @@ -29,7 +32,7 @@ def __exit__( def main() -> None: with Context() as ctx: - print("\nExecuting fancy function\n") + ctx.fancy_function() try: with Context() as ctx: From 5abbbf1714cc447b54abf01c239078d34a36d23a Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 16 Apr 2023 17:45:42 -0400 Subject: [PATCH 07/31] Added return type of bool for `__exit__` method --- src/feature-reef/enter_exit.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 70377a2..ee30698 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -3,10 +3,6 @@ from __future__ import annotations -def handle_error(exception): - ... - - class Context: def fancy_function(self) -> None: print("executing fancy function") @@ -18,7 +14,7 @@ def __enter__(self) -> Context: def __exit__( self, exception_type, exception_value, - exception_traceback) -> None: + exception_traceback) -> bool: print("exiting with block") if (exception_value is not None): @@ -26,20 +22,17 @@ def __exit__( f"occurred at line {exception_traceback.tb_lineno}: " f"{exception_value}") - print("handling error") - handle_error(exception_value) + print("ignoring error") + + return True def main() -> None: with Context() as ctx: ctx.fancy_function() - try: - with Context() as ctx: - raise Exception("error") - - except Exception: - pass + with Context() as ctx: + raise Exception("error") if __name__ == "__main__": From 779628cf245f52d9f37dd091d94e90becea3bdec Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 16 Apr 2023 19:24:57 -0400 Subject: [PATCH 08/31] Added comments --- src/feature-reef/enter_exit.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index ee30698..87456e6 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -24,15 +24,17 @@ def __exit__( print("ignoring error") - return True + return True # Returning true should suppress the exception def main() -> None: - with Context() as ctx: + with Context() as ctx: # Initializes ctx as a Context object ctx.fancy_function() + # Context.__exit__ gets called with Context() as ctx: raise Exception("error") + # Context.__exit__ suppresses the exception if __name__ == "__main__": From 42504ed3c052855af9b2feed5c75f8c40aa4f71b Mon Sep 17 00:00:00 2001 From: Rajin Braynard <85237518+FuexFollets@users.noreply.github.com> Date: Sun, 16 Apr 2023 19:57:05 -0400 Subject: [PATCH 09/31] Update src/feature-reef/enter_exit.py Co-authored-by: trag1c --- src/feature-reef/enter_exit.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/feature-reef/enter_exit.py b/src/feature-reef/enter_exit.py index 87456e6..729e5cd 100644 --- a/src/feature-reef/enter_exit.py +++ b/src/feature-reef/enter_exit.py @@ -30,9 +30,6 @@ def __exit__( def main() -> None: with Context() as ctx: # Initializes ctx as a Context object ctx.fancy_function() - # Context.__exit__ gets called - - with Context() as ctx: raise Exception("error") # Context.__exit__ suppresses the exception From eb5e7ad7ee3067806e6e9dcb1f663329ce245ff2 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Mon, 17 Apr 2023 08:06:29 -0400 Subject: [PATCH 10/31] Implemented Number class with all non-implace math dunders --- src/math-land/non_inplace_math.py | 83 +++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/math-land/non_inplace_math.py diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py new file mode 100644 index 0000000..e775838 --- /dev/null +++ b/src/math-land/non_inplace_math.py @@ -0,0 +1,83 @@ +# Dunders __add__, __sub__, __pos__, __neg__, +# __mul__, __floordiv__, __truediv__, __divmod__, __mod__, __int__ + +from __future__ import annotations +import math + + +class Number: + value: int | float = 0 + + def __init__(self, value: int | float) -> None: + self.value = value + + def __int__(self) -> int: + return int(self.value) + + def __float__(self) -> float: + return float(self.value) + + def __add__(self, other: Number) -> Number: + return Number(self.value + other.value) + + def __sub__(self, other: Number) -> Number: + return Number(self.value - other.value) + + def __pos__(self) -> Number: + return Number(+self.value) + + def __neg__(self) -> Number: + return Number(-self.value) + + def __mul__(self, other: Number) -> Number: + return Number(self.value * other.value) + + def __floordiv__(self, other: Number) -> Number: + return Number(self.value // other.value) + + def __truediv__(self, other: Number) -> Number: + return Number(self.value / other.value) + + def __divmod__(self, other: Number) -> tuple[Number, Number]: + return (Number(self.value // other.value), + Number(self.value % other.value)) + + def __mod__(self, other: Number) -> Number: + return Number(self.value % other.value) + + def __floor__(self) -> Number: + return Number(math.floor(self.value)) + + def __ceil__(self) -> Number: + return Number(math.ceil(self.value)) + + def __str__(self) -> str: # For printing + return str(self.value) + + +def main(): + val1 = Number(-2.71) + val2 = Number(3.14) + + # Calls __int__ which constructs an integer + print(f"val1 as intenger: {int(val1)}") + + # Calls __float__ which constructs a float + print(f"val2 as float: {float(val1)}") + + print(f"val1 + val2: {val1 + val2}") # Calls __add__ + print(f"val1 - val2: {val1 - val2}") # Calls __sub__ + print(f"+val1: {+val1}") # Calls __pos__ + print(f"-val1: {-val1}") # Calls __neg__ + print(f"val1 * val2: {val1 * val2}") # Calls __mul__ + print(f"val1 // val2: {val1 // val2}") # Calls __floordiv__ + print(f"val1 / val2: {val1 / val2}") # Calls __truediv__ + print(f"divmod(val1, val2): {divmod(val1, val2)}") # Calls __divmod__ + print(f"val1 % val2: {val1 % val2}") # Calls __mod__ + + print(f"math.floor(val1): {math.floor(val1)}") # Calls __floordiv__ + print(f"math.ceil(val1): {math.ceil(val1)}") # Calls __ceil__ + + +if __name__ == "__main__": + main() From 368e3621b284a7e3aee9bc4df24e3c15119a3837 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Mon, 17 Apr 2023 14:49:19 -0400 Subject: [PATCH 11/31] Changed container class representation and added additional math dunders --- src/math-land/non_inplace_math.py | 128 +++++++++++++++++++----------- 1 file changed, 81 insertions(+), 47 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index e775838..e315d64 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -5,78 +5,112 @@ import math -class Number: - value: int | float = 0 +class Land: + area: int | float = 0 - def __init__(self, value: int | float) -> None: - self.value = value + def __init__(self, area: int | float) -> None: + self.area = area def __int__(self) -> int: - return int(self.value) + return int(self.area) def __float__(self) -> float: - return float(self.value) + return float(self.area) - def __add__(self, other: Number) -> Number: - return Number(self.value + other.value) + def __add__(self, other: Land) -> Land: + return Land(self.area + other.area) - def __sub__(self, other: Number) -> Number: - return Number(self.value - other.value) + def __sub__(self, other: Land) -> Land: + return Land(self.area - other.area) - def __pos__(self) -> Number: - return Number(+self.value) + def __pos__(self) -> Land: + return Land(+self.area) - def __neg__(self) -> Number: - return Number(-self.value) + def __neg__(self) -> Land: + return Land(-self.area) - def __mul__(self, other: Number) -> Number: - return Number(self.value * other.value) + def __abs__(self) -> Land: + return Land(abs(self.area)) - def __floordiv__(self, other: Number) -> Number: - return Number(self.value // other.value) + def __mul__(self, scalar: int | float) -> Land: + return Land(self.area * scalar) - def __truediv__(self, other: Number) -> Number: - return Number(self.value / other.value) + def __floordiv__(self, dividend: int | float) -> Land: + return Land(self.area // dividend) - def __divmod__(self, other: Number) -> tuple[Number, Number]: - return (Number(self.value // other.value), - Number(self.value % other.value)) + def __truediv__(self, dividend: int | float) -> Land: + return Land(self.area / dividend) - def __mod__(self, other: Number) -> Number: - return Number(self.value % other.value) + def __divmod__(self, divided_and_modded: int | float) -> tuple[Land, Land]: + return (Land(self.area // divided_and_modded), + Land(self.area % divided_and_modded)) - def __floor__(self) -> Number: - return Number(math.floor(self.value)) + def __mod__(self, modded: int | float) -> Land: + return Land(self.area % modded) - def __ceil__(self) -> Number: - return Number(math.ceil(self.value)) + def __pow__(self, power: int | float) -> Land: + return Land(self.area ** power) + + def __floor__(self) -> Land: + return Land(math.floor(self.area)) + + def __ceil__(self) -> Land: + return Land(math.ceil(self.area)) + + def __complex__(self) -> complex: + return complex(self.area, 0) + + def __trunc__(self) -> int: + return int(self) def __str__(self) -> str: # For printing - return str(self.value) + return str(self.area) def main(): - val1 = Number(-2.71) - val2 = Number(3.14) + plot1 = Land(100) + plot2 = Land(-200) # Owes land to the government + plot3 = Land(5.5) # Calls __int__ which constructs an integer - print(f"val1 as intenger: {int(val1)}") + print(f"plot1 area as intenger: {int(plot1)}") # Calls __float__ which constructs a float - print(f"val2 as float: {float(val1)}") - - print(f"val1 + val2: {val1 + val2}") # Calls __add__ - print(f"val1 - val2: {val1 - val2}") # Calls __sub__ - print(f"+val1: {+val1}") # Calls __pos__ - print(f"-val1: {-val1}") # Calls __neg__ - print(f"val1 * val2: {val1 * val2}") # Calls __mul__ - print(f"val1 // val2: {val1 // val2}") # Calls __floordiv__ - print(f"val1 / val2: {val1 / val2}") # Calls __truediv__ - print(f"divmod(val1, val2): {divmod(val1, val2)}") # Calls __divmod__ - print(f"val1 % val2: {val1 % val2}") # Calls __mod__ - - print(f"math.floor(val1): {math.floor(val1)}") # Calls __floordiv__ - print(f"math.ceil(val1): {math.ceil(val1)}") # Calls __ceil__ + print(f"plot2 area as float: {float(plot2)}") + + print(f"Combined area of plot1, plot2: {plot1 + plot3}") # Calls __add__ + + # Calls __sub__ + print(f"The area of plot1 taken away from plot 2: {plot1 - plot3}") + + print(f"Positive of plot1 area +(plot1.area): {+plot1}") # Calls __pos__ + print(f"Negative of plot1 area (-plot1): {-plot1}") # Calls __neg__ + print("Absolute value plot2 area: {abs(plot2)}") # Calls __abs__ + print(f"plot1 area being scaled by 3: {plot1 * 3}") # Calls __mul__ + + # Calls __floordiv__ + print(f"Divisions into plots of land from plot1 of exactly 9 area:" + f"{plot1 // 9}") + print(f"Divides plot2 into 5 pieces: {plot2 / 5}") # Calls __truediv__ + + divisions, remainder = divmod(plot1, 7) # Calls __divmod__ + print(f"plot1 can be divided into {divisions} plots of 7 area each" + f"with a remainder of {remainder} area") + + # Calls __mod__ + print(f"The remainder of dividing plot1 into 22 pieces is {plot1 % 22}") + + # Calls __floor__ + print(f"The area of plot3 rounded down is: {math.floor(plot3)}") + + # calls __ceil__ + print(f"The are of plot3 rounded up is: {math.ceil(plot3)}") + + # calls __complex__ + print(f"Area of plot3 represented as a complex number {complex(plot3)}") + + # calls __trunc__ + print(f"The truncated integer area of plot3 {math.trunc(plot3)}") if __name__ == "__main__": From de32b69819eb59e215ff47beb9ec16f946b56346 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Mon, 17 Apr 2023 14:50:24 -0400 Subject: [PATCH 12/31] Update dunder listing comment at top --- src/math-land/non_inplace_math.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index e315d64..5020a3d 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -1,5 +1,6 @@ # Dunders __add__, __sub__, __pos__, __neg__, # __mul__, __floordiv__, __truediv__, __divmod__, __mod__, __int__ +# __complex__, __abs__, __trunc__, __pow__ from __future__ import annotations import math From 767def80d60b706c5ea843c6973de814ecb53777 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Tue, 18 Apr 2023 07:56:55 -0400 Subject: [PATCH 13/31] Added missing __pow__ showcase --- src/math-land/non_inplace_math.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 5020a3d..8f3d5ec 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -89,6 +89,10 @@ def main(): print("Absolute value plot2 area: {abs(plot2)}") # Calls __abs__ print(f"plot1 area being scaled by 3: {plot1 * 3}") # Calls __mul__ + # Calls __pow__ + print(f"plot3 area being raised to the power of 3 {plot3 ** 3}") + # pow(plot3, 3) also works + # Calls __floordiv__ print(f"Divisions into plots of land from plot1 of exactly 9 area:" f"{plot1 // 9}") From 4f6536db7b42b658ffe1928478609250256be888 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Tue, 18 Apr 2023 07:57:26 -0400 Subject: [PATCH 14/31] Fixed wording of print statments --- src/math-land/non_inplace_math.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 8f3d5ec..6c3c0ff 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -85,7 +85,7 @@ def main(): print(f"The area of plot1 taken away from plot 2: {plot1 - plot3}") print(f"Positive of plot1 area +(plot1.area): {+plot1}") # Calls __pos__ - print(f"Negative of plot1 area (-plot1): {-plot1}") # Calls __neg__ + print(f"Negative of plot1 area -(plot1): {-plot1}") # Calls __neg__ print("Absolute value plot2 area: {abs(plot2)}") # Calls __abs__ print(f"plot1 area being scaled by 3: {plot1 * 3}") # Calls __mul__ @@ -103,7 +103,8 @@ def main(): f"with a remainder of {remainder} area") # Calls __mod__ - print(f"The remainder of dividing plot1 into 22 pieces is {plot1 % 22}") + print(f"The remainder of dividing plot1 into 22 whole pieces is" + f"{plot1 % 22}") # Calls __floor__ print(f"The area of plot3 rounded down is: {math.floor(plot3)}") From 46ea2ca53be73596a1d54d050bd7e9bd5ffd92e0 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Tue, 18 Apr 2023 08:00:10 -0400 Subject: [PATCH 15/31] Added spaces for linebreak f-strings --- src/math-land/non_inplace_math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 6c3c0ff..b45d698 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -94,12 +94,12 @@ def main(): # pow(plot3, 3) also works # Calls __floordiv__ - print(f"Divisions into plots of land from plot1 of exactly 9 area:" + print(f"Divisions into plots of land from plot1 of exactly 9 area: " f"{plot1 // 9}") print(f"Divides plot2 into 5 pieces: {plot2 / 5}") # Calls __truediv__ divisions, remainder = divmod(plot1, 7) # Calls __divmod__ - print(f"plot1 can be divided into {divisions} plots of 7 area each" + print(f"plot1 can be divided into {divisions} plots of 7 area each " f"with a remainder of {remainder} area") # Calls __mod__ From 8513e5da4c0def967500743f0fdce63ecb985a8f Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Wed, 19 Apr 2023 17:45:31 -0400 Subject: [PATCH 16/31] Removed __int__, __float__, and __complex__ as examples --- src/math-land/non_inplace_math.py | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index b45d698..47ccbea 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -1,6 +1,6 @@ # Dunders __add__, __sub__, __pos__, __neg__, -# __mul__, __floordiv__, __truediv__, __divmod__, __mod__, __int__ -# __complex__, __abs__, __trunc__, __pow__ +# __mul__, __floordiv__, __truediv__, __divmod__, __mod__, +# __abs__, __trunc__, __pow__ from __future__ import annotations import math @@ -12,12 +12,6 @@ class Land: def __init__(self, area: int | float) -> None: self.area = area - def __int__(self) -> int: - return int(self.area) - - def __float__(self) -> float: - return float(self.area) - def __add__(self, other: Land) -> Land: return Land(self.area + other.area) @@ -62,7 +56,7 @@ def __complex__(self) -> complex: return complex(self.area, 0) def __trunc__(self) -> int: - return int(self) + return int(self.area) def __str__(self) -> str: # For printing return str(self.area) @@ -73,12 +67,6 @@ def main(): plot2 = Land(-200) # Owes land to the government plot3 = Land(5.5) - # Calls __int__ which constructs an integer - print(f"plot1 area as intenger: {int(plot1)}") - - # Calls __float__ which constructs a float - print(f"plot2 area as float: {float(plot2)}") - print(f"Combined area of plot1, plot2: {plot1 + plot3}") # Calls __add__ # Calls __sub__ @@ -112,9 +100,6 @@ def main(): # calls __ceil__ print(f"The are of plot3 rounded up is: {math.ceil(plot3)}") - # calls __complex__ - print(f"Area of plot3 represented as a complex number {complex(plot3)}") - # calls __trunc__ print(f"The truncated integer area of plot3 {math.trunc(plot3)}") From 8573d6996b3019da544f42667f11399133fa9d84 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Wed, 19 Apr 2023 17:49:20 -0400 Subject: [PATCH 17/31] Formatted file with black --- src/math-land/non_inplace_math.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 47ccbea..dca4eac 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -37,14 +37,16 @@ def __truediv__(self, dividend: int | float) -> Land: return Land(self.area / dividend) def __divmod__(self, divided_and_modded: int | float) -> tuple[Land, Land]: - return (Land(self.area // divided_and_modded), - Land(self.area % divided_and_modded)) + return ( + Land(self.area // divided_and_modded), + Land(self.area % divided_and_modded), + ) def __mod__(self, modded: int | float) -> Land: return Land(self.area % modded) def __pow__(self, power: int | float) -> Land: - return Land(self.area ** power) + return Land(self.area**power) def __floor__(self) -> Land: return Land(math.floor(self.area)) @@ -82,17 +84,19 @@ def main(): # pow(plot3, 3) also works # Calls __floordiv__ - print(f"Divisions into plots of land from plot1 of exactly 9 area: " - f"{plot1 // 9}") + print( + f"Divisions into plots of land from plot1 of exactly 9 area: " f"{plot1 // 9}" + ) print(f"Divides plot2 into 5 pieces: {plot2 / 5}") # Calls __truediv__ divisions, remainder = divmod(plot1, 7) # Calls __divmod__ - print(f"plot1 can be divided into {divisions} plots of 7 area each " - f"with a remainder of {remainder} area") + print( + f"plot1 can be divided into {divisions} plots of 7 area each " + f"with a remainder of {remainder} area" + ) # Calls __mod__ - print(f"The remainder of dividing plot1 into 22 whole pieces is" - f"{plot1 % 22}") + print(f"The remainder of dividing plot1 into 22 whole pieces is" f"{plot1 % 22}") # Calls __floor__ print(f"The area of plot3 rounded down is: {math.floor(plot3)}") From a37f6d3c0542b541b77564bb27ee082e83a31606 Mon Sep 17 00:00:00 2001 From: Rajin Braynard <85237518+FuexFollets@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:15:14 -0400 Subject: [PATCH 18/31] Update src/math-land/non_inplace_math.py Co-authored-by: trag1c --- src/math-land/non_inplace_math.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index dca4eac..6c4a9b0 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -54,9 +54,6 @@ def __floor__(self) -> Land: def __ceil__(self) -> Land: return Land(math.ceil(self.area)) - def __complex__(self) -> complex: - return complex(self.area, 0) - def __trunc__(self) -> int: return int(self.area) From 54738881d11314325fe97af735560c7337a4ee38 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Wed, 19 Apr 2023 18:16:05 -0400 Subject: [PATCH 19/31] Formatted files --- src/math-land/non_inplace_math.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 6c4a9b0..f6acc12 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -82,7 +82,8 @@ def main(): # Calls __floordiv__ print( - f"Divisions into plots of land from plot1 of exactly 9 area: " f"{plot1 // 9}" + f"Divisions into plots of land from plot1 of exactly 9 area: " + f"{plot1 // 9}" ) print(f"Divides plot2 into 5 pieces: {plot2 / 5}") # Calls __truediv__ @@ -93,7 +94,10 @@ def main(): ) # Calls __mod__ - print(f"The remainder of dividing plot1 into 22 whole pieces is" f"{plot1 % 22}") + print( + f"The remainder of dividing plot1 into 22 whole pieces is" + f"{plot1 % 22}" + ) # Calls __floor__ print(f"The area of plot3 rounded down is: {math.floor(plot3)}") From f5f8a44027e252782943e3fe7d0d954f0eed59c6 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Wed, 19 Apr 2023 18:59:44 -0400 Subject: [PATCH 20/31] Fixed import statement sorting --- src/math-land/non_inplace_math.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index f6acc12..a7a4dd4 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -3,6 +3,7 @@ # __abs__, __trunc__, __pow__ from __future__ import annotations + import math From d9f7b1e8d44ed35f9f7e4d671c23559cf6235b8b Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Fri, 5 May 2023 09:17:57 -0400 Subject: [PATCH 21/31] Changed land exmple to number wrapper, fixed strings and variable names --- src/math-land/non_inplace_math.py | 110 +++++++++++++++--------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index a7a4dd4..1ad0b87 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -7,107 +7,107 @@ import math -class Land: - area: int | float = 0 +class NumberWrapper: + value: int | float = 0 - def __init__(self, area: int | float) -> None: - self.area = area + def __init__(self, value: int | float) -> None: + self.value = value - def __add__(self, other: Land) -> Land: - return Land(self.area + other.area) + def __add__(self, other: NumberWrapper) -> NumberWrapper: + return NumberWrapper(self.value + other.value) - def __sub__(self, other: Land) -> Land: - return Land(self.area - other.area) + def __sub__(self, other: NumberWrapper) -> NumberWrapper: + return NumberWrapper(self.value - other.value) - def __pos__(self) -> Land: - return Land(+self.area) + def __pos__(self) -> NumberWrapper: + return NumberWrapper(+self.value) - def __neg__(self) -> Land: - return Land(-self.area) + def __neg__(self) -> NumberWrapper: + return NumberWrapper(-self.value) - def __abs__(self) -> Land: - return Land(abs(self.area)) + def __abs__(self) -> NumberWrapper: + return NumberWrapper(abs(self.value)) - def __mul__(self, scalar: int | float) -> Land: - return Land(self.area * scalar) + def __mul__(self, scalar: int | float) -> NumberWrapper: + return NumberWrapper(self.value * scalar) - def __floordiv__(self, dividend: int | float) -> Land: - return Land(self.area // dividend) + def __floordiv__(self, divisor: int | float) -> NumberWrapper: + return NumberWrapper(self.value // divisor) - def __truediv__(self, dividend: int | float) -> Land: - return Land(self.area / dividend) + def __truediv__(self, divisor: int | float) -> NumberWrapper: + return NumberWrapper(self.value / divisor) - def __divmod__(self, divided_and_modded: int | float) -> tuple[Land, Land]: + def __divmod__(self, divisor: int | float) -> tuple[NumberWrapper, NumberWrapper]: return ( - Land(self.area // divided_and_modded), - Land(self.area % divided_and_modded), + NumberWrapper(self.value // divisor), + NumberWrapper(self.value % divisor), ) - def __mod__(self, modded: int | float) -> Land: - return Land(self.area % modded) + def __mod__(self, divisor: int | float) -> NumberWrapper: + return NumberWrapper(self.value % divisor) - def __pow__(self, power: int | float) -> Land: - return Land(self.area**power) + def __pow__(self, power: int | float) -> NumberWrapper: + return NumberWrapper(self.value**power) - def __floor__(self) -> Land: - return Land(math.floor(self.area)) + def __floor__(self) -> NumberWrapper: + return NumberWrapper(math.floor(self.value)) - def __ceil__(self) -> Land: - return Land(math.ceil(self.area)) + def __ceil__(self) -> NumberWrapper: + return NumberWrapper(math.ceil(self.value)) def __trunc__(self) -> int: - return int(self.area) + return int(self.value) def __str__(self) -> str: # For printing - return str(self.area) + return str(self.value) def main(): - plot1 = Land(100) - plot2 = Land(-200) # Owes land to the government - plot3 = Land(5.5) + number_100 = NumberWrapper(100) + number_neg200 = NumberWrapper(-200) # Owes land to the government + number_5point5 = NumberWrapper(5.5) - print(f"Combined area of plot1, plot2: {plot1 + plot3}") # Calls __add__ + print(f"Combined value of number_100, number_neg200: {number_100 + number_5point5}") # Calls __add__ # Calls __sub__ - print(f"The area of plot1 taken away from plot 2: {plot1 - plot3}") + print(f"The value of number_100 taken away from plot 2: {number_100 - number_5point5}") - print(f"Positive of plot1 area +(plot1.area): {+plot1}") # Calls __pos__ - print(f"Negative of plot1 area -(plot1): {-plot1}") # Calls __neg__ - print("Absolute value plot2 area: {abs(plot2)}") # Calls __abs__ - print(f"plot1 area being scaled by 3: {plot1 * 3}") # Calls __mul__ + print(f"Positive of number_100 value +(number_100.value): {+number_100}") # Calls __pos__ + print(f"Negative of number_100 value -(number_100): {-number_100}") # Calls __neg__ + print(f"Absolute value number_neg200 value: {abs(number_neg200)}") # Calls __abs__ + print(f"number_100 value being scaled by 3: {number_100 * 3}") # Calls __mul__ # Calls __pow__ - print(f"plot3 area being raised to the power of 3 {plot3 ** 3}") - # pow(plot3, 3) also works + print(f"number_5point5 value being raised to the power of 3 {number_5point5 ** 3}") + # pow(number_5point5, 3) also works # Calls __floordiv__ print( - f"Divisions into plots of land from plot1 of exactly 9 area: " - f"{plot1 // 9}" + "Divisions into plots of land from number_100 of exactly 9 value: " + f"{number_100 // 9}" ) - print(f"Divides plot2 into 5 pieces: {plot2 / 5}") # Calls __truediv__ + print(f"Divides number_neg200 into 5 pieces: {number_neg200 / 5}") # Calls __truediv__ - divisions, remainder = divmod(plot1, 7) # Calls __divmod__ + divisions, remainder = divmod(number_100, 7) # Calls __divmod__ print( - f"plot1 can be divided into {divisions} plots of 7 area each " - f"with a remainder of {remainder} area" + f"number_100 can be divided into {divisions} plots of 7 value each " + f"with a remainder of {remainder} value" ) # Calls __mod__ print( - f"The remainder of dividing plot1 into 22 whole pieces is" - f"{plot1 % 22}" + f"The remainder of dividing number_100 into 22 whole pieces is" + f"{number_100 % 22}" ) # Calls __floor__ - print(f"The area of plot3 rounded down is: {math.floor(plot3)}") + print(f"The value of number_5point5 rounded down is: {math.floor(number_5point5)}") # calls __ceil__ - print(f"The are of plot3 rounded up is: {math.ceil(plot3)}") + print(f"The are of number_5point5 rounded up is: {math.ceil(number_5point5)}") # calls __trunc__ - print(f"The truncated integer area of plot3 {math.trunc(plot3)}") + print(f"The truncated integer value of number_5point5 {math.trunc(number_5point5)}") if __name__ == "__main__": From 1740e62bd8c15558e87317ae209802dcfb8c5035 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Fri, 5 May 2023 09:18:25 -0400 Subject: [PATCH 22/31] Formatted 'non_inplace_math.py' --- src/math-land/non_inplace_math.py | 48 +++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 1ad0b87..6656a13 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -37,7 +37,9 @@ def __floordiv__(self, divisor: int | float) -> NumberWrapper: def __truediv__(self, divisor: int | float) -> NumberWrapper: return NumberWrapper(self.value / divisor) - def __divmod__(self, divisor: int | float) -> tuple[NumberWrapper, NumberWrapper]: + def __divmod__( + self, divisor: int | float + ) -> tuple[NumberWrapper, NumberWrapper]: return ( NumberWrapper(self.value // divisor), NumberWrapper(self.value % divisor), @@ -67,18 +69,32 @@ def main(): number_neg200 = NumberWrapper(-200) # Owes land to the government number_5point5 = NumberWrapper(5.5) - print(f"Combined value of number_100, number_neg200: {number_100 + number_5point5}") # Calls __add__ + print( + f"Combined value of number_100, number_neg200: {number_100 + number_5point5}" + ) # Calls __add__ # Calls __sub__ - print(f"The value of number_100 taken away from plot 2: {number_100 - number_5point5}") + print( + f"The value of number_100 taken away from plot 2: {number_100 - number_5point5}" + ) - print(f"Positive of number_100 value +(number_100.value): {+number_100}") # Calls __pos__ - print(f"Negative of number_100 value -(number_100): {-number_100}") # Calls __neg__ - print(f"Absolute value number_neg200 value: {abs(number_neg200)}") # Calls __abs__ - print(f"number_100 value being scaled by 3: {number_100 * 3}") # Calls __mul__ + print( + f"Positive of number_100 value +(number_100.value): {+number_100}" + ) # Calls __pos__ + print( + f"Negative of number_100 value -(number_100): {-number_100}" + ) # Calls __neg__ + print( + f"Absolute value number_neg200 value: {abs(number_neg200)}" + ) # Calls __abs__ + print( + f"number_100 value being scaled by 3: {number_100 * 3}" + ) # Calls __mul__ # Calls __pow__ - print(f"number_5point5 value being raised to the power of 3 {number_5point5 ** 3}") + print( + f"number_5point5 value being raised to the power of 3 {number_5point5 ** 3}" + ) # pow(number_5point5, 3) also works # Calls __floordiv__ @@ -86,7 +102,9 @@ def main(): "Divisions into plots of land from number_100 of exactly 9 value: " f"{number_100 // 9}" ) - print(f"Divides number_neg200 into 5 pieces: {number_neg200 / 5}") # Calls __truediv__ + print( + f"Divides number_neg200 into 5 pieces: {number_neg200 / 5}" + ) # Calls __truediv__ divisions, remainder = divmod(number_100, 7) # Calls __divmod__ print( @@ -101,13 +119,19 @@ def main(): ) # Calls __floor__ - print(f"The value of number_5point5 rounded down is: {math.floor(number_5point5)}") + print( + f"The value of number_5point5 rounded down is: {math.floor(number_5point5)}" + ) # calls __ceil__ - print(f"The are of number_5point5 rounded up is: {math.ceil(number_5point5)}") + print( + f"The are of number_5point5 rounded up is: {math.ceil(number_5point5)}" + ) # calls __trunc__ - print(f"The truncated integer value of number_5point5 {math.trunc(number_5point5)}") + print( + f"The truncated integer value of number_5point5 {math.trunc(number_5point5)}" + ) if __name__ == "__main__": From 774e83ebb0de182ea1f6b93b3eb951e9927cb696 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Fri, 5 May 2023 09:19:54 -0400 Subject: [PATCH 23/31] Removed class variable --- src/math-land/non_inplace_math.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 6656a13..55f68ff 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -8,8 +8,6 @@ class NumberWrapper: - value: int | float = 0 - def __init__(self, value: int | float) -> None: self.value = value From ad63b48ee471a08f9e372b81d32e5bbb8f1fe7cf Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 15:20:31 -0400 Subject: [PATCH 24/31] Implemented fraction type for all dunders --- src/math-land/non_inplace_math.py | 175 ++++++++++++------------------ 1 file changed, 70 insertions(+), 105 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 55f68ff..8bef457 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -1,135 +1,100 @@ # Dunders __add__, __sub__, __pos__, __neg__, # __mul__, __floordiv__, __truediv__, __divmod__, __mod__, -# __abs__, __trunc__, __pow__ +# __abs__, __trunc__, __pow__, __ceil__, __floor__. __int__, __float__ from __future__ import annotations import math -class NumberWrapper: - def __init__(self, value: int | float) -> None: - self.value = value +class Fraction: + def __init__(self, numerator: int, denominator: int) -> None: + self.numerator: int = numerator + self.denominator: int = denominator - def __add__(self, other: NumberWrapper) -> NumberWrapper: - return NumberWrapper(self.value + other.value) + self.simplify() - def __sub__(self, other: NumberWrapper) -> NumberWrapper: - return NumberWrapper(self.value - other.value) + def simplify(self) -> Fraction: + gcd: int = math.gcd(self.numerator, self.denominator) + negative_remover = -1 if (self.numerator < 0 and self.denominator < 0) else 1 - def __pos__(self) -> NumberWrapper: - return NumberWrapper(+self.value) + return Fraction(self.numerator // gcd * negative_remover, self.denominator // gcd * negative_remover) - def __neg__(self) -> NumberWrapper: - return NumberWrapper(-self.value) + def flip(self) -> Fraction: + return Fraction(self.denominator, self.numerator) - def __abs__(self) -> NumberWrapper: - return NumberWrapper(abs(self.value)) + def __float__(self) -> float: + return self.numerator / self.denominator - def __mul__(self, scalar: int | float) -> NumberWrapper: - return NumberWrapper(self.value * scalar) + def __int__(self) -> int: + return self.numerator // self.denominator - def __floordiv__(self, divisor: int | float) -> NumberWrapper: - return NumberWrapper(self.value // divisor) + def __add__(self, other: Fraction) -> Fraction: + return Fraction( + self.numerator * other.denominator + other.numerator * self.denominator, + self.denominator * other.denominator, + ).simplify() - def __truediv__(self, divisor: int | float) -> NumberWrapper: - return NumberWrapper(self.value / divisor) + def __sub__(self, other: Fraction) -> Fraction: + return Fraction( + self.numerator * other.denominator - other.numerator * self.denominator, + self.denominator * other.denominator, + ).simplify() - def __divmod__( - self, divisor: int | float - ) -> tuple[NumberWrapper, NumberWrapper]: - return ( - NumberWrapper(self.value // divisor), - NumberWrapper(self.value % divisor), - ) + def __pos__(self) -> Fraction: + return Fraction(self.numerator, self.denominator).simplify() - def __mod__(self, divisor: int | float) -> NumberWrapper: - return NumberWrapper(self.value % divisor) + def __neg__(self) -> Fraction: + return Fraction(-self.numerator, self.denominator).simplify() - def __pow__(self, power: int | float) -> NumberWrapper: - return NumberWrapper(self.value**power) + def __mul__(self, other: Fraction | int) -> Fraction: + if isinstance(other, int): + return Fraction(self.numerator * other, self.denominator).simplify() - def __floor__(self) -> NumberWrapper: - return NumberWrapper(math.floor(self.value)) + return Fraction( + self.numerator * other.numerator, self.denominator * other.denominator + ).simplify() - def __ceil__(self) -> NumberWrapper: - return NumberWrapper(math.ceil(self.value)) + def __truediv__(self, other: Fraction) -> Fraction: + return (self * other.flip()).simplify() + + def __floordiv__(self, other: Fraction) -> int: + return int(self / other) + + def __mod__(self, other: Fraction) -> Fraction: + remainder: int = other - other * (self // other) + + return self - remainder * other + + def __divmod__(self, other: Fraction) -> tuple[Fraction, Fraction]: + return (self // other, + self % other) + + def __pow__(self, power: int) -> Fraction: + return Fraction(self.numerator ** power, self.denominator ** power).simplify() + + def __abs__(self) -> Fraction: + return Fraction(abs(self.numerator), abs(self.denominator)).simplify() def __trunc__(self) -> int: - return int(self.value) + # possible implementation + # return int(float(self)) + + # better way + return self.numerator // self.denominator + + def __ceil__(self) -> int: + return math.ceil(float(self)) + + def __floor__(self) -> int: + return math.floor(float(self)) - def __str__(self) -> str: # For printing - return str(self.value) + def __str__(self) -> str: + return f"{self.numerator}/{self.denominator}" def main(): - number_100 = NumberWrapper(100) - number_neg200 = NumberWrapper(-200) # Owes land to the government - number_5point5 = NumberWrapper(5.5) - - print( - f"Combined value of number_100, number_neg200: {number_100 + number_5point5}" - ) # Calls __add__ - - # Calls __sub__ - print( - f"The value of number_100 taken away from plot 2: {number_100 - number_5point5}" - ) - - print( - f"Positive of number_100 value +(number_100.value): {+number_100}" - ) # Calls __pos__ - print( - f"Negative of number_100 value -(number_100): {-number_100}" - ) # Calls __neg__ - print( - f"Absolute value number_neg200 value: {abs(number_neg200)}" - ) # Calls __abs__ - print( - f"number_100 value being scaled by 3: {number_100 * 3}" - ) # Calls __mul__ - - # Calls __pow__ - print( - f"number_5point5 value being raised to the power of 3 {number_5point5 ** 3}" - ) - # pow(number_5point5, 3) also works - - # Calls __floordiv__ - print( - "Divisions into plots of land from number_100 of exactly 9 value: " - f"{number_100 // 9}" - ) - print( - f"Divides number_neg200 into 5 pieces: {number_neg200 / 5}" - ) # Calls __truediv__ - - divisions, remainder = divmod(number_100, 7) # Calls __divmod__ - print( - f"number_100 can be divided into {divisions} plots of 7 value each " - f"with a remainder of {remainder} value" - ) - - # Calls __mod__ - print( - f"The remainder of dividing number_100 into 22 whole pieces is" - f"{number_100 % 22}" - ) - - # Calls __floor__ - print( - f"The value of number_5point5 rounded down is: {math.floor(number_5point5)}" - ) - - # calls __ceil__ - print( - f"The are of number_5point5 rounded up is: {math.ceil(number_5point5)}" - ) - - # calls __trunc__ - print( - f"The truncated integer value of number_5point5 {math.trunc(number_5point5)}" - ) + pass if __name__ == "__main__": From 0fa851288349a8f4a3864d8885390f14ca34aec5 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 15:20:55 -0400 Subject: [PATCH 25/31] Formatted code --- src/math-land/non_inplace_math.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 8bef457..7ed6376 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -16,9 +16,14 @@ def __init__(self, numerator: int, denominator: int) -> None: def simplify(self) -> Fraction: gcd: int = math.gcd(self.numerator, self.denominator) - negative_remover = -1 if (self.numerator < 0 and self.denominator < 0) else 1 + negative_remover = ( + -1 if (self.numerator < 0 and self.denominator < 0) else 1 + ) - return Fraction(self.numerator // gcd * negative_remover, self.denominator // gcd * negative_remover) + return Fraction( + self.numerator // gcd * negative_remover, + self.denominator // gcd * negative_remover, + ) def flip(self) -> Fraction: return Fraction(self.denominator, self.numerator) @@ -31,13 +36,15 @@ def __int__(self) -> int: def __add__(self, other: Fraction) -> Fraction: return Fraction( - self.numerator * other.denominator + other.numerator * self.denominator, + self.numerator * other.denominator + + other.numerator * self.denominator, self.denominator * other.denominator, ).simplify() def __sub__(self, other: Fraction) -> Fraction: return Fraction( - self.numerator * other.denominator - other.numerator * self.denominator, + self.numerator * other.denominator + - other.numerator * self.denominator, self.denominator * other.denominator, ).simplify() @@ -52,7 +59,8 @@ def __mul__(self, other: Fraction | int) -> Fraction: return Fraction(self.numerator * other, self.denominator).simplify() return Fraction( - self.numerator * other.numerator, self.denominator * other.denominator + self.numerator * other.numerator, + self.denominator * other.denominator, ).simplify() def __truediv__(self, other: Fraction) -> Fraction: @@ -67,11 +75,12 @@ def __mod__(self, other: Fraction) -> Fraction: return self - remainder * other def __divmod__(self, other: Fraction) -> tuple[Fraction, Fraction]: - return (self // other, - self % other) + return (self // other, self % other) def __pow__(self, power: int) -> Fraction: - return Fraction(self.numerator ** power, self.denominator ** power).simplify() + return Fraction( + self.numerator**power, self.denominator**power + ).simplify() def __abs__(self) -> Fraction: return Fraction(abs(self.numerator), abs(self.denominator)).simplify() From 23de871347b24d39378fd54269dbe5a776687eec Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 15:29:46 -0400 Subject: [PATCH 26/31] Fixed some bugs, added examples --- src/math-land/non_inplace_math.py | 57 +++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 7ed6376..6d8391e 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -12,8 +12,6 @@ def __init__(self, numerator: int, denominator: int) -> None: self.numerator: int = numerator self.denominator: int = denominator - self.simplify() - def simplify(self) -> Fraction: gcd: int = math.gcd(self.numerator, self.denominator) negative_remover = ( @@ -101,9 +99,62 @@ def __floor__(self) -> int: def __str__(self) -> str: return f"{self.numerator}/{self.denominator}" + def __repr__(self) -> str: + return f"Fraction({self.numerator}, {self.denominator})" + def main(): - pass + three_over_five: Fraction = Fraction(3, 5) + one_over_two: Fraction = Fraction(1, 2) + negative_seven_over_nine: Fraction = Fraction(-7, 9) + + # __float__ + print(f"Floating point value of {three_over_five} is {float(three_over_five)}") + + # __int__ + print(f"Integer floored value of {three_over_five} is {int(three_over_five)}") + + # __add__ + print(f"{three_over_five} + {one_over_two} = {three_over_five + one_over_two}") + + # __sub__ + print(f"{three_over_five} - {one_over_two} = {three_over_five - one_over_two}") + + # __pos__ + print(f"Positive value of {negative_seven_over_nine} is {+negative_seven_over_nine}") + + # __neg__ + print(f"Negative value of {three_over_five} is {-three_over_five}") + + # __mul__ + print(f"{three_over_five} * {one_over_two} = {three_over_five * one_over_two}") + + # __truediv__ + print(f"{three_over_five} / {one_over_two} = {three_over_five / one_over_two}") + + # __floordiv__ + print(f"{three_over_five} // {one_over_two} = {three_over_five // one_over_two}") + + # __mod__ + print(f"{three_over_five} % {one_over_two} = {three_over_five % one_over_two}") + + # __divmod__ + print(f"divmod({three_over_five}, {one_over_two}) = {divmod(three_over_five, one_over_two)}") + + # __pow__ + print(f"{three_over_five} ** 2 = {three_over_five ** 2}") + + # __abs__ + print(f"Absolute value of {negative_seven_over_nine} is {abs(negative_seven_over_nine)}") + + # __trunc__ + print(f"Truncated value of {three_over_five} is {math.trunc(three_over_five)}") + + # __ceil__ + print(f"Ceiled value of {three_over_five} is {math.ceil(three_over_five)}") + + # __floor__ + print(f"Floored value of {three_over_five} is {math.floor(three_over_five)}") if __name__ == "__main__": From e31b5da9b5ff5eb1b2b1c3aa5bafd5a58fb9c4c8 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 15:30:19 -0400 Subject: [PATCH 27/31] Reformatted code --- src/math-land/non_inplace_math.py | 52 +++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 6d8391e..678717c 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -109,52 +109,78 @@ def main(): negative_seven_over_nine: Fraction = Fraction(-7, 9) # __float__ - print(f"Floating point value of {three_over_five} is {float(three_over_five)}") + print( + f"Floating point value of {three_over_five} is {float(three_over_five)}" + ) # __int__ - print(f"Integer floored value of {three_over_five} is {int(three_over_five)}") + print( + f"Integer floored value of {three_over_five} is {int(three_over_five)}" + ) # __add__ - print(f"{three_over_five} + {one_over_two} = {three_over_five + one_over_two}") + print( + f"{three_over_five} + {one_over_two} = {three_over_five + one_over_two}" + ) # __sub__ - print(f"{three_over_five} - {one_over_two} = {three_over_five - one_over_two}") + print( + f"{three_over_five} - {one_over_two} = {three_over_five - one_over_two}" + ) # __pos__ - print(f"Positive value of {negative_seven_over_nine} is {+negative_seven_over_nine}") + print( + f"Positive value of {negative_seven_over_nine} is {+negative_seven_over_nine}" + ) # __neg__ print(f"Negative value of {three_over_five} is {-three_over_five}") # __mul__ - print(f"{three_over_five} * {one_over_two} = {three_over_five * one_over_two}") + print( + f"{three_over_five} * {one_over_two} = {three_over_five * one_over_two}" + ) # __truediv__ - print(f"{three_over_five} / {one_over_two} = {three_over_five / one_over_two}") + print( + f"{three_over_five} / {one_over_two} = {three_over_five / one_over_two}" + ) # __floordiv__ - print(f"{three_over_five} // {one_over_two} = {three_over_five // one_over_two}") + print( + f"{three_over_five} // {one_over_two} = {three_over_five // one_over_two}" + ) # __mod__ - print(f"{three_over_five} % {one_over_two} = {three_over_five % one_over_two}") + print( + f"{three_over_five} % {one_over_two} = {three_over_five % one_over_two}" + ) # __divmod__ - print(f"divmod({three_over_five}, {one_over_two}) = {divmod(three_over_five, one_over_two)}") + print( + f"divmod({three_over_five}, {one_over_two}) = {divmod(three_over_five, one_over_two)}" + ) # __pow__ print(f"{three_over_five} ** 2 = {three_over_five ** 2}") # __abs__ - print(f"Absolute value of {negative_seven_over_nine} is {abs(negative_seven_over_nine)}") + print( + f"Absolute value of {negative_seven_over_nine} is {abs(negative_seven_over_nine)}" + ) # __trunc__ - print(f"Truncated value of {three_over_five} is {math.trunc(three_over_five)}") + print( + f"Truncated value of {three_over_five} is {math.trunc(three_over_five)}" + ) # __ceil__ print(f"Ceiled value of {three_over_five} is {math.ceil(three_over_five)}") # __floor__ - print(f"Floored value of {three_over_five} is {math.floor(three_over_five)}") + print( + f"Floored value of {three_over_five} is {math.floor(three_over_five)}" + ) if __name__ == "__main__": From e971e7d99ba57da082ba7d959efb61eb8538946b Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 16:08:14 -0400 Subject: [PATCH 28/31] Fixed __mod__ --- src/math-land/non_inplace_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 678717c..10d44e2 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -68,7 +68,7 @@ def __floordiv__(self, other: Fraction) -> int: return int(self / other) def __mod__(self, other: Fraction) -> Fraction: - remainder: int = other - other * (self // other) + remainder: int = self - other * (self // other) return self - remainder * other From 680ea3a449f1a45e182b62c792febbc6b5706841 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 16:23:59 -0400 Subject: [PATCH 29/31] Changed __mod__ --- src/math-land/non_inplace_math.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 10d44e2..612eb7c 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -68,9 +68,7 @@ def __floordiv__(self, other: Fraction) -> int: return int(self / other) def __mod__(self, other: Fraction) -> Fraction: - remainder: int = self - other * (self // other) - - return self - remainder * other + return self - other * (self // other) def __divmod__(self, other: Fraction) -> tuple[Fraction, Fraction]: return (self // other, self % other) From 6c19f850fa66b00dbfa1172a6d458e06ae7662f7 Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 16:32:49 -0400 Subject: [PATCH 30/31] Fixed __mod__ implementation for fractions --- src/math-land/non_inplace_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 612eb7c..83893a9 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -68,7 +68,7 @@ def __floordiv__(self, other: Fraction) -> int: return int(self / other) def __mod__(self, other: Fraction) -> Fraction: - return self - other * (self // other) + return Fraction((self.numerator * other.denominator) % (other.numerator * self.numerator), self.denominator * other.denominator).simplify() def __divmod__(self, other: Fraction) -> tuple[Fraction, Fraction]: return (self // other, self % other) From 3b988d4e9339227e5d4551a354fd435de762979d Mon Sep 17 00:00:00 2001 From: FuexFollets Date: Sun, 25 Jun 2023 16:33:37 -0400 Subject: [PATCH 31/31] Formatted code --- src/math-land/non_inplace_math.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/math-land/non_inplace_math.py b/src/math-land/non_inplace_math.py index 83893a9..610643d 100644 --- a/src/math-land/non_inplace_math.py +++ b/src/math-land/non_inplace_math.py @@ -68,7 +68,11 @@ def __floordiv__(self, other: Fraction) -> int: return int(self / other) def __mod__(self, other: Fraction) -> Fraction: - return Fraction((self.numerator * other.denominator) % (other.numerator * self.numerator), self.denominator * other.denominator).simplify() + return Fraction( + (self.numerator * other.denominator) + % (other.numerator * self.numerator), + self.denominator * other.denominator, + ).simplify() def __divmod__(self, other: Fraction) -> tuple[Fraction, Fraction]: return (self // other, self % other)