IRS informants are paid cash rewards based on the value of the money recovered. If the information was specific enough to lead to a recovery, the informant receives
10% of the first $75,000 plus
5% of the next $25,000 plus
1% of the remainder up to a maximum reward of $50,000.
The following function accepts the amount of money recovered and returns the reward.
to run tests: python3 -m doctest irs_reward.py -v
'''def irs_reward(money_recovered):
IRS informants are paid cash rewards based on the value of the money recovered
calculate reward amount from money recovered
args:
money_recovered (float): dollar value of money recovered
returns:
the dollar value of the reward (float)
formula:
10% of the first $75k
+ 5% of the next $25k
+ 1% of the rest, up to max total reward of $50k
examples/doctests:
no money recovered
>>> round(irs_reward(0), 2)
0.0
$75k recovered
>>> round(irs_reward(75000), 2)
7500.0
$95k recovered
>>> round(irs_reward(95000), 2)
8500.0
$200,000 recovered
>>> round(irs_reward(200000), 2)
9750.0
$42 milliion recovered, max out at $50k reward
>>> round(irs_reward(42000000), 2)
50000.0
# TO DO: Add your code here #
# ========================= #
return
Can someone help me with the code. I have tried 5 to 6 times and finally closed out the program and did not save it.
You should learn how this works, not just get people to do your homework for you, but here goes:
def calculate_reward(money_recovered):
reward = 0
if money_recovered >= 4125000:
reward = 50000
elif money_recovered >= 100000:
reward = (money_recovered - 100000)/100 + 8750
elif money_recovered >= 75000:
reward = (money_recovered - 75000)/20 + 7500
else:
reward = money_recovered/10
return reward
The reason for the number 4125000 is because thats the number needed to make the total reward 50k. It is 10% of 75k + 5% of 25k + 1% of the rest, which makes the remaining 41.25k.
The next barrier is 100k since that is 25k + 75k, so things above that but below 4125000 get taxed 1%, and each time we check for the money being over a barrier we add the max they received from lower amounts.
Related
I just picked up coding for the first time and started with the MIT free intro to python course. I am on the first problem of the second homework and I am having a hard time figuring out how to solve. I saw some other posts about this but I think it would be way easier to learn if someone could show me how to do it with my code rather than anothers.
This is the problem:
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.
Here is my code so far:
total_cost = float(input("What is the cost of the home? "))
annual_salary = float(input("What is your annual salary? "))
portion_saved = float(input("How much would you like to save per year? "))
portion_down = (total_cost*.25)
current_savings = 0
monthly_salary = (annual_salary/12)
interest_rate = .04
#goal is to loop up until I have enough for the down payment
print (total_cost)
print (annual_salary)
print (portion_saved)
print ("The downpayment required for this house is", portion_down)
#need to use +=, otherwise you would have to do current saving = current savings + 1
months = 1
while current_savings < portion_down:
current_savings += current_savings*(.4/12) #monthly interest
current_savings += portion_saved #monthly savings
months += months + 1
print ("It will take", months, "months to save the needed down payment of", portion_down)
You did a pretty good job.
The biggest problem I see in your code is:
months += months + 1
You need to change it to:
months +=1
I also made some tweaks in your code, but essentially I kept the same idea:
total_cost = float(input("What is the cost of the home? "))
monthly_salary = float(input("What is your monthly salary? "))
#portion_saved = float(input("How much would you like to save per year? "))
portion_down = (total_cost*.25)
current_savings = 0
interest_rate = 0.04
months = 1
portion_saved = 0.1
print ("The downpayment required for this house is", portion_down)
while current_savings < portion_down:
current_savings += current_savings(interest_rate/12)+portion_saved*monthly_salary
months +=1
print ("It will take", months, "months to save the needed down payment of",portion_down)
I'm trying to create a function that is essentially a buy back program with bottles, the rules are as follows
money -> the amount of money the customer has
bottlesOwned -> the number of bottles the customer has to exchange
price -> the price of a bottle of soda pop
exchangeRate -> the exchange rate, expressed as a tuple. the first element is the minimum size of the group of bottles that can be exchanged. The second argument is the refund received for one group of bottles.
A customer may refund as many groups of bottles as they like on a single visit to the store, but the total number of bottles refunded must be a multiple of the first element of exchangeRate.
The function must output the total number of bottles which the customer is able to purchase over all trips, until the customer runs out of money.
def lightningBottle(money, bottlesOwned, price, exchangeRate):
if bottlesOwned >= exchangeRate[0]:
bottlesOwned -= exchangeRate[0]
money += exchangeRate[1]
if money >= price:
bottlesOwned += 1
bottlesbought += 1
money -= price
return lightningBottle(money, bottlesOwned, price, exchangeRate)
else:
print ("we bought",bottlesbought,"bottles")
return bottlesbought
this is as far as I've gotten but I cannot figure out how to get the bottlesbought counter to tick up without using a global variable (I can't use a global because it does not reset on concurrent tests and provides the wrong answer)
You're close. You just need bottlesbought to be an argument of your function:
def lightningBottle(money, bottlesOwned, price, exchangeRate, bottlesbought=0):
if bottlesOwned >= exchangeRate[0]:
bottlesOwned -= exchangeRate[0]
money += exchangeRate[1]
if money >= price:
bottlesOwned += 1
bottlesbought += 1
money -= price
return lightningBottle(money, bottlesOwned, price, exchangeRate, bottlesbought)
else:
print ("we bought",bottlesbought,"bottles")
return bottlesbought
You can give it a default value so you don't need to specify that it's equal to zero at the start (which it always is).
So currently this code is returning an infinite loop. The assignment is to calculate a fixed monthly payment. My biggest pain is with epsilon and trying to get my newly calculated balance within it's range. The code takes the balance and calculates the theoretical most and least amount we can pay monthly and be at 0 new_balance. MonthlyIR is monthly interest rate
def bisection(balance,annualinterestRate):
monthlyIR = annualinterestRate/12.0
new_balance = balance
monthly_lower = balance/12
monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
epsilon = 0.01
print(monthly_lower,monthly_upper)
while abs(new_balance) >= epsilon:
new_balance = balance
print(monthly_lower,monthly_upper)
payment = (monthly_upper + monthly_lower)/2
for i in range(12):
new_balance -= payment
new_balance *= monthlyIR
if new_balance > 0:
monthly_lower = payment
else:
monthly_upper = payment
return round(payment,2)
So pretty much when I go through the monthly payments, and the new balance is still bigger than epsilon then set either the max or the min = to payments. However when It runs the max or min don't update and I can't figure out why.
I would like someone to solve that particular issue and I would like insight on a cleaner way to do this. Whether it's more specialization of functions or a different approach other than iterative.
Ran 2 tests
annualinterestRate >= 12
No infinite loop, and returns results
annualinterestRate < 12 :
Infinite loop
Good luck :)
First, the monthly interest is incorrectly calculated. On one hand the algorithm treats it as non-compound interest:
monthlyIR = annualinterestRate/12.0
but earlier:
monthly_lower = balance/12
and later, in the loop:
new_balance *= monthlyIR
which implies that it is a compound interest. But the code does not converge for another reasons. You are calculating the impact of interest on the debt incorrectly. It should be:
new_balance *= monthlyIR + 1
The problem is that new_balance should be increased by monthly interest rate. For example, if the monthly IR is 0.005, then the original code lowers the balance to 0.005 of its previous size. Unfortunately for us, borrowers, our debt does not shrinks to 1/200 of its original value every month, but rather it increases by extra 1/200 of the original debt. A debt of 1000$ becomes 1005$, i.e., the debt should be multiplied by 1.005 instead of 0.005.
The original code will converge (incorrectly) only with annual interest rates of 12 and above (1200%), since it makes monthly IR >= 1 (100%). This way, the multiplication does not lower the debt in the original code.
The full code is:
def bisection(balance,annualinterestRate):
# This is most likely an incorrect monthly IR
# I suspect it should be:
# monthlyIR = pow(1+annualinterestRate, 1/12.0) - 1
monthlyIR = annualinterestRate/12.0
new_balance = balance
monthly_lower = balance/12
monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
epsilon = 0.01
print(monthly_lower,monthly_upper)
while abs(new_balance) >= epsilon:
new_balance = balance
print(monthly_lower,monthly_upper)
payment = (monthly_upper + monthly_lower)/2
for i in range(12):
new_balance -= payment
new_balance *= monthlyIR + 1
if new_balance > 0:
monthly_lower = payment
else:
monthly_upper = payment
return round(payment,2)
Besides, there is a trivial formula to calculate this in one line, instead of using bisection. Look it up, or derive it.
For example, read here
Following is the problem set from MIT opencourseware
Part C: Finding the right amount to save away
Your semiannual raise is .07 (7%)
Your investments have an annual return of 0.04 (4%)
The down payment is 0.25 (25%) of the cost of the house
The cost of the house that you are saving for is $1M.
I am now going to try to find the best rate of savings to achieve a down payment on a $1M house in 36 months. And I want your savings to be within $100 of the required down payment.I am stuck with the bisection search and 'It is not possible to pay the down payment in three years.' this output. I am new to programmers and English.Any help is appreciated.
And here is my code:
starting_salary = float(input("Enter your starting salary: "))
months_salary = starting_salary/12
total_cost = 1000000.0
semi_annual_rate = .07
investment_return = 0.04
down_payment = total_cost * 0.25
r = 0.04
current_savings = 0.0
#months = 36
tolerance = 100
steps = 0
high = 1.0
low = 0.0
guess = (high+low)/2.0
total_salaries = 0.0
def calSavings(current_savings,months_salary,guess,month):
for months in range(0,37):
if months%6==1 and months >1:
months_salary=months_salary*(1+semi_annual_rate)
current_savings = current_savings + months_salary * guess
current_savings = current_savings * (1+0.04/12)
return(current_savings)
current_savings = calSavings(current_savings,months_salary,guess,1)
while abs(current_savings-down_payment)>=100:
if current_savings < down_payment:
low = guess
elif current_savings > down_payment:
high = guess
else:
print("It is not possible to pay the down payment in three years.")
break
guess = (low+high)/2
steps = steps +1
print("Best saving rate: ", guess)
When I run this code, it will be stuck. I don't know why.
And I don't know how to determine which is the condition of output this "It is not possible to pay the down payment in three years."
I have seen Similar questions on stackoverflow like this and this but I am not quite followed.
# user input
annual_salary = float(input('Enter your annual salary: '))
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.`enter code here`
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)
I've already addressed most of my points in the comments, but I will recap:
You are trying to solve a problem using a method called recursive solving, in this case using the bisection method.
The steps are as follows:
start with an initial guess you chose 0.5
Perform your calculations in a loop and iterate the initial guess, in this case you must account for the following:
Maximum number of steps before failure, remember we can always add 2 values and divide by 2, your result will tend to 0.999999.. otherwise
A certain tolerance, if your step size is not small enough 25% of 1 M is 250 000 and you might never hit that number exactly, that' why you make a tolerance interval, for example: anything between 250 000 and 251 000 --> break loop, show result.
Your if statements for changing low and high to adjust guess are correct, but you forget to re-initialize savings to 0 which means savings was going to infinity.
Now that's all said, here's a working version of your code:
starting_salary = 100000 # Assuming Annual Salary of 100k
months_salary = starting_salary/12
total_cost = 1000000.0
semi_annual_rate = .07
investment_return = 0.04
down_payment = total_cost * 0.25
print("down payment: ", down_payment)
r = 0.04
current_savings = 0.0
#months = 36
tolerance = 100
steps = 0
high = 1.0
low = 0.0
guess = (high+low)/2.0
total_salaries = 0.0
tolerance = down_payment/100 # I chose this tolerance to say if my savings are between [down_payment - (downpayment + down_payment/100)] result is admissible. (this is quite a high tolerance but you can change at leisure)
def calSavings(current_savings,months_salary,guess,month):
for months in range(0,37):
if months%6==1 and months >1:
months_salary=months_salary*(1+semi_annual_rate)
current_savings = current_savings + months_salary * guess
current_savings = current_savings * (1+0.04)
return(current_savings)
while abs(current_savings-down_payment)>=100:
current_savings = calSavings(current_savings,months_salary,guess,1)
if current_savings < down_payment:
low = guess
current_savings = 0.
elif current_savings > down_payment + tolerance:
high = guess
current_savings = 0.
if (steps > 100): # I chose a maximum step number of 100 because my tolerance is high
print("It is not possible to pay the down payment in three years.")
break
guess = (low+high)/2
steps = steps +1
print("Best saving rate: ", guess)
print("With current savings: ", current_savings)
Output:
down payment: 250000.0
Best saving rate: 0.656982421875
With current savings: 250072.3339667072
[Finished in 0.08s]
For answer visit the GitHub link - MIT has added Problem set solutions
Part C: Finding the right amount to save away
In Part B, you had a chance to explore how both the percentage of your salary that you save each month and your annual raise affect how long it takes you to save for a down payment. This is nice, but suppose you want to set a particular goal, e.g. 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:
Your semiannual raise is .07 (7%)
Your investments have an annual return of 0.04 (4%)
The down payment is 0.25 (25%) of the cost of the house
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.
In ps1c.py, 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. You should be able to reuse some of the code you wrote for part B in this problem.
Because we are searching for a value that is in principle a float, we are going to limit ourselves 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 difference 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. By using this range, there are 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%).
Try different inputs for your starting salary, and see how the percentage you need to save changes to reach your desired down payment. Also keep in mind it may not be possible for to save 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. Please make your program print results in the format shown in the test cases below.
Note: There are multiple right ways to implement bisection search/number of steps so your results may not perfectly match those of the test case.
Hints:
● There may be multiple savings rates that yield a savings amount that is within $100 of the required down payment on a $1M house. In this case, you can just return any of the possible values.
● Depending on your stopping condition and how you compute a trial value for bisection search, your number of steps may vary slightly from the example test cases.
● Watch out for integer division when calculating if a percentage saved is appropriate and when calculating final decimal percentage savings rate.
● Remember to reset the appropriate variable(s) to their initial values for each iteration of bisection search.
I'm learning the Python 2.5.4 programming language using the MIT OCW Scholar course 6.00.
I have written a program, but with the same input, my program's output differs from the output that the MIT people have shown the program to produce.
I wish to write a Python 2.5.4 program that will get current outstanding balance and annual interest rate as input from the user, and then uses the bisection search method to find the minimum fixed minimum monthly payment that would cause the balance to fall below zero within 12 months. Then the program displays the right monthly amount, the number of months needed to claer the outstanding amount, and the final balance.
Here's my code:
# Start of code
balance = float(raw_input('Enter the outstanding balance on your credit card: '))
interestRate = float(raw_input('Enter the annual credit card interest rate as a decimal: '))
lower = balance / 12.0
upper = ( balance * ( 1 + interestRate / 12.0 ) ** 12.0 ) / 12.0
payment = ( lower + upper ) / 2.0
currentBalance = balance
while currentBalance > 0:
for months in range(1, 13):
currentBalance = currentBalance * ( 1 + interestRate / 12.0 ) - payment
if currentBalance <= 0:
break
if currentBalance <= 0:
break
else:
lower = payment
payment = ( lower + upper ) / 2.0
currentBalance = balance
print 'RESULT'
print 'Monthly payment to pay off debt in 1 year:', '$' + str(round(payment, 2))
print 'Number of months needed:', months
print 'Balance:', '$' + str(round(currentBalance, 2))
#End of code
Does my code do the desired job? If not, where lies the problem? And, how to fix it? Even if the program is right, in what ways can it be improved?
Please do bear in mind that I'm a only a beginner.
Regards.
You have a couple of typos (which may have been introduced when copying into your posting):
you split balance on your credit / card: across a line-ending, which will give a SyntaxError
currentBalance = currentBalance * ( 1 + interestRate / 12.0 ) payment is missing a - operator before payment
The first logical error is
if currentBalance <= 0:
break
... you stop as soon as you find a higher than needed payment; you only ever increase possible payment values (lower = payment), never decrease it (you should have a clause leading to upper = payment, otherwise your bisection search will be lopsided).
Once you do that, you will have to add a new test to know when to stop looping. What is your target accuracy - payment to the nearest cent? How will you know when you have found it?
My only other suggestion would be to improve your code organization by defining some operations as functions - get_float(prompt) and final_balance(current_balance, interest_rate, num_payments) are obvious candidates.