From ccbb4894dbc00c66158466f74b5f9ff8931e922f Mon Sep 17 00:00:00 2001 From: scuti Date: Sat, 11 May 2024 20:06:40 -0700 Subject: [PATCH] changed payment_number to payment-number; fixed one-time payments not counting --- Makefile | 2 +- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/amort.py | 11 +++++------ 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 README.md diff --git a/Makefile b/Makefile index d54cd5b..4ac9153 100644 --- a/Makefile +++ b/Makefile @@ -3,5 +3,5 @@ reference: amortize -P 100000 -r 0.05 -f monthly -n 36 -s > ref.txt test: - python src/amort.py -p 100000 -i 5.0 -t 3 -ot "{\"payment_number\":13,\"amount\":5000}" + python src/amort.py -p 100000 -i 5.0 -t 3 -ot "{\"payment-number\":13,\"amount\":5000}" diff --git a/README.md b/README.md new file mode 100644 index 0000000..9608fad --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ + +# amort + +Generates an amortization schedule based on the principal, interest rate, term, and any additional payments towards principal. + +## requirements + +Only imports `argparse` and `json` for the main block of the script. + +* saves results to a file `schedule.csv` +* does not access the web or internet + +## usage + +Invoke `make test` to generate a schedule based on loan of 100,000 over a 3 year term given an interest rate of 5.0% with a one-time payment towards principal of 5000 at the 13th month. + +### extra payments + +For extra payments towards principal, invoking the script will look like: + + python src/amort.py -p {principal} -i {interest rate} -t {years} --extra-payments extra_payments.json + +A valid json file contains an list named `extra-payments`. Each element is an object with the attributes `payment-number` and `amount`. + + { + "extra-payments" : [ + { + "payment-number": 1, + "amount": 500 + }, { + "payment-number": 2, + "amount": 500 + }, { + "payment-number": 3, + "amount": 500 + } + ] + } + +* `payment-number` is the month when the payment has been made. +* `amount` is self-explanatory + +## misc + +This originated from me playing with ChatGPT. I asked it a question and it blurted out a semi-functional script as an answer. Then I made this repo to track the errors I fixed. diff --git a/src/amort.py b/src/amort.py index b06a824..1d0db32 100644 --- a/src/amort.py +++ b/src/amort.py @@ -27,7 +27,7 @@ def generate_amortization_schedule(principal, interest_rate, loan_term, extra_pa principal_payment = round(monthly_payment - interest_payment, 2) # Apply one-time payment if provided - if one_time_payment and payment_number == one_time_payment['payment_number']: + if one_time_payment and payment_number == one_time_payment['payment-number']: principal_payment += one_time_payment['amount'] remaining_balance -= one_time_payment['amount'] if extra_payments != []: @@ -104,7 +104,7 @@ if __name__ == "__main__": p.add_argument("--term", "-t", type=int,\ help="sets the term (years)") p.add_argument("--one-time", "-ot", type=str,\ - help="factors in a one-time payment (json, example: {\"payment_number\":13,\"amount\":5000}") + help="factors in a one-time payment (json, example: {\"payment-number\":13,\"amount\":5000}") p.add_argument("--extra-payments", "-ep", type=str,\ help="facts in multiple one time payments (json file name)") args = p.parse_args() @@ -112,13 +112,12 @@ if __name__ == "__main__": if args.extra_payments is not None: with open(args.extra_payments) as f: l = json.loads(f.read()) - # print(extra["extra-payments"]) - if args.one_time is not None: - l.append(json.loads(args.one_time)) extra = [] if "extra-payments" in l: extra = l["extra-payments"] - extra.sort(key=lambda k: k["payment_number"]) + extra.sort(key=lambda k: k["payment-number"]) + if args.one_time is not None: + extra.append(json.loads(args.one_time)) return args.principal, args.interest_rate, args.term, extra principal, interest_rate, loan_term, extra_payments = get_arguments()