Reset and create variables before FOR loop in a WHILE loop - python

I came across a MIT open source Python coding practice as
Suppose you want to be able to afford the down payment in three years. How much should you save each month to achieve this? In this problem, you are going to write a program to answer that question. To simplify things, assume:
1. Your semi-annual raise is .07 (7%)
2. Your investments have an annual return of 0.04 (4%)
3. The down payment is 0.25 (25%) of the cost of the house.
4. The cost of the house that you are saving for is $1M.
You are now going to try to find the best rate of savings to achieve a down payment on a $1M house in 36 months. Since hitting this exactly is a challenge, we simply want your savings to be within $100 of the required down payment. Write a program to calculate the best savings rate, as a function of your starting salary. You should use [bisection search] to help you do this efficiently. You should keep track of the number of steps it takes your bisections search to finish. Limit floats to two decimals of accuracy (i.e., we may want to save at 7.04% - or 0.0704 in decimal - but we are not going to worry about the delta between 7.041% and 7.039%). This means we can search for an integer between 0 and 10000 (using integer division), and then convert it to a decimal percentage (using float division) to use when we are calculating the current_savings after 36 months. Using this range gives us only a finite number of numbers that we are searching over, as opposed to the infinite number of decimals between 0 and 1. This range will help prevent infinite loops. The reason we use 0 to 10000 is to account for two additional decimal places in the range 0% to 100%. Your code should print out a decimal (e.g. 0.0704 for 7.04%).
Keep in mind that it may not be possible to save on a down payment in a year and a half for some salaries. In this case your function should notify the user that it is not possible to save for the down payment in 36 months with a print statement.
EXAMPLE OUTPUTEnter the starting salary: 150000Best savings rate: 0.4411Steps in bisection search: 12
The following is one of the solutions that I found.
# user input
annual_salary = float(input('Enter your annual salary: '))
# static variables and initializers
semi_annual_raise = 0.07
r = 0.04
portion_down_payment = 0.25
total_cost = 1000000
steps = 0
current_savings = 0
low = 0
high = 10000
guess_rate = (high + low)//2
# Use a while loop since we check UNTIL something happens.
while abs(current_savings - total_cost*portion_down_payment) >= 100:
# Reset current_savings at the beginning of the loop
current_savings = 0
# Create a new variable for use within the for loop.
for_annual_salary = annual_salary
# convert guess_rate into a float
rate = guess_rate/10000
# Since we have a finite number of months, use a for loop to calculate
# amount saved in that time.
for month in range(36):
# With indexing starting a zero, we need to calculate at the beginning
# of the loop.
if month % 6 == 0 and month > 0:
for_annual_salary += for_annual_salary*semi_annual_raise
# Set monthly_salary inside loop where annual_salary is modified
monthly_salary = for_annual_salary/12
# Calculate current savings
current_savings += monthly_salary*rate+current_savings*r/12
# The statement that makes this a bisection search
if current_savings < total_cost*portion_down_payment:
low = guess_rate
else:
high = guess_rate
guess_rate = (high + low)//2
steps += 1
# The max amount of guesses needed is log base 2 of 10000 which is slightly
# above 13. Once it gets to the 14th guess it breaks out of the while loop.
if steps > 13:
break
# output
if steps > 13:
print('It is not possible to pay the down payment in three years.')
else:
print('Best savings rate:', rate)
print('Steps in bisection search:', steps)
Why is it necessary to reset variable value current_savings and to create a for_annual_salary before the FOR loop? The current_savings has already been defined as 0 at the beginning, and why does it creates a brand new variable for_annual_salary instead of using annual_salary in FOR loop?

If you don't assign annual_salary to a variable and your loop changed the value of it then you can access its previous value which user entered.
eg:
annual_salary = input("Enter salary")
annual_salary = 10000 + 1000
print(annual_salary ) #would give you 11000, And you got some bug in your code and you want to debug what user entered the salary.
You print("annual_salary") #And you get updated salary not what user entered.
If you created a variable like below:
annual_salary = input("Enter salary")
new_annual_salary = 10000 + 1000 # some operations
print(new_annual_salary ) #Every operation was performed on new variable and if code goes wrong somewhere,you still can find new and old value of annual_salary.
print(annual_salary)
Same for current_savings
And you need to set those variables to initially 0 because when you performing operation you need to provide some number/initial value.
c = 0
for i in range(3):
c+= i
print(c) # You will get 3 not 0
d #If you don't initialize your value and performing operations you'll get undefined error
d+= 1
print(d)
NameError: name 'd' is not defined

Related

Finding the right amount to save away

I am currently learning python and as a little test a friend of mine gave me a problem from the MIT open courseware python course. However, I am struggling on part C of the problem. It requires that you use a binary search to find the right amount you need to save if you want to buy a house in 3 years given a starting salary.
Here is the problem pdf for further details (scroll to part C):
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/assignments/MIT6_0001F16_ps1.pdf
I have technically "solved" it and am able to find the correct value according to the test cases given but the percents have many digits and the amount of bisection searches counted is much higher than that of the test cases.
I was wondering if there is actually anything wrong with my code and if I am implementing the binary search correctly with regards to this problem.
Example test cases:
Test Case 1:
Enter the starting salary:​ 150000
Best savings rate:​ 0.4411
Steps in bisection search:​ 12
MY RESULTS:
Enter the starting salary:​ 150000
Best savings rate:​ 0.4411391177390328
Steps in bisection search:​ 40
Thanks for any help!
Apologies in advance for this question I am still learning ;P
My Code:
annual_salary = float(input('Enter the starting salary: '))
constant = annual_salary
semi_annual_rate = 0.07
r = 0.04
down_payment = 0.25
total_cost = 1000000
current_savings = 0
months = 0
bisection_count = 0
min = 0
max = 1
portion_saved = (max/2.0)/1000
if(annual_salary*3<down_payment*total_cost):
print('It is not possible to pay the down payment in three years.')
while(True):
while(months<36):
current_savings += (current_savings*r/12)+(portion_saved*(annual_salary/12))
months+=1
if(months % 6 == 0):
annual_salary += annual_salary*semi_annual_rate
if(current_savings >= down_payment*total_cost+100):
max = portion_saved
portion_saved = max/2.0
bisection_count+=1
months = 0
current_savings = 0
annual_salary = constant
elif(current_savings >= down_payment*total_cost-100 and current_savings <= down_payment*total_cost+100):
break
else:
min = portion_saved
portion_saved = (max+min)/2.0
bisection_count+=1
months = 0
current_savings = 0
annual_salary = constant
print('Best savings rate: ', portion_saved)
print('Steps in bisection search: ', bisection_count)
The line which causes too many iterations is
portion_saved = max/2.0
You should simply do
portion_saved = (max+min)/2.0
as you correctly do some lines below.
Note you're not strictly respecting the assignment since it asks to use int values in the range 0-10000 for portion_saved, not float - in this test case it even comes as a slight advantage because you get 11 iterations instead of 12, but in other cases it may be the other way round. Anyhow if you want to keep using float you may just format the result.
One last, very important thing: please don't use min and max as variable names. You're overwriting two built-in functions, so should you ever need to do min(5,2,7) you would get
TypeError: 'float' object is not callable

Calculating house down payment [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
Using Python 3.6
You have graduated from MIT and now have a great job! You move to the San Francisco Bay Area and decide that you want to start saving to buy a house. As housing prices are very high in the Bay Area, you realize you are going to have to save for several years before you can afford to make the down payment on a house. In Part A, we are going to determine how long it will take you to save enough money to make the down payment given the following assumptions:
Call the cost of your dream home total_cost​.
Call the portion of the cost needed for a down payment portion_down_payment​. For
simplicity, assume that portion_down_payment = 0.25 (25%).
Call the amount that you have saved thus far current_savings​. You start with a current
savings of $0. 
Assume that you invest your current savings wisely, with an annual return of r ​(in other words,
at the end of each month, you receive an additional current_savings*r/12​ funds to put into
your savings – the 12 is because r​ is an annual rate). Assume that your investments earn a 
return of r = 0.04 (4%).
Assume your annual salary is annual_salary​.
Assume you are going to dedicate a certain amount of your salary each month to saving for 
the down payment. Call that portion_saved​. This variable should be in decimal form (i.e. 0.1
for 10%). 
At the end of each month, your savings will be increased by the return on your investment, plus a percentage of your monthly salary ​(annual salary / 12).
Write a program to calculate how many months it will take you to save up enough money for a down payment. You will want your main variables to be floats, so you should cast user inputs to floats
So far, I have this basic code:
annual_salary = float(input("Type annual salary here : "))
portion_saved = float(input("Type the portion you want to save (as a decimal) : "))
total_cost = float(input("Type the cost of your dream house here : "))
monthly_salary = (annual_salary / 12.0)
portion_down_payment = 0.25 * total_cost
current_savings = 0 + ???
returns = (current_savings * 0.4) / 12
overall_savings = returns + (portion_saved * monthly_salary)
months = ???`
My problem is that I have no idea how to calculate the months.
I do not know if I need to create an IF statement, a loop, or none of them at all.
The months are the value it will take to reach your necessary amount.
For example, you want to loop up until you have enough for the down payment.
months = 0
# Want to exit the loop when there is enough savings for a down payment
while current_savings < portion_down_payment:
current_savings += current_savings * (0.4 / 12) # Monthly interest
current_savings += portion_saved # Monthly savings
months += 1
print("It will take {} months to save!".format(months))
This can be solved analytically.
down_payment_rate = 0.25
saving_rate = 0.10
r = 0.04 #investment rate
target = total_cost * down_payment_rate
M = annual_salary/12*saving_rate/12 #Monthly savings
The question is to solve the following:
target = M*(1+r) + M*(1+r)^2 + M*(1+r)^3 ... M*(1+r)^N
The above is a geometric series, where N is the number of months to reach the target. This can be expressed succinctly as:
let g = 1+r:
target = M * (1-g^N)/(1-g)
You already know g, target, M, the only thing to solve for is N. you can find the result using algebra. Ie: N = log(1-target*(1-g)/M)/log(g)
You just need a while loop:
Initialize the months variable to 0 and ensure that the savings don't exceed and is less than or equal to the down payment. Also ensure that you set Current Saving to 0 initially
Current_Saving=0
rate=0.04/12
monthly_savings = monthly_salary*0.1
i=0
while (Current_Saving <= down_payment):
Current_Saving = Current_Saving+(monthly_savings)*rate + monthly_savings
i=i+1
print(i)
I will give the total number of months. Monthly salary can be obtained by dividing the annual salary by 12.

How can I find out the number of outputs in a loop?

I am a beginner at python and I'm struggling with one of my (simple) college assignments. I have been given the following instructions:
A bank is offering a savings account where a yearly fee is charged. Write
a program that lets the user enter
An initial investment.
The yearly interest rate in percent.
The yearly fee.
the program should then calculate the time it takes
for the investment to double. The interest is added on once per year.
An example run of the program:
Enter the investment: 1000
Enter the interest rate: 10
Enter the fee: 10
The investment doubles after 7 years.
I have formulated the following code but am receiving an error message with regards to t. I would really appreciate if I could get some help, thanks!:
t=0
p=float(input("Enter the investment:"))
a=float(input("Enter the interest rate:"))
m=float(input("Enter the fee:"))
i=(float(a/100))
f=p
while f<=(2*p):
f=(float(f*((1+i)**t)-m)
t=t+1
print("The investment doubles after",t,"years")
I tried to write this in a way that was very easy to follow and understand. I edited it with comments to explain what is happening line by line. I would recommend using more descriptive variables. t/p/a/m/f may make a lot of sense to you, but going back to this program 6 months from now, you may have issues trying to understand what you were trying to accomplish. NOTE You should use input instead of raw_input in my example if using Python 3+. I use 2.7 so I use raw_input.
#first we define our main function
def main():
#investment is a variable equal to user input. it is converted to a float so that the user may enter numbers with decimal places for cents
investment = float(raw_input("Starting Investment: "))
#interest is the variable for interest rate. it is entered as a percentage so 5.5 would equate to 5.5%
interest = float(raw_input("Interest Rate as %, ex: 5.5 "))
#annual_fee is a variable that will hold the value for the annual fee.
annual_fee = float(raw_input("Annual Fee: "))
#years is a variable that we will use with a while loop, adding 1 to each year (but we wait until within the loop to do this)
years = 1
#we use a while loop as opposed to a for loop because we do not know how many times we will have to iterate through this loop to achieve a result. while true is always true, so this segment is going to run without conditions
while True:
#this is a variable that holds the value of our total money per year, this is equal to the initial investment + investment * interest percentage - our annual fee per year
#I actually had to try a few different things to get this to work, a regular expression may have been more suited to achieve an interest % that would be easier to work with. do some research on regular expressions in python as you will sooner or later need it.
total_per_year = investment + (years * (investment * (interest / 100))) - (annual_fee * years)
#now we start adding 1 to our years variable, since this is a while loop, this will recalculate the value of total_per_year variable
years += 1
#the conditional statement for when our total_per_year becomes equal to double our initial investment
if total_per_year >= 2 * investment:
#print years value (at time condition is met, so it will be 5 if it takes 5 years) and the string ' Years to Double Investment'
print years,' Years to Double Investment'
#prints 'You will have $' string and then the value our variable total_per_year
print 'You will have $', total_per_year
#this will break our while loop so that it does not run endlessly
break
#here is error handling for if the fee is larger than investment + interest
if (years * annual_fee) >= (years * (investment * (interest / 100))):
print('Annual Fee Exceeds Interest - Losing Money')
break
#initial call of our main function/begins loop
main()

Python Blackjack Game how to carry a variable in a while loop

I'm still deep into the making of my Blackjack game in Python, my aim is to allow the computer to 'twist' (Take another card) until the total value is greater than 15. From then onwards I want it so that as the total of the cards gets higher, the chance of the computer taking another card gets smaller just like a human (taking a risk if the number isn't TOO big).The following code occurs after the computer has been dealt two values.
if (computerCardValueTotal < 15):
print ("The computer has decided to twist")
ranCompCard3 = random.choice(availableCards)
computerCardValueTotal = ranCompCard + ranCompCard2 + ranCompCard3
if (computerCardValueTotal < 15):
print ("The computer has chosen to twist again")
My aim is to have this piece of code loop if the total value is less than 15 so that the computer twists until it is over 15. I have considered using a while loop but I'm unsure on how to carry the current total to the start of the loop so that the next card value is added to the current total. Does anyone have a solution they could help me out with?
Also, secondly, it's not the biggest of the two issues in this question, but how would you recommend doing the computer so that the chance of it twisting again is smaller as the total value of cards get bigger? For example, for if the value of the cards totals at 17, there's a 1/10 chance of the computer twisting but if the total value of the cards is 19 the chance of the computer twisting is 1/20.
All valuable help will be voted up and as always, thanks in advance! :)
You have hobbled yourself by making e.g. ranCompCard, ranCompCard2, ranCompCard3, ... when a list would make life much easier:
compCards = [ranCompCard, ranCompCard2]
while sum(compCards) < 15:
compCards.append(random.choice(availableCards))
For adjusting the probability of picking another card, you could do something like:
while True:
gap = 21 - sum(compCards)
if gap > 0 and random.random() < (1 / (40 / float(gap))):
compCards.append(random.choice(availableCards))
else:
break
Note that this is a linear relationship between gap and the probability of picking another card:
>>> for card_sum in range(15, 21):
print card_sum, 1 / (40 / float(21 - card_sum))
15 0.15
16 0.125
17 0.1
18 0.075
19 0.05
20 0.025
but you can adjust the equation as needed.
While you're editing your code, take a look at (and consider following) the official style guide; variable names should be lowercase_with_underscores.
Simply reassign the value when it changes.
while computerCardValueTotal < 15:
# other code
computerCardValueTotal = <new value>

Silly Python Beginner

Having some trouble grasping why this "quick math" formula I was taught in high school does not seem to work correctly.
The premise is to take your hourly salary, double it and add three Zeros, the result will roughly equate to your yearly salary if you work full time 50 weeks out of the year.
# Preface
print '---> Want to know your yearly salary? <---'.upper()
# Question
money = raw_input("How much money do you earn per hour?")
# Math Work
mult = money * 2
result = mult + str(000)
# Answer
print "you make roughly $%r per year, Working full-time for 50 weeks out of the year" % result
Result:
my result looks something like this: "you make roughly $10100 per year, working full-time for 50 weeks out of the year"
I must be making a mistake in my expression...Simply put, I just do not know
You got all the types wrong.
raw_input acquires a string, so money is acquired as such. Thus, when you do mult=money*2 you are not doubling a number, but a string; writing money*2 thus has the effect of creating a string that is the concatenation of two copies of the string you provided. If you enter 10, mult will be '1010'.
Also, in str(000) 000 is an integer, so it's actually a plain 0; str(000) thus results in '0', which is concatenated to your doubled-string. 1010 concatenated with '0' => 10100.
What you actually want is
# Question
money = int(raw_input("How much money do you earn per hour?"))
# Math Work
mult = money * 2
result = str(mult) + "000"
By the way, adding zeroes and the like is fine for humans, but since we are dealing with a computer you can just multiply by 2000:
result = 2000*int(raw_input("How much money do you earn per hour?"))
You're trying to do math with a string. Convert it into an integer first:
money = int(raw_input("How much money do you earn per hour?"))
and multiply instead of trying to add a string to the end
result = money * 2000
Though if you really wanted to, you could convert the integer back to a string to add 3 zeros to the end:
mult = money * 2
strmult = str(mult)
result = strmult + '000'
The raw_input() function returns a string.
When you multiply money by a number, instead of multiplying the integer value, you are multiplying the string value. This results in the variable's new value being a multiple of the string, or the string repeated multiple times. I would suggest using the money=int(money) function on money to turn it into an integer, or better yet money=float(money) to get a floating-point number.
try this
money=int(input('how much you make an hour'))
final_yearly=money*2000
print(final_yearly)
You do realize the following would give you the desired answer, right?
#Math Work
mult = money * 2000
First, money is a string, when you read user input. So when the user inputs 10, you get '10'.
So when you do money*2, you don't get the expected 20. Rather, you get '10'*2, which is '10' concatenated twice, i/e/ '1010'.
Next, 000 is an int that evaluates to 0, the str of which is '0'. What you wanted to add is '000'
I would go about your task this way:
# Preface
print '---> Want to know your yearly salary? <---'.upper()
# Question
money = int(raw_input("How much money do you earn per hour?"))
# Math Work
mult = money * 2
result = str(mult) + "000"
Alternatively, you could do this as well:
# Preface
print '---> Want to know your yearly salary? <---'.upper()
# Question
money = int(raw_input("How much money do you earn per hour?"))
# Math Work
result = money*2000 # because adding three 0s is the same as multiplying by 1000
# Preface
print '---> Want to know your yearly salary? <---'.upper()
# Question
money = raw_input("How much money do you earn per hour?")
# Math Work
result = str(int(money)*2) + '000'
# Answer
print "you make roughly $%r per year, Working full-time for 50 weeks out of the year" % result

Categories

Resources