在while循环中更新变量的麻烦

时间:2019-02-18 14:22:27

标签: python

因此,当前此代码正在返回无限循环。任务是计算固定的每月付款。我最大的痛苦是使用epsilon,并试图将新计算的余额保持在其范围内。该代码获取余额并计算理论上我们每月可支付的最高和最低金额,并为0 new_balance。 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大,然后将最高或最低=设置为付款。但是,当它运行最大或最小时,不会更新,我也不知道为什么。 我希望有人可以解决该特定问题,并且希望获得更干净的方法来解决这一问题。无论是函数的专业化还是迭代之外的其他方法。

3 个答案:

答案 0 :(得分:1)

第2次测试

annualinterestRate> = 12 没有无限循环,并返回结果

annualinterestRate <12: 无限循环

祝你好运:)

答案 1 :(得分:1)

首先,月利息被错误地计算。一方面,该算法将其视为非复合兴趣:

   monthlyIR = annualinterestRate/12.0

但更早:

   monthly_lower = balance/12

,然后在循环中:

   new_balance *= monthlyIR

表示这是复利。但是,由于其他原因,代码无法收敛。您正在错误地计算利息对债务的影响。应该是:

   new_balance *= monthlyIR + 1

问题在于应按月利率增加new_balance。例如,如果每月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 :(得分:-1)

这已经是第一个问题:

new_balance = balance

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

当您打印尽可能多的值(new_balancemonthly_uppermonthly_lowerpayment,...)时,您应该明白为什么代码不正确表现符合预期。