10205102406 edited 4 年,1 月前
This is a past version of blog 计导第四次作业
Introduction to Computer Science
Homework 4
沙行勉教授
Due Date: 10am, Oct 29, 2020
打好基础的唯一方式就是主动学习,多做练习,请同学阅读计算机导论的第二章,完成编程导论第二章,自己开始看编程导论的第三章。这不是准备高考,你已经是大学生了,要自己学习知识。当作有趣的知识来阅读。好吗?
我们的作业可能比其他课程多,即使如此增加了老师和助教的负担,但是为了你们的好,为了国家社会的人才培养,我们必须努力。同学们更要用功,不要浪费这个宝贵的资源。大多数的同学原来都是毫无基础的,但是完成这些作业后,同学们的进步是可喜可贺的,你们的努力有了收货,你们已经比其他学校的同学要强了,并且距离在持续拉开。
我鼓励同学间互相讨论,请多帮助别人,好人有好报。 But do not directly copy others, or you will get punished.报告文字可以用中文或英文,不要用其他TA看不懂的语言。
我们特别准备了强大的助教TA小组,有四位研究生。你们若有问题尽量问他们。他们负责评定各位同学的作业。TA小组包含了 张昊,姚舜,戚潘杰,郝杉。
课程QQ群:108208962(2020计算机科学导论)。
提交作业要求:
将作业发送到邮箱: csintro@163.com
作业命名格式: 学号_姓名_第X次作业(如学号_姓名_第一次作业)
截止时间: 见作业标示。
答疑:每周二、周四,晚上7点到8点半,地点在理科大楼B522。 欢迎同学过来。TA等着你们。
对所有编程的题目, 请同学们把你的代码拷贝到你的报告word中,并将程序的运行结果截图粘贴到代码下方。有问题可以问TA或其他同学。请有编程经验的同学多帮助别人,但是不是让他们直接拷贝程序。
1、(20 points)Let ID=your student ID. Then, let k=ID %2. So k can be 0 or 1. Based on the value of your ID, you get value of k. Please tell us your k value.
If k==0: 做《计算机导论》练习题2.2.1, 2.2.3, 2.2.5,**2.2.7, 2.2.9, 2.2.11
If k==1: 做《计算机导论》练习题*2.2.2, 2.2.4,* 2.2.6*,2.2.8, 2.2.10. 2.2.12*
def shift(n, k):
res = ""
while(n != 0):
a = n%k
n //= k
if(a<10): res += str(a)
else: res += chr(55+a)
return res[::-1]
print("2.2.1", shift(78,2))
print("2.2.3", shift(358,16),shift(358,8))
print("2.2.5", 10*16**3+10*16**2+0+12)
print("2.2.7", "B")
print("2.2.9", 149.4375, 1205.6)
print("2.2.11", 8, 201)
2、(10 points)《计算机导论》程序练习2.2.1,
def shift(n, k):
res = 0
for i in n:
res *= k
if i != '0':
res += int(i)
return res
n = input("n:")
k = int(input("k:"))
print(shift(n, k))
3、(10 points)《计算机导论》程序练习2.2.2
def shift(n, k):
res = ""
while(n != 0):
a = n%k
n //= k
res += str(a)
return res[::-1]
n = int(input("n:"))
k = int(input("k:"))
print(shift(n, k))
4、(15 points)这题可以两人合作,写下合作同学的名字及学号。《编程导论》老虎机游戏的练习题2.5.4
import random
def tiger(money, k):
count = 0
while money > 0 and count != k:
money -= 1
r = random.random()
if r < 0.6:
prize = 0
elif r < 0.8:
prize = 1
elif r < 0.9:
prize = 2
else:
prize = 3
money += prize
count += 1
return count,money
print("在第%d轮结束,剩余:%d"%tiger(10,10))
print("在第%d轮结束,剩余:%d"%tiger(10,20))
print("在第%d轮结束,剩余:%d"%tiger(10,30))
print("在第%d轮结束,剩余:%d"%tiger(10,40))
import random
def tiger(money):
m = money
while m > 0:
m -= 1
r = random.random()
if r < 0.6:
prize = 0
elif r < 0.8:
prize = 1
elif r < 0.9:
prize = 2
else:
prize = 3
m += prize
if(m > money):
return 1
return 0
count = 0
for i in range(100):
count += tiger(10)
print(count)
5、(15 points)《编程导论》2.4节讨论for循环,(A)请说明Python的for i in range(a,b,step)的循环结构和C语言的 for(i=a; i的差异?(*B)解释for i in range(len(L)),* 与 i=0; while i:i+=1 结构的差异?(C)解释for e in L(L是一个列表)是如何遍历的?假设L在循环中被改变了,接下去是新列表还是旧列表被遍历?它比较像for i in range(len(L)), 还是 while i结构**?
A 首先,python中不需要提前创建变量i,而该c语句则需要在之前先定义i;其次,python实际上是遍历了range函数产生的list,会有额外的消耗,而c则确实是每次改变i,只需要常数空间;但同时,python不会在循环体中改变i,但c可以,甚至可以改变b和step,而python不可以。
B 首先,for循环的range产生list占用了空间,而while则是常数空间;其次while中i和len(L)可以改变,for中则不行。
C 从首个元素开始顺序遍历L。旧列表。像for。
6、(10 points)《编程导论》习题2.14。请不要用递归完成此程序。我们以后考试时可能会问你此题如何用递归完成,但是现在请不用。
def merge(L1, L2):
res = []
if len(L1) == 0:
return L2
elif len(L2) == 0:
return L1
a = 0
b = 0
while(a<len(L1) and b<len(L2)):
if(L1[a]>L2[b]):
res.append(L2[b])
b+=1
else:
res.append(L1[a])
a+=1
while(a<len(L1)):
res.append(L1[a])
a += 1
while (b < len(L2)):
res.append(L2[b])
b += 1
return res
print(merge([1,4,7],[2,5]))
print(merge([1,2,3],[]))
7、这题可以两人合作,写下合作同学的名字及学号。请同学们把你的代码拷贝到word报告中,并将程序的运行结果截图粘贴到代码下方。
大舅要贷款买房,知道你是华师大计算机专业的学生,认为你什么都懂,所以就请你为他解释并分析贷款的计算方式。你学了基本编程后自然功力大为增进,因此准备写个Python程序来回答大舅的疑问。
这个题目包含三个层面:探索、编程及分析,我们要自行探索现在银行最通用的贷款方式“等额本息”的原理,我们要利用编程计算出还款金额、每年所付出本金和利息,等等,最后是分析利弊得失。完成这个题目后,你已经比你中学同学上商学院一年级的要厉害多了!
首先假设本金为A,月利率为r,贷款期限为n个月,
a) (5 points)使用”等额本息”方式,请推导并说明每月还款金额的公式,请自行到网上探索;
b) (10 points)编写Python程序,假设贷款的本金为80万,年利率6%(月利率是它的1/12),贷款30年,(1)求出每月还款金额;(2)列出每年归还的本金及利息,以及全部交付的本金及利息;想想为什么要付这么多的利息啊?你大舅问你是不是前几年付的钱大部分都是付给利息啊?
def pay(A,r,n):
t = (1+r)**n
return A*r*t/(t-1)
A = 800000
r = 0.005
n = 360
rp1 = 1+r
paid_principal_sum = 0
paid_interest_sum = 0
average = pay(A,r,n)
for i in range(0,360):
paid_interest = A * r
A = A * rp1 - average
paid_principal = average - paid_interest
paid_principal_sum += paid_principal
paid_interest_sum += paid_interest
print("当前是第%d年第%d月,支付本金:%f,利息:%f"%(i//12+1, i%12+1, paid_principal, paid_interest))
print("共支付本金:%f,利息%f" %(paid_principal_sum, paid_interest_sum))
是啊大舅
c) (5 points)重复前面题目b),但是贷款期限为20年;利息是不是少了很多?
是啊大舅
d) (10 points)大舅为了要节省利息,所以想早点还款,如前所述,贷款期限为20年,但是在第三年结束时大舅提前多归还银行本金20万(注意是本金),注意这个时候大舅归还了3年原来每月还的本金部分和额外的20万本金。若以后每月还款金额维持原状(最后一个月还款数可以较少),那么本来需要240个月还清的贷款,现在需要多少个月还清?不准用log在公式上计算。
def pay(A,r,n):
t = (1+r)**n
return A*r*t/(t-1)
A = 800000
r = 0.005
n = 240
rp1 = 1+r
paid_principal_sum = 0
paid_interest_sum = 0
average = pay(A,r,n)
for i in range(0,36):
paid_interest = A * r
A = A * rp1 - average
paid_principal = average - paid_interest
paid_principal_sum += paid_principal
paid_interest_sum += paid_interest
print("当前是第%d年第%d月,支付本金:%f,利息:%f"%(i//12+1, i%12+1, paid_principal, paid_interest))
print("共支付本金:%f,利息%f" %(paid_principal_sum, paid_interest_sum))
A -= 200000
print(A)
i = 37
while(A>average):
paid_interest = A * r
A = A * rp1 - average
paid_principal = average - paid_interest
paid_principal_sum += paid_principal
paid_interest_sum += paid_interest
print("当前是第%d年第%d月,支付本金:%f,利息:%f" % (i // 12 + 1, i % 12 + 1, paid_principal, paid_interest))
i+=1
print("共支付本金:%f,利息%f" % (paid_principal_sum, paid_interest_sum))
print("现在是第%d月,剩余%f,本月底可付清"%(i,A))
大舅你只要162个月就能还完了
e) (10 points)另外一种贷款计算方式叫做“等额本金”,请到网上查询。请以20年贷款80万,年利率6%为例,为简单起见,以“月”为单位,不以“天”为单位,请编程计算出使用等额本金方式所支付的利息总数,以及列出前12个月每月所还的金额,并且请从利息的角度说明它与等额本息的差异,请分析两者,等额本息和等额本金,的优劣,为什么现在银行都喜欢用等额本息方式来计算贷款?
A = 800000
r = 0.005
n = 240
rp1 = 1+r
paid_interest_sum = 0
base = A/n
for i in range(n):
interest = (A-base*i)*r
paid_interest_sum+=interest
if(i<12):
print("第%d月支付:%f" %(i+1,interest+base))
print("总利息:%f"%paid_interest_sum)
制作者:姜博远