Wrong calculation in Python for overpayment - python

I started an online training for Python. The assignment wants to me calculate 45 hours work for 10.50 hourly payment. But, 5 hours in this is overwork. So, the payment goes to 10.50 X 5
So, the payment should be 498.75.
But, my program finds different sum. What is wrong with this code? (Note that I am novice)
hours = float(input("Enter hours: "))
rate = float(input("Enter rate: "))
extraPay = float((hours-40) * (rate*1.5))
def computepay(a, b, c):
paymentCalc= a * b + c
return paymentCalc
x = computepay(hours, rate, extraPay)
print(x)

you need to substract extra hours from basic hours on calculations and also add check that extra_pay will not be in negative. Do, Like this:
hours = float(45)
rate = float(10.5)
extra_hours = float(hours - 40)
extraPay = float(extra_hours * (rate*1.5))
def computepay(a, b, c, d):
if c < 0:
c = 0
payment_calc = (a - d) * b + c
return payment_calc
x = computepay(hours, rate, extraPay, extra_hours)
print(x)

The problem is that you are adding the overpay hours twice, once with the increased rate in extraPay and once in your payment calc (a is still 45).
Also, you need to check if hours are less than 40 because if it is less, extraPay will be negative and your calculation will be wrong.
Here is my suggestion:
def computepay(hours, rate):
bonus = 0
if hours>40:
overtime = hours-40
hours=40
bonus = (overtime)*rate*1.5
return hours*rate+bonus

Try:
hours = float(input("Enter hours: "))
rate = float(input("Enter rate: "))
remainder=(max(0,hours-40))
def computepay(a, b):
paymentCalc= a * b
return paymentCalc
def compute_ext(remainder,rate):
ext = remainder * (rate*1.5)
return ext
base = computepay(min(40,hours), rate)
if remainder:
base+=compute_ext(remainder,rate)
print(base)
you used all the hours instead for a max of 40 to calculate the base pay

Related

What is wrong with calculating total charges thru out my program

Hello my program can count how many customers and tell the customer their price based on the amount of hours but cannot add the total charges to save my life
Here’s my code
count = 1
total_charge = 0
total = 0
hours_parked = 0
ask = 1
standardRate = 2.00
FEE = .50
def calculate_charges(x, f, sr, t):
if x <= 3:
sr = 2.00
t = sr
print(t)
elif x >= 3 and x <= 24:
sr = 2.00
f = (x - 3) * .50
t = f + sr
print(t)
else:
print("We only allow 24 hours tops. Check the number of hours again!")
main(count, total_charge, hours_parked, ask, total)
def main(c, y, h, a, t):
h = int(input("How many hours did the customer park?"))
calculate_charges(h, FEE, standardRate, total)
c += 1
a = int(input("Is there more customers?(Type 1 for YES and 2 for NO.)"))
if a == 1:
y = t + y
main(count, total_charge, hours_parked, ask, total)
else:
y = t + y
c += 1
print("There was a total of ", c, " customers and a profit of $", y, "for the day!" )
main(count, total_charge, hours_parked, ask, total)
How many hours did the customer park?2
2.0
Is there more customers?(Type 1 for YES and 2 for NO.)1
How many hours did the customer park?2
2.0
Is there more customers?(Type 1 for YES and 2 for NO.)2
There was a total of 3 customers and a profit of $ 0 for the day!
Your previous code did not add up the results of the previous calculation.
count = 0
total_charge = 0
total = 0
hours_parked = 0
ask = 1
standardRate = 2.00
FEE = .50
def calculate_charges(x, f, sr):
if x <= 3:
t = sr
print(t)
else:
f = (x - 3) * f
t = f + sr
print(t)
return t
def main(c, y, h, a, t):
while True:
h = abs(int(input("How many hours did the customer park?")))
if h > 24:
print("We only allow 24 hours tops. Check the number of hours again!")
else:
break
t += calculate_charges(h, FEE, standardRate)
c += 1
a = int(input("Is there more customers?(Type 1 for YES and 2 for NO.)"))
if a == 1:
y = t + y
main(c, y, h, ask, total)
else:
y = t + y
print("There was a total of ", c, " customers and a profit of $", y, "for the day!")
main(count, total_charge, hours_parked, ask, total)
How many hours did the customer park?27
We only allow 24 hours tops. Check the number of hours again!
How many hours did the customer park?6
3.5
Is there more customers?(Type 1 for YES and 2 for NO.)1
How many hours did the customer park?28
We only allow 24 hours tops. Check the number of hours again!
How many hours did the customer park?10
5.5
Is there more customers?(Type 1 for YES and 2 for NO.)2
There was a total of 2 customers and a profit of $ 9.0 for the day!
You're calling
main(count, total_charge, hours_parked, ask, total)
but count, total_charge, hours_parked, ask and total are not being updated anywhere.
So you're passing in total_charge = 0 and that's what the program is returning.
Try passing c, y, h, a, t into main within your main function. (btw, it might be simpler to do everything in a while in the calculate_charges function)
Also...
It may be easier for you to figure out what's happening if your variables have meaningful names. After studying CompSci for 4 years in undergrad and now as a graduate student, one important lesson I've learned is that following coding convention will pay off both in the short run and in the long run.

How to loop with two conditions, in python?

I need to write a code that displays the a return of investments for 0 to 20 years or when the today's value has reached .5 * of the investment initial invested amount. I am stuck with the latter part. When I use an IF statment, I couldn't get any value. Here is my code.
def getExpInvestAmt(investAmt, i, n):
expInvestAmt = int(investAmt * pow(1 + i / 100, n))
return expInvestAmt
def getPresentValue(exp_invest_amt, d, n):
adjAmt = int(exp_invest_amt / pow(1 + d / 100, n))
return adjAmt
def main():
investAmt = float(input("Enter investment amount:"))
i = float(input("Enter the expected investment growth rate:"))
d = float(input("Enter the discount rate:"))
n = 0
adjA = 0
print("Year \t Value at year($) \t Today's worth($)")
for x in range(0, 21):
if adjA < 0.5 * investAmt
break
expected_value = getExpInvestAmt(investAmt, i, n)
present_value = getPresentValue(expected_value, d, n)
n += 1
adjA += 1
print("{} \t {:,} \t {:,}".format(x, expected_value, present_value))
main()
This is what I am suppose to get,
Enter investment amount: 10000
Enter the expected investment growth rate: 5
Enter the discount rate: 6.25
Year Value at Year($) Today's worth($)
1 10,500 9,346
2 11,025 8,734
3 11,576 8,163
4 12,155 7,629
5 12,763 7,130
6 13,401 6,663
7 14,071 6,227
8 14,775 5,820
9 15,513 5,439
10 16,289 5,083
11 17,103 4,751 # today's value have reached <= 50% of the initial amount program stops.
I think you can simplify your code; you don't need adjA or x. Where you are using adjA you should just be using present_value, and you can just iterate n over the range instead of x:
def main():
investAmt = float(input("Enter investment amount:"))
i = float(input("Enter the expected investment growth rate:"))
d = float(input("Enter the discount rate:"))
print("Year \t Value at year($) \t Today's worth($)")
for n in range(1, 21):
expected_value = getExpInvestAmt(investAmt, i, n)
present_value = getPresentValue(expected_value, d, n)
print("{} \t {:,} \t {:,}".format(n, expected_value, present_value))
if present_value < 0.5 * investAmt:
break
To get your expected results for an investAmt of 10000 and i of 5, you need a d value of 12.347528.

Loop Table using distance = speed * time

The distance a vehicle travels can be calculated as follows:
distance = speed * time
Write a program that asks the user for the speed of a vehicle (in miles per hour) and how many hours it has traveled. The program should then use a loop to display the distance the vehicle has traveled for each hour of that time period. Here is an example of the output:
What is the speed of the vehicle in mph? 40
How many hours has it traveled? 3
Hour Distance Traveled
1 : 40
2 : 80
3 : 120
I've gotten everything done so far but can't manage to get the table to come out properly, as shown in the example table at the first hour (1) it should start at 40 but instead it starts at 120. Can someone help me fix the code? forgot to mention it should work for any value the user enters such as if someone was going 50 mph in 5 hours
g = 'y'
while g == 'Y' or g == 'y':
speed = int(input('Enter mph: '))
time = int(input('Enter hours: '))
if time <= 0 or speed <= 0:
print('Invalid Hours and mph must be greater than 0')
else:
for t in range(time):
distance = speed * time
print(t + 1,':', distance)
time = time * 2
g = 'n'
print('End')
Just change 2 things in your program. First, there's no need to double the time inside for loop, Second use variable t instead of time to calculate distance.
g = 'y'
while g == 'Y' or g == 'y':
speed = int(input('Enter mph: '))
time = int(input('Enter hours: '))
if time <= 0 or speed <= 0:
print('Invalid Hours and mph must be greater than 0')
else:
for t in range(time):
distance = speed * (t+1) // Use t+1 instead of time
print(t + 1,':', distance)
# time = time * 2 // No need to double the time
g = 'n'
print('End')
Input:
40
3
Output:
(1, ':', 40)
(2, ':', 80)
(3, ':', 120)
End
You need to remove the commas from the print line, and print out the numbers in string format and concat it to the string colon like:
print(str(t + 1) + ':' + str(distance))
You also need to increment the time by one not multiply by 2
time = time + 1
Your output distance also can be fixed by calculating it based on t instead of time
distance = speed * (t+1)

How do I call a function inside another function in the same file in Python?

I am trying to break up some code into smaller subprograms within the same file to make it more modular. This is the code I would like to break up:
def time():
print("This program calculates the number of seconds in a given length of
time.\n")
second = 1
minute = second * 60
hour = minute * 60
day = hour * 24
week = day * 7
number1 = (eval(input("Enter a number of weeks: ")))
calc1 = number1 * week
number2 = (eval(input("Enter a number of days: ")))
calc2 = number2 * day
number3 = (eval(input("Enter a number of hours: ")))
calc3 = number3 * hour
number4 = (eval(input("Enter a number of minutes: ")))
calc4 = number4 * minute
number5 = (eval(input("Enter a number of seconds: ")))
calc5 = number5 * second
sum1 = (calc1 + calc2 + calc3 +calc4 + calc5)
print("\nIn", number1, "week(s),", number2, "day(s),", number3, "hour(s),",
number4, "minute(s), and", number5, "second(s), there are", sum1,
"second(s).")
It works the way I want it to when it's all together, but I'd like to break it up somewhere along the lines of this:
def count():
print("This program calculates the number of seconds in a given length of
time.\n")
second = 1
minute = second * 60
hour = minute * 60
day = hour * 24
week = day * 7
def number():
number1 = (eval(input("Enter a number of weeks: ")))
calc1 = number1 * week
number2 = (eval(input("Enter a number of days: ")))
calc2 = number2 * day
number3 = (eval(input("Enter a number of hours: ")))
calc3 = number3 * hour
number4 = (eval(input("Enter a number of minutes: ")))
calc4 = number4 * minute
number5 = (eval(input("Enter a number of seconds: ")))
calc5 = number5 * second
sum1 = (calc1 + calc2 + calc3 +calc4 + calc5)
def time():
print("This program calculates the number of seconds in a given length of
time.")
count()
number()
print("In,", number1, "weeks,", number2, "days,", number3, "hours,",
number4, "minutes, and", number5, "seconds, there are", sum1,
"seconds.")
time()
The goal is to run time() and have it call count() and number(), so the code for time() isn't as long. (I know the original code isn't that long, but I'm trying to learn how all this works.)
I've had success calling functions within a file before, but only when it was to print a string, and no math was involved. I've tried playing around with parameters and return and googling and even some gnashing of teeth, but to no avail. I keep ending up with errors like this:
Traceback (most recent call last):
File "<pyshell#525>", line 1, in <module>
time()
File "<pyshell#524>", line 4, in time
number()
File "<pyshell#522>", line 3, in number
calc1 = number1 * week
NameError: name 'week' is not defined
I'm new to programming so I'm sure I'm missing something annoyingly simple, but I haven't been able to figure it out on my own and would appreciate any help.
So it seems like the big thing you need to learn about is scope. When you declare a variable inside a function, you can only use that variable inside that function. So for example, when you declare week inside of the count function, you can only access the variable "week" when you are inside the function.
If you want to access a variable from anywhere inside a program you need to declare it globally. Here is a working version of your code with the time variables declared globally.
print("This program calculates the number of seconds in a given length of time.\n")
second = 1
minute = second * 60
hour = minute * 60
day = hour * 24
week = day * 7
def number():
number1 = (int(input("Enter a number of weeks: ")))
calc1 = number1 * week
number2 = (int(input("Enter a number of days: ")))
calc2 = number2 * day
number3 = (int(input("Enter a number of hours: ")))
calc3 = number3 * hour
number4 = (int(input("Enter a number of minutes: ")))
calc4 = number4 * minute
number5 = (int(input("Enter a number of seconds: ")))
calc5 = number5 * second
sum1 = (calc1 + calc2 + calc3 +calc4 + calc5)
print("In,", number1, "weeks,", number2, "days,", number3, "hours,",
number4, "minutes, and", number5, "seconds, there are", sum1,
"seconds.")
def time():
print("This program calculates the number of seconds in a given length of time.")
number()
time()
You need to be careful with global variables as you can run into problems if you use too many of them. Before trying to write more complicated programs I would recommend reading this article that does a good job explaining how scope and namespaces work in python.
Question: ... within the same file to make it more modular
You don't need a def count() at all.
All values are constant and therefore should be defined so.
There is no need to compute the values over and over again.
You can make it more modular, for instance:
SECONDS = {'s':1, 'm': 1*60, 'h':60*60, 'd':60*60*24, 'w': 60*60*24*7}
def get_input():
result = {'sum1':0}
for cat in ['weeks', 'days', 'hours', 'minutes', 'seconds']:
value = int( input( "Enter a number of {}: ".format(cat) ))
result[cat] = value
result['sum1'] += SECONDS[ cat[:1] ] * value
return result
def time():
result = get_input()
print("\nIn, {weeks}, week(s), {days}, day(s), {hours}, hour(s),"
" {minutes}, minute(s), and, {seconds} second(s), "
"there are, {sum1} second(s)."\
.format(**result))
if __name__ == '__main__':
print("This program calculates the number of seconds in a given length of time.\n")
time()
It's common, to use always a __main__ entry point.
This gives you the ability to call def get_input() from other python scripts.
Tested with Python: 3.4.2 and 2.7.9
You could have your count return a dict, like:
def count():
times = {'second': 1}
times['minute'] = times['second'] * 60
times['hour'] = times['minute'] * 60
times['day'] = times['hour'] * 24
times['week'] = times['day'] * 7
return times
Then you can call count in the time and pass it to number:
def time():
...
times = count()
values = number(times)
def number(times):
values = {}
number1 = int(input("Enter a number of weeks: "))
calc1 = number1 * times['week']
values.update({'number1': number1, 'calc1': calc1})
...
sum1 = calc1 + calc2 + calc3 + calc4 + calc5
values['sum1'] = sum1
return values
And then you can use the returned dict from number to populate your print at the end of time

Python: smarter way to calculate loan payments

How to calculate the monthly fee on a loan?
Given is:
a: an amount to loan.
b: the loan period (number of months).
c: the interest rate p.a. (interests is calculated and added every month, 1/12 of the interest is added. So if the interest is on 12%, 1% interest is added every month).
d: the amount of money owed after the end of the period.
This problem is a bit different than the usual since, the goal is not to have the loan payed after the loan period has ended, but to still owe an amount that is given. I have been able to find an algorithm so solve the problem if I wanted to pay the entire amount, but it will of course not work for this problem where the goal is to end up owing a given amount rather than not owing anything.
I managed to make a solution to this problem by starting with an guess and then keep on improving that guess until it was close enough. I wondered however, if there is a better way to simply calculate this, rather than just guessing.
Edit: Here's how I'm doing it now.
def find_payment(start, end, months, interest):
difference = start
guess = int(start / months * interest)
while True:
total = start
for month in range(1, months + 1):
ascribe = total * interest / 12
total = total + ascribe - guess
difference = total - end
# See if the guess was good enough.
if abs(difference) > start * 0.001:
if difference < 0:
if abs(difference) < guess:
print "payment is %s" % guess
return evolution(start, guess, interest, months)
else:
mod = int(abs(difference) / start * guess)
if mod == 0:
mod = 1
guess -= mod
else:
mod = int(difference / start * guess)
if mod == 0:
mod = 1
guess += mod
else:
print "payment is %s" % guess
return evolution(start, guess, interest, months)
evolution is just a function that displays how the loan would look like payment for payment and interest for interest, summing up total amount of interest paid etc.
An example would be if I wanted to find out the monthly payments for a loan starting with $100k and ending at $50k with an interest of 8% and a duration of 70 months, calling
>>> find_payment(100000, 50000, 70, 0.08)
payment is 1363
In the above case I would end up owing 49935, and I went through the loop 5 times. The amount of times needed to go through the loop depends on how close I want to get to the amount and it varies a bit.
This is a basically a mortgage repayment calculation.
Assuming that start is greater than end, and that interest is between 0 and 1 (i.e. 0.1 for 10% interest)
First consider the part of the payment you want to pay off.
Principal = start - end
The monthly payment is given by:
pay_a = (interest / 12) / (1 - (1+interest/12) ^ (-months))) * Principal
You then need to consider the extra interest. Which is just equal to the remaining principal times the monthly interest
pay_b = interest / 12 * end
So the total payment is
payment = (interest / 12) * (1 / (1 - (1+interest/12) ^ (-months))) * Principal + end)
On the example you gave of
Start: 100000
End: 50000
Months: 70
Interest: 8%
pay_a = 896.20
pay_b = 333.33
Payment = 1229.54
When I tested these values in Excel, after 70 payments the remaing loan was 50,000. This is assuming you pay the interest on the notional before the payment is made each month.
Perhaps the easiest way to think about this is to split the loan in two parts, one part which is to be repaid in full and another part where you don't pay off anything. You have already computed the monthly fee for the first part.
You can keep paying the interest of every month; then, you will alway owe the same amont.
Owe_1 = a
Int_2 = Owe_1*(InterestRate/12)
Pay_2 = Int_2
Owe_2 = Owe_1 + Int_2 - Pay_2 # ==> Owe_1 + Int_2 - Int_2 = Owe_1
Int_3 = Owe_2*(InterestRate/12)
Pay_3 = Int_3
Owe_3 = Owe_2 + Int_3 - Pay_3 # ==> Owe_2 + Int_3 - Int_3 = Owe_2 = Owe_1
python code to calculate emi
class EMI_CALCULATOR(object):
# Data attributes
# Helps to calculate EMI
Loan_amount = None # assigning none values
Month_Payment = None # assigning none values
Interest_rate = None #assigning none values
Payment_period = None #assigning none values
def get_loan_amount(self):
#get the value of loan amount
self.Loan_amount = input("Enter The Loan amount(in rupees) :")
pass
def get_interest_rate(self):
# get the value of interest rate
self.Interest_rate = input("Enter The Interest rate(in percentage(%)) : ")
pass
def get_payment_period(self):
# get the payment period"
self.Payment_period = input("Enter The Payment period (in month): ")
pass
def calc_interest_rate(self):
# To calculate the interest rate"
self.get_interest_rate()
if self.Interest_rate > 1:
self.Interest_rate = (self.Interest_rate /100.0)
else:
print "You have not entered The interest rate correctly ,please try again "
pass
def calc_emi(self):
# To calculate the EMI"
try:
self.get_loan_amount() #input loan amount
self.get_payment_period() #input payment period
self.calc_interest_rate() #input interest rate and calculate the interest rate
except NameError:
print "You have not entered Loan amount (OR) payment period (OR) interest rate correctly,Please enter and try again. "
try:
self.Month_Payment = (self.Loan_amount*pow((self.Interest_rate/12)+1,
(self.Payment_period))*self.Interest_rate/12)/(pow(self.Interest_rate/12+1,
(self.Payment_period)) - 1)
except ZeroDivisionError:
print "ERROR!! ZERO DIVISION ERROR , Please enter The Interest rate correctly and Try again."
else:
print "Monthly Payment is : %r"%self.Month_Payment
pass
if __name__ == '__main__':# main method
Init = EMI_CALCULATOR() # creating instances
Init.calc_emi() #to calculate EMI
for more info visit : https://emilgeorgejames.wordpress.com/2015/07/29/python-emi-equated-monthly-installment-calculator/
This rather a detailed way but will give the whole payment as well
# Mortgage Loan that gives the balance and total payment per year
# Function that gives the monthly payment
def f1 (principle,annual_interest_rate,duration):
r = annual_interest_rate/1200
n = duration*12
a=principle*r*((1+r)**n)
b= (((1+r)**n)- 1)
if r > 0 :
MonthlyPayment = (a/b)
else :
MonthlyPayment = principle/n
return MonthlyPayment
# Function that gives the balance
def f2 (principle,annual_interest_rate,duration,number_of_payments):
r = annual_interest_rate/1200
n = duration*12
a= ((1+r)**n)
b= ((1+r)**number_of_payments)
c= (((1+r)**n)-1)
if r > 0 :
RemainingLoanBalance = principle*((a-b)/c)
else :
RemainingLoanBalance = principle*(1-(number_of_payments/n))
return RemainingLoanBalance
# Entering the required values
principle=float(input("Enter loan amount: "))
annual_interest_rate=float(input("Enter annual interest rate (percent): "))
duration=int(input("Enter loan duration in years: "))
# Output that returns all useful data needed
print ("LOAN AMOUNT:",principle,"INTEREST RATE (PERCENT):",annual_interest_rate)
print ("DURATION (YEARS):",duration,"MONTHLY PAYMENT:",int(f1(principle,annual_interest_rate,duration)))
k=duration+1
BALANCE=principle
total=0
for i in range (1,k):
TOTALPAYMENT= f1(BALANCE,annual_interest_rate,k-i)*12
total+= TOTALPAYMENT
BALANCE= f2(principle,annual_interest_rate,duration,12*i)
print("YEAR:",i,"BALANCE:",int(BALANCE),"TOTAL PAYMENT",int(total))
How about this?
def EMI_calc(principle, rate, time, frequency):
return (principle / ((1-((1+(rate/frequency))**(-1*(time*frequency))))/(rate/frequency)))
print("""
----- Welcome to EMI programe for Python -----
""")
print("\n You have chosen to know the EMI for Loan.\n")
input('\nTo Continue Press ENTER --- to ABORT Press ctrl+c > \n')
print("\nPlease Enter amount of Loan to be taken: >\n")
principle = int(input())
print("\nEnter rate of interst (%): >\n")
rate = float(input())/100
print("\nEnter Term (Years): >\n")
time = float(input())
print("\nPlease enter the frequency of installments) : >\n")
frequency = int(input())
EMI = round(EMI_calc(principle, rate, time, frequency),0)
print("""
---------------------------------------------------------------------
""")
print(f"""
The EMI for Loan of Rs.{principle};
at interest rate of {rate*100} % for {time} years;
would be: Rs.""", EMI)
print("""
---------------------------------------------------------------------
""")
Here is a code snippet using numpy functions. This shows you the payment, principal, interest, instalment and total_amount each month. Run it and see the output. You can also check the syntax for Excel "IPMT()" and "PPMT()" functions for more explanation of the arguments.
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.pmt.html#numpy.pmt
import math
import numpy as np
rate = 0.08
start_amount = 100000.0
end_amount = 50000.0
diff_amount = start_amount - end_amount
# nr_years = 4
payment_frequency = int (12)
nr_months = 70 # = nr_years * payment_frequency
per_np = np.arange (nr_months) + 1 # +1 because index starts with 1 here
pay_b = rate / payment_frequency * end_amount
ipmt_np = np.ipmt (rate / payment_frequency, per_np, nr_months, diff_amount) - pay_b
ppmt_np = np.ppmt (rate / payment_frequency, per_np, nr_months, diff_amount)
for payment in per_np:
idx = payment - 1
principal = math.fabs (ppmt_np [idx])
start_amount = start_amount - principal
interest = math.fabs (ipmt_np [idx])
instalment = principal + interest
print payment, "\t", principal, "\t", interest, "\t\t", instalment, "\t\t", start_amount
print np.sum (ipmt_np)

Categories

Resources