ps1a.py
问题描述:
毕业后的你想买一套自己的房子,通过工作和理财获取收益,编程计算出经过多少个月,可以支付房子的首付。
变量说明:
从控制台输入年薪、每月存钱比例和房子的总价
annual_salary 年薪
portion_saved 每月存钱比例
total_cost 房子总价
current_saving 当前存款
month_salary 年薪
r = 0.04 理财收益率
portion_down_payment=0.25 房子的首付比例
每月的当前存款计算方式如下:
// 当前存款=上月存款+上月存款收益+本月存的月薪
current_saving+=current_saving*r/12+monthly_salary*portion_saved
ps1a.py 完整代码如下
# -*- coding: utf-8 -*-
# @File : ps1a.py
# @Author: ddmm
# @Date : 2020/7/11
# @Desc :
annual_salary=int(input("Enter your annual salary:"))
portion_saved=float(input("Enter the perdent of your salary to save,as a decimal:"))
total_cost=int(input("Enter the cost of your dream home:"))
monthly_salary=annual_salary/12
r=0.04
portion_down_payment=0.25
current_saving=0
month_num=0
while current_saving<total_cost*portion_down_payment:
current_saving+=current_saving*r/12+monthly_salary*portion_saved
month_num+=1
print("Number of months:",month_num)
ps1b.py
问题描述:
在ps1a.py的基础上,现在每隔半年会加薪一次
变量说明:
从控制台输入加薪比例
semi_annual_raise 加薪比例
ps1b.py 完整代码如下
# -*- coding: utf-8 -*-
# @File : ps1b.py
# @Author: ddmm
# @Date : 2020/7/11
# @Desc :
annual_salary=int(input("Enter your annual salary:"))
portion_saved=float(input("Enter the perdent of your salary to save,as a decimal:"))
total_cost=int(input("Enter the cost of your dream home:"))
semi_annual_raise=float(input("Enter the semiannual raise, as a decimal:"))
monthly_salary=annual_salary/12
r=0.04
portion_down_payment=0.25
current_saving=0
month_num=0
payment=total_cost*portion_down_payment
while(current_saving<payment):
current_saving+=current_saving*r/12+monthly_salary*portion_saved
month_num+=1
# 与ps1a.py 的不同支出,每半年加一次薪水
if month_num%6==0:
monthly_salary*=(1+semi_annual_raise)
print("Number of months:",month_num)
ps1a.py
问题描述:
现在的你想在毕业3年内,买一套自己的房子(支付25%的首付即可),同样你通过努力工作和认真理财获取收益,同时你还有半年一次的加薪。编程计算出每个月最低的存款比例。
问题分析:
- 由于计算当前存款的方式没变,所以我们对ps1b.py中的部分代码进行重用
# 重用pa1b.py中的代码
while month_num<36:
month_num += 1
current_saving += current_saving * r / 12 + monthly_salary * portion_saved
if current_saving>=payment-80:
return True
if month_num % 6 == 0:
monthly_salary *= (1 + semi_annual_raise)
return False
- 因为题目需要保留两位小数,通过[0,10000]之间的整数,来取代[0.0,1.0]之间的数,通过二分查找取代遍历,来快速找到合适的存款比例,
ps1c.py 完整代码如下
# -*- coding: utf-8 -*-
# @File : ps1c.py
# @Author: ddmm
# @Date : 2020/7/11
# @Desc :
def check(annual_salary,portion_saved):
total_cost = 1000000
monthly_salary = annual_salary / 12
r = 0.04
portion_down_payment = 0.25
semi_annual_raise = 0.07
current_saving = 0
month_num = 0
month_max=36
payment = total_cost * portion_down_payment
# 重用pa1b.py中的代码
while month_num<36:
month_num += 1
current_saving += current_saving * r / 12 + monthly_salary * portion_saved
if current_saving>=payment-80:
return True
if month_num % 6 == 0:
monthly_salary *= (1 + semi_annual_raise)
return False
annual_salary=int(input("Enter your annual salary:"))
left,right=0,10000
if not check(annual_salary,right/10000):
print("It is not possible to pay the down payment in three years.")
else:
bin_times = 0
# 控制save_rate精度
while right-left>=50:
bin_times+=1
mid = (left + right)/2
if check(annual_salary,mid/10000):
right=mid-1
else:
left=mid+1
print("Best savings rate:%.4f" % (mid / 10000)) # 输出结果
print("Steps in bisection search:", bin_times)
MIT6.0001课程 代码在我的github账号里同步更新,欢迎大家一起讨论交流。
https://github.com/ddmm7/MIT6.0001