I have a monthly budget code that shows the user if they are over/under the budget for a certain month. I am having trouble breaking the code up into def functions. here is what I have
print("""\
This program uses a for loop to monitor your budget.
The program will prompt you to enter your budget, and amount spent
for a certain month and calculate if your were under or over budget.
You will have the option of choosing how many months you would like to
monitor.\n""")
AmountSpent = 0
Budget = 0
numMonths = int(input("Enter the number of months you would like to monitor:"))
while numMonths<0:
print("\nNegative value detected!")
numMonths = int(input("Enter the number of months you would like to monitor"))
for month in range(1,numMonths+1):
print("\n=====================================")
AmountBudgeted = float(input(f"Enter amount budgeted for month {month}:"))
while AmountBudgeted<0:
print("Negative value detected!")
AmountBudgeted = float(input(f"Enter amount budgeted for month {month}:"))
AmountSpent = float(input(f"Enter amount spent for month {month}:"))
while AmountSpent<0:
print("Negative value detected!")
AmountSpent = float(input(f"Enter amount spent for month {month}:"))
if AmountSpent <= AmountBudgeted:
underB = AmountBudgeted - AmountSpent
print(f"Good Job! You are under budget by {underB}")
else:
overB = AmountSpent - AmountBudgeted
print(f"Oops! You're over budget by {overB}")
if month == "1":
print(f'your budget is {AmountBudgeted}.')
Can anyone help me break this code up into functions using "def" and other functions like "Describeprogram()" and "GetMonths()" ?
You could extract the user interaction like
def get_nb_months():
value = int(input("Enter the number of months you would like to monitor:"))
while value < 0:
print("Negative value detected!")
value = int(input("Enter the number of months you would like to monitor"))
return value
But then you notice that they're quite the same methods, so you can generalize:
def get_amount(msg, numeric_type):
value = numeric_type(input(msg))
while value < 0:
print("Negative value detected!")
value = numeric_type(input(msg))
return value
def summary(spent, budget):
diff = abs(budget - spent)
if spent <= budget:
print(f"Good Job! You are under budget by {diff}")
else:
print(f"Oops! You're over budget by {diff}")
if __name__ == "__main__":
numMonths = get_amount("Enter the number of months you would like to monitor:", int)
for month in range(1, numMonths + 1):
print("\n=====================================")
amount_budgeted = get_amount(f"Enter amount budgeted for month {month}:", float)
amount_spent = get_amount(f"Enter amount spent for month {month}:", float)
summary(amount_spent, amount_budgeted)
Related
I need the loop to stop at 12 months and not count all the way up to how many months it takes to reach the goal. I just need it to print how many months it takes to reach the goal but not count all the way to it. I only need it to go up to 12 months. For example if I input an original deposit for 1000, 4.5 interest rate, 12 months, and 1200 goal amount then I want it to only show it counting to 12 months not 49. I still need it to print out how many months it takes to reach the goal at the end but I do not need it to show it counting all the way up to 49. I am sorry if this sounds confusing.
#Keep asking until the user puts in a positive numeric value using loops
fDeposit = 0
while fDeposit <= 0:
try:
fDeposit = float(input('What is the original deposit (positive value): '))
if fDeposit <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
fInterest = 0
while fInterest <= 0:
try:
fInterest = float(input('What is the Interest Rate (positive value): '))
if fInterest <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
iMonths = 0
while iMonths <= 0:
try:
iMonths = int(input('What is the number of months (positive value): '))
if iMonths <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
fGoal = None
while fGoal == None:
try:
fGoal = float(input('What is the goal amount (Can enter 0 but not negative): '))
if fGoal < 0:
print("Input must be a positive numerical value: ")
fGoal = None
except ValueError:
print("Input must be a numeric value")
# Calculate Interest. First convert the variable to a decimal by dividing by 100 then divide
that by 12
fMonthlyInterest= (fInterest/100/12)
#Output the number of months the user has supplied and get account balance
i = 1
fAccountBalance = fDeposit
while i <= fAccountBalance:
if fAccountBalance >= fGoal:
break
fInterestForMonth = (fAccountBalance * fMonthlyInterest)
#Add the interest for the month to the deposit to get the new Account Balance
fAccountBalance += fInterestForMonth
print('Month: ',i, 'Account Balance is: $',format(fAccountBalance, ",.2f"))
i += 1
# Calculate how many months it will take of compounding to reach the goal amount
GoalFormatted = "{:.2f}".format(fGoal)
CompoundedSavingsAccountBalance = fMonthlyInterest + fAccountBalance
while CompoundedSavingsAccountBalance < fGoal:
iMonths += 1
print('It will take: ',i-1, 'months to reach the goal of $', GoalFormatted)
to solve your problem, add "if i < 12:" after line 52, and indent the next line where you printing the month & the account balance. The completed section is below.
i = 1
fAccountBalance = fDeposit
while i <= fAccountBalance:
if fAccountBalance >= fGoal:
break
fInterestForMonth = (fAccountBalance * fMonthlyInterest)
#Add the interest for the month to the deposit to get the new Account Balance
fAccountBalance += fInterestForMonth
if i <= 12:
print('Month: ',i, 'Account Balance is: $',format(fAccountBalance, ",.2f"))
i += 1
My program is supposed to tell users how many months it will take to double the money in their investment account. I am able to do the calculations correctly, but I'm unable to break out of the loop and print the statement that tells the user the final sentence "It will take x months to double your investment with a y% return".
balance = int(input("Enter an initial Roth IRA deposit amount:"))
apr = int(input("Enter an annual percent rate of return:"))
month = 0
while balance != 2*balance:
added_interest = balance * (apr / 100) / 12
balance = balance + added_interest
month +=1
formatted_balance = "${:.2f}".format(balance)
print("Value after month", month,":", formatted_balance)
if balance == 2*balance:
break
print("It will take", month, "months to double your investment with a", apr, "% return")
Your problem is that testing balance against 2*balance is always testing the current balance, not double the initial balance. Just store off the computed doubled balance initially, and test if the current balance is still less than that (no need for separate if/break, your while condition will handle it):
balance = int(input("Enter an initial Roth IRA deposit amount:"))
apr = int(input("Enter an annual percent rate of return:"))
month = 0
doubled_balance = 2 * balance # Store off doubled initial balance
while balance < doubled_balance: # Check current balance against doubled initial,
# and use <, not !=, so you stop when you exceed it,
# not just when you're exactly equal
added_interest = balance * (apr / 100) / 12
balance = balance + added_interest
month +=1
formatted_balance = "${:.2f}".format(balance)
print("Value after month", month,":", formatted_balance)
# No need for if/break
print("It will take", month, "months to double your investment with a", apr, "% return")
All that said, this doesn't need a loop at all. The initial balance doesn't matter (it takes just as long to double $1 as to double $1000 with a fixed rate of return, ignoring rounding errors), so this reduces to a simple conversion for APR to APY to account for monthly compounding, followed by a logarithm computation to figure out what power of the APY is necessary to reach 2 (a doubling), then convert from months to years and round up (since you won't double until the end of that month):
import math
apr = int(input("Enter an annual percent rate of return:"))
apr_decimal = apr / 100
apy = (1 + (apr_decimal / 12)) ** 12 # Standard APR to APY computation for monthly compounding
months = math.ceil(math.log(2, apy) * 12) # Compute the power (years) of APY to double the investment
# then multiply by 12 and round up to a full month
print("It will take", months, "months to double your investment with a", apr, "% return")
In your comparison you compared balance with 2*balance. Obviously balance == 2*balance will always be false, if balance > 0. So your code is stuck there forever if someone plans to invest anything more than $0.
You need a new variable to store the updated balance with rate of return:
# assuming you have balance and apr set
newBalance = balance # balance + returned amount
month = 0
while newBalance < 2*balance:
# replace ! with <, so that loop breaks when newBalance >= 2*balance
added_interest = newBalance * (apr / 100) / 12
newBalance = newBalance + added_interest
month +=1
formatted_balance = "${:.2f}".format(newBalance)
print("Value after month", month,":", formatted_balance)
The code above assumes that the added interest is calculated based on newBalance value. Please tell me if this does not work for you. I will debug it later.
Perhaps a little bit simpler solution.
from math import log, ceil
apr = int(input("Enter an annual percent rate of return: "))
rate = apr/12/100 # monthly rate
months = ceil(log(2)/rate)
print("It will take", months, "months to double your investment with a", apr, "% return")
prints:
Enter an annual percent rate of return: 10
It will take 84 months to double your investment with a 10 % return
This was calculated using the formula for continuous compounding. With a FV (future value) = PV (present value) * e**(rate * periods).
FV = PV * e**(rate*periods)
FV/PV = e**(rate*periods)
log(FV/PV) = log(e**(rate*periods))
log(FV/PV) = (rate*periods) * log(e)
log(FV/PV) = (rate*periods) * 1
log(FV/PV)/rate = periods
Since you want to find the months to double your initial investment, FV/PV will equal 2, so:
log(2)/rate = periods. (The log(e) == 1 above)
e and compound interest is defined here.
I have a question where im asked to calculate interest rate of an account after asking user for:
P is the present value of the account.
i is the monthly interest rate.
t is the number of months.
The current code I have is this:
def get_value(p, i , t):
return p * (1 + i) ** t
def main():
p = float(input("Please enter the current amount of money in your account: "))
i = float(input("Please enter the monthly interest rate: "))
t = float(input("Please enter the number of months: "))
#the while loop would probably go here, but I just dont know how to do it#
future_total = get_value(p, i, t)
print ("\nAfter", t, "months, you will have $", format(future_total, ".2f"), "in your account.")
main()
But the output is only giving me the final amount after 10 months, how do I implement a loop in order to see how much money would be in the account since month 1?
I would first make a variable called month and set it equal to 1. Then I would use the while loop so that when the month is less than the inputted month, the present value will be updated based on the inputted information. This will print out the money in the account for each month and not just the final value.
def get_value(p, i , t):
month = 1
while month <= t:
p = p * (1 + i)
print(month, p)
month += 1
def main():
p = float(input("Please enter the current amount of money in your account: "))
i = float(input("Please enter the monthly interest rate: "))
t = float(input("Please enter the number of months: "))
print(get_value(p,i,t))
# future_total = get_value(p, i, t)
# print ("\nAfter", t, "months, you will have $", format(future_total, ".2f"), "in your account.")
# print(f'After {t} months, you will have ${future_total} in your account.')
main()
I'm learning python on my own from a book and solving problems. In one problem, the user inputs amount of rain for each month in one year across a period of years. I need to find the average of rain in each year (sum(monthly rain)/numb_months, and also the average of rain in that period, e.g. in two years. In the following code, I can get the average for each year (I used 3 months only instead of 12 months to avoid tedious input now), but I don't know where I need to put an accumulator for total rain in that period and then average it. I appreciate your help.
number_of_months = 3
years_in_period = int(input("Please enter the number of years in the period. \n"))
for year in range(years_in_period):
yearly_rain = 0
print('Year', year+1)
print('−−−−−−−−−−−−−−−−−')
for month in range(number_of_months):
print('Month', month+1, end='')
monthly_rain = float(input("Please enter rainfall for this month: \n"))
yearly_rain += monthly_rain
average_yearly_rainfall = yearly_rain / number_of_months
print("Average yearly rainfall of year ", year+1, " is ", average_yearly_rainfall)
print("Year total rain is", yearly_rain)
print()
If I understood what you want (to calculate the absolute average of the rain amount during the period), this should do the trick:
number_of_months = 3
years_in_period = int(input("Please enter the number of years in the period. \n"))
total_rain = 0
for year in range(years_in_period):
yearly_rain = 0
print('Year', year+1)
print('−−−−−−−−−−−−−−−−−')
for month in range(number_of_months):
print('Month', month+1, end='')
monthly_rain = float(input("Please enter rainfall for this month: \n"))
yearly_rain += monthly_rain
total_rain += monthly_rain
average_yearly_rainfall = yearly_rain / number_of_months
print("Average yearly rainfall of year ", year+1, " is ", average_yearly_rainfall)
print("Year total rain is", yearly_rain)
print()
total_months = years_in_period * number_of_months
print("Absolute average of rain/month was", total_rain/total_months)
print("Absolute average of rain/year was", total_rain/years_in_period)
I wanted the result to show the total amount of money after adding interest every year but it only increases the year but not the amount. Why?
while True:
try:
investment = float(input('How much to invest : '))
interest = float(input('Interest rate : '))
break
except ValueError:
"Please enter a valid number"
for year in range(10):
money = investment + (investment * interest)
print("Total money in year {} : {}".format((year+1), money))
It sounds like you need to accrue the interest:
for year in range(10):
investment += (investment * interest)
print("Total money in year {} : {}".format((year + 1), investment))
Logical error. Your investment variable does not be assigned each round in the loop.