一、Algorithm
斐波那契数列/台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
# lambda
fib = lambda n: 1 if n <= 2 else fib(n - 1) + fib(n - 2)
# 装饰器记忆法
def memo(func):
cache={}
def wrap(*args):
if args not in cache:
cache[args]=func(*args)
return cache[args]
return wrap
@memo
def fib(i):
if i<2:
return 1
return fib(i-1)+fib(i-2)
# 数学运算
def fib(n):
a, b = 0, 1
while a < n:
a, b = b, a + b
print a
fib(1000)
链表反转
206. Reverse Linked List 1->2->3->4转换成2->1->4->3 解题可参照206. 反转链表(Python)、链表反转的python多种方法实现
class Node:
def __init__(self, val):
self.val = val
self.next = None
a = Node("8")
b = Node("5")
c = Node("3")
d = Node("1")
d.next = c
c.next = b
b.next = a
def reverse_linked_node1(n: Node):
if n is None or n.next is None:
return n
previous = None
while n:
next_node = n.next
n.next = previous
previous = n
n = next_node
return previous
def reverse_linked_node2(head: Node):
if not head or not head.next:
return head
previous = None
while head:
cur = head
head = head.next
cur.next = previous
previous = cur
return previous
def reverse_linked_node3(head: Node):
if not head or not head.next:
return head
p = reverse_linked_node3(head.next)
head.next.next = head
head.next = None
return p
def print_node(node: Node):
while node:
print(f"{node.val} =>", end=" ")
node = node.next
print()
a = Node("8")
b = Node("5")
c = Node("3")
d = Node("1")
d.next = c
c.next = b
b.next = a
print_node(d)
print_node(reverse_linked_node1(d))
a = Node("8")
b = Node("5")
c = Node("3")
d = Node("1")
d.next = c
c.next = b
b.next = a
print_node(reverse_linked_node2(d))
a = Node("8")
b = Node("5")
c = Node("3")
d = Node("1")
d.next = c
c.next = b
b.next = a
print_node(reverse_linked_node3(d))
二、Review
PEP 3107 – Function Annotations
用 : 类型的形式指定函数的参数类型,用 -> 类型 的形式指定函数的返回值类型。Python 解释器并不会因为这些注解而提供额外的校验,没有任何的类型检查工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响。但是出现以下这种代码时: 注意:注解中表达式会执行
def contract(a: int, b: int = 2) -> str:
return str(a) + str(b)
print(contract("a"))
# a2
三、Tip
装饰器:带参与多重
# 函数带参
def tips(func):
def wrapper(a, b):
print("start")
func(a, b)
print("stop")
return wrapper
@tips
def add(a, b):
print("result:%s" % (a + b))
# 装饰器和函数都带参
def new_tips(param):
def tips(func):
def wrapper(a, b):
print("start %s %s" %( param, func.__name__))
func(a, b)
print("stop %s %s" %( param, func.__name__))
return wrapper
return tips
@new_tips("sub")
def sub_name(a, b):
print("result:%s" % (a - b))
add(1, 2)
sub_name(1, 2)
# 多重装饰器
def wrapper1(func):
print("start ---111")
def inner1():
print('wrapper1 ,before func')
ret = func()
print('wrapper1 ,after func')
return ret
print('before return 1')
return inner1
def wrapper3(func):
print("start ---333")
def inner3():
print('wrapper3 ,before func')
ret = func()
print('wrapper3 ,after func')
return ret
print('before return 3')
return inner3
def wrapper2(func):
print("start ---222")
def inner2():
print('wrapper2 ,before func')
ret = func()
print('wrapper2 ,after func')
return ret
print('before return 2')
return inner2
@wrapper3
@wrapper2
@wrapper1
def f():
print('in f')
return "final"
print("start")
temp = f()
print(temp)
random函数
-
random.random() 随机生成一个[0,1)之间的浮点数。
-
random.randint(a,b) 随机生成[a,b]范围内一个整数。
-
random.randrange(a,b,step) 不指定step,随机生成[a,b)范围内一个整数。 指定step,step作为步长会进一步限制[a,b)的范围,比如randrange(0,11,2)意即生成[0,11)范围内的随机偶数。 不指定a,则默认从0开始。
-
random.uniform(a,b)
产生[a,b]范围内一个随机浮点数。
uniform()的a,b参数不需要遵循a<=b的规则,即a小b大也可以,此时生成[b,a]范围内的随机浮点数。但如果上面的三个方法采用这种方式就会产生TypeError或者ValueEeeor错误。
-
random.choice(seq) 从非空序列中随机选取一个数据并带回,该序列可以是list、tuple、str、set。 如果序列为空,则弹出IndexError错误。
-
random.choices(population,weights=None,*,cum_weights=None,k=1) Python3.6版本新增。
population:集群。 weights:相对权重。 cum_weights:累加权重。 k:选取次数。 作用:从集群中随机选取k次数据,返回一个列表,可以设置权重。 注意每次选取都不会影响原序列,每一次选取都是基于原序列。
- random.sample(population,k)
从集群population中选取k个元素,返回一个列表,集群可以是list、tuple、str、set。
与random.choices()的区别:一个是选取k次,一个是选取k个,选取k次的相当于选取后又放回,选取k个则选取后不放回。故random.sample()的k值不能超出集群的元素个数。
- random.shuffle(lst)
随机打乱序列lst的顺序并重新排序,注意它无返回值,另外lst只能是一个可变序列,且只支持有下标的序列,因此它也不适用于set,你最好只把它用在列表上。
import random
a = random.randint(1,5)
print(a)
print(random.choice(["aa", "bb", "cc"]))
name_list = ["a", "b", "c", "d", "e", "f", "g"]
print(random.choices(name_list, k=2))
> ["a","a"] #可能重复
print(random.sample(name_list, k=2))
> ["a","c"] #不会重复
多线程
# 1
def my_thread(arg1, arg2):
print(current_thread().getName(), ' start')
print("%s : %s" % (arg1, arg2))
time.sleep(1)
print(current_thread().getName(), ' finish')
for i in range(1, 6):
# t1 = my_thread(i, i+1)
t1 = threading.Thread(target=my_thread, args=(i, i + 1))
t1.start()
# 2
class MyThread(threading.Thread):
def run(self):
print(current_thread().getName(), 'start')
print('run')
print(current_thread().getName(), 'stop')
t1 = MyThread()
t1.start()
t1.join()
with
class Testwith():
def __init__(self):
print("init")
def __enter__(self): # 类开始时,初始化后执行
print("run")
def __exit__(self, exc_type, exc_val, exc_tb): # 类结束时运行
if exc_tb is None:
print('正常结束')
else:
print("has error %s" % exc_tb)
print("exit")
with Testwith():
print("test is running")
raise NameError("test name error")
四、Share
《软件测试价值提升之路》1-2 心得
一、现状
1、测试困局:
测试的工作大多属于破坏性的;软件设计开发的工作是建设性的;公司盈利最直接的原因就是建设性的工作成果,因此,由于工作性质,测试确实是一个相对难以做出价值的职业。
开发人员把产品“造出来”,市场人员把产品“推出去”,销售人员把产品“卖出去”。
那测试人员呢?我们使得开发更好的“造出来”,市场人员把更好的产品“推出去”,销售人员把更好的产品“卖出去”。
这个“好”字,整合了进度、成本、质量等,其实是比较难以估计的,也就是说测试本身的价值是难以衡量的。
2、测试价值:
观点:与其老板说什么我做什么,不如主动寻求新的测试价值。
3、测试历史的发展:
证实->质检;
证伪->局限性;
缺陷预防->预防在研发的各个环节引入缺陷,最终使得产品质量得到提升的活动。
4、他山之石
-
谷歌(20:1):1、帮助开发更快更好的测试;2、帮助产品更好地采集使用信息和用户反馈;3、安全性、可靠性、性能等专项测试;
-
微软(大变革):1、保障质量;2、提升研发效率;
-
腾讯(3:1):1、尽可能地发现导致商业目标无法达成的缺陷;2、体验测试;3、QQ平台测试侧重质量保证;
-
华为(2:1-4:1):1、保障质量;2、面向客户交付的验收测试;3、多级工具开发团队共同完成流程、工具、技术更新;
- 产品的特点和测试的职责有关;
- 测试团队规模和测试的职责有关;
- 测试工具开发测试是测试团队绕不过去的工作;
二、打破成见,看清环境,改变观念
1、成见
测试工作谁来做?找bug越多越好?面向团队内部?
2、匹配新的业务要求
VUCA时代:volatility(易变性),uncertainty(不确定性),complexity(复杂性),ambiguity(模糊性) 软件的发展:推出快、变化频繁、接口杂、开放性、新技术、重体验。
3、面向企业商业成功
判断测试将要进行的实践是否在创造新的价值,标准就是这个实践对企业必然会关心的3个方面–质量、成本、效率,是否有帮助。
4、寻找价值的最佳人选是自己
如果把问题的解决作为推动改进的契机,在解决问题的过程中探寻到问题对质量、成本、效率的影响方式和外在表征,进而促进多团队协作改进,这样也许会有助于问题的解决和测试自身的提升。
测试的继续进化,测试设计、自动化、环境管理、流程管理技术仍是测试工作的基石,新一代测试人需要站在这个基石上,寻求适合自己产品形态。
5、测试价值的层次
- 测试必须实现的价值:传统认为测试应该有的那些价值
- 测试可以实现的价值:测试有条件做到的那些价值,如改善研发过程质量、提升交付效率等,实现测试价值外延。
-
理想的测试工作场景:当测试把自动化、过程管理、能力建设都做到精致化、自动化的水平时,测试的工作场景是怎样的?
测试价值的实现,选择正确的技术方法很重要,但技术以外的沟通、管理工作一样重。