我的代码是这道作业的正确实现吗?
这个问题是要写一段Python代码,用来计算贷款的利息,并打印出还款计划。贷款的利息可以用一个简单的公式来计算:
I = P × R × T
这里面,I代表支付的利息,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 个回答
使用 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 的规范,并且避免使用单个字符的变量名。
首先,我建议不要同时使用 import decimal
和 from decimal import *
。选择其中一个,然后根据需要使用里面的内容。一般来说,我会用 import whatever
,然后用 whatever.what_is_needed
这样可以保持命名空间的整洁。
正如评论者所提到的,对于这么简单的事情,没有必要创建一个类(除非这是作业,老师要求这样做)。你可以删除类的声明,把 def __init__(self)
改成 def main()
,然后在你当前实例化 loan_class 的地方调用 main。想了解更多关于主函数的内容,可以看看 Guido 的经典帖子。
输入的值应该进行检查。一个简单的方法是在将它们转换为 Decimal 时使用 try-except 块。代码可能看起来像这样:
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
。我通常把我的导入放在文件的开头。
由于你的所有输入都应该是同一种类型,你可以很容易地把它做成一个通用函数,然后对每个输入调用这个函数。
计算中似乎存在某种错误。解决这个问题留给读者自己去做。;-)
这里有一个回答,跟你的写法很相似。我使用了我之前提到的方法,关于如何在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