Python编程实战 妙趣横生的项目之旅

978-7-115-56288-3
作者: [美]李·沃恩(Lee Vaughan)
译者: 翁健韩露露刘琦邢帅珂
编辑: 胡俊英
分类: Python

图书目录:

详情

《Python编程实战:妙趣横生的项目之旅》基于Python语言,通过项目展示Python的奇妙应用,适合Python初学者学习。在本书中,你将使用Python编程语言模拟探索火星、木星以及银河系最遥远的地方,体验诗人的意境,了解高级的金融知识等。你还会学到各种各样的技术,如马尔可夫链分析技术、蒙特卡罗模拟、图像叠加技术、基因遗传算法等。与此同时,你还会学习一些模块的使用方法,例如pygame、Pylint、pydocstyle、Tkinter、python-docx、Matplotlib和pillow等。 《Python编程实战:妙趣横生的项目之旅》基于一些有趣的项目进行讲解,能够让读者在新奇的项目案例中体验学习Python的乐趣。此外,读者还能将自己所学的知识与实际的应用程序开发、数据库设计和解决实际问题联系起来,提升自己的项目实践能力。

图书摘要

版权信息

书名:Python编程实战

ISBN:978-7-115-56288-3

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    [美] 李•沃恩(Lee Vaughan)

译    翁 健  韩露露  刘 琦  邢帅珂

责任编辑 胡俊英

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e56288”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。


Copyright © 2019 by Lee Vaughan. Title of English-language original: Impractical Python Projects, ISBN 9781593278908, published by No Starch Press. Simplified Chinese-language edition copyright © 2021 by Posts & Telecom Press. All rights reserved.

本书简体中文版由美国No Starch出版社授权人民邮电出版社出版。未经出版者书面许可,对本书任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


本书基于Python语言,通过项目展示Python的奇妙应用,适合Python初学者学习。在本书中,你将使用Python编程语言模拟探索火星、木星以及银河系最遥远的地方,体验诗人的意境,了解高级的金融知识等。你还会学到各种各样的技术,如马尔可夫链分析技术、蒙特卡罗模拟、图像叠加技术、基因遗传算法等。与此同时,你还会学习一些模块的使用方法,例如pygame、Pylint、pydocstyle、Tkinter、python-docx、Matplotlib和pillow等。

本书基于一些有趣的项目进行讲解,能够让读者在新奇的项目案例中体验学习Python的乐趣。此外,读者还能将自己所学的知识与实际的应用程序开发、数据库设计和解决实际问题联系起来,提升自己的项目实践能力。


李•沃恩(Lee Vaughan)是一位程序员和教育工作者。作为埃克森美孚公司的主管级科学家,他负责构建并审查计算机模型,开发和测试软件,并培训地球科学家和工程师。他还通过自己编写的图书,帮助很多读者磨炼Python编程技能,并从中获得乐趣。


杰里米•昆(Jeremy Kun)毕业于美国芝加哥的伊利诺伊大学,获得数学博士学位,目前在谷歌公司从事数据中心优化工作。


翁健,国家杰出青年科学基金获得者,暨南大学教授、博士生导师、副校长。主要研究方向为密码学与信息安全,在CRYPTO、EUROCRYPT、ASIACRYPT、PKC、Usenix Security、ACM CCS等顶级会议和期刊发表了上百篇论文,主持了国家重点研发计划、国家自然科学基金重点项目、广东省基础与应用基础重大项目等项目。担任国务院学位委员会网络空间安全学科评议组成员、国家自然科学基金委信息学部会评专家、教育部网络空间安全教学指导委员会委员等。曾获中国密码学会首届密码创新奖、2017年度全国网络安全优秀教师等奖励。

韩露露,暨南大学网络空间安全专业在读博士,研究方向为密码学与信息安全。曾在中国电子科技集团第30研究所工作,主要做密码算法的实现和优化,著有《深入浅出CryptoPP密码学库》一书。

刘琦,西安电子科技大学电子信息专业在读硕士,研究方向为图像和视频处理、深度学习和人工智能。

邢帅珂,毕业于福建师范大学数学与信息学院,应用统计专业硕士,研究方向为数据挖掘。


欢迎你翻开并阅读本书。在本书中,你将使用Python编程语言模拟探索火星、木星以及银河系最遥远的地方,体验诗人的意境,了解高级的金融知识,深挖游戏节目的诡计等。你还会学到各种各样的技术,如用马尔可夫链分析技术写俳句,用蒙特卡罗仿真模拟金融市场变化,用图像叠加技术来完善天体摄影图片,用基因遗传算法模拟培育一群大鼠等。与此同时,你还会积累一些模块的使用经验,例如pygame、Pylint、pydocstyle、Tkinter、python-docx、Matplotlib和pillow。最重要的是,在阅读本书的过程中,你会学得很开心。

你可以把本书当作学习Python的辅助类图书。本书是一本完全面向初学者的入门图书。在本书中,你将使用基于项目的方法进行自我训练。本书不会浪费你的金钱和书架空间,也不是对你已学过的知识概念的重新整理。不过,请别担心!本书不会让你独自去完成这些项目,书中所有的代码均有注释和解释。

本书的这些项目适用于希望通过编程进行实验仿真、理论验证、自然现象模拟和获取快乐的人。其中包括那些将编程作为工作的一部分但并不是程序员的人(如科学家和工程师),还包括那些“非专业人士”——编程的业余爱好者和把编程当作娱乐消遣的人。如果你想弄明白本书提到的项目,但又发现自己从头开始做这些复杂的项目会非常艰巨或耗费大量时间,那么本书就很适合你。

当浏览本书的项目时,你会了解一些非常有价值的Python库和模块,也会学到一些快捷键的使用方法、常用的内置函数以及一些重要的技术,还能从实践中学到程序设计、测试以及优化的方法。此外,你还会将正在做的事情与实际的应用程序开发、数据库设计和解决实际问题联系起来。

拉夫尔·沃尔多·艾默生说过:“没有热情就无法建立伟业。”学习的过程也是如此。本书的最终目的是激发你的想象力,并引导你开发自己感兴趣的项目。若一开始你觉得开发自己的项目过于雄心勃勃,那也不用担心。你只需要勤奋一点,经常上网搜索资料并学习,就能创造奇迹,这比你想象中更快。

下面是本书各章内容的简要描述。一般来说,你不必按照顺序阅读它们,但越是在前面的项目,往往会越简单,当新的概念、模块和技术首次出现时,本书会详细地解释它们。

第1章 虚假姓名生成器:这是一个热身项目。本章先介绍Python的PEP 8标准、PEP 257标准、Pylint模块和pydocstyle模块。这些标准和模块会帮助你分析代码是否符合编程规范。本章最后会给出一个奇怪姓名生成器程序,它的设计灵感来源于美国网络电视节目《灵异妙探》。

第2章 寻找回文:本章教你对代码进行性能分析。与此同时,你还会学到拯救挣扎在痛苦边缘的DC漫画中的女巫萨塔娜的方法。通过在线字典来寻找神奇的回文串,你可以帮助萨塔娜打败时间反转恶鬼。

第3章 寻找易位词:编写一个帮助用户创建他们输入名字的易位词的程序。例如,用“Clint Eastwood”生成“old west action”;然后,利用语言筛查器帮助汤姆· 马沃洛· 里德尔(Tom Marvolo Riddle)找到他名字的易位词——“I am Lord Voldemort”。

第4章 破解美国内战密码:首先,研究并破解历史上经典的军事密码——联邦路由密码;然后,让双方的间谍使用锯齿形栅栏密码发送和译码秘密信息。

第5章 编写英国内战密码:通过破解来自英国内战时期的空密码,获取明文隐含的深层次信息;之后,设计和实现更复杂的空密码以完成拯救苏格兰女王玛丽的任务。

第6章 隐写术:利用隐形电子墨水帮助企业间谍欺骗夏洛克·福尔摩斯的父亲,从而让间谍逃过侦察。本章的内容改编自美国哥伦比亚广播公司的电视剧《基本演绎法》。

第7章 用遗传算法培育大鼠:受达尔文进化论的启发,本章利用遗传算法模拟培育一种体型如雌性牛头獒一样的超级大鼠;然后,帮助詹姆斯·邦德在一眨眼的时间里破解密码有100亿种组合的保险柜。

第8章 统计俳句音节数:本章教你使用计算机统计英语单词的音节数,是下一章写作日本诗歌或俳句的先导部分。

第9章 用马尔可夫链分析技术编写俳句:本章将第8章的音节计数模块与马尔可夫链算法进行组合,通过分析含有数百个古今俳句的语料库,实现让计算机编写俳句的目标。

第10章 我们孤独吗——探索费米悖论:利用德雷克方程、银河系的大小以及假设的可探测“辐射气泡”大小,研究外星无线电信号缺失的原因;学习和使用流行的Tkinter模块,构建星系和地球自身的无线电气泡图。

第11章 蒙蒂·霍尔问题:首先论证蒙蒂·霍尔问题,然后使用面向对象编程语言构建一个有趣的、带有图形界面接口的蒙蒂霍尔游戏。

第12章 储蓄安全:使用蒙特卡罗金融模型为你自己(或你的父母)安排安稳的退休生活。

第13章 模拟外星火山:利用pygame模块模拟木星卫星艾奥上的火山爆发场景。

第14章 用探测器绘制火星地图:本章的目标是构建一款基于重力的街机游戏。当卫星燃料没有耗尽,也没有在大气层中燃烧时,让卫星的运行轨道变成一个圆形的测绘轨道。通过显示卫星的关键参数,跟踪其运行轨迹,为火星添加阴影图示,并让火星缓慢绕其轴旋转,以此来学习轨道力学知识。

第15章 用行星叠加技术完善天体摄影图片:利用Python的图像库,对从视频中获取的低质量图像进行光学叠加,从而显现木星的云带和大红斑效果;利用Python内置的os模块和shutil模块,学习解决文件、文件夹和目录路径等问题。

本书每章的末尾都至少包含一个实践项目或挑战项目。在本书的配套资源或附录中,你可以找到每个实践项目的答案。但这并不意味着这个答案就是最好的——你可能会想出一个更好的答案,所以在此之前不要偷看答案!

然而,对于挑战项目,你只能靠自己。1519年,当科尔特斯入侵墨西哥时,他将帆船烧掉,让追随他的士兵意识到他们没有回头路,于是他们不得不以坚定的决心面对阿兹特克人。因此,短语“burn your boat”(破釜沉舟)成为全心全意或全身心投入一项任务的代名词。这也是你面对挑战项目时应有的态度,如果你这样做了,那么你从这些练习中学到的东西可能会比从书中其他部分学到的东西都要多!

本书中的所有项目构建于Microsoft Windows 10操作系统环境下,使用的Python版本为3.5。使用不同的操作系统也没有问题。我建议适当地使用与平台兼容的模块。

本书中的示例代码和屏幕截图来自Python的文本编辑器IDLE或交互式shell。IDLE代表集成开发和学习环境(Integrated Development and Learning Environment)。IDLE比集成开发环境(Integrated Development Environment,IDE)多了一个字母“L”。交互式shell也叫作解释器(Interpreter),它是一个不需要创建文件就可以执行命令和测试代码的窗口。

IDLE有很多缺点,例如缺少行号。然而,IDLE与Python绑定在一起,每个人都可以免费地使用它。我也鼓励你使用任何自己喜欢的IDE。有许多IDE可用,例如Geany(发音为genie)、PyCharm和PyScripter。 Geany适用于各种操作系统,包括UNIX操作系统、macOS和Windows操作系统;PyCharm适用于Linux操作系统、Windows操作系统和macOS;而PyScripter只适用于Windows操作系统。

本书为每个项目都提供了完整的代码,但我建议你尽可能地手动输入它们。一位大学教授曾经告诉我,“要靠双手学习”。我们不得不承认,手动输入代码的过程会迫使你最大程度地关注自己正在做的事情。

但是如果你想快速完成一个项目,或者你不小心删除了所有的代码,那么你可以在异步社区网站下载到与本书配套的代码,其中也包括实践项目的解决方案。

本书以解决问题和为初学者提供乐趣为目标。因此,书中的这些代码可能并没有按照最佳的代码实践进行编写,它们的运行效率可能也不是最优的。

对非专业编程人员来说,让事情变简单是很重要的。这些人编写的大部分代码可能在特定场合使用一两次,便不再使用。这些代码也可能需要与同事共享,或者是在人员变更期间被添加。因此,如果代码的使用场景是上述这些情况的话,使代码易于理解就显得更为重要了。

本书每个主要项目的代码都有单独的注释和解释,通常它们也符合Python增强提议8(也称为PEP 8)中建议的编程风格。本书会为你介绍PEP 8详情和一些帮助你遵守这些编程规则的软件模块。

编写每个Python项目都是一件具有挑战性的事情。尽管Python语言非常友好,但是要完全弄明白它也并非易事。本书会提供配套资源,然而,对于那些需要你亲自完成的项目,在线搜索是出现问题后的最好解决方式。

搜索成功的关键在于知道该问什么。起初,搜索结果可能会让人很沮丧,但是你可以把它想象成一个Twenty Questions游戏,在你找到答案或到达收益递减点之前,在多次搜索中不断完善你的关键词。

如果查阅书籍和在线搜索的方式均不能解决出现的问题,那么你可以向他人寻求帮助。你可以通过网络做这件事,既可以选择付费网站,也可以选择Stack Overflow这样的免费论坛。需要注意的是:这些网站的用户不愿忍受“傻瓜式”的提问。在发布求助问题前,你一定要先阅读网站的“How do I ask a good question?”(我怎么提出好问题?)主题内容,你可以在Stack Overflow的相关页面中找到它。

感谢你花时间阅读前言部分!你已经有了一个良好的开端,从本书的正文里你会学到更多的知识。当阅读完本书后,你将会熟练地使用Python,并能够解决现实世界中一些具有挑战性的问题。现在,让我们一起学习本书吧!


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书提供配套资源,请在异步社区本书页面中单击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

您还可以扫码右侧二维码, 关注【异步社区】微信公众号,回复“e56288”直接获取,同时可以获得异步社区15天VIP会员卡,近千本电子书免费畅读。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线投稿(直接访问www.epubit.com/ selfpublish/submission即可)。

如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近40年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、人工智能、测试、前端、网络技术等。

异步社区

微信服务号


美国网络电视频道曾经播出过一部名叫《灵异妙探》的侦探类喜剧。在该剧中,对细节观察入微的业余侦探肖恩·斯宾塞总是假装使用超能力来侦破案件。剧中吸引人的一幕是肖恩介绍老朋友的场景,他总能天马行空地想出一些姓名,如伽利略·汉普金斯、拉文德·库姆斯、讨厌鬼马文·巴尔内斯等。我对这些姓名留有深刻印象。我曾经在人口普查局看到过一份姓名列表,列表中的姓名与肖恩起的那些姓名类似,让我觉得十分新奇。

在此阶段的热身项目中,你将编写一个把姓氏和名字随机组合来产生虚假姓名的简易Python程序。该程序将毫不费力地生成大量令人意想不到的假名。你还将学习编程规范的最佳实践,以及在外部应用程序帮助下编写符合这些规范的代码。

《灵异妙探》的剧情跟你毫不相关吗?你也可以用喜欢的姓名来替换代码列表中的姓名。你可以轻而易举地将此项目变成《权利的游戏》的姓名生成器,或者发现一个让自己感到很惊喜的姓名“Benedict Cumberbatch”。对我来说,我最喜欢的姓名是“Bendylick Cricketbat”。

 

目标

编写符合既定样式的Python代码,随机生成一些有趣的姓名。

 

制定项目计划绝不是一件浪费时间的事。不管编程是出于乐趣,还是为了盈利,从某种程度上来说,你都需要十分精准地评估一些因素,诸如此项目的耗时、可能遇到的困难、完成此项工作所需的工具和资源等。要解决好这些问题,你首先需要明确自己在做什么。

一位成功的管理人士曾告诉我,他成功的秘诀就是不断地向自己提出一些问题。例如,你在做怎样的尝试?你为什么要做这种尝试?为什么要采用这种方式?耗费的时间和需要的资金分别是多少?厘清这些问题将有助于我们完成最终的项目设计,还能使这些问题的解决方案在我们的头脑中呈现出清晰的脉络。

艾伦·唐尼(Allen Downey)在他的编写《像计算机科学家一样思考Python(第2版)》中描述了两种类型的软件开发计划:“原型和补丁(Prototype and Patch)”和“按计划开发(Designed Development)”。在“原型和补丁”思想的指导下,先从一个简单的程序开始,然后使用补丁和可编辑的代码去解决测试过程中遇到的问题。在解决一个难以理解的复杂问题时,这不失为一个好办法,但是这会产生复杂且不可靠的代码。如果对问题本身有清晰的认识,并且知道如何去解决它,那么你就应该采用“按计划开发”的软件设计思想,尽量解决未来可能出现的问题,避免后续为程序添加补丁。这种方法可以使编写的代码更简单和有效,而且通常也会使代码变得更健壮和可靠。

对于本书中的每个项目,你都需要先清晰地理解其中的问题,明确项目目标,在此基础上才开始编写代码。这样一来,你就能够更好地理解问题,制定开发计划和设计策略。

首先,定义两个清单,它们分别用于存储虚假的名字和姓氏。由于这两个清单长度较短,它们不会占用大量内存,且不需要动态更新。在程序运行的过程中,这两个列表应该也不会出现任何运行问题。因此,你可以用元组存储名字和姓氏清单。

当程序运行后,它会根据这两个元组存储的元素,匹配姓氏和名字,生成一个新的姓名组合。用户可以重复该过程,直到产生足够多的虚假姓名为止。

在解释器窗口中以某种方式突出显示姓名,使它与命令提示信息有明显的不同。IDLE提供的可用字体选项并不多,但是我们都知道错误信息会被标红。在解释器窗口中,默认的标准输出函数是print(),但当加载sys模块后,可以使用file参数将输出重定向到错误信息输出通道,使输出的文字颜色为红色:

print(something, file=sys.stderr).

最后,需要确定哪种编程风格是Python编程规范目前所推荐的。这些编程风格不仅约定了代码的编写规范,而且对嵌入在代码内的文档字符串(Docstring)也有具体的要求。

丘吉尔曾说过,“不要尝试做你喜欢的事,要去喜欢你正在做的事”,你很难将编写伪代码与这句话联系在一起,但这句话却道出了人们使用伪代码的心理过程。

伪代码是一种使用任何结构化的人类语言对计算机程序执行过程进行解释的高级非正式描述,它像是一种包含关键词和适当缩进的简单编程语言。程序开发者使用伪代码的主要目的是忽略所有编程语言中的复杂语法,从而专注于程序的底层逻辑。尽管伪代码被广泛使用,但是目前只存在一些伪代码使用方法的指导原则,而这些指导原则还没有形成正式的标准。

如果编写程序时受挫,那么主要原因是你没有花时间去编写伪代码。对我来说,每当对编写代码感到困惑迷茫的时候,伪代码总能给我新的启发。因此,在本书的大多数项目中,你都会看到伪代码的使用。至少,我希望你能看到伪代码的实用价值,也希望你能养成在项目中使用伪代码的习惯。

虚假姓名生成器程序的伪代码描述如下:

定义名字元组
定义姓氏元组
从名字元组中随机选择一个名字
将这个名字分配给变量
从姓氏元组中随机选择一个姓氏
将这个姓氏分配给变量
在屏幕上用红色字体按选择的顺序输出姓名
询问用户是退出程序,还是重新开始
如果用户选择重新开始:
   重复上述过程
如果用户选择退出:
   结束并退出程序

如果不是只为了通过编程课程考核和向他人提供清晰的程序说明,那么请牢记使用伪代码的目的。你不要认为这样做是盲目服从(非标准的)编程规范,也不要将伪代码的应用局限于编程,尝试将它应用到更多的地方。一旦掌握了其应用窍门,你就会发现它可以帮助你完成其他任务,例如管理税务、计划投资、建造房子,甚至是准备野营。这是一种使思维集中的好方式,同时也能锻炼你把编程思想移植到现实生活中的能力。

清单1-1是虚假姓名生成器程序pseudonyms.py,它根据已有的名字和姓氏元组生成假名,并输出这个假名。如果不想将这些姓名全部输入,你可以分别输入它们的一个子集,也可以直接从配套资源中获取这些假名数据。

清单1-1 根据名字和姓氏元组生成假名

pseudonyms.py 
  ➊ import sys, random

  ➋ print("Welcome to the Psych 'Sidekick Name Picker.'\n")
     print("A name just like Sean would pick for Gus:\n\n")

     first = ('Baby Oil', 'Bad News', 'Big Burps', "Bill 'Beenie-Weenie'",
              "Bob 'Stinkbug'", 'Bowel Noises', 'Boxelder', "Bud 'Lite' ",
              'Butterbean', 'Buttermilk', 'Buttocks', 'Chad', 'Chesterfield',
              'Chewy', 'Chigger", "Cinnabuns', 'Cleet', 'Cornbread', 'Crab Meat',
              'Crapps', 'Dark Skies', 'Dennis Clawhammer', 'Dicman', 'Elphonso',
              'Fancypants', 'Figgs', 'Foncy', 'Gootsy', 'Greasy Jim', 'Huckleberry',
              'Huggy', 'Ignatious', 'Jimbo', "Joe 'Pottin Soil'", 'Johnny',
              'Lemongrass', 'Lil Debil', 'Longbranch', '"Lunch Money"', 'Mergatroid',
               '"Mr Peabody"', 'Oil-Can', 'Oinks', 'Old Scratch',
              'Ovaltine', 'Pennywhistle', 'Pitchfork Ben', 'Potato Bug',
              'Pushmeet','Rock Candy', 'Schlomo', 'Scratchensniff', 'Scut',
              "Sid 'The Squirts'", 'Skidmark', 'Slaps', 'Snakes', 'Snoobs',
              'Snorki', 'Soupcan Sam', 'Spitzitout', 'Squids', 'Stinky',
              'Storyboard', 'Sweet Tea', 'TeeTee', 'Wheezy Joe',
              "Winston 'Jazz Hands'", 'Worms')

     last = ('Appleyard', 'Bigmeat', 'Bloominshine', 'Boogerbottom',
             'Breedslovetrout', 'Butterbaugh', 'Clovenhoof', 'Clutterbuck',
             'Cocktoasten', 'Endicott', 'Fewhairs', 'Gooberdapple', 'Goodensmith',
             'Goodpasture', 'Guster', 'Henderson', 'Hooperbag', 'Hoosenater',
             'Hootkins', 'Jefferson', 'Jenkins', 'Jingley-Schmidt', 'Johnson',
             'Kingfish', 'Listenbee', "M'Bembo", 'McFadden', 'Moonshine', 'Nettles',
             'Noseworthy', 'Olivetti', 'Outerbridge', 'Overpeck', 'Overturf',
             'Oxhandler', 'Pealike', 'Pennywhistle', 'Peterson', 'Pieplow',
             'Pinkerton', 'Porkins', 'Putney', 'Quakenbush', 'Rainwater',
             'Rosenthal', 'Rubbins', 'Sackrider', 'Snuggleshine', 'Splern',
             'Stevens', 'Stroganoff', 'Sugar-Gold', 'Swackhamer', 'Tippins',
             'Turnipseed', 'Vinaigrette', 'Walkingstick', 'Wallbanger', 'Weewax',
             'Weiners', 'Whipkey', 'Wigglesworth', 'Wimplesnatch', 'Winterkorn', 
             'Woolysocks')

  ➌ while True:
      ➍ firstName = random.choice(first)

      ➎ lastName = random.choice(last)

         print("\n\n")
      ➏ print("{} {}".format(firstName, lastName), file=sys.stderr)
         print("\n\n")

      ➐ try_again = input("\n\nTry again? (Press Enter else n to quit)\n")
         if try_again.lower() == "n":
             break

  ➑ input("\nPress Enter to exit.")

首先,向程序导入sys模块和random模块➊。sys模块使你能够访问具体的系统错误消息,同时允许你把IDLE窗口中的输出文字设置为醒目的红色。random模块使你可以随机地从存放名字和姓氏的元组中选择数据项。

print语句的作用是向用户介绍本程序的功能➋。换行命令符\n强制开始新行;在字符串输出的双引号中,不必使用\转义字符,而可以直接使用单引号’。需要注意的是,使用转义字符将会降低代码的可读性。

接下来,分别定义名字和姓氏元组。然后,程序开始执行while循环➌。将while循环语句的循环条件设置为True,即让程序“一直运行,直到我让你停下来为止”。最终,你会使用break语句来结束这个循环。

在while循环体内,先从first元组中随机选择一个名字,并把这个名字赋给firstName变量➍。random模块的choice()函数会随机地从非空序列中选择一个元素,并把该元素当作函数的返回值。就本例而言,非空序列指的是名字元组。

紧接着,从last元组中随机选择一个姓氏,并将它分配给lastName变量➎。此时,你已经得到一组名字和姓氏,把它们输出在shell窗口中。向print()函数提供可选参数file=sys.stderr➏,使IDLE窗口中的“错误”信息显示为红色。同时,使用新的字符串格式化方法把姓名变量值转换为字符串。需要注意的是,旧的字符串格式方法指的是使用操作符%将变量值转换为字符串。在Python的官方网站可以获得更多与新的字符串格式化方法有关的信息。

之后,程序生成的假名就会显示出来。接着,利用input语句显示一段提示信息,询问用户是再来一次,还是退出程序。为了使这个有趣的姓名在IDLE窗口中更加显眼,本示例程序会使输出结果之间包含一些空白行。对于这个请求,如果用户直接按Enter键,那么变量try_again就不会捕捉到任何输入内容➐。由于没有返回任何内容,因此if条件语句不成立,while循环会继续运行,程序会再次输出新的名字和姓氏对。如果用户按N键,那么if语句中的条件成立,break语句会被执行。此时,while循环语句的判断条件也不再是True,循环随之结束。为了避免用户不小心按下Caps lock键,利用字符串对象的lower()函数把用户的输入值转换为小写字符。换言之,用户不必考虑输入的是小写字符还是大写字符,程序会总是将它视为小写。

最后,程序显示一条提示信息,告诉用户按Enter键结束程序➑。当用户按Enter键时,input()函数不会把返回值赋给任何变量,程序结束,同时控制台窗口关闭。在IDLE编辑器窗口中,按F5键将会执行程序。

这段代码可以正常运行,但是仅能正常运行是不够的,Python程序还得合乎一定的编程规范。

1.Python社区的编程规范

根据Python之禅(The Zen of Python)的说法,“做好一件事情的方法应该有且只有一种”。在实践的基础上,Python社区不断推出新的编程指导原则,发布新的Python增强提议(Python Enhancement Proposals,PEP),这些提议涉及一系列编程规范。Python发行版中的标准库也遵循相关编程规范。PEP 8是这些增强提议中最重要的编程规范。新的编程规范不断涌现,而旧的编程规范随着语言的改变逐渐被淘汰,PEP 8标准也随着时间的推移而不断演化。

PEP 8标准不仅约定了Python中标识符的命名原则,还规定了空白行、制表符和空格的使用方式,以及每行允许的最大字符长度和可采用的注释方式。PEP 8标准能提高代码的可读性,使所有的Python程序在编程规范上保持一致。当开始用Python编写程序时,你应该努力学习这些公认的编程规范,并养成遵守这些规范的良好习惯。本书的代码样式将与PEP 8标准保持一致,但是为了满足出版行业的排版要求,我在撰写本书时并没有严格遵守编程规范(例如,在本书中我会尽量减少代码注释和空行,也会让文档字符串尽可能地短)。

在跨职能团队中,标准化的名称和过程对程序的开发尤为重要。否则,科学家和工程师之间可能会产生很多误解。1999年,由于不同的团队使用不同的测量单位,工程师们失去了对火星气候轨道飞行器(Mars Climate Orbiter)的控制。在过去的20年时间里,我建立了能够应用于工程上的地球计算机模型。工程师可以使用脚本将这些模型加载到专门的软件中。为了帮助那些没有经验的人提高效率,工程师们会在项目开发过程中共享这些脚本。由于这些“命令文件”是根据每个项目定制的,因此在模型更新期间,工程师会对属性名的更改感到恼火。实际上,他们的内部准则之一便是“要求建模者使用一致的属性名”。

2.使用Pylint模块检查代码

尽管你已经熟悉PEP 8标准,但是仍然可能会犯错误。查看代码是否遵守PEP 8标准也是一件很麻烦的事情。幸运的是,你有许多工具可用,例如Pylint、pycodestyle和Flake8。在这些工具的帮助下,你可以轻松地编写出遵循PEP 8标准的代码。对于本章中的这个项目,你可以使用Pylint模块检查其代码的规范性。

(1)安装Pylint模块

Pylint模块是一款Python的源代码错误和代码质量检查器。在Pylint模块官网上,你可以找到该模块安装包的免费副本;根据所使用的操作系统,找到Install按钮。这个按钮将显示安装Pylint模块的命令。例如,在Windows操作系统上进入Python的安装主目录(如C:\Python35),在主目录中按住Shift键并单击鼠标右键,打开上下文菜单,根据你所使用的Windows版本,选择“在此处打开PowerShell窗口”(open PowerShell window here)选项。最后,在弹出的窗口中执行pip install pylint命令。

(2)运行Pylint模块

在Windows操作系统中,在命令行窗口中可以运行Pylint模块。而对于较新的操作系统,也可以在PowerShell(在待检查的Python模块主目录中,按住Shift并单击鼠标右键即可打开它)中运行它。输入pylint filename就可以运行该程序,如图1-1所示。扩展名.py是可选的,需要注意的是,实际的目录路径可能与图中显示的有所不同。在macOS和类UNIX操作系统上可以使用终端模拟器来执行这些操作。

图1-1 在Windows操作系统的命令行窗口中运行Pylint模块

Pylint模块把程序的检查结果显示在命令行窗口中。下面是一个Pylint模块的输出示例:

C:\Python35\Python 3 Stuff\Psych>pylint pseudonyms.py
No config file found, using default configuration
************* Module pseudonyms
C: 45, 0: No space allowed around keyword argument assignment
    print(firstName, lastName, file = sys.stderr)
                                    ^ (bad-whitespace)
C: 1, 0: Missing module docstring (missing-docstring)
C: 2, 0: Multiple imports on one line (sys, random) (multiple-imports)
C: 7, 0: Invalid constant name "first" (invalid-name)
C: 23, 0: Invalid constant name "last" (invalid-name)
C: 40, 4: Invalid constant name "firstName" (invalid-name)
C: 42, 4: Invalid constant name "lastName" (invalid-name)
C: 48, 4: Invalid constant name "try_again" (invalid-name)

每行开头的大写字母代表消息码。例如,“C:15, 0”指的是第15行第0列违背Python编程规范。下面是一些常见的Pylint模块消息码:

R:违反“良好实践”原则。

C:违反编程规范。

W:不严重的编程问题。

E:严重的编程问题(可能是一个错误)。

F:致命错误,阻止Pylint模块进一步运行。

通过与PEP 8标准进行一致性对比,Pylint模块会为你的代码打分。在这个例子中,代码的得分为4(满分10分):

Global evaluation
-----------------
Your code has been rated at 4.00/10 (previous run: 4.00/10, +0.00)

(3)处理常量名称错误

你可能已经注意到,Pylint模块错误地假设全局代码空间中的所有变量都表示常量,因此它们必须全部使用大写。该问题的解决方法有许多。第一种方法就是将这些变量放入main()函数中,如清单1-2所示。这样一来,这些常量就不再位于全局代码空间。代码如下:

清单1-2 main()函数的定义和调用方式

     def main():
         some indented code
         some indented code
         some indented code
  ➊ if __name__ == "__main__":
      ➋ main()

变量__name__是一种特殊的内置变量,你可以用它判断程序的运行方式,即程序是独立运行的,还是以导入其他程序中的方式运行的。需要注意的是,导入模块指的是在一个Python程序内使用另一个Python程序的行为。如果直接运行该程序,变量__name__就会被设置为“__main__”。在清单1-2中,变量__name__的作用就是确保当该脚本以模块的形式导入其他程序时,main()函数不会被调用。只有当直接运行该脚本时,if语句的判断条件才成立➊,main()函数才会被调用➋。但你并非总要遵守这样的约定。例如,若代码中仅有一个函数,就不需要在代码中使用变量__name__,直接以模块的形式将它导入另一个调用它的模块中即可。

除import语句之外,我们把程序pseudonyms.py的所有代码都放到main()函数中,在if语句内调用main()函数,如清单1-2所示。你既可以手动修改程序,使程序pseudonyms.py的代码满足前面所述的编程规范,也可以从本书配套资源中下载对应的程序pseudonyms_main.py。然后重新运行Pylint模块,检查修改后的程序。你会在命令行窗口中看到下面的输出结果:

C:\Python35\Python 3 Stuff\Psych>pylint pseudonyms_main
No config file found, using default configuration
************* Module pseudonyms_main
C: 47, 0: No space allowed around keyword argument assignment
        print(firstName, lastName, file = sys.stderr)
                                        ^ (bad-whitespace)
C: 1, 0: Missing module docstring (missing-docstring)
C: 2, 0: Multiple imports on one line (sys, random) (multiple-imports)
C: 4, 0: Missing function docstring (missing-docstring)
C: 42, 8: Invalid variable name "firstName" (invalid-name)
C: 44, 8: Invalid variable name "lastName" (invalid-name)

现在,那些令人讨厌的无效常量名称提示已经消失,但是你的代码依然没有完全遵守PEP 8标准。尽管我很喜欢使用像firstName这样的驼峰命名法,但是Python规范不允许我这样做。

(4)配置Pylint模块

当使用Pylint模块检查较短的脚本时,我更倾向于使用Pylint模块的默认设置,并忽略掉“无效常量名称”提示。我还喜欢使用-rn(-reports=n的简写)选项,它会阻止Pylint模块返回大量无关的统计信息:

C:\Python35\Python 3 Stuff\Psych>pylint -rn pseudonyms_main.py

注意,-rn选项会禁用Pylint模块的代码评分功能。

当使用Pylint模块时,经常遇到的另外一个问题是:它的默认最大行长为100个字符,但是,PEP 8建议的最多字符个数为79。若想与PEP 8保持一致,请用下面所示的设置运行Pylint模块:

C:\Python35\Python 3 Stuff\Psych>pylint --max-line-length=79 pseudonyms_main

此时,你会看到缩减最大行长后,main()函数内某些行的长度超出规定值:

C: 12, 0: Line too long (80/79) (line-too-long)
C: 14, 0: Line too long (83/79) (line-too-long)
--snip--

当运行Pylint模块时,你不必每次都手动输入这些选项和参数。你可以使用该模块的--generate-rcfile命令生成自定义的配置文件。例如,为了避免输出大量的统计信息,将最大行长设置为79个字符,在命令行窗口中输入如下内容,即可生成所需的配置文件:

your pathname>pylint -rn --max-line-length=79 --generate-rcfile >
name.pylintrc

将自定义参数设置放在--generate-rcfile > name.pylintrc命令之前,在扩展名.pylintrc的前面输入配置文件名。你可以像前面所做的那样,生成一个独立的配置文件来评估Python程序的规范性。当生成配置文件时,Pylint模块允许设置配置文件的存储路径,但是默认情况下,它会自动保存在当前的工作目录中。

为了使用自定义的配置文件,你需要在待检查程序前输入自定义配置文件名,并在配置文件名前输入--rcfile。例如,若要在文件myconfig.pylintrc指定的配置下运行pseudonyms_main.py程序,则需要在命令行窗口中输入如下内容:

C:\Python35\Python 3 Stuff\Psych>pylint --rcfile myconfig.pylintrc
pseudonyms_main

3.使用文档字符串描述代码

Pylint模块检测出程序pseudonyms_main.py缺少文档字符串。PEP 257标准指出:文档字符串是一种常放在模块、函数、类和方法定义开头的字符串。文档字符串的作用是简要地描述代码的功能,它可能会包括诸如输入要求等在内的说明信息。下面是一个在函数中使用单行文档字符串的示例,该字符串在一对三引号内:

def circ(r):
    """Return the circumference of a circle with radius of r."""
    c = 2 * r * math.pi
    return c

上面的文档字符串只是为了说明函数的功能,在实际的应用中,文档字符串可能更长,包含的信息也更多。例如,下面是这个函数的多行文档字符串示例,该字符串包含函数的输入和输出参数说明等信息:

     def circ(r):
         """Return the circumference of a circle with radius of r.

         Arguments:
         r – radius of circle

         Returns:
             float: circumference of circle
         """

         c = 2 * r * math.pi
         return c

文档字符串的书写方式会因个人、项目和公司的不同而有所差别。因此,你会发现存在很多相互矛盾的规范。谷歌公司就有独具该公司特色的编程规范。科学界的某些人士喜欢使用NumPy文档字符串书写标准。reStructuresText是一种流行的文档字符串格式化工具,它主要与工具Sphinx结合使用。通过Python代码的文档字符串,这些工具可为项目生成HTML和PDF格式的文档。如果阅读过一些Python模块的字符串文档,你可能看到过Sphinx字符串文档格式工具的使用。在1.11节中,你可以学到一些不同风格的文档字符串编写规范。

利用一款名为pydocstring的免费工具可以检查文档字符串是否符合PEP 257标准。若想把这款工具安装在Windows操作系统和任何其他操作系统上,你可以打开命令行窗口并执行pip install pydocstyle命令(如果操作系统中既安装有Python2,又安装有Python3,那么安装该工具时,你要在命令行窗口中输入pip3)。

为了使用pydocstring工具,先打开命令行窗口,将当前工作目录切换至待检查代码所在的目录。如果在命令行窗口中未指定文件名,pydocstring工具会检查该目录中的所有Python程序,并为每个程序生成相应的检查报告:

C:\Python35\Python 3 Stuff\Psych>pydocstyle
.\OLD_pseudonyms_main.py:1 at module level:
        D100: Missing docstring in public module
.\OLD_pseudonyms_main.py:4 in public function `main`:
        D103: Missing docstring in public function
.\ pseudonyms.py:1 at module level:
        D100: Missing docstring in public module
.\ pseudonyms_main_broken.py:1 at module level:
        D200: Oneline docstring should fit on one line with quotes (found 2)
.\ pseudonyms_main_broken.py:6 in public function `main`:
        D205: 1 blank line required between summary line and description
(found 0)

如果程序的文档字符串满足Python编程规范,那么pydocstring工具不会返回任何内容:

C:\Python35\Python 3 Stuff\Psych>pydocstyle pseudonyms_main_fixed.py

C:\Python35\Python 3 Stuff\Psych>

对于本书的所有项目,我将会在项目代码中使用一些简单的文档字符串,尽量降低注释的使用频率,避免过多注释影响代码的可读性。当然,若想练习文档字符串的编写方法,你可以对前面的示例进行随意拓展,也可以使用pydocstring工具来检查文档字符串的规范性。

4.检查代码风格

下面来了解一下如何使虚假姓名生成器程序的代码更符合PEP 8和PEP 257标准。

将程序pseudonyms_main.py复制一份,把它重命名为pseudonyms_main_fixed.py,使用Pylint模块对它的规范性进行评估:

your_path>pylint --max-line-length=79 pseudonyms_main_fixed

不要使用-rn选项,否则会禁用评分功能。在命令行窗口的底部,你会看到如下输出信息:

Global evaluation
-----------------
Your code has been rated at 3.33/10

现在,根据Pylint模块的检查结果修改程序pseudonyms_main_fixed.py的代码。在下面的例子中,我已经用粗体标注了要更正的地方。为了解决最大行长度不一致引起的问题,我修改了元组的名称。在本书的配套资源中,你可以找到修改后的代码对应的程序pseudonyms_ main_fixed.py

pseudonyms_main_fixed.py
"""从两个独立的名字元组中随机选择元素来生成有趣的假名"""
import sys
import random

def main():
    """从两个名字元组中随机选择一些名字并输出到屏幕上"""
    print("Welcome to the Psych 'Sidekick Name Picker.'\n")
    print("A name just like Sean would pick for Gus:\n\n")

    first = ('Baby Oil', 'Bad News', 'Big Burps', "Bill 'Beenie-Weenie'",
             "Bob 'Stinkbug'", 'Bowel Noises', 'Boxelder', "Bud 'Lite'",
             'Butterbean', 'Buttermilk', 'Buttocks', 'Chad', 'Chesterfield',
             'Chewy', 'Chigger', 'Cinnabuns', 'Cleet', 'Cornbread',
             'Crab Meat', 'Crapps', 'Dark Skies', 'Dennis Clawhammer',
             'Dicman', 'Elphonso', 'Fancypants', 'Figgs', 'Foncy', 'Gootsy',
             'Greasy Jim', 'Huckleberry', 'Huggy', 'Ignatious', 'Jimbo',
             "Joe 'Pottin Soil'", 'Johnny', 'Lemongrass', 'Lil Debil',
             'Longbranch', '"Lunch Money"', 'Mergatroid', '"Mr Peabody"',
             'Oil-Can', 'Oinks', 'Old Scratch', 'Ovaltine', 'Pennywhistle',
             'Pitchfork Ben', 'Potato Bug', 'Pushmeet', 'Rock Candy',
             'Schlomo', 'Scratchensniff', 'Scut', "Sid 'The Squirts'",
             'Skidmark', 'Slaps', 'Snakes', 'Snoobs', 'Snorki', 'Soupcan Sam',
             'Spitzitout', 'Squids', 'Stinky', 'Storyboard', 'Sweet Tea',
             'TeeTee', 'Wheezy Joe', "Winston 'Jazz Hands'", 'Worms')

    last = ('Appleyard', 'Bigmeat', 'Bloominshine', 'Boogerbottom',
            'Breedslovetrout', 'Butterbaugh', 'Clovenhoof', 'Clutterbuck',
            'Cocktoasten', 'Endicott', 'Fewhairs', 'Gooberdapple',
            'Goodensmith', 'Goodpasture', 'Guster', 'Henderson', 'Hooperbag',
            'Hoosenater', 'Hootkins', 'Jefferson', 'Jenkins',
            'Jingley-Schmidt', 'Johnson', 'Kingfish', 'Listenbee', "M'Bembo",
            'McFadden', 'Moonshine', 'Nettles', 'Noseworthy', 'Olivetti',
            'Outerbridge', 'Overpeck', 'Overturf', 'Oxhandler', 'Pealike',
            'Pennywhistle', 'Peterson', 'Pieplow', 'Pinkerton', 'Porkins',
            'Putney', 'Quakenbush', 'Rainwater', 'Rosenthal', 'Rubbins',
            'Sackrider', 'Snuggleshine', 'Splern', 'Stevens', 'Stroganoff',
            'Sugar-Gold', 'Swackhamer', 'Tippins', 'Turnipseed',
            'Vinaigrette', 'Walkingstick', 'Wallbanger', 'Weewax', 'Weiners',
            'Whipkey', 'Wigglesworth', 'Wimplesnatch', 'Winterkorn',
            'Woolysocks')

         while True:
             first_name = random.choice(first)
             last_name = random.choice(last)

             print("\n\n")
             # 使用“致命错误”字体设置,在IDLE窗口中将输出的姓名颜色设为红色
             print("{} {}".format(first_name, last_name), file=sys.stderr)
             print("\n\n")

             try_again = input("\n\nTry again? (Press Enter else n to quit)\n ")

             if try_again.lower() == "n":
                 break

         input("\nPress Enter to exit.")

     if __name__ == "__main__":
         main()

在满分为10分的情况下,Pylint模块给修改后的程序代码打了10分:

Global evaluation
-----------------
Your code has been rated at 10.00/10 (previous run: 3.33/10, +6.67)

从前面的内容可以看到,当评估程序pseudonyms_main_fix .py时,pydocstyle工具没有产生错误信息。但是,不要错误地认为程序的编程规范良好,甚至认为它已经足够好。例如,下面的文档字符串也可以通过pydocstyle工具的检查:

"""ksjkdls lskjds kjs jdi wllk sijkljs dsdw noiu sss."""

编写简洁且真正有用的文档字符串和注释是一件很困难的事情。我们可以借助PEP 257标准来处理文档字符串,但是注释的样式通常比较灵活,适用范围也相对更为开放。注释太多会产生视觉干扰,从而导致用户反感。过多的注释是不必要的,良好的代码本身就是编写思路的自述。开发者添加注释的原因有很多,如澄清代码意图,避免用户使用程序时出现潜在的错误;提醒用户注意输入数据的度量单位或格式等。若想正确地使用注释,则需要关注别人使用注释的方式,借鉴那些好的注释例子。此外,你还要考虑5年后重新阅读自己的代码时,希望在注释中看到什么内容。

Pylint模块和pydocstyle工具都易于安装和运行,它们可以帮助你更好地学习并遵守Python社区公认的编程标准。当你通过Web论坛寻求帮助,并希望获得友好、温和的回答时,你应该遵循的一个原则就是:在代码发布到论坛之前,先运行Pylint模块,评估代码的规范性。

现在,你应该知道如何才能编写出Python社区所期望的代码和文档。重要的是,你已经学会编写产生一些诸如“sidekick”“gangster”“informant”等虚假名字的程序。下面是一些我比较喜欢的姓名。

Pitchfork Ben Pennywhistle       'Bad News' Bloominshine

Chewy Stroganoff           'Sweet Tea' Tippins

Spitzitout Winterkorn        Wheezy Joe Jenkins

'Big Burps' Rosenthal        Soupcan Sam Putney

Bill 'Beenie-Weenie' Clutterbuck    Greasy Jim Wigglesworth

Drak Skies Jingley-Schmidt     Chesterfiled Walkingstick

Potato Bug Quakenbush       Jimbo Woolysocks

Worms Endicott          Fancypants Pinkerton

Cleet Weiners           Dicman Overpeck

Ignatious Outerbridge        Buttocks Rubbins

通过本书的配套资源,你可以获得与本章相关的资源文件。

通过本书的配套资源,你可以看到对伪代码编写标准的正规描述。

从本书的配套资源中,你可以获得一些有用资源。例如一些有价值的第三方模块介绍:

尝试用字符串来处理这些实践项目。从本书的附录中,你可以找到这些项目的解决方案。

为了形成儿童黑话(Pig Latin)(注:故意颠倒句子中的字母顺序来形成话语),首先需要一个以辅音开头的英语单词,并把辅音移到末尾,然后在单词末尾加上“ay”。若单词以元音开头,则只需在单词最后面加上“way”。在梅尔·布鲁克斯的喜剧杰作Young Frankenstein中,马蒂·费尔德曼说出了有史以来最著名的儿童黑话短语“ixnay on the ottenray”。

编写一个以单词作为输入内容的程序,它使用字符串索引和切片操作返回单词对应的儿童黑话。运行Pylint模块和使用pydocstyle工具检查所编写的代码,纠正程序出现的任何样式错误。你可以在附录中找到儿童黑话项目的解决方案,也可以从本书的配套资源中下载它对应的程序pig_latin_practice.py

你可以借用助记符“etaoin”(发音为eh-tay-oh-in)来记忆英语中最常用的6个字母。编写一个以句子(字符串)为输入内容的Python脚本程序,该程序会返回一个字符型的简单条形图,如图1-2所示。小提示:本项目用到了字典数据结构和两个尚未学习的模块,即pprint模块和collections/defaultdict模块。

图1-2 附录中EATOIN_practice.py程序输出的简单条形图

对于挑战项目,本书不提供解决方案,你只能靠自己!

使用在线翻译器将你的文本转换成另一种基于拉丁文的文本(如西班牙语、法语),重新运行简单条形图程序的代码,并比较两者的输出结果。对于图1-2所示的西班牙语译文,程序EATOIN_challenge.py将会产生图1-3所示的输出结果。

图1-3 对于图1-2所示的西班牙语译文,运行EATOIN_challenge.py程序产生的输出结果

在西班牙语句子中,“L”出现的频率是英语句子中的两倍,而“U”出现的频率则是英语句子中的3倍。若想使用柱状图直接比较不同输入之间的差异,则需要进一步修改代码,即无论字母表中的键是否有对应的值,都要把它输出。

重写虚假姓名生成器的代码,使它包含中间名。首先,创建一个新的middle_name元组,然后将现有名字拆分成名字-中间名对(例如,“Joe‘Pottin Soil’”“Sid‘The Squirts’”),并将它们添加到元组中。你还应该将一些明显的昵称(如“Oil Can”)保存在middle_name元组中。最后,添加一些新的中间名(如“The Big News”“Grunts”“Tinkie Winkie”)。生成带有中间名的假名后,利用random模块使这些假名出现的概率为二分之一或三分之一。

创建一个你喜欢的有趣姓名列表,将它加载到虚假姓名生成器程序中。小提示:电影演职人员名单是一个获取姓名的不错来源。

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e56288”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。


相关图书

深度学习的数学——使用Python语言
深度学习的数学——使用Python语言
动手学自然语言处理
动手学自然语言处理
Web应用安全
Web应用安全
Python高性能编程(第2版)
Python高性能编程(第2版)
图像处理与计算机视觉实践——基于OpenCV和Python
图像处理与计算机视觉实践——基于OpenCV和Python
Python数据科学实战
Python数据科学实战

相关文章

相关课程