I am a beginner programmer and I am working on an assignment that requires me to do nested loops as part of a finance operation. I have written most of the code and the numbers work according (such as interest and such), however the issue arises when I try print out the savings summary for the years given.
import math
def main():
#This will be hardcoded values for the years running, savings amount and annual interest and calculate the monthly interest rate
savingsAmount = 500
annualInterest = 0.12
yearsRunning = 2
monthlyInterest = annualInterest / 12
#This will state the accumulator variables for totals of investment balance (month), savings (YTD), and interest earned (YTD)
totalInvestBal = 0
totalSavings = 500
totalInterest = 0
#This will begin the accumulator loop process
for i in range (1, yearsRunning + 1):
print "Savings Schedule for Year", i,":"
print "Month Interest Amount Balance"
for i in range (1, 13):
totalInterest = monthlyInterest * totalInvestBal
totalInvestBal = totalSavings + totalInterest + totalInvestBal
totalSavings = totalSavings
print i, round(totalInterest,2), round(totalSavings,2), round(totalInvestBal,2)
print
#i becomes 12 here so we need another answer.
print "Savings summary for year", (need a new way of saying the year here),":"
print "Total amount saved:", totalSavings
print "Total interest earned:", totalInterest
print "End of year balance:", totalInvestBal
main()
Since the "i" loop index variable is updated to 12, I can place that as the year. I am working from year 1 up and I need the savings summary to be from year 1 and up as well. How would that be fixed?
Simply change the second loop variable form i to anything else (e.g. k):
for i in range (1, yearsRunning + 1):
print
print "Savings Schedule for Year", i,":"
print "Month Interest Amount Balance"
for k in range (1, 13):
totalInterest = monthlyInterest * totalInvestBal
totalInvestBal = totalSavings + totalInterest + totalInvestBal
totalSavings = totalSavings
print k, round(totalInterest,2), round(totalSavings,2), round(totalInvestBal,2)
print
#IF WE KEEP ONLY i IT becomes 12 here so we need another -> VARIABLE!!!!! for example K!!.
print "Savings summary for year %s:" %(i) #use this " words words %s words" %(variable name)
print "Total amount saved:", totalSavings
print "Total interest earned:", totalInterest
print "End of year balance:", totalInvestBal
For starters, I added some \t 's to your code- they denote printing a tab for your output so that the output lines up better.
def main():
#This will be hardcoded values for the years running, savings amount and annual interest and calculate the monthly interest rate
savingsAmount = 500
annualInterest = 0.12
yearsRunning = 2
monthlyInterest = annualInterest / 12
#This will state the accumulator variables for totals of investment balance (month), savings (YTD), and interest earned (YTD)
totalInvestBal = 0
totalSavings = 500
totalInterest = 0
#This will begin the accumulator loop process
for i in range (1, yearsRunning + 1):
print
print "Savings Schedule for Year", i,":"
print "Month \tInterest \tAmount \tBalance"
for i in range (1, 13):
totalInterest = monthlyInterest * totalInvestBal
totalInvestBal = totalSavings + totalInterest + totalInvestBal
totalSavings = totalSavings
print i, "\t", round(totalInterest,2), "\t\t", round(totalSavings,2), "\t", round(totalInvestBal,2)
print
#i becomes 12 here so we need another answer.
print "Savings summary for year" #, (need a new way of saying the year here),":"
print "Total amount saved:", totalSavings
print "Total interest earned:", totalInterest
print "End of year balance:", totalInvestBal
main()
Since this is an assignment, I'll point out some errors I see and let you try to fix them. If you look at the output:
Savings Schedule for Year 1 :
Month Interest Amount Balance
1 0.0 500.0 500.0
2 5.0 500.0 1005.0
3 10.05 500.0 1515.05
4 15.15 500.0 2030.2
5 20.3 500.0 2550.5
6 25.51 500.0 3076.01
7 30.76 500.0 3606.77
8 36.07 500.0 4142.84
9 41.43 500.0 4684.26
10 46.84 500.0 5231.11
11 52.31 500.0 5783.42
12 57.83 500.0 6341.25
Savings summary for year
Total amount saved: 500
Total interest earned: 57.8341733327
End of year balance: 6341.2515066
your balance isn't correct, look at this line of code for a solution:
totalInvestBal = totalSavings + totalInterest + totalInvestBal
For your question, the way I'm interpreting it is that you want to have a separate interest-earned value in just the timeframe of a year, after the first year. So the output that I think you want for year 2 is (assuming you fix the end of year balances):
Savings Schedule for Year 2 :
Month Interest Amount Balance
1 63.41 500.0 6904.66
2 69.05 500.0 7473.71
3 74.74 500.0 8048.45
4 80.48 500.0 8628.93
5 86.29 500.0 9215.22
6 92.15 500.0 9807.37
7 98.07 500.0 10405.45
8 104.05 500.0 11009.5
9 110.1 500.0 11619.6
10 116.2 500.0 12235.79
11 122.36 500.0 12858.15
12 128.58 500.0 13486.73
Savings summary for year
Total amount saved: 500
Total interest earned: 70.74733
End of year balance: 13486.7324266
Is that correct?
Related
I'm trying to calculate daily returns using the time weighted rate of return formula:
(Ending Value-(Beginning Value + Net Additions)) / (Beginning value + Net Additions)
My DF looks like:
Account # Date Balance Net Additions
1 9/1/2022 100 0
1 9/2/2022 115 10
1 9/3/2022 117 0
2 9/1/2022 50 0
2 9/2/2022 52 0
2 9/3/2022 40 -15
It should look like:
Account # Date Balance Net Additions Daily TWRR
1 9/1/2022 100 0
1 9/2/2022 115 10 0.04545
1 9/3/2022 117 0 0.01739
2 9/1/2022 50 0
2 9/2/2022 52 0 0.04
2 9/3/2022 40 -15 0.08108
After calculating the daily returns for each account, I want to link all the returns throughout the month to get the monthly return:
((1 + return) * (1 + return)) - 1
The final result should look like:
Account # Monthly Return
1 0.063636
2 0.12432
Through research (and trial and error), I was able to get the output I am looking for but as a new python user, I'm sure there is an easier/better way to accomplish this.
DF["Numerator"] = DF.groupby("Account #")[Balance].diff() - DF["Net Additions"]
DF["Denominator"] = ((DF["Numerator"] + DF["Net Additions"] - DF["Balance"]) * -1) + DF["Net Additions"]
DF["Daily Returns"] = (DF["Numerator"] / DF["Denominator"]) + 1
DF = DF.groupby("Account #")["Daily Returns"].prod() - 1
Any help is appreciated!
Help, How do I turn this into a for loop from range(0, 99) instead of user input?
amount = int(input("enter the amount in cents from 0 to 99: "))
cents = amount
quarters = amount // 25
amount = quarters % 25
dimes = amount // 10
amount = amount % 10
nickels = amount // 5
amount = amount % 5
pennies = amount
print(cents, quarters, dimes, nickels, pennies)
Your current logic has a bug. If you try 99 as the input, the result will be
99 3 0 0 3 ie. 3 quarters and 3 pennies, which is NOT 99 cents.
You're doing a % on quarters instead of amount
If you fix that and then put it in a standard for loop, you'll get the following:
for amount in range(100):
cents = amount
quarters = amount // 25
amount = amount % 25
dimes = amount // 10
amount = amount % 10
nickels = amount // 5
amount = amount % 5
pennies = amount
print(cents, quarters, dimes, nickels, pennies)
The installment amount is calculated by the formula below.
I have a dataframe where I have the principal amount (P), installment amount and number of payments (n) in different columns and I wish to calculate the interest rate (i) for all rows.
Principal (P)
Installment Amount
Number of Installments (n)
Interest Rate (i)
5.300
187
35
r
Given a dataframe called df
>>> df
Principal Installment Num Payments
0 1000.0 40.0 30
1 3500.0 200.0 20
2 10000000.0 2000000.0 10
and a function interest using some solving method (in below example, Newton-Raphson)
ERROR_TOLERANCE = 1e-6
def interest(principal, installment, num_payments):
def f(x):
return principal * x**(num_payments + 1) - (principal + installment) * x**num_payments + installment
def f_prime(x):
return principal * (num_payments + 1) * x**num_payments - (principal + installment)*num_payments * x**(num_payments - 1)
guess = 1 + (((installment * num_payments / principal) - 1)/12)
intermediate = f(guess)
while abs(intermediate) > ERROR_TOLERANCE:
guess = guess - intermediate / f_prime(gues
intermediate = f(guess)
return guess
you can calculate the interest rate like
df['Interest'] = df.apply(lambda row: interest(row['Principal'],row['Installment'],row['Num Payments']),axis=1)
giving
>>> df
Principal Installment Num Payments Interest
0 1000.0 40.0 30 1.012191
1 3500.0 200.0 20 1.013069
2 10000000.0 2000000.0 10 1.150984
Note: tweak ERROR_TOLERANCE as desired to meet requirements.
I am working on a project for my thesis, which has to do with the capitalization of Research & Development (R&D) expenses for a data set of companies that I have.
For those who are not familiar with financial terminology, I am trying to accumulate the values of each year's R&D expenses with the following ones by decaying its value (or "depreciating" it) every time period.
I was able to apply the following code to get the gist of the operation:
df['rd_capital'] = [(df['r&d_exp'].iloc[:i] * (1 - df['dep_rate'].iloc[:i]*np.arange(i)[::-1])).sum() for i in range(1,len(df)+1)]
However, there is a major flaw with this method, which is that it continues to take away the depreciation rate once the value has reached zero, therefore going into negative territory.
For example if we have Apple's R&D expenses for 5 years at a constant depreciation rate of 20%, the code above gives me the following result:
year r&d_exp dep_rate r&d_capital
0 1999 10 0.2 10
1 2000 8 0.2 16
2 2001 12 0.2 24.4
3 2002 7 0.2 25.4
4 2003 15 0.2 33
5 2004 8 0.2 30.6
6 2005 11 0.2 29.6
However, the value for the year 2005 is incorrect as it should be 31.6!
If it was not clear, r&d_capital is retrieved the following way:
2000 = 10*(1-0.2) + 8
2001 = 10*(1-0.4) + 8*(1-0.2) + 12
2002 = 10*(1-0.6) + 8*(1-0.4) + 12*(1-0.2) + 7
2003 = 10*(1-0.8) + 8*(1-0.6) + 12*(1-0.4) + 7*(1-0.2) + 15
the key problem comes here as the code above does the following:
2004 = 10*(1-1) + 8*(1-0.8) + 12*(1-0.6) + 7*(1-0.4) + 15*(1-0.2) + 8
2005 = 10*(1-1.2) + 8*(1-1) + 12*(1-0.8) + 7*(1-0.6) + 15*(1-0.4) + 8*(0.2) + 11
Instead it should discard the values once the value reaches zero, just like this:
2004 = 8*(1-0.8) + 12*(1-0.6) + 7*(1-0.4) + 15*(1-0.2) + 8
2005 = 12*(1-0.8) + 7*(1-0.6) + 15*(1-0.4) + 8*(0.2) + 11
Thank you in advance for any help that you will give, really appreciate it :)
A possible way would be to compute the residual part for each investment. The assumption is that there a finite and known number of years after which any investment is fully depreciated. Here I will use 6 years (5 would be enough but it demonstrates how to avoid negative depreciations):
# cumulated depreciation rates:
cum_rate = pd.DataFrame(index = df.index)
for i in range(2, 7):
cum_rate['cum_rate' + str(i)] = df['dep_rate'].rolling(i).sum().shift(1 - i)
cum_rate['cum_rate1'] = df['dep_rate']
cum_rate[cum_rate > 1] = 1 # avoid negative rates
# residual values
resid = pd.DataFrame(index = df.index)
for i in range(1, 7):
resid['r' + str(i)] = (df['r&d_exp'] * (1 - cum_rate['cum_rate' + str(i)])
).shift(i)
# compute the capital
df['r&d_capital'] = resid.apply('sum', axis=1) + df['r&d_exp']
It gives as expected:
year r&d_exp dep_rate r&d_capital
0 1999 10 0.2 10.0
1 2000 8 0.2 16.0
2 2001 12 0.2 24.4
3 2002 7 0.2 25.4
4 2003 15 0.2 33.0
5 2004 8 0.2 30.6
6 2005 11 0.2 31.6
You have to keep track of the absolute depreciation and stop depreciating when the asset reaches value zero. Look at the following code:
>>> exp = [10, 8, 12, 7, 15, 8, 11]
>>> dep = [0.2*x for x in exp]
>>> cap = [0]*7
>>> for i in range(7):
... x = exp[:i+1]
... for j in range(i):
... x[j] -=(i-j)*dep[j]
... x[j] = max(x[j], 0)
... cap[i] = sum(x)
...
>>> cap
[10, 16.0, 24.4, 25.4, 33.0, 30.599999999999998, 31.6]
>>>
In the for loops I calculate for every year the remaining value of all assets (in variable x). When this reaches zero, I stop depreciating. That is what the statement x[j] = max(x[j], 0) does. The sum of the value of all assets is then stored in cap[i].
I am trying to produce output from .csv file as a table with column headers. I am trying to display as table with frequencies calculated. so far i can calculate frequencies with this code:
import pandas
d = pandas.read_csv('gapminder.csv', low_memory=False)
d['urbanrate'] = d['urbanrate'].convert_objects(convert_numeric=True)
print ('Count Urban rate')
c = d.groupby('urbanrate').size()
print (c)
print ('Urban rate percentage')
f = d.groupby('urbanrate').size() * 100/len(d)
print (f)
and the output is like:
Count Urban rate
urban rate
10.40 1
12.54 1
12.98 1
But i would like to have have columns like:
Rate Count
10.40 1
.. ..
Thanks
You can set the column names:
f.columns = ['Rate', 'Count']
print(f)
prints:
Rate Count
0 10.40 1
1 12.54 1
2 12.98 1
If you don't like to see the index:
print(f.to_string(index=False))
prints:
Rate Count
10.40 1
12.54 1
12.98 1