Jaccorot 日事日毕日清日高

ARTS-006

2020-07-03

一、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函数

  1. random.random() 随机生成一个[0,1)之间的浮点数。

  2. random.randint(a,b) 随机生成[a,b]范围内一个整数。

  3. random.randrange(a,b,step) 不指定step,随机生成[a,b)范围内一个整数。 指定step,step作为步长会进一步限制[a,b)的范围,比如randrange(0,11,2)意即生成[0,11)范围内的随机偶数。 不指定a,则默认从0开始。

  4. random.uniform(a,b)

产生[a,b]范围内一个随机浮点数。

uniform()的a,b参数不需要遵循a<=b的规则,即a小b大也可以,此时生成[b,a]范围内的随机浮点数。但如果上面的三个方法采用这种方式就会产生TypeError或者ValueEeeor错误。

  1. random.choice(seq) 从非空序列中随机选取一个数据并带回,该序列可以是list、tuple、str、set。 如果序列为空,则弹出IndexError错误。

  2. random.choices(population,weights=None,*,cum_weights=None,k=1) Python3.6版本新增。

population:集群。 weights:相对权重。 cum_weights:累加权重。 k:选取次数。 作用:从集群中随机选取k次数据,返回一个列表,可以设置权重。 注意每次选取都不会影响原序列,每一次选取都是基于原序列。

  1. random.sample(population,k)

从集群population中选取k个元素,返回一个列表,集群可以是list、tuple、str、set。

与random.choices()的区别:一个是选取k次,一个是选取k个,选取k次的相当于选取后又放回,选取k个则选取后不放回。故random.sample()的k值不能超出集群的元素个数。

  1. 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. 产品的特点和测试的职责有关;
  2. 测试团队规模和测试的职责有关;
  3. 测试工具开发测试是测试团队绕不过去的工作;

二、打破成见,看清环境,改变观念

1、成见

测试工作谁来做?找bug越多越好?面向团队内部?

2、匹配新的业务要求

VUCA时代:volatility(易变性),uncertainty(不确定性),complexity(复杂性),ambiguity(模糊性) 软件的发展:推出快、变化频繁、接口杂、开放性、新技术、重体验。

3、面向企业商业成功

判断测试将要进行的实践是否在创造新的价值,标准就是这个实践对企业必然会关心的3个方面–质量、成本、效率,是否有帮助。

4、寻找价值的最佳人选是自己

如果把问题的解决作为推动改进的契机,在解决问题的过程中探寻到问题对质量、成本、效率的影响方式和外在表征,进而促进多团队协作改进,这样也许会有助于问题的解决和测试自身的提升。

测试的继续进化,测试设计、自动化、环境管理、流程管理技术仍是测试工作的基石,新一代测试人需要站在这个基石上,寻求适合自己产品形态。

5、测试价值的层次

  1. 测试必须实现的价值:传统认为测试应该有的那些价值
  2. 测试可以实现的价值:测试有条件做到的那些价值,如改善研发过程质量、提升交付效率等,实现测试价值外延。
  3. 理想的测试工作场景:当测试把自动化、过程管理、能力建设都做到精致化、自动化的水平时,测试的工作场景是怎样的?

    测试价值的实现,选择正确的技术方法很重要,但技术以外的沟通、管理工作一样重。


Similar Posts

上一篇 ARTS-005

下一篇 ARTS-007