From f26b8b2c6d555c91e5f67ff21b939a3c85c4378a Mon Sep 17 00:00:00 2001 From: spamegg Date: Sat, 1 Aug 2020 11:18:51 +0300 Subject: [PATCH 1/4] added type hints and doctests to arithmetic_analysis/newton_method.py Continuing #2128 Also changed some variable names, made them more descriptive. --- arithmetic_analysis/newton_method.py | 49 +++++++++++++++++++++------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py index 1408a983041d..6acc45d263e5 100644 --- a/arithmetic_analysis/newton_method.py +++ b/arithmetic_analysis/newton_method.py @@ -1,23 +1,50 @@ """Newton's Method.""" # Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method - - -# function is the f(x) and function1 is the f'(x) -def newton(function, function1, startingInt): - x_n = startingInt +from typing import Callable + + +# function is the f(x) and derivative is the f'(x) +def newton( + function: Callable[[float], float], + derivative: Callable[[float], float], + starting_int: int, +) -> float: + """ + >>> newton(lambda x: x ** 3 - 2 * x - 5, lambda x: 3 * x ** 2 - 2, 3) + 2.0945514815423474 + >>> newton(lambda x: x ** 3 - 1, lambda x: 3 * x ** 2, -2) + 1.0 + >>> newton(lambda x: x ** 3 - 1, lambda x: 3 * x ** 2, -4) + 1.0000000000000102 + >>> import math + >>> newton(math.sin, math.cos, 1) + 0.0 + >>> newton(math.sin, math.cos, 2) + 3.141592653589793 + >>> newton(math.cos, lambda x: -math.sin(x), 2) + 1.5707963267948966 + >>> newton(math.cos, lambda x: -math.sin(x), 0) + Traceback (most recent call last): + ... + ZeroDivisionError: float division by zero, could not find root + """ + prev_guess: float = starting_int while True: - x_n1 = x_n - function(x_n) / function1(x_n) - if abs(x_n - x_n1) < 10 ** -5: - return x_n1 - x_n = x_n1 + if derivative(prev_guess) == 0: + raise ZeroDivisionError("float division by zero, could not find root") + + next_guess: float = prev_guess - function(prev_guess) / derivative(prev_guess) + if abs(prev_guess - next_guess) < 10 ** -5: + return next_guess + prev_guess = next_guess -def f(x): +def f(x: float) -> float: return (x ** 3) - (2 * x) - 5 -def f1(x): +def f1(x: float) -> float: return 3 * (x ** 2) - 2 From 4ad625dcefd5afdafc7c4d74ff0861c01c53dddf Mon Sep 17 00:00:00 2001 From: spamegg Date: Sat, 1 Aug 2020 15:56:10 +0300 Subject: [PATCH 2/4] Added type hints and doctests to arithmetic_analysis/newton_method.py added a type alias for Callable[[float], float] and cleaned up the exception handling --- arithmetic_analysis/newton_method.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py index 6acc45d263e5..152995f855ca 100644 --- a/arithmetic_analysis/newton_method.py +++ b/arithmetic_analysis/newton_method.py @@ -3,13 +3,11 @@ # Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method from typing import Callable +RealFunc = Callable[[float], float] # type alias for a real -> real function + # function is the f(x) and derivative is the f'(x) -def newton( - function: Callable[[float], float], - derivative: Callable[[float], float], - starting_int: int, -) -> float: +def newton(function: RealFunc, derivative: RealFunc, starting_int: int,) -> float: """ >>> newton(lambda x: x ** 3 - 2 * x - 5, lambda x: 3 * x ** 2 - 2, 3) 2.0945514815423474 @@ -27,17 +25,19 @@ def newton( >>> newton(math.cos, lambda x: -math.sin(x), 0) Traceback (most recent call last): ... - ZeroDivisionError: float division by zero, could not find root + ZeroDivisionError: Could not find root """ prev_guess: float = starting_int while True: - if derivative(prev_guess) == 0: - raise ZeroDivisionError("float division by zero, could not find root") - - next_guess: float = prev_guess - function(prev_guess) / derivative(prev_guess) - if abs(prev_guess - next_guess) < 10 ** -5: - return next_guess - prev_guess = next_guess + try: + next_guess: float = prev_guess - function(prev_guess) / derivative( + prev_guess + ) + if abs(prev_guess - next_guess) < 10 ** -5: + return next_guess + prev_guess = next_guess + except ZeroDivisionError: + raise ZeroDivisionError("Could not find root") def f(x: float) -> float: From 8e20e61fe5ace329e00448a602ecf8b866f21c71 Mon Sep 17 00:00:00 2001 From: spamegg Date: Sat, 1 Aug 2020 16:07:12 +0300 Subject: [PATCH 3/4] added type hints and doctests to arithmetic_analysis/newton_method.py improved exception handling --- arithmetic_analysis/newton_method.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py index 152995f855ca..8a4d2ccb839d 100644 --- a/arithmetic_analysis/newton_method.py +++ b/arithmetic_analysis/newton_method.py @@ -33,12 +33,13 @@ def newton(function: RealFunc, derivative: RealFunc, starting_int: int,) -> floa next_guess: float = prev_guess - function(prev_guess) / derivative( prev_guess ) - if abs(prev_guess - next_guess) < 10 ** -5: - return next_guess - prev_guess = next_guess except ZeroDivisionError: raise ZeroDivisionError("Could not find root") + if abs(prev_guess - next_guess) < 10 ** -5: + return next_guess + prev_guess = next_guess + def f(x: float) -> float: return (x ** 3) - (2 * x) - 5 From d55491a0c548a75300f1f6485b2ac0796b98c3f4 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 1 Aug 2020 15:17:14 +0200 Subject: [PATCH 4/4] Update newton_method.py --- arithmetic_analysis/newton_method.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py index 8a4d2ccb839d..fd7ad45c2944 100644 --- a/arithmetic_analysis/newton_method.py +++ b/arithmetic_analysis/newton_method.py @@ -27,15 +27,12 @@ def newton(function: RealFunc, derivative: RealFunc, starting_int: int,) -> floa ... ZeroDivisionError: Could not find root """ - prev_guess: float = starting_int + prev_guess float(starting_int) while True: try: - next_guess: float = prev_guess - function(prev_guess) / derivative( - prev_guess - ) + next_guess = prev_guess - function(prev_guess) / derivative(prev_guess) except ZeroDivisionError: raise ZeroDivisionError("Could not find root") - if abs(prev_guess - next_guess) < 10 ** -5: return next_guess prev_guess = next_guess