Python核心编程-第七章课后题
2016-06-03 00:00
162 查看
摘要: Python核心编程关于字典的课后题
就算创建出来这个字典再显示的时候就已经不是字母顺序了,哎~,顺序表现出来还是得用sorted()函数
b).同a)
c).
这是大神写的,就看看吧~为了赶进度,就……
真心不会写
raw_input()和input()其实有很大差别,前者你搞出来出来的都是字符格式str,而后者你输入什么,它就是什么,输入字典给的就是字典,输入数字出来数字!就是这么神奇!!
第二个,感觉像是上面写过的题目,为了更方便,我把两种排列都写在了一个函数里面,用户可以选择排列方式
7-9. 翻译 (a) 编写一个字符翻译程序(功能类似于 Unix 中的 tr 命令)。我们将这个函数叫做 tr(),它有 三个字符串做参数: 源字符串、目的字符串、基本字符串,语法定义如下:
b) 在这个函数里增加一个标志符参数,来处理不区分大小写的翻译问题。
答:
a).说的这么高大尚,其实不就是用dststr替换在string中的srcstr吗?这个函数好像在之前的字符串那一节写过,之前是用list化,现在改用string拼接试试。可是这个跟字典有什么联系呢?
b).其实这个也有歧义的,区分大小写是检索的时候区分不区分还是,替换的时候区分不区分,费劲~,我按照的是前者写的
c).这个……,我a题中做的就是这种智能的,因为
for i in range(string_lenth):
if srcstr == string[i:i+srcstr_lenth]:
new_string = string[0:i] + dststr + string[i+srcstr_lenth:]
这里拼接的时候用的就是srcstr的长度,直接截掉了srcstr这个字符串
答:我觉得上一题跟这个题的关系不大,因为上一题就没用到ASCII编码的值,难度不大
a).
b).首先小小吐槽一下,我想着用个switch开关来控制编码的加减号,从而控制解码编码问题,然后想到了eval()函数,然后带入由于自身掌握不周,没搞定。后来我想,还是用最傻的方法吧~于是乎又写了个rot13_reverse()函数,仅仅把“+”,“-”互换,后来测试好了,然后我发现!!
惊天秘密有木有!!!
一个字符串用rot13处理以后,表示被编码,然后在用这个得到的在处理一下,就返回当初的字符串了!!也就是说,解码只用把字符串再进行一次编码就可以了!!
擦!怪不得这个加密方式以后不用了,原来太特么坑了
基本还是a题的代码,只是加了个e,d的选择,然而选择这个没用,反正底层代码没人看到
a).集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体
b).python中没有详细说明什么是集合,只是说从数学上类比一下,集合对象是一组无序排列的哈希值。
少有的几个不用调试直接能用的代码,有点自我膨胀了。
附加题:我觉得题目有问题,创建某个集合的潜在子集,难道这个不肯定就是子集吗?为什么还要让用户判断?用户判断了几回发现被骗了(全部都回答‘是’),写这个题的目的又是什么呢?
如果要我写的话肯定是很长一排的if,然后觉得应该有更好的方法,看了大神的,用到了eval()函数,觉得挺不错的
7–1. 字典方法。哪个字典方法可以用来把两个字典合并到一起?
答:应该是dict.update(dict2).可以完成把dict2的键值对添加到dict里面去[code=language-python]>>> dict1 = {'a':1,'b':2} >>> dict2 = {'c' : 3} >>> dict1.update(dict2) >>> dict1 {'a': 1, 'c': 3, 'b': 2}
7–2. 字典的键。我们知道字典的值可以是任意的 Python 对象,那字典的键又如何呢?请试 着将除数字和字符串以外的其他不同类型的对象作为字典的键,看一看,哪些类型可以,哪些不行? 对那些不能作字典的键的对象类型,你认为是什么原因呢?
答:键必须是可哈希的,因为这样才能通过键来带入哈希函数求得对应的值的内存。如果键变成可变对象,则硬带入哈希函数可能会找不到原来值的内存而造成混乱[code=language-python]>>> dict3 = {} >>> dict3['abc'] = 123 >>> dict3[123] = 'abc' >>> dict3[['a','b']] = 12 Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list' >>> dict3[(1,2)] = 'ab' >>> dict3[([1,2],3)] = 'aba' Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list'
可以看到,数值,字符串,元组可以作为键对象,但是元组必须是一级的,不能包含列表
7–3. 字典和列表的方法。 (a) 创建一个字典,并把这个字典中的键按照字母顺序显示出来。
(b) 现在根据已按照字母顺序排序好的键,显示出这个字典中的键和值。
(c)同(b),但这次是根据已按照字母顺序排序好的字典的值,显示出这个字典中的键和值。(注 意:对字典和哈希表来说,这样做一般没有什么实际意义,因为大多数访问和排序(如果需要)都是 基于字典的键,这里只把它作为一个练习。)
答:a).[code=language-python]>>> dict1 = {'a':1,'b':2,'c':3,'d':4} >>> dict1 {'a': 1, 'c': 3, 'b': 2, 'd': 4} >>> for i in sorted(dict1): ... print i,':',dict1[i] ... a : 1 b : 2 c : 3 d : 4
就算创建出来这个字典再显示的时候就已经不是字母顺序了,哎~,顺序表现出来还是得用sorted()函数
b).同a)
c).
[code=language-python]>>> dict2 = {'animal':'cat','fruit':'apple','plant':'tree'} >>> for i in sorted(dict2.values()): ... for key in dict2: ... if dict2[key] == i: ... print "key:", key," and value:", i ... key: fruit and value: apple key: animal and value: cat key: plant and value: tree
7-4. 建立字典。给定两个长度相同的列表,比如说,列表[1, 2, 3,...]和['abc', 'def', 'ghi',...],用这两个列表里的所有数据组成一个字典, 像这样: {1:'abc', 2: 'def', 3: 'ghi',...}
答:题目的本意就是一对一,然后就想到了zip函数,如下:[code=language-python]>>> list1 = ['abc','def','ghi','jkl'] >>> list2 = [1,2,3,4] >>> dict(zip(list2,list1)) {1: 'abc', 2: 'def', 3: 'ghi', 4: 'jkl'}
7–5. userpw2.py. 下面的问题和例题 7.1 中管理名字-密码的键值对数据的程序有关。
(a)修改那个脚本,使它能记录用户上次的登录日期和时间(用 time 模块),并与用户密码一起 保存起来。程序的界面有要求用户输入用户名和密码的提示。无论户名是否成功登录,都应有提示, 在户名成功登录后,应更新相应用户的上次登录时间戳。 如果本次登录与上次登录在时间上相差不 超过 4 个小时,则通知该用户: “You already logged in at: .”
(b) 添加一个“管理”菜单,其中有以下两项:(1)删除一个用户 (2)显示系统中所有用户的名 字和他们的密码的清单。
(c) 口令目前没有加密。请添加一段对口令加密的代码(请参考 crypt, rotor, 或其它加密模块)
(d) 为程序添加图形界面,例如,用 Tkinter 写。
(e) 要求用户名不区分大小写。
(f) 加强对用户名的限制,不允许符号和空白符。
(g)合并“新用户”和“老用户”两个选项。 如果一个新用户试图用一个不存在的用户名登录, 询问该用户是否是新用户,如果回答是肯定的,就创建该帐户。否则,按照老用户的方式登录。
答:看到这么多小问,头大了~~~~~~,得了看了大神的博客这道题,蒙圈了,怎么类都用上了,还是有图形界面不得导入一个库吗?另外之前在运行例子的时候,发现用户名和密码必须写入一个文件,否则关闭以后就什么都没有了,更不用提不超过4小时限制了。这道题真的有难度,吃不下[code=plain]import time import wx import string class UserPw(object): """登录系统的类,包含用户登录,超级用户删除用户,显示所有用户 (需要超级用户帐号和密码)""" def __init__(self): """数据的初始化,用户信息保存格式为 用户名:【密码,登录时间(time(),用于计算),登录时间(ctime(),用于显示)】""" self.db = {} self._superName = "fzyz.abc" self._superpasswd = "fzyz" def userLogin(self, name, passwd): """用户的登录,支持新用户和老用户的一起登录,不区分大小写的用户名.新用户自动注册""" try: if self.db[name.lower()][0] == passwd: if time.time() - self.db[name.lower()][1] < 14400: #登录时间小于4小时 contents.SetValue("you already logged in at:" + str(self.db[name.lower()][2])) else: contents.SetValue("welcome back!") except IndexError: for i in name.lower(): if i in string.punctuation + string.whitespace: contents.SetValue("用户名不允许符号和空白符,请重新输入") return False self.db[name.lower()] = [passwd, time.time(), time.ctime()] return True def delUser(self, name): """通过超级用户进行用户的删除""" if userName == self._superName and userPw == self._superpasswd: del self.db[name.lower()] else: contents.SetValue("超级用户账户或密码输入有误") return def showAllUser(self): """通过超级用户,显示所有的用户""" if userName == self._superName and userPw == self._superpasswd: for key in self.db.keys(): contents.AppendText("用户名:%s", key) else: contents.SetValue("超级用户账户或密码输入有误") def load(event): oneUser = UserPw() oneUser.userLogin(str(userName), str(userPw)) def delUser(event): oneUser = UserPw() oneUser.delUser(str(name)) def showAllUser(event): oneUser = UserPw() oneUser.showAllUser() if __name__ == "__main__": app = wx.App() win = wx.Frame(None, title = "登录系统", size = (410, 335)) userName = wx.TextCtrl(win, pos = (5,5), size = (240, 25)) userPw = wx.TextCtrl(win, pos = (5, 30), size = (240, 25)) contents = wx.TextCtrl(win, pos = (5, 90), size = (390, 260), style = wx.TE_MULTILINE | wx.HSCROLL) loadButton = wx.Button(win, label = "登录", pos = (250, 5), size = (80, 25)) loadButton.Bind(wx.EVT_BUTTON, load) delUserButton = wx.Button(win, label = "删除用户", pos = (5, 60), size = (90, 25)) delUserButton.Bind(wx.EVT_BUTTON, delUser) showAllUserButton = wx.Button(win, label = "显示所有用户", pos = (100, 60), size = (90, 25)) showAllUserButton.Bind(wx.EVT_BUTTON, showAllUser) win.Show() app.MainLoop()
这是大神写的,就看看吧~为了赶进度,就……
7-6. 列表和字典。创建一个简单的股票证券投资数据系统。其中应至少包含四项数据:股市 行情显示器符号, 所持有的股票, 购买价格及当前价位 - 你可以随意添加其他数据项, 比如收益率, 52 周最高指数、最低指数,等等。 用户每次输入各列的数据构成一个输出行。每行数据构成一个列表。 还有一个总列表,包括了 所有行的数据。数据输入完毕后,提示用户选择一列数据项进行排序。把该数据项抽取出来作为字 典的键,字典的值就是该键对应行的值的列表。提醒读者:被选择用来排序的数据项必须是非重复 的键,否则就会丢失数据,因为字典不允许一个键有多个值。 你还可以选择其他计算输出,比如,盈亏比率,目前证券资产价值等。
答:WTF 题?这就好比教会你了1+1,然后出了个练习,Are you kidding me?真心不会写
7-7. 颠倒字典中的键和值。用一个字典做输入,输出另一个字典,用前者的键做值,前者的 值做键。
答:这个其实很简单,但是在输入的时候出现了一些问题。很有收获!!raw_input()和input()其实有很大差别,前者你搞出来出来的都是字符格式str,而后者你输入什么,它就是什么,输入字典给的就是字典,输入数字出来数字!就是这么神奇!!
[code=language-python]def swp_dict(dct): dct_final = {} for key in dct: dct_final[dct[key]] = key return dct_final if __name__ == '__main__': while True: dict1 = input("Please input a dict(-1 to quit):") if dict1 == -1: break else: print swp_dict(dict1)
7-8. 人力资源。创建一个简单的雇员姓名和编号的程序。让用户输入一组雇员姓名和编号。 你的程序可以提供按照姓名排序输出的功能,雇员姓名显示在前面,后面是对应的雇员编号。附加 题:添加一项功能,按照雇员编号的顺序输出数据。
答:这个不难,就是觉得没必要在写个 函数,只是在写的过程中发现匿名函数还有[(key,dict1[key]) for key in sorted(dict1)]这样的用法~[code=language-python]if __name__ == '__main__': dict1 = {} while True: list1 = [] name_num = raw_input("Please input a dict key-value pair,like'a:1'('E' to end enroll):") if name_num.lower() == 'e': break else: list1 = name_num.split(':') dict1[list1[0]] = list1[1] for key in sorted(dict1): print key,dict1[key]
第二个,感觉像是上面写过的题目,为了更方便,我把两种排列都写在了一个函数里面,用户可以选择排列方式
[code=language-python]if __name__ == '__main__': dict1 = {} while True: list1 = [] name_num = raw_input("Please input a dict key-value pair,like'a:1'('E' to end enroll):") if name_num.lower() == 'e': word = raw_input("Array it by name(for '1') or number(for '2')?:") break else: list1 = name_num.split(':') dict1[list1[0]] = list1[1] if word == '1': for key in sorted(dict1): print key,dict1[key] elif word == '2': for i in sorted(dict1.values()): for key in dict1: if dict1[key] == i: print i,key else: print "Wrong~~"
7-9. 翻译 (a) 编写一个字符翻译程序(功能类似于 Unix 中的 tr 命令)。我们将这个函数叫做 tr(),它有 三个字符串做参数: 源字符串、目的字符串、基本字符串,语法定义如下:
def tr(srcstr, dststr, string) srcstr 的内容是你打算“翻译”的字符集合,dsrstr 是翻译后得到的字符集合,而 string 是 你打算进行翻译操作的字符串。举例来说,如果 srcstr == 'abc', dststr == 'mno', string == 'abcdef', 那么 tr()的输出将是'mnodef'. 注意这里 len(srcstr) == len(dststr). 在这个练习里,你可以使用内建函数 chr() 和 ord(), 但它们并不一定是解决这个问题所必不 可少的函数。
b) 在这个函数里增加一个标志符参数,来处理不区分大小写的翻译问题。
c)修改你的程序, 使它能够处理删除字符的操作。字符串 srcstr 中不能够映射到字符串 dststr 中字符的多余字符都将被过滤掉。换句话说,这些字符没有映射到 dststr 字符串中的任何字符,因 此就从函数返回的字符里被过滤掉了。举例来说:如果 srcstr == 'abcdef', dststr == 'mno', string == 'abcdefghi', 那么 tr()将输出'mnoghi'. 注意这里 len(srcstr) >= len(dststr).
答:a).说的这么高大尚,其实不就是用dststr替换在string中的srcstr吗?这个函数好像在之前的字符串那一节写过,之前是用list化,现在改用string拼接试试。可是这个跟字典有什么联系呢?
[code=language-python]def tr(srcstr,dststr,string): string_lenth = len(string) srcstr_lenth = len(srcstr) for i in range(string_lenth): if srcstr == string[i:i+srcstr_lenth]: new_string = string[0:i] + dststr + string[i+srcstr_lenth:] return new_string if __name__ == '__main__': while True: srcstr = raw_input("Enter a source word(-1 to quit):") dststr = raw_input("Enter a desination word:") string = raw_input("Enter a full string:") if srcstr == '-1': break else: print tr(srcstr,dststr,string)
b).其实这个也有歧义的,区分大小写是检索的时候区分不区分还是,替换的时候区分不区分,费劲~,我按照的是前者写的
[code=language-python]def tr(srcstr,dststr,string): string_lenth = len(string) srcstr_lenth = len(srcstr) for i in range(string_lenth): if srcstr == string[i:i+srcstr_lenth]: new_string = string[0:i] + dststr + string[i+srcstr_lenth:] return new_string def tr_non_case(srcstr,dststr,string): #新增 string_lenth = len(string) srcstr_lenth = len(srcstr) for i in range(string_lenth): if srcstr.lower() == string[i:i+srcstr_lenth].lower(): new_string = string[0:i] + dststr + string[i+srcstr_lenth:] return new_string if __name__ == '__main__': while True: srcstr = raw_input("Enter a source word(-1 to quit):") dststr = raw_input("Enter a desination word:") string = raw_input("Enter a full string:") switch = raw_input("Case censitive?('Y' or 'N'):")#新增 if srcstr == '-1': break elif switch.lower() == 'y': print tr(srcstr,dststr,string) elif switch.lower() == 'n': print tr_non_case(srcstr,dststr,string) else: print 'Not kidding!'
c).这个……,我a题中做的就是这种智能的,因为
for i in range(string_lenth):
if srcstr == string[i:i+srcstr_lenth]:
new_string = string[0:i] + dststr + string[i+srcstr_lenth:]
这里拼接的时候用的就是srcstr的长度,直接截掉了srcstr这个字符串
7–10. 加密。 (a) 用上一个练习的思路编写一个"rot13"翻译器。 "rot13"是一个古老而又简单的加密方法, 它把字母表中的每个字母用其后的第 13 个字母来代替。字母表中前半部分字母将被映射到后半部分, 而后半部分字母将被映射到前半部分,大小写保持不变。举例来说,'a'将被替换为'n','X'将被替 换为'K'; 数字和符号不进行翻译。
(b)在你的解决方案的基础上加一个应用程序,让它提示用户输入准备加密的字符串(这个算法 同时也可以对加密后的字符串进行解密),如下所示:
[code=language-python]% rot13.py Enter string to rot13: This is a short sentence. Your string to en/decrypt was: [This is a short sentence.]. The rot13 string is: [Guvf vf n fubeg fragrapr.]. % % rot13.py Enter string to rot13: Guvf vf n fubeg fragrapr. Your string to en/decrypt was: [Guvf vf n fubeg fragrapr.]. The rot13 string is: [This is a short sentence.].
答:我觉得上一题跟这个题的关系不大,因为上一题就没用到ASCII编码的值,难度不大
a).
[code=language-python]def rot13(string): string_lenth = len(string) list1 = list(string) list_empty = [] for i in range(string_lenth): if 97 <= ord(list1[i]) <= 109 or 65 <= ord(list1[i]) <= 77: list_empty.append(chr(ord(list1[i])+13)) elif 110 <= ord(list1[i]) <= 122 or 78 <= ord(list1[i]) <= 90: list_empty.append(chr(ord(list1[i])-13)) else: list_empty.append(list1[i]) return ''.join(list_empty) if __name__ == '__main__': while True: string_ori = raw_input("Enter a string to en rot13(q to quit):") if string_ori == 'q': break else: print rot13(string_ori)
b).首先小小吐槽一下,我想着用个switch开关来控制编码的加减号,从而控制解码编码问题,然后想到了eval()函数,然后带入由于自身掌握不周,没搞定。后来我想,还是用最傻的方法吧~于是乎又写了个rot13_reverse()函数,仅仅把“+”,“-”互换,后来测试好了,然后我发现!!
惊天秘密有木有!!!
一个字符串用rot13处理以后,表示被编码,然后在用这个得到的在处理一下,就返回当初的字符串了!!也就是说,解码只用把字符串再进行一次编码就可以了!!
擦!怪不得这个加密方式以后不用了,原来太特么坑了
[code=language-python]def rot13(string): string_lenth = len(string) list1 = list(string) list_empty = [] for i in range(string_lenth): if 97 <= ord(list1[i]) <= 109 or 65 <= ord(list1[i]) <= 77: list_empty.append(chr(ord(list1[i])+13)) elif 110 <= ord(list1[i]) <= 122 or 78 <= ord(list1[i]) <= 90: list_empty.append(chr(ord(list1[i])-13)) else: list_empty.append(list1[i]) return ''.join(list_empty) if __name__ == '__main__': while True: string_ori = raw_input("Enter a string to en rot13(q to quit):") if string_ori == 'q': break else: print 'Your string to en/decrypt was:[%s].' % string_ori switch = raw_input('En/decrypt?(E/D):') if switch.lower() == 'e' or switch.lower() == 'd': print rot13(string_ori) else: print 'Wrong choose!'
基本还是a题的代码,只是加了个e,d的选择,然而选择这个没用,反正底层代码没人看到
7–11. 定义。什么组成字典中合法的键? 举例说明字典中合法的键和非法的键。
答:怎么又是这个题,不是在7-2中说了么?详情已经在2题中说过了,可以去参考一下7-12. 定义。 (a)在数学上,什么是集合? (b)在 Python 中,关于集合类型的定义是什么?
答:a).集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体
b).python中没有详细说明什么是集合,只是说从数学上类比一下,集合对象是一组无序排列的哈希值。
7–13. 随机数。修改练习 5-17 的代码:使用 random 模块中的 randint()或 randrange()方 法生成一个随机数集合: 从 0 到 9(包括 9)中随机选择,生成 1 到 10 个随机数。这些数字组成集合 A(A 可以是可变集合,也可以不是)。同理,按此方法生成集合 B。每次新生成集合 A 和 B 后,显示 结果 A | B 和 A & B。
答:还好再5-17的时候把这个题做了。没啥难度。[code=language-python]from random import * def gen_num(s): for i in range(10): s.add(str(randint(0,9))) return s if __name__ == '__main__': A = set() B = set() gen_num(A) gen_num(B) print 'A is %s.' % A print 'B is %s.' % B print 'The union of the two is %s.' % (A|B) print 'The intersection of the two is %s.' % (A&B)
少有的几个不用调试直接能用的代码,有点自我膨胀了。
7–14. 用户验证。修改前面的练习,要求用户输入 A | B 和 A & B 的结果,并告诉用户他(或 她)的答案是否正确,而不是将 A | B 和 A & B 的结果直接显示出来。如果用户回答错误,允许他(或 她)修改解决方案,然后重新验证用户输入的答案。如果用户三次提交的答案均不正确,程序将显示 正确结果。 附加题:运用你关于集合的知识, 创建某个集合的潜在子集,并询问用户此潜在子集是否真是 该集合的子集,要求和主程序一样有显示更正和答案的功能。
答:只写了union的方法,intersect的方案直接更换一下符号就可以了[code=language-python]from random import * def gen_num(s): for i in range(10): s.add(str(randint(0,9))) return s if __name__ == '__main__': A = set() B = set() gen_num(A) gen_num(B) print 'A is %s.' % A print 'B is %s.' % B union_AB = (A|B) intersection_AB = (A&B) i = 0 while i < 3: user_input = raw_input("Try to enter the union of the two\ (',' to divide):") user_union = set(user_input.split(',')) if union_AB == user_union: print 'You are so great!' break else: if i <= 1: print 'Try again!' i+=1 else: print 'You lose!' print 'The answer is %s.' % union_AB i += 1
附加题:我觉得题目有问题,创建某个集合的潜在子集,难道这个不肯定就是子集吗?为什么还要让用户判断?用户判断了几回发现被骗了(全部都回答‘是’),写这个题的目的又是什么呢?
7–15. 编写计算器。 这个练习取材于 http://math.hws.edu/ 在线免费 Java 教材中的练习 12.2。编写一个程序允许用户选择两个集合:A 和 B, 及运算操作符。例如,in, not in, &, |, ^, <, <=, >, >=, ==, !=, 等. (你自己定义集合的输入语法,它们并不一定要像 Java 示例中那样用方括 号括住。)解析输入的字符串,按照用户选择的运算进行操作。你写的程序代码应该比 Java 版本的 该程序更简洁。
答:我不会Java,应该比Java版本更简洁是个什么意思?我都看不懂的如果要我写的话肯定是很长一排的if,然后觉得应该有更好的方法,看了大神的,用到了eval()函数,觉得挺不错的
[code=language-python]def cal(set_A,set_B,op): return eval(str(set_A)+str(op)+str(set_B)) if __name__ == '__main__': A = raw_input('Enter the first set,like:1,2,3(q to quit):') B = raw_input('Enter the second set,like:1,2,3:') option = raw_input('Enter option you want:') #print type(A),B A = set(A.split(',')) B = set(B.split(',')) #print type(A),B #print type(option) print '%s,%s,%s is %s.' % (A,option,B,cal(A,B,option))
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法