Problem Set 1
文章目录
基本目标
A Very Simple Program: Raising a number to a power and taking a logarithm
- This problem set will introduce you to using control flow in Python and formulating a computational solution to a problem. It will also give you a chance to explore bisection search. This problem set has three problems. You should save your code for the first problem as ps1a.py , the second problem as ps1b.py and the third problem as ps1c.py , and make sure to hand in all three files. Don’t forget to include comments to help us understand your code!
- 本习题集将向您介绍如何在Python中使用控制流,并制定问题的计算解决方案。它也将给你一个机会探索二分检索。这个习题集有三个问题。您应该将第一个问题的代码保存为ps1a.py,第二个问题保存为ps1b.py,第三个问题保存为ps1c.py,并确保提交所有三个文件。别忘了添加注释来帮助我们理解您的代码!
作业A House Hunting
要求
-
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:
-
你已经从麻省理工学院毕业,现在有一份很棒的工作!你搬到旧金山湾区,决定开始存钱买房。由于湾区的房价很高,你意识到你要攒几年钱才能付得起房子的首付。在A部分中,我们将根据以下假设,确定您需要多长时间储蓄足够的钱来支付首付款:
-
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)
-
你梦想之家的总费用为 total_cost。
-
支付首付部分所需的费用为 portion_down_payment。为简单起见,假设首付部分=0.25(25%)。
-
您目前存下的金额为 current_savings。你可以从现在节省0美元开始。
-
假设你明智地投资你当前的储蓄,年回报率为r(换句话说,在每个月底,你会收到额外的current_savings*r/12基金,用于存入你的储蓄——12是因为r是年利率)。假设你的投资回报率为r=0.04(4%)。
-
假设你的年薪是annual_salary。
-
假设你每个月都要拿出一定数额的工资来存首付。把那部分叫做portion_saved。此变量应为十进制形式(即0.1表示10%)。
-
在每个月底,你的储蓄将增加你的投资回报,加上你一部分的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.
-
写一个程序来计算你需要多少个月才能攒够钱付定金。您将希望您的主变量是float,因此您应该将用户输入强制转换为float。
-
Your program should ask the user to enter the following variables:
- The starting annual salary (annual_salary)
- The portion of salary to be saved (portion_saved)
- The cost of your dream home (total_cost)
-
程序应要求用户输入以下变量:
- 起始年薪(annual_salary)
- 存工资比例(portion_saved)
- 梦想之家的花费(total_cost)
提示
为了帮助你开始,这里有一个大致的阶段:
- 检索用户输入。如果需要获取用户输入的帮助,请查看input()。对于这个问题集,您可以假设用户将输入有效的输入(例如,当您希望输入int时,他们不会输入字符串)
- 初始化一些状态变量。你应该决定你需要什么信息。请注意年和月的区别
- 尝试不同的输入,看看需要多长时间来节省首付款。
- 请使您的程序以下面测试用例中显示的格式来输出结果。
参考代码
import numpy
annual_salary = float(input('Enter your annual salary:'))
portion_saved = float(input('Enter the percent of your salary to save, as a decimal:'))
total_cost = float(input('Enter the cost of your dream home:'))
r = 0.04
portion_down_payment = 0.25*total_cost
current_savings = 0.0
monthly_salary = annual_salary/12
num_of_month = 0
while (current_savings<portion_down_payment):
current_savings = current_savings + monthly_salary*portion_saved + current_savings*r/12
num_of_month += 1
print('Number of months:%d' %(num_of_month))
作业B Saving, with a raise
要求
- In Part A, we unrealistically assumed that your salary didn’t change. But you are an MIT graduate, and clearly you are going to be worth more to your company over time! So we are going to build on your solution to Part A by factoring in a raise every six months.
- 在A部分,我们不切实际地假设你的薪水没有变化。但你是麻省理工学院的毕业生,很明显,随着时间的推移,你对公司的价值会更高!所以我们将在你的A部分解决方案的基础上,每六个月考虑一次加薪。
In ps1b.py , copy your solution to Part A (as we are going to reuse much of that machinery). Modify your program to include the following
-
Have the user input a semi-annual salary raise semi_annual_raise (as a decimal percentage)
-
After the 6 month, increase your salary by that percentage. Do the same after the 12 month, the 18 month, and so on.
-
把你半年工资涨幅设置为semi_annual_raise
-
每6个月涨一次工资
- 新输入变量:半年工资涨幅 (semi_annual_raise)
提示
推荐顺序
- Retrieve user input.
- Initialize some state variables. You should decide what information you need. Be sure to be careful about values that represent annual amounts and those that represent monthly amounts.
- 初始化变量
- Be careful about when you increase your salary – this should only happen after the 6 th , 12th , 18th month, and so on.
- 只在第6个月、12个月等后涨工资
参考代码
import numpy
annual_salary = float(input('Enter your annual salary:'))
portion_saved = float(input('Enter the percent of your salary to save, as a decimal:'))
total_cost = float(input('Enter the cost of your dream home:'))
semi_annual_raise = float(input('Enter the semi-annual raise, as a decimal:'))
r = 0.04
portion_down_payment = 0.25*total_cost
current_savings = 0.0
monthly_salary = annual_salary/12
num_of_month = 0
while (current_savings<portion_down_payment):
if ((num_of_month != 0)and(num_of_month%6 == 0)):
annual_salary = annual_salary*(1+semi_annual_raise)
monthly_salary = annual_salary/12
current_savings = current_savings + monthly_salary*portion_saved + current_savings*r/12
num_of_month += 1
print('Number of months:%d' %(num_of_month))
作业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.
-
在第二部分中,你有机会探究你每月储蓄的工资百分比和你的年度加薪是如何影响你为首付储蓄的时间。这很好,但是假设你想设定一个特定的目标,例如三年内支付得起首付。为了达到这个目标,你每个月应该节省多少钱?在这个问题中,你要写一个程序来回答这个问题。为了简化事情,假设:
- 你每半年加薪0.07(7%)
- 你的投资年回报率为0.04(4%)
- 首付款是房屋成本的0.25%(25%)
- 这所房子价格是100万美元。
-
You are now going to try to find the best rate of savings to achieve a down payment on a 1M dollars house in 36 months. Since hitting this exactly is a challenge, we simply want your savings to be within 100 dollars of the required down payment.
-
你现在要努力寻找最佳储蓄率,在36个月内实现100万美元房子的首付。我们只需令储蓄结果与实际首付价格差距在100美元内就可以了。
-
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.
-
在ps1c.py中,编写一个计算最佳储蓄率的程序,作为起始工资的函数。您应该使用二分检索来帮助您高效地执行此操作。你应该跟踪你的二分检索完成所需的步骤数。在这个问题中,您应该能够重新用第B部分编写的代码
-
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%).
-
因为我们正在寻找一个原则上是一个浮点数的值,所以我们将把精度限制在两个小数点(即,我们可能希望节省7.04%或0.0704个小数点,但我们不必担心7.041%和7.039%之间的差异)。这意味着我们可以搜索0到10000之间的整数(使用整数除法),然后将其转换为十进制百分比(使用浮点除法),以便在计算36个月后current_saving时使用。通过使用这个范围,我们只搜索有限数量的数字,而不是0到1之间的无限个小数。这个范围有助于防止无限循环。我们使用0到10000的原因是为了在0%到100%的范围内增加两个小数位。你的代码应该打印出一个十进制数(例如0.0704代表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. P lease make your program print results in the format shown in the test cases below.
-
尝试不同的输入为您的起薪,看看您需要保存的百分比,以达到您想要的首付。同时也要记住,在一年半的时间里,为一些薪水攒下首付是不可能的。在这种情况下,您的功能应该通知用户,不可能在36个月内用打印对账单保存首付款。请让您的程序以下面测试用例中显示的格式输出结果。
提示
- There may be multiple savings rates that yield a savings amount that is within 100 dollars of the required down payment on a 1M dollars 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.
- 记住,在二分检索的每次迭代中,都要将适当的变量重置为初始值。
参考代码
代码运行的二分法执行count次数比范例结果多很多次。应该是能更优化,但目前我不清楚该怎么修改,请教各位指点。
import numpy
annual_salary_start = float(input('Enter your annual salary:'))
annual_salary = annual_salary_start
total_cost = 1000000
semi_annual_raise = 0.07
r = 0.04
portion_down_payment = 0.25*total_cost
current_savings = 0.0
monthly_salary = annual_salary/12
num_of_month = 36
count = 0
start = 0
end = 10000
portion_saved = (start+end)/2
while(((end-start)>1)and(current_savings>(portion_down_payment-100))):
current_savings = 0
for i in range(36):
if ((i != 0)and(i%6 == 0)):
annual_salary = annual_salary*(1+semi_annual_raise)
monthly_salary = annual_salary/12
current_savings = current_savings + monthly_salary*portion_saved/10000 + current_savings*r/12
if(current_savings<(portion_down_payment-100)):
start = portion_saved
else:
end = portion_saved
portion_saved = (start+end)//2
annual_salary = annual_salary_start
monthly_salary = annual_salary/12
count += 1
if(current_savings<(portion_down_payment-100)):
print('It is not possible to pay the down payment in three years.')
else:
print('Best savings rate:%f' %(portion_saved/10000))
print('Steps in bisection search:%d'%(count))