pset2 Python Problem3-UsingBisectionSearch.py - python

I am completely new to Python, and I have lots of problems working out indentation, anyway I need someone to help me understand why my code not working...( The if condition is not recognizing the value from the inner while loop )
balance = 1000
annualInterestRate = 0.2
monthlyInterestRate = annualInterestRate /12
episilon = 0.01
numGuesses = 0
Low = balance / 12
High = (balance * (1 + monthlyInterestRate )**12) / 12.0
ans = (Low + High) / 2.0
newbalance = balance
monthlyPayment = ans
while newbalance > 0:
newbalance = balance
month = 0
while month < 12:
print('low = ' + str(Low) + ' high = ' + str(High) + ' ans = ' + str(ans))
newbalance -= monthlyPayment
interest = monthlyInterestRate * newbalance
newbalance += interest
month += 1
print month
if(newbalance > 0):
Low = ans
else:
High = ans
ans = (Low + High) / 2.0
print 'Lowest payment: ' + str(ans)

You should be deducting ans not monthlyPayment, setting monthlyPayment = ans outside the loop does not mean monthlyPayment will be updated when you set ans = (Low + High) / 2.0 inside the while loop each time, you are creating a new object each time:
while abs(newbalance) > 0.001: # check if we are withing +- .001 of clearing balance
newbalance = balance
month = 0
for month in range(12): # loop over 12 month range
print('low = ' + str(Low) + ' high = ' + str(High) + ' ans = ' + str(ans))
newbalance -= ans # deduct ans not the the original value set outside the while
interest = monthlyInterestRate * newbalance
newbalance += interest
print month
if newbalance > 0:
Low = ans
else:
High = ans
ans = (Low + High) / 2.0
print "Lowest Payment: {:.2f}".format(ans) # format to two decimal places
Also it is better to use for month in range(12), we know we only want to have 12 iterations so much simpler to use range.
Even if you were doing a ans += 2 your monthlyPayment would not be updated as ints are immutable so monthlyPayment would still only point to the original value of ans.
In [1]: ans = 10
In [2]: monthlyPayment = ans
In [3]: id(ans)
Out[3]: 9912448
In [4]: id(monthlyPayment) # still the same objects
Out[4]: 9912448
In [5]: ans += 10 # creates new object
In [6]: ans
Out[6]: 20
In [7]: monthlyPayment # still has original value
Out[7]: 10
In [8]: id(monthlyPayment) # same id as original ans
Out[8]: 9912448
In [9]: id(ans) # new id because it is a new object
Out[9]: 9912208

Related

i made a function and then i used the same code that is in the function to get the minimum value through a for loop but i am getting different answers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
The community reviewed whether to reopen this question 3 months ago and left it closed:
Not suitable for this site
Improve this question
the function is to calculate cost based on earning, loan taken, fees, rates and duration, but when applying the exact same code that is there in the function to a for loop the answers are coming different, can help me out as i am new to programming
#income tax calculation and cost calc
# earning, loan y n, interest rate, years, fees
def IT_calc(earn,l,ir,d,f):
interest_payable = f * ir * d
amount_payable = f + interest_payable
if l == 0:
if earn <= 250000:
income_tax = 0
elif earn <= 500000:
income_tax = (earn-250000)*0.05
elif earn <= 750000:
income_tax = (250000*0.05)+ (earn-500000)*0.10
elif earn <= 1000000:
income_tax = (250000)*(0.05+0.10) + (earn-750000)*0.15
elif earn <= 1250000:
income_tax = (250000)*(0.05+0.10+0.15) + (earn-1000000)*0.20
elif earn <= 1500000:
income_tax = (250000)*(0.05+0.10+0.15+0.20) + (earn-1250000)*0.25
else:
income_tax = (250000)*(0.05+0.10+0.15+0.20+0.25) + (earn-1500000)*0.30
cost = (income_tax * 1.04 * d) + f
print('Your total cost over', d, 'years without loan is:', cost)
else:
earn = earn-(amount_payable//d)
if earn <= 250000:
income_tax = 0
elif earn <= 500000:
income_tax = (earn-250000)*0.05
elif earn <= 750000:
income_tax = (250000*0.05)+ (earn-500000)*0.10
elif earn <= 1000000:
income_tax = (250000)*(0.05+0.10) + (earn-750000)*0.15
elif earn <= 1250000:
income_tax = (250000)*(0.05+0.10+0.15) + (earn-1000000)*0.20
elif earn <= 1500000:
income_tax = (250000)*(0.05+0.10+0.15+0.20) + (earn-1250000)*0.25
else:
income_tax = (250000)*(0.05+0.10+0.15+0.20+0.25) + (earn-1500000)*0.30
cost = (income_tax * 1.04 * d) + amount_payable
print('Your total cost over', d, 'years with loan is:', cost)
IT_calc(1200000,1,0.085,3,1600000)
>> Your total cost over 3 years with loan is: 2056568.104
#For loop
b = []
f = 1600000
ir = 0.085
earn = 1200000
l = 1
for t in range(1,20):
interest_payable = f * ir * t
amount_payable = f + interest_payable
if l == 0:
if earn <= 250000:
income_tax = 0
elif earn <= 500000:
income_tax = (earn-250000)*0.05
elif earn <= 750000:
income_tax = (250000*0.05)+ (earn-500000)*0.10
elif earn <= 1000000:
income_tax = (250000)*(0.05+0.10) + (earn-750000)*0.15
elif earn <= 1250000:
income_tax = (250000)*(0.05+0.10+0.15) + (earn-1000000)*0.20
elif earn <= 1500000:
income_tax = (250000)*(0.05+0.10+0.15+0.20) + (earn-1250000)*0.25
else:
income_tax = (250000)*(0.05+0.10+0.15+0.20+0.25) + (earn-1500000)*0.30
cost = (income_tax * 1.04 * t) + f
else:
earn = earn-(amount_payable//t)
if earn <= 250000:
income_tax = 0
elif earn <= 500000:
income_tax = (earn-250000)*0.05
elif earn <= 750000:
income_tax = (250000*0.05)+ (earn-500000)*0.10
elif earn <= 1000000:
income_tax = (250000)*(0.05+0.10) + (earn-750000)*0.15
elif earn <= 1250000:
income_tax = (250000)*(0.05+0.10+0.15) + (earn-1000000)*0.20
elif earn <= 1500000:
income_tax = (250000)*(0.05+0.10+0.15+0.20) + (earn-1250000)*0.25
else:
income_tax = (250000)*(0.05+0.10+0.15+0.20+0.25) + (earn-1500000)*0.30
cost = (income_tax * 1.04 * t) + amount_payable
b.append(cost)
b
>>[1736000.0,
1872000.0,
2008000.0,
2144000.0,
2280000.0,
2416000.0,
2552000.0,
2688000.0,
2824000.0,
2960000.0,
3096000.0,
3232000.0,
3368000.0,
3504000.0,
3640000.0,
3776000.0,
3912000.0,
4048000.0,
4184000.0]
i was trying to estimate the minimum costs but i am getting the wrong answer through the for loop, am i missing something?
In your for loop, you are changing the value of earn on every loop with the line earn = earn-(amount_payable//t), so that it is not starting at 1200000 for each case.
Either reset it inside the for loop, or as OneMadGypsy suggests, change the IT_calc function to return the value instead of printing and use it in your for loop instead of having a slightly modified copy of the entire function.

How to iterate code and save each output to a list

I'm just learning how to code and I've encountered a problem I can't seem to work around. I've built a strategy for a simple game of chance (similar to the Martingale strategy for those familiar) and I want to run the code n number of times and save the output of each iteration so I can aggregate the results. Note the current 'for' loop is part of my code, I tried using another 'for' loop to run the entire program n times to no avail. Thanks heaps in advance. Apologies if this is a silly question. Here is my code:
import math
import random
import heartrate
heartrate.trace(browser=True)
mult = 1.2
winChance = 0.8250
balance = 259
x = 0
for i in range (0,500):
bet1 = balance/259
balance = balance-bet1
print(balance)
n = random.random()
if n > winChance:
bet2 = (bet1*(1/(mult-1)))+bet1
balance = balance-bet2
n = random.random()
if n > winChance:
bet3 = ((bet1+bet2)*(1/(mult-1)))+bet1
balance = balance-bet3
n = random.random()
if n > winChance:
bet4 = ((bet1+bet2+bet3)*(1/(mult-1)))+bet1
balance = balance-bet4
n = random.random()
if n > winChance:
bet5 = ((bet1+bet2+bet3+bet4)*(1/(mult-1)))+bet1
balance = balance-bet5
print("end")
break
else:
balance = balance = bet4*mult
else:
balance = balance + bet3*mult
else:
balance = balance + bet2*mult
else:
balance = balance + bet1*mult
If I understand the question and code correctly (doubtful), this change would do what you ask for: Running your original code N times (with N = 10):
$ diff -u iterate.py.orig iterate.py
--- iterate.py.orig 2022-03-20 13:02:54.010642003 +0100
+++ iterate.py 2022-03-20 13:17:35.368615800 +0100
## -5,10 +5,12 ##
mult = 1.2
winChance = 0.8250
+end_balances = []
-balance = 259
-x = 0
-for i in range (0,500):
+for _ in range(10):
+ balance = 259
+ x = 0
+ for i in range (0,500):
bet1 = balance/259
balance = balance-bet1
print(balance)
## -35,7 +37,7 ##
break
else:
- balance = balance = bet4*mult
+ balance = balance + bet4*mult
else:
balance = balance + bet3*mult
## -47,3 +49,6 ##
else:
balance = balance + bet1*mult
+ end_balances.append(balance)
+
+print(end_balances)
Here is the full code:
import math
import random
import heartrate
heartrate.trace(browser=True)
mult = 1.2
winChance = 0.8250
end_balances = []
for _ in range(10):
balance = 259
x = 0
for i in range (0,500):
bet1 = balance/259
balance = balance-bet1
print(balance)
n = random.random()
if n > winChance:
bet2 = (bet1*(1/(mult-1)))+bet1
balance = balance-bet2
n = random.random()
if n > winChance:
bet3 = ((bet1+bet2)*(1/(mult-1)))+bet1
balance = balance-bet3
n = random.random()
if n > winChance:
bet4 = ((bet1+bet2+bet3)*(1/(mult-1)))+bet1
balance = balance-bet4
n = random.random()
if n > winChance:
bet5 = ((bet1+bet2+bet3+bet4)*(1/(mult-1)))+bet1
balance = balance-bet5
print("end")
break
else:
balance = balance + bet4*mult
else:
balance = balance + bet3*mult
else:
balance = balance + bet2*mult
else:
balance = balance + bet1*mult
end_balances.append(balance)
print(end_balances)
Note that you normally would extract the inner loop into a separate function.
Edit: Fixed the typo in the innermost else as well.
You can start by creating an empty list such as:
balance_end = []
And then appending the final balance after each iteration (I have fixed the first else which had a typo as well), such as:
else:
balance = balance + bet4*mult
balance_end.append(balance)
else:
balance = balance + bet3*mult
balance_end.append(balance)
else:
balance = balance + bet2*mult
balance_end.append(balance)
else:
balance = balance + bet1*mult
balance_end.append(balance)
Finally, you can safely assume that the balance_end index will match the number of iteration - 1 and the value, is the corresponding value of said iteration.
Here's my attempt to simplify things (to be honest, the code is quite convoluted and difficult to understand):
def bet(win_chance, previous_bets, mult):
if random.random() > win_chance:
this_bet = -1 * ((sum(previous_bets)*(1/(mult-1)))+previous_bets[0])
else:
this_bet = previous_bets[-1]*mult
return this_bet
# initialise variables
mult = 1.2
win_chance = 0.8250
balance = 259
for i in range(500):
previous_bets = []
previous_bets.append(balance/259)
balance -= previous_bets[0]
for i in range(5):
lost = bet(win_chance, previous_bets, mult)
balance += previous_bets[-1]
if not lost:
break
else:
# lost streak after 5 attempts
print('end')
print(balance)
create a list and append balance values to it
import math
import random
import heartrate
heartrate.trace(browser=True)
mult = 1.2
winChance = 0.8250
balance = 259
x = 0
values = list()
for i in range (0,500):
stop = False
bet1 = balance/259
balance = balance-bet1
print(balance)
n = random.random()
if n > winChance:
bet2 = (bet1*(1/(mult-1)))+bet1
balance = balance-bet2
n = random.random()
if n > winChance:
bet3 = ((bet1+bet2)*(1/(mult-1)))+bet1
balance = balance-bet3
n = random.random()
if n > winChance:
bet4 = ((bet1+bet2+bet3)*(1/(mult-1)))+bet1
balance = balance-bet4
n = random.random()
if n > winChance:
bet5 = ((bet1+bet2+bet3+bet4)*(1/(mult-1)))+bet1
balance = balance-bet5
print("end")
stop = True
else:
balance = balance = bet4*mult
else:
balance = balance + bet3*mult
else:
balance = balance + bet2*mult
else:
balance = balance + bet1*mult
values.append(balance)
if stop:
break

Why do I need to define variables in my while loop for my code to work?

This is a question from the 6.0001 MIT Intro to CS course PS1-C:
Why do I have to define certain variables twice - both inside and outside the while loop when the definition isn't changing? For example, diff_from_target or current_savings variable.
Full code below:
# User inputs
total_cost = 1000000
starting_annual_salary = 300000
semi_annual_raise = .07
# bisection search
low = 0
high = 10000
steps = 0
# Investments (investment = current_savings * monthly rate)
r = .04
monthly_rate = r/12
# Calculate down payment (target savings)
target_savings = .25 * total_cost
current_savings = 0
diff_from_target = target_savings - current_savings
savings_rate = (low+high)/2
while abs(diff_from_target) > 100 and steps < 100:
months = 0
current_savings = 0
annual_salary = starting_annual_salary
savings_rate = (low+high)/2
while months < 36:
current_savings += (annual_salary/12)*savings_rate + current_savings * monthly_rate
months += 1
if months % 6 == 0:
annual_salary += annual_salary * semi_annual_raise
diff_from_target = target_savings - current_savings
if diff_from_target > 0:
low = savings_rate
elif diff_from_target < 0:
high = savings_rate
steps +=1
else:
if abs(diff_from_target) <= 100:
print("%: {0:.4f}, steps: {1}".format(savings_rate, steps))
else:
print("Not possible to 36 months")
This is probably to make sure that the variable current_savings exists after the loop even if the loop didn't run a single time (for example if one of the conditions was False at the beginning)

Python bisection search confusion

I'm trying to work on the MIT intro to CS with Python problem set 1.
Here's the problem (bottom of page 3):
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
Here's my code:
#best savings rate in 3 years
annual_salary = float(input("Enter your annual salary: "))
total_cost = 1000000
semi_annual_raise = 0.07
portion_down_payment = 0.25*total_cost
r = 0.04
low = 0
high = 10000
pre_saved = int((high+low)/2)
steps = 0
current_savings = 0
epsilon = 100
months = 0
salary_increase_months = 0
portion_saved = pre_saved/10000
print(portion_saved)
while abs(current_savings - portion_down_payment) >= epsilon:
#calculates savings after 36 months
while(months < 36):
#checks every 6th iteration to add the semi annual raise
if(salary_increase_months == 6):
annual_salary += annual_salary*semi_annual_raise
salary_increase_months = 0
current_savings += current_savings*(r/12) + portion_saved*(annual_salary/12)
salary_increase_months += 1
months += 1
#print(current_savings)
#bisection search portion
if current_savings < portion_down_payment - epsilon:
#print('1')
low = portion_saved*10000
current_savings = 0
elif current_savings > portion_down_payment + epsilon:
#print('2')
high = portion_saved*10000
current_savings = 0
elif current_savings < portion_down_payment + epsilon and current_savings > portion_down_payment - epsilon:
print('Best savings rate:', portion_saved)
print('Steps in bisection search:', steps)
break
else:
print('It is not possible to pay the down payment in three years.')
break
portion_saved = int((low + high)/2)
portion_saved = portion_saved/10000
steps += 1
months = 0
salary_increase_months = 0
When I put in a value for the salary, all I get is the original percentage saved (0.5) and the output doesn't end. Nothing else gets printed. I created three if statements that are supposed to check the value of portion saved and do a bisection search (if the value is higher than portion down payment plus epsilon, then high becomes the portion saved, and vice versa).
def curr_saving(salary, Semi_raise, saveP, month):
saving = 0
monthly_income = salary/12
# down_pay = 0.25*cost
for i in range(1, month):
if i % 6 == 0:
salary += salary*Semi_raise
monthly_income = salary/12
interest = saving*(1+0.04/12)
saving = monthly_income*saveP+interest
return saving
def Hunting_C(base, Semi_raise, cost):
# saving = 0
# salary = base
# monthly_income = salary/12
down_pay = 0.25*cost
No_month = 36
# saving_range = numpy.arange(0, 1, 0.0001)
step = 0
min_S = 0
max_S = 1
saveP = (min_S+max_S)/2
while (abs(curr_saving(base, Semi_raise, saveP, No_month)-down_pay)) >= 100:
step += 1
if curr_saving(base, Semi_raise, saveP, No_month) > down_pay:
max_S = saveP
else:
min_S = saveP
saveP = (min_S+max_S)/2
return f'saving rate: {saveP}, No of steps: {step}, current saving: {curr_saving(base, Semi_raise, saveP, No_month)}'
print(Hunting_C(150000, 0.07, 1000000))

MIT opencourseware - stuck on a basic issue, credit card minimum payment over a year calculation

Basically I'm pretty stuck on this issue, I've linked the question below, it's part 'b' I'm stuck on, or the second question in the document:
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00sc-introduction-to-computer-science-and-programming-spring-2011/unit-1/lecture-4-machine-interpretation-of-a-program/MIT6_00SCS11_ps1.pdf
If I'm honest it's just got to the point where I'm totally confused! I've put my code below:
balance = float(raw_input('Vot is the outstanding balance? '))
InrAn = float(raw_input('Vot is the annual interest rate as a decimal? '))
month = 1
monthPay = 10
monthInr = InrAn/12.0
newBalance = balance
while balance > 0:
newBalance = newBalance * (1 + monthInr) - monthPay
month +=1
if month > 12:
month = 1
newBalance = balance
monthPay += 10
This does essentially nothing, I know, and it's not yet complete. If I add a 'print month' statement it just seems to show that the code just goes up to 12, then starts at 1 again. Any tips/prods in the right direction?
monthly_payment = 10.0
while True:
current_balance = start_balance
for month in range(1, 13):
current_balance = current_balance * (1. + monthly_rate) - monthly_payment
current_balance = round(current_balance, 2)
if current_balance <= 0.0:
break
if current_balance <= 0.0:
print("RESULT")
print("Monthly payment to pay off debt in 1 year: {}".format(int(monthly_payment)))
print("Number of months needed: {}".format(month))
print("Balance: {:0.2f}".format(current_balance))
break
monthly_payment += 10.0

Categories

Resources