You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复Python抵押贷款计算器程序的上月超额还款问题

修复抵押贷款计算器的最后一期超额还款问题

问题背景

我在解决David Beazly《Practical Python》中的抵押贷款计算器问题时,发现原始代码存在最后一期还款超额的问题,导致剩余本金变为负数,需要修复。

原始代码

principal = 500000.0
rate = 0.05 
payment = 2684.11 
total_paid = 0.0 
month = 0

extra_payment_start_month = 61 
extra_payment_end_month = 108 
extra_payment = 1000


while principal > 0: 
    month += 1 
    principal = principal * (1+rate/12) - payment 
    total_paid = total_paid + payment
    
    if month >= extra_payment_start_month and month <= extra_payment_end_month:
        principal = principal - extra_payment
        total_paid = total_paid + extra_payment

    print(month, round(total_paid,2), round(principal, 2))

print('Total paid', round(total_paid, 2)) 
print('Months', month)

原始代码运行问题

运行后出现最后一期超额还款,部分输出如下:

...
308 874705.88 3478.83
309 877389.99 809.21
310 880074.1 -1871.53 
Total paid 880074.1 
Months 310

我的尝试修改

我尝试根据剩余本金调整最后一期还款,修改后的代码如下:

principal = 500000.0
rate = 0.05 
payment = 2684.11 
total_paid = 0.0 
month = 0

extra_payment_start_month = 61 
extra_payment_end_month = 108 
extra_payment = 1000

while principal > 0: 
    month += 1 
    principal = principal * (1+rate/12) - payment 
    total_paid = total_paid + payment

# If remaining principal is less than the default payment amount:

    if principal < payment:
        payment = principal * (1+rate/12)
        total_paid = total_paid + payment

    if month >= extra_payment_start_month and month <= extra_payment_end_month:
        principal = principal - extra_payment
        total_paid = total_paid + extra_payment

    print(month, round(total_paid,2), round(principal, 2))

print('Total paid', round(total_paid, 2)) 
print('Months', month)

修改后的问题

修改后运行结果如下:

...
308 874705.88 3478.83
309 878202.57 809.21 
310 879015.16 0.0 
Total paid 879015.16 
Months 310

我发现修改后的代码存在问题:第309期的还款总额不符合预期,且理论上最终总还款额应为878202.57,恳请指点正确的修复方法。

正确修复方案

问题出在修改逻辑的顺序错误,且额外还款的处理时机不对。正确的做法是先计算当月应还的利息+本金,再判断是否需要调整还款额,最后处理额外还款(如果符合条件且本金还有剩余)。

修复后的代码:

principal = 500000.0
rate = 0.05 
monthly_payment = 2684.11 
total_paid = 0.0 
month = 0

extra_payment_start_month = 61 
extra_payment_end_month = 108 
extra_payment = 1000

while principal > 0: 
    month += 1
    # 计算当月产生的利息
    monthly_interest = principal * (rate / 12)
    # 判断剩余本金+利息是否小于等于每月固定还款额
    if principal + monthly_interest <= monthly_payment:
        current_payment = principal + monthly_interest
        total_paid += current_payment
        principal = 0
    else:
        current_payment = monthly_payment
        total_paid += current_payment
        principal = principal + monthly_interest - current_payment
    
    # 处理额外还款:仅在指定月份且本金仍大于0时执行,避免超额扣除
    if (extra_payment_start_month <= month <= extra_payment_end_month) and principal > 0:
        actual_extra = min(extra_payment, principal)
        principal -= actual_extra
        total_paid += actual_extra

    print(month, round(total_paid,2), round(principal, 2))

print('Total paid', round(total_paid, 2)) 
print('Months', month)

修复逻辑说明

  1. 先计算当月利息,再判断剩余本金+利息是否小于等于固定还款额:
    • 如果是,当月还款即为剩余本金+利息,直接清零本金
    • 如果不是,按固定还款额扣款,更新剩余本金
  2. 额外还款放在固定还款之后处理,且仅当本金仍大于0时执行,避免把本金扣成负数
  3. 用min(extra_payment, principal)确保额外还款不会超过当前剩余本金

运行该代码后,最终总还款额为878202.57,第309期后本金清零,不会产生多余的第310期还款。


内容的提问来源于stack exchange,提问作者Linus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:00:10