贷款利息计算器

import tkinter as tk
from tkinter import ttk, messagebox
import math
 
class LoanCalculator:
    def __init__(self, root):
        self.root = root
        self.root.title("贷款利息计算器")
        self.root.geometry("580x600")
        self.root.resizable(False, False)
         
        # 初始化变量
        self.loan_amount = tk.StringVar()  # 贷款金额
        self.annual_rate = tk.StringVar()  # 年利率(%)
        self.loan_years = tk.StringVar()   # 贷款年限
        self.result_var = tk.StringVar()   # 计算结果
        self.recommend_var = tk.StringVar()# 推荐方案
         
        # 创建界面
        self.create_widgets()
     
    def create_widgets(self):
        # 标题
        title_label = ttk.Label(
            self.root, 
            text="贷款利息计算器", 
            font=("微软雅黑", 16, "bold")
        )
        title_label.pack(pady=10)
         
        # 输入框架
        input_frame = ttk.LabelFrame(self.root, text="贷款信息")
        input_frame.pack(padx=20, pady=10, fill="x")
         
        # 贷款金额
        ttk.Label(input_frame, text="贷款金额(元):").grid(row=0, column=0, padx=10, pady=8, sticky="w")
        amount_entry = ttk.Entry(input_frame, textvariable=self.loan_amount, width=30)
        amount_entry.grid(row=0, column=1, padx=10, pady=8)
         
        # 年利率
        ttk.Label(input_frame, text="年利率(%):").grid(row=1, column=0, padx=10, pady=8, sticky="w")
        rate_entry = ttk.Entry(input_frame, textvariable=self.annual_rate, width=30)
        rate_entry.grid(row=1, column=1, padx=10, pady=8)
         
        # 贷款年限
        ttk.Label(input_frame, text="贷款年限(年):").grid(row=2, column=0, padx=10, pady=8, sticky="w")
        years_entry = ttk.Entry(input_frame, textvariable=self.loan_years, width=30)
        years_entry.grid(row=2, column=1, padx=10, pady=8)
         
        # 计算按钮
        calc_btn = ttk.Button(
            self.root, 
            text="计算并推荐最优方案", 
            command=self.calculate_loan
        )
        calc_btn.pack(pady=10)
         
        # 结果框架
        result_frame = ttk.LabelFrame(self.root, text="计算结果")
        result_frame.pack(padx=20, pady=5, fill="both", expand=True)
         
        # 结果文本框
        self.result_text = tk.Text(result_frame, font=("微软雅黑", 10), wrap=tk.WORD)
        scrollbar = ttk.Scrollbar(result_frame, orient="vertical", command=self.result_text.yview)
        self.result_text.configure(yscrollcommand=scrollbar.set)
         
        self.result_text.pack(side="left", fill="both", expand=True, padx=(0, 5), pady=5)
        scrollbar.pack(side="right", fill="y", pady=5)
         
        # 推荐方案标签
        recommend_label = ttk.Label(
            self.root, 
            textvariable=self.recommend_var,
            font=("微软雅黑", 11, "bold"),
            foreground="#d63031"
        )
        recommend_label.pack(pady=8)
     
    def validate_inputs(self):
        """验证输入是否合法"""
        try:
            amount = float(self.loan_amount.get())
            rate = float(self.annual_rate.get())
            years = int(self.loan_years.get())
             
            if amount <= 0:
                messagebox.showerror("错误", "贷款金额必须大于0!")
                return None
            if rate <= 0 or rate > 100:
                messagebox.showerror("错误", "年利率必须在0-100之间!")
                return None
            if years <= 0 or years > 50:
                messagebox.showerror("错误", "贷款年限必须在1-50之间!")
                return None
             
            return amount, rate, years
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字!")
            return None
     
    def calculate_equal_principal_interest(self, principal, annual_rate, years):
        """
        计算等额本息还款方式
        公式:
        月利率 = 年利率 / 12 / 100
        月供 = 本金 × 月利率 × (1 + 月利率)^还款月数 / [(1 + 月利率)^还款月数 - 1]
        总利息 = 月供 × 还款月数 - 本金
        """
        monthly_rate = annual_rate / 12 / 100
        months = years * 12
         
        if monthly_rate == 0:
            monthly_payment = principal / months
            total_interest = 0
        else:
            monthly_payment = principal * monthly_rate * math.pow(1 + monthly_rate, months) / (math.pow(1 + monthly_rate, months) - 1)
            total_interest = monthly_payment * months - principal
         
        return {
            "monthly_payment": monthly_payment,
            "total_interest": total_interest,
            "total_payment": principal + total_interest
        }
     
    def calculate_equal_principal(self, principal, annual_rate, years):
        """
        计算等额本金还款方式
        公式:
        月利率 = 年利率 / 12 / 100
        每月应还本金 = 本金 / 还款月数
        每月应还利息 = 剩余本金 × 月利率
        总利息 = (还款月数 + 1) × 本金 × 月利率 / 2
        """
        monthly_rate = annual_rate / 12 / 100
        months = years * 12
        monthly_principal = principal / months
         
        # 计算总利息
        total_interest = (months + 1) * principal * monthly_rate / 2
        # 首月还款额
        first_month_payment = monthly_principal + principal * monthly_rate
        # 每月递减金额
        monthly_decrease = monthly_principal * monthly_rate
         
        return {
            "first_month_payment": first_month_payment,
            "monthly_decrease": monthly_decrease,
            "total_interest": total_interest,
            "total_payment": principal + total_interest
        }
     
    def calculate_interest_first_principal_last(self, principal, annual_rate, years):
        """
        计算到期还本、按期还息(先息后本)还款方式
        公式:
        月利率 = 年利率 / 12 / 100
        每月还息 = 本金 × 月利率
        到期还本 = 本金
        总利息 = 本金 × 年利率 × 年限
        """
        monthly_rate = annual_rate / 12 / 100
        # 每月还息金额
        monthly_interest = principal * monthly_rate
        # 总利息
        total_interest = principal * annual_rate * years / 100
        # 总还款金额
        total_payment = principal + total_interest
         
        return {
            "monthly_interest": monthly_interest,
            "final_principal": principal,
            "total_interest": total_interest,
            "total_payment": total_payment
        }
     
    def calculate_loan(self):
        """主计算函数"""
        # 清空结果
        self.result_text.delete(1.0, tk.END)
        self.recommend_var.set("")
         
        # 验证输入
        inputs = self.validate_inputs()
        if not inputs:
            return
         
        principal, annual_rate, years = inputs
        months = years * 12
         
        # 计算三种还款方式
        eqi_pi = self.calculate_equal_principal_interest(principal, annual_rate, years)  # 等额本息
        eqi_p = self.calculate_equal_principal(principal, annual_rate, years)            # 等额本金
        interest_first = self.calculate_interest_first_principal_last(principal, annual_rate, years)  # 先息后本
         
        # 构建结果文本
        result_text = f"""
【贷款基本信息】
贷款金额:{principal:,.2f} 元
年利率:{annual_rate:.2f} %
贷款年限:{years} 年({months} 个月)
 
【等额本息还款方案】
每月还款额:{eqi_pi['monthly_payment']:,.2f} 元
总还款金额:{eqi_pi['total_payment']:,.2f} 元
总支付利息:{eqi_pi['total_interest']:,.2f} 元
 
【等额本金还款方案】
首月还款额:{eqi_p['first_month_payment']:,.2f} 元
每月递减金额:{eqi_p['monthly_decrease']:,.4f} 元
总还款金额:{eqi_p['total_payment']:,.2f} 元
总支付利息:{eqi_p['total_interest']:,.2f} 元
 
【到期还本、按期还息(先息后本)方案】
每月还息金额:{interest_first['monthly_interest']:,.2f} 元
到期还本金额:{interest_first['final_principal']:,.2f} 元
总还款金额:{interest_first['total_payment']:,.2f} 元
总支付利息:{interest_first['total_interest']:,.2f} 元
 
【三种方案利息对比】
等额本息利息:{eqi_pi['total_interest']:,.2f} 元
等额本金利息:{eqi_p['total_interest']:,.2f} 元
先息后本利息:{interest_first['total_interest']:,.2f} 元
        """
         
        # 插入结果
        self.result_text.insert(tk.END, result_text)
        self.result_text.see(tk.END)
         
        # 找出利息最低的方案
        interest_dict = {
            "等额本金": eqi_p['total_interest'],
            "等额本息": eqi_pi['total_interest'],
            "到期还本、按期还息": interest_first['total_interest']
        }
        # 按利息升序排序
        sorted_interest = sorted(interest_dict.items(), key=lambda x: x[1])
        best_plan = sorted_interest[0][0]
        best_interest = sorted_interest[0][1]
        second_interest = sorted_interest[1][1]
        interest_diff = second_interest - best_interest
         
        # 推荐最优方案
        self.recommend_var.set(f"✅ 推荐方案:{best_plan}(总利息最低,为 {best_interest:,.2f} 元,比第二名少付 {interest_diff:,.2f} 元)")
 
if __name__ == "__main__":
    root = tk.Tk()
    app = LoanCalculator(root)
    root.mainloop()
© 版权声明
THE END
喜欢就支持一下吧