python题目收集

  • Python是如何进行内存管理的?

    小块空间内存池和大对象缓冲池

    参考:python内存管理

  • 什么是lambda函数?它有什么好处?

    Python支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数是从Lisp中借用来的,可以被用在任何需要函数的地方。

    >>> def f(x):
    ...     return x*2
    ...     
    >>> f(3)
    6
    
    >>> g = lambda x: x*2
    >>> g(3)
    6
    
    >>> (lambda x: x*2)(3)
    6
    

    这是一个通常的函数声明,尽管以前你可能没有看到过定义在交互式窗口中的函数。这个 ... 说明它是一个多行的交互语句。只要在第一行的后面敲入回车,Python IDE会让你接着输入命令。

    这是一个 lambda 函数,它完成同上面普通函数相同的事情。注意这里的简短的语法;没有小括号, return 是默认的,并且函数没有名字,只有将它赋值给变量的变量名。

    你甚至可以不将 lambda 函数赋值给一个变量而使用它。这不是举世无双的东西,它只是展示了 lambda 函数只是一个内联函数。

    总之, lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数。 lambda 函数不能包含命令,它们所包含的表达式不能超过一个。不要试图向 lambda 函数中塞入太多的东西;如果你需要更复杂的东西,应该定义一个普通函数,然后想让它多长就多长。

    参考:lambda

  • 如何反序的迭代一个序列?how do I iterate over a sequence in reverse order

    如果是一个list, 最快的解决方案是:

    list.reverse()
    try:
        for x in list:
            “do something with x”
    finally:
        list.reverse()
    

    如果不是list, 最通用但是稍慢的解决方案是:

    for x in sequence[::-1]:
        <do something with x>
    

    参考:反序遍历

  • Python是如何进行类型转换的?

    函数                      描述
    int(x [,base ])         将x转换为一个整数
    long(x [,base ])        将x转换为一个长整数
    float(x )               将x转换到一个浮点数
    complex(real [,imag ])  创建一个复数
    str(x )                 将对象 x 转换为字符串
    repr(x )                将对象 x 转换为表达式字符串
    eval(str )              用来计算在字符串中的有效Python表达式,并返回一个对象
    tuple(s )               将序列 s 转换为一个元组
    list(s )                将序列 s 转换为一个列表
    chr(x )                 将一个整数转换为一个字符
    unichr(x )              将一个整数转换为Unicode字符
    ord(x )                 将一个字符转换为它的整数值
    hex(x )                 将一个整数转换为一个十六进制字符串
    oct(x )                 将一个整数转换为一个八进制字符串
    

    参考:python类型转换

  • Python里面如何实现tuple和list的转换?

    函数tuple(seq)可以把所有可迭代的(iterable)序列转换成一个tuple, 元素不变,排序也不变。
    例如,tuple([1,2,3])返回(1,2,3), tuple(‘abc’)返回(‘a’.'b’,'c’).如果参数已经是一个tuple的话,函数不做任何拷贝而直接返回原来的对象,所以在不确定对象是不是tuple的时候来调用tuple()函数也不是很耗费的。

    函数list(seq)可以把所有的序列和可迭代的对象转换成一个list,元素不变,排序也不变。
    例如 list([1,2,3])返回(1,2,3), list(‘abc’)返回['a', 'b', 'c']。如果参数是一个list, 她会像set[:]一样做一个拷贝。

    参考:元组列表转换

  • 请写出一段Python代码实现删除一个list里面的重复元素

    aa = ["1","2","3","1"]
    list(set(aa))
    

    参考:列表去重

  • list与tuple的区别 ?dictionary与set的区别?

    思路:首先弄懂什么是list类型,什么是tuple类型,什么是dict类型和set类型

    对于list与tupel的区别,在《Python核心编程2》中讲解的很清楚,可以总体概括为,可变与不可变、他们本质相同,但是就因为可变性就延伸了很多不同点。如list类型可以进行相应更改和方法操作,但tupel就没有这个功能。

    对于dict和set,一个是Python唯一的映射类型,一个是Python集合。python中集合对象(set)是一组无序排列的可哈希的值,包含两种类型:可变集合(set)和不可变集合(frozenset),所以set不是可哈希的,frozenset是可哈希的,能当作字典的键。

    参考:python字典和集合

  • 如何理解python for else?

    for i in range(0,10):
        if i > 10:
            break;
    else:
        print "hello world";
    

    即在for 循环中,如果没有从任何一个break中退出,则会执行和for对应的else,只要从break中退出了,则else部分不执行。
    while-else/for-else语句:
    在其他语言中,除了条件语句,是不会见到else分支的,但在Python中,while和for循环中,也是可以使用else语句的。它们的工作顺序为:在循环中使用时,else语句只在循环完成后执行,也就是说,break语句也会跳过else代码块,只要循环是正常结束,而不是通过break,else语句就会执行。

    参考Python中的else语句整理

  • 介绍下你所熟悉或知道的Python库

    思路,考察对应聘者对Python了解的程度,如:

    Tkinter———— Python默认的图形界面接口。

    Python Imaging Library(PIL)————python提供强大的图形处理的能力,并提供广泛的图形文件格式支持,

    PyGame———— 用于多媒体开发和游戏软件开发的模块。

    PyQt ———— 用于python的Qt开发库。

    PyMedia ———— 用于多媒体操作的python模块。

    参考:常用的Python库

  • Python如何实现单例模式?其他23种设计模式python如何实现?

    Python有两种方式可以实现单例模式,下面两个例子使用了不同的方式实现单例模式:

    1.

        class Singleton(type):
            def __init__(cls, name, bases, dict):
                super(Singleton, cls).__init__(name, bases, dict)
                cls.instance = None
    
            def __call__(cls, *args, **kw):
                if cls.instance is None:
                cls.instance = super(Singleton, cls).__call__(*args, **kw)
                return cls.instance
    
        class MyClass(object):
            __metaclass__ = Singleton
    
        print MyClass()
        print MyClass()
    
    1. 使用decorator来实现单例模式

      def singleton(cls):

      instances = {}
      

      def getinstance():

      if cls not in instances:
          instances[cls] = cls()
          return instances[cls]
      return getinstance
      

      @singleton
      class MyClass:

  • Python里面如何拷贝一个对象?

    标准库中的copy模块提供了两个方法来实现拷贝.一个方法是copy,它返回和参数包含内容一样的对象.

    import copy
    new_list = copy.copy(existing_list)
    

    有些时候,你希望对象中的属性也被复制,可以使用deepcopy方法:

    import copy
    new_list_of_dicts = copy.deepcopy(existing_list_of_dicts)
    

    当你对一个对象赋值的时候(做为参数传递,或者做为返回值),Python和Java一样,总是传递原始对象的引用,而不是一个副本.其它一些语言当赋值的时候总是传递副本.Python从不猜测用户的需求 ,如果你想要一个副本,你必须显式的要求.
    Python的行为很简单,迅速,而且一致.然而,如果你需要一个对象拷贝而并没有显式的写出来,会出现问题的,比如:

    >>> a = [1, 2, 3]
    >>> b = a
    >>> b.append(5)
    >>> print a, b 
    [1, 2, 3, 5] [1, 2, 3, 5]

在这里,变量a和b都指向同一个对象(一个列表),所以,一旦你修改了二者之一,另外一个也会受到影响.无论怎样,都会修改原来的对象。

参考:[浅复制深复制][10]
  • 介绍一下except的用法和作用?

    Python的异常处理能力是很强大的,可向用户准确反馈出错信息。在Python中,异常也是对象,可对它进行操作。所有异常都是基类Exception的成员。所有异常都从基类Exception继承,而且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。

    方式一:try语句:

    1使用try和except语句来捕获异常

    try:
       block
    except [exception,[data…]]:
       block
    
    try:
        block
    except [exception,[data...]]:
        block
    else:
        block
    

    该种异常处理语法的规则是:

    • 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
    • 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
    • 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
    • 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
    • 如果没有发生异常,则执行else块代码。

    参考:python异常

  • Python中pass语句的作用是什么?

    pass语句什么也不做,一般作为占位符或者创建占位程序,pass语句不会执行任何操作, 比如:

    while False:
        pass
    

    pass通常用来创建一个最简单的类:

    class MyEmptyClass:
        pass
    

    pass在软件设计阶段也经常用来作为TODO,提醒实现相应的实现,比如:

    def initlog(*args):
        pass #please implement this
    

    参考:python pass作用

  • 介绍一下Python下range()函数的用法?

    如果需要迭代一个数字序列的话,可以使用range()函数,range()函数可以生成等差级数。

    如例:

    for i in range(5)
        print(i)
    

    这段代码将输出0, 1, 2, 3, 4五个数字

    range(10)会产生10个值, 也可以让range()从另外一个数字开始,或者定义一个不同的增量,甚至是负数增量

    range(5, 10)从5到9的五个数字range(0, 10, 3) 增量为三, 包括0,3,6,9四个数字range(-10, -100, -30) 增量为-30, 包括-10, -40, -70可以一起使用range()和len()来迭代一个索引序列例如:

    a = ['Nina', 'Jim', 'Rainman', 'Hello']
    for i in range(len(a)): 
        print(i, a[i])
    

    参考:python range

  • 如何用Python来进行查询和替换一个文本字符串?

    可以使用sub()方法来进行查询和替换,sub方法的格式为:sub(replacement, string[, count=0])

    replacement是被替换成的文本

    string是需要被替换的文本

    count是一个可选参数,指最大被替换的数量

    例子:

    import re
    p = re.compile(‘(blue|white|red)’)
    print(p.sub(‘colour’,'blue socks and red shoes’))
    print(p.sub(‘colour’,'blue socks and red shoes’, count=1))
    

    输出:

    colour socks and colour shoes
    colour socks and red shoes
    

    subn()方法执行的效果跟sub()一样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量

    例如:

    import re
    p = re.compile(‘(blue|white|red)’)
    print(p.subn(‘colour’,'blue socks and red shoes’))
    print(p.subn(‘colour’,'blue socks and red shoes’, count=1))
    

    输出

    (‘colour socks and colour shoes’, 2)
    (‘colour socks and red shoes’, 1)
    
  • Python里面search()和match()的区别?

    match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none

    例如:
    print(re.match(‘super’, ‘superstition’).span())会返回(0, 5)
    而print(re.match(‘super’, ‘insuperable’))则返回None
    search()会扫描整个字符串并返回第一个成功的匹配

    例如:
    print(re.search(‘super’, ‘superstition’).span())返回(0, 5)
    print(re.search(‘super’, ‘insuperable’).span())返回(2, 7)

  • 用Python匹配HTML tag的时候,<.*><.*?>有什么区别?

    当重复匹配一个正则表达式时候, 例如<.*>, 当程序执行匹配的时候,会返回最大的匹配值

    例如:

    import re
    s = ‘<html><head><title>Title</title>’
    print(re.match(‘<.*>’, s).group())
    

    会返回一个匹配<html><head><title>Title</title>而不是<html>

    而:

    import re
    s = ‘<html><head><title>Title</title>’
    print(re.match(‘<.*?>’, s).group())
    

    则会返回<html>

    <.*>这种匹配称作贪心匹配
    <.*?>称作非贪心匹配

  • Python里面如何生成随机数?

    random.random()用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成随机数

    n: a <= n <= b。如果 a <b, 则 b <= n <= a。
    
    print random.uniform(10, 20)  
    print random.uniform(20, 10)  
    #---- 
    #18.7356606526  
    #12.5798298022  
    

    random.randint()用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,

    print random.randint(12, 20) #生成的随机数n: 12 <= n <= 20 
    print random.randint(20, 20) #结果永远是20 
    #print random.randint(20, 10) #该语句是错误的。 
    

    下限必须小于上限。

    random.randrange()从指定范围内,生成按指定基数递增的集合。

    随机整数:

    >>> import random
    >>> random.randint(0,99)
    21
    

    随机选取0到100间的偶数:

    >>> import random
    >>> random.randrange(0, 101, 2)
    42
    

    随机浮点数:

    >>> import random
    >>> random.random() 
    0.85415370477785668
    >>> random.uniform(1, 10)
    5.4221167969800881
    

    随机字符:

    >>> import random
    >>> random.choice('abcdefg&#%^*f')
    'd'
    

    多个字符中选取特定数量的字符:

    >>> import random
    random.sample('abcdefghij',3) 
    ['a', 'd', 'b']
    

    多个字符中选取特定数量的字符组成新字符串:

    >>> import random
    >>> import string
    >>> string.join(random.sample(['a','b','c','d','e','f','g','h','i','j'], 3)).replace(" ","")
    'fih'
    

    随机选取字符串:

    >>> import random
    >>> random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )
    'lemon'
    

    洗牌:

    >>> import random
    >>> items = [1, 2, 3, 4, 5, 6]
    >>> random.shuffle(items)
    >>> items
    [3, 2, 5, 6, 4, 1]
    
  • 如何用Python来发送邮件?

    可以使用smtplib标准库。

    以下代码可以在支持SMTP监听器的服务器上执行。

    import sys, smtplib
    
    fromaddr = raw_input("From: ")
    toaddrs = raw_input("To: ").split(",")
    print "Enter message, end with ^D:"
    msg = ""
    while 1:
        line = sys.stdin.readline()
        if not line:
            break
    msg = msg + line
    
    # 发送邮件部分
    server = smtplib.SMTP(‘localhost’)
    server.sendmail(fromaddr, toaddrs, msg)
    server.quit()
    
  • 有两个序列a,b,大小都为n,序列元素的值任意整形数,无序;
    要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。

    1. 将两序列合并为一个序列,并排序,为序列Source
    2. 拿出最大元素Big,次大的元素Small
    3. 在余下的序列S[:-2]进行平分,得到序列max,min
    4. 将Small加到max序列,将Big加大min序列,重新计算新序列和,和大的为max,小的为min。
  • Python如何定义一个函数?

    函数的定义形式如下:

    def (arg1, arg2,… argN): 
    

    函数的名字也必须以字母开头,可以包括下划线“ ”,但不能把Python的关键字定义成函数的名字。函数内的语句数量是任意的,每个语句至少有一个空格的缩进,以表示此语句属于这个函数的。缩进结束的地方,函数自然结束。
    下面定义了一个两个数相加的函数:

    >>> def add(p1, p2): 
        print p1, “+”, p2, “=”, p1+p2 
    >>> add(1, 2) 
    1 + 2 = 3 
    

    函数的目的是把一些复杂的操作隐藏,来简化程序的结构,使其容易阅读。函数在调用前,必须先定义。也可以在一个函数内部定义函数,内部函数只有在外部函数调用时才能够被执行。程序调用函数时,转到函数内部执行函数内部的语句,函数执行完毕后,返回到它离开程序的地方,执行程序的下一条语句。

  • 有没有一个工具可以帮助查找python的bug和进行静态的代码分析?

    有,PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告

    Pylint是另外一个工具可以进行coding standard检查。

  • 如何在一个function里面设置一个全局的变量?

    解决方法是在function的开始插入一个global声明:

    def f():
        global x
    
  • 听过 the zen of python 吗?尽可能地默写它,中英文皆可,大意也可。如果没有听过,谈谈你对 pythonic 的看法,或者你认为什么样的 python 代码才是好代码。

    在python中import this就会展示出The Zen of Python如下:

    The Zen of Python, by Tim Peters

    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than right now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!

    这被称为python之禅,以下是翻译

    Python之禅

    优美胜于丑陋(Python 以编写优美的代码为目标)
    明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
    简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
    复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
    扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
    间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
    可读性很重要(优美的代码是可读的)
    即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
    不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)
    当存在多种可能,不要尝试去猜测
    而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
    虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )
    做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
    如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
    命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)

    参考:pythonic

  • 现在有一个 dict 对象 adict,里面包含了一百万个元素,查找其中的某个元素的平均需要多少次比较?一千万个元素呢?

    python dict和set都是使用hash表来实现(类似c++11标准库中unordered_map),查找元素的时间复杂度是O(1)

    a = range(1000)
    s = set(a)
    d = dict((i,1) for i in a)
    %timeit -n 10000 100 in d
    %timeit -n 10000 100 in s
    10000 loops, best of 3: 43.5 ns per loop
    10000 loops, best of 3: 49.6 ns per loop
    

    dict的效率略高(占用的空间也多一些)。

  • 现在有一个 list 对象 alist,里面的所有元素都是字符串,编写一个函数对它实现一个大小写无关的排序。

    a = ['a', 'A', 'b', 'C', 'd']
    b = [i.lower() for i in a]
    b.sort()
    
  • python 里关于“堆”这种数据结构的模块是哪个?“堆”有什么优点和缺点?举一个游戏开发中可能会用到堆的问题(不限是于 python 的堆,可以是其它语言的相关实现)。

    heapq模块使用一个用堆实现的优先级队列。堆是一种简单的有序列表,并且置入了堆的相关规则。

    堆是一种树形的数据结构,树上的子节点与父节点之间存在顺序关系。二叉堆(binary heap)能够用一个经过组织的列表或数组结构来标识,在这种结构中,元素N的子节点的序号为2N+1和2N+2(下标始于0)。简单来说,这个模块中的所有函数都假设序列是有序的,所以序列中的第一个元素(seq[0])是最小的,序列的其他部分构成一个二叉树,并且seq[i]节点的子节点分别为seq[2i+1]以及seq[2i+2]。当对序列进行修改时,相关函数总是确保子节点大于等于父节点。

    import heapq
    
    heap = []
    
    for value in [20, 10, 30, 50, 40]:
        heapq.heappush(heap, value)
    
    while heap:
        print heapq.heappop(heap)
    

    heapq模块有两个函数nlargest()和nsmallest(),顾名思义,让我们来看看它们的用法。

    import heapq
    
    nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
    print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]
    print(heapq.nsmallest(3, nums)) # Prints [-4, 1, 2]
    

    两个函数也能够通过一个键参数使用更为复杂的数据结构,例如:

    import heapq
    
    portfolio = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}
    ]
    cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
    expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
    
    print cheap
    
    # [{'price': 16.35, 'name': 'YHOO', 'shares': 45},
    # {'price': 21.09, 'name': 'FB', 'shares': 200}, {'price': 31.75, 'name': 'HPQ', 'shares': 35}]
    
    print expensive
    
    # [{'price': 543.22, 'name': 'AAPL', 'shares': 50}, {'price': 115.65, 'name': 'ACME', 
    # 'shares': 75}, {'price': 91.1, 'name': 'IBM', 'shares': 100}]
    

    来看看如何实现一个根据给定优先级进行排序,并且每次pop操作都返回优先级最高的元素的队列例子。

    import heapq
    
    class Item:
        def __init__(self, name):
            self.name = name
    
        def __repr__(self):
            return 'Item({!r})'.format(self.name)
    
    class PriorityQueue:
        def __init__(self):
            self._queue = []
            self._index = 0
    
        def push(self, item, priority):
            heapq.heappush(self._queue, (-priority, self._index, item))
            self._index += 1
    
        def pop(self):
            return heapq.heappop(self._queue)[-1]
    
    q = PriorityQueue()
    q.push(Item('foo'), 1)
    q.push(Item('bar'), 5)
    q.push(Item('spam'), 4)
    q.push(Item('grok'), 1)
    
    print q.pop() # Item('bar')
    print q.pop() # Item('spam')
    print q.pop() # Item('foo')
    print q.pop() # Item('grok')
    

    数据结构优缺点

    类型    优点    缺点
    数组    插入块,如果知道下标,可以非常快的存储    查找慢,删除慢,大小固定
    有序数组    比无序数组查找快    删除和插入慢,大小固定
    栈    提供后进先出方式的存取    效率低
    队列    提供先进先出的方式存取    效率低
    链表    插入,删除快    查找慢
    二叉树    查找,插入,删除都快    如果非平衡就很慢,删除的算法复杂
    红黑树    查找,插入,删除都快    算法复杂
    哈希表    如果关键字已知则存取极快,插入块    删除慢,如果不知道关键字则存取很慢,对存储空间使用不充分
    堆    插入,删除快,对最大数据项的存取很快    对其他存储项很慢
    
  • set 是在哪个版本成为 build-in types 的?举一个你在以往项目中用到这种数据结构的问题(不限是于 python 的 set ,可以是其它语言的相关实现),并说明为什么当时选择了 set 这种数据结构。

    set跟list一样可以用{}来定义,但是pyton -v 版本 >2.7
    set的数据格式:

    [html] view plaincopy
    s1={"abc","def"}      #{} 自己定义  
    >>> print s1  
    set(['abc', 'def'])    
    >>> s2=set("abcdef")  #set 函数用string进行初始化  
    >>> print s2  
    set(['a', 'c', 'b', 'e', 'd', 'f'])  
    >>> s3=set(["abc",123,"def"])  #set 函数用list进行初始化  
    >>> print s3  
    set([123, 'abc', 'def'])  
    
  • 有一个排好序地 list 对象 alist,查找其中是否有某元素 a(尽可能地使用标准库函数)。

    index() 函数用于从列表中找出某个值第一个匹配项的索引位置。

    list.index(obj) # obj -- 查找的对象。
    

    该方法返回查找对象的索引位置,如果没有找到对象则抛出异常。

    count() 方法用于统计某个元素在列表中出现的次数。

    list.count(obj) # obj -- 列表中统计的对象。
    

    返回元素在列表中出现的次数。

  • 说说 dict 的 items() 方法与 iteritems() 方法的不同。

    #字典items()的使用
    dict = {"a" : "apple", "b" : "banana", "c" : "grape", "d" : "orange"}
    #每个元素是一个key和value组成的元组,以列表的方式输出
    print dict.items()
    #调用items()实现字典的遍历
    dict = {"a" : "apple", "b" : "banana", "g" : "grape", "o" : "orange"}
    for (k, v) in dict.items():
        print "dict[%s] =" % k, v
    #调用iteritems()实现字典的遍历
    dict = {"a" : "apple", "b" : "banana", "c" : "grape", "d" : "orange"}
    print dict.iteritems()
    for k, v in dict.iteritems():
        print "dict[%s] =" % k, v
    for (k, v) in zip(dict.iterkeys(), dict.itervalues()):
        print "dict[%s] =" % k, v
    

    python3.0以上,不存在dict.iteritems()这个函数。

  • 写一段程序逐行读入一个文本文件,并在屏幕上打印出来。

    file_object = open('thefile.txt')  
    try:  
         for line in file_object:
             print line.rstrip()
    finally:  
         file_object.close()
    
  • 默写尽可能多的 str 对象的方法。

    在python 中任何事物都是对象,就是万物皆对象,同时字符串也是一个对象,当你调用一些基本的操作方法时,会自动调用类定义的内建方法,在python中方法主要三种

    1. 一般的工友方法(默认)命名:和一般的函数命名规则相同
    2. 私有方法命名:一般以__开始
    3. 内建的方法,有时你也需要重写或重载 比如__init__构造方法
      下面具体来看一下str的类方法
    class str(basestring)
    
    |  str(object) ->string
    | 
    |  Return a nice stringrepresentation of the object.
    |  If the argument is a string,the return value is the same object.
    | 
    |  Method resolutionorder:
    |     str
    |     basestring
    |     object
    | 
    |  Methods defined here:
    | 
    |  __add__(...)
    |     x.__add__(y) <==> x+y
    | 
    |  __contains__(...)
    |     x.__contains__(y) <==> y in x
    | 
    |  __eq__(...)
    |     x.__eq__(y) <==> x==y
    | 
    |  __format__(...)
    |     S.__format__(format_spec) -> unicode
    | 
    |  __ge__(...)
    |     x.__ge__(y) <==>x>=y
    | 
    |  __getattribute__(...)
    |     x.__getattribute__('name') <==>x.name
    | 
    |  __getitem__(...)
    |     x.__getitem__(y) <==> x[y]
    | 
    |  __getnewargs__(...)
    | 
    |  __getslice__(...)
    |     x.__getslice__(i, j) <==>x[i:j]
    |     
    |     Use of negative indices is not supported.
    | 
    |  __gt__(...)
    |     x.__gt__(y) <==>x>y
    | 
    |  __hash__(...)
    |     x.__hash__() <==> hash(x)
    | 
    |  __le__(...)
    |     x.__le__(y) <==>x<=y
    | 
    |  __len__(...)
    |     x.__len__() <==> len(x)
    | 
    |  __lt__(...)
    |     x.__lt__(y) <==>x<y
    | 
    |  __mod__(...)
    |     x.__mod__(y) <==> x%y
    | 
    |  __mul__(...)
    |     x.__mul__(n) <==> x*n
    | 
    |  __ne__(...)
    |     x.__ne__(y) <==> x!=y
    | 
    |  __repr__(...)
    |     x.__repr__() <==> repr(x)
    | 
    |  __rmod__(...)
    |     x.__rmod__(y) <==> y%x
    | 
    |  __rmul__(...)
    |     x.__rmul__(n) <==> n*x
    | 
    |  __sizeof__(...)
    |     S.__sizeof__() -> size of S in memory, inbytes
    | 
    |  __str__(...)
    |     x.__str__() <==> str(x)
    | 
    |  capitalize(...)
    |     S.capitalize() -> string
    |     
    |     Return a copy of the string S with only its first character
    |     capitalized.
    | 
    |  center(...)
    |     S.center(width[, fillchar]) -> string
    |     
    |     Return S centered in a string of length width. Padding is
    |     done using the specified fill character (default is a space)
    | 
    |  count(...)
    |     S.count(sub[, start[, end]]) -> int
    |     
    |     Return the number of non-overlapping occurrences of substring subin
    |     string S[start:end].  Optional arguments start andend are interpreted
    |     as in slice notation.
    | 
    |  decode(...)
    |     S.decode([encoding[,errors]]) -> object
    |     
    |     Decodes S using the codec registered for encoding. encodingdefaults
    |     to the default encoding. errors may be given to set a differenterror
    |     handling scheme. Default is 'strict' meaning that encoding errorsraise
    |     a UnicodeDecodeError. Other possible values are 'ignore' and'replace'
    |     as well as any other name registered with codecs.register_errorthat is
    |     able to handle UnicodeDecodeErrors.
    | 
    |  encode(...)
    |     S.encode([encoding[,errors]]) -> object
    |     
    |     Encodes S using the codec registered for encoding. encodingdefaults
    |     to the default encoding. errors may be given to set a differenterror
    |     handling scheme. Default is 'strict' meaning that encoding errorsraise
    |     a UnicodeEncodeError. Other possible values are 'ignore', 'replace'and
    |     'xmlcharrefreplace' as well as any other name registered with
    |     codecs.register_error that is able to handleUnicodeEncodeErrors.
    | 
    |  endswith(...)
    |     S.endswith(suffix[, start[, end]]) -> bool
    |     
    |     Return True if S ends with the specified suffix, Falseotherwise.
    |     With optional start, test S beginning at that position.
    |     With optional end, stop comparing S at that position.
    |     suffix can also be a tuple of strings to try.
    | 
    |  expandtabs(...)
    |     S.expandtabs([tabsize]) -> string
    |     
    |     Return a copy of S where all tab characters are expanded usingspaces.
    |     If tabsize is not given, a tab size of 8 characters isassumed.
    | 
    |  find(...)
    |     S.find(sub [,start [,end]]) -> int
    |     
    |     Return the lowest index in S where substring sub is found,
    |     such that sub is contained within s[start:end]. Optional
    |     arguments start and end are interpreted as in slice notation.
    |     
    |     Return -1 on failure.
    | 
    |  format(...)
    |     S.format(*args, **kwargs) -> unicode
    | 
    |  index(...)
    |     S.index(sub [,start [,end]]) -> int
    |     
    |     Like S.find() but raise ValueError when the substring is notfound.
    | 
    |  isalnum(...)
    |     S.isalnum() -> bool
    |     
    |     Return True if all characters in S are alphanumeric
    |     and there is at least one character in S, False otherwise.
    | 
    |  isalpha(...)
    |     S.isalpha() -> bool
    |     
    |     Return True if all characters in S are alphabetic
    |     and there is at least one character in S, False otherwise.
    | 
    |  isdigit(...)
    |     S.isdigit() -> bool
    |     
    |     Return True if all characters in S are digits
    |     and there is at least one character in S, False otherwise.
    | 
    |  islower(...)
    |     S.islower() -> bool
    |     
    |     Return True if all cased characters in S are lowercase and thereis
    |     at least one cased character in S, False otherwise.
    | 
    |  isspace(...)
    |     S.isspace() -> bool
    |     
    |     Return True if all characters in S are whitespace
    |     and there is at least one character in S, False otherwise.
    | 
    |  istitle(...)
    |     S.istitle() -> bool
    |     
    |     Return True if S is a titlecased string and there is at leastone
    |     character in S, i.e. uppercase characters may only followuncased
    |     characters and lowercase characters only cased ones. ReturnFalse
    |     otherwise.
    | 
    |  isupper(...)
    |     S.isupper() -> bool
    |     
    |     Return True if all cased characters in S are uppercase and thereis
    |     at least one cased character in S, False otherwise.
    | 
    |  join(...)
    |     S.join(sequence) -> string
    |     
    |     Return a string which is the concatenation of the strings inthe
    |     sequence.  The separator between elements isS.
    | 
    |  ljust(...)
    |     S.ljust(width[, fillchar]) -> string
    |     
    |     Return S left-justified in a string of length width. Paddingis
    |     done using the specified fill character (default is a space).
    | 
    |  lower(...)
    |     S.lower() -> string
    |     
    |     Return a copy of the string S converted to lowercase.
    | 
    |  lstrip(...)
    |     S.lstrip([chars]) -> string or unicode
    |     
    |     Return a copy of the string S with leading whitespaceremoved.
    |     If chars is given and not None, remove characters in charsinstead.
    |     If chars is unicode, S will be converted to unicode beforestripping
    | 
    |  partition(...)
    |     S.partition(sep) -> (head, sep, tail)
    |     
    |     Search for the separator sep in S, and return the part beforeit,
    |     the separator itself, and the part after it.  Ifthe separator is not
    |     found, return S and two empty strings.
    | 
    |  replace(...)
    |     S.replace (old, new[, count]) -> string
    |     
    |     Return a copy of string S with all occurrences of substring
    |     old replaced by new.  If the optional argumentcount is
    |     given, only the first count occurrences are replaced.
    | 
    |  rfind(...)
    |     S.rfind(sub [,start [,end]]) -> int
    |     
    |     Return the highest index in S where substring sub is found,
    |     such that sub is contained within s[start:end]. Optional
    |     arguments start and end are interpreted as in slice notation.
    |     
    |     Return -1 on failure.
    | 
    |  rindex(...)
    |     S.rindex(sub [,start [,end]]) -> int
    |     
    |     Like S.rfind() but raise ValueError when the substring is notfound.
    | 
    |  rjust(...)
    |     S.rjust(width[, fillchar]) -> string
    |     
    |     Return S right-justified in a string of length width. Paddingis
    |     done using the specified fill character (default is a space)
    | 
    |  rpartition(...)
    |     S.rpartition(sep) -> (tail, sep, head)
    |     
    |     Search for the separator sep in S, starting at the end of S, andreturn
    |     the part before it, the separator itself, and the part afterit.  If the
    |     separator is not found, return two empty strings and S.
    | 
    |  rsplit(...)
    |     S.rsplit([sep [,maxsplit]]) -> list of strings
    |     
    |     Return a list of the words in the string S, using sep as the
    |     delimiter string, starting at the end of the string andworking
    |     to the front.  If maxsplit is given, at mostmaxsplit splits are
    |     done. If sep is not specified or is None, any whitespacestring
    |     is a separator.
    | 
    |  rstrip(...)
    |     S.rstrip([chars]) -> string or unicode
    |     
    |     Return a copy of the string S with trailing whitespaceremoved.
    |     If chars is given and not None, remove characters in charsinstead.
    |     If chars is unicode, S will be converted to unicode beforestripping
    | 
    |  split(...)
    |     S.split([sep [,maxsplit]]) -> list of strings
    |     
    |     Return a list of the words in the string S, using sep as the
    |     delimiter string.  If maxsplit is given, at mostmaxsplit
    |     splits are done. If sep is not specified or is None, any
    |     whitespace string is a separator and empty strings areremoved
    |     from the result.
    | 
    |  splitlines(...)
    |     S.splitlines([keepends]) -> list of strings
    |     
    |     Return a list of the lines in S, breaking at line boundaries.
    |     Line breaks are not included in the resulting list unlesskeepends
    |     is given and true.
    | 
    |  startswith(...)
    |     S.startswith(prefix[, start[, end]]) -> bool
    |     
    |     Return True if S starts with the specified prefix, Falseotherwise.
    |     With optional start, test S beginning at that position.
    |     With optional end, stop comparing S at that position.
    |     prefix can also be a tuple of strings to try.
    | 
    |  strip(...)
    |     S.strip([chars]) -> string or unicode
    |     
    |     Return a copy of the string S with leading and trailing
    |     whitespace removed.
    |     If chars is given and not None, remove characters in charsinstead.
    |     If chars is unicode, S will be converted to unicode beforestripping
    | 
    |  swapcase(...)
    |     S.swapcase() -> string
    |     
    |     Return a copy of the string S with uppercase characters
    |     converted to lowercase and vice versa.
    | 
    |  title(...)
    |     S.title() -> string
    |     
    |     Return a titlecased version of S, i.e. words start withuppercase
    |     characters, all remaining cased characters have lowercase.
    | 
    |  translate(...)
    |     S.translate(table [,deletechars]) -> string
    |     
    |     Return a copy of the string S, where all characters occurring
    |     in the optional argument deletechars are removed, and the
    |     remaining characters have been mapped through the given
    |     translation table, which must be a string of length 256.
    | 
    |  upper(...)
    |     S.upper() -> string
    |     
    |     Return a copy of the string S converted to uppercase.
    | 
    |  zfill(...)
    |     S.zfill(width) -> string
    |     
    |     Pad a numeric string S with zeros on the left, to fill afield
    |     of the specified width.  The string S is nevertruncated.
    
  • 打乱一个排好序的 list 对象 alist。

    import random
    b = ['a', 'a', 'b', 'c', 'd']
    random.shuffle(b)
    
  • 有二维的 list 对象(即它的每一个元素都是一个 list 对象)alist,假定其中的所有元素都具有相同的长度(把 alist 想象成一个表格),写一段程序根据元素的第二个元素排序(即对表格的第二列字段排序)。

    a = [['3', 'b'], ['2', 'd'], ['1', 'c'], ['4', 'a']]
    sorted(a, key=lambda a:a[1])
    

    参考:python中sorted内建函数的用法

  • 实现一个 stack。

    class Stack :
    
        # Creates an empty stack.
        def __init__( self ):
            self._theItems = list()
    
        # Returns True if the stack is empty or False otherwise.
        def isEmpty( self ):
            return len( self ) == 0
    
        # Returns the number of items in the stack.
        def __len__ ( self ):
            return len( self._theItems )
    
        # Returns the top item on the stack without removing it.
        def peek( self ):
            assert not self.isEmpty(), "Cannot peek at an empty stack"
            return self._theItems[-1]
    
        # Removes and returns the top item on the stack.
        def pop( self ):
            assert not self.isEmpty(), "Cannot pop from an empty stack"
            return self._theItems.pop()
    
        # Push an item onto the top of the stack.
        def push( self, item ):
            self._theItems.append( item )
    
  • 编写一个简单的 ini 文件解释器。

    ConfigParser 是用来读取配置文件的包。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。

    [db]
    db_host = 127.0.0.1
    db_port = 22
    db_user = root
    db_pass = rootroot
    
    [concurrent]
    thread = 10
    processor = 20
    

    中括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。

    ConfigParser 初始工作
    使用ConfigParser 首选需要初始化实例,并读取配置文件:

    cf = ConfigParser.ConfigParser()
    cf.read("配置文件名")
    

    ConfigParser 常用方法

    1. 获取所有sections。也就是将配置文件中所有“[ ]”读取到列表中:

      s = cf.sections()
      print 'section:', s

      将输出(以下将均以简介中配置文件为例):
      

      section: ['db', 'concurrent']

    2. 获取指定section 的options。即将配置文件某个section 内key 读取到列表中:

      o = cf.options("db")
      print 'options:', o

      将输出:
      

      options: ['db_host', 'db_port', 'db_user', 'db_pass']

    3. 获取指定section 的配置信息。

      v = cf.items("db")
      print 'db:', v

      将输出:
      

      db: [('db_host', '127.0.0.1'), ('db_port', '22'), ('db_user', 'root'), ('db_pass', 'rootroot')]

    4. 按照类型读取指定section 的option 信息。

      同样的还有getfloat、getboolean。
      

      可以按照类型读取出来

      db_host = cf.get("db", "db_host")
      db_port = cf.getint("db", "db_port")
      db_user = cf.get("db", "db_user")
      db_pass = cf.get("db", "db_pass")

      返回的是整型的

      threads = cf.getint("concurrent", "thread")
      processors = cf.getint("concurrent", "processor")

      print "db_host:", db_host
      print "db_port:", db_port
      print "db_user:", db_user
      print "db_pass:", db_pass
      print "thread:", threads
      print "processor:", processors

      将输出:
      

      db_host: 127.0.0.1
      db_port: 22
      db_user: root
      db_pass: rootroot
      thread: 10
      processor: 20

    5. 设置某个option 的值。(记得最后要写回)

      cf.set("db", "db_pass", "zhaowei")
      cf.write(open("test.conf", "w"))

    6.添加一个section。(同样要写回)

        cf.add_section('liuqing')
        cf.set('liuqing', 'int', '15')
        cf.set('liuqing', 'bool', 'true')
        cf.set('liuqing', 'float', '3.1415')
        cf.set('liuqing', 'baz', 'fun')
        cf.set('liuqing', 'bar', 'Python')
        cf.set('liuqing', 'foo', '%(bar)s is %(baz)s!')
        cf.write(open("test.conf", "w"))
    
    1. 移除section 或者option 。(只要进行了修改就要写回的哦)

          
          cf.remove_option('liuqing','int')
          cf.remove_section('liuqing')
          cf.write(open("test.conf", "w"))
      
  • 现有 N 个纯文本格式的英文文件,实现一种检索方案,即做一个小搜索引擎。
  • python自动连接ssh的代码

    python自动连接ssh的代码:

    #!/usr/bin/python
    #-*- coding:utf-8 -*-
    
    import sys, time, os
    
    try:
        import pexpect
    except ImportError:
        print """
            You must install pexpect module
        """
        sys.exit(1)
    
    addr_map = {
        'v3' :('root@192.168.1.162', 'sina@2009'),
        'dev':('test016@192.168.1.136', 'test016'),
        }
    
    try:
        key = sys.argv[1]
        host = addr_map[key]
    except:
        print """
            argv error, use it link
            jssh v3, v3 must defined in addr_map
        """
    sys.exit(1)
    
    server = pexpect.spawn('/usr/bin/ssh %s' % host[0])
    server.expect('.*ssword:')
    server.sendline(host[1])
    server.interact()
    
  • 用Python写一个小小的爬虫程序

    Python有一个urllib的库,可以很方便的从给定的url抓取网页,以下这段程序实现了抓取一个url并存到指定文件的功能:

    def downURL(url, filename):
        try:
            fp = urllib2.rulopen(url)
        except:
            print 'download exception'
            return 0
        while 1:
            s = fp.read()
            if not s:
                break
            op.write(s)
        
        fp.close()
        op.close()
    

    爬虫工作的基本原理就是,给定一个初始的url,下载这个url的网页,然后找出网页上所有满足下载要求的链接,然后把这些链接对应的url下载下来,然后再找下载下来的这些网页的url,我们可以用广度优先搜索实现这个算法,不过,首先得有一个函数找出网页上所有的满足要求的url,下面这个例子用正则表达式找出url。

    def getURL(url):
        try:
            fp = urllib2.urlopen(url)
        except:
            print 'get url exception'
            return []
    
        pattern = re.compile(""http://sports.sina.com.cn/[^\>]+.shtml")
        while 1:
            s = fp.read()
            if not s:
                break
            urls = pattern.findall(s)
        fp.close()
        return urls
    

    最后就是广度优先搜索了,这个实现起来也很简单:

    def spider(startURL, times):
        urls = []
        urls.append(startURL)
        i = 0
        while 1:
            if i>times:
                break;
            if len(urls)>0:
                url = urls.pop(0)
                print url, len(urls)
                downURL(url,str(i)+'.htm')
                i = i + 1
                if len(urls)<times:
                    urllist = getURL(url)
                    for url in urllist:
                        if urls.count(url) == 0:
                            urls.append(url)
            else:
                break
        return 1
    
  • 输出一个[1,2,3,...,100]的序列,不用循环、控制语句、函数等。

    
    l = range(1,101)
    print l
    

部分from 豆瓣


做一件事需要几个步骤

大约是13年的10月开始,我在公司里从事着黑盒测试的工作。当时我的任务是要对服务端的接口进行测试。为了能更好(偷懒)的完成好工作,我开发了一个简单的自动化接口测试程序personal,她可以根据我提交的测试数据、接口文档,自动发送报文进行测试并收集测试结果,然后生成报表发邮件通知我。这本来也没什么值得可说的,本来没打算有大用的小程序,随着被头头的喜爱而不断对其的功能进行扩充。于是,本来没有太经过设计规划的代码喜闻乐见的越来越冗余,连我自己都不忍落目。

于是,在一次次下决心之后,我打算对之前的小程序进行重新设计、重写。这也算是对以前工作的一个重新思考、总结,也期待经过这样一次回顾后,我能对python、自动化测试、框架有更深的理解。当然,这些都是垃圾话,问题是,怎样的一个设计才能更灵活,并且在不同项目之间,也能很快的移植、定制。

我果然又标题党了么 (●´ϖ`●) ?这些貌似跟标题没多大的关系,在说这个之前,我想先谈谈qml中关于Rectangle的若干思考。


自从大约是去年6月左右转了Qt开发之后,就掉进了qml的世界。刚接触时,第一眼觉得qml真的跟css长的很像很像,再加上曾经有用PyQt库的经验,学起来还是不是很难理解的。这半年以来,对qml的理解越来越深,觉得qml真的是很有趣的一个东西。在qml里第一个接触到的组件就是Rectangle,矩形,其实就是一个方块嘛,但是在很多可视的控件设计中都少不了它。

Rectangle

唔,好吧,其实我只是手欠,所以画了个Rectangle的示意图。

刚上手Qt的时候,是在老手的带领下,拼装拼装小组件,拼装拼装页面啥的。用“拼装”这个词来描述可是一点都不虚。我那会所做的就是简单的把组件和组件组合在一起,然后就行啦。于是,对那时的我来说,Rectangle就是一个神奇玩意了,为什么这么说呢。比如,你想自己做一个按钮,一被点击就触发一个事件。(我知道还有一个叫做button的控件,但是让我们忽略它。)那就可以画一个Rectangle上面在盖一个MouseArea,就可以了。ヾ( ´ ▽ ‘ )ノ

Button代码示例

Button

//MyButton.qml
import QtQuick 2.4

Rectangle {
    id:button
    implicitWidth: 100
    implicitHeight: 62
    color:"red"

    signal clicked //点击事件

    MouseArea {
        anchors.fill: parent

        onClicked: {
            button.forceActiveFocus()
            button.clicked()
        }
    }
}

再比如说,你打算弄个霸气大板砖形的输入框,最简单的方法就是弄个Rectangle上面放个TextInput,当然也可以通过定制style来实现,不过总觉得麻烦,不如这样简单粗暴。(=。= )

TextinputBar代码示例

TextinputBar

//MyTextinputBar.qml
import QtQuick 2.4

Rectangle {
    id:textinputbar
    implicitWidth: 100
    implicitHeight: 62
    color:"yellow"
    clip:true

    TextInput {
        anchors.fill: parent
    }
}

在每个qml文件里,组件们被串成了一棵树。在久了之后,有时候我就会想知道,为什么是一种树形结构,或者说这种结构有什么样的好处。并且,在每个qml页面里,起码要有一个根组件,也就是说,你不能创建一个全空白的qml,而这又是为何?

当我试图换个角度来重新看待Rectangle这件事时,我觉得我又对qml有了更深的理解。每个qml文件的根组件就好比是一个类,在其中的其他组件就是那些组件类的一个实例,各种继承、各种封装。Rectangle、Text等是继承Item的,ListView各种wiew是继承Flickable的,Flickable也是继承Item。Item是继承QtObject的……于是,一个qml组件的金字塔一层层的展现出来。


那么,回到我那个倒霉悲催的personal程序上,在这一次的重写计划中,我一直在思考,从qml中学习到的东西,有没有我可以加以借鉴学习的。

personal流程

当初的整个personal程序的大体流程就是如此。我的整个程序的输入是用户的测试用例(集),以及由于是要对接口和后台服务进行测试,我需要读取与服务器通讯的接口配置文档。得到之后,根据用例集以及用例顺序,有序的组装报文,以便于进行测试。当得到报文后,发送报文到被测程序开始测试。被测后台服务会根据接口给我返回报文,我收获返回报文后,对报文进行解析,判断报文格式是否正确,报文内的数据是否与用户之前预留的一致,并将结果记录下来。整个测试结束后,开始统计测试结果、计算通过率、绘制图表,然后生成测试报告,打包将其发送到测试人员邮箱。

当时的我,并没有对程序进行仔细的结构设计,于是我就按照流程,就那么面向过程的实现了整个程序还一度沾沾自喜。于是问题来了,当我有序(悠闲)的用这个程序进行着测试工作时,头头觉得我写的这个很方便,并且每天下班后,服务器自己还可以默默的开始几轮测试简直是太攒了之后。小小的personal程序的需求突然变的开始爆炸,更多的接口、不同的报文格式、验证返回报文内容加上逻辑运算、嵌套多层的测试数据等等,为了适应这些需求,程序变得越来越难改、越改越不好用,我开始头疼了…… (๑´灬`๑)

其实,如果在站的高点来看整个pensonal程序,她所做的事不过就是准备测试开始测试测试结果分析,这三大部分。在准备测试里,读取各种数据、组装报文、得到真实用例集;开始测试里,发送报文并接收返回报文、对返回报文进行验证、收集结果;测试结果分析里,统计结果、根据结果生成各种报表等、发送结果。整个流程和每层内部都看着即熟悉又陌生,有那么一点点相似。如果在站的高一点呢,其实我把每个部分都分成了3个部分,即pre、do、after。

do one thing

于是,我可以再抽象一下,定义一个类。这个类它做一件事,并将此事可以分为3个步骤,分别为准备做开始做后续处理。在此基础上,我可以定义上面三大部分里的每一个小类、以及准备测试、开始测试、测试结果分析等等。这样,就像qml的金字塔一样,一层层的搭起来我的测试程序。

(ง •̀_•́)ง 当然这只是我现在最初的构想,细节部分完全没有涉及、譬如插件系统、并发等等,但是总归要一步一步不是,这一次,我定要想好在动笔。哦,回到那个最初的问题上,做一件事需要几个步骤?对于当下的我来说,应该是3步吧~~ (//▽//)


又是年末,晚安2014

2014qqMail--by mail.qq.com

诸多开心、忧伤、烦恼、不如意一起晚安,
我的2014……晚安。

bgm: 乐活女王 -- 龙宽


修改Typecho程序解决Gravatar被墙

我素来不是辣么暴力的一个人。当Gravatar刚被墙的时候,我只是简单的在主题文件中对Gravatar地址进行了修改。这原本是一件十分简单又美好的事情,我也没有破坏te程序。但紧接着,我后面蛋疼的开始调整新皮、换主题,于是简单而美好的方法让我最终饱受其痛苦,我总是在最后才想起要修改Gravatar地址。

于是,在简洁主义的带领下,我直接对te程序进行了修改( ˘ ³˘)♥,嗯,下面把方法记录于下。


typecho(0.9)
打开 /var/Widget/Abstract/Comments.php
然后搜索$url = $host . '/avatar/'
大概在413行左右的位置,修改如下

 //$url = $host . '/avatar/';
 $url = 'https://secure.gravatar.com/avatar/';

然后保存离开就OK啦,( •́ .̫ •̀ )

这本该也是一个简单又美好的事情,但是我今天又闲的DT的升级了typecho程序,升级到了typecho1.0(141010)。当我开打comments.php文件,想要再次习惯性的修改那行代码,然后见证奇迹的时候,尼玛发现,我去,那行代码呢,去哪了~然后在熟悉的位置上,我看到了,$url = Typecho_Common::gravatarUrl($this->mail, $size, $rating, $default, $this->request->isSecure()); ,我揍、莫要欺负我读书少,尼玛你把gravatarUrl方法收集到哪里去了!!!

(●´∀`●)不过,哼,鱼唇的中原人啊,像寡人这么天资聪慧、肿么可能找不到,想到这,我用我智慧满满的CPU猜了下文件的位置,哦呵呵呵哈哈哈哈哈哈……


typecho(1.0)
打开 /var/Typecho/Common.php
然后搜索 gravatarUrl
大概在937行左右的位置,找到了gravatarUrl方法,修改如下

//$url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
$url = $isSecure ? 'https://secure.gravatar.com' : 'https://secure.gravatar.com';

然后保存离开就可以啦~(๑乛◡乛๑)

最后,原谅我,实在是懒得改了,才用这么暴力的方法解决问题~


p.s. 最近有点想看看php的书换换口味,有没有好的入门级的php书可推荐的~


逐渐消失的文字技能

现在是2014年12月5日22点46分,我无法肯定这篇日志什么时候才能真正写完并发布出去,但我仍在努力。总是这样,每时每刻都在不断的被各种事物所触动,总有想写什么的冲动,但是当真正提笔准备挥毫的时候,突然发现,刚刚那么在意的事情,也许是大惊小怪罢了。

很久以前、曾经,在那个博客大红大紫的年代,似乎每天都有说不完的新鲜事,就是想写下来。那会比较流行的新浪、雅虎、163、百度,哦还有msn,都有很多人在上面说着各式各样的故事。那时候,我先是一头扎进了百度空间,被它可以自定义模板啥的说吸引,好像还是初中吧,天天的,跟神经病一样,一放学就往电脑上渣。好吧,不是打游戏、也不是看动漫,就尼玛捣鼓css(=。=)。这要是搁现在,估计也是醉了吧。也分享了不少自己做的主题,虽然从现在的审美来说,绝对也是丑到一个境地了,哎,一世英名啊~但是,那会看到别人用了自己分享的残次品,心里总是特别开心,也算是小小的幸福感了吧。那会真的是特别喜欢写文,总是没事自己写点故事啥的,虽然不是啥结构严谨、荡气回肠的文章,好歹可以自豪的说,在我混沌无知的年纪,绝对没写过什么奇葩的玛丽苏文来。哈哈哈哈哈哈哈.....一直在百度呆了很久很久,大约2-3年吧,然后就是空间改版的时候了吧。新空间不再能够自定义模板,QAQ就这样,我小小的、小小的幸福也被夺走了,然后我就义无反顾的一头扎进了博客大巴,小清新的大巴一度是我的挚爱啊,因为能够自定义模板= =。

感觉一直在咕噜咕噜扯皮,完全没有主线剧情。其实我并不是想吐槽自己的博客心酸史,尤其是在明个还要加班的夜晚。(¬_¬)现在这么理智的我已经无法分析出来,那个能被我吐槽千千万的中二的我,确比如今的我更会写字,更会表达,究竟在什么时候,文字技能被我丢弃在路上了呢。

前几日,同事L表示他在博客园久违的开了个博客,在那个满是技术大触的地方,他说是用来转载一些有用的资料的同时,也写一些自己的感悟。(˘•灬•˘)于是乎,我将其订阅了下来。几日下来,他跟我说,那天他确实准备自己动手写一些Qt的教程、感悟的,提笔了,却突然觉得没什么好写的,也不知道从何下笔。你看,不光是我,好像还有人也一样丢掉了这个技能。

也许是,我那程序员思维吧,这也说不定,富有感情的文字,并不能更好的帮助计算机理解我想要他帮我做的事,却不如直接了当的表达出来的好。又或者是,浮躁且快节奏的社会,并没有留下太多的时间,让我细细斟酌、提笔挥毫、放空自己,做点不一样的事。还是说,我已经渐渐远离小时候那份纯真,那份觉得可以跟所有恶势力抗争的本心。或许原因永远也无法知晓,但唯一能感受到的是,我不再不愿不能也无法像以前那样肆无忌惮的写作了...

网络是一个说近就近说远就远的地方,一直以来总是不想在上面吐露太多太私人的情感,好像那样就会失去什么。可,一段时间过去,缺发现遗忘了之后,再也找不到任何痕迹再去审视当时的自己,再去回顾当时的得与失。慢慢的,很多想说的话不知道该如何谈吐,不知道如何下笔,就这样只有树洞知道,再也不知道。

这篇吐槽的缘由是,上班的时候看了很多设计从最初什么都没有很不精细、再到各种可以乱真的拟物化设计、然后再次回归到扁平化设计的文章。然后由此想到互联网的发展,从大红大紫的博客到微博、再到图片式博客、然后再到简书、Medium又试图把大家的视线再一次拉回到文字上面来,找回文字的力量,因此引出了我这长长的吐槽来。不过如果换个角度来看这两件事,突然觉得圆是一个很神秘的图形不是么,你看事物的发展都是这样从最初到极致,然后再一次回归本心,一次一次这样不断旋转不断发展。不过这就不是我现在想要吐槽的了,也许下一次、某个时候,当我再有更深的感触的时候,或许是一个不错的槽点。

现在,从现在开始,我要开始努力把一件事写的简单又复杂...


一年记。

这就是一年了罢、从建站到现在,对于像我这种做事毫无持久性的人来说,也算是值得赞赏的一件事了。

这一年发生了不少的事情,于是如果按照一般的总结写法,在一堆废话之后,该说一句总结如下,然后开始1、2、3了。不过,像我这么懒的人来说,这么写简直是太!麻!烦!了。所以,还是按照吐槽的一般标准来写吧~

我是一个很怕回头看的人,在思考一遍当时的情节与发展,总会让我再一次处在当时的心情里。

3月,时间终究是带走了我的亲人,刚知道消息的时候,大哭了一场,后面慢慢回归平静,一遍遍对自己说,这是正常的生命旅行的终点而已、仅此而已。本以为我能冷酷的说再见,而在遗体告别的最后一刻前,终究还是克制不了满溢的泪水,一遍遍、一遍遍...我不知道,在真正生命尽头的地点到底会经历什么,是否上苍真的有神明存在,今天的我只愿,在那一刻,感受不到病痛、安详而温暖的沉睡、消散在天地间、回归虚无...

6月,开始不断的加班,日子感觉一眼望不到头,留在视线中的只有烫金的加班二字。从那会开始,基本每天都是8.30-19.30下班,单休,有时候周日也不休。当然,在boss极度的压榨工作之下,虽然是刚转去Qt开发的我,是进步大大滴。虽然直到现在我仍认为,这种进步对我下份工作的帮助甚微。通俗点说就是,我使用了大量的技能点,却点亮了各种各样的技能,但是每样技能都没点到满,=。=这听起来就有这种淡淡的惆怅。

10月,终于不断的加班加到的高潮,好不容易上一个项目眼看就到到底了,可以轻松几个日子了。我们又被叫回来做另外的活了,于是开始了噩梦一般的封闭开发。哎、一周七天,天天9点多上班到晚上11点多。还不让出去,天天就让对着个电脑干活啊啥的,日子简直都没法过下去了的感觉。当时,想要跳槽的心都有了,如果用%来表示的话,就是99.98%,不过在懒惰大神的指引下,还是忍住了。

今天,我仍然坐在公司里我的位置上,打着代码发着呆、嚼着口香糖加着永远加不完的班、反思着我为啥还不走这一事实。哎,我咋那么懒...

转眼,又见年根。


容我冬个眠

好多月没吐槽了。
实在是因为……懒。
最近想对主题动一下刀。
不过,容我先翻个身,再睡一觉~


我们都要好好的

深秋了,长日蜷缩在工位的我感觉不到任何季节的变换。一天天的就是起床、早饭、上班、午饭、上班、晚饭、上班、睡觉。我彷徨过,无奈过,却也无法改变什么。来之前,同事间笑谈说,就跟监狱一样。现在看来,还是有不同的,起码我们可以网购<( ̄ ﹌  ̄)>
大家都在干活,就我在忙里偷闲,用sublime吐槽,哈哈~没办法,感觉今年从7月份开始就一直在加班,一直在过没双休的日子,最好也就是单休了。于是现在我虽然看着文档,但是什么文字都没看进去,满脑子就俩烫金大字“酱油”。真是不喜欢这样的状态,工作是生活的一部分,但于我,绝不能成为生活。
同事A最近在纠结着打算辞职,各种纠结,各种不爽快,他谈了个妹纸,是异地恋,前几周,妹纸家里出事了,却正逢我们开始封闭开发,他无法去在妹纸最难过的日子陪妹纸,因此而不开心,况且这俩月工作强度那么大,他们十一中秋一共就放了1天半,而工资也不多,就想跑路了。
我也在反思,为啥我要留在这,这里有什么吸引我。可能,也是要走的时候了。可以遇见的未来,马上的11/12月也是逃不过天天加班的命运。真是,真是,不喜欢这样的节奏。本来从年初就在打算,要在暖和的日子里,去外面走走看看。现在,这些也不想了,我就想在太阳满照的日子里,好好的睡一觉。
这里,突然又想起了另外一个妹纸,同事B。她貌似一直肠胃不好吧,之前加班加到病了,先是在偏蔽的卫生所,说她急性肠胃炎。然后晚上开始发了烧,最后终于大晚上跑老远去了医院,最后说是阑尾炎,可能要做手术了吧,哎。
好吧,我去工作去了,终有一日,我要在阳光里,听着最爱的NewAge音乐,旅行上路。


关于 ubuntu 14.04 SunPinYin 没法输入 ue 的拼音的解决办法~

之前一直发现sunpinyin无法输入ue的拼音,像月啊、学啊,都只能输入首字母才能打出来。忍了小半年后,今天终于忍无可忍了,于是,解决了~撒花~终于小二货可以愉快的输入好好学习了~
据说,造成这样的原因是因为ubuntu打包的时候打包错了还是啥的,反正解决了~
解决方案如下:
1.下载最新的sunpinyin库 sunpinyin-data_0.1.22+20131212-1_amd64.deb[戳我下载]然后安装~
2.重启sunpinyin
$sudo ibus restart
就是这样简单,so easy~~


哎。加班!

从昨天起开始了又一轮漫长的加班ing...
每天基本12小时的班,
no weekend,
好累&好想睡啊...
哎,不敢多说了,下次继续,我这上班偷偷偷懒呢^3^
今天是2014.10.11.


又见周末,所有人都放假了,除了我们几个(。T^T)。
连续好几天的帝都的雾霾终于散去了,
在会议室看着远处的山脉,内心不是一般的悲哀,
雾霾退散~
好想出去玩儿啊~
今天是2014.10.12.