1

I am not too familiar with Python, but I am attempting to create a program which takes in a file name, worksheet name, monthly payment, user's additional monthly payment, and principal loan amount. The program should then create an excel file with the name submitted, a worksheet with the name submitted. In the excel sheet start subtracting the monthly payment from the balance write that into the excel sheet with a payment date calculated and then do the same with the additional amount and keep repeating until the balance reaches 0. I have done this using recursion, but I get the following error

zsh: segmentation fault  python3 loanPayoff.py

The following is my code:

  import datetime
import xlsxwriter
import sys

sys.setrecursionlimit(10**6)

# we create the workbook
def createWorkBook(workBookName, workSheetName, monthly, principal, additional, date):
    #creating the workbook
    workbook = xlsxwriter.Workbook(workBookName + '.xlsx')
    worksheet = workbook.add_worksheet(workSheetName)
    worksheet.write('A1', 'Date')
    worksheet.write('B1', 'Mortgage principal amount')
    worksheet.write('C1', 'Regular amount against principal')
    worksheet.write('D1', 'Against principal additional')
    payments(monthly, additional, principal, worksheet, 'regular', date, 1)
    workbook.close()

# update the workbook's worksheet with the next date
def workBookUpdateDate(date, row, workSheet):
    dateColumn = 0
    workSheet.write(row, dateColumn, date)

# update the workbook's worksheet with the new balance
def workBookUpdateBalance(balance, row, workSheet):
    balanceColumn = 1
    workSheet.write(row, balanceColumn, balance)

# update the workbook's worksheet with the regular amount being paid
def workBookUpdateRegularAmount(regularAmount,row, workSheet):
    regularAmountColumn = 2
    workSheet.write(row, regularAmountColumn, regularAmount)

# update the workbook's worksheet with the additional amount being paid
def workBookUpdateAdditionalAmount(additionalAmount,row, workSheet):
    additionalAmountColumn = 3
    workSheet.write(row, additionalAmountColumn, additionalAmount)

# increment the date by two weeks
def addTwoWeeksToDate(date):
    twoWeeks = datetime.timedelta(days=14)
    newDate = date + twoWeeks
    #print("DATE ......", format(newDate))
    return newDate

def payments(monthly, additional, principal, workSheet, type, date, row):
   while principal != 0:
       if type == 'regular':
           principal = principal - monthly
           date = addTwoWeeksToDate(date)
           workBookUpdateDate(date, row, workSheet)
           workBookUpdateAdditionalAmount(0,row, workSheet)
           workBookUpdateRegularAmount(monthly, row, workSheet)
           workBookUpdateBalance(principal, row, workSheet)
           row = row + 1
           payments(0, additional, principal, workSheet, 'additional', date, row)
       elif type == 'additional':
           principal = principal - additional
           date = addTwoWeeksToDate(date)
           workBookUpdateDate(date, row, workSheet)
           workBookUpdateAdditionalAmount(additional, row, workSheet)
           workBookUpdateRegularAmount(0, row, workSheet)
           workBookUpdateBalance(principal, row, workSheet)
           row = row + 1
           payments(0, additional, principal, workSheet, 'regular', date, row)



# prompt the user for the information
fileName = input('Hello what will the file be called? ')
workSheetNameToBe = input('Ok, what will the worksheet be called? ')
monthlyPaymentAmount = float(input('How much do you pay monthly? '))
additionalPaymentAmount = float(input('How much additional can you pay monthly? '))
principalAmount = float(input('How much is the principal? '))
# set the start date for today
new_date = datetime.date.today()
createWorkBook(fileName, workSheetNameToBe, monthlyPaymentAmount, principalAmount, additionalPaymentAmount, new_date)

I am currently using Python 3.8.2 on a Mac 10.15.4

Any feedback welcomed.

Ace
  • 603
  • 2
  • 15
  • 33
  • 1
    See the answer [here](https://stackoverflow.com/questions/3323001/what-is-the-maximum-recursion-depth-in-python-and-how-to-increase-it). The limit that you've set probably caused the crash. – null Apr 04 '20 at 17:09
  • In your own words, why does `payments` use *both* a while loop *and* recursion? What problem are you trying to solve with the recursion, that isn't solved by the while loop already? – Karl Knechtel Apr 04 '20 at 17:16
  • `sys.setrecursionlimit(10**6)` causes a stack overflow and so a segfault. Don't do that. – Martijn Pieters Apr 04 '20 at 17:27

2 Answers2

1

I would assume your issue is the changing of recursion limit

From this link: https://bugs.python.org/issue35542

https://docs.python.org/3/library/sys.html#sys.setrecursionlimit

The highest possible limit is platform-dependent. A user may need to set the limit higher when they have a program that requires deep recursion and a platform that supports a higher limit. This should be done with care, because a too-high limit can lead to a crash.

I think this is a known case where the stack limit is hit depending on the operating system before RecursionError can be raised when a higher recursion limit is set. On my machine (Mac 10.10.4) this segfaults on 2.7 but raises RecurstionError on Python 3.7.1. Increasing the limit to 200000 causes segfault on 3.7.1.

001001
  • 530
  • 1
  • 4
  • 13
0

Python will not 'segv' under normal circumstances. Something about your Python installation is broken. You should try to replace it with a fresh installation.

Also, it's a little weird to recurse the way you are. You can write that to run iteratively and more legibly.

Chad Miller
  • 1,435
  • 8
  • 11