unittest, nosetest
#!coding=utf-8
"""
门面模式(外观模式)
class Agv:
name = ""
price = 0.0
type = "AGV"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class Fork_truck(Agv):
def __init__(self):
self.name = 'fork truck'
self.price = 10.0
class Small_agv(Agv):
def __init__(self):
self.name = 'Small_agv'
self.price = 8.0
class Rgv:
name = ""
price = 0.0
type = "RGV"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class Truck(Agv):
def __init__(self):
self.name = 'truck'
self.price = 10.0
class Small_rgv(Agv):
def __init__(self):
self.name = 'Small_rgv'
self.price = 8.0
# small_agv = Small_agv()
# print(small_agv.getName())
class Factory:
def get_pro(self,pro_class):
return pro_class()
class Agv_factory(Factory):
type = 'AGV'
class Rgv_factory(Factory):
type = 'RGV'
class GV_name:
def __init__(self):
self.agv = Agv_factory().get_pro(Fork_truck)
self.rgv = Rgv_factory().get_pro(Small_agv)
def get_name(self):
print(self.agv.getName())
print(self.rgv.getName())
if __name__ =='__main__':
GV_name().get_name()
以工厂模式为例,多个类实例化调用函数,如果动词调用可以封装为一个对象方法,需要时去调
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。门面模式注重“统一的对象”,也就是提供一个访问子系统的接口。门面模式与之前说过的模板模式有类似的地方,都是对一些需要重复方法的封装。但从本质上来说,是不同的。模板模式是对类本身的方法的封装,其被封装的方法也可以单独使用;而门面模式,是对子系统的封装,其被封装的接口理论上是不会被单独提出来用的。
减少了系统之间的相互依赖,提高了系统的灵活;
2、提高了整体系统的安全性:封装起的系统对外的接口才可以用,隐藏了很多内部接口细节,若方法不允许使用,则在门面中可以进行灵活控制。
使用场景:
1、为一个复杂的子系统提供一个外界访问的接口。这类例子是生活还是蛮常见的,例如电视遥控器的抽象模型,电信运营商的用户交互设备等;
2、需要简化操作界面时。例如常见的扁平化系统操作界面等,在生活中和工业中都很常见。门面外观的称呼由来
代理模式
class Email:
name ='qq_email'
def send(self):
print('qq email')
# class Requ_Email:
# def send(self):
# print('163 email')
def send():
print('163 email')
class Agent:
white_list = []
def __init__(self,obj):
self.server = obj
setattr(self.server,'send',send)
def __getattr__(self, item):
print('o')
return getattr(self.server,item)
def addWhite(self, addr):
self.white_list.append(addr)
def rmvWhite(self, addr):
self.white_list.remove(addr)
def clearWhite(self):
self.white_list = []
if __name__ == '__main__':
email = Email()
Agent(email).send()
# print(email.name)
print(Agent(email).name)
代理模式代码与适配器很相似但是仍然有一些区别:
适配器模式是因为新旧接口不一致导致出现了客户端无法得到满足的问题,但是,由于旧的接口是不能被完全重构掉的,因为我们还想使用实现了这个接口的一些服务。那么为了使用以前实现旧接口的服务,我们就应该把新的接口转换成旧接口;实现这个转换的类就是抽象意义的转换器。
相比于适配器的应用场景,代理就不一样了,虽然代理也同样是增加了一层,但是,代理提供的接口可以和原本的接口是一样的,代理模式的作用是不把实现直接暴露给client,而是通过代理这个层,代理能够做一些处理。
1、职责清晰:非常符合单一职责原则,主题对象实现真实业务逻辑,而非本职责的事务,交由代理完成;
2、扩展性强:面对主题对象可能会有的改变,代理模式在不改变对外接口的情况下,可以实现最大程度的扩展;
3、保证主题对象的处理逻辑:代理可以通过检查参数的方式,保证主题对象的处理逻辑输入在理想范围内。
应用场景:
1、针对某特定对象进行功能和增强性扩展。如IP防火墙、远程访问代理等技术的应用;
2、对主题对象进行保护。如大流量代理,安全代理等;
3、减轻主题对象负载。如权限代理等。
1、可能会降低整体业务的处理效率和速度。
工厂模式
class Agv:
name = ""
price = 0.0
type = "AGV"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class Fork_truck(Agv):
def __init__(self):
self.name = 'fork truck'
self.price = 10.0
class Small_agv(Agv):
def __init__(self):
self.name = 'Small_agv'
self.price = 8.0
class Rgv:
name = ""
price = 0.0
type = "RGV"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class Truck(Agv):
def __init__(self):
self.name = 'truck'
self.price = 10.0
class Small_rgv(Agv):
def __init__(self):
self.name = 'Small_rgv'
self.price = 8.0
small_agv = Small_agv()
print(small_agv.getName())
class Factory:
def get_pro(self,pro_class):
return pro_class()
class Agv_factory(Factory):
type = 'AGV'
print(Agv_factory().get_pro(Fork_truck).getName())
工厂模式的重点在于将类似产品抽象出对应的工厂进行实例化,工厂类负责实例化,产品类负责对应的属性和方法
工厂方法使一个类的实例化延伸到其子类
如果将实例化方法设为静态方法@classmethod为简单工厂模式
如果将每一个细致的产品都建立对应的工厂(如Small_rgv建立对应一个Small_rgv_factory),这样,生成食物时,foodClass也不必指定。事实上,此时。这种模式,就是抽象工厂模式
好处是:
1、工厂模式巨有非常好的封装性,代码结构清晰;在抽象工厂模式中,其结构还可以随着需要进行更深或者更浅的抽象层级调 整,非常灵活;
2、屏蔽产品类,使产品的被使用业务场景和产品的功能细节可以分而开发进行,是比较典型的解耦框架。
工厂模式、抽象工厂模式的使用场景:
3、当系统实例要求比较灵活和可扩展时,可以考虑工厂模式或者抽象工厂模式实现。比如,
在通信系统中,高层通信协议会很多样化,同时,上层协议依赖于下层协议,那么就可以对应建立对应层级的抽象工厂,根 据不同的“产品需求”去生产定制的实例。
坏处是:
1、工厂模式相对于直接生成实例过程要复杂一些,所以,在小项目中,可以不使用工厂模式;
2、抽象工厂模式中,产品类的扩展比较麻烦。毕竟,每一个工厂对应每一类产品,产品扩展,就意味着相应的抽象工厂也要扩展
单例模式
class Single_logger():
instance =None
class _Single_logger():
def __init__(self):
self.val = None
def __str__(self):
return self.val
def __new__(cls,):
if not cls.instance:
cls.instance = cls._Single_logger()
return cls.instance
def __getattr__(self, item):
return getattr(self.instance,item)
def __setattr__(self,name):
return setattr(self.instance,name)
class Single_logger():
instance =None
def __str__(self):
return self.val
def __new__(cls):
if not cls.instance:
cls.instance = object.__new__(cls)
return cls.instance
可以用于打印日志,缺点会影响全局状态,从头到尾一个对象
适用于日志缓存等
策略模式
class Add:
def excute(self, x, y):
print(x + y)
class Sub:
def excute(self, x, y):
print(x - y)
class Excutor:
def __init__(self, x, y):
self.x = x
self.y = y
def excute_way(self,obj):
obj.excute(self.x,self.y)
Excutor(1,2).excute_way(Sub())
定义一组算法,将每个算法都封装起来,并使他们之间可互换。以上述例子为例,customer类扮演的角色(Context)直接依赖抽象策略的接口,在具体策略实现类中即可定义个性化的策略方式,且可以方便替换。
、各个策略可以自由切换:这也是依赖抽象类设计接口的好处之一;
2、减少代码冗余;
3、扩展性优秀,移植方便,使用灵活。
应用场景:
1、算法策略比较经常地需要被替换时,可以使用策略模式。如现在超市前台,会常遇到刷卡、某宝支付、某信支付等方式,就可以参考策略模式
d={'a':24,'g':52,'i':12,'k':33}
# print(sorted(d.items(),key=lambda x:x[1]))
def extendlist(val, list=[]):
list.append(val)
return list
list1 = extendlist(10)
list2 = extendlist(123, [] )
list3 = extendlist('a')
print("list1 = %s" %list1)
print("list2 = %s" %list2)
print("list3 = %s" %list3)
一行代码99乘法
print("\n".join(" ".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(10)))
内存管理
引用计数,垃圾回收,内存池
垃圾回收:引用计数,标记清楚,分代回收
1. Python 的内存机制呈现金字塔形状,-1,-2 层主要有操作系统进行操作;
2. 第 0 层是 C 中的 malloc,free 等内存分配和释放函数进行操作;
3. 第1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于256K 时有该层直接分配内存;
4. 第3层是上层,也就是我们对 Python 对象的直接操作;
Python 在运行期间会大量地执行 malloc 和 free 的操作,频繁地在用户态和核心态之间进行切换,
这将严重影响 Python 的执行效率。为了加速Python 的执行效率,Python 引入了一个内存池 机制,
用于管理对小块内存的申请和释放。 Python 内部默认的小块内存与大块内存的分界点定在 256 个字节,
当申请的内存小于 256 字节 时,PyObject_Malloc会在内存池中申请内存;当申请的内存大于 256 字节时,PyObject_Malloc 的
行为将蜕化为 malloc 的行为。当然,通过修改 Python 源代码,我们可以改变这个默认值,从而改
变 Python 的默认内存管理行为。
.手动垃圾回收
2.调高垃圾回收阈值
3.避免循环引用(手动解循环引用和使用弱引用)
2.内存泄露是什么?如何避免?
指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的 消失,
而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪 费。导致程序运行速度减慢
甚至系统崩溃等严重后果。 有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。
不使用一个对象时使用:del object 来删除一个对象的引用计数就可以有效防止内存泄漏问题。 通过Python 扩展模块
gc 来查看不能回收的对象的详细信息。 可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0
来判断是否内存
并发编程复习2,多线程
import time,os
# from multiprocessing import Process,Lock
from threading import Thread,Lock,RLock
# def run(name):
# print('%s正运行'%name)
# time.sleep(19)
#
# class Prs(Thread):
# def __init__(self,lock):
# super().__init__()
# self.lock=lock
# def run(self):
# self.lock.acquire()
# print('%s正在运行' % os.getpid())
# time.sleep(2)
# print('%sjieshu'%os.getpid())
# self.lock.release()
# if __name__=='__main__':
# p1 = Thread(target=run,args=('hah',))
# lock=Lock()
# for i in range(3):
# p2 = Prs(lock)
# p2.setDaemon(True)
# p2.start()
# # p2.join()
# p1.start()
# print('你好')
# 对守护线程来说要等主线程所在的进程内所有非守护线程结束才算结束
# GIL锁是解释器级别的锁和线程进程锁级别不一样
# 单核多线程
# 多核计算密集多进程,io密集多线程
# 死锁就是开启一把锁的钥匙在另一把锁内,另一把锁的钥匙自己拿到了给不出去
# 递归锁则不会因为此死锁
# 递归锁
# 可以开几层 不像lock只能acquire一次
# alock=RLock()
# block=RLock()
# alock.acquire()
# block.acquire()
# alock.release()
# block.release()
from threading import Semaphore
# 信号量:允许多个进入的锁用法一致
#
# def run():
# sm.acquire()
# print('进来')
# time.sleep(2)
# sm.release()
# print('出去')
#
#
# if __name__=='__main__':
# sm=Semaphore(5)
# for i in range(16):
# p=Thread(target=run,)
# p.start()
# Event
from threading import Event
# set设为True,wait一直阻塞,isset判断,clear恢复false
# def connect():
#
# print('在连接')
# if eve.isSet():
# print('success')
# eve.clear()
# else:
# print('failed')
#
# def check():
# eve.set()
#
# if __name__=='__main__':
# eve=Event()
# t1=Thread(target=check)
# t2=Thread(target=connect)
# t3 = Thread(target=connect)
# t1.start()
# t2.start()
# t3.start()
# 定时器
# from threading import Timer
# def prin():
# print('soso')
# timer=Timer(2,prin)
# timer.start()
# quene
import queue
# 三种,队列queue.Quene,堆栈queue.LifoQueue,
# 优先级队列queue.PriorityQueue((10,'a'))传元祖,第一个是优先级
"""
"""
# unittest 源码浅析
__main__.py
main.py TestProgram 项目入口 main() 初始化TestProgram对象, 通过__import__或者 parseArgs(self, argv)获取用例所在位文件
parseArgs(self, argv)
判断条件去执行_do_discovery()此会将文件中符合条件test_方法有先加入self.tests
调self.createTests()
_do_discovery(self, argv, Loader=None)
调self.createTests(from_discovery=True, Loader=Loader)
self.createTests()
先将优先级较高的test_函数加入self.test
通过loader.py的loadTestsFromNames 等方法返回 suite.py的self.suiteClass(tests)即为suite.py的TestSuite(tests)
tests为测试类TestCase列表
runTests(self) 通过runner.py的TextTestRunner启动用例 testRunner.run(self.test)#self.test为self.createTests()返回的对象
loader.py 加载模块找到符合条件测试类
TestLoader
loadTestsFromNames
调用[self.loadTestsFromName(name, module) for name in names]作为初始化参数
返回suite.TestSuite对象
loadTestsFromName()
self.loadTestsFromModule(obj)
获取模块内的文件判断执行
self.loadTestsFromTestCase(obj)
获取文件内的类执行
loadTestsFromTestCase(obj)
判断类中的方法是否满足test开头,返回
suite.TestSuite
loadTestsFromModule()
判断文件中类满足TestCase子类返回suite.TestSuite对象
runner.py 启动测试类
TextTestRunner 类属性resultclass = TextTestResult
self._makeResult() ,返回TextTestResult实例对象,包含系统版本描述等信息
run(self, test) 调用self._makeResult()并判断返回对象 startTestRun(),stopTestRun()
并在test(result)先后执行,test(result)为suite.py的self.suiteClass(tests)对象,执行__call__方法
TextTestResult 继承自result.py ,实例化出的对象伴随用例运行整个过程将结果加入对应属性列表
并提供输出方法
suite.py TestSuite 继承BaseTestSuite
__init__初始化已执行self.addTests(tests)将测试类 TestCase对象符合的加入自己self._test
__call__(self, *args, **kwds):
return self.run(*args, **kwds)
调用BaseTestSuite().run()
TestSuite.run()
for index, test in enumerate(self): 因此类对象加__iter__方法为可迭代对象,返回self._test迭代器
if result.shouldStop:
break
if not debug:
test(result) 此时有递归,递归到每一个对象是TestCase对象时,case.py的TestCase实例化对象 (),执行__call__()
else: 否则递归自己的__call__,run()
test.debug()
BaseTestSuite.debug(self):
for test in self:
test.debug()
case.py 测试类继承类
__init__
debug(self):
self.setUp()
getattr(self, self._testMethodName)()
self.tearDown()
while self._cleanups:
function, args, kwargs = self._cleanups.pop(-1)
function(*args, **kwargs)
__call__:
return self.run(*args, **kwds)
run(*args, **kwds)
startTestRun()
result.startTest(self)
self.setUp()
getattr(self, self._testMethodName)()
self.tearDown()
self._addSkip(result, test, reason)
result.addSuccess(self)
result.stopTest(self)
stopTestRun()
result.py 获取结果输出结果
TestResult 提供各种结果列表和输出方法
# nose 源码浅析
__main__.py 项目入口 main() 初始化TestProgram对象,
core.py TestProgram(unittest.TestProgram) 继承自unittest TestProgram
__init__
if config is None:
config = self.makeConfig(env, plugins)
if addplugins:
config.plugins.addPlugins(extraplugins=addplugins)
...
继承父类 调用parseArgs(self, argv)
parseArgs(self, argv)
赋值
self.testLoader = defaultTestLoader(config=self.config)
调用 createTests(self)
createTests(self)
if self.suite is not None:
self.test = self.testLoader.suiteClass(self.suite)
else:
self.testLoader默认为 loader.py的TestLoader(unittest.TestLoader) 调用
self.test = self.testLoader.loadTestsFromNames(self.testNames)
返回 suite.py 的ContextSuiteFactory对象
runTests(self)
plug_runner = self.config.plugins.prepareTestRunner(self.testRunner)
其余大致相同
loader.py
TestLoader(unittest.TestLoader)
__init__ 新增三个属性
self.config = config 即为core.py里的defaultTestLoader(config=self.config)
selector = defaultSelector(config)
self.suiteClass = ContextSuiteFactory(config=config)()为ContextSuite(LazySuite)
loadTestsFromNames()
插件处理其余类似unittest
调用loadTestsFromName()
loadTestsFromName()自定义重写方法
addr = TestAddress(name, workingDir=self.workingDir)
return self.loadTestsFromModule(
module, addr.filename,
discovered=discovered)
loadTestsFromModule()
调用self.selector的wantClass,wantFunction,方法将模块内的符合条件的函数,测试类加入列表
并调用 makeTest 进行处理
makeTest() 调用 _makeTest()
_makeTest() 判断函数、方法、类是否是可迭代对象和unittest。TestCase 子类后
一般情况返回 return self.loadTestsFromTestClass(obj)
return MethodTestCase(obj)
return FunctionTestCase(obj)
皆为unittest.TestCase子类对象,在self.testRunner.run(self.test)时执行
注意一般MethodTestCase(obj)是由MethodTestCase(obj)迭代makeTest() 得到
case.py Test(unittest.TestCase)复用父类__init__方法
__call__ 调用run
run 调用runTest
runTest()
self.test(result)
TestBase(unittest.TestCase): 复用父类__init__方法
runTest(self):
self.test(*self.arg)
unittest.TestCase
调用getattr(self, self._testMethodName)()时默认执行
MethodTestCase(obj)
FunctionTestCase(obj)
初始化将自己函数方法设置为self.test属性
selector.py
Selector(object)
wantClass(self, cls)
test开头或者 unittest.TestCase子类 并不以_开头的 或者 __test__为True 的返回True
wantFile(self, file)
test开头 的返回True
wantFunction(self, function)
wantMethod(self, method)
test开头并不以_开头的 或者 __test__为True 的返回True
suite.py ContextSuite(LazySuite)
_tests = property(_get_wrapped_tests, LazySuite._set_tests, None,)
重写self._test
_get_wrapped_tests(self):
for test in self._get_tests():
if isinstance(test, Test) or isinstance(test, unittest.TestSuite):
yield test 会迭代取出MethodTestCase(obj)
FunctionTestCase(obj)
else:
yield Test(test,
config=self.config,
resultProxy=self.resultProxy)
返回Test对象,或者unittest.TestSuite对象, Test对象时将函数方法执行self.test()然后调用unittest.TestCase,
执行self.test的runTest即TestBase()
"""
"""
并发编程复习3,协程,线程池
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import random,time
# def random_print():
# time.sleep(1)
# print(random.randint(1,4))
# if __name__=='__main__':
# pr_pool=ProcessPoolExecutor(max_workers=3)
#
# res_list=[]
# for i in range(10):
# res=pr_pool.submit(random_print)
# res_list.append(res)
# pr_pool.shutdown()
# for k in res_list:
# print(k.result())
# if __name__ == '__main__':
# th_pool = ThreadPoolExecutor(max_workers=3)
# # th_pool.submit(random_print)
# th_pool.map(random_print,range(10))
# def consumer():
# while True:
# x=yield
# print(x)
# def product():
# g=consumer()
# next(g)
# for i in range(10):
# g.send(i)
# print(i)
#
# product()
# 协程在线程下面开并发,本质其实是开发者代码层面的使程序遇到i/o就切换,cpu检测不到
# from greenlet import greenlet
#
#
# def eat():
# print('eat了第一个')
# g2.switch()
# print('eat了第二个')
# g2.switch()
#
# def product():
# print('生产了第一个')
# g1.switch()
# print('生产了第二个')
#
#
# g1 = greenlet(eat)
# g2 = greenlet(product)
# g1.switch()
# gevent与猴子补丁
# import gevent
# from gevent import monkey
# monkey.patch_all()
# def h1():
# print('h1在运行')
# time.sleep(5)
# print('h1结束了')
#
# def h2():
# print('h2在运行')
# print('h2结束了')
#
# g1=gevent.spawn(h1)
# g2=gevent.spawn(h2)
#
# g1.join()
# g2.join()"""
"""
# import random
# li = [i for i in range(10)]
# random.shuffle(li)
# print(li)
# 冒泡
# def bubb_sort(li):
# for i in range(len(li)-1):
# for k in range(1,len(li)):
# if li[k] < li[k-1]:
# li[k],li[k-1] = li[k-1],li[k]
#
#
# bubb_sort(li)
# print(li)
#
#
# #选择
# def chose_sort(li):
# for i in range(len(li)):
# for k in range(i,len(li)):
# if li[k] < li[i]:
# li[i],li[k] = li[k],li[i]
#
#
# chose_sort(li)
# print(li)
#
#
# def insert_sort(li):
# for i in range(1,len(li)):
# k = i
# while li[k] < li[k-1] and k>0:
# li[k],li[k-1] = li[k-1],li[k]
# k-=1
#
# insert_sort(li)
# print(li)
# 快排
# def quick_sort(li,le,ri):
# if ri>le:
# m = li[le]
# right=ri
# left=le
# while right > left :
# while li[right] > m and right>left:
# right -= 1
# # print(right)
#
# li[left] = li[right]
# # print(li)
# while li[left] < m and right > left:
# left += 1
# # print(left)
# li[right] = li[left]
# # print(li)
# li[right] = m
# quick_sort(li, le, left)
# quick_sort(li, left+1, ri)
#
# quick_sort(li,0,9)
# print(li)
# # 归并
# def al_sort(li,left,right):
# if right>left:
# mid = (right+left)//2
# al_sort(li, left,mid)
# al_sort(li, mid+1, right)
# real_sort(li,left,right)
#
# def real_sort(li,left,right):
# mid = (right + left) // 2
# r_m = mid+1
# l_m = left
# list1=[]
# while mid >= l_m and right >= r_m:
# if mid >= l_m and li[l_m] > li[r_m]:
# list1.append(li[r_m])
# r_m+=1
# if right >= r_m and li[l_m] < li[r_m]:
# list1.append(li[l_m])
# l_m += 1
# while mid >= l_m:
# list1.append(l_m)
# l_m +=1
# while right >= r_m:
# list1.append(r_m)
# r_m +=1
# li[left:right]=list1[0:len(list1)-1]
#
# al_sort(li,0,9)
# print(li)
# 计数排序
def count_sort(li, max_num):
count = [0 for i in range(max_num + 1)]
for num in li:
count[num] += 1
i = 0
for num,m in enumerate(count):
for j in range(m):
li[i] = num
i += 1
#
# 排序方法 时间复杂度 稳定性 代码复杂度
# 最坏情况 平均情 最好情况
# 冒泡排序 O(n2) O(n2) O(n) 稳定 简单
# 直接选择排序 O(n2) O(n2) O(n2) 不稳定 简单
# 直接插入排序 O(n2) O(n2) O(n2) 稳定 简单
# 快速排序 O(n2) O(nlogn) O(nlogn) 不稳定 较复杂
# 堆排序 O(nlogn) O(nlogn) O(nlogn) 不稳定 复杂
# 归并排序 O(nlogn) O(nlogn) O(nlogn) 稳定 较复杂
# 希尔排序 O(1.3n) 不稳定 较复杂
#
# 希尔
# 希尔排序是一种分组插入排序算法。
# 首先取一个整数d1=n/2,将元素分为d1个组,每组相邻量元素之间距离为d1,在各组内进行直接插入排序;
# 取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即所有元素在同一组内进行直接插入排序。
#
#
#
#
# 希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序;最后一趟排序使得所有数据有序。
def shell_sort(li):
gap = len(li) // 2
while gap > 0:
for i in range(gap, len(li)):
tmp = li[i]
j = i - gap
while j >= 0 and tmp < li[j]:
li[j + gap] = li[j]
j -= gap
li[j + gap] = tmp
gap /= 2
"""
li = [i for i in range(10)]
import random
random.shuffle(li)
print li
# def bubb_sort(li):
# for i in range(len(li) - 1):
# for k in range(len(li) - i -1):
# if li[k] > li[k+1]:
# li[k], li[k+1] = li[k+1], li[k]
# print bubb_sort(li)
# print li
#
# def quick_sort(le, li, ri):
# left = le
# right = ri
# if ri > le:
# demo = li[le]
# while right > left:
# while right > left and li[right] > demo:
# right -= 1
# li[left] = li[right]
# while right > left and li[left] < demo:
# left += 1
# li[right] = li[left]
# li[right] = demo
# quick_sort(le, li, right)
# quick_sort(right + 1, li, ri)
#
#
# quick_sort(0, li, len(li)-1)
# print li
# def quick_sort(left, li, right):
# le = left
# ri = right
# if left < right:
# demo = li[le]
# while le < ri:
# while le < ri and li[ri] > demo:
# ri -= 1
# li[le] = li[ri]
# while le < ri and li[le] < demo:
# le += 1
# li[ri] = li[le]
# li[le] = demo
# quick_sort(left, li, le)
# quick_sort(le + 1, li, right)
#
#
# quick_sort(0, li, len(li)-1)
# print li
# def chose_sort(li):
# for i in range(len(li)):
# for k in range(i, len(li)):
# if li[i] > li[k]:
# li[i], li[k] = li[k], li[i]
# print li
#
# chose_sort(li)
# def insert_sort(li):
# for i in range(len(li)):
# index = i
# while index > 0:
# index -= 1
# if li[index + 1] < li[index]:
# li[index + 1], li[index] = li[index], li[index + 1]
# print li
#
# print insert_sort(li)
# def start_ping(cls, src_vm_obj, src_ip, dst_ip, file_suffix):
# """
# :param src_vm_obj:
# :param src_ip:
# :param dst_ip:
# :param file_suffix: ping文件后缀,用来标识文件
# :return:
# """
# ping_file = '/tmp/ping_%s_%s' % (
# file_suffix, time.strftime('%m-%d__%H_%M_%S', time.localtime(time.time())))
# result = Util.exec_cmd_in_vm(src_vm_obj, 'nohup ping %s -c 1000 -I %s &>%s &' % (
# dst_ip, src_ip, ping_file))
# time.sleep(5)
# expectEqual(True, result["isSuccess"])
# return ping_file
#
#
# def check_ping(cls, src_vm_obj, ping_files):
# """
# :param src_vm_obj:
# :param ping_files:
# :return:
# """
# result = Util.exec_cmd_in_vm(src_vm_obj, 'pkill -2 ping')
# expectEqual(True, result["isSuccess"])
# check_cmd = "sleep 1;cat {}"
# for ping_file in ping_files:
# check_result = Util.exec_cmd_in_vm(vm_obj=src_vm_obj, command=check_cmd.format(ping_file))
# expectIn(" 0% packet loss", check_result["msg"], "ping check")
import re
print int(re.findall("icmp_seq=(\d+)",'64 bytes from 100.83.113.76: icmp_seq=35 ttl=62 time=0.385 ms')[0])
浙公网安备 33010602011771号