开发者

Is my code a correct implementation of this homework?

开发者 https://www.devze.com 2023-02-01 12:38 出处:网络
The problem is to write the python that calculates the interest due on a loan and prints a payment schedule. The interest due on a loan can be calculated according to the simple formula:

The problem is to write the python that calculates the interest due on a loan and prints a payment schedule. The interest due on a loan can be calculated according to the simple formula:

I = P × R × T

where I is the interest paid, P is the amount borrowed (principal), R is the interest rate, and T is the length of the loan.

Finally it needs to displayed as follows:

The program will print the amount borrowed, total interest paid, the amount of the monthly payment, and a payment schedule.

Sample session

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.开发者_JAVA技巧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

The complete problem description is here: http://openbookproject.net/pybiblio/practice/wilson/loan.php To accomplish this I have written the code which is as follows:

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()


The use of Decimal(input()) is wrong:

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

Using input causes Python to evaluate the input, which creates a floating-point value. Fix this by using raw_input and passing the string directly to Decimal:

>>> decimal.Decimal(raw_input('enter the number: '))
enter the number: 0.1
Decimal('0.1')

Indent the code by 4 spaces, follow PEP 8, and avoid single-character variable names.


To start with, I recommend against doing both import decimal and from decimal import *. Pick one and use what you need from there. Generally, I do import whatever and then use whatever.what_is_needed to keep the namespace cleaner.

As commenters have already noted there's no need to create a class for something this simple (unless this is homework and your instructor requires it). Delete the class declaration, change your def __init__(self) into a def main(), and call main where you currently instantiate loan_class. For more about main functions, see Guido's classic post about them.

The input values should be checked. A simple way to do this would be with a try-except block as they are converted to Decimal. The code could look something like:

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)

To get this to work, you'd have to import sys sometime before the sys.exit() call. I usually put my imports at the start of the file.

Since all your inputs are to be of the same type, you could easily make this a general use function and then call that function for each input.

There does appear to be some sort of bug in the calculations. Resolving that is left as an exercise for the reader. ;-)


Here's an answer closely patterned to the way yours is written. Using the method I explained and suggested when you asked about how to round off a floating number in python, it uses the decimal module equivalent of the math module's ceil function to get the same answer as shown at the practice link (except for some minor output formatting). I also re-indented the code to the more commonly used 4-spaces, and renamed the variables to be a little more readable. Hope you learn something from it. Notice that I don't set decimal.getcontext().prec to 3 (I don't believe it does what you think).

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


Rewritten (in Python 3, sorry). I'm not sure I understand the algorithm but you can modify it. Maybe this will help?

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

Notice the following:

  • No silly variable name. Everything is named how it should be.
  • String formatting to make the printing neater.
  • No nasty while loop with multiple cases. You're going to print one line per month in the term, so use a for loop.


The logic is much the same as previous answers, but severely reformatted. Enjoy!

# 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()
0

精彩评论

暂无评论...
验证码 换一张
取 消