Program that takes the purchase price as input. The program should display a table, with appropriate headers, of a payment schedule for the lifetime of the loan.
I am new to python coding I have tried for hours and the resulted I posted is the best I can do. I have tried to use "break" but that result only gets me the first two months.
while ending> 0:
Month+=1
payment = starting N * .05
ending-=payment
interest = (starting N * rate) / 12
principal = payment - interest
starting N = ending + payment
infinite loop
The problem is that you are deleting from ending a value (payment) that becomes quickly really small at each iteration (by a factor of 1/20 = 0.05).
Fixing:
ending = 1000
N = ending
as start values, you get:
while ending> 0:
Month+=1
payment = N * .05
ending-=payment
interest = (starting N * rate) / 12 # don't think about this value now
principal = payment - interest # don't think about this value now
N = ending + payment # N becomes the previous ending, without subtracting payment
print("Ending: ", ending, "Payment:", payment)
# Ending: 4e-323 Payment: 0.0
# Ending: 4e-323 Payment: 0.0
# Ending: 4e-323 Payment: 0.0
...
Basically, the amount that you pay at the end becomes so small that the values doesn't go under 4e-323, which is really near to 0.
And because 4e-323 * 0.05 is basically 0 in python you get a value that is forever near to 0 without becoming smaller.
payment = 4e-323 * 0.05 # 0
ending -= payment # 4e-323 - 0 = 4e-323
One solution could be to set the condition in the while statement as such:
while ending > 0.00000001 :
...
Related
So If I have a number 1000 (original number),
I want to get another number (calculated number) by subtracting 3 other amounts,
The three amounts I want to take from original number are as follows:
MepMiAmount = (calculated number - 169) divided by 13.8%
MepPenAmount = (calculated number but only if higher than 120 and only the amount between min 120 to max 962) the amount between min and max is then divided by 3%
leviAmount = calculated number divided by 0.5%
Calculated number = original number - MepMiAmount - MepPenAmount - leviAmount
I am able to calculate this just now using a repetitive iteration and a delta number like so :
*this is not actual code but just to give an idea, though almost identical
calculated_number = original number - (original number / 1.138)
checked = calculated_number + MepPenAmount + MepMiAmount + leviAmount
checked_calculated_numbers = []
while checked != payment:
# calculate a delta for the calculated_number
delta = make_float(abs(checked - payment))
delta = max(delta, Decimal('0.01'))
# let's check if we should add or subtract this delta
if checked > payment:
calculated_number -= delta
else:
calculated_number += delta
#re calculate MepMiAmount from new checked number
MepMiAmount = getMepMi(Args)
# re calculate MepPenAmount with the checked number
MepPenAmount = Decimal(0)
MepPenAmount = calculate_MepPenAmount (args)
# recalculate leviAmount
leviAmount = calculate_leviAmount (args)
checked_calculated_numbers.append(checked)
checked = float(calculated_number + MepPenAmount + MepMiAmount + leviAmount )
return { number}
I think there has to be a more elegant way to do this rather than brute fore iterations
I want to develop an electric calculator which :
Converts money into units(KWh).
It also takes user input to determine how many electric component he/she uses in home in order to determine average electricity consumption per day.
After having those in inputs and calculation it will also show how many day he/she can have against the money he/she recharged(Ex: for 10$ he can have 100 Kwh, if average use per day is 10 KWh how many day he can have? [day=100kwh/10kwh=10 days]
I have solved 1 and 2 problem using two function, now i want to use the final value of those two function to get the day. i was trying to divide the final of those function. is it possible to divide the value of those function?
1. this function converts money into units in KWh
def money_to_unit():
recharge=int(input("Enter yor recharge amount : "))
amount=recharge-(recharge*(5/100)) # after deducting 5% vat
unit=0
if amount<=300: #300 is max value for using 75 Kwh
unit=amount/4 # 4 is the slab rate for 0-75 Kwh
elif amount<=981.25: #981.25 is max value for using 200 Kwh
unit=75+((amount-300)/5.45) #5.45 is the slab rate for 76-200 Kwh
elif amount<=1551.25: #1551.25 is max value for using 300 Kwh
unit=75+125+((amount-681.25)/5.7) #5.7 is the slab rate for 201-300 Kwh
elif amount<=2153.25:
unit=75+125+100+((amount-1551.25)/6.02)
elif amount<=4013.25:
unit=75+125+100+100+((amount-2153.25)/9.30)
else:
unit=75+125+100+100+200+((amount-4013.25)/10.7)
print("Useable amount is :"+ " "+str(round(amount,2))+" "+"Taka")
print("Useable unit is: "+" "+str(round(unit,2))+" "+"Kwh")
money_to_unit()
2. to determine the average use per day in KWh
def comp():
light=int(input("Enter the number of light :"))
watt=int(input("Enter the watt : "))
hour=int(input("Enter the agerage use of light in hour per day : "))
consumption=(light*watt*hour)/1000
print("you total consumption is"+ " " + str(consumption)+ " " + "Kwh per day")
comp()
3. divided money_to_unit() by comp(). how to do it?
(1).for 500 taka, usable amount is 475 taka, usable unit is 107.11 Kwh
(2).for 5 light of 20 w per hour using 6 hour a day, average use is 0.6 Kwh per day.
(3). day = 107.11 Kwh/0.6 Kwh = 178.5 day
Both of your function should return the calculated value that you want to use for further calculations (instead of just printing it).
def money_to_unit():
/* function definition */
return round(amount,2), round(amount,2)
and
def comp():
/* function definition */
return consumption
Then you can simply call the functions like this:
x, y = money_to_unit()
z = comp()
and finally you can perform any extra calculation you want with x,y,z like:
result = x/z
/* or */
result2 = y/z
def money_to_unit():
# all your previous code
return round(unit,2)
def comp():
# all your previous code
return consumption
and perhaps:
money_unit = money_to_unit()
consumption = comp()
day = money_unit / consumption
print(round(day,1), "{}".format("day"))
OUTPUT:
178.5 day
Use return. Give functions specific tasks to do, not only wrapping around some scripts.
1.Define two functions for first step:
def recharge_to_amount(recharge, vat):
return recharge * (1 - vat)
and
def amount_to_kwh(amount):
if amount <= 300:
return amount / 4
elif amount <= 981.25:
return 75 + ((amount - 300) / 5.45)
elif amount <= 1551.25:
return 75 + 125 + ((amount - 681.25) / 5.7)
elif amount <= 2153.25:
return 75 + 125 + 100 + ((amount - 1551.25) / 6.02)
elif amount <= 4013.25:
return 75 + 125 + 100 + 100 + ((amount - 2153.25) / 9.30)
else:
return 75 + 125 + 100 + 100 + 200 + ((amount - 4013.25) / 10.7)
2.Define another function for second step:
def consumption(light, watt, hour):
return light * watt * hour / 1000
3.Define last function:
def days(watt, cons):
return watt / cons
And perform your calculation:
amount = recharge_to_amount(500)
kwh = amount_to_kwh(amount)
consumption = consumption(5, 20, 6)
days = days(kwh, consumption)
I am trying to calculate a constant for month-to-month growth rate from an annual growth rate (goal) in Python.
My question has arithmetic similarities to this question, but was not completely answered.
For example, if total annual sales for 2018 are $5,600,000.00 and I have an expected 30% increase for the next year, I would expect total annual sales for 2019 to be $7,280,000.00.
BV_2018 = 5600000.00
Annual_GR = 0.3
EV_2019 = (BV * 0.3) + BV
I am using the last month of 2018 to forecast the first month of 2019
Last_Month_2018 = 522000.00
Month_01_2019 = (Last_Month_2018 * CONSTANT) + Last_Month_2018
For the second month of 2019 I would use
Month_02_2019 = (Month_01_2019 * CONSTANT) + Month_01_2019
...and so on and so forth
The cumulative sum of Month_01_2019 through Month_12_2019 needs to be equal to EV_2019.
Does anyone know how to go about calculating the constant in Python? I am familiar with the np.cumsum function, so that part is not an issue. My problem is I cannot solve for the constant I need.
Thank you in advance and please do not hesitate to ask for further clarification.
More clarification:
# get beginning value (BV)
BV = 522000.00
# get desired end value (EV)
EV = 7280000.00
We are trying to get from BV to EV (which is a cumulative sum) by calculating the cumulative sum of the [12] monthly totals. Each monthly total will have a % increase from the previous month that is constant across months. It is this % increase that I want to solve for.
Keep in mind, BV is the last month of the previous year. It is from BV that our forecast (i.e., Months 1 through 12) will be calculated. So, I'm thinking that it makes sense to go from BV to the EV plus the BV. Then, just remove BV and its value from the list, giving us EV as the cumulative total of Months 1 through 12.
I imagine using this constant in a function like this:
def supplier_forecast_calculator(sales_at_cost_prior_year, sales_at_cost_prior_month, year_pct_growth_expected):
"""
Calculates monthly supplier forecast
Example:
monthly_forecast = supplier_forecast_calculator(sales_at_cost_prior_year = 5600000,
sales_at_cost_prior_month = 522000,
year_pct_growth_expected = 0.30)
monthly_forecast.all_metrics
"""
# get monthly growth rate
monthly_growth_expected = CONSTANT
# get first month sales at cost
month1_sales_at_cost = (sales_at_cost_prior_month*monthly_growth_expected)+sales_at_cost_prior_month
# instantiate lists
month_list = ['Month 1'] # for months
sales_at_cost_list = [month1_sales_at_cost] # for sales at cost
# start loop
for i in list(range(2,13)):
# Append month to list
month_list.append(str('Month ') + str(i))
# get sales at cost and append to list
month1_sales_at_cost = (month1_sales_at_cost*monthly_growth_expected)+month1_sales_at_cost
# append month1_sales_at_cost to sales at cost list
sales_at_cost_list.append(month1_sales_at_cost)
# add total to the end of month_list
month_list.insert(len(month_list), 'Total')
# add the total to the end of sales_at_cost_list
sales_at_cost_list.insert(len(sales_at_cost_list), np.sum(sales_at_cost_list))
# put the metrics into a df
all_metrics = pd.DataFrame({'Month': month_list,
'Sales at Cost': sales_at_cost_list}).round(2)
# return the df
return all_metrics
Let r = 1 + monthly_rate. Then, the problem we are trying to solve is
r + ... + r**12 = EV/BV. We can use numpy to get the numeric solution. This should be relatively fast in practice. We are solving a polynomial r + ... + r**12 - EV/BV = 0 and recovering monthly rate from r. There will twelve complex roots, but only one real positive one - which is what we want.
import numpy as np
# get beginning value (BV)
BV = 522000.00
# get desired end value (EV)
EV = 7280000.00
def get_monthly(BV, EV):
coefs = np.ones(13)
coefs[-1] -= EV / BV + 1
# there will be a unique positive real root
roots = np.roots(coefs)
return roots[(roots.imag == 0) & (roots.real > 0)][0].real - 1
rate = get_monthly(BV, EV)
print(rate)
# 0.022913299846925694
Some comments:
roots.imag == 0 may be problematic in some cases since roots uses a numeric algorithm. As an alternative, we can pick a root with the least imaginary part (in absolute value) among all roots with a positive real part.
We can use the same method to get rates for other time intervals. For example, for weekly rates, we can replace 13 == 12 + 1 with 52 + 1.
The above polynomial has a solution by radicals, as outlined here.
Update on performance. We could also frame this as a fixed point problem, i.e. to look for a fixed point of a function
x = EV/BV * x ** 13 - EV/BV + 1
The fix point x will be equal to (1 + rate)**13.
The following pure-Python implementation is roughly four times faster than the above numpy version on my machine.
def get_monthly_fix(BV, EV, periods=12):
ratio = EV / BV
r = guess = ratio
while True:
r = ratio * r ** (1 / periods) - ratio + 1
if abs(r - guess) < TOLERANCE:
return r ** (1 / periods) - 1
guess = r
We can make this run even faster with a help of numba.jit.
I am not sure if this works (tell me if it doesn't) but try this.
def get_value(start, end, times, trials=100, _amount=None, _last=-1, _increase=None):
#don't call with _amount, _last, or _increase! Only start, end and times
if _amount is None:
_amount = start / times
if _increase is None:
_increase = start / times
attempt = 1
for n in range(times):
attempt = (attempt * _amount) + attempt
if attempt > end:
if _last != 0:
_increase /= 2
_last = 0
_amount -= _increase
elif attempt < end:
if _last != 1:
_increase /= 2
_last = 1
_amount += _increase
else:
return _amount
if trials <= 0:
return _amount
return get_value(start, end, times, trials=trials-1,
_amount=_amount, _last=_last, _increase=_increase)
Tell me if it works.
Used like this:
get_value(522000.00, 7280000.00, 12)
Having a play around trying to better understand recursion. I want to make a function that shows the CPI increase for a particular year given a starting amount.
Assuming the starting amount is 100000 and CPI rate is 5%, then f(0) = 100000, f(1) = 5000, f(2) = 5250 etc.I want to return the CPIincrease column from below
rate 0.05
n TotalCPI CPIincrease
0 100000
1 105000 5000
2 110250 5250
3 115762.5 5512.5
4 121550.625 5788.125
5 127628.1563 6077.53125
6 134009.5641 6381.407812
7 140710.0423 6700.478203
8 147745.5444 7035.502113
9 155132.8216 7387.277219
10 162889.4627 7756.64108
So far I have the TotalCPI from column of the above table
def CPIincreases(n):
if n<=0:
return initial
else:
return (CPIincreases(n-1))*(1+CPIrate)
initial = 100000
CPIrate = 0.05
print(CPIincreases(1),CPIincreases(2),CPIincreases(3),CPIincreases(4))
output: 105000.0 110250.0 115762.5 121550.625
Now I'm lost. Because the output shows the I should be adding in
CPIincrease(n) - CPIincrease(n-1)
Somewhere.
Any Help greatly appreciated, even if its to say this function is not possible.
Cheers
The function you have created calculates the total value of the lump sum over time, and as you have pointed out, you can call it twice (once with year and once with year - 1) and take the difference to get your answer.
If you really want do this recursively in one go we need to think through the base cases:
Year 0: At the beginning there is no interest
return 0
Year 1: After the first year the change is just the initial amount times the interest rate
return initial * rate
Year 2+: From this year on, we make the same as last year, plus the interest on that interest
return last_year + rate * last_year
Or just: return last_year * (1 + rate)
Now we can put it all together:
def cpi_increase(year, initial, rate):
if year == 0:
return 0
if year == 1:
return initial * rate
return (1 + rate) * cpi_increase(year - 1, initial, rate)
If we print this out we can see the values about match up:
initial = 100000
rate = 0.05
for year in range(11):
print('{year:<5} {total:<21} {cpi_increase}'.format(
year=year,
total=initial * (1 + rate) ** year,
cpi_increase=cpi_increase(year, initial, rate)
))
The values:
0 100000.0 0
1 105000.0 5000.0
2 110250.0 5250.0
3 115762.50000000001 5512.5
4 121550.62500000003 5788.125
5 127628.15625000003 6077.53125
6 134009.56406250005 6381.407812500001
7 140710.04226562506 6700.478203125001
8 147745.5443789063 7035.502113281251
9 155132.8215978516 7387.2772189453135
10 162889.4626777442 7756.64107989258
Thinking through our base cases also shows how to create the direct calculation. At year y we have applied the (1 + rate) multiplication y - 1 times and the base (initial * rate) once. This gives us:
def cpi_increase_direct(year, initial, rate):
if year <= 0:
return 0
return initial * rate * (1 + rate) ** (year - 1)
I like how Jon's answers is more elaborate. Here's my code, I've tried to make variable names self explanatory but I'll briefly describe them as well.
total_cpi: first column
cpi_increase: 2nd column
cpi_rate: CPIrate
If we need to solve it in one recursive function, we can solve this problem only by using state variables:-
def calculate_cpi_increase(total_cpi, cpi_increase, year):
if year == 0:
return total_cpi, cpi_increase
else:
return calculate_cpi_increase(total_cpi*(1+cpi_rate), total_cpi*cpi_rate, year-1)
cpi_rate = 0.05
calculate_cpi_increase(100000, 0, 10)
result: (162889.46267774416, 7756.641079892579)
First of all you should not call a recursive function with all the values that you want to print. For example if you call F(2),F(3),F(4) and F(5) you would repeat the calculations for F(2) 4 times, as every other call needs this calculation.
You should not use global variables also, you can use my simple approach and encapsulate them in another function. In this code I generate not only one value, this generates the full table, a list of python tuples. Any tuple are two values, the value and the increment per iteration. The full table is printed by another function.
def CPITable(n, initial = 100000, CPIrate = 0.05):
def CPITableRecurse(n):
if n<=0:
return [(initial,0)]
else:
CPI = CPITable(n-1)
inc = CPI[-1][0] * CPIrate
CPI.append((CPI[-1][0] + inc , inc ))
return CPI
return CPITableRecurse(n)
def printTable(table):
i = 0
for line in table:
print ( str(i) + " %5.2f %5.2f" % line)
i += 1
printTable(CPITable(6))
#output:
# 0 100000.00 0.00
# 1 105000.00 5000.00
# 2 110250.00 5250.00
# 3 115762.50 5512.50
# 4 121550.62 5788.12
# 5 127628.16 6077.53
# 6 134009.56 6381.41
hi am a newbie to python and i am having a bit of hard time understanding this simple while loop.this program is supposed to calculate the time its takes for the bacteria to double.
time = 0
population = 1000 # 1000 bacteria to start with
growth_rate = 0.21 # 21% growth per minute
while population < 2000:
population = population + growth_rate * population
print population
time = time + 1
print "It took %d minutes for the bacteria to double." % time
print "...and the final population was %6.2f bacteria." % population
and the result is:
1210.0
1464.1
1771.561
2143.58881
It took 4 minutes for the bacteria to double.
...and the final population was 2143.59 bacteria.
what i dont get is why is the final result greater than 2000 cause its supposed to stop before 2000.i am i getting something wrong?
Your code reads: "As long as the population is less than 2000, calculate the population of the next generation and then check again". Hence, it will always calculate one generation too many.
Try this:
while True:
nextGen = population + growth_rate * population
if nextGen > 2000: break
population = nextGen
print population
time = time + 1
EDIT:
Or to get the exact result:
print (math.log (2) / math.log (1 + growth_rate) )
So the whole program could be:
import math
population = 1000
growth_rate = 0.21 # 21% growth per minute
t = math.log (2) / math.log (1 + growth_rate)
print 'It took {} minutes for the bacteria to double.'.format (t)
print '...and the final population was {} bacteria.'.format (2 * population)
Because prior to your last iteration (#4 below) it IS below 2,000.
Iteration #1: 1210.0
Iteration #2: 1464.1
Iteration #3: 1771.561
Iteration #4: 2143.58881
Another way to do this, although perhaps less elegant, would be to add a break in your While loop like this (assuming all you care about is not printing any number higher than 2,000):
while population < 2000:
population = population + growth_rate * population
if population >= 2000:
break
else:
print population
time = time + 1
At the penultimate iteration of the loop the population was less than 2,000, so there was another iteration. On the final iteration the population became more than 2,000 and so the loop exited.
If the population increased by 1 each time then you're correct; the loop would have exited at 2,000. You can see this behaviour using a simpler version:
i = 0
while i < 10:
i += 1
print i
Vary the amount that i increases by in order to see how it changes.
A while loop is an example of an "entry controlled" loop. This means that the condition is checked before entering the loop. Hence, this means if your loop condition was violated during the previous iteration, but not at the beginning, your loop will terminate after the first violation, not before it.
Here is a simple example:
>>> a = 1
>>> while a < 5:
... a = a+3
... print a
...
4
7
So, if you want that your loop must exit before a is greater than or equal to 5, you must do the check in the loop itself and break out of the loop:
>>> a = 1
>>> while a < 5:
... a = a+3
... if a < 5:
... print a
... else:
... break
...
4
So your code right here:
while population < 2000:
population = population + growth_rate*population
Say we enter that while loop and population = 1800, and growth_rate = .21. This satisfies all the requirements for the while loop to enter another loop. But, in the next line, you will set population = 1800 +(.21)*1800 which equals 2178. So, when you print out population, it will say 2178 even though it's higher than 2000
What you could do, is something like this:
while population < 2000:
if population == population + growth_rate * population < 2000:
population = population + growth_rate * population
time = time + 1
else:
break
print population
time = 0
population = 1000 # 1000 bacteria to start with
growth_rate = 0.21 # 21% growth per minute
while population != 2*population:
population = population + (growth_rate * population )
time = time + 1
print "It took %d minutes for the bacteria to double." % time
I think you will be getting the right output now.
I think this is a simple math problem - you're expecting the time to be an integer, although it probably is a floating point number. The loop can't stop when the population has reached 2000, because the way you're calculating it, it never has a value of 2000.