1.1 引言

计算机科学是一门非常广泛的学科。全球分布式系统、人工智能、机器人、图形学、安全、科学计算、计算机体系结构等领域,以及数十个新兴的子领域,每年都以新的技术和发现扩展。计算机科学的飞速发展几乎影响到了人类生活的方方面面。商业、通信、科学、艺术、休闲和政治都被重新定义为计算领域。

计算机科学的高生产率之所以成为可能,是因为该学科是建立在一套优雅而强大的基本思想之上的。所有的计算都始于表示信息、指定处理它的逻辑,以及设计管理该逻辑复杂性的抽象。要掌握这些基本知识,就需要我们准确地理解计算机是如何解释计算机程序和执行计算过程的。

这些基本思想长期以来一直使用经典的教科书结构和计算机程序解释(SICP),由Harold Abelson和Gerald Jay Sussman和Julie Sussman教授。本文大量借用了那本教科书,它的原始作者善意地许可改编和在创作共用许可证下重用。这些注释是在知识共享署名非商业性共享许可第三版下发布的。

1.1.1 用Python编程

Arika Okren:一门语言不是你学的东西,而是你加入的东西。

为了定义计算过程,我们需要一种编程语言; 最好是一个许多人和各种各样的计算机都能理解的语言。 在本文中,我们将主要使用 Python语言。

Python是一种广泛使用的编程语言,它有着各种职业的爱好者:web程序员、游戏工程师、科学家、学者,甚至是新编程语言的设计师。 当你学习Python的时候,你加入了一个有上百万人的开发者社区。 开发人员社区是非常重要的机构:成员互相帮助解决问题,分享他们的项目和经验,共同开发软件和工具。 敬业的会员往往因其贡献而获得名气和广泛的尊重。

Python语言本身是一个大型志愿者社区的产物,该社区以其贡献者的多样性而自豪。 该语言是由Guido van Rossum在20世纪80年代后期构想并首次实施的。 在他的Python 3教程的第一章中,解释了为什么Python在众多语言中如此流行。

Python作为一种教学语言非常出色,因为在它的历史中,Python的开发人员一直强调Python代码的人类可解释性,并通过Python的禅学指导原则的美感、简单性和可读性加以加强。 Python特别适合于本文,因为它广泛的特性集支持各种不同的编程风格,我们将探讨这些风格。 虽然没有单一的Python编程方法,但是开发人员社区共享了一组约定,这些约定有助于阅读、理解和扩展现有程序。 Python结合了极大的灵活性和可访问性,允许学生探索许多编程范式,然后将他们新获得的知识应用到成千上万正在进行的项目中。

这些文字通过与抽象技术和严格的计算模型同步引入Python的特性,维护了SICP的精神。 此外,这些文字提供了Python编程的实用介绍,包括一些高级语言特性和说明性示例。 随着您阅读文本的进展,使用Python增加您的功能应该是自然而然的。

开始用Python编程的最好方法是直接与解释器交互。 本节介绍如何安装Python 3,启动与解释器的交互式会话,并开始编程。

1.1.2 安装Python 3

和所有优秀的软件一样,Python有很多版本。 本文将使用Python 3的最新稳定版本。 许多计算机已经安装了较旧的Python版本,例如Python 2.7,但这些版本与本文中的描述不匹配。 您应该能够使用任何计算机,但希望安装Python 3。 (别担心,Python是免费的。)

您可以通过单击以3(而不是2)开头的版本从Python下载页面下载Python 3。按照安装程序的说明完成安装。

要获得进一步的指导,请尝试Julia Oh创建的Windows安装Mac安装Python 3的视频教程。

1.1.3 交互式会话

在一个交互式的Python会话中,你在提示符>>>后面输入一些Python代码。 Python解释器读取并执行你输入的内容,执行你的各种命令。

要启动交互式会话,请运行Python 3应用程序。 在终端提示符中输入python3 (Mac/Unix/Linux)或在Windows中打开Python 3应用程序。

如果您看到Python提示符>>>,那么您已经成功启动了一个交互式会话。 这些注释描述了使用提示符和输入符的示例交互。

>>> 2 + 2
4

交互控制。 每个会话都保存您输入的内容的历史记录。 要访问历史记录,请按<Control>-P(前面)和<Control>-N(后面)。 <Control>-D退出会话,会话将丢弃此历史记录。 在一些系统上,向上和向下的箭头也可以查询历史。

1.1.4 第一个例子

And, as imagination bodies forth The forms of things to unknown, and the poet's pen Turns them to shapes, and gives to airy nothing A local habitation and a name.

-威廉·莎士比亚《仲夏夜之梦》

为了正确地介绍Python,我们将从一个使用几种语言特性的例子开始。 在下一节中,我们将从头开始,一点一点地构建语言。 可以把这个部分看作是即将到来的特性的预览。

Python内置了对各种常见编程活动的支持,比如操作文本、展示图形和网络通信。

>>> from urllib.request import urlopen

这一Python代码行是一个导入语句,用于加载在Internet上访问数据的功能。 特别是,它提供了一个名为urlopen的函数,该函数可以访问统一资源定位器(URL)上的内容,URL是Internet上的某个位置。

语句和表达式。 Python代码由表达式和语句组成。 从广义上说,计算机程序由任意一种指令组成。

  1. 计算某个值

  2. 执行某种行为

语句通常描述动作。 当Python解释器执行一条语句时,它会执行相应的动作。 另一方面,表达式通常描述计算。 当Python计算表达式时,它会计算该表达式的值。 本章介绍几种类型的语句和表达式。

赋值语句

>>> shakespeare = urlopen('http://composingprograms.com/shakespeare.txt')

将命名shakespeare与=后面的表达式的值相关联。 该表达式将urlopen函数应用于一个URL,该URL包含威廉·莎士比亚37部戏剧的完整文本,全部在一个文本文档中。

函数。 函数封装了操作数据的逻辑。 urlopen是一个函数。 网址是一段数据,莎士比亚戏剧的文本是另一段数据。 前者导致后者的过程可能是复杂的,但我们可以只使用简单的表达式应用该过程,因为复杂性隐藏在函数中。 函数是本章的主要主题。

另一个赋值语句

>>> words = set(shakespeare.read().decode().split())

将words与莎士比亚戏剧中所有33721个独特的单词联系起来。 要读取、解码和拆分的命令链,每个都对一个中间计算实体进行操作:我们从打开的URL读取数据,然后将数据解码为文本,最后将文本拆分为单词。 所有这些词都放在一个集合中。

对象。 集合是一种对象类型,它支持集合操作,如计算交叉和成员关系。 对象以一种管理两者复杂性的方式,无缝地将数据和操作数据的逻辑捆绑在一起。 对象是第二章的主要主题。

>>> {w for w in words if len(w) == 6 and w[::-1] in words}
{'redder', 'drawer', 'reward', 'diaper', 'repaid'}

最后,上述表达式是一个复合表达式,计算结果为同时是反拼写的所有莎士比亚式单词的集合。 神秘的符号w[::-1]枚举单词中的每个字母,但-1表示倒退。 当您在交互式会话中输入表达式时,Python将在下一行输出它的值。

解释器。 求复合表达式需要一个精确的过程,以可预测的方式解释代码。 实现这样一个计算复合表达式的过程的程序称为解释器。 第三章主要讨论解释器的设计与实现。

与其他计算机程序相比,程序语言解释器的通用性是独一无二的。 Python的设计并没有考虑到莎士比亚。 然而,它的巨大灵活性允许我们只用几个语句和表达式来处理大量文本。

最后,我们会发现所有这些核心概念都是紧密相关的:函数是对象,对象是函数,解释器是两者的实例。 然而,清晰地理解这些概念及其在组织代码中的作用,对于掌握编程艺术是至关重要的。

1.1.5 错误

Python正在等待你的命令。 鼓励你尝试这门语言,即使你可能还不知道它的全部词汇和结构。 但是,要为错误做好准备。 虽然计算机非常快速和灵活,但它们也非常僵硬。 计算机的本质在斯坦福大学的入门课程中被描述为

计算机的基本方程是:

电脑=强大+愚蠢

计算机的功能非常强大,可以快速地查看大量数据。 计算机每秒可以执行数十亿次操作,而每一次操作都非常简单。

电脑也非常愚蠢和脆弱。 它们所能做的操作是极其严格、简单和机械的。 电脑缺乏真正的洞察力…… 跟电影里的哈尔9000一点都不像。 如果没有别的,你不应该被计算机吓倒,就好像它是某种大脑一样。 它的本质是机械的。

编程是关于一个人用他们的真知灼见去构建一些有用的东西,这些东西是由电脑能做的微小的,简单的操作组成的。

—Francisco Cai and Nick Parlante, Stanford CS101

当你尝试使用Python解释器时,计算机的刚性将立即变得明显:即使最小的拼写和格式更改也会导致意外的输出和错误。

学习解释错误和诊断意外错误的原因被称为调试。 调试的一些指导原则是:

  1. 增量测试:每一个编写良好的程序都是由可以单独测试的小的、模块化的组件组成的。 尽快尝试您编写的所有内容,以便尽早识别问题,并在您的组件上获得信心。

  2. 隔离错误:语句输出中的错误通常可以归因于特定的模块化组件。 当试图诊断一个问题时,在尝试纠正它之前,尽可能地跟踪错误到最小的代码片段。

  3. 检查你的假设:解释器确实严格执行你的指示——不多不少。 当某些代码的行为与程序员认为(或假设)的行为不匹配时,它们的输出是意外的。 了解您的假设,然后将调试工作集中于验证您的假设是否确实成立。

  4. 咨询他人:你并不孤单! 如果你不理解错误信息,可以问朋友、老师或搜索引擎。 如果您已经隔离出了一个错误,但不知道如何纠正它,请其他人看看。 在群体问题解决的过程中,有很多有价值的编程知识被分享。

增量测试,模块化设计,精确假设,和团队合作是贯穿这篇文章的主题。 希望它们也能贯穿你的计算机科学职业生涯。

Last updated

Was this helpful?