2012-10-09 21 views
1

我在爲我的Python類寫信用卡付款計算器。這項任務是爲一個計算器編寫一個定義,該計算器計算在x個月內使餘額爲零所需的每月支付。爲什麼我的平分算法不起作用? Python

該定義需要3個參數:initialBalance,apr,months。

雖然我自己看着辦,分配的關鍵是讓我們用二分法來找到了答案,我已經寫了幫助分配其他兩個定義:

1)新百倫() - 確定付款後的新餘額; 2)餘額() - 在付款後返回餘額清單;

在這種情況下,balances()[ - 1]返回最終餘額,所以我的行動計劃是評估列表中最後一項等於0(或至少在0的0.005內!)和如果是的話,退還給我的付款。如果最終餘額爲負數(我付出的太多!):payment = payment - (payment/2); 如果餘額爲正值(我沒有付出足夠的錢!):payment = payment +(payment/2);

是最好的,我自己看着辦吧,我的算法應該最終的結論,但它從來沒有發現足夠接近的答案...

這裏是我的代碼,(和教授的在最後測試DEF):

def newBalance(prevBalance, apr, payment): 
    """ 
    - prevBalance: the balance on the credit card statement. 
    - apr: the annual percentage rate (15.9 here means 15.9%). 
    - payment: the amount paid this month to the credit card company. 
    - returns: the new balance that will be owed on the credit card 
     (assumes no purchases are made). 
    """ 
    interestCharge = float(((apr/12.0)/100) * prevBalance) 
    return float((interestCharge + prevBalance) - payment) 




def balances(initialBalance, apr, payments): 
    """ 
    - initialBalance: the initial balance on the credit card. 
    - apr: the annual percentage rate (15.9 here means 15.9%). 
    - payments: a list of monthly payments made on the credit card. 
    - returns: a list giving the balance on the credit card each 
     month. The first number in the list is the initial 
     balance, the next number is the balance after the first 
     payment is made, and so on. Note that the length of the returned 
     list is len(payments) + 1. 
     """ 
    balancelist = [] 
    balancelist.append(initialBalance) 
    for x in range(0, len(payments)): 
     balancelist.append(newBalance(balancelist[x], apr, payments[x])) 
    return balancelist 




def findMonthlyPayment(initialBalance, apr, months): 
    """ 
    - initialBalance: the starting balance on the card. 
    - apr: the APR. 
    - months: the number of equal monthly payments you wish to 
     make in order to reduce the balance to zero. 
    - returns: the monthly payment amount needed to reduce the 
     balance to zero (well, "zero" to within $0.005, anyway) 
     in the given number of months. 
    """ 
    guess = float(initialBalance/months) 
    listo = months*[guess] 

    while True: 

     if abs(float(balances(initialBalance, apr, listo)[-1]) - initialBalance) < 0.006: 
      print "BINGO", guess ##for debugging 
      print balances(initialBalance, apr, listo)[-1] 
      return guess 

     else: 
      if float(balances(initialBalance, apr, listo)[-1]) < -0.005: 
       guess = guess - (guess/2) 

       print "BOO", guess ##for debugging 
       print balances(initialBalance, apr, listo)[-1] 

      else: 
       guess = guess + (guess/2) 
       print "NAY", guess ##for debugging 
       print balances(initialBalance, apr, listo)[-1] 

     listo = months*[guess] 



def testFindMonthlyPayment(): 
    answer = findMonthlyPayment(1000, 18.9, 60) 
    print 
    myString = "Monthly payment to pay off $%.2f in %d months at %.2f%% APR:" 
    print myString % (1000, 60, 18.9) 
    print "$%.2f" % answer 
    # Output should look approximately like this: 
    """ 
    iteration: 1 guess: 500.0 final bal: -46777.3384635 
    iteration: 2 guess: 250.0 final balance: -22111.7016729 
    iteration: 3 guess: 125.0 final balance: -9778.88327752 
    iteration: 4 guess: 62.5 final balance: -3612.47407985 
    iteration: 5 guess: 31.25 final balance: -529.269481021 
    iteration: 6 guess: 15.625 final balance: 1012.3328184 
    iteration: 7 guess: 23.4375 final balance: 241.531668687 
    iteration: 8 guess: 27.34375 final balance: -143.868906167 
    iteration: 9 guess: 25.390625 final balance: 48.83138126 
    iteration: 10 guess: 26.3671875 final balance: -47.5187624535 
    iteration: 11 guess: 25.87890625 final balance: 0.656309403241 
    iteration: 12 guess: 26.123046875 final balance: -23.4312265251 
    iteration: 13 guess: 26.0009765625 final balance: -11.387458561 
    iteration: 14 guess: 25.9399414062 final balance: -5.36557457885 
    iteration: 15 guess: 25.9094238281 final balance: -2.35463258781 
    iteration: 16 guess: 25.8941650391 final balance: -0.849161592282 
    iteration: 17 guess: 25.8865356445 final balance: -0.0964260945206 
    iteration: 18 guess: 25.8827209473 final balance: 0.27994165436 
    iteration: 19 guess: 25.8846282959 final balance: 0.0917577799204 
    iteration: 20 guess: 25.8855819702 final balance: -0.00233415730086 

    Monthly payment to pay off $1000.00 in 60 months at 18.90 APR: 
    $25.89 
    """ 

感謝您的幫助。可能不會加入compsci,除非我使用過的所有東西都在stackoverflow上。

+0

它究竟是什麼,你期望它做什麼? – 2012-10-09 02:51:31

+0

它圍繞着正確的答案擺動(25.89美元),但從未到達答案。我預計它會通過確定付款額是否過高或過低來降低結果(並且最終達到我的0.005容忍度並接受它)。 –

回答

5

這不是你如何平分

guess = guess - (guess/2) 

通常你保持low_guess和high_guess。您嘗試

guess = (low_guess+high_guess)/2 

,然後根據結果,你要麼設置

low_guess = guess 

high_guess = guess 

,並重復

注:在Python2,/是整數divison如果分母和分子都是整數,所以最好確保最初的guess is a float

+0

謝謝gnibbler - 我會在這裏幾分鐘。稍後檢查! –

+0

you rock gnibbler –

+0

是的,他的確如此。 –

1
def findMonthlyPayment(initialBalance, apr, months): 
    """ 
    - initialBalance: the starting balance on the card. 
    - apr: the APR. 
    - months: the number of equal monthly payments you wish to 
     make in order to reduce the balance to zero. 
    - returns: the monthly payment amount needed to reduce the 
     balance to zero (well, "zero" to within $0.005, anyway) 
     in the given number of months. 
    """ 
    low_guess = 0 
    high_guess = initialBalance 
    guess = float((low_guess + high_guess)/2) 
    listo = months*[guess] 

    while True: 

     if abs(float(balances(initialBalance, apr, listo)[-1])) < 0.006: 
      print "BINGO", guess ##for debugging 
      print balances(initialBalance, apr, listo)[-1] 
      return guess 

     elif float(balances(initialBalance, apr, listo)[-1]) < -0.005: 
      high_guess = guess 
      print "BOO", guess ##for debugging 
      print balances(initialBalance, apr, listo)[-1] 

     else: 
      low_guess = guess 
      print "NAY", guess ##for debugging 
      print balances(initialBalance, apr, listo)[-1] 
     guess = float((low_guess + high_guess)/2) 
     listo = months*[guess] 
相關問題