How do I insert a condition under while loop? - python-3.x

I am a beginner trying to learn python through MIT OpenCourseware. This problem is from part B of problem set 1. I understand the mathematical expression but I do not know how to write it out in code.
This is the problem:
Determine how long it will take to save enough
money to make the down payment for a house given the following assumptions:
portion_down payment = 0.25 (25%)
You start with a current savings of $0
Assume that you invest your current savings wisely, with an annual return of r = 0.04 (4%)
Your salary increases by a certain percentage every 6 months (semi-annual rise)
Here is a test case:
Enter your starting annual salary: 120000
Enter the percent of your salary to save, as a decimal: .05
Enter the cost of your dream home: 500000
Enter the semi­annual raise, as a decimal: .03
Number of months: 142 
Here is my code:
annual_salary = float(input('Annual Salary: '))
portion_saved = float(input('Portion saved (decimal): '))
total_cost = float(input('Total Cost of House: '))
semi_annual_rise = float(input('Semi-annual salary rise (decimal): '))
downp = float(0.25*total_cost)
current_savings = 0
monthly_savings = float(portion_saved*annual_salary/12)
ret = 1 + .04/12
rise = 1 + semi_annual_rise
n = 0
while current_savings < downp:
for n in range(0,300,6):
monthly_savings = monthly_savings*(rise)
current_savings = (current_savings + monthly_savings)*(ret)
n += 1
print ('Number of months: ' + str(n))
Under the while loop, I am trying to increase the salary after 6, 12, 18 etc... months. But I dont know how to insert such a conditionI know it's wrong but I do not know how to correct it. Please help me!!

Just make the raise when n%6 == 0 ...
...
n = 0
while current_savings < downp:
n += 1
if n % 6 == 0: #every six months
monthly_savings = monthly_savings*(rise)
current_savings = (current_savings + monthly_savings)*(ret)
...

Related

How to check if this input is a negative number

I'm new to python and want to make a program that generates Pi with the given decimal numbers. Problem is that I don't know how to check if the user has inputted a positive number.
This is the function that generates Pi (I don't know for sure how it works)
def PiBerekening(limiet):
q = 1
r = 0
t = 1
k = 1
n = 3
l = 3
decimaal = limiet
teller = 0
while teller != decimaal + 1:
if 4 * q + r - t < n * t:
# yield digit
yield n
# insert period after first digit
if teller == 0:
yield '.'
# end
if decimaal == teller:
print('')
break
teller += 1
nr = 10 * (r - n * t)
n = ((10 * (3 * q + r)) // t) - 10 * n
q *= 10
r = nr
else:
nr = (2 * q + r) * l
nn = (q * (7 * k) + 2 + (r * l)) // (t * l)
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr
And this is how I ask the user how many decimals he wants to see
while not verlaatloop:
try:
pi_cijfers = PiBerekening(int(input("With how many decimals would you like to calculate Pi?")))
assert pi_cijfer > 0 # This is one of the things I've tried but I get the "NameError: name 'pi_cijfer' is not defined" error and I don't know what to do to check if the inputted number is negative
except ValueError:
print("This isn't a valid number, try again")
except AssertionError:
print("This number is negative, try again")
else:
verlaatloop = True
This is how I show the calculated Pi
for pi_cijfer in pi_cijfers:
print(pi_cijfer, end='')
You can first validate the input and then pass it to the PiBerekening function. Something like this:
while not verlaatloop:
try:
no_decimals = int(input("With how many decimals would you like to calculate Pi?"))
if no_decimals > 0:
pi_cijfers = PiBerekening(no_decimals)
#assert pi_cijfer > 0 # This is one of the things I've tried but I get the "NameError: name 'pi_cijfer' is not defined" error and I don't know what to do to check if the inputted number is negative
except ValueError:
print("This isn't a valid number, try again")
except AssertionError:
print("This number is negative, try again")
else:
verlaatloop = True

While loop doesn't work fine if I multiply current_savings with a number lower than 1 inside the loop

I am encountering an infinite while loop when I type in the following code. The problem only occurs if I multiply current_savings with a number lower than 1. 099999 doesn't give the error, but 0.999 does. What am I doing wrong?
I have tried multiplying current_savings with any floating point number above 1 and the code works fine.
total_cost = float(input('enter cost of your dream house: '))
annual_salary = float(input('enter annual salary: '))
portion_saved = float(input('enter percentage of monthly salary to be saved in decimals: '))
monthly_salary = annual_salary/12
saved_portion = monthly_salary*portion_saved
portion_down_payment = 0.25*total_cost
months = 0
current_savings = 0.0
while (portion_down_payment > current_savings):
current_savings = (current_savings*0.04)/12 + saved_portion
months = months + 1
print(months)
I expected to program to print the number of months as expected, but the loop doesn't terminate for some reason.
When you are calculating your current_savings, you are not including the savings you already have:
current_savings = (current_savings*0.04)/12 + saved_portion
should be
current_savings = current_savings + (current_savings*0.04)/12 + saved_portion
This gives new code:
total_cost = float(input('enter cost of your dream house: '))
annual_salary = float(input('enter annual salary: '))
portion_saved = float(input('enter percentage of monthly salary to be saved in decimals: '))
monthly_salary = annual_salary/12
saved_portion = monthly_salary*portion_saved
portion_down_payment = 0.25*total_cost
months = 0
current_savings = 0.0
while (portion_down_payment > current_savings):
old_current = current_savings
current_savings = current_savings + (current_savings*0.04)/12 + saved_portion
months = months + 1
print(months)
Printing out months and current_savings within the while loop allowed me to see that the current_savings stopped changing after a point.

I have a for loop nested within my while loop, what is causing an infinite loop within my code?

I'm new to Python and coding in general. I am trying to use a while loop with a nested for loop to calculate the lowest % of salary that can be saved that will reach the savings goal within 36 months. The code also includes functions to apply a semi-annual raise to the salary every 6 months and to apply interest gained to the savings.
When I run my code it results in an infinite loop and I haven't been able to see what is causing it.
total_cost = 1000000
semi_annual_raise = 0.07
down_payment = 0.25*total_cost
starting_salary = float(input("What is your annual salary?: "))
monthly_salary = starting_salary/12.0
r = 0.04
steps = 0
epsilon = 100
low = 0
high = 10000
portion_saved = (high + low)/2.0
current_savings = 0
raise_counter = 0
while abs(current_savings - down_payment) > epsilon:
current_savings = 0
for months in range(36):
current_savings += (current_savings*r/12) + (monthly_salary*
(portion_saved/10000))
if raise_counter == 6:
monthly_salary += monthly_salary*semi_annual_raise
raise_counter = 0
raise_counter += 1
if current_savings < down_payment:
low = portion_saved
else:
high = portion_saved
portion_saved = (high + low)/2.0
steps += 1
raise_counter = 0
print ("Number of steps =", steps)
print ("Optimal % to save:", portion_saved/10000)
Why have you used (monthly_salary*portion_saved/10000 ? Since you need to add the portion_saved to the current_savings each month, i would recommend you to use
current_savings+=(current_savings*r/12) + portion_saved
I think you can also simplify the process by finding the % to be saved using the below formula
monthly_salary*(save_percent/100)* 36 = down_payment-epsilon

Python - track inputs

I am having difficulty keeping a track of the total number of inputs. I want my program to keep track of the total number of inputs and print it when my while loop breaks. Any help is appreciated!
r = float(input("enter r:"))
def main(r):
a = 3.14 * (float(r ** 2))
s_v = 0
total = 0
while True:
r = float(input("enter r:"))
if r == sentinal_value:
total += r
print("Total = " , total)
break
else:
print("Area = ", a)
continue
main(r)
I assume that you want your program to re-calculate the area with each iteration. As written, it will only be calculated the first time you run the mymian function. You don't need to pass any arguments to the function.
def mymian():
sentinal_value = 0
total = 0
while True:
r = float(input("enter r:"))
if r == sentinal_value:
print("Total number of r provided to this program" , total)
break
else:
print("Area = ", 3.14 * (float(r ** 2)))
total += 1
continue

Euler 12 need optimization

I have solved euler problem 12, but it needs some optimization. I have read on the euler forums, but it has not helped me optimized it. However, I have managed to get the solution, I just need to speed it up. It currently takes 4 minutes to run. Here is my code:
import time
def nthtriangle(n):
return (n * (n + 1)) / 2
def numberofnfactors(n):
count = 0
if n==1:
return 1
for i in range(1, 1 + int(n ** 0.5)):
if n % i == 0:
count += 2
return count
def FirstTriangleNumberWithoverxdivisors(divisors):
found = False
counter = 1
while not found:
print(int(nthtriangle(counter)), " ", numberofnfactors(nthtriangle(counter)))
if numberofnfactors(nthtriangle(counter)) > divisors:
print(" first triangle with over ",divisors, " divisors is ", int(nthtriangle(counter)))
found = True
break
counter += 1
start_time = time.time()
FirstTriangleNumberWithoverxdivisors(500)
print("My program took", time.time() - start_time, "to run")
Instead of calculating each triangle number individually, use a generator to get the triangle numbers
from timeit import timeit
def triangle_numbers():
count = 1
num = 0
while True:
num += count
count += 1
yield num
def count_divisors(n):
count = 0
if n==1:
return 1
for i in range(1, 1 + int(n ** 0.5)):
if n % i == 0:
count += 2
return count
print(timeit('next(num for num in triangle_numbers() if count_divisors(num) >= 500)',
globals=globals(), number=1))
Gives me 3.8404819999996107 (seconds) on my machine. You could probably also improve the divisor counting.
What's really slowing you down is calling nthtriangle and numberoffactors more than once in your loop! Plus, those calls to print aren't free.

Resources