# loan_calc.py
# Menu-driven loan/investment calculator using the EMI formula:
# EMI = P * [ r * (1 + r)^n ] / [ (1 + r)^n - 1 ]
import math
def calculate_interest_rate():
"""Option 1: Find the monthly interest rate given loan amount, number of payments and installment."""
print("\n--- Calculate Interest Rate ---")
try:
P = float(input("Loan amount (P): "))
n = int(input("Number of installments (n): "))
EMI = float(input("Installment amount (EMI): "))
if P <= 0 or n <= 0 or EMI <= 0:
print("All values must be positive.")
return
if EMI <= P / n:
print("No positive interest rate can satisfy these numbers (EMI must be greater than P/n).")
return
low, high = 0.0, 1.0
for _ in range(100):
mid = (low + high) / 2
try:
f_mid = P * mid * (1 + mid)**n / ((1 + mid)**n - 1) - EMI
except ZeroDivisionError:
f_mid = float('inf')
if f_mid > 0:
high = mid
else:
low = mid
r = (low + high) / 2
r_percent = r * 100
print(f"Monthly interest rate = {r_percent:.4f}%")
print(f"Yearly interest rate (approx.) = {r_percent * 12:.2f}%")
except ValueError:
print("Invalid input. Please enter numbers only.")
def calculate_installment():
"""Option 2: Calculate the fixed monthly installment (EMI) using annual rate."""
print("\n--- Calculate Installments ---")
try:
P = float(input("Loan amount (P): "))
annual_rate_percent = float(input("Annual interest rate (%): "))
n = int(input("Number of installments (n): "))
if P <= 0 or n <= 0 or annual_rate_percent < 0:
print("Loan, installments and interest rate must be non-negative, installments > 0.")
return
r = (annual_rate_percent / 100) / 12
if r == 0:
EMI = P / n
else:
EMI = P * r * (1 + r)**n / ((1 + r)**n - 1)
print(f"Monthly installment (EMI) = {EMI:.2f}")
print(f"(Monthly rate used: {r * 100:.4f}%)")
except ValueError:
print("Invalid input. Please enter numbers only.")
def calculate_balance_after_investment():
"""Option 3: Simulate the invested loan balance after each monthly payment."""
print("\n--- Balance After Investment (Loan Invested) ---")
try:
n = int(input("A. Number of installments: "))
installment = float(input("B. Installment amount: "))
r_percent = float(input("C. Monthly interest rate (%): "))
P = float(input("D. Initial loan amount (invested): "))
if n <= 0 or installment <= 0 or r_percent < 0 or P <= 0:
print("All values must be positive (rate can be zero).")
return
r = r_percent / 100
balance = P
print("\nMonth | Balance after payment")
print("------|------------------------")
for i in range(1, n + 1):
balance = balance * (1 + r) - installment
print(f"{i:5} | {balance:20.2f}")
print(f"\nAfter {n} payments, remaining balance = {balance:.2f}")
except ValueError:
print("Invalid input. Please enter numbers only.")
def calculate_saving_requirement_cost():
"""
Option 4: Account for the opportunity cost of a required savings account.
Corrected logic:
- Net starting wealth = Loan amount - lost investment profit on the required deposit.
- This net amount grows monthly at YOUR investment rate, and the EMI is subtracted each month.
- Final balance = net profit (positive) or loss (negative) after all payments.
"""
print("\n--- Loan Cost with Required Saving Account ---")
try:
L = float(input("Desired loan amount: "))
ratio = float(input("Loan to saving ratio (Loan / Saving): "))
t = int(input("How many months must you keep the savings account? "))
r_inv_percent = float(input("Your alternative investment monthly interest rate (%): "))
n = int(input("Number of loan installments: "))
annual_loan_percent = float(input("Bank's annual loan interest rate (%): "))
if L <= 0 or ratio <= 0 or t < 0 or r_inv_percent < 0 or n <= 0 or annual_loan_percent < 0:
print("All inputs must be non‑negative, and loan/ratio/installments > 0.")
return
# Required savings deposit
S = L / ratio
# Lost profit factor: (1 + r_inv)^t - 1
r_inv = r_inv_percent / 100
lost_profit = S * ((1 + r_inv) ** t - 1)
# EMI calculation (bank's annual rate → monthly)
r_loan = (annual_loan_percent / 100) / 12
if r_loan == 0:
EMI = L / n
else:
EMI = L * r_loan * (1 + r_loan) ** n / ((1 + r_loan) ** n - 1)
print(f"\nRequired saving deposit: {S:,.2f}")
print(f"Lost investment profit on that deposit: {lost_profit:,.2f}")
print(f"Monthly installment (EMI) (bank rate): {EMI:,.2f}")
# Net starting balance = loan amount minus the opportunity cost
balance = L - lost_profit
print(f"Initial net wealth (Loan - lost profit): {balance:,.2f}")
print("\nThis net wealth will grow at your investment rate, and the EMI is withdrawn each month.\n")
print("Month | Remaining balance (net wealth)")
print("------|---------------------------------")
for i in range(1, n + 1):
balance = balance * (1 + r_inv) - EMI
print(f"{i:5} | {balance:>31,.2f}")
print("\n=== FINAL RESULT ===")
if balance > 0:
print(f"After {n} payments, you have a NET PROFIT of: {balance:,.2f}")
elif balance < 0:
print(f"After {n} payments, you have a NET LOSS of: {-balance:,.2f}")
else:
print("You exactly broke even.")
except ValueError:
print("Invalid input. Please enter numbers only.")
def main():
while True:
print("\n" + "="*40)
print("Loan & Investment Calculator")
print("="*40)
print("1. Calculate the interest rate of my loan")
print("2. Calculate the installments")
print("3. Calculate the balance after each month (loan invested)")
print("4. Calculate effective cost with required savings account")
print("5. Exit")
choice = input("Enter your choice (1-5): ").strip()
if choice == '1':
calculate_interest_rate()
elif choice == '2':
calculate_installment()
elif choice == '3':
calculate_balance_after_investment()
elif choice == '4':
calculate_saving_requirement_cost()
elif choice == '5':
print("Goodbye!")
break
else:
print("Invalid choice. Please select 1, 2, 3, 4 or 5.")
if __name__ == "__main__":
main()