Control flow python - python

Actually I am used to c++ and I am stuck in python. I can't seem to understand what's causing the infinite while loop.
The main goal of the code is to calculate how many months are required to save enough money for upfront payment.
#*******Initializing all the required variables***********
home_price = float(input("Enter the price of your dream home:")) # cost of the home
down_payment_portion = 0.25 # initial upfront pay for the home which is 25%
stamp_duty_portion = 0.03 # 3%
annual_salary = float(input("Enter your annual salary:"))
tax_portion = 0.2 # 20%
save_amount = 0
save_portion = float(input("Enter the amount of money you want to save after tax-cut:"))
annual_return = 0.05 # 5%
months = 0
#*********************************************************
#------------Calculating all the necessary values---------
down_payment_portion = down_payment_portion * home_price # calculating the down payment for the dream home
stamp_duty_portion = stamp_duty_portion * home_price # calculating the stamp duty for the home
tax_portion = tax_portion * annual_salary # calculating the tax cut
save_portion = save_portion * save_amount # calculating the portion of tax-cut income to be put into savings
annual_return = (save_amount * annual_return) / 12
upfront_payment = down_payment_portion + stamp_duty_portion
while(save_amount < upfront_payment):
save_amount = save_amount + annual_return
save_amount = save_amount + (annual_salary - tax_portion) * save_portion / 12
months = months + 1
print(f'You will need {months} month to save enough for your upfront payment{upfront_payment}.')

You initialise save_amount = 0
you get annual_return as annual_return = (save_amount * annual_return) / 12 which would be zero
you also get save_portion as save_portion = save_portion * save_amount which is again zero
Therefore your save_amount in the while loop is never incremented it too remains zero, save_amount < upfront_payment is always true ==> Infinite loop
In your code
while(save_amount < upfront_payment):
save_amount = save_amount + annual_return # 0 + 0 = 0
# 0 + (some value * 0)/12 = 0
save_amount = save_amount + (annual_salary - tax_portion) * save_portion / 12

Related

What is wrong with this while loop, it seems not ending as the print statement ager it is not executed

I am an absolute beginner in programming (just started yesterday and my major is not CS). I have been struggling with this while loop as I don't know why this print statement is not executed(sometimes it prints as "1"). Please tell me where is wrong. Thanks, guys.
current_saving = 0
# This program intends to calculate the how many months the down
# portion can be paid
annual_input = int(input("Enter your annual salary:"))
portion_saved = float(
input("Enter the percent of your salary to save, as a decimal:"))
total_cost = int(input("Enter the cost of your dream home:"))
portion_down_payment = total_cost * 0.25
months = 0
while current_saving <= portion_down_payment:
current_saving = annual_input / 12 * portion_saved + current_saving * 0.04 / 12
months = months + 1
print(months)
Modify the code to accumulate savings.
current_saving = 0
# This program intends to calculate the how many months the down
# portion can be paid
annual_input = int(input("Enter your annual salary:"))
portion_saved = float(
input("Enter the percent of your salary to save, as a decimal:"))
total_cost = int(input("Enter the cost of your dream home:"))
portion_down_payment = total_cost * 0.25
months = 0
while current_saving <= portion_down_payment:
# Accumulate savings
current_saving = current_saving + annual_input / 12 * portion_saved + \
current_saving * 0.04 / 12
print(f'{current_saving=}') # Comment out this line to not print the accumulation
months = months + 1
print(months)
Test Reults
Enter your annual salary:5000
Enter the percent of your salary to save, as a decimal:.5
Enter the cost of your dream home:10000
current_saving=208.33333333333334
current_saving=417.36111111111114
current_saving=627.0856481481482
current_saving=837.5092669753087
current_saving=1048.6342978652262
current_saving=1260.4630788581103
current_saving=1472.9979557876372
current_saving=1686.2412823069292
current_saving=1900.195419914619
current_saving=2114.862737981001
current_saving=2330.245613774271
current_saving=2546.3464324868523
12

Working on a problem to find the lowest number at which we can pay off debt in a year. Answer is a bit off

I am taking a course on edx and trying to solve a problem using bisection to calculate a monthly payment at which we can pay off the debt in a year. I have coded a solution but the results are a bit off than expected. Code is below. Answer code shared by edx is also listed beneath. Can you please share why my code is not giving same results? I am trying to get to to 2 decimal places accuracy.
balance=float(input('balance = '))
annualInterestRate=float(input('annualInterestRate = '))
remainingbalance=balance
low=float(remainingbalance/12)
high=float(remainingbalance*((1+(annualInterestRate/12))**12)/12.0)
if remainingbalance>0.01 or remaningbalance<0.01:
remainingbalance=balance
increment=round(float((high+low)/2), 2)
for i in range(1, 13):
unpaidbalance=remainingbalance-increment
interest=(annualInterestRate/12) * unpaidbalance
remainingbalance=round(unpaidbalance + interest, 2)
if remainingbalance>0.01:
low=increment
elif remainingbalance<-0.01:
high=increment
print('Lowest Payment: ', increment)
Sample code for solution provided by edx
init_balance = balance
monthlyInterestRate = annualInterestRate/12
lower = init_balance/12
upper = (init_balance * (1 + monthlyInterestRate)**12)/12.0
epsilon = 0.03
while abs(balance) > epsilon:
monthlyPaymentRate = (upper + lower)/2
balance = init_balance
for i in range(12):
balance = balance - monthlyPaymentRate + ((balance - monthlyPaymentRate) * monthlyInterestRate)
if balance > epsilon:
lower = monthlyPaymentRate
elif balance < -epsilon:
upper = monthlyPaymentRate
else:
break
print('Lowest Payment:', round(monthlyPaymentRate, 2))
My Code Results:
balance = 320000
annualInterestRate = 0.2
Lowest Payment: 29591.88
Edx Results:
balance = 320000
annualInterestRate = 0.2
Lowest Payment: 29157.09

Calculating returns with trading costs

This perhaps is an over simplification of calculating trading returns while including trading costs. I've made some assumptions - the commission for investing and extracting an investment is 1% and 2% respectively. The commissions do not change over the trading period which in this case is 5 time steps. I've used Python code to perform the calculations.
Set of positive and negative percentage changes in price for a given asset over 5 time steps is {0.031% , 0.00121% , 0.0231% , -0.0213% , -0.0121%}.
The commission to enter an investment is 1% of the invested amount, the commission to exit an investment is 2% of the current value of the invested amount.
If I invest 1 euro in this asset, is the following correct?
1.
The final investment amount if I do not trade the investment until $t=5$ is:
the final percentage change amount at $t=5$ which is 'initial invested amount' + '% change' - 'commission to enter' - 'commission to exit', therefore:
initial_investment_amt = 1
comission_in_amt = 1
comission_out_amt = 2
price_change = -.0121
return_amt = (initial_investment_amt + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100) = 0.97 which represents a loss of 1 - .97 = .03
2.
The final investment amount if I trade the investment at each time step until $t=5$ is:
initial_investment_amt = 1
comission_in_amt = 1
comission_out_amt = 2
price_change = .031
return_amt_1 = (initial_investment_amt + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100)
price_change = .00121
return_amt_2 = (return_amt_1 + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100)
price_change = .0231
return_amt_3 = (return_amt_2 + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100)
price_change = -.0213
return_amt_4 = (return_amt_3 + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100)
price_change = -.0121
return_amt_5 = (return_amt_4 + (price_change / 100)) - (comission_in_amt / 100) - (comission_out_amt / 100)
print(return_amt_1)
print(return_amt_2)
print(return_amt_3)
print(return_amt_4)
print(return_amt_5)
prints :
0.97031
0.9403220999999999
0.9105530999999999
0.8803400999999998
0.8502190999999998
which represents a loss of $1 - 0.85 = 0.15$.
First, I have to respectfully disagree with your conclusion for case 1:
The final investment amount if I do not trade the investment until $t=5$ is: the final percentage change amount at $t=5$ which is 'initial invested amount' + '% change' - 'commission to enter' - 'commission to exit
The correct formula for the final value, I believe, is
((initial investment amount - commission to enter) * (1 + % change)) - commission-to-exit.
The main difference being the fact that the commission to enter/investment fee is taken out of circulation before the return on investment can be earned. This makes for a significant difference over time.
Assuming I'm correct, below is the code I propose. I took the liberty of changing some of the terminology for ease of reference, but you can obviously change it to whatever suits you:
p_changes = [0.03100, 0.00121, 0.02310, 0.02130, -0.01210]
initial_investment_amt = 100 #I used a larger initial investment; otherwise, the fees would have eaten you alive...
invest_fee = 1
sell_fee = 2
def periodic_ret(amount,change,reinv):
if reinv == 0:
if ind + 1 == 1: #for the initial period
forward = (amount-invest_fee)*(1+change)
if ind +1 == len(p_changes): #for the final period
forward = (amount*(1+change))-sell_fee
else:
forward = (amount*(1+change))
else:
forward = (amount-invest_fee)*(1+change)-sell_fee
print(forward)
return forward
for i in range(len(p_changes)):
reinv = 1 #1 if an invest and sell fee are paid each period, or 0, if an invest fee is paid once upfront and sell fee is paid once at the end
if i == 0: #for the initial period
cur = periodic_ret(initial_investment_amt, p_changes[0], reinv)
else:
cur = periodic_ret(cur,p_changes[i], reinv)
Output (w/ reinv = 1):
100.06899999999999
97.18887348999998
96.41083646761896
95.44308728437926
91.30032592823827
Both the commissions and price changes are given as percentages. This means that immediately after investment the amount in the account is:
initial_investment_amt*(1-commission_in_amt/100)
The _amt suffix is perhaps confusing but commission is stated as % in the question.
After the first investment period the account has the amount:
initial_investment_amt*(1-commission_in_amt/100)*(1-price_change/100)
And finally after exit the client receives:
initial_investment_amt*(1-commission_in_amt/100)(1-price_change/100)(1-commission_out_amt/100)
I think the pattern is clear so you just insert more price_changes for a lengthier investment and if you disinvest and reinvest you'll have a lot more commission to pay.
Hope this is OK - sorry no code - but it seems clearer like this and uses the question notation.

Calculate change from paid amount

Why is this code creating an infinite loop? I would think this should be an appropriate solution for this type of problem. For example, if the price was $5 and you paid $5.47, the program would print:
Quarters: 1
Dimes: 2
Nickels: 0
Pennies: 2
However, an infinite loop occurs and I'm not sure why. Anyone know the reason?
price = round(float(input("Enter the price: ")), 2)
print price
paid = round(float(input("Enter the amount paid: ")), 2)
print paid
change = round(float(paid - price), 2)
print change
quarters = 0
dimes = 0
nickels = 0
pennies = 0
while change > 0.00:
print change
if change >= .25:
change = change - .25
quarters += 1
continue
elif change >= .1:
change = change - .1
dimes += 1
continue
elif change >= .05:
change = change - .05
nickels += 1
elif change >= .01:
change = change - .01
pennies += 1
print "Quarters: " + str(quarters)
print "Dimes: " + str(dimes)
print "Nickels: " + str(nickels)
print "Pennies: " + str(pennies)
Rather than dealing with loops, I would suggest just subtracing off the change that you already gathered, prioritizing larger coins.
price = float(input("Enter the price: "))
paid = float(input("Enter the amount paid: "))
change = paid - price
if change < 0:
raise ValueError('Not enough paid')
quarters = change // 0.25
dimes = (change - (0.25 * quarters)) // 0.10
nickels = (change - (0.25 * quarters) - (0.10 * dimes)) // 0.05
pennies = 100 * (change - (0.25 * quarters) - (0.10 * dimes) - (0.05 * nickels))
print("Quarters: {:.0f}".format(quarters))
print("Dimes: {:.0f}".format(dimes))
print("Nickels: {:.0f}".format(nickels))
print("Pennies: {:.0f}".format(pennies))
There's one minor bug in the code which causes the program to only work correctly if price and amount paid are interchanged (e.g. price = 2, paid = 1). But that is not the issue causing the infinite loop.
Your code creates an infinite loop for e.g. the following arguments:
price: 5.6
paid: 5.4
The reason for the infinite loop can be seen from your own print output:
0.009999999999999275
0.009999999999999275
0.009999999999999275
0.009999999999999275
0.009999999999999275
0.009999999999999275
0.009999999999999275
...
Since change < 0.01, no if clause applies and thus the loop is never left.
How could you solve the problem more robustly?
Here's a sketch
from math import floor
change = paid - price
quarters = int(floor(change / 0.25))
change -= quarters * 0.25
dimes = int(floor(change / 0.1))
change -= dimes * 0.1
nickels = int(floor(change / 0.05))
change -= nickels * 0.05
pennies = int(floor(change / 0.01))
change -= pennies * 0.01
remaining = change
print("Quarters:", quarters)
print("Dimes:", dimes)
print("Nickels:", nickels)
print("Pennies:", pennies)
Personally I would also condense this into a loop over the coin type:
increments = {"quarter":0.25, "dimes": 0.1, "nickels": 0.05, "pennies": 0.01}
change_parts = {}
for inc_name, inc in increments.items():
amount = int(floor(change / inc))
print(inc_name, inc, amount)
change -= amount * inc
change_parts[inc_name] = amount
for inc_name, amount in change_parts.items():
print(inc_name + ":", amount)

Why is string not recognizing my output as an integer

balance = int(100)
balance *= 0.05 + balance
balance *= 0.05 + balance
balance *= 0.05 + balance
print (int(round ( balance, '.2f' )))
im trying to calculate what 100$ interest would be after 3 years compound interest.
I originally tried this
balance = 100
balance *= 0.05 + balance
balance *= 0.05 + balance
balance *= 0.05 + balance
print (format( balance, '.2f' ))
but my formatting caused the answer to be in the trillions instead of a 5 digit float.
You're multiplying the balances. Try this:
balance = int(100)
balance = balance * 0.05 + balance
balance = balance * 0.05 + balance
balance = balance * 0.05 + balance
print("{:.02f}".format(balance))
You have your operator precedence incorrect: the assignment operator is last. Thus, what you've done is
balance = balance * (0.05 + balance)
Instead, try one of the canonical ways to express interest:
rate = 0.05
balance += balance * rate
or
balance *= (1 + rate)
The parentheses aren't needed, but will help you read this.
Also, you might make a parameter (variable) for your repetition:
limit = 3
for year in range(limit):
balance *= 1 + rate
print("{:.02f}".format(balance))
You should pay attention to order of operations. balance *= 0.05 + balance will add 0.05 and balance before multiplying it to balance. What you'd want is balance = balance + balance * 0.05 or balance = balance * 1.05.
You can create a function to calculate compound interest to make it easier:
def comp_int(balance, rate, years):
return balance * (1 + rate)**years
balance = 100
rate = 0.05
years = 3
new_bal = comp_int(balance, rate, years)
print(f'{new_bal:.2f}')

Categories

Resources