计导第四次作业 (Past)

10205102406 edited 3 年,5 月前

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 pointsLet 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)

avatar

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))

avatar

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))

avatar

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))

avatar

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)

avatar

5、(15 points)《编程导论》2.4节讨论for循环,(A)请说明Pythonfor i in range(a,b,step)的循环结构和C语言的 for(i=a; i的差异?(*B)解释for i in range(len(L)),* i=0; while ii+=1 结构的差异?(C)解释for e in LL是一个列表)是如何遍历的?假设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],[]))

avatar

7、这题可以两人合作,写下合作同学的名字及学号。请同学们把你的代码拷贝到word报告中,并将程序的运行结果截图粘贴到代码下方。

大舅要贷款买房,知道你是华师大计算机专业的学生,认为你什么都懂,所以就请你为他解释并分析贷款的计算方式。你学了基本编程后自然功力大为增进,因此准备写个Python程序来回答大舅的疑问。

这个题目包含三个层面:探索、编程及分析,我们要自行探索现在银行最通用的贷款方式“等额本息”的原理,我们要利用编程计算出还款金额、每年所付出本金和利息,等等,最后是分析利弊得失。完成这个题目后,你已经比你中学同学上商学院一年级的要厉害多了!

首先假设本金为A,月利率为r,贷款期限为n个月,

a) 5 points)使用等额本息方式,请推导并说明每月还款金额的公式,请自行到网上探索;

avatar

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))

avatar

是啊大舅

c) 5 points)重复前面题目b),但是贷款期限为20年;利息是不是少了很多?

avatar

是啊大舅

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))

avatar

大舅你只要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)

avatar

制作者:姜博远