Using functions in 'while' loop python - python

So I want to create a code that would calculate the minimum monthly payment and remaining balance, given an annual interest rate, principal amount and monthly payment rate. The desired output is:
Month: 1
Minimum monthly payment: 168.52
Remaining balance: 4111.89
Month: 2
Minimum monthly payment: 164.48
Remaining balance: 4013.2
and so on until month 12.
I know there's a way to do it without defining functions but the whole function thing was just messing me up so I wanted to try it. My current code is -
a=0
while a<=11:
def min_mth_pay(balance,monthlyPaymentRate):
x = balance * monthlyPaymentRate
return x
def balance(balance,min_mth_pay,annualInterestRate):
y=(balance - min_mth_pay)*((annualInterestRate/12)+1)
return y
a +=1
print('Month:' + str(a) + 'Minimum monthly payment:' + str(x) + 'Remaining balance:' + str('y'))
I'm not even sure if I can use functions in such a format? The error pops out saying the name 'x' is undefined. Really new at Python here obviously would appreciate any clarifications! :)

You're confusing defining functions with calling them. You should define then functions separately, then call them from within your loop.
def min_mth_pay(balance,monthlyPaymentRate):
x = balance * monthlyPaymentRate
return x
def balance(balance,min_mth_pay,annualInterestRate):
y=(balance - min_mth_pay)*((annualInterestRate/12)+1)
return y
a=0
while a<=11:
a +=1
x = min_mth_pay(balance,monthlyPaymentRate)
y = balance(balance,min_mth_pay,annualInterestRate)
print('Month:' + str(a) + 'Minimum monthly payment:' + str(x) + 'Remaining balance:' + str(y))
Note that it's not clear where balance, monthlyPaymentRate, min_mth_pay, and annualInterestRate are coming from in your code.

Related

Python syntax errors - coin machine problem

I know these are very basic questions but cannot figure out what I'm doing wrong. I'm just beginning to learn python and don't understand why I am getting a syntax error every time I try to subtract something.
When I try to run this:
```#def variables - input cash entered and item price in float parentheses
cash = float(400)
price = float(215)
#change calculation
def cash_owed(cash - price)```
I get a
SyntaxError: invalid syntax with the ^ pointing to the - sign.
I can't find any information about why using a subtraction sign would return a syntax error in this context. What am I doing wrong?
I am trying to create a coin machine program where the cash is entered in integers representing cents (i.e $5 = 500) returns the required change in the most convenient coin denominations. This is the rest of the code that I wrote, but I can't even get past that first syntax error.
cash = float(400)
price = float(215)
#change calculation
def cash_owed(cash - price)
c = cash_owed
#display amount recieved, cost of item, required change
print ("Amount recieved : " + str(cash)) \n
print ("Cost of item : " + str(float)) \n
print("Required change : " + str(c)) \n
#calculate toonies owed
def calculate_toonies(c//200)
round(calculate_toonies)
print("Toonies x " + str(calculate_toonies))
c = c%200
#calculate loonies owed
def calculate_loonies(c//100)
round(calculate_loonies)
print("Loonies x " + str(calculate_loonies))
c = c%100
#calculate quarters owed
def calculate_quarters(c//25)
round(calculate_quarters)
print("Quarters x " + str(calculate_quarters))
c = c%25
#calculate dimes owed
def calculate_dimes(c//10)
round(calculate_dimes)
print("Dimes x " + str(calculate_dimes))
c = c%10
#calculate nickles owed
def calculate_nickles(c//5)
round(calculate_nickles)
print("Nickles x " + str(calculate_nickles))
c = c%5```
Your function definition is wrong. The parameter cannot do an operation & should contain a colon.
Change
def cash_owed(cash - price)
To
def cash_owed(cash, price):
new_price = cash - price
You have to put a colon after function
You can try this:
def cash_owed(cash, price):
return(cash - price)

Fixed payment is returned as 0. Why? What corrections to make?

Now write a program that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, we mean a single number which does not change each month, but instead is a constant amount that will be paid each month.
In this problem, we will not be dealing with a minimum monthly payment rate.
The following variables contain values as described below:
balance - the outstanding balance on the credit card
annualInterestRate - annual interest rate as a decimal
The program should print out one line: the lowest monthly payment that will pay off all debt in under 1 year, for example:
Lowest Payment: 180
Assume that the interest is compounded monthly according to the balance at the end of the month (after the payment for that month is made). The monthly payment must be a multiple of $10 and is the same for all months. Notice that it is possible for the balance to become negative using this payment scheme, which is okay. A summary of the required math is found below:
Monthly interest rate = (Annual interest rate) / 12.0
Monthly unpaid balance = (Previous balance) - (Minimum fixed monthly payment)
Updated balance each month = (Monthly unpaid balance) + (Monthly interest rate x Monthly unpaid balance)
Here is my code. I do not know where I'm going wrong:
balance = float(raw_input('enter the outsanding balance on your card'))
annualInterestRate = float(raw_input('enter the anual interest rate as a decimal'))
month = 0
checkBalance = balance
monthlyFixedPayment = 0
while checkBalance <= 0:
checkBalance = balance
monthlyFixedPayment += 10
while month <= 11:
monthlyInterestRate = annualInterestRate/12.0
monthlyUnpaidBalance = checkBalance - monthlyFixedPayment
checkBalance = monthlyUnpaidBalance + (monthlyInterestRate * monthlyUnpaidBalance)
print('lowest payment:' + str(monthlyFixedPayment))
I think this is the program you are looking for:
balance = 500
annualInterestRate = .5
checkBalance = balance
monthlyFixedPayment = 10
count = 0
while checkBalance > 0:
month = 0
while month <= 11 and checkBalance > 0:
count+=1
monthlyInterestRate = annualInterestRate/12.0
monthlyUnpaidBalance = checkBalance - monthlyFixedPayment
checkBalance = monthlyUnpaidBalance - (monthlyInterestRate * monthlyUnpaidBalance)
print "\t"+str(checkBalance)
month+=1
print checkBalance
print "lowest amount: "
print count*monthlyFixedPayment+checkBalance
I have left the print statements, so that you can see what is going on in each iteration.
Some problems i noticed in your code:
1) you were doing a monthlyFixedPayment += 10 that was changing the fixed payemnt. you are not supposed to change the fixed payment according to your problem definition.
2) you were doing a checkBalance = balance in each iteration of outer while loop. This was causing the calculated value to be resetted.
3) I have introduced a count variable to check how many times these decuctions were happening, as month was getting reset in each iteration.
while checkBalance <= 0: to while checkBalance >= 0:
Also, you need to increment month in the while month <= 11: loop.
You are going at it the hard way; there is an analytic solution for fixed_payment:
from math import ceil
def find_fixed_monthly_payment(balance, months, yearly_rate):
i = 1. + yearly_rate / 12.
im = i ** months
return balance * (im * (1. - i)) / (i * (1. - im))
def find_final_balance(balance, months, yearly_rate, fixed_payment):
i = 1. + yearly_rate / 12.
for _ in range(months):
# make payment
balance -= fixed_payment
# add interest
balance *= i
return balance
def get_float(prompt):
while True:
try:
return float(raw_input(prompt))
except ValueError:
# input could not be cast to float; try again
pass
def main():
balance = get_float("Please enter starting balance: ")
annual_rate = get_float("Annual interest rate (in percent): ") / 100.
fixed_payment = find_fixed_monthly_payment(balance, 12, annual_rate)
# round up to the nearest $10
fixed_payment = ceil(fixed_payment / 10.) * 10.
# double-check value of fixed_payment:
assert find_final_balance(balance, 12, annual_rate, fixed_payment ) <= 0., "fixed_payment is too low!"
assert find_final_balance(balance, 12, annual_rate, fixed_payment - 10.) > 0., "fixed_payment is too high!"
print("Lowest payment: ${:0.2f}".format(fixed_payment))
if __name__ == "__main__":
main()

Beginner Python exercise

I'm having trouble solving problem 2 from this page
Here
Here's my code:
#Problem set 1 b
out_bal = float(raw_input("Enter the outstanding balance on your credit card: "))
ann_interest = float(raw_input("Enter the annual interest rate as a decimal: "))
min_pmnt = 10
months = 1
prev_bal = out_bal
month_interest = ann_interest / 12.0
updated_bal = prev_bal * (1 + month_interest) - min_pmnt
while out_bal > 0:
for i in range(1,13):
out_bal = updated_bal
prev_bal = out_bal
months += 1
if out_bal <= 0:
break
else:
min_pmnt = min_pmnt + 10
months = 0
print out_bal
print "RESULT"
print "Monthly payment to pay off debt in 1 year: $", min_pmnt
print "Number of months needed: ", months
print "Balance: ", round(out_bal, 2)
I want to take 1200 and .18 for the first two inputs, respectively. However when I do this the program gets caught in my while loop and keeps printing 1208.00.
When I read the code to myself it seems like it should be working. But I think I'm not using the prev_bal variable correctly.
Also, it's performing the math the way I expect it to the first time it goes through the loop but then it seems like it's not adding 10 to min_pmnt and going through the loop again. It seems like it's just using 10 over and over.
How can I write this so it does actually add 10 and perform the loop again?
Thanks!
Your problem is that updated_bal isn't changing, yet you are setting out_bal to it each time you iterate, and then conditioning the loop on out_bal becoming reduced in value.
It looks to me like you are thinking that updated_bal changes on each loop iteration, based on its component parts. In order for that to work, you would need to instead use a function that calculates an updated balance each time around.

Multiple parameters definition of a function Python

I'm trying to write a function that calculates the cost of a loan, but I keep getting the cost of the loan to be the negative value of what the user inputs as the amount of the loan.
#define monthly payment
def MonthlyPayment (ammountOfLoan, numberOfPeriods,yearlyInterestRate):
ammountOfLoan = 0
numberOfPeriods = 0
yearlyInterestRate = 0
payment = [(yearlyInterestRate/12)/(1-(1+yearlyInterestRate/12))**(-numberOfPeriods)] * ammountOfLoan
return (payment)
#define cost of loan
def LoanCost(principal, month, payment):
period = 0
month = 0
payment = 0
cost = period * payment - principal
return (cost)
#calculate cost of loan
def main():
loan = float(raw_input("What is the ammount of your loan? "))
period = float(raw_input("How many months will you make payments? "))
rate = float(raw_input("What is the interest rate? "))
rate = rate / 100
MonthlyPayment(loan, period, rate)
costOfLoan = LoanCost(loan, period, rate)
print "The cost of the loan is $" + str(costOfLoan)
#run main
main()
LoanCost is setting period and payment to 0 (you're making the same mistake in MonthlyPayment, as well), then multiplying them. So you're ending up with (0 * 0) - principal. You're also calling the second parameter "month", when what you really mean is "period".
Just to clarify, when you have a function definition like
def func(a, b, c):
You shouldn't initialize a, b, and c to zero inside the function body. You're overwriting their values when you do that. Just use them directly.

Python Bisection search overshoots target

I have to create a code to find the exact payment, to the cent, needed to pay off a loan in 12 months using bisection. The code I created for this works but it overshoots it's target. The loan will be payed off within the 12 months but after making 12 payments the final balance should be around 0. However it is a way bigger negative number.
The code I am using is:
StartBalance = float(raw_input('Credit Balance in $: '))
AnnualRate = float(raw_input('Annual interest rate in decimals: '))
MonthlyRate = AnnualRate / 12.0
MinPaymentLow = StartBalance / 12.0
MinPaymentHigh = (StartBalance*(1+MonthlyRate)**12.0)/12.0
cent = 0.01
Payment = (MinPaymentHigh+MinPaymentLow)/2.0
while (Payment*12-StartBalance) >= cent:
for month in range(0, 12):
Balance = (StartBalance-Payment)/10*(1+MonthlyRate)
if Balance < 0:
MinPaymentLow = Payment
elif Balance > 0:
MinPaymentHigh = Payment
Payment = (MinPaymentHigh + MinPaymentLow)/ 2.0
print 'RESULT'
print 'Number of months needed: 12'
print 'Montly pay: $', round(Balance,2)
It looks like these lines:
for month in range(0, 12):
Balance = (StartBalance-Payment)/10*(1+MonthlyRate)
Should be:
Balance = StartBalance
for month in range(0, 12):
Balance = (Balance-Payment) * (1 + MonthlyRate)
Or something similar, depending on how you want to calculate interest, and whether you consider payments occurring at the start or end of the month.
Your code seemed to work fine for me, but if you're getting results that are "way off" it's probably because you're using the float datatype. Float is untrustable, because it rounds on every operation. Given enough iterations and you've rounded off a lot of money. Try using decimal instead. This module keeps track of decimals as indexed integer values.

Categories