Python 作业 1
现有一个游戏系统的日志文件,记录内容的字符串 的格式 如下所示
A girl come in, the name is Jack, level 955;
其中包含的 the name is 后面会跟着人名,随后紧跟一个逗号, 这是固定的格式。
其它部分可能都是会变化的,比如,可能是下面这些
A old lady come in, the name is Mary, level 94454
A pretty boy come in, the name is Patrick, level 194
请大家实现一个函数,名为getName,如下所示
def getName(srcStr):
函数体
该函数的参数srcStr 是上面所描述的格式字符串(只处理一行),该函数需要将其中的人名获取出来,并返回
比如 调用 getName('A old lady come in, the name is Mary, level 94454')
返回结果应该是 'Mary'
def getName(srcStr): return srcStr.split('the name is ')[1].split(',')[0]
Python 编程作业 02
请实现一个程序,实现如下需求点
1.程序开始的时候提示用户输入学生年龄信息 格式如下:
Jack Green , 21 ; Mike Mos, 9;
我们假设 用户输入 上面的信息,必定会遵守下面的规则:
学生信息之间用分号隔开(分号前后可能有不定数量的空格),
每个学生信息里的 姓名和 年龄之间用 逗号隔开(逗号前后可能有不定数量的空格)
2. 程序随后将输入的学生信息分行显示,格式如下
Jack Green : 21;
Mike Mos : 09;
学生的姓名要求左对齐,宽度为20, 年龄信息右对齐,宽度为2位,不足前面补零
请再实现一个程序,实现如下需求点
1.下面的log变量记录了云服务器上 当天上传的文件信息
其中第一列是文件名,第二列是文件大小
请编写一个程序,统计出不同类型的 文件的大小总和
比如:
jpeg 9988999
json 324324
png 2423233
----------------------------------
log = '''
f20180111014341/i_51a7hC3W.jpeg 169472 FrITJxleSP7wUD-MWw-phL_KP6Eu 15156063244230469 image/jpeg 0
f20180111014341/j_R0Hpl4EG.json 1036 ForGzwzV3e-uR3_UzvppJs1VgfQG 15156064773253144 application/json 0
f20180111020739/i_0TDKs0rD.jpeg 169472 FrITJxleSP7wUD-MWw-phL_KP6Eu 15156076847077556 image/jpeg 0
f20180111020739/j_JFO6xiir.json 1040 FmUhTchdLOd7LBoE8OXzPLDKcW60 15156077904192983 application/json 0
f20180111090619/i_1BwNksbL.jpg 49634 FtXBGmipcDha-67WQgGQR5shEBu2 15156329458714950 image/jpeg 0
f20180111090619/i_3BKlsRaZ.jpg 30152 FoWfMSuqz4TEQl5FT-FY5wqu5NGf 15156330575626044 image/jpeg 0
f20180111090619/i_5XboXSKh.jpg 40238 Fl84WaBWThHovIBsQaNFoIaPZcWh 15156329453409855 image/jpeg 0
f20180111090619/i_6DiYSBKp.jpg 74017 FrYG3icChRmFGnWQK6rYxa88KuQI 15156329461803290 image/jpeg 0
f20180111090619/i_76zaF2IM.jpg 38437 Fui8g5OrJh0GQqZzT9wtepfq99lJ 15156334738356648 image/jpeg 0
f20180111090619/i_B6TFYjks.jpg 37953 FleWqlK2W1ZmEgAatAEcm1gpR0kC 15156329464034474 image/jpeg 0
f20180111090619/i_N9eITqj3.jpg 38437 Fui8g5OrJh0GQqZzT9wtepfq99lJ 15156330419595764 image/jpeg 0
f20180111090619/i_QTSNWmA6.jpg 37953 FleWqlK2W1ZmEgAatAEcm1gpR0kC 15156333104224056 image/jpeg 0
f20180111090619/i_XdHcAfh1.jpg 56479 FjLQIQ3GxSEHDfu6tRcMylK1MZ05 15156334227270309 image/jpeg 0
f20180111090619/i_Xyy723MU.jpg 50076 FsfZpQzqu084RUw5NPYW9-Yfam_R 15156334229987458 image/jpeg 0
f20180111090619/i_d8Go0EOv.jpg 30152 FoWfMSuqz4TEQl5FT-FY5wqu5NGf 15156334736228515 image/jpeg 0
f20180111090619/i_diuHmX53.jpg 40591 FuTx1pw4idbKnV5MSvNGxCA5L470 15156333878320713 image/jpeg 0
f20180111090619/i_qQKzheSH.jpg 55858 Fj0A3i8V7fzzOiPQFL79ao15hkN9 15156329456666591 image/jpeg 0
f20180111090619/i_rHL5SYk8.jpg 40238 Fl84WaBWThHovIBsQaNFoIaPZcWh 15156336509742181 image/jpeg 0
f20180111090619/i_xZmQxUbz.jpg 40238 Fl84WaBWThHovIBsQaNFoIaPZcWh 15156333240603466 image/jpeg 0
f20180111090619/i_zBDNgXDv.jpeg 73616 FlgNwq8lypgsxrWs_ksrS_x47SQV 15156334232887875 image/jpeg 0
f20180111090619/j_4mxbEiVh.json 2990 Fpq-3yl3Yr1CadNrJVSDnpeRhQtT 15156331445226898 application/json 0
f20180111090619/j_i1K74768.json 3042 Fl5PpDw1TsZXMuhoq1RUrOeGZ6br 15156335067090003 application/json 0
f20180111095839/i_Q7KMKeda.png 518522 Fl-yB1_ruL2uxZN9k7DjB62h9dYH 15156359599713253 image/png 0
f20180111095839/j_5DpqHolV.json 184 FoYvi7cmSrzuVjUgCRzW5kU95SVo 15156359719719064 application/json 0
f20180111100442/i_No8kToIV.jpg 48975 Fu1cw3f--5Vpz9kLGeJfvljhCtyZ 15156364349642377 image/jpeg 0
f20180111100442/i_P1bkvSeg.jpg 68200 FvYe8vi46TjUKhEy_UwDqLhO6ZsW 15156363800690634 image/jpeg 0
f20180111100442/i_T1AulKcD.jpg 52641 Fj2YzvdC1n_1sF93ZZgrhF3OzOeY 15156364021186365 image/jpeg 0
f20180111100442/i_X8d8BN07.jpg 50770 FivwidMiHbogw77lqgkIKrgmF3eA 15156363969737156 image/jpeg 0
f20180111100442/i_g0wtOsCX.jpg 76656 Fmtixx0mP9CAUTNosjLuYQHL6k0P 15156363448222155 image/jpeg 0
f20180111100442/i_h5OT9324.jpg 72672 FvbIqPLTh2cQHTIBv2akUfahZa_Z 15156364401354652 image/jpeg 0
f20180111100442/i_he8iLYI6.jpg 49399 FjeJvwjwhU-hKZsq66UoBg9_tEJs 15156363907932480 image/jpeg 0
f20180111100442/i_kg29t7Pp.jpg 76293 FuYj__sSeEN7AsXMbxO24Z8Suh8d 15156364156384686 image/jpeg 0
f20180111100442/i_oz1YoBI1.jpg 75620 FkY3xsUMwOI01zgoH1iXXgiQeq6I 15156364089112904 image/jpeg 0
f20180111100442/i_xrOT98on.jpg 50021 Fql7ookM1Rc6V7VairKAfnKe-o9w 15156363856357316 image/jpeg 0
f20180111135114/i_Zqt8Tmoe.png 161629 FlELw59_mV3VqDBLyu1BKN4fIWnx 15156500155209863 image/png 0
f20180111135114/j_uhHoMXKq.json 159 FrypljwAr2LgoLAePBNTUYTUAgDt 15156500200488238 application/json 0
f20180111142119/i_s83iZ2GR.png 92278 Fns8tdh3JCkRmfE_COYEu4o8w03E 15156517082371259 image/png 0
f20180111142119/j_0g45JRth.json 159 Fq1rFwdRguYRXrp61nGZ5TsUG1V- 15156517143375596 application/json 0
f20180111144306/i_yE5TC84E.png 139230 Fjf61ymabEnEvnr5ZMHFjXGCrYlP 15156530038824150 image/png 0
f20180111144306/j_OF4WVtSH.json 159 FqwkKcxfo8jd0jFUyuH4X2CrnE9q 15156530083419530 application/json 0
f20180111150230/i_KtnER4g3.png 120044 FuwOWdrqzcr2-UScem-LzEMgMezs 15156541734892258 image/png 0
f20180111150230/j_xMSUEejY.json 158 FjJr_4deMqFphGaptm-2Pa6wwRP2 15156541771989216 application/json 0
f20180111151741/i_JuSWztB3.jpg 92506 FrIjRevHSi6xv4-NQa2wrHu5a1zQ 15156550875370965 image/jpeg 0
f20180111153550/i_9wWzVenl.gif 769872 FvslKY9JUaCQm-lu02E34tvAP_oG 15156561674621628 image/gif 0
'''
题1 inputStr = input('Please input student age info:') studentInfo = inputStr.split(';') for one in studentInfo: # check if it is valid input if ',' not in one: continue name,age = one.split(',') name = name.strip() age = age.strip() # check is age digit if not age.isdigit(): continue age = int(age) print('%-20s : %02d' % (name, age)) # print('{:20} : {:02}'.format(name, age)) # print(f'{name:20} : {age:02}') 题2 # 记录各种类型的文件的数量统计,存储格式如下 # [['jpg',4566],['json',4566]] fileLenTable = [] # 根据文件类型找到记录对象,进行累加 def putRecordToTable(fileType,fileLen): for one in fileLenTable: if one[0] == fileType: one[1] += fileLen return # 没有找到,创建一个记录元素 fileLenTable.append([fileType,fileLen]) return for line in log.split(' '): if line.strip() == '': continue parts = line.split(' ') name,size = parts[:2] ext = name.split('.')[-1] putRecordToTable(ext,int(size)) print(fileLenTable)
Python 作业 03
请定义一个函数 mySort,参数为一个列表,参数列表中的元素都是整数.
mySort 函数需要将参数列表中的元素按从小到大排序,最终返回一个新的list。
请按下面算法的思路实现函数:
1. 创建一个新的列表newList
2. 先找出所有元素中最小的,append在newList里面
3. 再找出剩余的所有元素中最小的,append在newList里面
4. 依次类推,直到所有的元素都放到newList里面
def sort(inList): newList = [] # 设计一个循环,每个循环做如下事情(直到 inlist 没有元素): # 找出当前inlist中所有元素中最小curMin的,append在newList里面 # # inList 去掉 curMin while len(inList) > 0: theMin = inList[0] # 记录当前循环最小元素 minIdx = 0 # 记录当前最小元素的下标 idx = 0 # 指向当前元素下标 for one in inList: if theMin > one: theMin = one minIdx = idx idx += 1 inList.pop(minIdx) newList.append(theMin) return newList print (sort([1,3,5,7,34,23,55,56,2,3,4]))
Python 作业 5
现有一个数据库记录文件(见附件0005_1.txt),保存了学生课程签到的数据库记录。 内容格式如下 ,
('2017-03-13 11:50:09', 271, 131),
('2017-03-14 10:52:19', 273, 131),
('2017-03-13 11:50:19', 271, 126),
每一行记录保存了学生的一次签到信息。
每一次签到信息的记录,分为三个部分, 分别是签到时间、签到课程的id号、签到学生的id号
要求大家实现下面的函数。其中参数fileName 为 数据库记录文件路径, 输出结果是将数据库记录文件中的学生签到信息保存在一个字典对象中,并作为返回值返回。
def putInfoToDict(fileName):
要求返回的字典对象的格式是这样的:
key 是各个学生的id号, value是 该学生的签到信息
其中value,里面保存着该学生所有签到的信息
其中每个签到的信息是字典对象,有两个元素: key 是lessonid的 记录课程id,key是checkintime的 记录签到时间
比如,对于上面的示例中的3条记录,相应的返回结果如下:
{
131: [
{'lessonid': 271,'checkintime':'2017-03-13 11:50:09'},
{'lessonid': 273,'checkintime':'2017-03-14 10:52:19'},
],
126: [
{'lessonid': 271,'checkintime':'2017-03-13 11:50:19'},
],
}
def putInfoToDict(fileName): retDict = {} with open(fileName) as f: lines = f.read().splitlines() for line in lines: # remove '(' and ')' line = line.replace('(','').replace(')','').replace(';','').strip() parts = line.split(',') ciTime = parts[0].strip().replace("'",'') lessonid = int(parts[1].strip()) userid = int(parts[2].strip()) toAdd = {'lessonid':lessonid,'checkintime':ciTime} # if not in, need to create list first if userid not in retDict: retDict[userid] = [] retDict[userid].append(toAdd) # or just #retDict.setdefault(userid,[]).append(toAdd) return retDict ret = putInfoToDict('0005_1.txt') import pprint pprint.pprint(ret)
Python 作业 6
附件里压缩 了一个目录(见附件phone.zip),解压后结构如下。
phone
├─apple
└─samsung
├─note
└─s
这个目录里面对应了苹果、三星手机 的价格。
在相应目录里面,包含对应手机价格的python文件。
请同学们在维持目录结构不变的前提下,把这个目录结构做成名为python包。
然后,自己写一个Python程序调用 那个python包里面的每个
模块文件(共四个)里面的askPrice 函数,显示每种手机的价格
同学们先将那个phone包,和自己写的调用程序文件放在同一个目录下,
运行调用程序,显示各种手机价格
同学们再将那个phone包,和自己写的调用程序文件放在不同的目录下,
通过设置 sys.path 或者 环境变量PYTHONPATH,
来保证可以找到phone包,并成功调用。
Python 作业 7
下载附件cfiles.zip(见附件cfiles.zip)
解压该压缩包,里面 包含了两个文件。 一个叫 'gbk编码.txt',
该文件是gbk编码的。
另一个文件叫 'utf8编码.txt', 该文件是utf8编码的。
两个文件里面的内容都包含中文。
要求大家编写一个python程序,该程序做到以下2点
1. 将两个文件内容读出, 合并内容到一个字符串中,
并能用print语句将合并后的内容正确显示
2. 然后,程序用中文提示用户“请输入 新文件的名称”,
用户输入文件名可以包含中文
将上面合并后的内容存储到一个新文件中,以utf8格式编码。
新文件的文件名就是上面用户输入的名字。
# 根据不同的编码格式,指定参数 with open('cfiles/gbk编码.txt',encoding='gbk') as f1, open('cfiles/utf8编码.txt',encoding='utf8') as f2: # read后,自动转化成unicode content1 = f1.read() content2 = f2.read() newContent = content1 + content2 print(newContent) newFile = input('请输入新文件的名称:') with open(newFile,'w',encoding='utf8') as f: f.write(newContent)
Python 作业 8
下载附件0008.zip(见附件0008.zip)
解压该压缩包,里面 包含了3个文件。 都是数据库中导出的数据文件,
记录了松勤的老师和授课信息。
其中
1. teacher.txt 文件中包含了 松勤的老师信息,格式如下:
id;user_id;desc;display_idx;realname
42;106;;1;小猪老师
43;107;;2;mandy老师
首行表示 下面数据各字段的含义。
第1列id 表示老师的id号。
第2、3、4 列的含义大家可以先不必了解。
第5列realname 表示 老师的姓名
2. course.txt 文件中包含了 松勤的课程信息,格式如下:
id;name;desc;display_idx
32;软件测试框架课程;;1
33;web测试技术课程;;2
首行表示 下面数据各字段的含义。
第1列id 表示课程的id号
第2列name 表示 课程的名称
第3、4 列的含义大家可以先不必了解。
3. teacher_course.txt 文件中包含了 松勤老师授课信息,格式如下:
teacher_id;course_id
42;32
42;33
首行表示 下面数据各字段的含义
第1列teacher_id 表示老师的id号(对应第一张表的老师id号)
第2列course_id表示 课程的id号(对应第二张表的课程id号)。
要求大家编写一个python程序,根据这3张表的内容,输出一个包含老师授课信息的文件。
要求格式为 老师姓名: 课程名,例如
小猪老师 : 软件测试框架课程
mandy老师 : 软件测试框架课程
mandy老师 : web测试技术课程
实现过程中,有什么问题,请通过课堂上讲解的调试方法,尽量自己发现错误原因。
# 先读取文件创建两张表(两个dict),记录老师的 id:name with open('records/course.txt',encoding='utf8') as f : courses = f.read().splitlines()[1:] with open('records/teacher.txt',encoding='utf8') as f : teachers = f.read().splitlines()[1:] courseDict = {} for course in courses: if not course.strip(): continue parts = course.split(';') courseId = parts[0] courseName = parts[1] courseDict[courseId] = courseName teacherDict = {} for teacher in teachers: if not teacher.strip(): continue parts = teacher.split(';') teacherId = parts[0] teacherName = parts[4] teacherDict[teacherId] = teacherName # 根据老师教学记录表, 将里面的id替换为 名字 with open('records/teacher_course.txt') as f : teacher_courses = f.read().splitlines()[1:] with open('ret.txt','w',encoding='utf8') as f : for tc in teacher_courses: if not tc.strip(): continue parts = tc.split(';') teacherId = parts[0] courseId = parts[1] if (teacherId not in teacherDict) or (courseId not in courseDict): print(f'skip record {tc}') continue ret = f"{teacherDict[teacherId]:10} : {courseDict[courseId]}" print(ret) f.write(ret+' ')
Python 作业 9
要求大家用面向对象的设计编写一个python程序,实现一个文字游戏系统。
动物园里面有10个房间,房间号从1 到 10。
每个房间里面可能是体重200斤的老虎或者体重100斤的羊。
游戏开始后,系统随机在10个房间中放入老虎或者羊。
然后随机给出房间号,要求游戏者选择敲门还是喂食。
如果选择喂食:
喂老虎应该输入单词 meat,喂羊应该输入单词 grass
喂对了,体重加10斤。 喂错了,体重减少10斤
如果选择敲门:
敲房间的门,里面的动物会叫,老虎叫会显示 ‘Wow !!’,羊叫会显示 ‘mie~~’。 动物每叫一次体重减5斤。
游戏者强记每个房间的动物是什么,以便不需要敲门就可以喂正确的食物。
游戏3分钟结束后,显示每个房间的动物和它们的体重。
实现过程中,有什么问题,请通过课堂上讲解的调试方法,尽量自己发现错误原因。
单线程版 from random import randint import time class Tiger(object): classname = 'tiger' def __init__(self,weight=200): self.weight = weight def roar(self): print('wow!!!') self.weight -= 5 def feed(self,food): if food == 'meat': self.weight += 10 print('正确,体重 + 10') else : self.weight -= 10 print('太惨了,体重 - 10') class Sheep: classname = 'sheep' def __init__(self,weight=100): self.weight = weight def roar(self): print('mie~~') self.weight -= 5 def feed(self,food): if food == 'grass': self.weight += 10 print('正确,体重 + 10') else : self.weight -= 10 print('太惨了,体重 - 10') class Room: def __init__(self,num,animal): self.num = num self.animal = animal rooms = [] for no in range(10): if randint(0,1): ani = Tiger(200) else: ani = Sheep(100) room = Room(no,ani) rooms.append(room) startTime = time.time() while True: curTime = time.time() if (curTime - startTime) > 120: print(' ********** 游戏结束 ********** ') for idx, room in enumerate(rooms): print('房间 :%s' % (idx + 1), room.animal.classname, room.animal.weight) break roomno = randint(1, 10) room = rooms[roomno-1] # why -1 ? ch = input('我们来到了房间# %s, 要敲门吗?[y/n]' % roomno) if ch == 'y': room.animal.roar() food = input('请给房间里面的动物喂食:') room.animal.feed(food.strip())
多线程中文版,以后学过多线程后再看 from random import randint import time,os import threading class Tiger: classname = 'tiger' def __init__(self): self.weight = 200 def roar(self): print('wow!!!') self.weight -= 5 def feed(self,food): if food == 'meat': self.weight += 10 print('正确,体重 + 10') else : self.weight -= 10 print('太惨了,体重 - 10') class Sheep: classname = 'sheep' def __init__(self): self.weight = 100 def roar(self): print('mie~~') self.weight -= 5 def feed(self,food): if food == 'grass': self.weight += 10 print('正确,体重 + 10') else : self.weight -= 10 print('太惨了,体重 - 10') class Room: def __init__(self,num,animal): self.num = num self.animal = animal rooms = [] for no in range(10): if randint(0,1) == 0: ani = Tiger() else: ani = Sheep() room = Room(no+1,ani) rooms.append(room) def count_thread(): # 记录下游戏开始时间 startTime = time.time() while True: time.sleep(0.1) curTime = time.time() if (curTime - startTime) > 20: break print(u'游戏结束') for room in rooms: print(u'房间%s, 里面是%s,体重%s' % (room.num, room.animal.classname, room.animal.weight)) os._exit(0) t = threading.Thread(target=count_thread) t.start() # 循环做如下事情 while True: # 提示房间号,让用户选择 敲门 还是 喂食 curRoomIdx = randint(0,9) room = rooms[curRoomIdx] print('当前来到房间%s,敲门【q】还是喂食【w】' % room.num) ch = input() # 如果选择敲门:...... if ch == 'q': room.animal.roar() # 如果选择喂食:...... elif ch == 'w': print('请输入食物:') food = input() room.animal.feed(food)
Python 作业 10
获取统计 远程Linux主机的 可用内存率。
请大家先安装 paramiko : 执行pip install paramiko
请大家自行百度搜索,安装虚拟机管理器 virtualbox 或者 vmvareplayer, 创建 64位 虚拟机,
安装centos镜像
cetos6.9 下载地址 :
http://mirrors.163.com/centos/6.9/isos/x86_64/CentOS-6.9-x86_64-bin-DVD1.iso
Putty 下载地址 :
https://the.earth.li/~sgtatham/putty/0.70/w32/putty-0.70-installer.msi
然后编写一个python程序,代码文件名为 memory.py , 该代码文件 计划在远程Linux机器运行。该程序做如下的事情:
每隔5秒钟 打开文件 /proc/meminfo,该文件包含了系统内存使用信息,前面数行内容如下
MemTotal: 1920648 kB
MemFree: 87788 kB
Buffers: 229704 kB
Cached: 1180244 kB
memory.py 程序要将 memFree 、buffers、cached 的值 相加 (结果是可用内存的数量)。
然后除以 MemTotal的值, 得到可用内存占的百分比(赋值给变量 avaMem)。
将 avaMem 的数值存入 结果文件ret.txt中。
上面的程序一直运行,每隔 5秒钟 获取记录一次 avaMem 对应的时间戳, 格式如下
20170315_12:10:00 77%
20170315_12:10:05 74%
20170315_12:10:10 70%
20170315_12:10:15 72%
再编写一个python程序,代码文件名为 auto.py,该程序运行起来做如下工作:
以自己名字的拼音(比如lixia) 在远程机器建立一个目录 。如果该目录已经存在则跳过此步骤
拷贝文件memory.py 到远程机器该目录下面,
远程在Linux主机执行文件 memory.py
过5分钟后,将远程文件memory.py执行产生的结果文件ret.txt 内容拷贝回本机
memory.py # coding=utf8 import time # MemTotal: 1920648 kB # MemFree: 87788 kB # Buffers: 229704 kB # Cached: 1180244 kB def getContent(lines,field): for line in lines: if field in line: value = line.split(':')[1].split('kB')[0].strip() return int(value) # count 用来时间上计数,防止一直运行 count = 0 while True: count += 1 with open('/proc/meminfo') as f: beginlines = f.readlines()[:8] memTotal = getContent(beginlines,'MemTotal') memFree = getContent(beginlines,'MemFree') buffers = getContent(beginlines,'Buffers') cached = getContent(beginlines,'Cached') # print memTotal,memFree,buffers,cached # 别忘了 * 100 memUsage = (memFree + buffers + cached) *100.0/memTotal # 搜索时间格式 memUsage = '%s %.2f%%' % (time.strftime('%Y%m%d_%H:%M:%S'),memUsage) print(memUsage) with open('ret.txt','a') as f: f.write(memUsage+' ') time.sleep(5) # 防止一直运行 if count>15: break auto.py # coding=utf8 import paramiko,time ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("120.26.96.231",22,"stt", "stt0707") # 创建自己名字的目录 dirName = "jcy" # 先检查 是否已经存在同名目录了, 如果没有则创建 stdin, stdout, stderr = ssh.exec_command("ls") # exec_command 返回的是bytes类型,需要解码 dircontent = stdout.read().decode() print(dircontent) if dirName in dircontent.splitlines(): print('{} already exists'.format(dirName)) else: print('make dir {}'.format(dirName)) ssh.exec_command("mkdir {}".format(dirName)) # 传输文件 sftp = ssh.open_sftp() sftp.put('memory.py', '{}/memory.py'.format(dirName)) sftp.close() # 检查文件是否传输成功,可以将检查文件是否存在机器,做成一个函数。。。 # 执行脚本 # 考虑到长时间没有消息,网络连接可能会被断开。 到网上搜索一番后。 # 设置一个保持连接的参数 transport = ssh.get_transport() transport.set_keepalive(30) print('remote exec python memory.py') ssh.exec_command("cd %s; python memory.py" % dirName) print('wait for 30 seconds...') time.sleep(30) # 传输文件 sftp = ssh.open_sftp() sftp.get('{}/ret.txt'.format(dirName),'ret.txt') sftp.close() ssh.close()
Python 作业 11
阅读下面的两个知识点
1. ffmpeg可以用下面的参数来录制Windows 桌面操作的视频。
ffmpeg.exe -y -rtbufsize 100M -f gdigrab -framerate 10 -draw_mouse 1 -i desktop
-c:v libx264 -r 20 -crf 35 -pix_fmt yuv420p -fs 100M "fffffffffffffffff"
其中 fffffffffffffffff 部分 是需要填入 产生的视频文件名。
录制过程中,用户按键盘 q 键,可以退出录制。
2. ffmpeg还可以用来合并视频文件,windows下面的格式如下
ffmpeg.exe -f concat -i concat.txt -codec copy out.mp4
其中concat.txt 是要合并视频的文件列表。格式如下,每行以file 开头 后面是要合并的视频文件名:
file 20170330_110818.mp4
file 20170330_110833.mp4
------------------------------
下载ffmpeg程序 (进入 http://ffmpeg.zeranoe.com/builds/ 点击 Download FFmpeg按钮即可)
要求大家写一个python程序,运行后提示用户是要做什么操作,如下
'请选择您要做的操作:1:录制视频,2:合并视频:'
如果用户输入1并回车, 则调用ffmpeg录制视频文件,产生在当前目录下面。
要求录制的视频文件名 是当前时间(年月日_时分秒.mp4格式),
比如 '20170330_093612.mp4' (怎么产生这种时间格式的字符串,不知道的请自行网上搜索方法)
如果用户输入2并回车,则按字母顺序列出当前目录下所有的 mp4为扩展名
的视频文件(怎么列出,请自行网上搜索方法),并在前面编上序号。如下所示
---------------------------------
目录中有这些视频文件:
1 - 20170329_202814.mp4
2 - 20170330_093251.mp4
3 - 20170330_093612.mp4
请选择要合并视频的视频文件序号(格式 1,2,3,4) :
---------------------------------
用户输入视频序号(序号以逗号隔开)后, 程序合并视频文件, 输出的合并后视频文件名 固定为 out.mp4
# coding=utf8 import time,os import glob FFMPEG_PATH = 'd:/data/bandicam/tmp/ffmpeg.exe' VIDEO_DIR = 'd:\' def recording(): # 输出视频文件 outputfile = VIDEO_DIR + time.strftime('%Y%m%d_%H%M%S', time.localtime()) + '.mp4' # 工具目录 settings = '-y -rtbufsize 100M -f gdigrab -framerate 20 ' + '-draw_mouse 1 -i desktop -c:v libx264 -r 20 ' + '-crf 35 -pix_fmt yuv420p ' '-fs 100M "%s"' % outputfile recordingCmdLine = FFMPEG_PATH + ' ' + settings # 查看命令内容 print(recordingCmdLine) # 执行命令录制视频 os.system(recordingCmdLine) def merging(): os.chdir(VIDEO_DIR) fileList = glob.glob(VIDEO_DIR + '*.mp4') fileList = [os.path.basename(one) for one in fileList] if fileList: print(' 目录中有这些视频文件:') else: print(' 目录中没有视频文件') return idx = 1 for one in fileList: print('%s - %s' % (idx, one)) idx += 1 print(' 请选择要合并视频的视频文件序号(格式 1,2,3,4) :', end=' ') mergeSequence = input('') videoFilesToMer = mergeSequence.split(',') videoFileNamesToMer = [fileList[int(one.strip())-1] for one in videoFilesToMer] print(videoFileNamesToMer) with open('concat.txt','w',encoding='utf8') as f: for one in videoFileNamesToMer: f.write('file ' + one + ' ') cmd = FFMPEG_PATH + ' -f concat -i concat.txt -codec copy out.mp4' # 执行命令录制视频 os.system(cmd) while True: print(' 请选择您要做的操作:1-录制视频,2-合并视频 :', end=' ') choice = input('') if choice == '1': recording() elif choice == '2': merging()
Python 作业 12
先阅读下面关于Python requests 库的文章 ,了解 使用它去获取一个网页内容的方法。
http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
然后编写一个python程序,创建两个子线程,分别到下面的网址获取文本内容
http://mirrors.163.com/centos/build/rpmcompare5.pl.txt
http://mirrors.163.com/centos/6.9/isos/x86_64/README.txt
主线程等待这个两个子线程获取到信息后,将其内容合并后存入名为 readme89.TXT 的文件中
# coding=utf8 import requests import threading urls = [ 'http://mirrors.163.com/centos/build/rpmcompare5.pl.txt', 'http://mirrors.163.com/centos/6.9/isos/x86_64/README.txt', ] # 对应urls 依次存储网页文件内容, 先创建同样个数的元素占位 fileContentList = [None for one in urls] # 锁对象,用来控制访问 fileContentList lock = threading.Lock() def thread_entry(idx,url): print('thread #%s start' % idx) r = requests.get(url) # 注意上面的代码不应该放在获取锁的代码中 lock.acquire() # 注意 r.text的类型是unicode,可以在文档中查到 fileContentList[idx] = r.text lock.release() print('thread #%s end' % idx) if __name__ == '__main__': print('main thread start.') threadpool = [] for idx,url in enumerate(urls): t = threading.Thread(target=thread_entry, args=(idx,url)) t.start() threadpool.append(t) # 等所有 线程结束 for t in threadpool: t.join() # 所有线程结束后,所有内容都获取到了,合并内容 mergeTxt = ' ---------------------- '.join(fileContentList) print(mergeTxt) with open('readme89.txt','w',encoding='utf8') as f: f.write(mergeTxt) print('main thread end.')
Python 作业 13
实现 一个 简单的 客服聊天系统。
客服中心是tcp服务端程序 客户使用tcp客户端程序。
服务端程序 先运行, 绑定本机一个ip地址, 等待客户端系统连接上来 。
客户端程序有一个命令行参数, 表示客户的名字
连接成功后, 客户端发送给服务端第一个消息 必须告诉客服中心,用户的名字
一个客户连接后,别的客户不能连接, 等到前面的客户断开连接后,才能连上。
客户端和服务端都是手动在终端输入信息,发送消息后,必须等待接受到对方的消息才能发送下一个消息。
我们定义消息的格式如下:
0008|1|nickname
用竖线隔开3部分的字段,分别表示 消息长度、 消息类型 、消息内容
前面字段是4个字节的字符串,比如'0008',其内容是数字,表示消息的长度, 不足4个字节前面补零。
注意长度是整个消息内容的长度,包括 消息头部和消息体
后面用竖线隔开的字段,是1个字节的字符串,是消息类型,其内容是数字,1表示客户昵称, 2 表示 普通消息
前面两个字段合起来 0008|1| , 可以看成是一个消息的头部, nickname 是消息体
再后面用竖线隔开的字段是 消息内容,其长度等于 前面消息长度字段指明的长度 减去 消息头部长度 (也就是7个字节)
服务端程序在下面, 大家参考服务端程序的实现,开发客户端程序和服务端进行通讯
# coding=utf8 import sys from socket import socket,AF_INET,SOCK_STREAM HOST = '' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) class CloseSocketError(Exception): pass # 一个 ConnectionHandler 处理和一个客户端的连接 class ConnectionHandler: # 0008|1|nickname LEN_MSG_LEN_FIELD = 4 LEN_MSG_LEN_TYPE_FIELD = 7 def __init__(self,sock): # 消息缓存区 self._readbuffer = b'' self.sock = sock self.customername = '' # msgBody 是 unicode @staticmethod def encode(msgType,msgBody): rawMsgBody = msgBody.encode('utf8') msgLenth = '{:04}' .format(len(rawMsgBody)+ConnectionHandler.LEN_MSG_LEN_TYPE_FIELD) .encode() msgType = f'{msgType}'.encode() return b'|'.join([msgLenth,msgType,rawMsgBody]) @staticmethod def decode(rawmsg): msgType = int(rawmsg[5:6]) # 这样写rawmsg[5] 返回的是字节对应的数字 msgbody = rawmsg[ConnectionHandler.LEN_MSG_LEN_TYPE_FIELD:].decode('utf8') return [msgType,msgbody] def readMsg(self): bytes = self.sock.recv(BUFSIZ) # ** 用不同的返回值表示不同的含义 # 当对方关闭连接的时候,抛出异常 if not bytes: self.sock.close() raise CloseSocketError() # 应用程序的读取缓冲,和前面讲的系统的读取缓冲是两个不同的缓冲 self._readbuffer += bytes buffLen = len(self._readbuffer) # 如果已经获取了消息头部 (包括 消息长度,消息类型) if buffLen >= self.LEN_MSG_LEN_TYPE_FIELD: msgLen = int(self._readbuffer[:self.LEN_MSG_LEN_FIELD]) # 缓存区消息 已经包含了一个整体的消息(包括 消息长度,消息类型,消息体) if buffLen >= msgLen: # 从缓存区,截取整个消息 msg = self._readbuffer[0:msgLen] # 缓存区变成剩余的消息部分 self._readbuffer = self._readbuffer[msgLen:] return self.decode(msg) # 如果已经获取的消息还不包括一个完整的消息头部, 不做处理等待下面继续接受消息 else: return None print('get:%s' % bytes) # msgBody 是 unicode def sendMsg(self,msgType,msgBody): self.sock.sendall(self.encode(msgType,msgBody)) def handleMsg(self,msgType,msgBody): # 客户名称 if msgType == 1: self.customername = msgBody print('客户名称设置:%s' % self.customername) # 普通消息 elif msgType == 2: print(msgBody) print('---------------') # 客服输入消息内容 msgSend = input('>>') self.sendMsg(2,msgSend) # 主循环,不断的接受消息发送消息 def mainloop(self): while True: try: msg = self.readMsg() # msg 里面包含了 type 和body if msg: msgType,msgBody= msg self.handleMsg(msgType,msgBody) except CloseSocketError: print('对方断开了连接,等待下一个客户') break except IOError: print('对方断开了连接,等待下一个客户') break #创建socket,指明协议 tcpSerSock = socket(AF_INET, SOCK_STREAM) #绑定地址和端口 tcpSerSock.bind(ADDR) tcpSerSock.listen(5) print('等待客户端连接...') while True: #阻塞式等待连接请求 tcpCliSock, addr = tcpSerSock.accept() print('有客户连接上来', addr) handler = ConnectionHandler(tcpCliSock) handler.mainloop() tcpSerSock.close()
# coding=utf-8 from socket import * import traceback,sys HOST = 'localhost' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) class CloseSocketError(Exception): pass class ConnectionHandler: # 0008|1|nickname LEN_MSG_LEN_FIELD = 4 LEN_MSG_LEN_TYPE_FIELD = 7 def __init__(self,sock): # 消息缓存区 self._readbuffer = b'' self.sock = sock self.customername = '' # msgBody 是 unicode @staticmethod def encode(msgType,msgBody): rawMsgBody = msgBody.encode('utf8') msgLenth = '{:04}' .format(len(rawMsgBody)+ConnectionHandler.LEN_MSG_LEN_TYPE_FIELD) .encode() msgType = f'{msgType}'.encode() return b'|'.join([msgLenth,msgType,rawMsgBody]) @staticmethod def decode(rawmsg): msgType = int(rawmsg[5:6]) msgbody = rawmsg[ConnectionHandler.LEN_MSG_LEN_TYPE_FIELD:].decode('utf8') return [msgType,msgbody] def readMsg(self): bytes = self.sock.recv(BUFSIZ) # ** 用不同的返回值表示不同的含义 # 当对方关闭连接的时候,抛出异常 if not bytes: self.sock.close() raise CloseSocketError() self._readbuffer += bytes buffLen = len(self._readbuffer) # 如果已经获取了消息头部 (包括 消息长度,消息类型) if buffLen >= self.LEN_MSG_LEN_TYPE_FIELD: msgLen = int(self._readbuffer[:self.LEN_MSG_LEN_FIELD]) # 缓存区消息 已经包含了一个整体的消息(包括 消息长度,消息类型,消息体) if buffLen >= msgLen: # 从缓存区,截取整个消息 msg = self._readbuffer[0:msgLen] # 缓存区变成剩余的消息部分 self._readbuffer = self._readbuffer[msgLen:] return self.decode(msg) # 如果已经获取的消息还不包括一个完整的消息头部, 不做处理等待下面继续接受消息 else: return None print('--> %s' % bytes) # msgBody 是 unicode def sendMsg(self,msgType,msgBody): self.sock.sendall(self.encode(msgType,msgBody)) def handleMsg(self,msgType,msgBody): # 客户名称 if msgType == 2: print(msgBody) print('---------------') def userinputAndSend(self): msgSend = input('>>') self.sendMsg(2, msgSend) # 主循环,不断的接受消息发送消息 def mainloop(self): # 先发送客户名称 userName = '***' if len(sys.argv) > 1: userName = sys.argv[1].decode(sys.stdin.encoding) self.sendMsg(1,userName) while True: try: self.userinputAndSend() # print('reading...') msg = self.readMsg() if msg: msgType,msgBody= msg self.handleMsg(msgType,msgBody) except CloseSocketError: print('对方断开了连接,程序退出') return except IOError: print('对方断开了连接,程序退出') return #创建socket,指明协议 tcpCliSock = socket(AF_INET, SOCK_STREAM) #连接远程地址和端口 tcpCliSock.connect(ADDR) handler = ConnectionHandler(tcpCliSock) handler.mainloop()
Python 作业 14
有的时候,工作中,我们需要存档文件, 会拷贝一个目录里面所有的文件到另外的机器上
如果是特别机密的存档文件,比如合约,财务信息等,我们不希望这些目录中的文件有任何修改。
假如有员工偷偷修改了存档的文件,就会和源文件不一致
我们需要实现一个工具,能够快速检测存档目录中的文件和源文件是否有不同。
方法是,为源目录中的所有文件产生一个校验文件,里面记录了所有文件的校验和(使用MD5算法)
这样存档后,如果有人修改任何一个文件,
运行工具 检查 就能发现 现有文件的校验和 与源文件中的校验文件里面记录的值 不同
网上有类似的工具: filecheckmd5.exe
下载地址:https://github.com/jcyrss/songqin-testdev/raw/master/others/softwares/filecheckmd5.zip
要求大家用Python语言开发类似的工具。
实现难点 如下,大家自己到网上搜索解决方法,锻炼自己查询资料,解决问题的能力,
难点1: 图形界面
大家可以使用Python 内置的图形界面库 tkinter 去实现
难点2: md5校验和的概念 和 生成文件md5校验和的方法 (特别是对大文件的支持)
from tkinter import Button, Tk, HORIZONTAL,Label,filedialog,messagebox,END from tkinter.ttk import Notebook,Frame from tkinter.scrolledtext import ScrolledText import time,os,threading,hashlib MD5_VALIDATION_FILE = u'FCMD5-sums.MD5' def center(toplevel): toplevel.update_idletasks() w = toplevel.winfo_screenwidth() h = toplevel.winfo_screenheight() size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x')) x = w/2 - size[0]/2 y = h/2 - size[1]/2 toplevel.geometry("%dx%d+%d+%d" % (size + (x, y))) def generate_file_md5( filepath, blocksize=2**20): m = hashlib.md5() with open( filepath, "rb" ) as f: while True: buf = f.read(blocksize) if not buf: break m.update( buf ) return m.hexdigest() class MonApp(Tk): def __init__(self): super().__init__() self.minsize(width=650, height=550) center(self) self.srcFolderPath = '' self.targetFolderPath = '' self.title(u'md5校验器') self.tabMgr = Notebook(self) self.tab1Initial() self.tab2Initial() def tab1Initial(self): tab1 = Frame(self.tabMgr) self.tabMgr.add(tab1, text=u' 创建校验码 ') self.tabMgr.pack(expand=1, fill="both") # tab1.rowconfigure(1, minsize=100) # tab1.columnconfigure(0,minsize=100) Button(tab1, text=u'选择源文件夹', command=self.selectSrcFolder).grid(row=0, column=0, columnspan=3, padx=20, pady=20) self.txtSrcFolder = Label(tab1, text= " ") self.txtSrcFolder.grid(row=1, column=0, columnspan=3, ) self.btnCreating = Button(tab1, text='Go!', command=self.createMD5) self.btnCreating.grid(row=2, column=0, columnspan=2, padx=20, pady=10) self.txtCreating = ScrolledText(tab1) self.txtCreating.grid(row=3, column=0, rowspan=2,columnspan=2, padx=20, pady=10) # self.txtCreating['state']= 'disabled' def tab2Initial(self): tab2 = Frame(self.tabMgr) self.tabMgr.add(tab2, text=u' 进行校验 ') self.tabMgr.pack(expand=1, fill="both") Button(tab2, text=u'选择目标文件', command=self.selectTargetFolder).grid(row=0, column=0, columnspan=3, padx=20, pady=20) self.txtTargetFile = Label(tab2, text= " ") self.txtTargetFile.grid(row=1, column=0, columnspan=3, ) self.btnValidating = Button(tab2, text=u'校验!', command=self.validateMD5) self.btnValidating.grid(row=2, column=0, columnspan=2, padx=20, pady=10) self.txtValidating = ScrolledText(tab2) self.txtValidating.grid(row=3, column=0, rowspan=2,columnspan=2, padx=20, pady=10) def selectSrcFolder(self): self.srcFolderPath = os.path.abspath(filedialog.askdirectory()) self.txtSrcFolder['text'] = self.srcFolderPath # self.targetFolderPath = filedialog.askdirectory() # self.txtTargetFile['text'] = self.targetfilePath def selectTargetFolder(self): self.targetFilePath = os.path.abspath(filedialog.askopenfilename(defaultextension='.MD5', filetypes=[('MD5 file','*.MD5'),('All files','*.*')])) self.targetFolderPath = os.path.dirname(self.targetFilePath) self.txtTargetFile['text'] = self.targetFilePath def _getAllFiles(self,directory): fileList = [] for path, dirs, files in os.walk(os.path.abspath(directory)): # 去掉 System Volume Information 卷信息文件 if 'System Volume Information' in path: continue for filename in files: # 去掉校验文件本身 if filename == MD5_VALIDATION_FILE: continue filepath = os.path.join(path, filename) # print(filepath) fileList.append(filepath) return fileList def createMD5(self): if not self.srcFolderPath.strip(): messagebox.showwarning(u'错误', u'请先选择目录') return def real_create(): allfiles = self._getAllFiles(self.srcFolderPath) self.txtCreating.delete(1.0, END) self.btnCreating['state'] = 'disabled' allfileMd5 = [] for one in allfiles: basedir = self.srcFolderPath if not basedir.endswith('\'): basedir += '\' curFile = one.replace(basedir, '') self.txtCreating.insert(END, curFile + ' ') md5Record = '%s|%s' % (generate_file_md5(one), curFile) allfileMd5.append(md5Record) self.txtCreating.see("end") with open(os.path.join(self.srcFolderPath, MD5_VALIDATION_FILE), 'w',encoding='utf8') as md5file: md5file.write(' '.join(allfileMd5)) messagebox.showinfo('OK', u'处理完成') self.btnCreating['state'] = 'normal' threading.Thread(target=real_create).start() def validateMD5(self): if not self.targetFolderPath.strip(): messagebox.showwarning(u'错误', u'请先选择目录') return if not os.path.isfile(self.targetFilePath): messagebox.showwarning(u'错误', u'没有校验记录文件:'+self.targetFilePath) return def real_check(): # 读取md5校验文件 md5Table = {} with open(self.targetFilePath,'r',encoding='utf8') as md5file: for line in md5file.read().splitlines(): line = line.strip() if line.startswith(';'): continue if line.count('|') != 1: continue md5str,filename = line.split('|') md5Table[filename] = md5str if len(md5Table) == 0: messagebox.showwarning('warning',u'文件中没有md5记录信息') return allfiles = self._getAllFiles(self.targetFolderPath) self.txtValidating.delete(1.0, END) self.btnValidating['state']= 'disabled' errList = '' for one in allfiles: basedir = self.targetFolderPath if not basedir.endswith('\'): basedir += '\' curFile = one.replace(basedir,'') self.txtValidating.insert(END, curFile+' ... ') self.txtValidating.see("end") if curFile not in md5Table: self.txtValidating.insert(END, u'md5校验记录不存在!!!!!!!!!!!! ') errList += curFile + u' md5校验记录不存在 ' continue md5Str_ori = md5Table[curFile] md5Str_now = generate_file_md5(one) if md5Str_now != md5Str_ori: self.txtValidating.insert(END, u'md5校验不匹配!!!!!!!!!!!!!! ') errList += curFile + u' md5校验不匹配 ' continue self.txtValidating.insert(END, u'ok ') for one in md5Table.keys(): if os.path.join(self.targetFolderPath, one) not in allfiles: err = u'{} 文件丢失!!!!!!!!!!!!! '.format(one) errList += err self.txtValidating.insert(END, u' ============ 校验结果 =========== ') if errList: info = u'校验结果有错误!!!' self.txtValidating.insert(END, errList) else: info = u'校验结果完全匹配' self.txtValidating.insert(END, u' ********* 通过 *********') self.txtValidating.see("end") messagebox.showinfo('OK',u'处理完毕 , ' + info) self.btnValidating['state']= 'normal' threading.Thread(target=real_check).start() if __name__ == '__main__': app = MonApp() app.mainloop()
pyhton实现斐波纳契数列前20项
lis = [] for i in range(20): if i == 0 or i==1: lis.append(1) else: lis.append(lis[i-2] + lis[i-1]) print(lis)
python实现n!
def jicheng(n): if n == 0 or n == 1: return 1 else: return (n*jicheng(n-1)) if __name__ == "__main__": print(jicheng(4))
python实现阶乘递归之和1!+2!+3!+。。。+20!
def jicheng(n): if n == 1: return 1 else: return n*jicheng(n-1) print("将结果写入列表之后求和".center(80,'*')) lis = [] for i in range(1,21): lis.append(jicheng(i)) print(sum(lis)) print("for循环直接调用递归函数求和".center(80,'*')) sum_0 = 0 for i in range(1,21): sum_0 +=jicheng(i) print(sum_0)