摊销时间表

2024-10-04 09:25:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我是来自COBOL的python新手。 我正在尝试创建一个程序,接受用户关于贷款的输入,然后输出付款时间表,以及它们将如何影响贷款余额。在

#ACCEPTS USER INPUT AND ASSIGNS VALUES
print('lets try to amortize a loan')
input()
print('when will this loan begin?')
year = int(input('year: '))
month = int(input('month: '))
day = int(input('day: '))
principal = float(input('give me a loan amount: '))
rate = float(input('give me an interest rate in decimal form: '))
term = int(input('how many year will this loan be for: '))
comp = int(input('how many times a year will payments be made: '))
monthly = float(input('what will the payment amount be: '))

#DISPLAYS HOW THE SYSTEM TOOK USER INPUT
print('lets take a look at these values')
input()
print('\n', '$', principal,
      '\n', (rate*100), '%',
      '\n', term, 'years',
      '\n', 'paying ', comp, 'times per year',
      '\n', 'beginning:', month, '/', day, '/', year,
      '\n', 'our monthly payment is $', monthly)
input()

#CALCULATES PERDIEM
perdiem = ((principal * rate) / 365)
print('our perdiem will be $', round(perdiem, 4))
print('with this we can calculate a months payment')
input()
print('first lets try and structure for the first month')

#BELOW IS TESTING TO SEE HOW MANY DAYS ARE IN A BILLING CYCLE
if month == 1 or 3 or 5 or 7 or 8 or 10 or 12:
    NumDays = 31
elif month == 4 or 6 or 9 or 11:
    NumDays = 30
elif month == 2 and (year % 4) != 0:
    NumDays = 28
elif month == 2 and (year % 4) == 0:
    NumDays = 29

print('so our first month would have', NumDays, 'days of perdiem')
input()
print('FIRST MONTH PAYMENT')

#BELOW TESTS TO SEE WHAT MONTH NEEDS TO BE DISPLAYED
if month == 12:
    NextMonth = month - 11
    NextYear = year + 1
else:
    NextMonth = month + 1
    NextYear = year

#DISPLAYS FIRST MONTHS DATA
print('Date:', NextMonth, '/', day, '/', NextYear)
PayNum = 1
print('Payment: #', PayNum)
print('Payment Amount: $', monthly)
print('Days this cycle:', NumDays)
MonthInt = round((perdiem * NumDays), 2)
print('Months Interest: $', MonthInt)
MonthP = round((monthly - MonthInt), 2)
print('Months Principal: $', MonthP)
balance = round((principal - MonthP), 2)
print('Remainder: $', balance)
input()

基本上,我想重复从第一个月支付相同的信息,调整值(paynum+1,nextmonth+1,balance-monthp,等等),直到余额小于每月付款。在

我尝试过if和while语句的变体,但似乎无法构建任何有效的语句。我的值只会调整一次,似乎不能持续覆盖值。 感谢您在这个问题上的帮助,以及更好地编写现有代码的建议。在


Tags: orprincipalinputratethisyearwillint
1条回答
网友
1楼 · 发布于 2024-10-04 09:25:09

我个人的看法是,在学习python时,应该不惜一切代价避免使用input()函数:(a)它将您从模块化的代码结构中转移出去;(b)它很少用于应用程序-接口通常是命令行参数或直接函数调用。在

您提供的代码有点难以理解,尽管我很欣赏它与COBOL风格和文化的联系。最好的办法是把你的问题设计成更小的子任务,并测试它们是如何分开工作的。这样你就能知道你的问题在哪里,而且更容易集中你的问题(以及回答问题的人的注意力)。在

我的理解是,你的脚本的核心思想是计算每月还款和贷款摊销。考虑以下代码:

# FIXME: missing compound interest
def perdiem(amount, rate):
    return (amount * rate) / 365


def days_per_month(month, year):
    if month in [1, 3, 5, 7, 8, 10, 12]:
        return 31
    elif month in [4, 6, 9, 11]:
        return 30
    elif month == 2:
        if (year % 4) == 0:
            return 29
        else:
            return 28
    else:
        raise ValueError('month expected', month)


def next_month(month, year):
    if month == 12:
        next_month = 1
        next_year = year + 1
    else:
        next_month = month + 1
        next_year = year
    return next_month, next_year

def monthly_interest(principal, days, rate):
    return perdiem(principal, rate) * days


def monthly_principal(monthly_payment, current_interest_payment):
    return monthly_payment - current_interest_payment

def yield_expected_payment_schedule(start_year, 
                                    start_month, 
                                    initial_amount, 
                                    rate,
                                    duration_in_years,
                                    monthly_payment):
    year = start_year
    month = start_month
    amount = initial_amount 
    for t in range(duration_in_years * 12 + 1):
        days = days_per_month(month, year)
        interest_due = monthly_interest(amount, days, rate)
        if amount > 0:
            yield {'balance at month start': amount,
                   'interest due': monthly_interest(amount, days, rate),  
                   'year': year,
                   'month': month
                   } 
        amount = amount - (monthly_payment - interest_due)
        month, year = next_month(month, year)

if __name__ == '__main__':
    arg_dict1 = dict(start_year=1965, 
                     start_month=8, 
                     initial_amount=1000, 
                     rate=0.05,
                     duration_in_years=1,
                     monthly_payment=85.61)        
    schedule = list(yield_expected_payment_schedule(**arg_dict1))
    print(schedule)       

一些后续思考:

  • 尽量把你的论点收集、计算和结果展示分开
  • 当您指定金额和期限时,您只知道作为年金的每月付款,不允许同时输入它们,请考虑设计evaluate_monthly_payment()
  • 将预期付款、已付金额和当前应付金额分开,使之更切合实际
  • 使用datatime.date类型和相应的函数进行日期操作。在

希望有用。在

相关问题 更多 >