xiao-qing

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(\'\n\'):
    if line.strip() == \'\':
        continue

    parts = line.split(\'\t\')
    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+\'\n\')

  

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(\'\n\n **********  游戏结束 ********** \n\n\')
        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+\'\n\')

    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(\'\n目录中有这些视频文件:\')
    else:
        print(\'\n目录中没有视频文件\')
        return

    idx = 1
    for one in fileList:
        print(\'%s - %s\' % (idx, one))
        idx += 1

    print(\'\n请选择要合并视频的视频文件序号(格式 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 + \'\n\')


    cmd = FFMPEG_PATH + \' -f concat -i concat.txt -codec copy out.mp4\'
    # 执行命令录制视频
    os.system(cmd)

while True:
    print(\'\n请选择您要做的操作: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 = \'\n\n----------------------\n\n\'.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 + \'\n\')
                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(\'\n\'.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校验记录不存在!!!!!!!!!!!!\n\')
                    errList += curFile + u\'  md5校验记录不存在\n\'
                    continue

                md5Str_ori = md5Table[curFile]
                md5Str_now = generate_file_md5(one)
                if md5Str_now != md5Str_ori:
                    self.txtValidating.insert(END, u\'md5校验不匹配!!!!!!!!!!!!!!\n\')
                    errList += curFile + u\'  md5校验不匹配\n\'
                    continue

                self.txtValidating.insert(END, u\'ok\n\')



            for one in md5Table.keys():
                if os.path.join(self.targetFolderPath, one) not in allfiles:
                    err = u\'{} 文件丢失!!!!!!!!!!!!!\n\'.format(one)

                    errList += err


            self.txtValidating.insert(END, u\'\n\n============ 校验结果 =========== \n\n\')
            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)

 



分类:

技术点:

相关文章:

  • 2022-03-02
  • 2022-01-19
  • 2021-11-15
  • 2021-12-24
  • 2021-12-01
  • 2021-06-11
  • 2021-12-12
  • 2021-06-06
猜你喜欢
  • 2022-03-06
  • 2022-12-23
  • 2021-05-15
  • 2021-10-27
相关资源
相似解决方案