import math def evaluate_expression(expression, x): """ Helper function to safely evaluate a mathematical string. Replaces '^' with '**' for user convenience. Available math functions: sin, cos, tan, exp, sqrt, log. """ # Allow common math functions to be used in the eval context safe_dict = { 'x': x, 'sin': math.sin, 'cos': math.cos, 'tan': math.tan, 'exp': math.exp, 'sqrt': math.sqrt, 'log': math.log, 'e': math.e, 'pi': math.pi } # Handle user using '^' for power instead of Python's '**' clean_expr = expression.replace('^', '**') try: return eval(clean_expr, {"__builtins__": None}, safe_dict) except Exception as e: return None def run_newton_raphson(func_str, deriv_str, x0, N): """ Runs the Newton-Raphson logic based on string inputs. """ x_current = x0 print(f"\nSolving for: f(x) = {func_str}") print(f"{'Iter':<5} | {'x_n':<20} | {'Error (|f(x)|)':<20}") print("-" * 50) # Print initial state (n=0) fx_start = evaluate_expression(func_str, x_current) if fx_start is None: print("Error: Could not evaluate function. Check your syntax.") return print(f"{0:<5} | {x_current:<20.10f} | {abs(fx_start):<20.10f}") for n in range(1, N + 1): # Calculate f(x) and f'(x) fx = evaluate_expression(func_str, x_current) dfx = evaluate_expression(deriv_str, x_current) if fx is None or dfx is None: print("Error parsing the equation. Please use python syntax (e.g., 3*x instead of 3x).") return # Check for zero derivative (division by zero risk) if dfx == 0: print("Derivative is zero. Newton-Raphson fails.") return # The Newton-Raphson Formula x_next = x_current - (fx / dfx) # Calculate error # We evaluate the function at the NEW x to see how close to 0 we are error = abs(evaluate_expression(func_str, x_next)) print(f"{n:<5} | {x_next:<20.10f} | {error:<20.10f}") x_current = x_next print("-" * 50) print(f"Final Root Approximation: {x_current}\n") def main(): # --- PART 1: Run the specific Assignment Question first --- print("--- ASSIGNMENT DEFAULT RUN ---") print("Function: x^3 - 7x") print("Derivative: 3x^2 - 7") run_newton_raphson("x**3 - 7*x", "3*x**2 - 7", 1.5, 20) # --- PART 2: Interactive Loop --- while True: choice = input("Do you want to try another function? (y/n): ").strip().lower() if choice != 'y': print("Exiting program. Goodbye!") break print("\n--- CUSTOM INPUT MODE ---") print("Instructions:") print("1. Use '*' for multiplication (e.g., 3*x, not 3x)") print("2. Use '**' or '^' for power (e.g., x^3)") try: # Get User Inputs f_input = input("Enter Function f(x): ") # Note: We ask for derivative because standard Python cannot do calculus automatically df_input = input("Enter Derivative f'(x): ") x0_input = float(input("Enter Initial Guess (x0): ")) N_input = int(input("Enter Number of Iterations (N): ")) run_newton_raphson(f_input, df_input, x0_input, N_input) except ValueError: print("Invalid input! Please enter numbers for x0 and N.") if __name__ == "__main__": main()