From 877b50ef8802f8b59d81ccabcab22fe185e898d7 Mon Sep 17 00:00:00 2001 From: xengineering Date: Wed, 4 Sep 2024 20:56:03 +0200 Subject: Rename income to flow Modeling income and expenses separately does not make sense since the only difference is the sign of the amount. Separate definitions would lead to a lot of duplicated code. --- finance/flow.py | 33 +++++++++++++++++++++++++++++++++ finance/income.py | 33 --------------------------------- finance/test_flow.py | 18 ++++++++++++++++++ finance/test_income.py | 18 ------------------ 4 files changed, 51 insertions(+), 51 deletions(-) create mode 100644 finance/flow.py delete mode 100644 finance/income.py create mode 100644 finance/test_flow.py delete mode 100644 finance/test_income.py diff --git a/finance/flow.py b/finance/flow.py new file mode 100644 index 0000000..fb28228 --- /dev/null +++ b/finance/flow.py @@ -0,0 +1,33 @@ +import dataclasses +from datetime import datetime +from decimal import Decimal + + +@dataclasses.dataclass(kw_only=True, frozen=True) +class Flow: + """Time-discrete flow of money paid on the first day of a month""" + + amount: Decimal + + def integrate(self, start: datetime, end: datetime) -> Decimal: + """Integrate the flow between two dates to an amount of money""" + + retval = Decimal(0.0) + + current = datetime(start.year, start.month, 1) + + if start == current: + retval += self.amount + + while True: + if current.month == 12: + current = datetime(current.year + 1, 1, 1) + else: + current = datetime(current.year, current.month + 1, 1) + + if current <= end: + retval += self.amount + else: + break + + return retval diff --git a/finance/income.py b/finance/income.py deleted file mode 100644 index 8d775cb..0000000 --- a/finance/income.py +++ /dev/null @@ -1,33 +0,0 @@ -import dataclasses -from datetime import datetime -from decimal import Decimal - - -@dataclasses.dataclass(kw_only=True, frozen=True) -class Income: - """Income models financial income paid on the first day of a month""" - - amount: Decimal - - def integrate(self, start: datetime, end: datetime) -> Decimal: - """Integrate the income from a start to an end date""" - - retval = Decimal(0.0) - - current = datetime(start.year, start.month, 1) - - if start == current: - retval += self.amount - - while True: - if current.month == 12: - current = datetime(current.year + 1, 1, 1) - else: - current = datetime(current.year, current.month + 1, 1) - - if current <= end: - retval += self.amount - else: - break - - return retval diff --git a/finance/test_flow.py b/finance/test_flow.py new file mode 100644 index 0000000..aad4e74 --- /dev/null +++ b/finance/test_flow.py @@ -0,0 +1,18 @@ +from datetime import datetime +from decimal import Decimal + +from finance import flow + + +def test_income_integration() -> None: + inc = flow.Flow(amount=Decimal(3000.0)) + + tests = ( + (datetime(2024, 3, 12), datetime(2024, 4, 2), Decimal(3000.0)), + (datetime(2024, 3, 1), datetime(2024, 3, 15), Decimal(3000.0)), + (datetime(2024, 2, 25), datetime(2024, 3, 1), Decimal(3000.0)), + (datetime(2024, 2, 25), datetime(2024, 6, 12), Decimal(12000.0)), + ) + + for test in tests: + assert inc.integrate(start=test[0], end=test[1]) == test[2] diff --git a/finance/test_income.py b/finance/test_income.py deleted file mode 100644 index fc75bef..0000000 --- a/finance/test_income.py +++ /dev/null @@ -1,18 +0,0 @@ -from datetime import datetime -from decimal import Decimal - -from finance import income - - -def test_income_integration() -> None: - inc = income.Income(amount=Decimal(3000.0)) - - tests = ( - (datetime(2024, 3, 12), datetime(2024, 4, 2), Decimal(3000.0)), - (datetime(2024, 3, 1), datetime(2024, 3, 15), Decimal(3000.0)), - (datetime(2024, 2, 25), datetime(2024, 3, 1), Decimal(3000.0)), - (datetime(2024, 2, 25), datetime(2024, 6, 12), Decimal(12000.0)), - ) - - for test in tests: - assert inc.integrate(start=test[0], end=test[1]) == test[2] -- cgit v1.2.3-70-g09d2