Skip to content
📖 Auto 版 Think Python本书目录

编程是一种思维方式 ​

本书的第一个目标是教你如何用 Auto 编程。 但学习编程意味着学习一种新的思维方式,所以第二个目标是帮助你像计算机科学家一样思考。 这种思维方式融合了数学、工程学和自然科学的最佳特点。 像数学家一样,计算机科学家使用形式化语言来表达思想——特别是计算。 像工程师一样,他们设计事物,将组件组装成系统并评估各种方案的权衡。 像科学家一样,他们观察复杂系统的行为,提出假设并验证预测。

我们将从最基本的编程元素开始,逐步深入。 在本章中,我们将了解 Auto 如何表示数字、字母和单词。 你还将学习执行算术运算。

你还将开始学习编程词汇,包括运算符、表达式、值和类型等术语。 这些词汇很重要——你需要它们来理解本书的其余内容、与其他程序员交流,以及有效地使用工具。

算术运算符 ​

算术运算符是表示算术计算的符号。 例如,加号 + 执行加法。

auto
30 + 12

减号 - 执行减法。

auto
43 - 1

星号 * 执行乘法。

auto
6 * 7

正斜杠 / 执行除法。

auto
84 / 2

注意除法的结果是 42.0 而不是 42。 这是因为 Auto 中有两种数字类型:

  • 整数(integer),表示没有小数部分的数字,以及

  • 浮点数(floating-point number),表示整数和带小数点的数字。

如果你对两个整数进行加法、减法或乘法,结果仍然是整数。 但如果你对两个整数进行除法,结果会是浮点数。

Auto 还提供了另一个运算符 //,执行整数除法(也称为"向下取整除法")。 整数除法的结果始终是整数——它总是向下取整。

auto
84 // 2    // 结果是 42
85 // 2    // 结果是 42(向下取整,不是 42.5)

取模运算符 % 计算整数除法的余数。

auto
85 % 2     // 结果是 1

最后,运算符 ** 执行幂运算,即将一个数字提升到某个幂次。

auto
7 ** 2     // 结果是 49
2 ** 10    // 结果是 1024

Python 程序员注意:

Auto 与 Python 使用相同的算术运算符:+、-、*、/、//、% 和 **。这些运算符通过 a2p 转译时不会有任何变化。

表达式 ​

由运算符和数字组成的集合称为表达式。 表达式可以包含任意数量的运算符和数字。 例如,下面是一个包含两个运算符的表达式。

auto
6 + 6 ** 2

注意幂运算先于加法执行。 Auto 遵循标准的运算顺序:幂运算先于乘法和除法,乘法和除法先于加法和减法。

在下面的例子中,乘法先于加法执行。

auto
12 + 5 * 6

如果你想先执行加法,可以使用括号。

auto
(12 + 5) * 6

每个表达式都有一个值。 例如,表达式 6 * 7 的值是 42。

Auto 中的算术运算

工作原理

本程序演示了 Auto 中的所有七种算术运算符。前四行展示了四种基本运算:加法(+)、减法(-)、乘法(*)和除法(/)。注意 84 / 2 产生 42.0(浮点数),而不是 42(整数)——这是因为常规除法总是返回浮点数。

整数除法运算符 // 总是向下取整。所以 85 // 2 是 42,而不是 42.5。取模运算符 % 返回余数,所以 85 % 2 是 1。幂运算使用 **:7 ** 2 是 49,2 ** 10 是 1024。

最后三行展示了运算顺序。在 6 + 6 ** 2 中,幂运算先执行,所以这是 6 + 36 = 42。在 12 + 5 * 6 中,乘法先执行,所以这是 12 + 30 = 42。使用括号时,(12 + 5) * 6,加法先执行:17 * 6 = 102。

算术函数 ​

除了算术运算符之外,Auto 还提供了处理数字的内置函数。

round 函数接收一个浮点数并将其四舍五入到最接近的整数。

auto
42.4.round()    // 结果是 42
42.6.round()    // 结果是 43

abs 函数计算一个数字的绝对值。

auto
42.abs()        // 结果是 42
(-42).abs()     // 结果是 42

Python 程序员注意:

在 Python 中,你这样调用:round(42.4) 和 abs(-42)。在 Auto 中,方法直接在值上调用:42.4.round() 和 (-42).abs()。a2p 转译器会将这些转换为等效的 Python 函数调用。

当我们像这样使用函数时,我们说我们在调用函数。 调用函数的表达式称为函数调用。

字符串 ​

除了数字,Auto 还可以表示字母序列,称为字符串(string),因为这些字母像项链上的珠子一样串在一起。 要写字符串,我们将字符序列放在引号内。

auto
"Hello"
'world'

单引号和双引号都可以使用。双引号方便在字符串中包含撇号。

auto
"it's a small world."

字符串还可以包含空格、标点符号和数字。

auto
"Well, "

+ 运算符可以用于字符串;它将两个字符串连接成一个字符串,这称为拼接(concatenation)。

auto
"Well, " + "it's a small " + "world."

* 运算符也可以用于字符串;它将一个字符串复制多次并拼接起来。

auto
"Spam, " * 4

Auto 提供了 len 函数来计算字符串的长度。

auto
"Spam".len()    // 结果是 4

注意 len 计算的是引号之间的字符数,不包括引号本身。

Auto 支持f-string(格式化字符串)。语法在字符串内的变量名前使用 $ 前缀。

auto
let name = "Alice"
let age = 30
print(f"My name is $name and I am $age years old.")

Python 程序员注意:

在 Python 中,f-string 使用 {name} 语法。在 Auto 中,相同的功能使用 $name 语法。a2p 转译器会自动将 f"$name" 转换为 f"{name}"。

Auto 中的字符串操作

工作原理

我们首先打印了使用单引号和双引号的字符串。双引号特别适用于字符串中包含撇号的情况("it's a small world.")。

字符串拼接使用 + 运算符将三个字符串首尾相连。* 运算符重复字符串:"Spam, " * 4 产生 "Spam, Spam, Spam, Spam, "。.len() 方法返回字符串中的字符数——"Spam" 有 4 个字符。

f-string f"My name is $name and I am $age years old." 使用 $name 和 $age 来插值变量。在 Python 输出中,这些会变成 {name} 和 {age}。

值和类型 ​

到目前为止我们见过三种值:

  • 2 是整数,

  • 42.0 是浮点数,以及

  • "Hello" 是字符串。

一种值的类别称为类型(type)。 每个值都有一个类型——或者我们有时说它"属于"某个类型。

我们目前见过的类型有:

  • int 表示整数(如 42、-7、1_000_000 等整数)

  • float 表示浮点数(如 3.14、0.5 等带小数点的数字)

  • str 表示字符串(如 "Hello, World!" 等字符序列)

  • bool 表示布尔值(true 或 false)

类型名 int、float 和 str 也可以用来将值从一种类型转换为另一种类型。 例如,int 可以接收一个浮点数并将其转换为整数(总是向下取整)。

auto
42.9.int()      // 结果是 42

float 可以将整数转换为浮点数。

auto
42.float()      // 结果是 42.0

现在,有一个容易混淆的地方。 如果你把一串数字放在引号里会怎样?

auto
"126"

它看起来像数字,但实际上是字符串。 如果你尝试像数字一样使用它,可能会得到错误。 如果你有一个包含数字的字符串,可以使用 int 将其转换为整数。

auto
int("126") / 3     // 结果是 42.0

如果你有一个包含数字和小数点的字符串,可以使用 float 来转换。

auto
float("12.6")      // 结果是 12.6

当你书写较大的整数时,可以使用下划线使其更易读。

auto
1_000_000          // 一百万

Python 程序员注意:

在 Python 中,类型转换是函数调用:int(42.9)、float(42)、int("126")。在 Auto 中,这些是值上的方法调用:42.9.int()、42.float()、int("126")。a2p 转译器会将所有这些转换为标准的 Python 函数调用形式。

Auto 使用小写的 true 和 false 表示布尔值,a2p 会将其转换为 Python 的 True 和 False。

Auto 中的类型转换

工作原理

第一组调用展示了内置函数:42.4.round() 返回 42,42.6.round() 返回 43。abs 函数返回绝对值——(-42).abs() 返回 42。

类型转换部分展示了如何在类型之间进行转换。42.9.int() 通过向下取整(截断)将浮点数转换为整数,结果为 42。42.float() 将整数转换为浮点数,结果为 42.0。

将字符串转换为数字在接收文本形式的数字输入时非常必要。int("126") 将字符串 "126" 转为整数 126。一旦转换完成,就可以用于算术运算:int("126") / 3 产生 42.0。

最后,1_000_000 展示了如何在数字字面量中使用下划线来提高可读性。Auto(和 Python)在计算数字时会忽略这些下划线。

形式语言与自然语言 ​

自然语言是人们说的语言,如英语、西班牙语和法语。 它们不是由人设计的;它们是自然演变的。

形式语言是人们为特定应用而设计的语言。 例如,数学家使用的符号是一种形式语言,特别适合表示数字和符号之间的关系。 同样,编程语言是为了表达计算而设计的形式语言。

虽然形式语言和自然语言有一些共同特征,但存在重要差异:

  • 歧义性:自然语言充满歧义,人们通过使用上下文线索和其他信息来处理歧义。 形式语言被设计为几乎或完全无歧义,这意味着任何程序无论在什么上下文中都只有一个含义。

  • 冗余性:为了弥补歧义并减少误解,自然语言使用冗余。 因此,它们往往比较冗长。 形式语言的冗余较少,更加简洁。

  • 字面性:自然语言充满惯用语和比喻。 形式语言字面意思就是其含义。

因为我们都是在自然语言中长大的,所以有时很难适应形式语言。 形式语言比自然语言更密集,所以阅读它们需要更长时间。 此外,结构很重要,所以并不总是从上到下、从左到右阅读最好。 最后,细节很重要。 在自然语言中可以忽略的拼写和标点小错误,在形式语言中可能会造成很大的差异。

调试 ​

程序员会犯错误。 出于有趣的原因,编程错误被称为bug(缺陷),而追踪和修复它们的过程称为调试(debugging)。

你将遇到三种主要的错误:

  1. 语法错误(syntax error):程序的结构有问题。 例如,在函数调用中省略括号,或者使用反引号而不是引号来表示字符串。 编译器会在运行程序之前检测到语法错误。

  2. 运行时错误(runtime error):程序的语法是正确的,但在运行过程中出了问题。 例如,尝试将字符串除以数字会产生运行时错误。

  3. 逻辑错误(也称为语义错误):程序运行时没有产生错误消息,但它没有按照你的预期工作。

编程,尤其是调试,有时会引起强烈的情绪反应。 如果你正在为一个困难的 bug 苦恼,你可能会感到愤怒、悲伤或尴尬。 提前做好应对这些反应的准备可能会有所帮助。 一种方法是把计算机看作一个员工——它有某些优势(如速度和精度),但也有特定的弱点(如缺乏同理心、无法把握全局)。

你的任务是成为一个好的管理者:找到方法利用其优势,缓解其弱点。 找到方法让你的情绪投入到问题中,而不让你的反应影响你的工作效率。

学习调试可能令人沮丧,但它是一项在编程之外的许多活动中都很有用的宝贵技能。

术语表 ​

算术运算符: 一个符号,如 + 和 *,表示加法或乘法等算术运算。

整数: 表示没有小数部分的数字的类型。在 Auto 中,该类型为 int。

浮点数: 表示整数和带小数部分的数字的类型。在 Auto 中,该类型为 float。

整数除法: 运算符 //,将两个数字相除并向下取整为整数。

取模: 运算符 %,计算整数除法的余数。

幂运算: 运算符 **,将一个数字提升到某个幂次。

表达式: 变量、值和运算符的组合。

值: 整数、浮点数、字符串或布尔值——或者我们后面会看到的其他类型的值。

函数: 执行某种有用操作的命名语句序列。

函数调用: 运行函数的表达式。在 Auto 中,它由函数名后跟括号中的参数组成。

语法错误: 程序中的错误,使其无法被解析——因此无法运行。

运行时错误: 直到程序开始运行后才会出现的错误。

字符串: 表示字符序列的类型。在 Auto 中,该类型为 str。

拼接: 使用 + 运算符将两个字符串首尾相连。

类型: 值的类别。我们目前见过的类型有 int、float、str 和 bool。

操作数: 运算符所操作的值之一。

自然语言: 人们所说的自然演变而来的语言。

形式语言: 人们为特定目的(如表示数学思想或计算机程序)而设计的语言。所有编程语言都是形式语言。

缺陷(bug): 程序中的错误。

调试: 发现和纠正错误的过程。

练习 ​

练习 1 ​

当你学习一个新功能时,你应该亲自尝试并故意犯错。 这样你可以学到错误信息,当你再次看到它们时,就会知道它们的意思。

  1. 你可以使用减号来创建负数,如 -2。如果在数字前放一个加号会怎样?2++2 呢?

  2. 如果两个值之间没有运算符,如 4 2,会怎样?

  3. 如果你调用函数时省略括号,如 42.4.round,会怎样?

练习 2 ​

以下问题给你练习编写算术表达式的机会。

  1. 42 分 42 秒等于多少秒?

  2. 10 公里等于多少英里?提示:1 英里等于 1.61 公里。

  3. 如果你用 42 分 42 秒跑完 10 公里,你的平均配速是多少秒/英里?

  4. 你的平均配速是多少分多少秒/英里?

  5. 你的平均速度是多少英里/小时?

编写一个 Auto 程序来计算并打印答案。

练习 3 ​

思考以下问题,在运行任何代码之前尝试回答:

  1. 765 的类型是什么?

  2. 2.718 的类型是什么?

  3. "2 pi" 的类型是什么?

  4. "126" + "3" 的结果是什么?为什么不是 "129"?

  5. int("126") + int("3") 的结果是什么?

现在编写一个 Auto 程序来验证你的答案。

基于 MIT 许可发布。