mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-07-07 11:37:36 +08:00
Merge branch 'master' into Python-3.14
This commit is contained in:
103
financial/straight_line_depreciation.py
Normal file
103
financial/straight_line_depreciation.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
"""
|
||||||
|
In accounting, depreciation refers to the decreases in the value
|
||||||
|
of a fixed asset during the asset's useful life.
|
||||||
|
When an organization purchases a fixed asset,
|
||||||
|
the purchase expenditure is not recognized as an expense immediately.
|
||||||
|
Instead, the decreases in the asset's value are recognized as expenses
|
||||||
|
over the years during which the asset is used.
|
||||||
|
|
||||||
|
The following methods are widely used
|
||||||
|
for depreciation calculation in accounting:
|
||||||
|
- Straight-line method
|
||||||
|
- Diminishing balance method
|
||||||
|
- Units-of-production method
|
||||||
|
|
||||||
|
The straight-line method is the simplest and most widely used.
|
||||||
|
This method calculates depreciation by spreading the cost evenly
|
||||||
|
over the asset's useful life.
|
||||||
|
|
||||||
|
The following formula shows how to calculate the yearly depreciation expense:
|
||||||
|
|
||||||
|
- annual depreciation expense =
|
||||||
|
(purchase cost of asset - residual value) / useful life of asset(years)
|
||||||
|
|
||||||
|
Further information on:
|
||||||
|
https://en.wikipedia.org/wiki/Depreciation
|
||||||
|
|
||||||
|
The function, straight_line_depreciation, returns a list of
|
||||||
|
the depreciation expenses over the given period.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def straight_line_depreciation(
|
||||||
|
useful_years: int,
|
||||||
|
purchase_value: float,
|
||||||
|
residual_value: float = 0.0,
|
||||||
|
) -> list[float]:
|
||||||
|
"""
|
||||||
|
Calculate the depreciation expenses over the given period
|
||||||
|
:param useful_years: Number of years the asset will be used
|
||||||
|
:param purchase_value: Purchase expenditure for the asset
|
||||||
|
:param residual_value: Residual value of the asset at the end of its useful life
|
||||||
|
:return: A list of annual depreciation expenses over the asset's useful life
|
||||||
|
>>> straight_line_depreciation(10, 1100.0, 100.0)
|
||||||
|
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
||||||
|
>>> straight_line_depreciation(6, 1250.0, 50.0)
|
||||||
|
[200.0, 200.0, 200.0, 200.0, 200.0, 200.0]
|
||||||
|
>>> straight_line_depreciation(4, 1001.0)
|
||||||
|
[250.25, 250.25, 250.25, 250.25]
|
||||||
|
>>> straight_line_depreciation(11, 380.0, 50.0)
|
||||||
|
[30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0]
|
||||||
|
>>> straight_line_depreciation(1, 4985, 100)
|
||||||
|
[4885.0]
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not isinstance(useful_years, int):
|
||||||
|
raise TypeError("Useful years must be an integer")
|
||||||
|
|
||||||
|
if useful_years < 1:
|
||||||
|
raise ValueError("Useful years cannot be less than 1")
|
||||||
|
|
||||||
|
if not isinstance(purchase_value, (float, int)):
|
||||||
|
raise TypeError("Purchase value must be numeric")
|
||||||
|
|
||||||
|
if not isinstance(residual_value, (float, int)):
|
||||||
|
raise TypeError("Residual value must be numeric")
|
||||||
|
|
||||||
|
if purchase_value < 0.0:
|
||||||
|
raise ValueError("Purchase value cannot be less than zero")
|
||||||
|
|
||||||
|
if purchase_value < residual_value:
|
||||||
|
raise ValueError("Purchase value cannot be less than residual value")
|
||||||
|
|
||||||
|
# Calculate annual depreciation expense
|
||||||
|
depreciable_cost = purchase_value - residual_value
|
||||||
|
annual_depreciation_expense = depreciable_cost / useful_years
|
||||||
|
|
||||||
|
# List of annual depreciation expenses
|
||||||
|
list_of_depreciation_expenses = []
|
||||||
|
accumulated_depreciation_expense = 0.0
|
||||||
|
for period in range(useful_years):
|
||||||
|
if period != useful_years - 1:
|
||||||
|
accumulated_depreciation_expense += annual_depreciation_expense
|
||||||
|
list_of_depreciation_expenses.append(annual_depreciation_expense)
|
||||||
|
else:
|
||||||
|
depreciation_expense_in_end_year = (
|
||||||
|
depreciable_cost - accumulated_depreciation_expense
|
||||||
|
)
|
||||||
|
list_of_depreciation_expenses.append(depreciation_expense_in_end_year)
|
||||||
|
|
||||||
|
return list_of_depreciation_expenses
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
user_input_useful_years = int(input("Please Enter Useful Years:\n > "))
|
||||||
|
user_input_purchase_value = float(input("Please Enter Purchase Value:\n > "))
|
||||||
|
user_input_residual_value = float(input("Please Enter Residual Value:\n > "))
|
||||||
|
print(
|
||||||
|
straight_line_depreciation(
|
||||||
|
user_input_useful_years,
|
||||||
|
user_input_purchase_value,
|
||||||
|
user_input_residual_value,
|
||||||
|
)
|
||||||
|
)
|
@ -11,23 +11,31 @@ If the mismatched character does not occur to the left in Pattern,
|
|||||||
a shift is proposed that moves the entirety of Pattern past
|
a shift is proposed that moves the entirety of Pattern past
|
||||||
the point of mismatch in the text.
|
the point of mismatch in the text.
|
||||||
|
|
||||||
If there no mismatch then the pattern matches with text block.
|
If there is no mismatch then the pattern matches with text block.
|
||||||
|
|
||||||
Time Complexity : O(n/m)
|
Time Complexity : O(n/m)
|
||||||
n=length of main string
|
n=length of main string
|
||||||
m=length of pattern string
|
m=length of pattern string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
|
|
||||||
class BoyerMooreSearch:
|
class BoyerMooreSearch:
|
||||||
|
"""
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
bms = BoyerMooreSearch(text="ABAABA", pattern="AB")
|
||||||
|
positions = bms.bad_character_heuristic()
|
||||||
|
|
||||||
|
where 'positions' contain the locations where the pattern was matched.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, text: str, pattern: str):
|
def __init__(self, text: str, pattern: str):
|
||||||
self.text, self.pattern = text, pattern
|
self.text, self.pattern = text, pattern
|
||||||
self.textLen, self.patLen = len(text), len(pattern)
|
self.textLen, self.patLen = len(text), len(pattern)
|
||||||
|
|
||||||
def match_in_pattern(self, char: str) -> int:
|
def match_in_pattern(self, char: str) -> int:
|
||||||
"""finds the index of char in pattern in reverse order
|
"""
|
||||||
|
Finds the index of char in pattern in reverse order.
|
||||||
|
|
||||||
Parameters :
|
Parameters :
|
||||||
char (chr): character to be searched
|
char (chr): character to be searched
|
||||||
@ -35,6 +43,10 @@ class BoyerMooreSearch:
|
|||||||
Returns :
|
Returns :
|
||||||
i (int): index of char from last in pattern
|
i (int): index of char from last in pattern
|
||||||
-1 (int): if char is not found in pattern
|
-1 (int): if char is not found in pattern
|
||||||
|
|
||||||
|
>>> bms = BoyerMooreSearch(text="ABAABA", pattern="AB")
|
||||||
|
>>> bms.match_in_pattern("B")
|
||||||
|
1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in range(self.patLen - 1, -1, -1):
|
for i in range(self.patLen - 1, -1, -1):
|
||||||
@ -44,8 +56,8 @@ class BoyerMooreSearch:
|
|||||||
|
|
||||||
def mismatch_in_text(self, current_pos: int) -> int:
|
def mismatch_in_text(self, current_pos: int) -> int:
|
||||||
"""
|
"""
|
||||||
find the index of mis-matched character in text when compared with pattern
|
Find the index of mis-matched character in text when compared with pattern
|
||||||
from last
|
from last.
|
||||||
|
|
||||||
Parameters :
|
Parameters :
|
||||||
current_pos (int): current index position of text
|
current_pos (int): current index position of text
|
||||||
@ -53,6 +65,10 @@ class BoyerMooreSearch:
|
|||||||
Returns :
|
Returns :
|
||||||
i (int): index of mismatched char from last in text
|
i (int): index of mismatched char from last in text
|
||||||
-1 (int): if there is no mismatch between pattern and text block
|
-1 (int): if there is no mismatch between pattern and text block
|
||||||
|
|
||||||
|
>>> bms = BoyerMooreSearch(text="ABAABA", pattern="AB")
|
||||||
|
>>> bms.mismatch_in_text(2)
|
||||||
|
3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in range(self.patLen - 1, -1, -1):
|
for i in range(self.patLen - 1, -1, -1):
|
||||||
@ -61,7 +77,14 @@ class BoyerMooreSearch:
|
|||||||
return -1
|
return -1
|
||||||
|
|
||||||
def bad_character_heuristic(self) -> list[int]:
|
def bad_character_heuristic(self) -> list[int]:
|
||||||
# searches pattern in text and returns index positions
|
"""
|
||||||
|
Finds the positions of the pattern location.
|
||||||
|
|
||||||
|
>>> bms = BoyerMooreSearch(text="ABAABA", pattern="AB")
|
||||||
|
>>> bms.bad_character_heuristic()
|
||||||
|
[0, 3]
|
||||||
|
"""
|
||||||
|
|
||||||
positions = []
|
positions = []
|
||||||
for i in range(self.textLen - self.patLen + 1):
|
for i in range(self.textLen - self.patLen + 1):
|
||||||
mismatch_index = self.mismatch_in_text(i)
|
mismatch_index = self.mismatch_in_text(i)
|
||||||
@ -75,13 +98,7 @@ class BoyerMooreSearch:
|
|||||||
return positions
|
return positions
|
||||||
|
|
||||||
|
|
||||||
text = "ABAABA"
|
if __name__ == "__main__":
|
||||||
pattern = "AB"
|
import doctest
|
||||||
bms = BoyerMooreSearch(text, pattern)
|
|
||||||
positions = bms.bad_character_heuristic()
|
|
||||||
|
|
||||||
if len(positions) == 0:
|
doctest.testmod()
|
||||||
print("No match found")
|
|
||||||
else:
|
|
||||||
print("Pattern found in following positions: ")
|
|
||||||
print(positions)
|
|
||||||
|
Reference in New Issue
Block a user