大二上学期lfb老师面向大数据的python开发课程中一些简单编程题目的记录。

1.生日攻击

生日攻击是一个著名的概率问题,在分析hash函数安全性问题时有用,是类比这样一个问题:随机选取至少多少个学生,才能使这些学生中有两个同学生日一样的概率不少于一半。用python代码写程序,用多次随机试验的方法找这个人数的下限。

生日攻击python代码验证程序

>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>import random

>days_in1year = 365
>try_and_loop = 10000
>for g in range(1,365):#range函数是常用于遍历数字的内置函数
>hit=0
>for loop_i in range(0,try_and_loop):#0到9999 对于每个人数 实验10000次 看成功多少次 即为概率
>birthdays=set([])
>for o in range(0,g):#o为0到当前实验次数,即多少个人
birthday1 = random.randint(1,days_in1year)#随机生成一个生日
#要生成随机整数则需要用到 random模块里的randint()函数。randint()函数随机产生括号里两个参数之间的整数,且包括这两个参数,划定随机生成整数的范围(最小最大值)。
if birthday1 in birthdays:
hit=hit+1
#print("break at", o)
break
else:
birthdays.add(birthday1)
>print("with", g, "hit",hit,"in",try_and_loop,"loop")

消化版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import random
days_in_ayear = 365
try_and_loop = 10000
for i in range(0,days_in_ayear+1):
hit = 0
for j in range(0,try_and_loop):#注意0到9999 一共10000次
birthdays = set([])
for k in range(0,i):
birthday1 = random.randint(1,days_in_ayear)#注意函数名称randint
if birthday1 in birthdays:
hit += 1
break
else:
birthdays.add(birthday1)
print("with",i,"hit",hit,"in",try_and_loop,"loops")#注意缩进 每一个人数打印一次

'''
自己写完了这个问题
第一个for循环:多少个人
第二个for循环:每种人数试验10000次算概率
第三个for循环:为每个人随机生成生日,若成功则提前结束
'''

python set

set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

set 语法:

1
class set([iterable])

参数说明:

  • iterable — 可迭代对象对象;

返回值:返回新的集合对象。

Python random() 函数


描述

random() 方法返回随机生成的一个实数,它在[0,1)范围内。


语法

以下是 random() 方法的语法:

1
2
3
import random

random.random()

注意:random()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。


参数


返回值

返回随机生成的一个实数,它在[0,1)范围内。


实例

以下展示了使用 random() 方法的实例:

实例

#!/usr/bin/python # -- coding: UTF-8 -- import random # 生成第一个随机数 print “random() : “, random.random() # 生成第二个随机数 print “random() : “, random.random()

以上实例运行后输出结果为:

1
2
random() :  0.281954791393
random() : 0.309090465205

2.三门问题

写个writeup放到git

参考Yourdictionary.com对 write-up 提供的英文解释:a write-up is a written report on something or someone. (write-up就是针对某事、或某人的一篇书面报告。 )比如一篇详尽的影评(full movie review)就可以称为write-up。

三门问题代码模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import random
not_change = 0
change = 0
for i in range(0,100000):
door = [0,0,1]
random.shuffle(door)
choice1 = random.choice(door)
door.remove(choice1)
if choice1 == 1:
door.remove(random.choice(door))
else:
door.remove(0)#或者door = [1]
if choice1 == 1:
not_change += 1
else:
change += 1
print('不换门得到汽车的次数:',not_change,'中奖概率:',not_change/100000)
print('换门得到汽车的次数:',change,'中奖概率:',change/100000)

Python choice() 函数


描述

choice() 方法返回一个列表,元组或字符串的随机项。


语法

以下是 choice() 方法的语法:

1
2
3
import random

random.choice( seq )

注意:choice()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。


参数

  • seq — 可以是一个列表,元组或字符串。

返回值

返回随机项。


实例

以下展示了使用 choice() 方法的实例:

1
2
3
4
5
6
#!/usr/bin/python
import random

print "choice([1, 2, 3, 5, 9]) : ", random.choice([1, 2, 3, 5, 9])
print "choice('A String') : ", random.choice('A String')
以上实例运行后输出结果为:
1
2
choice([1, 2, 3, 5, 9]) :  2
choice('A String') : n

Python List remove()方法


描述

remove() 函数用于移除列表中某个值的第一个匹配项。

语法

remove()方法语法:

1
list.remove(obj)

参数

  • obj — 列表中要移除的对象。

返回值

该方法没有返回值但是会移除列表中的某个值的第一个匹配项。

实例

以下实例展示了 remove()函数的使用方法:

1
2
3
4
5
6
7
8
#!/usr/bin/python

aList = [123, 'xyz', 'zara', 'abc', 'xyz'];

aList.remove('xyz');
print "List : ", aList;
aList.remove('abc');
print "List : ", aList;

以上实例输出结果如下:

1
2
List :  [123, 'zara', 'abc', 'xyz']
List : [123, 'zara', 'xyz']

Python shuffle() 函数


描述

shuffle() 方法将序列的所有元素随机排序。


语法

以下是 shuffle() 方法的语法:

1
2
3
import random

random.shuffle (lst )

注意:shuffle()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。


参数

  • lst — 可以是一个列表。

返回值

该函数没有返回值。


实例

以下展示了使用 shuffle() 方法的实例:

实例

#!/usr/bin/python
# -- coding: UTF-8 --

import random

list = [20, 16, 10, 5]
random.shuffle(list)
print “随机排序列表 : “, list

random.shuffle(list)
print “随机排序列表 : “, list

以上实例运行后输出结果为:

1
2
随机排序列表 :  [16, 5, 10, 20]
随机排序列表 : [16, 5, 20, 10]

3.统计一个文本文件中所有的英文单词,按照频率排序输出

1
2
3
4
5
6
7
8
9
10
11
12
13
# coding = utf -8
import re

with open("this.txt", "r", encoding="utf-8") as fd:
word_list = [] # 存放所有单词,全部小写,并去除,.!等后缀,并去除空格字符串
word_dict = {} # 保留{word: count}键值对
for line in fd.readlines():
for word in line.strip().split(" "):
word_list.append(re.sub(r"[.|!|,]", "", word.lower()))
word_sets = list(set(word_list)) # 确保唯一
word_dict = {word: word_list.count(word) for word in word_sets if word}
result = sorted(word_dict.items(), key=lambda d: d[1], reverse=True)[:]
print(result)

简单的程序

1
2
3
4
5
6
7
8
9
10
# coding = utf -8
import re
from collections import Counter

with open("this.txt", "r", encoding="utf-8") as fd:
texts = fd.read() # 将文件的内容全部读取成一个字符串
count = Counter(re.split(r"\W+", texts)) # 以单词为分隔

result = count.most_common() # 统计最常使用的
print(result)

fd

文件描述符(file descriptor,简称fd),其对应的就是后面要操作的文件对象

Python open() 函数

python open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

更多文件操作可参考:Python 文件I/O

函数语法

1
open(name[, mode[, buffering]])

参数说明:

  • name : 一个包含了你要访问的文件名称的字符串值。
  • mode : mode 决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
  • buffering : 如果 buffering 的值被设为 0,就不会有寄存。如果 buffering 的值取 1,访问文件时会寄存行。如果将 buffering 的值设为大于 1 的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。

不同模式打开文件的完全列表:

模式 描述
t 文本模式 (默认)。
x 写模式,新建一个文件,如果该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(不推荐)。
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

file 对象方法

  • file.read([size]):size 未指定则返回整个文件,如果文件大小 >2 倍内存则有问题,f.read()读到文件尾时返回””(空字串)。

  • file.readline():返回一行。

  • file.readlines([size]) :返回包含size行的列表, size 未指定则返回全部行。

  • for line in f: print line :通过迭代器访问。

  • f.write(“hello\n”):如果要写入字符串以外的数据,先将他转换为字符串。

  • f.tell():返回一个整数,表示当前文件指针的位置(就是到文件头的字节数)。

  • f.seek(偏移量,[起始位置]):用来移动文件指针。

    • 偏移量: 单位为字节,可正可负
    • 起始位置: 0 - 文件头, 默认值; 1 - 当前位置; 2 - 文件尾
  • f.close() 关闭文件

更多内容参考:Python File(文件) 方法

实例

测试文件 test.txt,内容如下:

1
2
RUNOOB1
RUNOOB2

>>>f = open(‘test.txt’) >>> f.read() ‘RUNOOB1\nRUNOOB2\n’4.设计练习:py爬虫和处理

Python strip()方法

Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。

注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。

语法

strip()方法语法:

1
str.strip([chars]);

参数

  • chars — 移除字符串头尾指定的字符序列。

返回值

返回移除字符串头尾指定的字符生成的新字符串。

实例

以下实例展示了strip()函数的使用方法:

#!/usr/bin/python # -- coding: UTF-8 -- str = “123abcrunoob321” print (str.strip( ‘12’ )) # 字符序列为 12

以上实例输出结果如下:

1
3abcrunoob3

Python split()方法


描述

Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串

语法

split() 方法语法:

1
str.split(str="", num=string.count(str)).

参数

  • str — 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
  • num — 分割次数。默认为 -1, 即分隔所有。

返回值

返回分割后的字符串列表。

实例

以下实例展示了 split() 函数的使用方法:

实例(Python 2.0+)

#!/usr/bin/python # -- coding: UTF-8 -- str = “Line1-abcdef \nLine2-abc \nLine4-abcd”; print str.split( ); # 以空格为分隔符,包含 \n print str.split(‘ ‘, 1 ); # 以空格为分隔符,分隔成两个

以上实例输出结果如下:

1
2
['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']

以下实例以 # 号为分隔符,指定第二个参数为 1,返回两个参数列表。

实例(Python 2.0+)

#!/usr/bin/python # -- coding: UTF-8 -- txt = “Google#Runoob#Taobao#Facebook” # 第二个参数为 1,返回两个参数列表 x = txt.split(“#”, 1) print x

以上实例输出结果如下:

1
['Google', 'Runoob#Taobao#Facebook']

4.python爬虫

用python爬取https://www.freeproxylists.net/zh/中的代理。即,如何:
用py代码爬取,
用re过滤提取其中的ip和端口,
再用啥库或函数尝试用一下该代理以验证是否可用。
不用具体实现,就是设计。

1.开头的这个是设置编码为utf-8 ,写在开头,防止乱码。

2.header是requests.get的一个参数,目的是模拟浏览器访问,应对反爬虫

3.requests:用来抓取网页的html源代码

4.BeautifulSoup解析网页结构,数据

5.查找符合我们要求的数据,用BeautifulSoup的方法以及 re 库的
正则表达式去匹配过滤和提取文件内容

6.匹配到符合我们要求的数据,然后存进 dataList

7.保存数据可以选择保存到 xls 表, 需要(xlwt库支持)
也可以选择保存数据到 sqlite数据库, 需要(sqlite3库支持)

5.本地磁盘全文检索设计练习:

针对一个本地磁盘目录,其中有很多很多各种各样不同格式、大小不一的文件,试图对文件的可文本化的内容,以及文件的属性(路径、名字、扩展名、大小、日期、码率、分辨率等等)可以进行全文检索风格的查询。用py怎么实现,写一个设计。设计中也应该开放问题说明一下,比如说读文本文件如果使用readlines(),可能会遇见内存不足的返回错误,处理不了大文件,等等。设计中也应该开放问题说明一下,比如说读文本文件如果使用readlines(),可能会遇见内存不足的返回错误,处理不了大文件,等等。

列一个表说明几个知识点:

(1)遍历本地目录和文件,使用py库/函数os.listdir()等;

(2)对该文件提取纯文本,使用tika;

(3)对纯文本分词,使用jieba;

(4)做检索,可以使用python的dick或者使用whoosh,whoosh这样用啦啦啦啦。

6.口令练习题

产生一个6位以上的口令,要求有至少各一个大写、小写、数字、特殊符号(键盘上能输入的其他符号)。

假设我们要生成7位密码:
第1位字符从数字0 ~ 9中随机选取一个字符
第2位字符从小写字母a ~ z中随机选取一个字符
第3位字符从大写字母A ~ Z中随机选取一个字符
第4位字符从自定义符号!@#$%&*()中随机选取一个字符
第5~7位,每一位先随机选取字符类型,再从该字符类型中随机选取字符
最后随机打乱7位密码的排列次序

1
2
3
4
5
6
7
8
9
10
11
import random,string
def make_passwd(a): #生成密码长度a位
passwd = []
char = [string.digits,string.ascii_lowercase,string.ascii_uppercase,'!@#$%&*()']
for i in range(0,4):
passwd.append(str(random.choice(char[i])))
for i in range(0,a-4):
passwd.append(str(random.choice(random.choice(char))))
random.shuffle(passwd)
passwd=''.join(passwd)
return passwd

7.银行家练习题

一位慈善的银行家,1块钱存1年可以返回连本带利2块,1块钱存半年可以返回1块半,1.5重新存进去再半年后返回2.25,就是这么仁慈。如果你自己不嫌麻烦,可以每个季度提取并重新存入,每个月、每周、每天等等。计算一下,如果你够勤奋,能不能1块钱财富自由?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
''''
考py小程序,是给了一个机会在一个限定的工作场景内展示你的py编程知识和能力,目的真不是计算pai或e或生日
py小程序练习题:
一位慈善的银行家,1块钱存1年可以返回连本带利2块,1块钱存半年可以返回1块半,1.5重新存进去再半年后返回2.25,就是这么仁慈。如果你自己不嫌麻烦,可以每个季度提取并重新存入,每个月、每周、每天等等。计算一下,如果你够勤奋,能不能1块钱财富自由?
'''

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

# 计算本金、利率、周期的抽象函数
def mod_increase(base, inc, inter):
return base*pow((1+inc),inter) # 可以使用^

def usage():
print("提示: \n 1.分期数须是正整数 \n 2.命令行可输入分期数")

def main():
loopn=0
if len(sys.argv) > 1:
a1 = sys.argv[1]
if a1.isdigit():
loopn = int(a1)
else: # 使用input()
print("pls input fen-qi:")
pass

if loopn<=0:
usage()
exit(-2)
total = mod_increase(1, 1.0/loopn, loopn)
print(str(loopn)+"期则连本带利共得"+str(total))

if __name__ == "__main__":
main()


# 不严格评分举例
'''
1分版本
#!/usr/bin/python --or-- #!/usr/bin/env python
'''

'''
2分版本
#!/usr/bin/python3
# -*- coding: utf-8 -*- --or-- something alike
'''

'''
3分版本
for i in range(1,10000,500):
print(i, pow(1+1.0/i,i))
'''

'''
4分版本
i=1
while (i<10000):
print(i, pow(1+1.0/i,i))
i=i+i
'''

8.计算圆周率

我写的简单版本:

1
2
3
4
5
6
7
8
9
import random
try_and_loop = 1000000
hit = 0
for i in range(0,try_and_loop-1):
x = random.random()
y = random.random()
if x*x + y*y <= 1:
hit += 1
print("Pi = ",4 * hit / try_and_loop)#Pi*r*r/4

老师发的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import random

hit=0
All=0
while (True):
x=random.random()
y=random.random()
if x*x+y*y<1:
hit+=1
#All:=All+1
#if (All%(1000*10000)==0):
if ((All:=All+1)%(1000*10000)==0): #这不是一个好的演示pep572的地方
#print("pie=", hit/All*4, " hit ", hit, " out of ", All)
print("pie=%.6f hit %d outof %d" %(hit/All*4, hit, All))

#pie=3.141555 hit 78538882 outof 100000000
#pie=3.141593 hit 785398303 outof 1000000000

#附加问题:分析该方法能达到的圆周率的精度的限制因素