书名:Python编程做中学
ISBN:978-7-115-58939-2
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 [加] 丹尼尔•津加罗(Daniel Zingaro)
译 王海鹏
责任编辑 郭泳泽
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
读者服务:
微信扫码关注【异步社区】微信公众号,回复“e58939”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。
Copyright © 2021 by Daniel Zingaro. Title of English-language original: Learn to Code by Solving Problems: A Python Programming Primer, ISBN 9781718501324, published by No Starch Press Inc. 245 8th Street, San Francisco, California United States 94103. The Simplified Chinese-edition Copyright © 2022 by Posts and Telecom Press Co., Ltd under license by No Starch Press Inc. All rights reserved.
本书中文简体字版由No Starch出版社授权人民邮电出版社独家出版。未经出版者书面许可,不得以任何方式复制或抄袭本书内容。
版权所有,侵权必究。
本书是一本零基础的Python编程入门书。全书介绍了Python的基本知识、条件语句、循环语句、列表、函数,并涉及数据结构、文件读写、算法等基本知识,引入了编程竞赛中重要的软件运行效率的概念。本书立足各编程挑战网站上的真题,将编程的基本思想和Python的知识点拆解成小任务,使读者在解题的过程中逐步探索,以亲自上手实践的方式学习编程。
本书适合想要零基础学习编程思想和Python编程语言的人阅读。
Daniel Zingaro博士是多伦多大学计算机科学的副教授和获奖教师。他的主要研究领域是计算机科学教育,研究计算机科学相关资料的学习方法。他是Algorithmic Thinking(No Starch出版社,2021年)的作者,该书帮助学习者理解和使用算法和数据结构。
Luke Sawczak是编辑也是业余程序员。他最喜欢的项目包括一个将散文转换为诗歌的转换器、一个切割正确数量的蛋糕块的视觉辅助工具,以及一个为数学老师制作的使用数字的Boggle游戏版本。他目前在多伦多郊区教法语和英语。他还创作诗和钢琴曲,如果可以的话,他愿意以此为生。
这是真的吗?我又能和No Starch出版社的人合作了?是Barbara Yien带我起航的。Bill Pollock和Barbara信任我在本书中使用的教学方法。Alex Freed编辑仔细、亲切,能够及时提供帮助。感谢所有参与本书制作的人,包括校对Kim Wimpsett、生产负责人Kassie Andreadis和封面设计师Rob Gale。我非常幸运能与他们合作。
感谢多伦多大学为我提供了写作的时间和地点。感谢技术审校人Luke Sawczak对手稿的仔细检查。
感谢所有为本书收录的问题和其他编程竞赛问题做出贡献的人。感谢DMOJ的管理人员对我工作的支持。
感谢我的父母,他们处理了所有事情—他们要求我做的就是学习。
感谢我的伴侣Doyali以无比的细心为本书投入大量精力。
最后,感谢大家阅读本书并愿意学习。
我们用计算机来完成任务和解决问题。例如,你也许曾用文字处理程序写过文章或信件,用电子表格程序来组织你的财务数据,用图像编辑程序来修饰一张图片。很难想象在没有计算机的情况下做这些事情。
文字处理程序、电子表格程序和图像编辑程序使我们获益。这些程序被写成通用工具,以完成各种各样的任务。不过,归根结底,它们是由其他人编写的程序,而不是由我们编写的。如果一个现有的程序不能完全满足我们的需要,该怎么办呢?
在本书中,我们的目标是学习如何控制计算机,编写自己的程序,而不是像普通用户那样仅使用已有程序、只做已有程序做到的事情。我们不会编写文字处理程序、电子表格或图像编辑程序,因为这些都是巨大的任务,而且幸运的是,已经有人完成了编写它们的工作。我们要学习的是如何编写小程序,以解决用其他方法无法解决的问题。我希望帮助你学习向计算机发出指令,这些指令将告诉计算机如何执行你的计划,以解决问题。
为了向计算机发出指令,我们用编程语言编写代码。编程语言规定了我们所写代码的规则,也规定了计算机对这些代码的响应。
我们将学习用Python编程语言编程。这是你将从本书中获得的一项具体技能,你可以将这项技能写入你的简历。除了Python,你也会学到使用计算机解决问题所需的思维方式。编程语言换来换去,但我们解决问题的方式不会改变。我希望这本书能帮助你在从普通用户到程序员的道路上走得更远,并希望你能在探索中获得乐趣。
本书适用于所有想学习如何编写计算机程序来解决问题的人。我想到了三类特定的人。
第一类,你可能已经听说过Python编程语言,并想学习如何用Python编写代码。我将在后面进一步解释为什么Python是入门编程的理想选择。在这本书中,你会学到很多关于Python的知识,为读更多关于Python的高级书籍打下基础——如果这是你的下一步计划。
第二类,如果你没有听说过Python,或者只是想了解编程是怎么回事,不要担心,这本书也是为你准备的!本书将教你编程的思维。程序员有特殊的方法将问题分解成可管理的部分,并在代码中表达这些部分的解决方案。在这个层面上,使用什么编程语言并不重要,因为程序员的思维方式并不会绑定特定的语言。
第三类,你可能有兴趣学习其他一些编程语言,如C++、Java、Go或Rust。作为学习Python的“副产品”,你学到的很多知识在你学习其他编程语言时都会很有用。另外,Python本身也是值得学习的。接下来我们来谈谈为什么。
多年的编程入门教学让我意识到,Python是入门编程语言的理想选择。与其他语言相比,Python代码通常更具结构性和可读性。你一旦习惯了它,可能会认同这种说法——它的部分内容读起来很像英语!
Python还具有许多其他语言所没有的特征,包括带有能够处理和存储数据的强大工具。我们将在本书中使用其中的许多特性。
Python不仅是优秀的教学语言,在实践中还有着庞大的需求量。程序员们用它来编写网络应用程序、游戏、可视化工具、机器学习软件……
这是一种非常适合教学的语言,它也带来了专业优势。我没有更多奢求了!
在使用Python编程之前,我们需要安装它。现在我们就来做这件事。
主要的Python版本有两个——Python 2和Python 3。Python 2是Python的旧版本,很多情况下已经不再受支持了。在本书中,我们使用Python 3,所以你需要在计算机上安装Python 3。
Python 3是从Python 2演变而来的,但即使在版本3中,Python也在持续变化。Python 3的第一个版本是Python 3.0,然后是Python 3.1,接着是Python 3.2,以此类推。在写这篇文章的时候,Python 3的最新版本是Python 3.9。对于本书来说,像Python 3.6这样的版本已经足够了,但我鼓励你安装并使用最新版本的Python。
请根据你的操作系统来安装Python。
Windows默认不包含Python。要安装Python,请访问Python的官网并选择Downloads。这将为你提供下载最新版本的Python for Windows的选项。选择链接下载Python,然后运行安装程序。在安装过程的第一个界面选择Add Python 3.9 to PATH或Add Python to environment variables,这会让运行Python更容易。(如果想要升级Python,你可能需要选择Customize installation来找到相关选项。)
macOS默认不包含Python 3。要安装Python 3,请访问Python的官网并选择Downloads。这将为你提供下载最新版本的Python for macOS的选项。选择链接以下载Python,然后运行安装程序。
Linux自带Python 3,但它可能是Python 3的旧版本。安装说明会根据你使用的Linux发行版而不同,但你应该可以使用你最喜欢的软件包管理器来安装最新版本的Python。
一口气把这本书从头到尾读完,你很可能学不到什么。这就好比试图通过以下方法学会弹钢琴:邀请某人到你家里弹几小时的钢琴,然后把他们赶出去,把灯调暗,直接开始弹奏小夜曲。这不是学习基于实践的技能的方式。
以下是我对学习本书的建议。
把你的工作分散开来。将练习集中在少量的环节中,远不如将练习间隔开有效。当你觉得累了,就休息一下。没有人可以告诉你在休息之前要工作多少时间。没有人可以告诉你应该用多长时间学完这本书。这取决于你自己的脑力和体力。
暂停以检验你的理解。阅读经常会给我们一种错觉——我们以为自己懂了,而实际没懂。应用这些内容会迫使我们将自己知道的信息与我们认为自己知道的信息保持一致。出于这个原因,在每一章的关键点上,我都提供了多项选择的“概念检查”问题,要求你进行预判。请认真对待这些问题!阅读每一个问题,在不使用计算机查阅任何东西的情况下,专心作答。然后,阅读我的答案和解释。这是确认你是否偏离道路的机会。如果你答错了,或者答对了但没有给出正确的理由,请在继续之前花时间修正你的理解,比如多研究一下正在讨论的相关Python特性,重读书中的内容,或者在网上搜索额外的解释和例子。
练习编程。在阅读时进行预判,有助于巩固你对关键概念的理解。但要成为一个熟练的问题解决者和程序员,你需要的不仅仅是这些。你需要练习使用Python来解决新的问题,而这些问题的解决方案是你在书中没有读到的。每一章都有一个练习列表。请尽可能多地完成这些练习。
学习编程需要时间。如果你进展缓慢或者犯了很多错误,不要灰心。不要被你在网上可能遇到的任何虚张声势的家伙所吓倒。在你周围要有能够帮助你学习的人和资源。
我决定围绕来自编程评测网站的问题来组织内容。编程评测网站提供了一个编程题库,全世界的程序员都可以尝试解决这些问题。你提交解决方案(你的Python代码),然后网站对你的代码进行测试。如果你的代码对每个测试用例都能给出正确的答案,那么你的解决方案很可能是正确的。如果你的代码对一个或多个测试用例给出错误的答案,那么你的代码是不正确的,需要修改。
我认为编程评测网站是特别适合学习编程的网站,有几个原因。
快速反馈。在学习编程的早期阶段,快速、有针对性的反馈是至关重要的。编程评测网站几乎可以在你提交代码的同时提供反馈。
高质量的问题。我发现来自编程评测网站的问题都有较高质量。许多问题最初来自竞争性的编程比赛。其他问题是由编程评测网站的有关人员编写的,或者只是想帮助别人学习。关于我们要研究的每个问题的来源,请参见附录。
问题的数量。编程评测网站包含数百个问题。在本书中,我只选编了其中一小部分。如果你需要更多的练习,请相信我,编程评测网站可以提供。
社区属性。编程评测网站让用户能够阅读和回复帖子。如果你在一个问题上卡住了,可以浏览评论,看看别人在那里写下的提示。如果仍然被卡住,可以考虑自己发帖,寻求帮助。
成功地解决了一个问题后,你的学习还没有结束!许多编程评测网站允许你查看别人提交的代码。仔细研究一下这些代码,看看它们与你的代码相比如何。解决一个问题总是有多种方法。也许你现在的方法对你来说是最直观的,但请对其他可能存在的方法持开放心态。这是迈向编程专家的重要一步。
我们将在整本书中使用几个编程评测网站。这是因为每个编程评测网站都会提供一些在其他编程评测网站那里找不到的问题,我们需要多个编程评测网站来提供我所选择的所有问题。
以下是我们将使用的编程评测网站:
● DMOJ;
● Timus;
● 美国计算机奥林匹克竞赛(USA Computing Olympiad,USACO)。
这些网站要求你在提交代码之前创建一个账号。现在让我们来看看创建账号的过程,并在此过程中了解一下这些网站的情况。
DMOJ是本书最常使用的编程评测网站。比起其他编程评测网站,你更应该花时间去探索DMOJ网站,了解该网站提供的内容。
要在DMOJ上创建一个账号,请进入DMOJ网站,选择Sign up,在注册页面上,输入用户名、密码和电子邮件地址。这个页面还允许你设置默认的编程语言。在本书中,我们将专门使用Python编程语言,所以我建议选择Python 3。选择Register!来创建你的账号。注册后,你可以用你的用户名和密码登录DMOJ。
本书中的每个问题开始时都指出了可以找到该问题的编程评测网站,你可以使用问题代码来访问它。例如,我们在第1章要解决的第一个问题可以在DMOJ上找到,其问题代码为dmopc15c7p2。要在DMOJ上找到这个问题,选择Problems,在搜索框中输入dmopc15c7p2,然后选择Go。你应该看到这个问题是唯一的搜索结果。选择问题的标题,就会看到该问题本身。
当你准备针对一个问题提交Python代码时,请找到这个问题,然后选择Submit solution。在出现的页面上,将Python代码粘贴到文本框中,然后选择Submit!。网站将评测你的代码,并给出结果。
要在Timus上创建账号,请进入Timus网站,并选择Register。在出现的注册页面上,输入用户名、密码、电子邮件地址和其他所需信息。选择Register来创建账号。然后检查你的电子邮件,看是否有来自Timus的包含你的评测网站ID的信息。当你提交Python代码时,会需要你的评测网站ID。
目前没有办法在该网站设置默认编程语言,所以无论何时提交Python代码,一定要选择Python 3的可用版本。
我们只在第6章中使用了一次Timus,所以我在这里就不多说了。
要在USACO上创建账号,请进入USACO网站,选择Register for New Account。在出现的注册页面上,输入用户名、电子邮件地址和其他所需信息。选择Submit来创建账号。然后检查你的电子邮件,看看是否有来自USACO的信息,其中包含你的密码。一旦有了密码,你就可以使用用户名和密码来登录USACO。
目前没有办法在该网站设置默认编程语言,所以无论何时提交Python代码,一定要选择Python 3的可用版本。你还需要上传包含Python代码的文件,而不是把代码粘贴到一个文本框中。
在第7章之前,我们不会使用USACO,所以在这里我不再多说。
本书中的每一章都是问题驱动的,它们来自专业的编程评测网站。事实上,在教授新的Python知识前,我喜欢先设置问题。这样做的目的是激励你去学习我们解决问题所需的Python特征。如果你在阅读了一个问题的描述后不确定如何解决,不要担心。(还不能解决这个问题,就说明你读对了书!)只要明白这个问题要求你做什么就足够了。我们将学习Python并一起解决问题。各章的后续问题可能会介绍更多的Python特性,或者要求我们拓展在第一个问题中学到的东西。章末设有练习,你应该自己解决这些问题,以将刚刚学到的东西投入实践。
下面是我们在每一章中要学习的内容概要。
第1章 启程。在使用Python解决任何问题之前,我们需要学习一些基础概念。在本章中,我们将学习这些概念,包括输入Python代码、处理字符串和数字、使用变量、在程序中输入和输出内容。
第2章 做判断。在本章中,我们将学习if语句,它允许程序根据特定的条件来决定要做什么。
第3章 重复代码:定循环。许多程序只要有工作要做,就会持续运行。在本章中,我们将学习for循环。它让程序逐一处理输入,直到工作完成。
第4章 重复代码:不定循环。有时,我们事先并不知道程序具体应该重复多少次某些指定的行为,for循环并不适合这些问题。在本章中,我们将学习while循环,只要一个特定的条件为真,程序就会重复执行代码。
第5章 用列表来组织值。Python列表允许我们用一个名字来指代整个数据序列。使用列表可以帮助我们组织数据,并利用Python提供的强大的列表操作(如排序和搜索)。在本章中,我们将学习关于列表的知识。
第6章 用函数来设计程序。对于一个有大量代码的大型程序,如果我们不好好组织它,它就会变得很笨重。在本章中,我们将学习函数,它可以帮助我们设计由小的、独立的代码块组成的程序。使用函数可以让程序更容易理解和修改。我们还将学习自顶向下的设计,这是一种用函数设计程序的方法。
第7章 读写文件。文件可以使向程序提供数据和从程序中获取数据变得很方便。在本章中,我们将学习如何从文件中读取数据、如何向文件中写入数据。
第8章 用集合和字典来组织值。随着要解决的挑战性问题越来越多,我们必须考虑如何存储数据。在本章中,我们将学习使用Python存储数据的两种新方法:使用集合和使用字典。
第9章 用完全搜索设计算法。程序员在解决每个问题时都不会从头开始,他们会考虑是否可以用一种一般的解决模式(一种算法)来解决这个问题。在这一章中,我们将学习用完全搜索设计算法,以解决各种各样的问题。
第10章 大O和程序效率。有时我们设法写出了一个程序,它能做正确的事情,但做得太慢,在实践中没有用。在本章中,我们将学习如何提高程序效率,并了解用来编写更高效代码的工具。
本书由异步社区出品,社区(www.epubit.com)为您提供相关资源和后续服务。
您还可以扫码右侧二维码, 关注【异步社区】微信公众号,回复“e58939”直接获取,同时可以获得异步社区15天VIP会员卡,近千本电子书免费畅读。
虽然作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。
当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入错误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的错误信息进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。
扫描下方二维码,您将会在异步社区微信服务号中看到本书信息及相关的服务提示。
我们的联系邮箱是contact@epubit.com.cn。
如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。
如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区投稿(直接访问www.epubit.com/contribute即可)。
如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。
如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值内容的动力之源。
“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网。
“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的标志。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。
异步社区
微信服务号
编程就是编写代码来解决问题。因此,我想从一开始就和你一起解决问题。也就是说,我们不是先逐一学习Python概念再来解决问题,而是用问题来决定我们需要学习的概念。
在本章中,我们将解决两个问题:确定一行文字中的单词数(就像字处理软件中的单词数统计功能),以及计算一个圆锥体的体积。解决这些问题需要了解若干Python概念。你可能觉得,需要更多的细节才能完全理解这里介绍的一些内容,以及它们在Python程序中是如何配合的。不必担心,我们将在后面的章节中重新探讨和阐述重要的概念。
正如引言所述,我们将使用Python编程语言解决编程竞赛中的问题。编程评测网站可以提供这些问题。我假定你已经按照引言中的说明安装了Python,并建立了你的编程评测网站账号。
对于每个问题,我们会写一个程序来解决它。每个问题都指定了要提供给该程序的输入类型,以及预期的输出(即结果)类型。如果我们的程序能够接受任意有效的输入并产生正确的输出,那么它就正确地解决了这个问题。
一般来说,输入会有数百万或数十亿种可能。每个这样的输入都被称为一个问题实例。例如,在我们要解决的第一个问题中,输入是一行文本(如“hello there”或“baabbb aa abab”),而我们的任务是输出该行文本的单词数。编程中强大的想法之一就是:通过少量的通用代码解决看似无尽的问题实例。
无论这一行有2个词、3个词还是50个词,都不重要。我们的程序每次都能解决这个问题。
我们的程序将执行如下3项任务。
输入:我们需要确定待解决问题的具体实例,所以先读取用户提供的输入。
处理:对输入进行处理,以确定正确的输出。
输出:在解决了问题之后,产生期望的输出。
这些步骤之间的界限可能并不总是那么清晰(例如,我们可能需要让一些处理过程和一些输出的产生交错发生),但将这3个一般步骤牢记在心是有帮助的。
你可能每天都在使用遵循这种“输入—处理—输出”模式的程序。考虑一个计算器程序:你输入一个算式(输入),程序进行计算(处理),然后显示答案(输出)。或者考虑一个网络搜索引擎:你输入一个关键词(输入),搜索引擎确定最相关的结果(处理),并显示它们(输出)。
将这些类型的程序与交互式程序进行对比就会发现,交互式程序融合了输入、处理和输出。例如,我正在使用文本编辑器录入这本书。当我输入一个字符时,编辑器会做出反应,将该字符添加到我的文档中。它并不会等我打完整个文档后才显示给我,而是在我建立文档时就交互式地显示出来。我们不会在本书中编写交互式程序。如果你在学习本书后对编写这样的程序感兴趣,那么你会很高兴地发现,Python能胜任这项任务。
每个问题都可以在评测网站中找到。但是,题干的文字描述不会完全一样,因为我为了全书的一致性而重写了题干。不必担心,我所写的内容传达的信息与官方的问题陈述是相同的。
对于书中的每个问题,我们都希望写一个程序,并将它保存在一个文件中,但前提是我们知道要写什么程序!对于书中的许多问题,我们首先需要学习一些新的Python特性,然后才能解决问题。
若想验证Python特性,可以使用Python Shell。这是一个交互式环境,你输入一些Python代码并按下回车键,Python会向你显示结果。一旦学到了足够的知识来解决当前的问题,我们就不再使用Python Shell,而是在文本文件中输入我们的解决方案。
首先,在你的桌面上创建一个名为programming的新文件夹。我们用这个文件夹来保存我们为本书所做的所有工作。
现在,我们导航到这个programming文件夹,并启动Python Shell。在你想启动Python Shell时,根据你的操作系统,按如下步骤进行。
在Windows上,执行以下操作。
1.按住Shift键,右击programming文件夹。
2.在出现的菜单中,选择“在Power Shell中打开”。如果没有这个选择,选择“在终端中打开”。
3.在结果窗口的底部,你会看到一行以“>
”结尾的文字。这是操作系统提示符,它正在等待你输入一个命令。你在这里输入操作系统的命令,而不是Python代码。一定要在每个命令后按下回车键。
4.现在你在programming文件夹中。如果你想看看那里有什么,可以输入dir(代表directory,即目录)。你应该看不到任何文件,因为我们还没有创建任何文件。
5.现在,输入python来启动Python Shell。
当你启动Python Shell时,应该看到类似如下的信息:
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:30:23)
[MSC v.1928 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
这里有一点很重要:第一行的Python版本至少要是3.6。如果你的版本较老,特别是以2开始,或者Python根本不能加载,你就需要按照引言中的说明,安装一个最新的Python版本。
在这个窗口的底部,你会看到Python提示符“>>>
”。这是你输入Python代码的地方。不要自己输入“>>>
”符号。一旦完成了编程,你可以按Ctrl+Z组合键,然后按回车键退出。
在macOS上,执行以下操作。
1.打开终端。你可以按Command+空格组合键,输入terminal,然后选择搜索结果。
2.在出现的窗口中,你会看到一行以“$
”结尾的文字。这是操作系统提示符,它在等待你输入一个命令。你在这里输入操作系统的命令,而不是Python代码。一定要在每个命令后按下回车键。
3.你可以输入ls命令来获得当前文件夹中的内容列表。在那里应该列出你的Desktop文件夹。
4.输入cd Desktop,导航到Desktop文件夹。cd命令代表改变目录(change directory),目录是文件夹的另一个名称。
5.输入cd programming,导航到programming文件夹。
6.现在,输入python3来启动Python Shell。(你也可以尝试输入python,不加3,但这可能会启动旧版本的Python 2。Python 2不适合完成本书的工作。)
当你启动Python Shell时,应该看到类似如下的信息:
Python 3.9.2 (default, Mar 15 2021, 17:23:44)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
这里有一点很重要:第一行的Python版本至少要是3.6。如果你的版本较老,特别是以2开始,或者如果Python根本不能加载,你就需要按照引言中的说明,安装一个最新的Python版本。
在这个窗口的底部,你会看到一个Python提示符“>>>
”。这是你输入Python代码的地方。不要自己输入“>>>
”符号。一旦完成了编程,你可以按Ctrl+D组合键退出。
在Linux上,执行以下操作。
1.右击你的programming文件夹。
2.在出现的菜单中,选择Open in Terminal。你也可以打开终端,并导航到你的programming文件夹(如果你更习惯这样操作)。
3.在出现的窗口的底部,你会看到一行以“$
”结尾的文字。这是操作系统提示符,它在等待你输入一个命令。你在这里输入操作系统的命令,而不是Python代码。一定要在每个命令后按下回车键。
4.你现在在programming文件夹中。如果你想看看那里有什么,你可以输入ls。你应该看不到任何文件,因为我们还没有创建任何文件。
5.现在,输入python3来启动Python Shell。(你也可以尝试输入python,但不要输入3,但这可能会启动一个旧版本的Python 2。Python 2不适合用于完成本书的工作。)
当你启动Python Shell时,应该看到类似如下的信息:
Python 3.9.2 (default, Feb 20 2021, 20:57:50)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
这里有一点很重要:第一行的Python版本至少要是3.6。如果你的版本较老,特别是以2开始,或者如果Python根本不能加载,你就需要按照引言中的说明,安装一个最新的Python版本。
在这个窗口的底部,你会看到一个Python提示符“>>>
”。这是你输入Python代码的地方。不要自己输入“>>>
”符号。一旦完成了编程,你可以按Ctrl+D组合键退出。
现在是时候解决我们的第一个问题了!我们要用Python编写一个小的单词计数程序。我们将学习如何读取用户的输入,处理输入以解决问题,并输出结果。我们还将学习如何在程序中处理文本和数字,利用Python的内置操作,并在解决问题的过程中保存中间结果。
这是DMOJ上代码为dmopc15c7p2的问题。
统计所提供文本的单词数量。对于这个问题,一个单词是指任意小写字母的序列。例如,hello是一个单词,但英文中没有含义的“单词”也计为一个单词,如baabbb。
一行文本,由小写字母和空格组成。每两个词之间正好有一个空格,而且在第一个词之前和最后一个词之后没有空格。
该行的最大长度为80个字符。
输入行文本所含的单词数。
值是Python程序的一个基本构件。每个值都有一个类型。类型决定了可以对值进行的操作。在“单词计数”问题中,我们要处理一行文本。在Python中,文本保存为一个字符串值,所以我们需要学习字符串的相关知识。为了解决这个问题,我们要输出文本中的单词数,所以我们也需要学习数值的相关知识。让我们从字符串开始。
字符串是用于保存和操作文本的Python类型。要写出一个字符串值,我们将它的字符放在单引号之间。请在Python Shell中继续学习:
>>> 'hello'
'hello'
>>> 'a bunch of words'
'a bunch of words'
Python Shell会回显我们输入的每个字符串。
如果字符串中有一个单引号作为它的一个字符,会发生什么?
>>> 'don't say that'
File "<stdin>", line 1
'don't say that'
^
SyntaxError: invalid syntax
don't
中的单引号终止了这个字符串。这一行的其余部分(t say that
)因此没有意义,这就是产生语法错误的原因。语法错误意味着我们违反了Python的规则,没有写出有效的Python代码。
为了解决这个问题,我们可以利用一个特性——双引号也可以用来给字符串定界:
>>> "don't say that"
"don't say that"
除非有关的字符串中含有单引号,否则我在本书中不会使用双引号表示字符串。
我们可以用一个字符串来保存我们想要计数的文本。为了对单词计数,或者对字符串做任何其他事情,我们需要学习如何处理字符串。
有各种各样的字符串操作供我们执行。其中一些操作在其操作数之间使用特殊符号。例如,+
操作符用于字符串连接:
>>> 'hello' + 'there'
'hellothere'
hello和there这两个词之间需要一个空格。让我们在第一个字符串的末尾添加一个空格:
>>> 'hello ' + 'there'
'hello there'
又如,*
操作符可将一个字符串按指定的次数重复:
>>> '-' * 30
'------------------------------'
30是一个整数值。关于整数,我们很快会对其进行进一步探讨。
概念检查
以下代码的输出是什么?
>>> '' * 3
A.''''''
B.''
C.这段代码产生一个语法错误(是无效的Python代码)
答案:B。''
是空字符串,即不含字符的字符串。一个空字符串重复3次仍然是一个空字符串。
方法是专门针对某一类型值的操作。字符串有大量的方法(method)。例如,有一个名为upper
的方法,可以产生字符串的大写版本:
>>> 'hello'.upper()
'HELLO'
我们从一个方法中得到的信息称为该方法的返回值。例如,对于前面的例子,我们可以说upper
返回字符串'HELLO'
。
在一个值上执行一个方法称为调用该方法。调用一个方法需要在值和方法名之间放置圆点操作符“.
”,并在方法名后面加上括号。对于某些方法,我们让这些括号中的内容保持为空,例如在调用upper
时。
对于其他方法,我们可以选择性地在括号中加入信息。还有一些方法要求必须加入信息,没有这些信息就根本无法工作。我们在调用一个方法时包含的信息被称为该方法的实参(argument)。
例如,字符串有一个strip
方法。如果调用时没有实参,则strip
将删除字符串中所有的前导和尾部空格:
>>> ' abc'.strip()
'abc'
>>> ' abc '.strip()
'abc'
>>> 'abc'.strip()
'abc'
我们也可以将一个字符串作为实参来调用这个方法。如果我们这样做,字符串实参就决定了哪些字符会从开头和结尾被剥离:
>>> 'abc'.strip('a')
'bc'
>>> 'abca'.strip('a')
'bc'
>>> 'abca'.strip('ac')
'b'
再来谈谈另一个字符串方法:count
。我们传递给它一个字符串实参,它告诉我们在字符串中发现了该实参多少次:
>>> 'abc'.count('a')
1
>>> 'abc'.count('q')
0
>>> 'aaabcaa'.count('a')
5
>>> 'aaabcaa'.count('ab')
1
如果该实参的出现位置有重叠,则只统计第一个:
>>> 'ababa'.count('aba')
1
与其他方法不同,count对“单词计数”问题有直接作用。
考虑一个字符串,如'this is a string with a few words'
。请注意,单词之间各有一个空格。事实上,如果你不得不手工来计算单词的数量,可能利用空格来识别每个单词的结束位置。如果我们计算一个字符串中的空格数,会怎么样?为了做到这一点,可以向count传入一个由单个空格字符组成的字符串,像这样:
>>> 'this is a string with a few words'.count(' ')
7
我们得到的数值是7。这并不完全等于单词数(字符串中有8个单词),但很接近了。为什么我们得到的是7而不是8?原因是最后一个单词后面没有空格。因此,统计单词后的空格数意味着忘记统计最后一个单词。为了弥补这一缺陷,我们需要学习如何处理数字。
表达式是由数值和操作符组成的。我们会看到如何表示数值,并用操作符将它们结合起来。
有两种不同的Python类型可以表示数字:整数(没有小数部分)和浮点数(有小数 部分)。
我们将整数值写成没有小数点的数字。下面是一些例子:
>>> 30
30
>>> 7
7
>>> 1000000
1000000
>>> -9
-9
值本身就是一种简单的表达式。
我们熟悉的数学操作符适用于整数:用+
表示加法,用-
表示减法,用*
表示乘法。我们可以用这些操作符来编写更复杂的表达式:
>>> 8 + 10
18
>>> 8 - 10
-2
>>> 8 * 10
80
注意操作符周围的空格。虽然就Python而言,8+10
(无空格)和8 + 10
(+
两侧各有一个空格)是一样的,但后者让表达式更容易阅读。
Python有两个表示除法的操作符。//
操作符执行整数除法,它摒弃任何余数,并将结果向下取整:
>>> 8 // 2
4
>>> 9 // 5
1
>>> -9 // 5
-2
如果你想得到除法的余数,可以使用模操作符%
。例如,8除以2的余数为0:
>>> 8 % 2
0
8除以3,余数为2:
>>> 8 % 3
2
与//
相比,/
操作符不做任何舍入:
>>> 8 / 2
4.0
>>> 9 / 5
1.8
>>> -9 / 5
-1.8
这些结果值不是整数。它们带有小数点,且属于另一种Python类型——浮点数(float)。写出带有小数点的数时,它就是一个浮点数:
>>> 12.5 * 2
25.0
我们现在先关注整数,在解决“圆锥体积”问题时再回来探讨浮点数。
如果我们在一个表达式中使用多个操作符,则Python使用优先级规则来决定操作符的应用顺序。每个操作符都有一个优先级。就像我们在纸上求一个数学表达式的值一样,Python在加法和减法(优先级较低)之前执行乘法和除法(优先级较高):
>>> 50 + 10 * 2
70
同样,像在纸上一样,括号内的操作具有最高的优先权。可以用它来强迫Python按我们所期望的顺序操作:
>>> (50 + 10) * 2
120
程序员经常添加括号,即使在技术上不需要。这是因为Python有许多操作符,记清它们的优先级并不容易,也不是程序员通常会做的事。
整数值和浮点数是否像字符串一样有方法?确实有!但这些方法并不是那么有用。例如,有一个方法可以告诉我们一个整数占用了多少计算机的内存。整数越大,它需要的内存就越多:
>>> (5).bit_length()
3
>>> (100).bit_length()
7
>>> (99999).bit_length()
17
整数两边需要加上小括号。否则,圆点操作符会与小数点混淆,我们就会遇到语法 错误。
我们现在知道了如何写出字符串和数值。我们也会发现,能够保存这些数值是很有价值的,这样以后就可以访问它们。在单词计数时,如果能够在某处保存这一行单词,然后计算单词数,那就很方便了。变量是指一个值的名称。每当我们使用一个变量的名字,它就会被该变量所指的内容所取代。
为了让一个变量指代一个值,我们使用赋值语句。赋值语句由变量、等号“=”和表达式组成。Python对表达式求值,并让变量指代结果。下面是一个赋值语句的例子:
>>> dollars = 250
现在,每当我们使用dollars
时,都会用250来代替它:
>>> dollars
250
>>> dollars + 10
260
>>> dollars
250
一个变量在同一时间只指代一个值。一旦我们用赋值语句让一个变量指代另一个值,它就不再指代之前的值:
>>> dollars = 250
>>> dollars
250
>>> dollars = 300
>>> dollars
300
我们可以有任意多的变量。大型程序通常使用数百个变量。下面这个例子使用了两个变量:
>>> purchase_price1 = 58
>>> purchase_price2 = 9
>>> purchase_price1 + purchase_price2
67
请注意,我选择的变量名称在一定程度上说明了它们所保存的内容。例如,这两个变量与两次购物的价格有关。使用变量名p1
和p2
会更容易输入,但几天后我们可能就会忘记这些名字的含义了!
我们也可以让变量指代字符串:
>>> start = 'Monday'
>>> end = 'Friday'
>>> start
'Monday'
>>> end
'Friday'
与指代数字的变量一样,我们可以在表达式中使用这些变量:
>>> start + '-' + end
'Monday-Friday'
Python的变量名应该以小写字母开始,可以包含小写字母、分隔单词的下线、数字。
假设我们有一个变量dollars
,它指代的是值250:
>>> dollars = 250
现在我们想增加这个值,使dollars
指代251。下面的方法是不行的:
>>> dollars + 1
251
结果是251,但这个值已经消失了,没有保存在任何地方:
>>> dollars
250
我们需要一个赋值语句来记录dollars + 1
的结果:
>>> dollars = dollars + 1
>>> dollars
251
>>> dollars = dollars + 1
>>> dollars
252
初学者通常会认为赋值符号“=”表示相等。但请不要这样认为。赋值语句是一个命令,使一个变量指代一个表达式的值,而不是声称两个实体是相等的。
概念检查
执行下面的代码后,y
的值是多少?
>>> x = 37
>>> y = x + 2
>>> x = 20
A.39
B.22
C.35
D.20
E.18
答案:A。对y
来说,只进行过一次赋值,使y
指代值39。x=20
的赋值语句将x
指代的值从37改为20,但这对y
所指代的值没有影响。
让我们总结一下在解决“单词计数”问题上的进展。
● 我们知道了字符串,可以用一个字符串来保存这一行单词。
● 我们知道了字符串的count
方法,可以用它来计算这行单词的空格数。这让我们的输出值比所需的输出值少1。
● 我们知道了整数,可以用它的+
操作符来给一个数字加1。
● 我们知道了变量和赋值语句,它们可以帮助我们保存数值,这样数值就不会丢失。
综上所述,我们可以让一个变量指代一个字符串,然后计算单词数:
>>> line = 'this is a string with a few words'
>>> total_words = line.count(' ') + 1
>>> total_words
8
line
和total_words
变量在这里不是必需的,下面是不使用它们来实现的代码:
>>> 'this is a string with a few words'.count(' ') + 1
8
但是,使用变量来记录中间结果是保持代码可读性的一个好做法。对于更长的程序,变量几乎是不可或缺的。
我们写的代码有一个问题:它只对输入的特定字符串起作用。它告诉我们'this is a string with a few words'
中有8个单词,但这就是它的全部功能。如果我们想知道另一个字符串中有多少个单词,就必须用一个新字符串替换当前字符串。不过,为了解决“单词计数”问题,我们需要程序能够处理作为输入的任意字符串。
为了读取一行输入,我们使用input
函数。函数(function)类似于方法:我们调用它(也许带有一些实参),它向我们返回一个值。方法和函数的一个区别是,函数不使用点操作符。所有信息都是通过实参传递给函数的。
下面是一个调用input
函数并键入一些输入的例子。本例中,输入了testing
这个词:
>>> input()
testing
'testing'
当你输入input()
并按下回车键时,不会得到“>>>
”提示符。作为替代,Python等待你在键盘上输入一些内容并按下回车键。然后input
函数返回输入的字符串。像往常一样,如果不把这个字符串保存在任何地方,它就会丢失。我们用一个赋值语句来保存输入的内容:
>>> result = input()
testing
>>> result
'testing'
>>> result.upper()
'TESTING'
注意最后一行,我对输入的值使用了upper
方法。这是允许的,因为input
返回一个字符串,而upper
是一个字符串方法。
你已经看到,在Python Shell中输入表达式会使它们的值显示出来:
>>> 'abc'
'abc'
>>> 'abc'.upper()
'ABC'
>>> 45 + 9
54
这只是Python Shell的特性。它假定,如果你输入了一个表达式,那么你可能想看到它的值。但是如果在Python Shell之外运行一个Python程序,这个特性就没有了。作为替代,每当我们想输出一些东西时,必须明确地使用print
函数。print
函数在Python Shell中也可以工作:
>>> print('abc')
abc
>>> print('abc'.upper())
ABC
>>> print(45 + 9)
54
请注意,由print
输出的字符串周围没有引号。这很好——毕竟,我们在与程序的用户交流时可能不希望每条消息都包括引号。
print
有一个很好用的特点:你可以提供很多实参,它们都会以空格分隔输出。
>>> print('abc', 45 + 9)
abc 54
我们现在准备编写一个完整的Python程序,从而解决“单词计数”问题。
我们先退出Python Shell,回到操作系统的命令提示符下。
我们将使用一个文本编辑器来编写代码。根据你的操作系统,按如下步骤进行。
在Windows上,我们将使用记事本(一个简单的文本编辑器)。如果你还没有在programming文件夹中,请导航到该文件夹。在操作系统的命令提示符下输入notepad word_count.py
并按下回车键。由于word_count.py文件不存在,记事本会问你是否要创建一个新的word_count.py文件。选择“是”,就可以输入Python程序了。
在macOS上,你可以使用你喜欢的任何文本编辑器。此处以TextEdit编辑器为例。如果你还没有在programming文件夹中,请导航到该文件夹。在操作系统的命令提示符下输入以下两个命令,在每个命令之后按回车键:
$ touch word_count.py
$ open -a TextEdit word_count.py
touch
命令创建了一个空文件,以便文本编辑器可以打开它。现在你已经准备好输入Python程序了。
在Linux上,你可以用你喜欢的任何文本编辑器。此处以gedit编辑器为例。如果你还没有在programming文件夹中,请导航到该文件夹。在操作系统的命令提示符下输入gedit word_count.py并按下回车键。现在你已经准备好输入Python程序了。
加载了文本编辑器之后,你可以输入Python程序的代码。代码在清单1-1中。
清单1-1:解决“单词计数”问题
❶ line = input()
❷ total_words = line.count(' ') + 1
❸ print(total_words)
输入这段代码时,不要输入“❶❷❸”这些数字。带圆圈的数字是用来帮助你在本书中查看代码的,不是代码本身的一部分。
我们开始通过输入获取文本行,并将它赋值给一个变量❶。这样我们就有了一个字符串,可以对它使用count
方法。我们在对空格的计数上加1,从而考虑到字符串中的最后一个单词,我们用变量total_words
来指代结果❷。最后要做的是输出total_words
所指代的值❸。
输入代码后,一定要保存该文件。
为了运行这个程序,我们会在操作系统的命令提示符下使用python
命令。如你所见,输入python
会运行Python Shell,但这次我们不希望这样。作为替代,我们要告诉Python运行word_count.py中的程序。为了做到这一点,导航到你的programming文件夹,并输入python word_count.py
。
程序现在正在输入提示符下等待你输入一些东西。输入几个单词,按回车键,你应该看到程序在正常工作。例如,输入:
this is my first python program
你应该看到程序的输出是6。
如果你看到一个Python错误,请回头查看一下代码,确保你准确地输入了代码。Python要求精确。即使缺少一个小括号或单引号也会导致错误。
如果你花了一些时间才使这个程序运行,不要感到沮丧。让第一个程序运行可能需要大量的工作。我们必须能够将一个程序输入文件,调用Python来运行这个程序,并修复不正确的程序导致的任何错误。运行程序的过程是不会改变的,不管程序有多复杂。你在这里花费的时间,对学习本书的其余部分是非常值得的。
祝贺你!我希望在你的计算机上运行的第一个Python程序令你满意。但是我们的程序正确吗?它对所有可能的字符串都有效吗?如果你愿意,可以在更多的字符串上测试它。但是,让我们对代码的正确性更有信心的方法是将它提交给在线评测网站。评测网站会自动对我们的代码进行一系列的测试,并告诉我们是否通过了测试、是否有问题。
请访问DMOJ网站并登录(如果你没有DMOJ账号,请按照引言中的说明创建一个账号)。选择Problems,并搜索“单词计数”问题的代码dmopc15c7p2。选择搜索结果,加载该问题——它被称为“Not a Wall of Text”,而不是“单词计数”。
然后你应该看到问题作者所写的问题文本。选择Submit Solution,并将我们的代码粘贴到文本区域。一定要选择Python 3作为编程语言。最后,选择Submit按钮。
DMOJ对我们的代码进行测试并显示结果。对于每个测试用例,你会看到一个状态代码。“AC”代表接受(即accepted),这是你对每个测试用例都想看到的结果。其他代码包括“WA”(错误答案,即wrong answer)和“TLE”(超过时限,即time limit exceeded)等。如果你看到这些代码,请仔细检查你粘贴的代码,确保它与你的文本编辑器中的代码完全一致。
假设所有测试用例都被接受,会看到得分是100/100。我们因这项工作而获得3个积分。
对于每一个问题,我们都将遵循“单词计数”问题的解决思路。首先,根据需要学习的Python功能,在Python Shell上进行探索。然后,写一个程序来解决这个问题,使用自己设计的测试用例在自己的计算机上测试。最后,将代码提交给评测网站。如果有任何测试用例失败,我们会再次查看代码并修复问题。
在“单词计数”问题中,我们需要从输入中读取一个字符串。在这个问题中,我们需要从输入中读取整数。这样做需要一个额外的步骤:从一个字符串中产生一个整数。我们还将学习更多在Python中进行数学运算的知识。
这是DMOJ上代码为dmopc14c5p1的问题。
计算一个圆锥的体积。
输入由两行文本组成。第一行包含整数r,即圆锥体的半径。第二行包含整数h,即圆锥体的高。r和h的取值范围均为1~100(也就是说,r和h的最小值是1,最大值是100)。
半径为r、高为h的右旋圆锥体的体积,计算体积的公式为(πr2h)/3。
假设我们有r和h两个变量,分别指代半径和高:
>>> r = 4
>>> h = 6
现在我们要求值(πr2h)/3。代入半径为4,高为6,则有(π×42×6)/3。如果π取3.14159,计算器给出的结果为100.531。如何在Python中做到这一点呢?
为了访问π的值,我们将使用一个合适的变量。下面是一个对PI的赋值语句,它的值非常接近π的精确值:
PI = 3.141592653589793
与其说这是一个变量,不如说它是一个常量,因为在我们的代码中,永远不会想改变PI的值。按照Python的惯例,对这样的变量使用大写字母,正如我在这里所做的。
回顾公式(πr2h)/3,我们唯一还没有谈到的是如何计算r2部分。r2可以由r*r
计算:
>>> r
4
>>> r * r
16
但直接使用指数会更清晰。我们总是希望写的代码尽可能清晰。此外,有一天你可能不得不计算更大的指数,在这种情况下,重复乘法会变得越来越不方便。Python的指数操作符是**
:
>>> r ** 2
16
下面是完整的公式:
>>> (PI * r ** 2 * h) / 3
100.53096491487338
很好,这已经接近我们预期的结果(100.531)了!
请注意,我们在这里产生的是一个浮点数。正如我们在1.3.2小节所讨论的,除法操作符“/
”会产生一个浮点数的结果。
我们最终必须读取半径和高作为输入,然后用这些值来计算体积。让我们试一试吧:
>>> r = input()
4
>>> h = input()
6
input
函数总是返回一个字符串,即使用户输入一个整数:
>>> r
'4'
>>> h
'6'
单引号表明这些值是字符串。字符串不能用来进行数学计算。如果尝试像下面这样计算字符串,会得到一个错误:
>>> (PI * r ** 2 * h) / 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
如果使用错误类型的值,则程序运行时会得到TypeError。Python反对我们在r
所指代的字符串和整数2上使用**
操作符。**
操作符是纯粹的数学运算,与字符串一起使用时没有任何意义。
为了将字符串转换为整数,我们可以使用Python的int
函数:
>>> r
'4'
>>> h
'6'
>>> r = int(r)
>>> h = int(h)
>>> r
4
>>> h
6
现在可以再次在公式中使用这些值:
>>> (PI * r ** 2 * h) / 3
100.53096491487338
对于以字符串形式表示的整数,可以用int
函数将它转换成一个类型为整数的值。该函数可以处理字符串开头和结尾的空格,但不能处理非数字字符:
>>> int(' 12 ')
12
>>> int('12x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '12x'
在将input
返回的字符串转换为整数时,我们可以分两步走。首先将input
的返回值赋给一个变量,然后将该值转换为整数:
>>> num = input()
82
>>> num = int(num)
>>> num
82
或者我们可以把input
和int
的调用结合起来:
>>> num = int(input())
82
>>> num
82
这里,传递给int
的实参是input
返回的字符串。int
函数接收这个字符串并将它返回为一个整数。
如果需要反过来转换,即将一个整数转换为一个字符串,我们可以用str
函数来实现:
>>> num = 82
>>> 'my number is ' + num
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
>>> str(num)
'82'
>>> 'my number is ' + str(num)
'my number is 82'
我们不能把一个字符串和一个整数连接起来。str
函数将82转换为'82'
,这样就可以在字符串连接中使用它。
现在,我们准备好解决圆锥体积问题了。创建一个名为cone_volume.py的新文本文件,并输入清单1-2中的代码。
清单1-2:解决“圆锥体积”问题
❶ PI = 3.141592653589793
❷ radius = int(input())
❸ height = int(input())
❹ volume = (PI * radius ** 2 * height) / 3
❺ print(volume)
这里包含了一些空行,将代码按逻辑分开。Python会忽略这些空行,但是这样的空行让我们更容易阅读代码。
注意,我使用了描述性的变量名:radius
(而不是r
)、height
(而不是h
),以及volume
。在数学公式中,单字母的变量名是常态,但在编写代码时,我们可以使用包含更多信息的变量名。
我们首先用一个名为PI
的变量指代π的近似值❶。从输入中读取半径❷和高❸并将两者从字符串转换为整数,然后利用正圆锥体的体积公式来计算体积❹,最后输出体积❺。
保存cone_volume.py文件。
输入python cone_volume.py
运行程序,然后输入半径值和高度值。可以用计算器来验证程序是否产生了正确的输出。
如果输入的半径或高是垃圾数据,会发生什么?例如,运行程序并输入:
xyz
你应该看到一个错误:
Traceback (most recent call last):
File "cone_volume.py", line 3, in <module>
radius = int(input())
ValueError: invalid literal for int() with base 10: 'xyz'
它对用户一点都不友好,这是肯定的。但对于学习编程来说,我们不会担心这个问题。根据问题的输入规格说明,评测网站的所有测试用例都是有效的,所以我们永远不必担心如何处理无效的输入。
说到评测网站,DMOJ欠我们3个积分,因为我们已经为这个问题编写了正确代码。来吧,提交你的作品吧!
我们已经出发!我们刚刚通过编写Python代码解决了最初的两个问题。我们学习了编程的基础知识,包括值、类型、字符串、整数、方法、变量、赋值语句,以及输入输出。
一旦你熟悉了这些内容(也许是通过下面的一些练习),就可以进入第2章。在那里,我们将学习程序如何做判断。我们将不再编写那些从上到下一成不变地运行的程序。程序将更加灵活,针对需要解决的具体问题实例做需要的事情。
每一章最后都有一些练习供你尝试。我鼓励你尽可能多地完成练习。
有些练习可能会花费你很长时间。你可能会因为反复出现的错误而感到沮丧。像任何值得学习的技能一样,这需要专心练习。在开始做一个练习时,我建议你手动求解几个例子。这样你就知道问题的要求是什么、程序应该做什么,否则,你可能会在没有计划的情况下写代码。既组织思路又写程序是很困难的。
如果你的代码不工作,就问自己:准确地说,你想要的行为是什么?哪几行代码可能是导致你出错的罪魁祸首?是否有其他更简单的方法可以尝试?
我在本书的网站上提供了练习的解决方案。但是,在你真正尝试完成练习之前,不要偷看那些解决方案。选择两三个练习。如果你看了一个解决方案,了解了别人如何解决这个问题,那就休息一下,然后自己试着从头开始解决这个问题。解决问题的方法往往不止一种。如果你的解决方案做了正确的事情,但与我的不同,这并不意味着你的或我的解决方案是错误的。相反,这是一个机会,将你的代码和我的代码进行比较,也许你在这个过程中可以学到其他技术。
1.DMOJ上代码为wc16c1j1的问题:A Spooky Season。
2.DMOJ上代码为wc15c2j1的问题:A New Hope。
3.DMOJ上代码为ccc13j1的问题:Next in Line。
4.DMOJ上代码为wc17c1j2的问题:How’s the Weather?(提示:注意转换的方向)。
5.DMOJ上代码为wc18c3j1的问题:An Honest Day’s Work(提示:请思考如何确定瓶盖的数量和这些瓶盖所需的油漆总量)。
“单词计数”问题来自DMOPC’15的4月比赛。“圆锥体积”问题来自DMOPC’14的3月比赛。
微信扫码关注【异步社区】微信公众号,回复“e58939”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。