我的代码是否正确实现了这项功课?

时间:2010-12-23 16:47:04

标签: python

问题是编写计算贷款利息的python并打印付款计划。贷款的利息可以根据简单的公式计算:

  

I = P×R×T

我是支付的利息,P是借入的金额(本金),R是利率,T是贷款的长度。

最后需要显示如下:

  

该计划将打印借入的金额,支付的利息总额,每月付款金额以及付款时间表。

示例会话

Loan calculator

Amount borrowed: 100
Interest rate: 6
Term (years): 1

Amount borrowed:    $100.00
Total interest paid:  $6.00

           Amount     Remaining
Pymt#       Paid       Balance
-----      -------    ---------
  0        $ 0.00      $106.00
  1        $ 8.84      $ 97.16
  2        $ 8.84      $ 88.32
  3        $ 8.84      $ 79.48
  4        $ 8.84      $ 70.64
  5        $ 8.84      $ 61.80
  6        $ 8.84      $ 52.96
  7        $ 8.84      $ 44.12
  8        $ 8.84      $ 35.28
  9        $ 8.84      $ 26.44
 10        $ 8.84      $ 17.60
 11        $ 8.84      $  8.76
 12        $ 8.76      $  0.00

完整的问题描述如下:http://openbookproject.net/pybiblio/practice/wilson/loan.php 为此,我编写了如下代码:

import decimal
from decimal import *
class loan_calc:

 def __init__(self):
  decimal.getcontext().prec = 3
  p = Decimal(input('Please enter your loan amount:'))
  r = Decimal(input('Please enter the rate of interest:'))
  t = Decimal(input('Please enter loan period:'))
  r_e = r/100
  i = p*r_e*t 
  term = t*12
  r_a = p+i
  amnt = p/term
  count = 0
  b_r = r_a
  print "Payment\t\tAmount Paid\t\tBal.Rem."
  while count <= term:
   if count == 0:
    print count,"\t\t"'0.00'"\t\t\t",b_r
    count += 1
    b_r -= amnt
    continue

   if term - count == 1:
    amnt = b_r
    print count,"\t\t",amnt,"\t\t\t",b_r
    count += 1
    b_r -= amnt
    continue

   else: 
    print count,"\t\t",amnt,"\t\t\t",b_r
    b_r -= amnt
    count += 1
    continue



loan = loan_calc()

5 个答案:

答案 0 :(得分:2)

使用Decimal(input())是错误的:

>>> decimal.getcontext().prec=3
>>> decimal.Decimal(input('enter the number: '))
enter the number: 0.1
Decimal('0.1000000000000000055511151231257827021181583404541015625')

使用input会导致Python评估输入,从而创建浮点值。使用raw_input并将字符串直接传递给Decimal

来解决此问题
>>> decimal.Decimal(raw_input('enter the number: '))
enter the number: 0.1
Decimal('0.1')

将代码缩进4个空格,跟随PEP 8,并避免使用单字符变量名。

答案 1 :(得分:2)

首先,我建议不要同时执行import decimalfrom decimal import *。选择一个并从那里使用你需要的东西。通常,我会import whatever然后使用whatever.what_is_needed来保持名称空间更清晰。

评论者已经注意到,没有必要为这么简单的事情创建课程(除非这是家庭作业而你的导师需要它)。删除类声明,将def __init__(self)更改为def main(),并调用main当前实例化loan_class的位置。有关主要功能的更多信息,请参阅Guido's classic post有关它们的信息。

应检查输入值。一个简单的方法是使用try-except块,因为它们被转换为Decimal。代码看起来像:

prin_str = raw_input('Please enter your loan amount: ')
try:
    principal = decimal.Decimal(prin_str)
except decimal.InvalidOperation:
    print "Encountered error parsing the loan amount you entered."
    sys.exit(42)

要使其工作,您必须在sys.exit()调用之前的某个时间import sys。我通常把我的导入放在文件的开头。

由于您的所有输入都属于同一类型,因此您可以轻松地将其作为常规使用函数,然后为每个输入调用该函数。

计算中似乎存在某种错误。解决这个问题留给读者练习。 ; - )

答案 2 :(得分:1)

重写(在Python 3中,抱歉)。我不确定我理解算法,但你可以修改它。也许这会有所帮助吗?

import decimal

balance = decimal.Decimal(input("Amount borrowed: "))
rate = decimal.Decimal(input("Rate (%): ")) / 100
term = int(input("Term (years): "))

print("\t".join(s.rjust(15) for s in ("Payment", "Amount Paid", "Balance")))
print("-"*54)

balance *= (1 + rate * term)
payment = balance / (12 * term)
total = 0
for month in range(12 * term):
    if balance < payment:
        payment = balance
    print(("{: >15.2f}\t"*3)[:-1].format(payment, total, balance))
    total += payment
    balance -= payment

请注意以下事项:

  • 没有愚蠢的变量名。一切都被命名为应该如何。
  • 字符串格式化以使打印更整洁。
  • 没有令人讨厌的while循环多个案例。您将在该术语中每月打印一行,因此请使用for循环。

答案 3 :(得分:1)

这是一个与你的写作方式密切相关的答案。使用我在询问how to round off a floating number in python时解释和建议的方法,它使用与decimal模块的math函数等效的ceil模块来获得相同的答案,如下所示。练习链接(除了一些小的输出格式)。我还将代码重新缩进到更常用的4空格,并将变量重命名为更具可读性。希望你从中学到一些东西。请注意,我decimal.getcontext().prec设置为3(我不相信它符合您的想法)。

import decimal

def main():
    principle = decimal.Decimal(raw_input('Please enter your loan amount:'))
    rate = decimal.Decimal(raw_input('Please enter rate of interest (percent):')) / 100
    term = decimal.Decimal(raw_input('Please enter loan period (years):')) * 12

    interest = (principle * rate).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_HALF_EVEN)
    balance = principle + interest
    payment = (balance / term).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_CEILING)
    print "Payment\t\tAmount Paid\t\tRem.Bal."
    for count in range(1+term):
        if count == 0:
            print count, "\t\t0.00\t\t\t", balance
        elif count == term: # last payment?
            payment = balance
            balance -= payment
            print count, "\t\t", payment, "\t\t\t", balance
        else:
            balance -= payment
            print count, "\t\t", payment, "\t\t\t", balance

main()

# > python loan_calc.py
# Please enter your loan amount:100
# Please enter rate of interest (percent):6
# Please enter loan period (years):1
# Payment         Amount Paid             Rem.Bal.
# 0               0.00                    106.00
# 1               8.84                    97.16
# 2               8.84                    88.32
# 3               8.84                    79.48
# 4               8.84                    70.64
# 5               8.84                    61.80
# 6               8.84                    52.96
# 7               8.84                    44.12
# 8               8.84                    35.28
# 9               8.84                    26.44
# 10              8.84                    17.60
# 11              8.84                    8.76
# 12              8.76                    0.00

答案 4 :(得分:1)

逻辑与之前的答案大致相同,但严重重新格式化。享受!

# Loan payment calculator
import decimal

def dollarAmt(amt):
    "Accept a decimal value and return it rounded to dollars and cents"
    # Thanks to @Martineau!
    # I found I had to use ROUND_UP to keep the final payment
    # from exceeding the standard monthly payments.
    return amt.quantize(decimal.Decimal('0.01'), rounding=decimal.ROUND_UP)

def getAmt(msg):
    "Get user input and return a decimal value"
    return decimal.Decimal(raw_input(msg))

class MonthlyFixedPaymentLoan(object):
    def __init__(self, principal, yearlyRate, months):
        self.principal  = principal
        self.yearlyRate = yearlyRate
        self.months     = months

        self.interest   = dollarAmt(principal * yearlyRate * (months/12))
        self.balance    = principal + self.interest
        self.payment    = dollarAmt(self.balance / months)

    def __str__(self):
        return ("Amount borrowed:     ${0:>10}\n" +
                "Total interest paid: ${1:>10}").format(dollarAmt(self.principal), dollarAmt(self.interest))

    def payments(self):
        # 'month 0'
        yield 0, decimal.Decimal('0.00'), self.balance

        pmt = self.payment
        bal = self.balance
        for mo in range(1,self.months):
            bal -= pmt
            yield mo, pmt, bal

        # final payment
        yield self.months, bal, decimal.Decimal('0.00')

def main():
    amt  = getAmt('Amount borrowed ($): ')
    rate = getAmt('Interest rate (%/yr): ')
    pd   = getAmt('Loan term (years): ')

    loan = MonthlyFixedPaymentLoan(amt, rate/100, pd*12)

    print('')
    print(loan)
    print('')
    print('Month     Payment       Balance')
    print('-----    --------    ----------')

    for mo,pay,rem in loan.payments():
        print('{0:>4}     ${1:>7}    ${2:>9}'.format(mo, pay, rem))

if __name__=="__main__":
    main()