修复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)
修复逻辑说明
- 先计算当月利息,再判断剩余本金+利息是否小于等于固定还款额:
- 如果是,当月还款即为剩余本金+利息,直接清零本金
- 如果不是,按固定还款额扣款,更新剩余本金
- 额外还款放在固定还款之后处理,且仅当本金仍大于0时执行,避免把本金扣成负数
- 用
min(extra_payment, principal)确保额外还款不会超过当前剩余本金
运行该代码后,最终总还款额为878202.57,第309期后本金清零,不会产生多余的第310期还款。
内容的提问来源于stack exchange,提问作者Linus
相关产品推荐
相关产品推荐

