在while循环中更新变量时遇到问题

2024-05-17 03:20:14 发布

您现在位置:Python中文网/ 问答频道 /正文

所以现在这个代码返回一个无限循环。任务是计算每月的固定付款。我最大的痛苦是与epsilon和试图得到我新计算的平衡范围内。代码获取余额并计算出理论上我们每月可以支付的最大和最小金额,并且新的余额为0。MonthlyIR是月利率

def bisection(balance,annualinterestRate):
    monthlyIR = annualinterestRate/12.0
    new_balance = balance
    monthly_lower = balance/12
    monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
    epsilon = 0.01
    print(monthly_lower,monthly_upper)


    while abs(new_balance) >=  epsilon:
        new_balance = balance
        print(monthly_lower,monthly_upper)
        payment = (monthly_upper + monthly_lower)/2
        for i in range(12):
            new_balance -= payment
            new_balance *= monthlyIR
        if new_balance > 0:
            monthly_lower = payment
        else: 
            monthly_upper = payment

    return round(payment,2)

所以当我检查每月的付款时,新的余额仍然大于epsilon,然后设置max或min=payments。然而,当它运行的最大或最小不更新,我不知道为什么。 我想有人来解决这个特定的问题,我想在一个更干净的方式做这方面的见解。无论是函数的更专业化,还是迭代以外的其他方法。你知道吗


Tags: 代码newpayment理论金额upperlower余额
3条回答

这已经是第一个问题:

new_balance = balance

您总是将while循环主变量放回其原始值。你知道吗

当您打印尽可能多的值(new_balancemonthly_uppermonthly_lowerpayment,…)时,您应该知道为什么您的代码没有按预期运行。你知道吗

首先,月利息计算错误。一方面,算法将其视为非复利:

   monthlyIR = annualinterestRate/12.0

但在此之前:

   monthly_lower = balance/12

后来,在循环中:

   new_balance *= monthlyIR

这意味着它是复利。但代码不收敛还有另一个原因。你计算利息对债务的影响是错误的。应该是:

   new_balance *= monthlyIR + 1

问题是新的存款余额应该按月利率增加。例如,如果每月IR为0.005,则原始代码会将余额降低到其先前大小的0.005。不幸的是,对于我们这些借款人来说,我们的债务并没有每个月缩减到原来价值的1/200,而是增加了原来债务的1/200。1000美元的债务变为1005美元,即债务应乘以1.005而不是0.005。你知道吗

原始代码只会收敛(错误地)年利率为12%或更高(1200%),因为它使每月IR>;=1(100%)。这样,乘法就不会降低原始代码中的债务。你知道吗

完整代码为:

def bisection(balance,annualinterestRate):
    # This is most likely an incorrect monthly IR
    # I suspect it should be:
    # monthlyIR = pow(1+annualinterestRate, 1/12.0) - 1
    monthlyIR = annualinterestRate/12.0
    new_balance = balance
    monthly_lower = balance/12
    monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
    epsilon = 0.01
    print(monthly_lower,monthly_upper)

    while abs(new_balance) >=  epsilon:
        new_balance = balance
        print(monthly_lower,monthly_upper)
        payment = (monthly_upper + monthly_lower)/2
        for i in range(12):
            new_balance -= payment
            new_balance *= monthlyIR + 1
        if new_balance > 0:
            monthly_lower = payment
        else: 
            monthly_upper = payment

    return round(payment,2)

此外,还有一个简单的公式来计算这在一行,而不是使用二分法。查找或派生。你知道吗

例如,读取here

进行了2次测试

年度利率>;=12 没有无限循环,返回结果

年度利率<;12: 无限循环

祝你好运:)

相关问题 更多 >