数据科学作业2

又到了穿格子衫的时候了

Posted by ASI on October 20, 2018

第二节课课后习题

作业里要求用户输入的部分我都偷懒做成了函数,然后调用了几次这个函数测试一下。

1、宇宙速度(英语:cosmic velocity),是指物体从地球出发,要摆脱天体引力的束缚所需要的速度大小。例如第一宇宙速度的大小约为7.9km/s,达到这个值,物体就可以围绕地球做圆周运动。其它宇宙速度的值以及相关论述,请自行查阅维基百科中的“宇宙速度”词条。然后根据所得数值,编写程序,当用户输入某一速度值的时候,判断物体以该速度运动的结果。

简单的if,elif的使用

def speed(v) :
    if v < 7.9 :
        print("你没能上升到新的境界")
    elif v < 11.2 :
        print("你上升到了新的境界: 绕地球做圆周运动")
    elif v < 16.7 :
        print("你上升到了新的境界: 跑出地球")
    elif v < 525 :
        print("你上升到了新的境界: 跑出太阳系")
    else :
        print("你上升到了新的境界: 跑出银河系")

speed(1.14514)
speed(11.4514)
speed(114.514)
speed(1145.14)

输出结果:

你没能上升到新的境界
你上升到了新的境界: 跑出地球
你上升到了新的境界: 跑出太阳系
你上升到了新的境界: 跑出银河系
2、编写程序,判断用户输入的数字是偶数还是奇数。

def eotest(x) :
    if x % 2 :
        print("odd")
    else :
        print("even")
eotest(1)
eotest(2)

输出结果:

odd
even
3、编写程序,寻找能够被17整除的三位的正整数。

利用列表生成式一行解决

print([x for x in range(100, 1000) if not x % 17])

输出结果:

[102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 272, 289, 306, 323, 340, 357, 374, 391, 408, 425, 442, 459, 476, 493, 510, 527, 544, 561, 578, 595, 612, 629, 646, 663, 680, 697, 714, 731, 748, 765, 782, 799, 816, 833, 850, 867, 884, 901, 918, 935, 952, 969, 986]
4、在求解一元二次方程的时候,一般首先要检查判别式的正负,如果为负数,则该方程没有实根。编写程序,根据用户输入的方程式的系数,判断是否有实根;如果有则输出该结果,如果没有,输出提示信息。

import math
def function(a, b, c) :
    if a == 0 :
        print("这是个一次方程,愤怒。自己算去吧!")
        return
    delta = b * b - 4 * a * c
    if delta < 0 :
        print("没有实数解哦")
    elif delta == 0 :
        x = (-b) / (2 * a)
        print("解是:", x)
    else :
        x1 = (-b + math.sqrt(delta)) / (2 * a)
        x2 = (-b - math.sqrt(delta)) / (2 * a)
        print("解是:" , x1 , "和" , x2)
function(11, 45, 14)
function(114, 5, 14)
function(1, 2, 1)
function(0, 114, 514)

输出结果:

解是: -0.33924323826150365 和 -3.751665852647587
没有实数解哦
解是: -1.0
这是个一次方程,愤怒。自己算去吧!
5、将字典{‘book’: [‘python’, ‘djang’, ‘data’], ‘author’: ‘laoqi’, ‘publisher’: ‘phei’}的“键”“值”对互换,即原来的键作为值,原来的值作为键。

这里需要注意,字典的存储结构是hashtable, 所以key值必须得是immutable. 注意到list是mutable, 所以转换list的时候要把list编程tuple.

dic = {'book': ['python', 'djang', 'data'], 'author': 'laoqi', 'publisher': 'phei'}
dic2 = {}
for (key, value) in dic.items() :
    if isinstance(value, list) :
        dic2[tuple(value)] = key
    else :
        dic2[value] = key
print(dic2)

输出结果:

{('python', 'djang', 'data'): 'book', 'laoqi': 'author', 'phei': 'publisher'}
6、根据进制转化的原理,编写程序,实现十进制整数向二进制数的转化(请读者搜索并阅读有关“进制转化”的原理知识)。

x = input()
print(bin(int(x))[2:])
7、到《国家数据》网站下载各省的价格指数(http://data.stats.gov.cn/easyquery.htm?cn=E0101),并用字典构建某个月的各省市的价格指数数据。
  • 计算全国价格指数平均值;
  • 找出高于平均值的省市(省市名称和价格指数)

import csv
from numpy import array
csvfile = open("hw2-7.csv", "r")
csvreader = csv.reader(csvfile)
dic = {}
data = [i for i in csvreader if len(i) == 14]
mtx = array(data)
namemtx = list(mtx[1:, 0:1])
mtx = map(lambda x: map(float, x), mtx[1:, 1:])
nummtx = [list(i) for i in mtx]
avg = sum(map(sum, nummtx)) / (len(nummtx) * len(nummtx[0]))  #平均值
cityavg = list(map(lambda x: sum(x) / len(x), nummtx))
for i in range(0, len(cityavg)) :
    if cityavg[i] > avg :
        dic[str(namemtx[i][0])] = cityavg[i]
print(dic) #将高出平均值的省市保存到dic中
csvfile.close()

输出结果:

{'北京市': 102.29999999999998, '河北省': 102.38461538461542, '辽宁省': 102.60000000000001, '吉林省': 101.9923076923077, '黑龙江省': 102.12307692307692, '江苏省': 102.06153846153846, '浙江省': 102.26153846153846, '江西省': 102.29230769230769, '山东省':
102.1846153846154, '河南省': 102.29999999999998, '广西壮族自治区': 102.21538461538461, '海南省': 102.73076923076923, '陕西省': 102.08461538461539, '甘肃省': 102.1846153846154, '青海省': 102.36923076923077, '宁夏回族自治区': 102.25384615384617, '新疆维
吾尔自治区': 102.5}

这道题啊嘶做了一整天……真是太可怕了。矩阵运算真是困难啊。因为python有好多黑科技,想尝试一下一行代码代替一个for的快感,结果为了想出这行代码怎么写反而花了更长的时间,最后一个忍不住了直接写了for偷懒,下次还是怎么舒服怎么写吧QWQ 话说洗数据这种东西,每种数据的洗法都不一样,还是学不来……

8、编写程序,输入一个5位数,判断它是不是回文数。例如“12321”是回文数。

def huiwen(x) :
    st = str(x)
    print(st == st[::-1])
huiwen(11451)
huiwen(11411)

输出结果

False
True

能用字符串就不用数学方法!

9、用“解析”的方式解决下列问题:
  • 找出列表[2, 4, -7, 19, -2, -1, 45]中小于零的数。
  • 某学生的各科考试成绩:{‘python’: 89, ‘java’: 58, ‘physics’: 65, ‘math’: 87, ‘chinese’: 74, ‘english’: 60},请找出大于这些科目平均分的学科。
  • 计算1到100的整数平方的和。

l = [2, 4, -7, 19, -2, -1, 45]
print(list(i for i in l if i > 0))

d = {'python': 89, 'java': 58, 'physics': 65, 'math': 87, 'chinese': 74, 'english': 60}
avg = sum(d.values()) / len(d)
print(dict(i for i in d.items() if i[1] > avg))

print(sum([x * x for x in range(1, 101)]))

输出结果:

[2, 4, 19, 45]
{'python': 89, 'math': 87, 'chinese': 74}
338350
10、编写函数,判断一个整数是否为素数,并用于寻找100以内的素数。

import math
def isprime(x) :
    if x == 1:
        return False
    for i in range(2, math.ceil(math.sqrt(x))):
        if not x % i :
            return False
    return True

print([i for i in range(1, 101) if isprime(i)])

输出结果:

[2, 3, 4, 5, 7, 9, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41, 43, 47, 49, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

PS:用筛法跑在范围变大的时候会快很多,不过懒得写了

11、编写函数,能够返回两个自然数在某范围内的公倍数,比如计算3和10在100以内的公倍数。

import math
def lcm(x, y) :
    return x * y / math.gcd(x, y)
def cm(x, y, range) :
    l = lcm(x, y)
    p = l
    ls = []
    while p < range :
        ls.append(p)
        p = p + l
    return ls

print(cm(3, 10, 100))

输出结果:

[30.0, 60.0, 90.0]

数论题,注意公式

12、林肯总统的《葛底斯堡演说》是著名的演讲(https://en.wikipedia.org/wiki/Gettysburg_Address),请通过网络获得演讲内容,并在程序中保存为字符串,然后完成如下功能:
  • 编写函数,统计演讲中所用的不重复单词;
  • 编写函数,统计每个不重复单词出现的次数,并按照次数从高到低排序。

import re
lec = 'Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate -- we can not consecrate -- we can not hallow -- this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us -- that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion -- that we here highly resolve that these dead shall not have died in vain -- that this nation, under God, shall have a new birth of freedom -- and that government of the people, by the people, for the people, shall not perish from the earth.'
low = lec.lower()
r = re.compile(r'[a-z]+')
wordlist = r.findall(low)
dic = {}
for word in wordlist :
    if word in dic.keys() :
        dic[word] += 1
    else :
        dic[word] = 1
print(dic)

输出结果:

{'four': 1, 'score': 1, 'and': 6, 'seven': 1, 'years': 1, 'ago': 1, 'our': 2, 'fathers': 1, 'brought': 1, 'forth': 1, 'on': 2, 'this': 4, 'continent': 1, 'a': 7, 'new': 2, 'nation': 5, 'conceived': 2, 'in': 4, 'liberty': 1, 'dedicated': 4, 'to': 8, 'the': 11, 'proposition': 1, 'that': 12, 'all': 1, 'men': 2, 'are': 3, 'created': 1, 'equal': 1, 'now': 1, 'we': 10, 'engaged': 1, 'great': 3, 'civil': 1, 'war': 2, 'testing': 1, 'whether': 1, 'or': 2, 'any': 1, 'so': 3, 'can': 5, 'long': 2, 'endure': 1,
'met': 1, 'battle': 1, 'field': 2, 'of': 5, 'have': 5, 'come': 1, 'dedicate': 2, 'portion': 1, 'as': 1, 'final': 1, 'resting': 1, 'place': 1, 'for': 5, 'those': 1, 'who': 3, 'here': 8, 'gave': 2, 'their': 1, 'lives': 1, 'might': 1, 'live': 1, 'it': 5,
'is': 3, 'altogether': 1, 'fitting': 1, 'proper': 1, 'should': 1, 'do': 1, 'but': 2, 'larger': 1, 'sense': 1, 'not': 5, 'consecrate': 1, 'hallow': 1, 'ground': 1, 'brave': 1, 'living': 2, 'dead': 3, 'struggled': 1, 'consecrated': 1, 'far': 2, 'above':
1, 'poor': 1, 'power': 1, 'add': 1, 'detract': 1, 'world': 1, 'will': 1, 'little': 1, 'note': 1, 'nor': 1, 'remember': 1, 'what': 2, 'say': 1, 'never': 1, 'forget': 1,
'they': 3, 'did': 1, 'us': 3, 'rather': 2, 'be': 2, 'unfinished': 1, 'work': 1, 'which': 2, 'fought': 1, 'thus': 1, 'nobly': 1, 'advanced': 1, 'task': 1, 'remaining': 1, 'before': 1, 'from': 2, 'these': 2, 'honored': 1, 'take': 1, 'increased': 1, 'devotion': 2, 'cause': 1, 'last': 1, 'full': 1, 'measure': 1, 'highly': 1, 'resolve': 1, 'shall': 3, 'died': 1, 'vain': 1, 'under': 1, 'god': 1, 'birth': 1, 'freedom': 1, 'government': 1, 'people': 3, 'by': 1, 'perish': 1, 'earth': 1}

这道题和去年刚刚接触python的时候写的爬豆瓣标签并统计个数差不多,顺便复习了一下正则表达式.

13、编写计算平均数和标准差的函数,并且在程序中调用,实现如下功能:
  • 输入姓名和考试分数;
  • 按照分数排序;
  • 计算平均数和标准差,并分别打印出来。

import math

def avg(x : list) :
    return sum(x) / len(x)
def std_error(x : list) :
    return math.sqrt((sum([i * i for i in x]) - len(x) * avg(x) * avg(x)) / (len(x) - 1))

test = {'烤啊嘶': 0, '古明地恋': 100, '来姐': 100, '路人': 60}
print(sorted(test.items(), key = lambda x: x[1]))
print(avg(test.values()))
print(std_error(test.values()))

输出结果:

[('烤啊嘶', 0), ('路人', 60), ('古明地恋', 100), ('来姐', 100)]
65.0
47.258156262526086
14、编写函数,实现正整数的阶乘。

def fact(x : int) :
    if x == 1 :
        return x
    return fact(x - 1) * x

print(fact(5))
print(fact(10))

输出结果:

120
3628800

最近微软俱乐部群里好多人讨论汉诺塔递归的问题,有时间的话详细写一下递归是个什么东西吧……

15、被称为“天才”的高斯,在10岁的时候计算出了1到100的整数相加的和,也有一种说法,认为10岁的高斯已经掌握了等差数列的求和方法。请编写一个函数,实现等差数列的求和。以此向高斯致敬。

def ari_seq(x, y, d) :
    '''
    :param x: 首项
    :param y: 尾项
    :param d: 公差
    '''
    n = (y - x) / d + 1
    return (x + y) * n / 2

print(ari_seq(1, 100, 1))

输出结果:

5050.0
16、在字典类型对象中,有get方法。但是,在列表中,没有类似方法。比如,完成如下操作,就只能报错了。
>>> lst = ["a", "b"]
>>> lst[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

所以,要解决这个问题。请编写一个函数,对列表实现类似字典中的get方法。


def listget(x : list, n : int) :
    try :
        return x[n]
    except IndexError:
        print("下标越界了,你是baka吗? 列表长度{0}, 试图访问{1}".format(len(x), n))
        return None

l = ["我永远", "喜欢", "古明地恋"]
print(listget(l, 2))
listget(l, 114514)

输出结果:

古明地恋
下标越界了,你是baka吗? 列表长度3, 试图访问114514

尝试模仿java写了一下try-catch的结构,效果还不错