Skip to content

Commit 70327b3

Browse files
committed
Requested changes implemented
1 parent 56157cd commit 70327b3

File tree

1 file changed

+29
-35
lines changed

1 file changed

+29
-35
lines changed

numpy_financial/_financial.py

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@
2626
'start': 1,
2727
'finish': 0}
2828

29+
# Define custom Exceptions
30+
31+
class NoRealSolutionException(Exception):
32+
""" No real solution to the problem. """
33+
def __init__(self, message):
34+
self.message = message
35+
36+
def __str__(self):
37+
return self.message
38+
39+
class IterationsExceededException(Exception):
40+
""" Maximum number of iterations reached. """
41+
def __init__(self, message):
42+
self.message = message
43+
44+
def __str__(self):
45+
return self.message
46+
2947

3048
def _convert_when(when):
3149
# Test to see if when has already been converted to ndarray
@@ -598,7 +616,7 @@ def _g_div_gp(r, n, p, x, y, w):
598616
# where
599617
# g(r) is the formula
600618
# g'(r) is the derivative with respect to r.
601-
def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100, raise_exceptions=False):
619+
def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100, *, raise_exceptions=False):
602620
"""
603621
Compute the rate of interest per period.
604622
@@ -621,7 +639,7 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100, raise
621639
maxiter : int, optional
622640
Maximum iterations in finding the solution
623641
raise_exceptions: bool, optional
624-
Flag to raise an exception when the at least one of the rates
642+
Flag to raise an exception when at least one of the rates
625643
cannot be computed due to having reached the maximum number of
626644
iterations (IterationsExceededException). Set to False as default,
627645
thus returning NaNs for those rates.
@@ -669,29 +687,22 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100, raise
669687
iterator += 1
670688
rn = rnp1
671689

672-
# Define the custom Exceptions in case the flag raise_exceptions
673-
# is set to True
674-
if raise_exceptions:
675-
class IterationsExceededException(Exception):
676-
"Raised when the maximum number of iterations is reached"
677-
pass
678-
679690
if not np.all(close):
680691
if np.isscalar(rn):
681692
if raise_exceptions:
682-
raise IterationsExceededException('\n Maximum number of iterations exceeded.')
693+
raise IterationsExceededException('Maximum number of iterations exceeded.')
683694
return default_type(np.nan)
684695
else:
685696
# Return nan's in array of the same shape as rn
686697
# where the solution is not close to tol.
687698
if raise_exceptions:
688-
raise IterationsExceededException(f'\n Maximum number of iterations exceeded in '
699+
raise IterationsExceededException(f'Maximum number of iterations exceeded in '
689700
f'{len(close)-close.sum()} rate(s).')
690701
rn[~close] = np.nan
691702
return rn
692703

693704

694-
def irr(values, guess=None, tol=1e-12, maxiter=100, raise_exceptions=False):
705+
def irr(values, guess=None, *, tol=1e-12, maxiter=100, raise_exceptions=False):
695706
"""
696707
Return the Internal Rate of Return (IRR).
697708
@@ -772,23 +783,13 @@ def irr(values, guess=None, tol=1e-12, maxiter=100, raise_exceptions=False):
772783
if values.ndim != 1:
773784
raise ValueError("Cashflows must be a rank-1 array")
774785

775-
# Define the custom Exceptions in case the flag raise_exceptions
776-
# is set to True
777-
if raise_exceptions:
778-
class NoRealSolutionException(Exception):
779-
"Raised when all the input cashflows are of the same sign"
780-
pass
781-
class IterationsExceededException(Exception):
782-
"Raised when the maximum number of iterations is reached"
783-
pass
784-
785786
# If all values are of the same sign no solution exists
786787
# we don't perform any further calculations and exit early
787788
same_sign = np.all(values > 0) if values[0] > 0 else np.all(values < 0)
788789
if same_sign:
789790
if raise_exceptions:
790-
raise NoRealSolutionException('\nNo real solution exists for IRR since all '
791-
'cashflows are of the same sign.\n')
791+
raise NoRealSolutionException('No real solution exists for IRR since all '
792+
'cashflows are of the same sign.')
792793
return np.nan
793794

794795
# If no value is passed for `guess`, then make a heuristic estimate
@@ -826,7 +827,7 @@ class IterationsExceededException(Exception):
826827
g -= delta
827828

828829
if raise_exceptions:
829-
raise IterationsExceededException('\n Maximum number of iterations exceeded.')
830+
raise IterationsExceededException('Maximum number of iterations exceeded.')
830831

831832
return np.nan
832833

@@ -910,7 +911,7 @@ def npv(rate, values):
910911
return npv
911912

912913

913-
def mirr(values, finance_rate, reinvest_rate,raise_exceptions=False):
914+
def mirr(values, finance_rate, reinvest_rate, *, raise_exceptions=False):
914915
"""
915916
Modified internal rate of return.
916917
@@ -939,13 +940,6 @@ def mirr(values, finance_rate, reinvest_rate,raise_exceptions=False):
939940
values = np.asarray(values)
940941
n = values.size
941942

942-
# Define the custom Exception in case the flag raise_exceptions
943-
# is set to True
944-
if raise_exceptions:
945-
class NoRealSolutionException(Exception):
946-
"Raised when all the input cashflows are of the same sign"
947-
pass
948-
949943
# Without this explicit cast the 1/(n - 1) computation below
950944
# becomes a float, which causes TypeError when using Decimal
951945
# values.
@@ -956,8 +950,8 @@ class NoRealSolutionException(Exception):
956950
neg = values < 0
957951
if not (pos.any() and neg.any()):
958952
if raise_exceptions:
959-
raise NoRealSolutionException('\nNo real solution exists for IRR since'
960-
' all cashflows are of the same sign.\n')
953+
raise NoRealSolutionException('No real solution exists for MIRR since'
954+
' all cashflows are of the same sign.')
961955
return np.nan
962956
numer = np.abs(npv(reinvest_rate, values*pos))
963957
denom = np.abs(npv(finance_rate, values*neg))

0 commit comments

Comments
 (0)