你好树莓派-全-
你好树莓派(全)
原文:Hello Raspberry Pi!
译者:飞龙
第一部分:入门
准备使用你的树莓派来探索 Python!你需要一个树莓派和一些其他部件和电缆来进行第一部分。以下是你的购物清单:
-
树莓派 2 型 B
-
8 GB SD 内存卡,预装了树莓派基金会的 NOOBS(新开箱即用软件)
-
带有微型 USB 电缆的 USB 电源(必须提供 1.2 A @ 5 V)
-
USB 键盘
-
USB 鼠标
-
电视或监视器
-
连接到电视或监视器的电缆(关于你的电视或监视器的特定电缆在第第一章中有讨论)
可选项目:
- 树莓派外壳
第一部分将帮助你开始使用树莓派,并让你用 Python 编程启动。在第第一章中,你将设置你的树莓派,学习如何启动(或引导)它,然后查看 Pi 的桌面。在第第二章中,你将开始探索 Python 语言。你将创建你的第一个程序,并学习如何使用 Python 给树莓派下达指令。
到第一部分结束时,你将知道如何启动树莓派。你将能够编写 Python 程序,并与你的 Pi 交互,使其执行诸如计算奶酪汉堡套餐成本和显示愚蠢信息在屏幕上的事情。
第一章:认识树莓派
在本章中,你将学习如何
-
设置你的树莓派
-
在你的 Pi 上安装操作系统——Raspbian
-
查找和打开应用程序
-
在 Python 中编写你的第一段代码
你认为你可以用树莓派做什么?
1. 玩游戏。
2. 看视频。
3. 创建一个视频游戏。
4. 听音乐。
5. 为舞会制作一个声音混合器。
6. 建造一个机器人。
信不信由你,这些都是你可以自己动手做的项目,如果你学会了用 Python 编程,那么你的天空就是无边的。你可以在你的树莓派上实现很多功能,只要你能够编写一个程序来实现它。但在我们谈论这个之前,让我们先看看树莓派,并了解是什么让它运转。
什么是树莓派?
树莓派(有时被称为 Pi),是由英国树莓派基金会发明的一种小型、低成本计算机。它提供了一个易于使用的工具,帮助你学习用 Python 编程(其名称中的 Pi 部分来源于其专注于用 Python 编程)。
大小约等于一副扑克牌,它不像笔记本电脑或台式计算机那样强大;它的计算能力更类似于智能手机。但它缺乏的处理能力,它通过其许多功能来弥补:
-
它在 Python 编程方面的准备情况
-
你可以用它的许多方式
-
它的小尺寸和成本
树莓派及其配套的内存卡预装了所有你需要开始用 Python 编程的软件。输入命令,看看会发生什么。输入你在互联网或杂志上找到的程序,运行它,看看它是如何工作的。树莓派是为了让你通过玩耍、使用和与之交互来学习编码而设计的。
一旦你学会了用 Python 编程,你就可以将树莓派作为各种项目的基石——凭借你的想象力,可能性是无限的!树莓派的小巧尺寸使其便于携带并融入项目。你可以把它藏在架子上,或者装在墙上带摄像头的安全系统中;如果你需要它便携,可以用充电电池组供电;甚至可以把它连接到遥控车上或直升机上。而且如果你不小心弄坏了什么,恢复起来也很简单。即使你弄坏了树莓派,更换起来也很便宜。
核心上,树莓派是一块电路板,它拥有许多计算机中找到的所有组件。下一节将检查树莓派的组件并探讨它们的功能。让我们开始吧!
探索你的树莓派组件:硬件
曾经你用放大镜仔细观察过昆虫,或者拆解过玩具吗?人类天生对事物的工作原理感到好奇。不同的部分是什么,它们的功能是什么?哪些部分是独特的?让我们以同样的方式对待树莓派,探索其组件,并学习如何设置它。
幸运的是,你不需要打开它来查看其组件。你可以在手中的绿色电路板上看到树莓派的组件(见图 1.1)。让我们逐一了解树莓派的组件以及它们的功能。我们将重点关注树莓派 2 型 B 版;如果你有树莓派 1 型 B+或 B 版,请参阅附录 B 获取更多信息。
图 1.1. 树莓派为学习 Python 编程提供了一个极好的平台。它包括许多输入和输出端口,以便你灵活地连接它。就像使用台式计算机一样,在开始使用你的树莓派之前,你需要连接键盘、鼠标、显示器和电源线。

定义一些技术术语
输入 和 输出 是用于计算机通信的术语。
USB 是计算机上常见的连接器。它用于连接键盘、鼠标、闪存驱动器以及许多其他计算机外围设备。
HDMI 是一种将设备连接到高清电视或显示器的标准方式。我们将在讨论如何将电视或显示器连接到你的树莓派时进一步讨论这个问题。
以太网 是一种用于将计算机连接到网络的技术。此端口提供了一种在无线连接不可用时连接到互联网或家庭网络的方式。
给你的树莓派一个舒适的家园:树莓派外壳
我们都喜欢在我们的家中感到温暖舒适。Raspberry Pi 也不例外。做正确的事情,通过将 Pi 放入外壳(见图 1.2)来保护它(图 1.2)。如果你的 Pi 没有附带外壳,你有很多选择。你可以购买一个或者自己制作一个。我最喜欢的做法是从木材、纸板、塑料容器甚至乐高积木中制作自己的外壳。关键是确保你的 Pi 免受意外跌落,理想情况下,避免溅洒。但在你将 Pi 收入外壳之前,让我们先仔细看看它的一些特性。
图 1.2. 一个外壳保护你的 Raspberry Pi 免受损坏,同时使其易于访问端口。有些人使用外壳来给他们的 Pi 增加独特的个性。你可以购买一个外壳,或者更好的是,自己制作一个。塑料外壳是最常见的,但这些图片展示了由纸张、塑料和铝制成的外壳示例。你甚至可以尝试使用乐高积木来制作一个。

你的 Pi 的脑:系统芯片
认识一下你的 Raspberry Pi 的脑。系统芯片(SoC) 是 Pi 电路板中间的黑方块,如图 1.3 所示。图 1.3。这个令人难以置信的芯片是许多部分的组合:中央处理器(CPU)、图形处理器(GPU)、数字信号处理器和 Pi 的工作内存。芯片提供了运行应用程序和播放视频的计算能力、图形能力和内存。
图 1.3. Raspberry Pi 的系统芯片(SoC)包含其计算和图形处理能力以及工作内存。Pi 使用 ARM11 微处理器作为其 CPU,并使用 VideoCore IV 作为其 GPU。ARM11 微处理器存在于手持式电子产品中,如智能手机和游戏系统。Raspberry Pi 2 Model B 中的 SoC 配备了 1 GB 的 RAM。

Pi 的 CPU 负责运行应用程序和执行指令。同样的处理器也存在于智能手机和电子阅读器中。把它想象成你大脑中允许你遵循指令和计算数学问题答案的部分。
GPU 就像你大脑中的视觉部分,允许你在脑海中可视化一个 3D 对象或追踪向你投掷的球。它处理 Pi 的多媒体任务,如处理数字图像、绘制图形和播放视频。GPU 为你的 Pi 提供了令人惊讶的高清视频播放能力。中央处理器和图形处理器共享 Pi 的工作内存,或 RAM,它是 SoC 的一部分。
工作内存:RAM
问题:你能记住以下杂货店清单吗?香蕉、牛奶、花生酱、果酱、面包。再读一遍清单,然后远离书本,尝试从记忆中背诵清单。
为了记住它,你需要将物品的名称保持在你的记忆中。你只需要暂时存储它们。一旦你去商店购买这些物品,你就可以忘记它们了。
当计算机工作时,它做的大同小异。它可能必须每秒记住和处理数百万条指令和信息片段,但一旦处理完毕,它通常会忘记它们。计算机使用工作内存或随机存取存储器(RAM)来完成这项工作。它集成在 SoC 中,并使您的树莓派能够通过在工作时记住信息片段并在不再需要时忘记它们来快速处理指令——这与您大脑中的神经元协同工作以记住购物清单的方式非常相似。稍后,我们将讨论长期存储信息以及信息存储的地方。
连接键盘和鼠标:USB 端口
来认识一下树莓派上的USB端口。每个金属矩形盒子中包含两个 USB 端口,如图 1.4 所示。图 1.4。USB 代表通用串行总线。^([1]) 树莓派提供 USB 端口,以便您连接键盘、鼠标、U 盘和其他 USB 外围设备。
¹
U代表通用,因为它为计算机制造商和计算机设备制造商提供了一种连接到计算机的标准方式。连接到计算机的东西通常被称为外围设备。
图 1.4。树莓派 2 Model B 有四个 USB 端口。它们在板上以两对两的形式并排排列。USB 端口用于将键盘和鼠标连接到您的树莓派。也可以插入 USB 集线器,以允许连接更多的外围设备。

为什么它们被称为端口?
回到古代,当罗马人四处走动并用拉丁语交谈时,门或门的单词是porta。虽然计算机没有门或闸门,但它们有可以插入东西的地方,称为端口。
端口允许电信号进出您的计算机。没有端口,您就无法查看计算机的屏幕、下载网页或移动鼠标。
让我们假设您能够缩小,并且您有特殊的眼镜,可以用来看到这些电信号。当我按下键盘上的 E 键时,您会看到什么?您会看到一个电信号从键盘飞过键盘的线,通过计算机的端口,进入计算机。端口就像一个门,允许信号进入或离开您的计算机。
准备好你的键盘和鼠标。让我们将它们连接到你的树莓派上。
连接键盘
您需要一个可以插入 USB 端口的键盘。图 1.5 展示了带有 USB 连接器的键盘示例.^([2])
²
如果您没有 USB 连接器的键盘,不要担心。您可以在网上或您当地的电脑或电子产品店以低于 15 美元的价格找到它。
图 1.5。您需要一个 USB 键盘在您的树莓派上打字和输入命令。键盘插入树莓派 2 Model B 上的四个可用 USB 端口之一。

要将键盘连接到你的 Pi,请将键盘的线缆插入树莓派的 USB 端口。你的 Pi 上有四个 USB 端口。你选择哪一个都无关紧要。
小贴士
如果键盘的 USB 接口无法插入树莓派的 USB 接口,请翻转接口并再次尝试。USB 接口只能以一个方向插入。
太棒了!你的键盘已经连接到 Pi 上了。现在是时候添加鼠标了。
连接鼠标
对于这一步骤,你需要一个可以插入 USB 端口的鼠标。键盘正在使用你的树莓派的四个 USB 端口之一。将你的鼠标插入另一个端口。
另一个选项:无线键盘和鼠标组合
如果你拥有无线键盘和鼠标组合,你可以将 USB 接收器插入 Pi 的一个 USB 端口,而不是使用线缆。这会释放你的一个 USB 端口,如果你决定连接多个 USB 设备(如 USB Wi-Fi 适配器或 USB 闪存驱动器)或你想要在桌子上减少线缆数量时,这会很有用。
太好了!给你的 Pi 提供存储和检索信息的能力是你的下一个任务。
存储记忆:你的 Pi 获得了一张存储卡
我们都喜欢记住对我们重要的事情。生日、假期和节日都是美好的时光,我们发明了帮助回忆它们的方法。你可能使用剪贴簿或相册来存储记忆。即使经过多年,你仍然可以打开这些书籍并回忆起这些过去的事件。
除了工作内存(RAM)外,计算机还需要一种方式来记住事物,即使它们长时间关闭。树莓派,就像所有计算机一样,具有这种内存存储能力,使其能够保存和检索数据、文件和应用程序。就像相册让你回忆假期一样,树莓派的内存存储允许你存储重要的应用程序和信息。当你学习如何保存 Python 指令集或程序时,你会使用这种能力。
SD 存储卡
树莓派与大多数计算机不同,因为它的内存存储包含在 SD 存储卡中,而大多数笔记本电脑和台式机使用硬盘。文件、应用程序,甚至是 Pi 的操作系统都存储在 SD 存储卡上,无论是你创建的 Python 游戏还是为 Pi 的新音乐播放器应用程序。如果你购买树莓派套件,它将附带一张 SD 卡(见图 1.6)。^([3])
³
有关兼容卡的信息,请参阅
elinux.org/RPi_SD_cards。
图 1.6. SD 存储卡为树莓派提供了存储内存,用于存储所有软件和文件,包括操作系统。树莓派套件附带一张预装了启动 Pi 所需软件的 SD 卡。左边的两张图片显示了 Pi 板底部的 SD 存储卡插槽位置。右边的图片显示了一张插入 SD 卡插槽的 SD 存储卡。

SD 卡有多种尺寸
SD 卡有三种尺寸:全尺寸 SD 卡(最大)、miniSD 和 microSD(最小)。Raspberry Pi 2 Model B 使用 microSD 卡。
你可以通过连接 USB 外设,如 USB 闪存驱动器或 USB 硬盘,为你的 Pi 添加更多存储空间。
NOOBS
你的 Raspberry Pi 套件附带了一张预装了 NOOBS 的 SD 卡。由 Raspberry Pi 基金会开发的新开箱即用软件(NOOBS)是一组文件,可以帮助你首次设置 Pi。如果你丢失了它或需要 NOOBS SD 内存卡,你可以在网上购买新的。或者,如果你有一张 SD 卡并想在上面安装 NOOBS,请访问 Raspberry Pi 基金会网站(www.raspberrypi.org/downloads)了解如何操作。
SD 内存卡插槽
图 1.6 显示了 SD 内存卡插槽的位置。这个薄薄的金属插槽位于 Raspberry Pi 的底部。当你插入时,为了让你的 Pi 工作,它必须有一些初始知识来启动并在屏幕上显示一些内容。除了这些启动信息外,它还必须有一个地方来存储任何新的信息。
将 SD 卡插入插槽
持卡时,让带有金属触点的端面向上并朝向 Pi。将卡片沿板底插入插槽。当卡片被推入插槽时,你会听到一个小咔哒声。卡片通过一个小弹簧机构固定。卡片只能以一种方式插入,所以如果它不合适,就翻过来。如果你需要移除卡片,再次按下它(你会听到咔哒声);然后你可以将其拔出。
替换丢失或损坏的 SD 卡
如果你丢失了 SD 卡,你将失去存储在卡上的信息、应用程序和操作系统。这就像你在家用电脑上丢失了硬盘。你可以轻松地更换卡片,但你需要从头开始。以下是更换卡片的两种选择:
-
在商店购买 SD 卡并重新设置。建议你购买至少有 8GB 存储空间的 SD 内存卡。你可以从 Raspberry Pi 基金会网站www.raspberrypi.org/downloads下载并安装启动软件。参见附录 A 了解如何为你的 Raspberry Pi 制作新的 SD 卡。
-
购买预装了 Raspberry Pi 启动软件的 SD 内存卡。你可以在 Raspberry Pi 基金会网站和在线零售商处找到出售的卡片。
SD 卡使你的 Pi 内存变得便携
如果你的 Raspberry Pi 坏了,你可以移除 SD 内存卡并将其插入新的 Pi。所有你的文件和软件都会在那里。这就像带着你的相册搬到一个新家。记忆在相册中是安全的,随时准备让你享受。
小贴士
你可以为你的 Raspberry Pi 设置多个 SD 卡,并且随时切换它们,以给 Pi 带来完全不同的个性。也许为 Pi 设置一个作为媒体中心的 SD 卡,包括游戏、音乐和视频。为你的 Pi 机器人项目设置另一个 SD 卡。每张存储卡都可以独立设置,具有不同的操作系统、应用程序和文件。更换 SD 卡并重新启动 Pi,你立刻就拥有了一个具有不同特性的 Pi,以满足你的需求。
连接电视或显示器:HDMI 端口
如图 1.7 所示,HDMI端口用于将你的 Raspberry Pi 连接到电视或显示器。HDMI 代表高清晰度多媒体接口。输出提供的是音频和视频的组合信号——这意味着声音和图像都从这个端口输出并传输到你的电视或显示器。如果你想要清晰、清晰的显示,并且你已经拥有高清电视或显示器,那么你将想要使用 HDMI 输出端口将 Raspberry Pi 连接到它。因为 HDMI 输出包含音频和视频信号,如果你的电视或显示器内置了扬声器,那么你的 Raspberry Pi 的声音可以设置为从扬声器输出,而不是通过 3.5 毫米音频输出。
图 1.7. Raspberry Pi 上的 HDMI 端口提供了一种可以连接到电视或显示器的全高清音频和视频信号。使用 HDMI 线缆将你的 Pi 连接到你的电视或显示器。根据电视或显示器上的连接器,你可能需要适配器。

现在你已经了解了 HDMI 端口,让我们看看如何将你的 Pi 连接到电视或显示器。
将你的 Pi 连接到电视或显示器
一旦你决定了要使用的电视或显示器,你需要在电视或显示器上寻找可用的视频输入端口(查看背面或侧面以找到它们)。你看到了哪些端口?不幸的是,制造商经常提供各种不同的端口。把它想象成一场匹配游戏。你的目标是匹配电视上的连接器与 Pi 上的连接器。如果它们不匹配,你需要使用稍后讨论的适配器之一。无论如何,你肯定能解决这个问题。
识别端口并建立连接
花时间研究你的电视或显示器上的连接。尝试识别视频端口,将它们与图 1.8 中的连接器图片进行比较。
图 1.8. HDMI 和 DVI 是现代电视和显示器上常见的视频输入端口类型。使用 HDMI 端口将 Raspberry Pi 连接到电视或显示器最简单。HDMI 提供高清图像,不需要任何适配器或转换器——只需要一根 HDMI 线缆,这通常包含在许多 Pi 套件中。DVI 端口需要特殊适配器才能与 Pi 连接。

本节提供了如何使用 HDMI 或 DVI 端口将你的 Pi 连接到电视或显示器的说明。如果你的电视或显示器有不同的视频输入端口,请查看附录 B 以获取连接它们的技巧。
HDMI
HDMI 端口是一个金属的、大部分是矩形的端口,上面标有HDMI。将一根 HDMI 线从屏幕的 HDMI 端口连接到你的 Raspberry Pi 的 HDMI 端口(见图 1.9)。如果你已经连接了 HDMI 线,你现在可以跳过其他端口在 Pi 上的讨论。
图 1.9. 使用 HDMI 线,可以将 Raspberry Pi 连接到电视或显示器。将线从 Pi 的 HDMI 端口连接到电视或显示器的 HDMI 输入。除了视频外,HDMI 线还包含 Pi 的音频输出,可以通过电视或显示器的扬声器播放。
![01fig09_alt.jpg]
DVI
电视和显示器上的 DVI 端口有多种不同的形式。它们都是带有三排八个方形针孔和一个水平孔或一组孔旁边的矩形端口。如果你已经有了 HDMI 线,解决方案是购买一个 HDMI-to-DVI 适配器。你可以在网上或电脑店找到这些适配器。将适配器插入电脑屏幕的 DVI 端口,然后将你的 HDMI 线插入适配器的背面,另一端插入 Raspberry Pi 的 HDMI 端口(见图 1.10)。
图 1.10. 使用 HDMI-to-DVI 适配器和 HDMI 线,可以将 Raspberry Pi 连接到带有 DVI 端口的电视或显示器。HDMI 线的一端插入 Pi 的 HDMI 端口。另一端连接到适配器,适配器连接到电视或显示器。适配器可以通过在线零售商或当地电脑店购买。
![01fig10_alt.jpg]
另一个解决方案,而不是使用适配器,是购买一个 DVI-to-HDMI 线。你可以在网上或电脑店找到这些线。将线的 DVI 接头插入你的电脑屏幕,然后将 HDMI 接头插入 Pi 的 HDMI 端口。
太棒了!你已经通过将你的 Pi 连接到电视或显示器完成了一个重要的步骤。
其他端口和连接
你会在你的 Raspberry Pi 上找到其他端口。我们将在后面的章节中介绍这些端口,或者你可以参考附录 B 以获取有关特定端口和连接的更多信息。以下是一些包括的内容:
-
GPIO 引脚 —Raspberry Pi 上两排长的引脚用于发送和接收电信号。本书的第三部分将介绍如何编程这些引脚和构建项目。
-
互联网 —你可以通过插入以太网线将你的 Raspberry Pi 连接到互联网或家庭网络。但你可能会发现,使用许多 Raspberry Pi 套件中提供的 USB Wi-Fi 适配器上网是最简单的方法。附录 B 有关于以太网端口和使用 USB Wi-Fi 适配器的信息。
-
3.5 mm 音频/视频输出 —这个小圆形插头用于插入耳机或带电源的扬声器。第八章将向您展示如何将 Raspberry Pi 变成音乐播放器时播放声音。
让我们看看如何为您的 Pi 供电。
为您的 Pi 供电:microUSB 电源端口
Raspberry Pi 的电源通过位于板角附近的 microUSB 电源端口提供。这是您将电源适配器连接到 Pi 的地方;它与许多手机上的端口相同。Raspberry Pi 套件附带一个 microUSB 电源适配器。
图 1.11. Raspberry Pi 需要至少提供 1.2 安培(A)电流的 microUSB 电源适配器。如果您计划使用 Pi 上的所有 USB 端口,您可能需要一个提供 2 安培(A)或更多电流的适配器。推荐的电压是 5 伏(V),但 Pi 可以在 4.8 伏到 5.2 伏的电压范围内运行。如果您有一个想与 Pi 一起使用的电源适配器,请检查其输出电压和电流,这些信息在充电器的小字中列出。在这个例子中,该充电器的输出为 5.1 伏和 2.5 安培的电流,使其成为 Pi 的合适电源。使用错误的电压或电流不足可能会损坏或摧毁您的 Pi,所以请仔细检查。

注意
只有某些手机充电器可以用来为 Raspberry Pi 供电。该充电器必须产生足够的电流来供电。如果您想走这条路,那么您应该阅读充电器上的详细说明。该充电器必须为 Pi 产生 1.2 安培(A)或更多的电流。
它活着!插入 Pi
在将 Raspberry Pi 连接到电源之前,请通过此快速检查清单:
1. 您确定您的键盘、鼠标和显示器已连接到 Pi 吗?
2. 您是否已打开电视或显示器,并将其设置为正确的输入源?例如,如果您将 Raspberry Pi 插入电视的 HDMI 端口,请确保电视设置为 HDMI 输入。
3. 您是否已将带有 NOOBS 的 SD 卡插入 Pi 中?
一个示例设置如图图 1.12 所示。
图 1.12. 连接外围设备和插入 SD 卡的 Raspberry Pi 的示例设置。键盘和鼠标连接到 Pi 的两个可用 USB 端口。一个 microUSB 电源适配器插入 Pi;另一端放在桌子上,准备插入墙壁。一根 HDMI 线从 Pi 的 HDMI 端口连接到显示器的后面。以太网端口从路由器(未显示)插入一根以太网线。

小贴士
电视和显示器通常允许您连接多个视频源。也许您的电视上有 Wii、DVD 播放器和数字视频录像机。这些电视和显示器有选择显示到屏幕上的输入选项。使用您的电视或显示器的输入选择器设置正确的输入。
好的,如果您已经完成了这三个步骤,那么是时候启动您的 Raspberry Pi 了。将电源适配器插入电源插座,并将微型 USB 连接器插入 Pi。您的 Pi 的指示灯将开始闪烁。享受灯光的美丽光芒——这是您的 Raspberry Pi 正在启动的标志。这也被称为 引导;这是计算机检测连接到它的设备并启动计算机操作系统的时刻(OS)。有些人认为术语 引导 来自于踢马使其开始移动。您可以想象您正在给 Pi 一点“引导”以启动它。
让您的 Pi 运行起来:软件
您已经将 Pi 连接好并准备就绪。现在是时候让它运行起来并做一些有用的事情了——为此,您需要一些软件。
操作系统是一组常见的指令或软件,有助于管理计算机。您可能遇到的一些常见操作系统包括 Microsoft Windows、Apple 的 OS X 和 Linux。所有这些操作系统都控制着您的键盘、鼠标、显示器和其他外围设备的连接。最重要的是,操作系统为您在计算机上安装应用程序并使用它们提供了一个基础。
您的 Pi 套件中附带的 SD 存储卡已经包含了在 Pi 上安装多个不同操作系统的文件。我们将逐步安装 Raspbian 操作系统——Pi 的默认操作系统——并对其进行配置。
安装 Raspbian 操作系统
第一次启动 Raspberry Pi 时,您需要在上面安装一个操作系统,然后配置它以便为您良好地工作。让我们一步步来完成第一个任务:安装操作系统。您将在下一节中进行配置。一旦您连接上 Pi,您将看到用于选择操作系统的 NOOBS 菜单,如图 1.13 所示。
图 1.13. NOOBS 选择菜单允许您选择要安装到 SD 卡并用于 Raspberry Pi 的操作系统。此菜单在您第一次启动 Pi 时出现。

Raspberry Pi 可以安装多种操作系统。Raspberry Pi 基金会推荐使用 Raspbian 操作系统,这也是本书中我们将使用的系统。让我们了解一下如何在您的 Pi 上安装它。
如果您没有看到 NOOBS 软件屏幕怎么办?
如果您在第一次启动 Pi 后没有看到 NOOBS 软件屏幕,那么有一些事情需要检查。
如果您在插入 Pi 时没有看到指示灯闪烁,请确保您使用的电源插座有电。许多 Pi 用户不小心将 Pi 插入电源插座,并忘记了打开电源插座。听起来很傻,但即使是最好的程序员也会犯错误。
如果您在插入电源供应时 Pi 的指示灯闪烁,但您的显示器屏幕上没有显示任何内容,请确保显示器已插入电源插座,HDMI 线已从显示器连接到 Pi,并且您已打开显示器。
最后,如果你的 Pi 开始启动,你在黑色屏幕上看到许多消息,但你从未看到 NOOBS 选择菜单,那么很可能是你的 SD 卡出现了错误。请参阅附录 A 了解修复 SD 卡的方法。
有时你可能会遇到你的 Pi 的问题。如果你遇到了,请使用附录 A 中的故障排除步骤,并在 Raspberry Pi 基金会网站上搜索解决方案^([a])。
^a
Raspberry Pi 基金会网站是www.raspberrypi.org。
在 NOOBS 选择菜单(见图 1.13),按照以下步骤操作:
1. 选择 Raspbian(确保 Raspbian 旁边的框中有 X;如果没有,点击框以选择它)。
2. 点击菜单顶部的“安装”按钮。
3. 出现一条消息,警告你该过程将安装操作系统,并且 SD 卡上所有现有数据将被覆盖.^([4]) 选择“是”以继续安装。
⁴
当你被告知所有数据将被覆盖时,这并不包括 NOOBS,它保留在 SD 卡上,以便你需要在任何时候重新安装操作系统。
4. 等待安装完成。这可能需要 5 到 10 分钟,所以你可以喝点东西或拿点小吃,同时等待。
5. 安装完成后,会弹出一个框,告诉你操作系统已成功安装。点击“确定”,你的 Raspberry Pi 将开始加载 Raspbian。
6. 当它完成加载 Raspbian 后,你的 Raspberry Pi 会自动重启。首先出现一个黑色屏幕,然后显示许多许多消息。不要担心;这些消息是 Pi 执行其启动任务,例如检测键盘、鼠标和电视或显示器。
恭喜你!你已经安装了你的 Raspberry Pi 的操作系统,Raspbian。现在你将想要配置它的工作方式以适应你。
配置操作系统:让它成为你的
你已经完成了在 SD 卡上安装 Raspbian 操作系统,并且第一次运行。接下来你会看到 Raspberry Pi 配置屏幕,如图 1.14 所示。
图 1.14. 当你的 Pi 第一次启动时,你会看到 Raspberry Pi 配置菜单。这个菜单通过允许你更改设置(如时区和键盘布局)来简化 Pi 的设置。菜单还有一个选项,可以将 Pi 设置为始终启动到 Raspbian 桌面环境。

小贴士
你不能使用鼠标来操作这个菜单!请使用箭头键(上、下、左、右)和 Tab 键在菜单中移动。按 Enter 键选择高亮的菜单项。
让我们了解一下你可能想要更改的一些基本配置设置。
更改键盘设置
树莓派在英国制造,因此预设为英国键盘。如果你住在世界其他地方,键盘可能会在屏幕上显示意外的字符。例如,你可能输入一个 # 符号(Shift-3),而你的 Pi 显示的是英镑符号。奇怪,对吧?
你可以使用配置工具通过以下步骤更改 Pi 的键盘布局:
1. 在树莓派配置菜单中,选择选项 4—国际化选项—并按 Enter 键。
2. 选择更改键盘布局,并按 Enter 键。
3. 选择你的键盘型号——例如,戴尔——并按 Enter 键。
4. 你可以看到键盘布局的国家/地区选项。选择适当的地区,并按 Enter 键。
5. 出现键盘布局列表。选择你所在位置的布局,并按 Enter 键。
6. 在接下来的几个屏幕上,你可以设置快捷键。设置成你个人的偏好。如果你不确定,接受默认设置(按 Enter 键直到返回到配置菜单)。
如果需要,你总是可以返回配置工具。你将在后面的章节中学习如何使用命令行模式。
选择你的树莓派启动方式
Raspbian,像大多数操作系统一样,允许你以两种不同的方式使用它(见图 1.15):
图 1.15. 树莓派运行 Raspbian 操作系统的命令行模式(顶部)和图形用户界面模式(底部)的示例屏幕图像。命令行模式是基于文本的:你在提示符下输入指令。图形用户界面几乎与 Windows 或 Mac 界面相同,有窗口、图标和菜单,你可以使用鼠标指针与之交互。

-
命令行模式 —你向操作系统输入命令。这对于新手来说可能有点困难,因为你需要知道命令并准确输入。由于这种模式使用起来更困难,你在这本书中只有在需要运行需要管理员或超级用户权限的命令时才会使用它。例如,当你创建使用 GPIO 引脚的 Python 程序或想要更改 Pi 的配置时,你需要命令行。
-
图形用户界面(GUI)模式 —所有内容都显示在窗口、图标和菜单中,你可以通过点击来与之交互。就像在 Windows 和 Mac 电脑上一样,这将是你与 Pi 和用 Python 编程的主要交互方式。它代表了访问应用程序、文件和文件夹的最自然方式。
问题:你更喜欢哪个选项?
-
你的树莓派启动到一个带有闪烁光标的屏幕,等待你输入命令
-
树莓派启动并显示一个带有应用程序图标排列在屏幕上的桌面,等待你用鼠标指向并点击它们
如果你选择了第二个选项,你可以按照以下步骤将 Raspbian 设置为始终启动到桌面:
1. 在 Raspberry Pi 配置菜单中,选择选项 3—启用启动到桌面/Scratch—and 按 Enter。
2. 选择第二个选项——“在图形桌面以用户‘pi’登录”——然后按 Enter。
太棒了!下次你的 Raspberry Pi 启动时,你将被带到 Raspbian 桌面。
小贴士
如果你决定你更喜欢将 Raspberry Pi 启动到命令行,你总是可以在命令行中输入 startx 来启动 Raspbian 桌面。
| |
小贴士
有时你可能会发现自己在使用 Raspbian 图形用户界面,但你想使用命令行。有一个简单的方法可以改变。你可以通过点击菜单按钮,然后选择附件类别并点击 Terminal^([5)) 图标来在窗口中打开命令行模式。
⁵
Terminal 是 LXTerminal 或 Linux 终端的简称。Raspbian 是基于 Linux 的操作系统,终端 指的是你可以输入命令的命令行模式。
进行其他更改
Raspberry Pi 配置菜单包括其他选项,如设置摄像头和超频。如果你需要使用它们,这些选项都是可用的。查看 Raspberry Pi 论坛以获取有关这些选项的更多信息。
保存配置和重新启动
如果你对你对 Raspberry Pi 所做的更改感到满意,请按照以下步骤退出 Raspberry Pi 配置工具并重新启动你的 Pi:
1. 在 Raspberry Pi 配置菜单中,使用箭头键选择完成,然后按 Enter。
2. 你会看到这条消息:“你现在想重新启动吗?”选择是,然后按 Enter。
当你的 Raspberry Pi 启动时,它会显示许多行文本。(是的,它又这样做了!不要担心,很快这对你来说就会显得很正常。)这是你的 Pi 连接外围设备并启动操作系统时的启动序列。接下来,将出现一个带有 Raspberry Pi 标志的白色屏幕,以及一组图标——这是你的 Raspbian 桌面(见 图 1.16)。恭喜!你的 Raspberry Pi 准备就绪。
图 1.16. Raspberry Pi 启动后 Raspbian 桌面的视图。桌面类似于 Microsoft Windows 或 Apple Mac OS X 的桌面。如果你的桌面与此不同,请不要担心。根据你购买 Pi 的时间,你可能收到了带有较旧或较新版本 Raspbian 的 SD 卡。

面前的 Pi 的一点点:故障排除
如果你没有看到 图 1.16 中显示的视图,不要气馁。这很可能是因为你没有选择启动到桌面的选项。如果你的屏幕显示 Raspbian 的命令行模式 (图 1.17),你可以登录并启动 Raspbian 图形用户界面。
图 1.17. 如果你没有设置你的 Pi 以启动到 Raspbian 桌面,当你的 Raspberry Pi 启动时将显示命令行模式。它会要求你输入用户名和密码。

在命令行中,你会被提示输入你的登录名和密码。默认登录名是 pi,密码是 raspberry。输入这些信息后,使用以下步骤从命令行启动 Raspbian 桌面:
1. 输入
startx。2. 按 Enter 键。
执行命令后,树莓派将启动 Raspbian 图形用户界面模式并显示你的树莓派桌面。如果你遇到不同的问题,请参阅附录 A 以获取故障排除思路。
导航:学习 Raspbian
在你的树莓派上四处逛逛,看看随 Raspbian 操作系统预装的一些应用程序。
在你的树莓派上查找和打开应用程序
你的树莓派上有许多应用程序。你可以通过点击桌面左上角的菜单按钮来访问它们(见图 1.18)。享受探索你的 Pi 上预装的内容吧。
图 1.18. 当你在桌面左上角点击菜单按钮时,Raspbian 应用程序菜单会打开。你可以通过将鼠标移到菜单上列出的类别上,然后点击应用程序来打开一个应用程序。

你的文件和文件夹
与 Windows 资源管理器或 Mac Finder 类似,Raspbian 有一些内置的工具,可以让你更容易地在树莓派上导航文件夹和文件。在 Raspbian 中,用于管理文件的程序称为 文件管理器,你可以通过点击 Raspbian 桌面左上角的文件夹图标来访问它。图 1.19 展示了图标和文件管理器应用程序。就像在 Windows 资源管理器中一样,你可以
图 1.19. Raspbian 文件管理器允许你像在 Windows 资源管理器或 Mac Finder 中一样管理文件。你可以通过点击桌面左上角的文件夹图标来访问文件管理器。这是存储在 /home/pi 文件夹中大量文件的树莓派视图。

-
通过双击文件夹进入文件夹。
-
拖动文件将它们移动到另一个文件夹。
-
使用文件和文件夹上的右键菜单复制和粘贴文件。
-
重命名文件。
-
通过双击文件打开它们。
树莓派是为编程而设计的。让我们看看你如何在你的树莓派上编写代码。
编写代码
你将学习如何在 Python 编程语言中编写代码。认识一个新的程序,IDLE。IDLE 是一个帮助你编写 Python 程序的工具。IDLE 代表 Integrated DeveLopment Environment。Python 语言是以 Monty Python 命名的,而 IDLE 这个缩写是对 Monty Python 创始成员之一 Eric Idle 的致敬。
按照以下步骤操作:
点击桌面上的菜单按钮。
选择编程 > Python 3。
几秒钟后,IDLE 会打开 Python Shell,如图图 1.20 所示。
图 1.20. IDLE 是一个开发环境,它使得编写 Python 程序变得更加容易。这是你可以用来逐个输入 Python 命令或指令的 IDLE Python Shell。

注意
之前的 Raspberry Pi 模型在桌面上有 Python 的图标:IDLE 和 IDLE 3。您将在这本书的练习中使用 Python 3(或 IDLE 3)。 在较老的 Pi 模型上,IDLE 3 图标打开 Python 3 的 Python Shell。你可能已经猜到了,没有 3 的 IDLE 图标打开的是 Python 2 的 IDLE。
注意
要从 Raspbian 命令行启动 Python Shell,请输入 python3 并按 Enter。您将看到一个 >>> 提示符,可以交互式地输入 Python 命令。当您完成使用 Python Shell 后,输入 exit() 并按 Enter 以结束您的 Python 会话。
图 1.20 中所示的 Python Shell 允许您输入 Python 命令并按 Enter 执行它们。命令提示符允许您在三个大于号(>>>)之后输入命令。
执行以下操作:
1. 输入
3 + 4。2. 按 Enter 键。
屏幕显示答案:7。尝试一些减法:
1. 输入
17 – 9。2. 按 Enter 键。
屏幕显示答案:8。现在让我们让 Python 通过在屏幕上打印一条消息来与你交谈:
1. 输入
print("I am alive!")。2. 按 Enter 键。
你的屏幕应该显示“我活着!”
了不起的工作!你写了三行代码。当你每按一次 Enter 后,Raspberry Pi 的处理器就会执行这些命令并完成你所要求的事情。这是强大的!
Fruit Picker Extra:在 Pi Store 购物
你的 Raspberry Pi 可以做很多事情。我们在书中包含了特殊部分,称为 Fruit Picker Extras,以教你一些 Pi 可以做的不同事情。这个 Fruit Picker Extra 是关于在 Pi Store 购物的。
Pi Store 是一个在线应用商店,提供对 Pi 的游戏、应用和资源的访问(见图 1.21)。您可以从任何设备浏览 Pi Store,例如手机或笔记本电脑。要从 Raspberry Pi 访问它,请双击桌面上的 Pi Store 图标。如果您想将内容下载到 Pi 上,您需要将 Pi 连接到互联网,并且您还需要使用电子邮件地址和密码创建一个 IndieCity 账户。
图 1.21. 您可以从 Raspbian 桌面上的图标访问 Pi Store。商店允许您浏览和下载包括游戏、教程和数字杂志在内的应用和内容。您将找到免费和付费内容,分为五个类别:游戏、应用、教程、开发工具和媒体。

一些应用是免费的;其他则需要付费。您将找到一些很好的资源,例如免费的 MagPi 期刊,这是 Raspberry Pi 社区杂志,一本充满技巧、项目和编程教程的数字杂志(在 Pi Store 的媒体类别中寻找这些)。尽情享受将免费游戏和教程下载到 Pi 上吧!

挑战
每一章的结尾都会有挑战供你尝试。如果你无法解决它们,请查看书的背面(见附录 C)以获取提示和答案。
寻宝游戏
是时候通过寻宝游戏来探索你的树莓派了。目标是通过对周围环境进行观察、打开应用程序并与之互动来了解更多关于树莓派的信息。尝试完成以下寻宝物品清单:
1. 找到一个松鼠吃其他松鼠的游戏。你能获得“Omega Squirrel”的称号吗?提示:双击 Python Games 桌面图标来寻找它。
2. 在你的树莓派上找到一个计算器应用程序。计算一个数学问题的答案:87x34。提示:计算器在菜单>附件中找到。
3. 在不拔掉你的树莓派的情况下,你能想出如何关闭或重启它吗?
4. 将你的桌面背景设置为黑色。
5. 加分:打开 Scratch,尝试让一只猫跳舞。
想象自己是一名官方的树莓派探险家。如果你想,可以花更多的时间点击一些图标,看看它们的功能。你已经取得了很大的成就!
摘要
树莓派在很多方面都与其他计算机相似,但也有一些重要的差异。与其他计算机的相似之处包括以下:
-
树莓派需要键盘、鼠标和显示器,就像其他台式机一样。这些设备的接口是树莓派的一部分。
-
树莓派可以配置为桌面操作系统 Raspbian,它与微软 Windows 或苹果 OS X 类似。
-
尽管它的计算能力有限(类似于智能手机),但树莓派仍然可以让你做许多在台式机或笔记本电脑上做的事情,比如浏览网站、玩游戏和听音乐。
树莓派具有使其特殊和独特的品质和能力。与其他计算机相比,以下是一些关键差异:
-
树莓派的成本和尺寸都较小,使其成为项目的理想选择。
-
树莓派是为 Python 编程而设计的,并预装了 Python 开发环境,这样你就可以立即开始编码。
-
树莓派使用 SD 存储卡来存储所有文件和软件,包括操作系统。
-
它有 GPIO 引脚可以发送和接收电信号。在这本书的第三部分中,你将学习如何使用这些引脚创建与周围世界交互的项目。
第二章。探索 Python
在本章中,你将学习如何通过使用 Python 与你的树莓派进行交互
-
快速轻松地进行数学计算
-
使用变量存储信息
-
让消息显示在屏幕上
-
在 Python 中创建并运行你的第一个程序
编程的有趣之处在于让计算机与你互动。这是让计算机感觉具有人工智能的第一步。
玩 Python
学习编程的最好方法之一是通过探索和玩耍。当你玩耍时,你会尝试做一些事情并观察会发生什么。通过体验编程的行为并看到结果,你可以学习。在这种方法中,你会尝试输入不同的命令并观察会发生什么。
通过点击菜单按钮并选择你的树莓 Pi 桌面上的“编程 > Python 3”,打开 Python 3 的 IDLE(见图 2.1)。点击后,你需要等待几秒钟,直到 IDLE 打开。
图 2.1. 你的树莓 Pi 上的 Python 3 图标打开一个交互式编程 Shell,用于 Python 3.x。

注意
在你的桌面上的“菜单 > 编程”下,既有 Python 3 图标也有 Python 2 图标。请确保你点击的是 Python 3 而不是 Python 2。
Python 3 图标打开 IDLE.^([1]) 你会看到一个提示符,准备接收你的命令——这就是 Python Shell(见图 2.2)。在 Python Shell 打开的情况下,让我们看看如何使用 Python 与你的树莓派进行交互。
¹
树莓 Pi 预先安装的 Python 版本可能因购买时间而异。截至本文撰写时,大多数树莓派都配备了 Python 版本 3.2.3。
图 2.2. 在树莓 Pi 桌面上的“菜单 > 编程”下打开 Python 3 应用程序,它会打开 IDLE 并进入 Python 3.x 的 Python Shell。

发现 Python 的数学运算符
编程语言的核心能力之一是进行数学运算,或者说,用程序员的术语来说,执行数学操作。让我们尝试不同的数学运算,看看哪些可行,哪些不可行。
加法和减法
假设你去了你最喜欢的餐厅,点了一份汉堡、薯条和橙味汽水。你想知道你需要付多少钱。菜单(见图 2.3)上写着汉堡是 5.49 美元,薯条是 1.99 美元,橙味汽水是 1.49 美元。
图 2.3. 你最喜欢的汉堡餐厅的菜单

使用 Python 来计算总额。在 IDLE Python Shell 中输入
>>> 5.49 + 1.99 + 1.49
按下 Enter 键查看 Python 计算结果:8.97,或 $8.97(见图 2.4)。
图 2.4. 在 Python 中使用 + 符号进行加法运算。

好消息:你记得你有一个 3.00 美元的优惠券,所以让我们再次计算总额。在 IDLE Python Shell 中输入
>>> 8.97 – 3.00
结果是 5.970000000000001. 哇!为什么它不是正好 5.97 呢?这是因为计算机如何将数字存储为 1 和 0 有关。我们不会在这里详细讲解,但脚注^([2])中有一个网页链接,你可以了解更多信息。目前,这个数字对于你的计算来说已经足够接近了。
²
在这里了解更多关于十进制数学(也称为 浮点数学)的信息:
docs.python.org/3.4/tutorial/floatingpoint.html。
如你所见,Python 在进行数学运算方面相当出色,并使用熟悉的运算符进行加法和减法:
-
加法运算符(
+)计算两个数字的和:>>> 4 + 5结果是 9。
-
减法运算符 (
-) 计算两个数字之间的差:>>> 8 - 5结果是 3。
Python 风格:运算符和数字的间距
尝试输入 24 加 32,在加号 (+) 和数字之间没有任何空格:
>>> 24+32
然后尝试在它周围有很多空格:
>>> 24 + 32
两者都得到了相同的答案:56. 当你做数学时,数字和运算符之间的空格数量并不重要。Python 忽略额外的空格并计算总和。
最好的方法是什么?嗯,Pythonista(这个名字是给那些用 Python 编程的人起的)认为你的代码应该是易于阅读的。Python 风格指南^([a])建议在数学运算符前后使用空格。你不必这样做,但这样做更容易阅读!
^a
Python 风格指南被称为 PEP 8,可以在网上找到:www.python.org/dev/peps/pep-0008。
让我们看看你可以在 Python 中做哪些其他数学运算。
小贴士
当输入大数字时,不要输入逗号来分隔每三位数字。因此,1000 应该输入为 1000. Python 无法解释数字中的逗号分隔符,所以如果你添加了它们,你会得到一些奇怪的结果。Python 会将逗号解释为你正在输入一个数字列表。例如,12,231 被解释为两个数字的列表:12 和 231。你将在本书的第二部分中了解更多关于列表的内容。
乘法和除法
在狼吞虎咽地吃完汉堡后,你发现自己还想吃两球冰淇淋和一块草莓派作为甜点。冰淇淋每球 $1.79,派每片 $3.50,所以你的总账单是多少?
使用 Python 来找出答案。尝试使用 Python 的乘法运算符 (*):
>>> (2 * 1.79) + 3.50
你的总账单是 $7.08. 你还可以看到你可以使用括号来分组。
你的三个朋友和你一起在餐厅吃饭,每个人都点了甜点。在更多的冰淇淋和派之后,总账单变成了 $33.36. 他们都同意平均分摊账单。使用 Python 的除法运算符 (/) 来计算他们每个人应该支付的价格:
>>> 33.36 / 3
结果是每份 $11.12。这可是很多甜点了!
在吃饱了之后,你观察了 Python 执行乘法和除法以及你可以如何使用括号进行分组:
-
乘法运算符 (
*) 给你两个数字的乘积:>>> 7 * 3.14结果是 21.98。
-
除法运算符 (
/) 可以用来除以两个数字:>>> 40 / 8结果是 5。
-
括号可以用来分组数字,以便它们先被评估:
>>> (3 + 7) * 10Python 的答案是 100。
你认为这会得到什么结果?
>>> 3 + (7 * 10)
如果你猜到 73,你就对了。如果你改变括号的位置,你会得到不同的答案。当我们检查运算顺序时,我们会更多地讨论这个问题。
确定整数和余数
你的朋友告诉你今年还有 19,272 分钟的学校时间。你如何计算出多少小时和分钟?首先,你将 19,272 除以 60,因为一小时有 60 分钟。你会发现结果是 321 小时余 12 分钟。在 Python 中,你有两个运算符可以给出除法总和的整数部分和余数:
-
//(地板除法) 给出整数部分:>>> 19272 // 60结果是 321。
-
%(取模) 给出余数:>>> 19272 % 60结果是 12。
你已经除了一些大数,但让我们看看 Python 如何处理更大的数。
指数
你可能在天文学中学到的一个有趣的事实是,地球到太阳的距离大约是 1.496 × 10⁸ km。让我们用 Python 来表示这个数字。在 Python 中,你使用指数运算符 (**) 如下所示:
>>> 1.496 * 10**8
Python 的答案是 149600000.0 km。
指数运算允许你取两个数 (a, b) 并将一个数提升到另一个数的幂(a^b)。Python 使用两个数之间的指数运算符 (**) 来执行此操作。例如,如果你想将 2 提到三次幂,你会输入
>>> 2 ** 3
结果是 8 (2 * 2 * 2 = 8)。
再试一次:
>>> 122 ** 5
结果是 27,027,081,632 (122 * 122 * 122 * 122 * 122 = 27027081632)。
注意
在 Python 的旧版本中,你可能看到 122**5 显示的结果是 27027081632L。这是因为之前 Python 在表示非常长的整数时会在数字后添加字母 L。
指数运算在解决这类问题时很有用:
-
估算天文距离
-
根据给定的利率计算银行账户余额
-
根据给定的增长率预测动物群体的规模
平方根
你可以通过使用指数 1/2 或 0.5 来找出平方根。这等同于取平方根:
>>> 14400**0.5
结果是 120.0。
挑战:堆叠 Raspberry Pi!
需要堆叠多少个 Raspberry Pi 才能到达太阳?你可以测量你的 Pi,你会发现 Raspberry Pi 的长度为 85.6 毫米或 0.0856 米。首先,你需要将 Pi 的尺寸转换为千米,通过将 0.0856 除以 1000;然后,将地球到太阳的距离除以 Pi 的千米长度(见 图 2.5)。这将给出太阳的距离,以 Pi 的数量表示。
图 2.5。地球到太阳的距离大约是 149,600,000 km。Raspberry Pi 的长度为 85.6 毫米。

将方程输入 Python:
>>> 1.496 * 10**8 / (0.0856 / 1000)
Python 的答案是 1747663551401.8694。这是超过 1700 亿个 Raspberry Pi 连接起来的长度。想想这么多 Pi 真是挺有趣的!
数字类型:整数和浮点数
到目前为止,你已经在计算中使用了整数和小数。在 Python 中,小数也称为 浮点数,或简称为 float。以下是一些浮点数的例子:
1.2
0.00001
3.14159
1000000.01
检查类型
尝试输入以下内容:
>>> type(3.14)
Python 会回答您:<class 'float'>。您刚刚使用了 Python 内置的工具来检查某物的类型。这些内置工具被称为 函数。您稍后会看到更多这些函数。让我们看看这个函数的作用:
>>> type(10001)
你猜到了吗?这返回了 <class 'int'>,其中 int 代表 整数。
到目前为止,您已经输入了数字并执行了计算。但如果你想要更改一个数字,你必须再次输入所有信息。您也没有保存信息的方法——每次都必须查找并输入数字。好消息!有更好的方法。
使用变量存储信息
在编程中,有时存储信息比反复输入信息更容易。变量 提供了这种特殊功能。变量为您提供了一种存储信息并在任何时候检索信息的方法。让我们看看一个例子。
想象一下,您拥有一家披萨餐厅,您的价格如 图 2.6 所示。
图 2.6. 您披萨餐厅的菜单

第一位顾客,丹尼尔点了一份披萨和橙味汽水:
>>> 14 + 1.5
丹尼尔的餐费为 15.50 美元。
第二位顾客,埃琳点了一份披萨、橙味汽水和鸡翅:
>>> 14 + 1.5 + 8
埃琳的餐费为 23.50 美元。
每次您想要计算餐费时,您必须记住或查找每个项目的价格并输入它。想象一下,如果您有一份包含 15 个项目和 100 位顾客的菜单,查找项目和将它们的单价加起来将花费很长时间!您还容易出错。让我们让计算机为您做这项工作。
创建变量并分配值
这是在程序中使用变量的完美场所。变量存储信息以使您的生活更轻松。(我们是程序员,我们喜欢偷懒。至少我们总是在寻找更高效的方法来做事情。)让我们再次这样做,但为每种食品项目创建变量。第一步是定义您的第一个变量并设置其值:
>>> cheese_pizza = 14
让我们仔细看看这段代码是如何在 图 2.7 中工作的。
图 2.7. 变量存储信息,可以创建并分配一个值。等号用作操作符(也称为 赋值操作符),位于变量名左侧和右侧分配给它的值之间。

接下来,让我们为橙味汽水和鸡翅创建另外两个变量:
>>> orange_soda = 1.5
>>> wings = 8.00
在您输入每一行后,屏幕上不会显示任何内容,但 Python 会将变量及其值存储在您的树莓派内存中。
显示变量值
您如何检查变量中存储的内容?就像之前的 type 函数一样,您使用 Python 中的另一个内置函数 print,如下所示:
>>> print(cheese_pizza)
14
打印 并非指用纸张和墨水打印某物。在 Python 中,打印意味着在屏幕上显示某物。
注意
当您在 Shell 中工作时,Python 会显示表达式的结果。但如果你将总和分配给一个变量,Shell 不会显示该值,除非您使用 print。
使用 print,你已经看到 cheese_pizza 中存储了值 14。你应该确信你的变量正在保存你放入它们的信息。
让我们看看你是否能使用变量来计算餐费(而无需查找数字):
>>> meal_cost = cheese_pizza + orange_soda
打印 meal_cost 来查看其值:
>>> print(meal_cost)
15.5
Python 显示 15.5。现在,让我们计算其他餐点的费用:
>>> meal_cost = cheese_pizza + orange_soda + wings
>>> print(meal_cost)
23.5
Python 返回 23.5。当你需要重复计算时,你会更加欣赏变量如何节省你的时间和精力。恭喜你——你正在使用变量来存储信息!
定义
将值放入变量的过程称为 赋值。
在你开始创建大量变量之前,让我们学习命名它们的指南。
变量命名
每个人都遇到过无法辨认他人笔迹的问题。作者可能知道他们写了什么,但你却无法解读。你想要避免变量带来的这种混淆。为了做到这一点,有一套创建清晰变量名的指南——这些名字对你和阅读你代码的其他人来说都是有意义的:
-
不要使用任何空格。相反,使用下划线(
_)。 -
Python 风格指南建议使用小写字母和单词之间的下划线来使你的代码易于阅读。
-
不要以数字开头。
-
不要使用 Python 的任何保留字作为你的变量名(见边栏“注意保留字”)。
这里有一些变量名的例子:
>>> shoe_size = 10
>>> age = 16
>>> favorite_color = 'blue'
>>> first_name = "John"
>>> pizza_slices_eaten = 4
尽量使用有意义的变量名。
注意保留字
Python 中某些单词是 保留的,因为它们是 Python 语言的一部分。你不能将这些单词用作变量的名称:
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise
Python 3.x 保留字被 Python 用于特殊目的,不能用作变量名。
赋值:左边和右边
当你创建一个变量并为其赋值时,将变量的名字放在等号的左边。将你想要设置的值放在等号的右边。让我们创建一个名为 name 的变量并将其设置为“亚瑟王”:
>>> name = "King Arthur"
在这一行中,左边创建了一个名为 name 的变量,并将字符集“亚瑟王”存储在其中。让我们学习更多关于在变量中存储文本的知识。
在变量中存储字符串
生活不仅仅是数字。你可能想要创建显示荒谬信息或屏幕上讲述故事的程序。这些信息是一种称为 字符串 的数据类型。字符串是一组字符。
字符串
Python 允许你在变量中存储一组字符(或字符串)。你已经在“亚瑟王”的例子中使用了字符串。
关于字符串,以下是一些你应该知道的事情:
-
它们必须始终以引号开头和结尾。
-
你可以使用单引号(‘Hi’)或双引号(“Hi”),但不能混合使用(“Hi’):
>>> message = "Greetings Earthlings"或者,使用单引号:
>>> message = 'Greetings Earthlings' -
当数字放在引号内时,它就是一个字符串。
-
字符串可以是短的(零个或只有几个字符)或很长的。
-
字符串甚至可以是空的。这些被称为 零长度字符串:
my_string = ""
字符串的例子
一些字符串的例子会给你一个关于可能性的概念:
"Y"
"No"
"Spam"
"Yeah, remarkable bird the Norwegian Blue"
"There he is!"
"No, no sir, it's not dead. It's resting."
"17"
"RUNAWAY, RUNAWAY, RUNAWAY!"
"Tuesday"
测量字符串的长度
你可以使用 len 函数让 Python 告诉你字符串的长度。我们将在第三章中更多地讨论字符串函数,但这里是一个使用 len 的例子:
>>> your_nickname = "Pi Master"
>>> len(your_nickname)
9
或者尝试一个更长的:
>>> quote = "To be, or not to be, that is the question."
>>> len(quote)
42
在确定字符串长度时,空格也被计算在内。这是一个讨论空格的好点。
空格计数
虽然空格可能看起来没什么,但它们被认为是字符。你可以创建单个空格或一组空格的字符串,例如
short_set_of_spaces = " "
long_set_of_spaces = " "
你现在已经了解了变量和字符串,字符串是一种可以存储在其中的数据类型。让我们看看你如何改变你的变量。
改变变量的值
如你所猜,存储在变量中的值可以更改或更新。试试看。你正在为你的电脑设置一个密码。创建一个变量 password,并将其设置为 bunny:
>>> password = "bunny"
现在让我们将密码更改为 dragon:
>>> password = "dragon"
你认为存储在 password 中的值是什么:“bunny”还是“dragon”?让我们使用 print 函数检查值:
>>> print(password)
dragon
显示了值 dragon。注意 Python 如何在将新值赋给变量时替换存储在变量中的值。
将变量可视化成盒子
将其可视化的一种方法是想象创建一个变量就像制作一个盒子——一个用于存储信息的盒子。当你创建这个盒子时,你给它起一个名字,并在其中存储一个值。图 2.8 是创建变量并将其重新赋值的图形表示。
图 2.8。当创建变量时,它存储在你的树莓派内存中。你可以随时更改变量的值。使用 print 函数,你可以在屏幕上显示变量的值。

在 Python 中改变变量的值很容易。让我们看看另一个例子。
变量重新赋值
让我们看看 Python 如何评估这些语句:
>>> x = 10
这将 x 设置为值 10。接下来,你用 x 做一个计算,并将计算结果存储在 x 中:
>>> x = x * 10 + 32
当 Python 计算这一行时,它首先处理等号右边的表达式:
1. Python 计算等号右边的表达式:
x * 10 + 32。2. Python 获取
x的当前值,10,并计算10 * 10。3. Python 将 32 加到这个数上。等号右边的数是 132。
4. 它最后计算等号左边的表达式。结果是 132,存储在等号左边的变量
x中。
你已经看到了 Python 可以使用变量存储和检索信息。变量可以节省你的时间,因为它们持有它们被赋予的值,这意味着你不必记住值或查找它们。变量可以是数字或字符串的形式,你可以使用 print 函数检查存储在变量中的值。
太棒了!你已经看到了变量赋值的顺序为什么很重要。检查一下数学运算的顺序是如何重要的。
运算顺序
你认为如果你输入以下内容,Python 会返回什么?
>>> (3 * 2) * 5**3 / 25 + 10
如果你猜到 40,你是对的。Python 遵循你在数学课上学习的运算顺序。
小贴士
你可能还记得学校里学过的 BOMDAS 或 PEMDAS。这个字母模式对于记住在数学方程中评估运算的顺序很有用。Python 遵循相同的运算顺序:括号(或括号),指数(或阶数),乘法和除法,然后是加法和减法。
首先评估括号或方括号中分组的内容。3 * 2 等于 6。让我们将 3 * 2 替换为 6 并进行下一步:
>>> 6 * 5**3 / 25 + 10
接下来分析指数(或阶数)。5**3 等于 125(与 5 * 5 * 5 相同):
>>> 6 * 125 / 25 + 10
乘法和除法接下来,并且从左到右进行。6 * 125 是 750。750 / 25 是 30:
>>> 30 + 10
最后一步是加法和减法。30 + 10 等于 40。图形上,图 2.9 显示了数学中解决示例方程的顺序以及 Python 如何处理它。
图 2.9。Python 遵循数学中使用的运算顺序。你可能知道它是 BOMDAS 或 PEMDAS:括号(或括号),指数(或阶数),乘法和除法,最后是加法和减法。

你在 Python 中做数学题做得相当不错。你准备好学习更多关于如何使用 Python 在屏幕上通信和显示文本的知识了。
在屏幕上显示文本
与技术互动并让它做出回应很有趣。这可以表现为计算机的俏皮回应,使其感觉更像人类。或者计算机的回应可以更实用,在网站表单上显示个人信息。在两种情况下,你希望你的计算机与你沟通。
在屏幕上显示文本,也被称为 Python 中的 打印,是计算机直接与你沟通的一种直接方式。你可以使用打印让你的树莓派做类似这样的事情:
-
显示随机、愚蠢的消息。
-
在冒险游戏中描述神秘场景。
-
输出复杂数学问题的答案。
将信息打印到屏幕上是一种输出各种信息的关键方式。
使用 print 函数
在本章的早期,你使用了 print 函数来显示变量的值。让我们再来了解一下如何使用 print 函数。尝试像这样将消息“Hello World!”打印到屏幕上:
>>> print("Hello World!")
Hello World!
仔细看看你如何在 图 2.10 中使用 print 函数。Python 将“Hello World!”打印到 Python Shell。
图 2.10. Python 中的print函数在屏幕上显示文本。括号内的字符串必须用单引号或双引号括起来。

重复文本
让我们尝试一些不同的东西。输入
>>> message = "Hello, I am your Raspberry Pi!"
>>> print(message)
这将在屏幕上打印一次消息。你可以使用乘法运算符与字符串一起打印多次:
>>> print(message * 100)
消息在屏幕上横向和纵向重复 100 次(见图 2.11)。
图 2.11. 如果你使用字符串和乘法运算符(*)与 Python 的print函数一起使用,它可以重复显示文本在屏幕上。

享受这个过程。尝试一些更大的数字和不同的消息,看看你会得到什么。
故障排除
我们都是人类,所以在按键和输入代码时可能会出错。在创建存储字符串的变量时,你可能忘记关闭引号:
>>> message = "Hello, I am your Raspberry Pi!
注意到感叹号后面的引号缺失了。这听起来可能有些滑稽,但想想引号就像拥抱。当你拥抱某人时,你会用双臂环绕他们。一个字符串必须用引号包围才能完成。如果你在 Python Shell 中运行这段代码,你会收到一个错误,如图 2.12 所示。
图 2.12. 记住要在字符串的开始和结束处放置引号。如果你忘记关闭引号,Python 将显示一个错误。

Python 显示一个错误消息(SyntaxError: EOL while scanning string literal)。你可以通过再次输入带有前后引号的字符串来修复它。
创建程序
再次想象你拥有一家披萨店,并且你想使用 Python 来计算包括税费在内的餐费。一位顾客点了一份两片披萨和橙汁。让我们先创建两个变量来记录菜单价格:
>>> pizza_slice = 3.5
>>> orange_soda = 1.50
创建两个变量来跟踪披萨片和饮料的数量:
>>> num_slices = 2
>>> num_drinks = 1
接下来让我们计算不含税的餐费:
>>> meal_no_tax = (num_slices * pizza_slice) + (num_drinks *
orange_soda)
定义 5%的税率,并计算税费:
>>> tax = 0.05
>>> meal_cost = meal_no_tax + (meal_no_tax * tax)
>>> print(meal_cost)
8.925
现在想象如果其中一个或多个数字发生了变化。比如说披萨片现在是$4.75,橙汁是$1.75。你不得不再次输入所有信息。这会花费太多时间。
更好的方法是把八个语句放入一个文本文件中。然后你可以告诉 Python 读取文件并执行指令。
定义
程序是一组指令。Python 程序可以创建在文本文件中。程序可以反复运行(或执行)。
现在你可以反复运行程序,并在需要时进行更新。如果菜单项目的价格发生变化或顾客想要不同数量的披萨片,你可以更新程序并再次运行。这将节省大量时间!
计算机程序是一组指令。到目前为止,您已经使用 Python Shell 逐个输入命令。程序允许您创建、保存和运行更复杂的指令集。您可以轻松地编辑您的程序并再次运行它们。您的程序可能只有几行,也可能有数千行长。
使用 IDLE 编写 Python 程序
编写程序需要一种输入指令的方法。IDLE 将是您选择的程序。IDLE 是一个使开发程序更简单的应用程序。
Python 的拼写检查器
如果您曾经使用过 Microsoft Word 或 Gmail,您应该熟悉拼写检查器功能。它已经拯救了成千上万的家庭作业免于得到低分,并阻止了拼写错误的电子邮件被发送。每个程序都会突出显示您拼错的单词,这样您就可以轻松地找到它们并进行更正。
当您编写程序时,您希望有一些东西可以帮助您捕捉错误。IDLE 就是这样为您做的。IDLE 会自动为您的 Python 语句着色,以便您知道您正在使用正确的拼写。通过使用着色,IDLE 可以帮助您在输入命令错误时发出警报,并突出显示错误或错误。在后面的章节中,我将向您介绍 IDLE 的一些功能。
集成开发环境
其他编程语言也有类似于 IDLE 的软件应用程序,可以使编程过程更加愉快,帮助防止错误,甚至提出修复建议。这些软件应用程序统称为集成开发环境(IDE)。IDLE 是 Python 中最受欢迎的 IDE 之一。
使用文本编辑器
除了 IDLE,您还可以在任何您喜欢的文本编辑器中编写和保存 Python 程序。例如,您可以使用 Leafpad 或 Nano,它们是 Raspbian 附带的简单文本编辑器。请注意:它们允许您编写,但它们不会帮助您避免错误或找到代码中的错误,这使得 IDLE 成为一个更好的选择。
开始新程序
让我们创建我们的第一个程序。在 IDLE Python Shell 中使用时,选择文件 > 新窗口。您将看到一个空白的新窗口出现,顶部标题为“未命名”(见图 2.13)。这是 IDLE 文本编辑器。
图 2.13。顶部窗口是 IDLE Python Shell。底部窗口是 IDLE 文本编辑器,可以用来创建和编辑 Python 程序。您可以通过按 Ctrl-N 或从 IDLE Python Shell 中选择文件 > 新窗口来打开 IDLE 文本编辑器。

小贴士
打开新 IDLE 文本编辑器的快捷键是 Ctrl-N。
让我们在 IDLE 文本编辑器中编写一个程序。输入以下文本行:
message = "And now for something completely different."
print(message)
小贴士
文本编辑器会自动突出显示 Python 语言中的关键字。在这个例子中,您会注意到print以紫色文本出现,表示它是一个 Python 关键字。字符串以绿色着色。
这是从《蒙提·派森的飞行马戏团》中的经典台词。节目以这句台词开始。图 2.14 显示了 IDLE 文本编辑器中的程序。
图 2.14. IDLE 提供了一个文本编辑器,帮助你编写 Python 程序。编辑器突出显示单词以帮助你编写程序并识别错误。此程序在屏幕上打印一条消息。

现在你已经编写了一个程序,你将想要保存它,以便你可以稍后打开、运行和编辑它。
保存程序
要保存程序,选择 File > Save。一个保存对话框出现。将文件命名为 FirstProgram,然后点击保存(见图 2.15)。默认情况下,文件将保存到你的/home/pi 文件夹。如果你愿意,你可以为你的 Python 程序创建一个文件夹。
图 2.15. 使用 File > Save 菜单选项或按 Ctrl-S 保存程序。默认保存位置是/home/pi。当文件保存时,其名称末尾会附加.py,表示它是一个 Python 程序。

小贴士
保存程序的快捷键是 Ctrl-S。
注意
当你点击保存时,程序将保存到你的/home/pi 文件夹,扩展名为.py。你可以使用文件管理器打开你的/home/pi 文件夹,查看你保存的文件:FirstProgram.py。
当使用 Python 文本编辑器时,你可以通过点击 Run > Run Module 运行程序,或者按 F5。当你这样做时,IDLE Python Shell 成为活动窗口,你将看到打印到 Shell 的消息(见图 2.16)。
图 2.16. 你可以从 IDLE 文本编辑器运行程序。在 IDLE 中运行程序会在 Python Shell 中显示程序的结果。这通过显示一条消息展示了你的第一个程序的输出。

Python 解释程序
当你运行你的程序时,Python 会打开文件并解释每一行文本。第一行创建一个名为message的变量,存储值为“And now for something completely different。”你的程序的第二行调用 Python 的print函数,并将变量message传递给它以输出到屏幕。太棒了——你将在本书的下一部分继续构建更多程序。
水果采摘者额外内容:创建文档
本节特别介绍教你新且不同的事情,你的树莓派可以做什么。这部分额外内容是关于创建文档的。
写下愚蠢的事情并保存它们
让我们从创建一个简单的文本文件并保存它开始。使用树莓派来完成作业可以非常有趣。也许你会写一个描述你最新游戏想法的文档,或者创建一个短篇故事集。与其使用父母的电脑或纸笔,不如使用你的树莓派。
幸运的是,Raspbian 自带一个名为 Leafpad 的应用程序。它是一个用于创建文本文档的轻量级软件程序。
在 Leafpad 中创建文本文件
创建 Leafpad 文档的简单步骤如下:
1. 点击桌面左上角的菜单按钮。
2. 将鼠标悬停在“附件”上。
3. 找到“文本编辑器”,并点击它。这将打开 Leafpad。
4. 在 Leafpad 窗口中输入:
I'm a lumberjack and I'm okay!(见图 2.17)。图 2.17. Leafpad 是 Raspbian 附带的一个文本编辑器。您可以从“附件”菜单访问 Leafpad。
现在您已经创建了文件,让我们保存它(见图 2.18):
1. 选择“文件”>“保存”,或使用键盘快捷键 Ctrl-S。
2. 出现一个窗口,您可以使用它来保存文件。您需要选择您想要保存文件的文件夹。点击标有 pi 的文件夹。这是您个人的文件夹,您可以在其中保存文件。
3. 在名称框中,输入
lumberjack作为文件名。4. 点击“保存”按钮。
图 2.18. 在 Leafpad 中保存文件让您可以选择保存的文件夹并输入文件名。保存窗口的工作方式与您在 Microsoft Word 中保存文件的方式类似。

恭喜!您已将 lumberjack 文件保存到 Raspberry Pi 的内存卡中,位于此处:\home\pi(这意味着文件保存在主文件夹中,并在名为 pi 的子文件夹中)。文件包含您输入的句子:“我是一个伐木工,我很好!”。现在可以关闭 Leafpad。
Nano:命令行文本编辑器
Leafpad 使用窗口,因此仅从 Raspbian GUI 中可用。但如果您决定更喜欢使用 Raspbian 命令行,有一个方便的文本编辑器叫做 nano,您可以使用。在命令行中输入 nano 并按 Enter 打开 nano。Nano 使用键盘控制来打开、保存和关闭文件。以下是一个 nano 文本编辑器的示例:

您必须使用键盘,而不是鼠标,在 nano 中进行选择和执行操作。例如,Ctrl-X 退出 nano。一旦您习惯了使用命令键来导航,nano 如果您决定更喜欢使用 Raspbian 的命令行模式,将非常有用。
查找已保存的文件
您已保存文件。现在让我们看看您是否可以使用文件管理器找到它并再次打开它:
1. 打开文件管理器。
2. 点击左侧标有 pi 的文件夹图标。
3. 查看窗口中列出的文件夹和文件。注意,在顶部,pi 文件夹位于 \home\pi。这意味着 pi 文件夹位于 Raspberry Pi 的 SD 卡上的 home 文件夹中。
4. 在文件列表中找到 lumberjack 文件,并双击它(见图 2.19)。
图 2.19. 使用文件管理器查看文件夹内容
Leafpad 将打开,您将看到您输入的消息。现在让我们关闭 Leafpad 并学习如何输入一些代码。
享受制作文档和探索 Pi 可以做的其他事情!

挑战
尝试这些挑战,这些挑战将测试您对数学运算符、打印和变量的使用。
矩阵
使用 print 函数,创建一个类似于流行计算机图形中的 1 和 0 的级联屏幕。提示:记得你如何使用 print(message * 100) 在屏幕上显示一条信息 100 次。图 2.20 展示了这种效果的一个例子。
图 2.20. 尝试使用 print 函数和字符串来创建一个全屏的 1 和 0。

矩阵挑战是关于创建一个全屏的数字。尝试其他数字和字符。
建造砖墙
对于这个挑战,创建一个名为 brick 的变量,并在其中存储一个字符串,当反复打印时,会使你的屏幕变成砖墙(参见图 2.21)。
图 2.21. 这个挑战使用 print 函数和一个名为 brick 的字符串在屏幕上创建砖墙图案。

你的目标是找出应该存储在名为 brick 的变量中的字符串,以便实现这个显示。祝你好运!奖励:你能让你的砖块看起来更像覆盆子,或者让它们包含 RPi 以代表 Raspberry Pi 吗?
Pi 电子
对于这个高级挑战,让我们检查从电源流入你的 Raspberry Pi 的电流。然后,让我们看看你是否能以每秒流入 Pi 的等效电子数量来表示那个电流。
小贴士
你可能已经了解到,电流是电荷通过某一点的量度。一安培(或安培)的电流等于每秒流过一库仑的电荷。
你的 Pi 所使用的电流量取决于你使用了多少个 USB 端口,但让我们假设你的 Pi 正在使用一安培。一安培相当于每秒流过 1 库仑的电荷。一个电子的电荷为 1.60 × 10^(-19) 库仑(或 0.000000000000000000160 库仑)。需要多少个电子每秒才能等于流进你的 Raspberry Pi 的 1 安培?提示:你可以将电子的电荷表示为 1.60 * 10**-19。
对于挑战的提示和解决方案,请参阅附录 C。
概述
编程是关于能够与计算机交互和通信的能力。你的 Raspberry Pi 配备了 IDLE,这是一个用于 Python 编程的开发环境。Python 提供了两种不同的编程方式:
-
通过交互式地一次输入一个命令使用 Python Shell。Shell 对于快速计算或测试命令很有用。
-
通过创建保存在文件中的程序或命令集。程序允许你反复编写、编辑和运行你的代码。
你可以与你的树莓派进行的第一场对话之一就是使用 Python 进行数学交流。Python 提供了一套完整的数学运算符,你可以使用它们。当你需要在程序中执行计算时,如跟踪屏幕上玩家的位置,数学运算符就非常方便。另一种交互方式是使用 Python 内置的print函数在你的树莓派屏幕上显示文本。这让你能够创建在计算机和你之间进行通信的程序。
编程中的一个重要思想是使用变量来存储信息——它们为你节省时间,可以反复使用。在 Python 中,变量可以存储不同类型的数据,包括整数、浮点数(小数)和字符串。使用变量,你可以存储信息并在任何时候检索它。这是一个关键优势,因为它意味着你不必记住值;Python 会为你处理。你还可以更改变量的值,当你想要用不同的输入运行相同的指令时,这是一个非常有用的功能。
第二部分. 与 Python 玩耍
Minecraft、Pac-Man 和超级马里奥兄弟都是优秀的游戏,它们都是由像您这样的程序员创造的。您将需要获得更多技能才能制作出那样的游戏,但您可以快速创建一些基本游戏。所有这些游戏都让游戏玩家与计算机互动。计算机被编程为具有 逻辑:控制游戏如何对玩家的选择做出反应的指令。游戏不断响应用户的输入,无论是按钮点击还是按键。
游戏是学习编程的好方法,因为它们将创造力、乐趣和逻辑思维结合到一个项目中。游戏也是交互式的,需要用户做出选择,并使计算机对这些选择做出响应。目标是使游戏有趣,因此您将使用您的创造力和想象力为您的游戏增添魔力。您决定如何编程您的游戏以及它如何响应!
在 第二部分 中,您将使用 Python 和您的 Raspberry Pi 创建自己的交互式游戏。您将从 第三章 开始,制作一个创建荒谬句子的程序。您将学习如何使用 Python 请求用户输入信息,将信息存储在变量中,并使您的 Pi 响应。第四章 将深入探讨如何创建一个使您的 Pi 更智能的猜谜游戏:它将根据玩家的选择做出简单的决定。您还将了解如何使用 Python 使您的 Raspberry Pi 反复执行某些指令。第五章 中,您将戴上头盔和头灯,进入地下洞穴。您将创建一个基于文本的游戏,玩家可以选择去哪里;根据他们的选择,他们可能会找到财富或面临不幸的死亡。
第三章. 荒谬句子生成器 3000:创建交互式程序
在本章中,您将了解如何使用 Python
-
为游戏创建一个欢迎信息
-
在您的代码中添加注释
-
请求用户输入(或键入)信息并使用变量保存它
-
连接字符串
-
根据该信息将信息显示回用户
访问一个网站、启动游戏系统或打开移动应用程序,它可能会要求您输入姓名和电子邮件地址并创建密码。这些都是计算机程序,一旦您登录,它们可能会在屏幕顶部显示特殊消息,例如“欢迎,Aaron”(或您的名字)。一些程序非常复杂,会记住您玩过的游戏、获得的徽章、账户余额或查看过的产品。
iTunes、Netflix、Facebook 和 Gmail 都是使用计算机程序来询问您信息、保存信息并根据这些信息与您互动的网站。在本章中,您将了解如何使用 Python 创建一个荒谬有趣的单词游戏,名为 Silly Sentence Generator 3000。
创建欢迎信息
在 Silly Sentence Generator 3000 中,游戏玩家(也就是你)被要求输入诸如名词、动词、形容词等单词。你将把这些单词存储为变量,然后使用它们来创建荒谬、不合逻辑的句子。图 3.1 展示了完成程序的一个示例。
¹
如果你曾经玩过疯狂填词游戏,这很相似。
图 3.1. Silly Sentence Generator 3000 要求用户输入他们的名字和一些单词,然后从这些单词中创建一个荒谬的句子。
![03fig01_alt.jpg]
把程序想象成一个接收一组输入并创建输出的机器。你将通过创建驱动它的指令来组装这个机器。从概念上讲,这个“机器”可能看起来像图 3.2。改变你输入的单词,你会得到一个完全不同的结果。这就是游戏如此有趣的一部分原因!
图 3.2. 一个交互式游戏让你输入信息,然后创建输出。
![03fig02_alt.jpg]
让我们看看如何创建这个游戏。一旦创建,你可以随意修改和添加。
开始一个新的程序
如果你打开一个游戏,你看到的第一件事可能是一个主菜单或标题屏幕。让我们利用你关于在屏幕上显示文本的知识来让你的程序显示一个游戏标题。你首先打开 IDLE 并创建一个新的程序。通过点击菜单按钮,在树莓派的桌面上选择编程 > Python 3 来打开 IDLE for Python 3(见图 3.3)。
图 3.3. 选择菜单 --> 编程 --> Python 3 以在树莓派上打开 Python Shell。
![03fig03_alt.jpg]
给你的树莓派一点时间来打开 IDLE。IDLE 打开后,你会看到 Python Shell(见图 3.4)。
图 3.4. Python Shell
![03fig04_alt.jpg]
按下 Ctrl-N 或选择文件 > 新建窗口以打开 IDLE 文本编辑器。你会看到一个空白窗口,准备好让你开始输入你的程序(见图 3.5)。
图 3.5. IDLE 文本编辑器是你可以输入你的 Python 程序的地方。你也可以使用菜单选项来编辑、保存和运行程序。
![03fig05_alt.jpg]
使用你在第二章中学到的 print 函数,让我们制作一个标题屏幕:
print("*" * 48)
print("* Welcome to the Silly Sentence Generator 3000 *")
print("*" * 48)
极好。请随意详细说明欢迎信息和不同角色的艺术作品。在你继续之前,你应该保存程序。
保存程序
通过选择文件 > 保存或按 Ctrl-S 来保存程序。这将打开一个窗口询问你想要将程序保存到哪个位置以及如何命名它。让我们命名为 SillySentence(见图 3.6)。默认情况下,IDLE 将你的文件保存到 /home/pi 文件夹。让我们使用那个文件夹。
图 3.6. 将您的文件保存为 SillySentence。这样会将文件存储在您的 Raspberry Pi 的 /home/pi 文件夹中,以便您运行程序并对其进行修改。

点击保存,文件将保存为 SillySentence.py(.py 文件扩展名由 IDLE 自动添加)。保存文件后,文本编辑器窗口顶部的标题将显示文件名和文件位置,如图 3.7 所示。
图 3.7. 您的程序的前三行使用 print 函数创建 Silly Sentence Generator 3000 程序的欢迎信息。

猜测输出。您认为运行程序时会得到什么?
让我们试试。点击运行 > 运行模块(或按键盘快捷键 F5)。Python 将读取您程序的每一行并执行命令。这些命令在屏幕上打印一行 * 字符,欢迎信息,以及另一行 * 字符(见图 3.8)。
图 3.8. 运行程序 SillySentence.py 在屏幕上显示一条欢迎信息。

太棒了!现在您为您的游戏有了合适的欢迎信息。接下来,您需要从游戏玩家那里收集一些输入。一些游戏使用按钮点击,但您将在这个游戏中使用键盘。
从命令行运行程序
运行程序的另一种方式是从 Raspbian 命令行。您可以通过在菜单中找到的终端应用程序访问命令行,即菜单-->附件。一个窗口将打开,显示以下提示:
pi@raspberrypi ~ $

要在命令行中运行 Silly Sentence 程序,请输入
pi@raspberrypi ~ $ python3 SillySentence.py
下一个图显示了此命令及其结果。请注意,您在命令行中得到了相同的输出。

命令行是运行 Python 程序的另一种选项。在这本书的第三部分中,您将看到一些程序需要您从命令行运行它们,因为您必须在 Raspberry Pi 上以超级用户身份运行它们。
在您的代码中添加注释
想象一本没有文字的漫画书。仅从图片中,您可能很难理解正在发生的事情。也许如果您足够长时间地研究这本漫画,您可能能够弄清楚,但文字对于理解故事非常重要。代码行可能就像一本没有文字的漫画书:您知道正在发生某事,但您可能无法不猜测就能知道。
正因如此,程序员发明了添加注释的想法。注释 是代码中的注释,用于解释正在发生的事情。它们既是为了您,也是为了可能阅读您代码的其他人。您可以使用注释来解释您为什么编写这个程序以及程序的部分是如何工作的。
使用标签进行注释
您可以通过在行首添加一个标签(#)和一个空格,然后输入您的注释文本来添加注释。让我们在 Silly Sentence Generator 3000 的开头添加注释,以解释程序标题、其目的以及谁编写了它。
列表 3.1. 给您的程序添加注释

注释对阅读代码的人类很有帮助。但 Python 在运行您的程序时会忽略注释。您可以通过保存您的程序并再次运行它来检查这一点;您会发现您得到的结果与之前相同。
Easter egg:Python 的禅意
Python 在 Python 风格方面有一个隐藏的惊喜。在计算机程序中,这些惊喜有时被称为 Easter eggs。您可以通过在 Python Shell 中输入 import this 并按 Enter 键来找到这个蛋。屏幕上会出现一首名为“Python 的禅意”的美丽诗歌。

诗歌强调了 Python 的哲学。其中一些谈论了高级主题,但许多行讨论了适用于任何使用 Python 的人的编码方式。第七行捕捉了 Python 中的一个伟大想法:“可读性很重要。”使用简单、易于阅读的指令编写程序,比试图将步骤混合在复杂、长的代码行中要好。在回到您的项目之前,尝试做一些深度的冥想 Python 呼吸。
Python 的创造者 Guido van Rossum 表示,代码的阅读频率比写作频率更高。² 可读性是编程中极其重要的部分,也是 Python 程序风格的一个指导原则。注释是保持代码易于阅读和理解的重要方式。
²
查看由 Python 创造者编写的资源 PEP 8——Python 风格指南:
legacy.python.org/dev/peps/pep-0008。一个名为“愚蠢的一致性是小智者的妖怪”的精彩部分讨论了可读代码的重要性。
注释是您的新朋友,它们会使您的代码易于阅读。您将在收集游戏玩家(或用户)的信息并创建一个愚蠢的句子时继续使用它们来为代码添加注释。
获取和存储信息
要从用户那里获取输入,您可以使用 input 函数。让我们在您的程序中添加一行代码,询问用户他们的信息并将该信息存储在变量中。
列表 3.2. 从玩家那里收集输入

当您使用 input 函数时,它会显示一个提示并等待用户的回复。用户输入一些内容并按 Enter 键后,信息将存储在等号左侧的变量中。
在 IDLE 编辑器中,input 以紫色高亮显示,表示它是 Python 中一个函数的名称。让我们仔细看看 input 函数,看看它是如何工作的(参见图 3.9)。
图 3.9. input 函数向用户显示提示信息。提示信息“请输入您的名字:”告诉用户您希望他们输入或输入的内容。在这种情况下,您是在询问他们的名字。

在等号右边,调用input函数,并打开一组括号。你可以给input函数一个字符串作为提示。这是显示在屏幕上的消息,告诉用户“嘿,请输入一些内容”——但更加礼貌!确保你的字符串以引号("")开头和结尾。
通过按 F5 或选择运行 > 运行模块来运行程序。程序显示欢迎消息,然后显示带有闪烁光标的输入提示。Python 正在等待你的输入:它需要你输入一些内容并按 Enter 键。
在等号左边是存储信息的变量的名字。当你输入一些内容并按 Enter 键时,你输入的值的值将作为字符串存储在变量player_name中。
Python 2.X
input函数在 Python 2.X 中是raw_input。
连接字符串
就像其他应用程序和网站一样,你希望用户感到受欢迎,所以让我们使用他们的名字并给予他们适当的问候。屏幕上显示的友好消息可能是
"Hello, Ryan! Let's make a silly sentence!"
为了营造个人化的感觉,你需要创建一条将用户的名字与一些欢迎词结合在一起的消息。你使用加号(+)符号来连接字符串:
message = "Hello, " + player_name + "! Let's make a silly sentence!"
如果player_name等于“Melissa”,则消息等于
"Hello, Melissa! Let's make a silly sentence!"
将此添加到你的程序中,并使用print将消息显示在屏幕上。
列表 3.3. 使用+连接字符串

程序让用户输入他们的名字,这个名字存储在变量 player_name中。在下一行,通过连接字符串创建了一条消息。这条消息显示在屏幕上,为游戏创建个性化的开始。
更多字符串工具:字符串方法
为了让生活更简单,Python 包含了一些用于处理字符串的内置工具。这些工具与之前看到的函数类似,但它们被称为方法。以下是一个将字符串的第一个字母大写的示例方法:
"jOHn".capitalize()
capitalize方法将“jOHn”转换为“John”。
Python 有一整套内置的方法。字符串的一个方法是lower方法,它将字符串转换为全部小写:
"RABBIT".lower()
这使得“RABBIT”变成了“rabbit”。
另一个方法,upper,将所有字母转换为大写:
"king Arthur".upper()
upper方法非常适合大声喊叫。它将“king Arthur”转换为“KING ARTHUR”。
这些方法可以节省你的时间^([a]),并使你更容易完成任务。
^a
你可以在在线 Python 文档中了解更多关于可用字符串方法的信息:
mng.bz/9z49。
方法与函数
方法是一种函数类型,但它们使用点符号。这意味着你在项目后面放一个点(.),然后是方法的名字。如果你的项目是“John Cleese”并且你想使用的方法是lower,你会写成
"John Cleese".lower()
括号跟在方法名后面。你需要在括号中放入方法所需的所有输入。你可以在网上查看 Python 文档,看看需要什么。
一些方法不需要任何输入,比如字符串方法capitalize、upper和lower。但有些方法,比如count,需要输入。想象一下,你有一套测试答案,用T代表正确,用F代表错误,你想要计算正确答案的数量。你可以使用count:
>>> TestAnswers = "TTTFFFTTTFTFFFFTTTFFTT"
>>> TestAnswers.count("T")
12
测试中有 12 个正确答案。
让我们更进一步,添加更多的输入。
使用多个输入
你的游戏开始了,这是一个美好的开始。现在你需要从玩家那里收集多个输入。让我们先请玩家给出一个名词——一个著名人物的名称:
famous_person = input("Enter the name of a famous person: ")
接下来,你应该再获取一些单词:
adjective1 = input("Enter an adjective: ")
adjective2 = input("Enter another adjective: ")
verb = input("Enter a verb ending in –ING: ")
使用这些多个输入,你的代码现在应该看起来像以下列表。
列表 3.4。从玩家那里收集多个项目

你多次使用input函数从用户那里收集一组单词。每个单词都存储在等号左边的变量中。尽量使用有意义的变量名;这样以后更容易记住你存储了什么。
构建句子
现在,让我们通过使用+来连接单词来为你的“愚蠢句子生成器 3000”创建句子:
silly_sentence = ("The " + adjective1 + " " + player_name + " is " +
verb + " the " + adjective2 + " " + famous_person)
让我们更仔细地看看图 3.10 中的这一行代码,看看发生了什么。
图 3.10。silly-sentence是通过连接一系列字符串创建的。这些字符串是你输入的,并用引号括起来的字符串,以及从游戏玩家那里收集并存储在变量中的字符串的组合。括号是必需的,因为代码太长,无法放在一行中。

在等号右边,括号括住了要连接以创建句子的字符串。它们使用+运算符连接(或连接)。因为这一行代码太长,你可以使用一组括号将其分成两行。Python 建议将所有行限制在不超过 79 个字符,这样代码就可以很容易地阅读。查看等号左边,你会看到结果字符串存储在名为silly_sentence的变量中。
尤其令人兴奋的是,这段代码会在用户输入不同的单词时创建不同的句子。因为你使用了变量,并且变量存储了用户的输入,所以这真是一个愚蠢的句子生成器!
故障排除
在编写代码时,很容易犯错误,称为错误。讨厌错误。为了追踪并修复它们,你需要调试你的代码。调试万岁。你可能忘记关闭一组引号,你可能遗漏了一个括号,或者你可能拼错了单词。让我们看看你可能犯的一些常见错误以及如何修复它们。
在最后一个部分,你使用了+来连接字符串和存储字符串的变量。看看这个有错误的代码:
silly_sentence = ("The + adjective1 + " " + player_name + " is " +
verb + " the " + adjective2 + " " + famous_person)
你看到问题了吗?第一个字符串("The"”)缺少关闭引号("The "`)。如果你运行这个程序,Python 会输出错误(见图 3.11)。给缺少关闭引号的字符串添加关闭引号,然后保存你的程序并再次运行。
图 3.11。如果你忘记关闭字符串周围的引号,当你尝试运行程序时,Python 会给你错误。Python 会在红色中突出显示有错误的行。检查每个字符串以找到并修复错误。

你可能犯的另一个常见错误是拼写变量名错误或使用不同的首字母大小写。这是相同的一行代码,但这次有一个拼写错误的变量和一个大小写错误的变量。你能找到它们吗?
silly_sentence = ("The " + adjectve1 + " " + player_name + " is " +
verb + " the " + adjective2 + " " + Famous_person)
第一个是adjectve1,应该是adjective1(缺少i)。第二个错误是Famous_person,应该是famous_person(F应该小写)。如果你运行这个程序,你会看到的错误显示在图 3.12 中。
图 3.12。编程中的一个常见错误是拼写变量名错误或使用不正确的大小写。显示的错误说程序的第 25 行有问题。错误类型是NameError: name 'adjectve1 ' is not defined。

小贴士
变量的拼写和大小写必须始终相同。如果你将变量命名为my_number,然后后来输入my_nomber或My_number,Python 会给你一个错误。
通过修正adjectve1的拼写使其变为adjective1来纠正错误。修正后,你仍然会收到错误,但这次是因为Famous_person的大小写错误(NameError: name 'Famous_person' is not defined)。将Famous_person的大小写更改为famous_person。一旦你进行了修正,保存程序并再次运行。
你已经调试了你的程序。做得好!
完成程序:显示愚蠢的句子
你已经制作了你的愚蠢句子,并希望 Python 将其显示给玩家。使用print语句打印它,但像你的欢迎信息一样,让我们给它添加一些活力!
print("*" * 48)
print(silly_sentence)
print("*" * 48)
猜猜它做什么?它在屏幕上打印一排字符(星号)48 次。然后显示句子,并再次打印一排符号 48 次。尝试其他字符或字符模式,看看哪个看起来对你来说更好!
它看起来相当不错,但你可以做得更好。通过运行程序来测试你的程序,你会注意到符号的数量与句子的长度不匹配。你编程使其显示正好 48 个星号——不多也不少。相反,让我们更新这些行,使符号重复以匹配愚蠢句子的长度。你将使用另一个内置的 Python 函数len,它计算字符串的长度并返回一个数字,告诉你字符的数量:
print("*" * len(silly_sentence))
print(silly_sentence)
print("*" * len(silly_sentence))
好多了!让我们一起看看代码(见图 3.13)。
图 3.13. Silly Sentence Generator 3000 是一个有趣的程序,展示了程序如何从用户那里收集信息,与他们互动,并提供更个性化的体验。

你已经完成了你的程序。让我们进行一些最后的测试,看看它能做什么!见图 3.14 以查看游戏的输出示例。
图 3.14. Silly Sentence Generator 3000 基于你输入的单词生成一些荒谬的句子。

太棒了!你可以自由地更新代码以添加更多的形容词、动词或名词。你已经学会了如何从计算机用户那里获取输入,并通过在屏幕上显示消息与他们互动。
水果采摘器额外功能:Minecraft Pi
在这个水果采摘器额外功能中,你将探索 Pi 的另一个独特功能:它有自己的 Minecraft 版本。多亏了 Minecraft 制造商 Mojang 和 Raspberry Pi 基金会的合作,Raspberry Pi 上提供了一款免费、精简版的 Minecraft。自 2014 年 9 月以来,这个版本被称为 Minecraft Pi,并自动与 Raspbian 操作系统一起安装。
什么是 Minecraft?
Minecraft 是一个发生在由方块组成的 3D 虚拟世界中的游戏。在最基本层面上,你四处跑动采矿(通过击打方块来挖掘)和制作物品(在游戏中组合物品以制作新物品)。你还可以在这个虚拟世界中使用不同类型的方块来建造东西。
启动 Minecraft Pi
在菜单>游戏下寻找 Minecraft Pi 图标(见图 3.15)。如果你在 2014 年 9 月之前获得了 Pi,请参阅第六章侧边栏“更新你的 Pi”以了解如何更新 Raspbian。
图 3.15. Minecraft Pi 是基于 Minecraft Pocket Edition 的精简版免费 Minecraft。与完整版本相比,它有所限制,但仍然非常有趣!

点击 Minecraft Pi 图标以打开游戏。一个 Minecraft 窗口将会打开(见图 3.16)。它有点古怪——你会在 Minecraft 窗口后面看到一个黑色窗口,但这很正常。
图 3.16. Minecraft Pi 主屏幕允许你开始单人游戏或加入多人游戏。多人选项允许你连接到其他人的世界,但你需要在同一网络中。

点击“开始游戏”开始游戏。接下来,点击“创建新游戏”创建一个新的世界。加载完成后,你将发现自己在一个方块世界中(见图 3.17)。每个世界都不同,所以你可能看到树木、水、泥土或任何数量的环境。
图 3.17. 每个 Minecraft 世界都是由方块组成,但各不相同。你可能会发现自己在一个森林里或沙漠中。屏幕底部显示了你背包中的物品。使用鼠标滚轮选择不同的物品,或者按键盘上的数字 1-9。

在 Minecraft 中,你是一个可以使用以下控制键四处走动的玩家:
-
W —向前移动。
-
A —向左移动。
-
S —向后移动。
-
D —向右移动。
-
空格键 —跳跃。
-
鼠标移动 —四处查看或转身。
-
Escape —退出游戏。
除了基本操作外,这里还有一些你可能需要的其他动作:
-
空格键两次 —飞到空中(双击空格键然后按住以飞起)。按左 Shift 键向下移动。如果你在飞行,双击空格键以回到地面。
-
E —显示你可以使用的方块和物品的游戏库存(与游戏的完整版本相比有限)。将你想要的物品拖到屏幕底部的下方小方块中。按 Esc 键隐藏库存屏幕。
-
滚轮或数字 1-9 键 —从屏幕底部底部的玩家库存位置中选择一个物品。选中的物品现在在你的手中供你使用。
一旦你掌握了移动的方法,使用鼠标左键来挖掘或破坏方块。使用鼠标右键放置方块或使用手中的工具。当你准备离开时,按 Esc 键退出游戏。
小贴士
要退出 Minecraft Pi,按 Esc > 退出到标题,然后点击角落的 X 来关闭窗口。
Python 编程接口到 Minecraft Pi
Minecraft Pi 有一个有趣的材料和工具库存——甚至还有一把剑!更好的是,Minecraft Pi 有一个 Python 编程接口。前往 Raspberry Pi 基金会网站了解更多关于如何使用 Python 与 Minecraft Pi 交互的信息。
探索世界,挖掘地下基地,或建造一个树屋。你将做什么?

挑战
尝试这些挑战,看看你是否可以使用input函数和字符串创建一些有趣且交互式的项目。
骑士故事创造者 3000
在这个挑战中,尝试使用你关于输入(收集文本)和输出(显示文本)的知识来创建一个骑士故事生成器。这里有一个你可以使用的模板故事:
曾经有一位勇敢的骑士,[player_name],被派去消灭[adjective]的恶棍,[famous_person]。骑着他/她的可靠的[animal],勇敢的[player_name]穿越到遥远的[travel_place]。[player_name]使用他的[sharp_thing]勇敢地与[famous_person]的军队战斗,直到击败他们。胜利归来,[player_name]大声喊道,“[exclamation]!!!”我代表 Python 声称[travel_place]的土地。
括号中的单词是为了在程序中创建的变量;你需要让玩家输入这些单词。记得使用+来连接字符串,创建一个独特的骑士故事,然后将故事打印到屏幕上。祝你好运!
潜意识信息
潜意识信息是一种隐藏的信息,试图让人们思考你希望他们思考的事情。常用于电视广告,这是一种与朋友和父母尝试以获得你想要的东西的绝佳技巧.^([3]) 在这个挑战中,尝试创建一个隐藏在大量字符显示中的信息。信息应该通过询问人的名字、他们想要的东西的名字和字母、数字和符号的模式来构建。在你的程序中,你应该创建一个信息,说“你真的很想给[玩家名字]买一个[东西]”,并将其隐藏在一个字符模式中。图 3.18 显示了示例。
³
在自己的风险下使用潜意识信息(给瑞恩送披萨!)。如果人们知道你试图操纵他们的思想,他们可能会用他们自己的潜意识信息进行反击。
图 3.18. 潜意识信息挑战是在屏幕上的一堆字符中隐藏一个秘密信息。你能看到隐藏的信息吗?

在这个例子中,隐藏的信息是,“你真的很想给瑞恩买一个玉米卷。”要狡猾一点,看看你能否找到一种方法来创建和隐藏一个潜意识信息!
概述
在本章中,你学习了如何编写交互式程序,从一个人那里获取信息并提供娱乐性回应:
-
使用
input函数从一个人那里收集文本输入。使用变量和等号来存储人们输入的信息。以下是一个要求用户告诉你他们最喜欢的颜色并将其保存到名为favorite_color的变量中的示例:favorite_color = input("What is your favorite color?") -
通过在行首添加一个井号(
#)和一个空格来为你的程序添加注释:# A comment tells you about the code # They help you read the code, # but they are ignored by Python -
使用
+来连接字符串。 -
当你需要连接超过单行的字符串时,请使用括号:
name = input("What is your name?") favorite_color = input("What is your favorite color?") message = ("Your name is: " + name + " and your "+ "favorite color is: " + favorite_color)
你创建的游戏使用相同的思想从用户那里收集信息,并以他们每天在网站、移动应用和游戏中看到的方式与他们互动。
第四章. 挪威蓝鹦鹉游戏:为程序添加逻辑
在本章中,你将学习如何创建 Python 程序,
-
显示一个介绍
-
从用户那里收集输入
-
使用
if语句以不同的方式对用户做出响应 -
使用
while循环来重复做某事 -
使用 Python 代码库生成随机数
打开一个流行的游戏,如 Minecraft,或者想想一个机器人,如火星漫游车。两者都是计算机程序。它们有什么共同点?它们都有从输入中获取信息并对其进行处理的的能力。它们所做的事情取决于它们所接收的输入。在游戏中,如果你按前进并从悬崖上掉下来,你的角色就会掉下来死去。如果你只剩下一条命,那么你就会被带到游戏结束屏幕。同样,火星漫游车可能会被指示前往某个位置,但如果它检测到前方有一个大石头,它就会停止或尝试绕过障碍物。
游戏的工作逻辑或漫游车移动的逻辑被编程进去。但您如何在程序中创建这种逻辑呢?您将通过制作一个关于特殊鹦鹉——挪威蓝鹦鹉的简单猜年龄游戏来学习如何做到这一点。
显示游戏介绍
挪威蓝鹦鹉是一种虚构的鹦鹉,是蒙提·派森最著名的喜剧片段之一的主旨。^([1)] 您的游戏是假装您正在参观一个出售挪威蓝鹦鹉的宠物店。店主挑战您猜测鹦鹉的年龄(见图 4.1)。如果您猜对了,那么您可以免费带回家这只鹦鹉。
¹
如果您还没有看过,请查看这个维基百科页面,其中包含了这个喜剧片段的音频录音:
zh.wikipedia.org/wiki/Dead_Parrot_sketch。
图 4.1. 挪威蓝鹦鹉有着美丽的羽毛,是猜年龄游戏的绝佳主题。
![04fig01.jpg]
每次玩游戏时,程序都会选择一个介于 1 和 20 之间的不同随机数作为鹦鹉的年龄。游戏玩家有五次机会猜测鹦鹉的年龄。如果玩家猜对了,游戏会显示一条有趣的祝贺信息,恭喜他们赢得了他们新鹦鹉。如果玩家猜错了,程序会显示一条善意的侮辱,就像它对玩家的猜测感到冒犯一样。如果玩家在五次尝试内没有猜对,他们就会输,宠物店老板会告诉他们鹦鹉的真实年龄(见图 4.2)。
图 4.2. 游戏逻辑可以用文字表达。问号表示游戏需要逻辑来做出决定。此图还显示了需要重复的代码,因为玩家有五次猜测机会。每个决定都有简单的真/假或是/否答案。
![04fig02.jpg]
当这个游戏完成时,您将能够玩它。输出将类似于图 4.3。在示例中,玩家前四次猜测都不正确;但在第五次尝试时,他们猜对了。他们赢了,店主给了他们这只鹦鹉。
图 4.3. 挪威蓝鸟猜年龄游戏是关于尝试猜测宠物店里一只鸟的年龄。
![04fig03_alt.jpg]
创建游戏欢迎信息和说明
让我们从打开 Python 3 的 IDLE 并创建一个新的程序开始。通过点击您的树莓派桌面上的菜单 > 编程下的 Python 3 图标来打开 IDLE(见图 4.4)。
图 4.4. 点击 Python 3 图标,在您的树莓派上打开 IDLE 的 Python 3 Shell。
![04fig04_alt.jpg]
给您的树莓派几秒钟的时间来打开 IDLE。您将看到 Python Shell。按 Ctrl-N 或文件 > 新窗口来打开 IDLE 文本编辑器。您将看到一个空白窗口,准备好让您开始输入程序。
让我们在文本编辑器的程序顶部输入一些注释。每行以一个井号(#)和一个空格开始。
列表 4.1。在你的新程序顶部创建注释
# Title: The Norwegian Blue Parrot Guessing Game
# Author: Ryan Heitz
# The goal of the game is guess the age of a parrot.
# The program generates a random age between 1 and 20.
# The player gets 5 guesses to guess the age correctly.
# If they're correct, they win the parrot!
将单词改为你喜欢的。注释是你和可能与你分享程序的人的笔记,所以让它们以你想要的方式阅读。记住,避免注释超出屏幕——保持每行不要太长。每行不超过 79 个字符是良好的风格;这确保了你的美丽 Python 程序可以适应窗口,并且不需要用户滚动或调整窗口大小。
提示
你可以通过使用光标位置信息来跟踪你的光标所在的行和列(见图 4.5)。它显示在文本编辑器的右下角。字母Col代表列:这显示了光标从屏幕左侧的距离。左侧是 0,中间是 40,右侧是 80,以此类推。
图 4.5。一旦保存了文件,窗口顶部将显示文件名和文件存储在 Raspberry Pi 上的位置(/home/pi/NorwegianBlue.py)。光标位置始终显示在窗口的右下角。

在 IDLE 文本编辑器中的程序现在包含几行注释。在你继续之前,保存你的工作:按 Ctrl-S 保存程序。将弹出一个窗口,你可以命名并选择保存文件的位置。在文件名文本框中,输入文件名:命名为NorwegianBlue。当你点击保存按钮时,文件将以 NorwegianBlue.py(.py 扩展名由 IDLE 自动添加)保存,并存储在 Pi 的 SD 内存卡上的/home/pi 文件夹中.^([2]) 程序保存后,文本编辑器将在窗口顶部显示文件位置和文件名(见图 4.5)。
²
你可以在新文件夹中创建一个用于存储你的 Python 程序。通过打开 Raspbian 文件管理器应用程序并选择文件 > 创建新 > 文件夹来创建文件夹。就像你的鞋子一样,你想要记住你存储程序的地方,这样你就不必花太多时间寻找它们。
接下来,你需要让用户知道你的游戏名称和玩法说明。使用 Python 的内置print函数编写几行代码,在屏幕上显示标题。
列表 4.2。在屏幕上显示标题

在玩家看到标题后,你需要让他们知道接下来要做什么。你应该为游戏设置场景并提供说明。让我们创建一个名为instructions的变量,并存储描述如何玩游戏的句子。就像在第三章的 Silly Sentence Generator 3000 中一样,这个变量将包含几个句子长度的字符字符串。
你不想在一行中输入一个超级长的字符串,你希望使用一种更整洁的方式来保持字符串在屏幕上,并且限制其宽度不超过 79 个字符(记住,好的 Python 风格是保持文本在屏幕上)。在 Python 中,你可以使用字符串字面量来做这件事。
定义
字符串字面量 是可以包含多行文本并且当它们在屏幕上显示时,会精确地按照你在文本编辑器中输入的样子显示的字符串。字符串字面量保留了行与字符之间的空格。要创建一个字符串字面量,你可以用三个双引号(""")或三个单引号(''')开始和结束字符串。
让我们在程序的注释之后添加一些说明。你将使用字符串字面量来编写说明,并将其打印到显示设备上。
列表 4.3. 包含多行文本的字符串字面量

字符串字面量让你能够以你输入文本编辑器中的样子精确地显示字符串。把它想象成一种“所见即所得”的创建字符串的方式。
用 ASCII art 表达
在桌面操作系统(OS)和游戏拥有高端图形之前,计算机的显示能力有限。计算机用户和程序员发明了一种新的艺术形式,称为 ASCII art,它使用文本字符来制作图像。
ASCII 是一种将字符存储为二进制数字的方式。例如,字母 A 被表示为 1000001。后来的编码支持了更多的字符,以支持更多的语言,但 ASCII art 这个名字保留了下来。ASCII art 使用精心设计的图案中的 95 个 ASCII 字符(字母、数字和符号)来表示图像。
这里有一个例子,展示了如何通过创建一个字符串字面量并将其打印到屏幕上来制作游戏标题的 ASCII art。用一点想象力和试错法来制作你自己的 ASCII art:
bird_art = """
#########################################################################
____
/ 0 \ NORWEGIAN
| >
|UUU) | BLUE
|UUU) |
//UUU) | GUESSING
//UUU) /
//UU) / GAME
//U) /
// -|--|/
==// ==W==W====
//
/
#########################################################################
"""
print(bird_art)
有时候,稍微模糊一下你的眼睛,看看图像是否看起来像你想要的样子,会有所帮助。发挥创意,想想你如何可以使用大写和小写字母来创造效果,比如用U来代表鹦鹉翅膀上的羽毛,或者用W来代表鹦鹉的爪子。
尝试这些 ASCII art 网站,享受乐趣:
-
www.chris.com/ascii —一个按主题分类的 ASCII art 大集合
-
patorjk.com/software/taag—一个文本到 ASCII art 生成器 (TAAG)。你输入文字,它会自动为你创建 ASCII art。 -
picascii.com—一个将图片转换为 ASCII art 的工具
看看你是否能制作一些比这更好的 ASCII art 作为你游戏标题屏幕。享受这个过程吧!
经常测试你的程序总是一个好主意,以捕捉任何错误。现在测试你的程序,看看你得到了什么。标题和说明应该会很好地显示在屏幕上。
当你输入此代码时,你可能会犯的一个常见错误是忘记在字符串开头或结尾处的一些引号。如果你这样做,图 4.6 展示了你在 Python 中会收到的错误示例。
图 4.6. 如果你忘记了开始或结束引号,Python 会显示错误。有错误的行将在你的程序中高亮显示。通过添加缺失的引号修复程序,然后保存并运行程序。

你可能会犯的另一个类似错误是忘记以三重引号开始你的字符串字面量。在这种情况下,Python 会给你一个语法错误消息(见图 4.7)。
图 4.7. 字符串字面量必须以一组三个引号开始和结束。如果你忘记了,Python 会告诉你你有语法错误。添加缺失的三重引号以修复错误。

通过确保字符串字面量开头和结尾有三个引号,可以轻松修复这个错误。使用 IDLE 文本编辑器中显示的高亮来找出导致问题的那一行。
从玩家那里收集输入
你的游戏有一个合适的介绍;现在让我们开始与玩家互动。游戏、网站和应用程序都是关于引起互动的,无论是为了创造一些乐趣还是帮助你在线购买东西。这与你最近看过的电影形成对比。电影没有互动——它们总是相同的。
计算机程序接受输入并响应输入的能力是特殊的。在像你正在创建的基于文本的游戏中,这种交互通过键盘发生。玩家输入答案或做出选择,游戏就会做出响应。
对于这个游戏,你希望让游戏玩家猜测鹦鹉的年龄。程序知道鹦鹉的年龄,并检查玩家的每个猜测是否与之匹配。为了使这起作用,你必须给程序提供鹦鹉的年龄(它存储在一个变量中)。这给了你作为程序员类似神一样的力量——作为游戏的制作者,你可以决定这个值是多少。让我们创建一个变量并将其设置为你要选择的值。作为计算机程序员的一个很好的事情是,只有你知道鹦鹉的真实年龄.^([3])
³
任何其他正在阅读这本书的人!稍后你将让游戏使用一个随机数,即使你也不知道鹦鹉的年龄。
让鹦鹉变老。创建一个名为 parrot_age 的变量,并将其赋值为 19。
列表 4.4. 为鹦鹉创建一个年龄

注意,在注释中包含了一个 TODO 备注:这告诉你你有一个稍后要完成的项。
小贴士
在你的注释中使用 TODO 作为提醒,指出程序中未完成或需要进一步改进的区域。注释是你的朋友,它们在那里帮助你。根据需要使用它们!
接下来,让我们获取用户的第一次猜测。使用 Python 的 input 函数(就像你在第二章中做的那样)从用户那里收集输入并存储在一个名为 guess 的变量中。给 input 函数一个清晰的消息,提示游戏玩家输入适当的值。当你期望他们在 1 到 20 之间输入一个数字时,你不想他们输入 50。在这种情况下,你希望他们猜测一个 1 到 20 之间的数字。
列表 4.5. 获取猜测并将其存储在变量中

在从用户那里收集输入后,你需要将值从字符串(例如,“5”)转换为整数(简单地是整数 5)。默认情况下,游戏玩家输入的任何内容都存储为字符串(即使他们输入的是数字)。图 4.8 以图形方式显示了这一点:你从用户那里收集输入,然后将其转换为整数。int 函数将 guess 变量的值转换为整数,然后将其存储回 guess 变量。
图 4.8. input 函数收集用户输入的文本;然后文本以字符串数据类型存储。你取变量的值(“5”),将其转换为整数(5),并存储为变量。

与人合作的一个危险是,他们可以输入他们想要的任何东西。如果有人输入“one”而不是“1”,你会看到这样的错误:
Traceback (most recent call last):
File "<pyshell#C>", line 1, in <module>
int(guess)
ValueError: invalid literal for int() with base 10: 'one'
这个错误表示你没有给 int 函数提供一个有效的字符串,该字符串可以转换为整数。
如果你将你想要在代码中创建的逻辑与目前的程序进行比较,你会发现你已经完成了几个部分(见图 4.9)。
图 4.9. 左边是你想要创建的逻辑。右边是你的代码。到目前为止,你已经欢迎了用户,并给出了游戏说明。你还添加了收集他们猜测的代码。

太棒了!再次测试程序以确保它正在正常工作。现在它将要求你输入一个猜测。在下一节中,你将看到如何测试猜测是否正确。
使用 if 语句以不同方式响应用户
当你醒来吃早餐时,你可能会走进厨房四处看看有什么可以吃的。你使用逻辑来选择你的早餐。如果你的最爱食物在厨房里,你就会吃它。例如,如果你的最爱食物是巧克力芯片松饼,厨房里有,那么你就会吃它们。如果没有,你可能会吃一碗谷物。在这个例子中,你应用了简单的逻辑——你使用推理来做决定。
计算机程序使用类似的逻辑与用户和周围的世界交互。这些交互基于你(程序员)编写的一组规则。我们作为程序员创建这种逻辑的一种方法是通过称为 if 语句的东西。
在你的游戏中,你想要测试玩家的猜测是否与(等于)鹦鹉的年龄匹配。你想要在代码中创建的逻辑如下:
-
如果玩家的猜测等于鹦鹉的年龄,祝贺他们,并给他们一只挪威蓝鸟带回家。结束游戏。
-
否则(如果玩家的猜测不等于鹦鹉的年龄),显示一条轻微侮辱性的消息,告诉他们猜错了。如果这不是他们的最后一次猜测,让他们再猜一次。如果是他们的最后一次猜测,结束游戏。
让我们在程序中使用if语句来创建你需要的逻辑。
列表 4.6. 使用if语句给游戏添加逻辑

让我们仔细看看if语句是如何工作的,以及它是如何给你在程序中创建逻辑的方法(参见图 4.10)。
图 4.10. if语句可以控制程序的流程。这个例子展示了如何使用if语句在guess等于鹦鹉的年龄时显示一条消息,如果不等于,则显示不同的消息。

关键字if后面跟着guess == parrot_age,并且行以冒号(:)结束。guess == parrot_age是要测试的条件。双等号(==)是一个特殊运算符,用于检查guess和parrot_age的相等性。
小贴士
确保你在测试相等性时不要使用单个等号。单个等号用于将值赋给(或存储)变量。
如果它们相等,if条件将被评估为真,Python 将执行其后的缩进命令。在这种情况下,你将打印一条消息:
Congratulations! You win! Enjoy your Norwegian Blue!
如果猜测错误(guess == parrot_age为假),那么 Python 将执行else部分。else部分要执行的语句缩进四个空格。在这种情况下,如果猜测错误,程序将在屏幕上显示以下内容:
Wrong! You obviously don't know your Norwegian Blues!
如果你检查代码并回想一下你想要创建的逻辑,你可以看到if语句是如何让你检查猜测是否正确的(参见图 4.11)。
图 4.11. 你想要创建的逻辑在代码中显示。你使用if语句来检查玩家的猜测是否正确。

你已经看到了if语句如何让程序做出决策。这是一个通过检查某事是否为真或假来控制程序的一种简单方法。
没有“嗯...也许”
if语句使用一种称为布尔逻辑的东西。在布尔逻辑中,答案必须始终是真或假。没有“嗯...也许”。它总是要么是真要么是假。
布尔逻辑有一套自己的比较操作。这些比较在数学课上应该很熟悉,例如小于(<)和大于(>)。以下是一个表格,列出了你可能需要在你的if语句中使用的一些常见比较:
| 比较操作 | 定义 |
|---|---|
| == | 等于 |
| != | 不等于 |
| < | 小于 |
| <= | 小于或等于 |
| > | 大于 |
| >= | 大于等于 |
对于这个游戏,你使用相等比较来检查两个值是否相等。
如果你需要反转比较中的逻辑,可以使用 not 操作符。not 操作符将 True 变为 False 或将 False 变为 True。如果 x 是 True,那么 not x 就是 False。
记住这些比较运算符。无论你使用哪一个,Python 都会分析比较并返回 True 或 False 的答案。
练习 if 语句
尝试更多 if 语句的例子将帮助你熟悉逻辑和如何编写它们。让我们做一个例子,检查一个秘密密码是否正确。如果是,代码应该允许该人访问;否则,应该拒绝访问。
列表 4.7. 使用 if 语句检查密码

Python 的 if 语句是创建能够按你希望的方式响应的程序的有力工具。你现在有了创建逻辑的能力,让你的程序根据与用户的交互来反应和响应。这是在程序中添加一点人工智能的第一步。做得太棒了!
在使用 if 语句时最常见的错误之一是忘记在末尾放置冒号 (:)。图 4.12 是一个缺少冒号的 if 语句的例子。
图 4.12. 在 if 语句的末尾缺少冒号将会创建一个语法错误。Python 会突出显示错误所在的位置。在行末添加一个冒号来修复问题。

编写程序时,错误是常见的。尽量记住在 if 语句的末尾添加冒号。如果 Python 抛出一个语法错误框并突出显示 if 语句末尾的空格,你就知道你做了什么。
使用 while 循环重复事物
你已经从用户那里获得了输入,但你需要一种方式让用户反复猜测鹦鹉的年龄。你可能觉得反复做同样的事情会感到无聊,但计算机会乐意重复你想要的次数。程序的重复部分被称为 循环。
在你的猜测游戏中,你给游戏玩家五次机会猜测鹦鹉的年龄。Python 有几种类型的循环:你将使用 while 循环。while 循环会重复执行,直到某个条件或情况不再为真。重复什么由你决定。每次通过循环时,在程序重复你给出的指令之前,它会检查那个条件。
让我们看看如何使用 while 循环与 if 语句结合,只给用户五次猜测的机会。为了帮助,你将创建一个名为 number_of_guesses 的变量来跟踪猜测次数。
列表 4.8. 使用 while 循环重复指令


注意你如何必须稍微调整程序中的代码。首先,你开始while循环,然后要求用户输入他们的猜测。还要注意,while循环中要重复的代码是缩进的(向右移动四个空格)。让我们更仔细地看看while循环的关键元素(见图 4.13)。
图 4.13。思考你想要创建的逻辑,然后将其翻译成你的代码。当你需要重复某些内容时,可以使用while循环。当你需要检查某个条件是否为真或假时,可以使用if语句。

while循环有一个特殊之处:你必须缩进所有你想要循环重复的代码(就像你在if语句中做的那样)。每一行应该从左边缩进四个空格(从你输入while中的w的位置开始测量)。同样,当你想要while循环结束时,停止缩进代码。没有缩进的代码位于while循环之外,并且只有在while循环完成后才会执行。
小贴士
IDLE 文本编辑器会自动为你缩进循环文本。在 Python 中,缩进用于将代码分组。
注意,你创建了一个名为number_of_guesses的变量,它有助于跟踪已经进行了多少次猜测。它从 0 开始;每次猜测后,值增加 1。当它达到 5 的值时,如果最后一次猜测是错误的,游戏应该结束。只要猜测次数少于五次,程序将检查玩家输入的猜测是否正确。如果猜测正确,游戏应该恭喜玩家,跳出循环,并结束。
深入了解while循环
while循环会重复执行一系列指令或代码,但只有在while循环的条件为真时才会这样做。当你想要重复某些内容但需要一个表示何时停止的开关时,这非常有用。while循环的一个非常常见的用途是在游戏中。循环使得用户可以反复玩游戏,直到他们表示不想再玩了。
图 4.14 中的while循环从 0 计数到 99。让我们更仔细地看看它的各个部分。
图 4.14。你可以使用while循环重复执行任务。循环中的代码缩进四个空格。在这种情况下,这个while循环显示从 0 到 99 的数字;完成后,它会打印消息,“我完成计数了!”通常,条件应该是这样的,循环中的代码可以使其变为假,从而结束循环。

和if语句一样,while循环有一个表达式,它必须是 True 或 False。图 4.14 中的例子使用了count < 100。这一行以冒号(:)结束,属于循环的后续行应该缩进四个空格。在while循环中,你可以使用你通常在 Python 中使用的任何其他命令。为了表示循环的结束,停止缩进语句。注意,print("I finished counting!")没有缩进,所以它只会在计数完成后打印一次。Python 通过缩进来知道你想要你的循环从哪里开始和结束。
小贴士
你可以在while循环中使用if语句。在你的游戏中,你在一个while循环中使用if语句。听起来很复杂,但你需要检查玩家的猜测是否正确,并且你需要重复这样做以给他们提供五次猜测机会。
使用循环可以让你避免编写大量的代码。它们让你可以命令计算机重复执行一系列命令多次。命令只需要在循环中写一次。
跳出while循环
有时候你需要休息一下,吃点东西或者喝点饮料。Python 有一个break命令,它允许你提前跳出while循环。在这个例子中,你想要循环重复,如果玩家的最后一次猜测是错误的。如果玩家正确猜出鹦鹉的年龄,那么你想要跳出循环——即使你没有达到第五次猜测,你想要停止循环,因为玩家已经得到了正确答案。
让我们修改之前的计数例子,将其改为 99,这样当它达到数字 77 时就会跳出循环。你可以使用一个if语句来完成这个操作。
列表 4.9. 跳出循环

练习while循环
让我们再试一个使用while循环的例子,以熟悉如何编写它们:一个询问你最喜欢的颜色的while循环。看看你是否能弄清楚这个程序做了什么。
列表 4.10. 最喜欢的颜色
favorite_color = input("What is your favorite color? ")
while favorite_color != "blue":
print("Nope, you got it wrong!")
favorite_color = input("Try again: What is your favorite color? ")
print("Me too! What a coincidence!")
这个例子要求你输入你最喜欢的颜色;如果你输入blue,它会说,“我也是!真巧!”然后结束。如果你没有输入blue,程序会不断地要求你输入你最喜欢的颜色(直到你说它是蓝色)。
假设你的循环没有产生你预期的输出。也许猜谜游戏给你六次猜测而不是五次。这就是你尝试找出问题并修复它的时候——这个过程也被称为故障排除。在while循环中修复错误可能很棘手,因为循环中可能有多个命令。命令执行得很快,所以很难看到发生了什么。你可以使用的一种故障排除技术是在循环中添加一个print函数,并在每次循环迭代时使用它来打印变量的值,例如计数器。
在这个例子中,你可能会在循环中添加这一行:
print(number_of_guesses)
这会在代码每次通过循环时打印出存储在 number_of_guesses 变量中的值。您可以看到计数器是否如您预期的那样递增,以及它是否从正确的数字开始。
使用 Python 代码库生成随机数
您的程序应该运行得很好。玩家有五次猜测机会,如果他们正确猜出鹦鹉的年龄,他们就会赢!游戏的一个令人兴奋的部分是其不可预测性——您永远不知道您什么时候会赢或输。您的下一个任务是让程序随机选择挪威蓝鹦鹉的年龄。这将使其更加刺激,因为即使您也不知道答案!
如果您曾经尝试修理过一辆坏自行车、烤面包机或汽车,您可能需要一些工具。赤手空拳可以做好多事情,但可能不足以完成这项工作。同样,在 Python 中,标准工具(您的赤手空拳)也不够用。有时您需要拿一个工具箱,拿出一把大锤、烙铁或螺丝刀。
Python 也有工具箱。这些工具箱也称为 模块。每个工具箱(模块)都包含不同集合的工具(方法),这些工具对特定工作很有用。以下是一些常见的 Python 模块示例:
-
datetime提供了获取当前时间和日期以及格式化它们的实用工具。 -
random给您创建随机数的能力。 -
math支持更广泛的数学函数。 -
fileinput支持从文件中读取信息。
在您可以使用这些工具箱之前,您必须首先将它们带入房间,就像您可能会拿起一个自行车工具箱来修理自行车一样。要引入一个工具箱,您使用 import 命令:
import random
您可以在程序中的任何地方添加此行,在您需要使用它来创建随机数之前。在您的游戏程序开头的注释之后添加它。这将在程序开始时引入工具箱,使其他阅读您代码的人更容易看到您正在使用哪些工具箱(或模块)。这一行实际上是在将工具箱加载到 Python 的内存中,以便您可以在程序中使用这些工具。
现在您已经添加了工具箱,您可以使用一个名为 randint 的工具来生成介于 1 和 20 之间的随机数。此代码替换了 parrot_age = 19 这一行:
parrot_age = random.randint(1,20)
注意,您输入工具箱的名称,然后放一个点(.),然后放您想要使用的工具的名称。这个特定的工具 randint 需要您提供两个数字:随机整数应该介于的下限和上限。如果您想要一个介于 1 和 100 之间的数字,您会写
parrot_age = random.randint(1,100)
添加这两行代码后,完整的代码列表应与图 4.15 中的代码相匹配。图 4.15。
图 4.15。要随机选择一个数字,您需要导入 random 库并使用 randint 函数来选择介于 1 和 20 之间的随机整数。

太棒了!你已经制作了一个挪威蓝猜测游戏,并学会了如何使用 if 语句和 while 循环在你的程序中创建逻辑。
果实采摘者额外:Scratch
你是否好奇为什么你的 Pi 有一个猫头图片的图标?那是 Scratch 的图标。麻省理工学院(MIT)开发 Scratch 是为了帮助教授编程,Scratch 是一个简单的程序,你可以用它来在你的 Raspberry Pi 上创建动画和游戏。Scratch 还是一种基于拖放程序块的简单易用的编程语言。
通过点击菜单 > 编程 > Scratch 在你的 Raspbian 桌面上打开 Scratch。当 Scratch 打开时,你会看到一个白色方块中的猫。图 4.16 展示了 Scratch 界面的概述。
图 4.16。Scratch 界面分为精灵移动的区域和脚本区域。你可以在脚本区域通过拖放块并连接它们来为你的精灵创建程序。

Scratch 可以做很多事情,我们不会解释所有内容。你可以通过点击帮助 > 帮助页面来了解更多关于如何使用 Scratch 创建项目的信息。帮助信息告诉你如何使用每个块,并提供了一些教程。
你有没有项目的想法?就像在 Python 中一样,你可以编写程序来请求输入、显示消息、生成随机数,并使用 if 语句和循环。你可能添加一个狗精灵,并在点击它时让它像人一样唱歌。或者尝试创建你最喜欢的经典电子游戏的 Scratch 版本。

挑战
让我们玩石头、剪刀、布!对于这个挑战,尝试创建经典游戏。
石头、剪刀、布是用手玩的。每个人同时用他们的手做出三种形状之一:石头的形状、一张纸或一把剪刀。如果两个人做出相同的形状,则为平局。三种游戏形状相互作用如下:
-
石头胜剪刀。
-
布胜石头。
-
剪刀胜布。
让我们计划如何应对这个挑战。以下是一些关键要素:
-
使用
while循环反复要求玩家选择石头、布或剪刀。 -
创建一个选择列表:
choices = ["Rock","Paper","Scissors"] -
使用
random库让计算机在三个选择(“石头”,“布”和“剪刀”)之间随机选择。 -
记住,
randint选择一个随机整数。你可以选择并将随机选择存储在变量中:computer_choice = choices[random.randint(0,2)] -
你可以通过使用表示列表中项目位置的数字来选择列表中的不同项。这个数字被称为 列表索引。在这种情况下,列表中有三个项目。第一个项目的索引为 0,第二个项目的索引为 1,第三个项目的索引为 2。要显示列表中的第二个项目,你写下
print(choices[1]);代码会在屏幕上显示“布”。 -
使用
if语句比较玩家的选择和计算机的选择,并让玩家知道谁赢了。 -
询问玩家是否想要再玩一次。如果是,循环应该重复;如果不是,游戏应该结束。
看看您是否能想出一个程序!参见附录 C 以获取解决方案。
摘要
在本章中,您已经学习了在 Python 中处理文本的一些新技巧以及创建程序逻辑的一些基础元素:
-
您可以让 Python 按照您想要的方式打印内容。字符串字面量允许您创建跨越多行的文本。使用它们来使文本以与您在程序中输入的方式相同的方式显示。
-
您可以编写能够做出决定的智能代码。
if语句通过仅在特定条件为 True 时做出响应来向程序添加逻辑。您可以将if与else语句结合使用,使程序在条件为 False 时执行不同的操作。 -
您不必重复输入内容——您可以让 Python 为您重复它们。
while循环可以用来重复某些内容,只要某个条件为 True。break命令允许您在需要时退出while循环。 -
您可以使用模块(工具箱)来访问更多强大的工具,以便在您的程序中使用。
random模块有一个生成随机整数的工具。
第五章. 拉斯皮洞穴冒险
在本章中,您将创建一个游戏来学习新的编程技术:
-
绘制流程图以映射复杂程序
-
使用布尔运算符检查用户输入
-
使用
if,elif, 和else语句制作多选代码 -
创建和使用您自己的函数来组织代码并避免重复代码
-
嵌套
if/else语句以创建具有复杂逻辑的游戏
就像一本好书一样,一个游戏可以在您的脑海中创造一个完整的虚构世界。游戏中最令人兴奋的方面之一就是您感觉就像身处游戏之中。这不需要虚拟现实眼镜或高清晰度图形。您可以通过与玩家的想象力建立联系,并创造一个他们可以做出决定并决定自己命运的世界,即使在完全基于文本的游戏中也能创造出这种沉浸感。要创建具有虚构世界的游戏,您通常需要通过让用户从一个房间移动到另一个房间或从一个场景移动到另一个场景来产生深度感。游戏应该允许用户选择自己的路径并引入惊喜元素。最后,您还应该有一些出色的描述,让玩家感觉他们就在房间里。
在本章中,您将创建这样一个游戏,基于探索地下洞穴。在这个过程中,玩家将不得不做出选择,如果他们做出错误的决定,游戏就结束了。如果他们做出正确的决定,他们将找到无法计数的黄金、红宝石和钻石!
项目介绍:拉斯皮洞穴冒险
游戏设定在中世纪:一个石头城堡、骑士和剑的时代,以及(有人说)喷火的神话生物。你的主要角色是一个名叫 Raspi 的年轻男孩。^([1)] 一天,Raspi 外出砍柴时在森林中迷了路。他偶然发现了洞穴的入口。他朝入口看去,发现洞穴分为一个左隧道和一个右隧道。他记得他祖母曾经讲述的一个民间故事,说的是这个森林里有一个神秘的洞穴,里面藏有巨大的宝藏。据说宝藏被一只凶猛的喷火龙守护着。Raspi 无法抗拒探索洞穴的诱惑;尽管他知道他应该回头,但他慢慢地走进了黑暗的洞穴。这是你下一个项目的开始:Raspi 的洞穴冒险。
¹
因为这是你的游戏,你可以自由地让 Raspi 成为女孩或男孩。
游戏可以有多种不同的结果,这取决于玩家为 Raspi 选择的路径。程序输出的一个简短示例显示在图 5.1 中。
图 5.1。Raspi 的洞穴冒险要求玩家决定走哪条路。根据他们的选择,玩家将遇到不同的命运。

让我们看看洞穴的地图,看看宝藏在哪里,龙也住在哪里!因为你是游戏设计师和开发者,你将使用这个作为指南来编写创建游戏逻辑的代码(见图 5.2)。
图 5.2。这张洞穴系统的地图显示 Raspi 将需要做出许多选择。如果他做出了错误的选择,游戏就结束了!但如果他做出了正确的选择,他将找到传说中的宝藏!

让我们来看看 Raspi 在洞穴中可以选择的不同路径和选择以及他可能的命运。当 Raspi 进入洞穴的入口后,他可以选择向左或向右走。
左边洞穴
如果 Raspi 进入左边的洞穴,他会发现自己靠近一条地下河流。他需要决定是乘船顺流而下,还是游泳顺流而下,或者沿着河岸行走。如果 Raspi 决定乘船,他很快就会知道船上有洞,他会沉下去(游戏结束)。如果 Raspi 选择避开河流并沿着河岸行走,他很快就会被他的思绪分心,踩在石头上,撞到头上(游戏结束)。如果 Raspi 富有冒险精神并决定在河中游泳,他将到达对岸,并发现一个藏有丰富宝藏的隐藏宝库!
右边洞穴
如果 Raspi 决定进入右边的洞穴,他需要决定是使用绳子爬进洞里还是走向看起来像火炬的东西。在走向火炬之后,Raspi 将进入一个满是晶体的洞穴。晶体洞穴听起来很有希望,但不幸的是,一个晶体将从天花板落下,结束 Raspi 的生命(游戏结束)。或者,如果 Raspi 使用绳子并从洞里下去,他会在龙穴中发现自己,面临最后的抉择:是和龙战斗还是进入一个黑暗的房间。如果 Raspi 和龙战斗,龙会吃掉他;但如果 Raspi 走向黑暗的房间,他会发现里面装满了成千上万的金币、红宝石和钻石。Raspi 变得富有,而且非常健康!
嘿,等等,你需要一个计划(流程图)
你的目标是创建一个允许玩家做出多个决策的程序。你有一张洞穴地图;现在你需要将这张地图变成一个可以指导你编写游戏代码的图表。就像你在第二章中所做的那样,你将布置游戏的逻辑,然后编写代码来创建这种逻辑。
你可以制作一个既是一张地图又是一个流程图的图表。你可以可视化决策集和每个决策的结果。图 5.3 显示了洞穴地图作为流程图。
图 5.3. Raspi 的洞穴冒险流程图显示了玩家可以做出的各种决策及其结果。它是游戏逻辑的地图,可以在你编程逻辑时为你提供指导。

图表中的每个决策都由一个菱形形状表示。菱形内部是当前的问题。菱形外部是表示可能选择及其结果的箭头。有时选择会引出其他选择(其他菱形)。有时,一个选择会导致赢得游戏或游戏结束!
流程图遵循一些简单的规则(见图 5.4)。你可以为任何决策集构建一个流程图,包括游戏、机器人和应用程序中使用的决策集。
图 5.4. 流程图是展示程序逻辑的视觉方式。它们使用菱形、箭头和方框来表示决策、选择和活动。这个例子展示了一个当按钮被按下时打开灯的程序流程图。

流程图是组织思路和将复杂问题分解成一系列简单步骤的绝佳方式。记住 Python 的方式:简单比复杂好。
Raspi 该走哪条路呢?(检查输入)
拿着你的图表,第一部分的逻辑是用户选择是向左走还是向右走。让我们显示文本来告诉玩家他们在洞穴中看到的东西,然后提示他们输入一个选择。你使用input函数提示用户并收集信息。
列表 5.1. 选择左边的洞穴或右边的洞穴

此示例使用 input 函数和 if/else 语句来创建所需的逻辑。代码要求用户通过输入 L 或 R 来做出选择。if 语句检查用户的选项是否等于L。如果是 True,则代码显示玩家进入了左洞。如果他们的选择不等于 L(如果该条件为 False),则程序转到 else 语句并显示玩家进入了右洞。
处理意外输入
用户经常做一些意外的事情。作为一名程序员,你必须思考的一件事是,如果用户做了你预料之外的事情会发生什么。玩你的游戏的人可以输入他们想要的任何内容。让我们检查一些不同的可能性,看看会发生什么:
-
如果用户输入
l(小写的L)会怎样?如果用户输入l,程序将检查(评估)l是否等于L。因为这两个字符串不同,这个条件是 False。程序将执行else语句并显示用户输入了右洞的消息。 -
如果用户输入
left会怎样?如果用户输入left,程序将评估left是否等于“L”。因为这两个字符串不同,这个条件是 False。程序将执行else语句并显示用户输入了右洞的消息。 -
如果用户输入类似
44992或banana这样愚蠢的内容会怎样?程序检查44992或banana是否等于“L”。因为这两个都不等于“L”,这个条件是 False。程序将执行else语句并显示用户输入了右洞的消息。 -
如果用户输入除
L之外的内容会怎样?你猜对了;他们将看到一条消息,表明他们输入了右洞。
这并不理想。让我们按如下方式改进代码:
1. 允许用户输入
L或l,以及Left或left来进入左洞。2. 允许用户输入
R或r,以及Right或right来进入右洞。3. 通过让游戏对用户输入错误的内容进行斥责并以幽默的方式结束游戏来处理其他任何问题。也许天花板上的钟乳石会掉下来,或者洞穴蜘蛛会咬他们!
要创建这种行为,你需要引入布尔 or 运算符。你还需要使用 Python 的 upper() 方法将输入信息转换为大写字母。最后,为了处理所有三种可能的结果,你将使用一个新的 if/elif/else 语句(见 列表 5.2)。
方法
方法 是仅对特定类型的 Python 对象(程序员称之为 对象)起作用的函数。在这个例子中,.upper() 只能作用于字符串,因此被称为 字符串方法。方法的调用方式与其他函数不同。方法使用 点表示法,这意味着你输入对象(对象)的名称,然后输入一个点(.)和方法。
这里有一些示例:
-
"Left".upper()产生“LEFT”。 -
"riGHt".lower()变为“right”。
这里是更新后的代码,以应用这些新方法来避免用户输入错误。
列表 5.2.改进玩家选择的代码

upper()方法将输入文本转换为大写。如果用户输入LEFT、LeFt、left或Left,字符串将被转换为LEFT。
布尔或运算符:检查任一是否为真
or运算符检查是否有一个条件或另一个条件为真。这使你的代码更具灵活性——它能够接受多个输入并继续执行。如果任一为真,则if语句为真,Python 会执行if语句下缩进的任何操作。
elif是else if的缩写。
elif语句是else if的缩写。它检查另一个条件是否为真。把它想象成一个多项选择题。如果用户没有输入L或Left,程序就会转到下一个选项。如果用户没有输入R或r,程序就会转到else语句,并在他们的头上掉下一块钟乳石。游戏结束!更仔细地看看图 5.5 中的if/elif/else语句,看看如何创建一个。
图 5.5.if语句可以有多种形式。这是一个带有两个elif和一个else的if语句。它创建了代码中的逻辑,可以根据用户的输入执行许多不同的事情。在这种情况下,你让玩家猜测鹦鹉的年龄。程序会告诉他们他们的猜测是太高、太低、正确还是无效。

注意,你可以有多个elif语句。实际上,你可以有任意多个。使用if/elif语句,你可以创建你的洞穴所需的逻辑。
布尔逻辑运算符:and、or和not
Python 有一套完整的布尔运算符,你可以用来构造表达式:
-
当你希望表达式在任一操作数为真时为真时,使用
or。 -
当你希望表达式仅在两个操作数都为真时为真时,使用
and。 -
not用于将操作数从真变为假或从假变为真。
让我们看看使用这些运算符的一些示例。
and运算符
假设你想要创建一个程序,只有当你的用户名和密码都正确时,才能访问系统。你可以使用and运算符来编写这个程序:
if name == "Ryan" and password == "PiTaster":
print("The name and password are correct!")
print("Access granted! Welcome!")
else:
print("Access denied!")
只有当name和password都正确时,程序才会授予你访问权限。试着创建一个自己的吧!
or运算符
接下来,让我们想象你想要创建一个程序,如果某人的年龄小于 20 岁或他们有优惠券,就会免费送他们披萨。假设你有一个变量age,它是人的年龄,另一个变量coupon已经持有真或假的值。使用or运算符,你可以创建如下逻辑:
if age < 20 or coupon == True:
print("You get 1 FREE PIZZA")
else:
print("No free pizza for you!")
如果任一为真,用户就会得到披萨。如果两者都为真,他们就会得到披萨。如果两者都不为真,那么就没有免费的披萨!
not 运算符
最后,假设你有一个等于 True 或 False 的变量 is_absent。is_absent 告诉你学生是否在场。如果你想要打印一个“欢迎来到学校!”的消息,如果学生没有缺席,你可以使用 not 运算符:
if not is_absent:
print("Welcome to school!")
else:
print("Please return to school as soon as possible. School misses you!")
not 运算符将一个为 True 的变量或语句转换为 False,将一个为 False 的转换为 True。它帮助你创建当你阅读代码时更有意义的条件语句(if 语句)。正如你所见,布尔运算符为你提供了创建逻辑表达式的多种不同选项。
是时候用你新学的 if/elif/else 和布尔运算符去洞穴探险(这是一个探索洞穴的时髦词)了!
将流程图转换为代码
现在,让我们集中精力为左边的洞穴编写一个程序。玩家已经进入了左边的洞穴,需要做出下一步的选择。查看地图和流程图,玩家接下来遇到的是一条地下溪流。玩家看到一艘船,必须在三个选项中进行选择:
-
沿着河岸继续前行。
-
登上船。
-
在河里游泳。
这些都将是你的代码中的 if 或 elif 语句。但是等等!还有一个第四种可能的结果——他们没有选择这三个选项之一。你将这个作为 else 语句。 显示了左边的洞穴流程图和创建所需逻辑的代码。
图 5.6。左边的洞穴内部有一条溪流,用户有三个下一步行动的选择。在代码中,你创建一个 if 语句,后面跟着两个 elif 语句,以涵盖每个选项。else 语句用于控制如果用户输入了除了三个选项之外的任何内容会发生什么。

你显示一些关于 Raspberry Pi 在左边的洞穴内看到的内容的文字。你要求用户选择下一步要做什么。然后,一旦你收集了这些输入,你就评估这些信息并相应地做出回应。注意,每个可能的选项都出现在一个 if 或 elif 语句中,并且缩进在左边的洞穴 if 语句之下。用户必须选择是继续前行(W)、使用船(B)还是游泳(S)。对于每种情况,程序应该显示你根据流程图设计的信息。
这不仅仅适用于洞穴
布尔运算符和 if/elif/else 语句非常适合当你的程序需要多个选项或选择时。看看你能否创建一个有四个可能选项的程序:A、B、C 和以上皆非。以下代码片段展示了使用 elif 语句创建这四种可能结果的一个示例。在这个例子中,你假装一个人在参加一个游戏节目,选择一个后面有奖品背后的门:
print("Welcome to the Pi Game Show!")
print("There are three doors with prizes behind them: A, B, and C.")
door = input("Select a door by typing A, B, or C").upper()
#Logic for door selection
if door == "A":
print("You've won a new car!")
elif door == "B":
print("You've won a new boat!")
elif door == "C":
print("You've won a trip around the world!")
else:
print("Uh oh! You didn't follow directions!")
print("Game Over!!!")
print("Thank you for playing.")
基于逻辑创建带有选择的程序是一种强大的编程技能。通过组合简单的选择,你可以创建复杂的程序。
优秀的工作!你已经为 Raspi 的洞穴冒险创建了左侧洞穴的逻辑。让我们添加更多的决策。
简化!创建自己的函数
哎呀!左侧洞穴的代码开始看起来很长(而且有点丑陋和难以阅读),你还有右侧洞穴要处理。你如何简化你的程序?
答案是函数。这次你不会调用内置的 Python 函数——你将创建自己的函数!
函数就像你可以创建的小型程序,用于组织或简化你的代码。当你有很长的程序时,你可以将逻辑代码块(所有代码都放在一起)放入函数中。一旦你创建(或定义)了一个函数,你就可以在代码中调用(或使用)该函数。
注意
函数应该始终在程序顶部定义。函数的定义必须在其被调用(或使用)之前。
让我们通过为左侧洞穴创建(或定义)两个函数来看看这是如何工作的。
列表 5.3. 为左侧洞穴创建函数

在继续之前,让我们更仔细地看看你如何创建自己的函数(见图 5.7)。你已经创建了两个函数:left_cave和wrong_answer。让我们重写洞穴程序以使用(或调用)这些函数。每次你调用一个函数时,就好像代码都在那个地方,但你将其隐藏了。
图 5.7. 函数简化你的代码并可以减少重复。使用def关键字创建一个新函数,并在其下缩进函数代码。如果你需要一个函数返回一个值,请在函数中包含一个return语句。

一些函数需要返回某些内容;而另一些则不需要。你可能有一个打印屏幕或播放声音的函数;这些类型的函数不需要返回任何内容。在示例代码中,wrong_answer()函数是一个很好的例子。你可以这样调用函数:
wrong_answer()
或者,当函数返回某些内容并且你想存储这些信息时,你可以这样写:
choice = left_cave()
这将存储调用left_cave()函数返回的任何信息,并将其存储在名为choice的变量中。列表 5.4 显示了如何通过调用left_cave()和wrong_answer()函数来简化程序。
列表 5.4. 使用新函数简化你的代码


太棒了!生成的代码更容易阅读,你避免了代码重复。注意,你调用了wrong_answer()函数两次。这让你不必两次编写这些代码行。此外,如果你想要更改错误答案的结尾,你只需在一个地方更改(在函数中)。除了帮助你组织代码外,能够重用函数是它们的关键特性之一。你没有改变程序的功能,但通过使用函数,你使代码更容易阅读并简化了它。
定义
重构 是一种编程技术,它专注于重新组织和简化程序中的代码。重构使代码更容易阅读且更简单。
| |
传递参数:具有输入的函数
到目前为止,你已经看到了两个不同的函数:一个不返回任何内容,另一个返回内容。除了能够返回某些内容的能力之外,函数还具有另一个特性——它们也可以接收信息。将其视为函数的输入。在编程术语中,你说该函数有一个 参数 或 参数。让我们通过一个例子来看看这是如何工作的。假设你有一个猜谜游戏,你想创建一个函数,该函数会在屏幕上打印一条消息,告诉玩家他们的猜测是太高、太低还是准确无误:
def check_guess(guess, answer):
# Compare the guess to the answer
if guess == answer:
print("You're correct!")
is_correct = True
elif guess < answer:
print("Too low!")
is_correct = False
elif guess > answer:
print("Too high!")
is_correct = False
else:
print("Invalid guess")
is_correct = False
# Return True or False depending upon if the guess is correct
return is_correct
在这种情况下,def 语句具有你的函数名称(check_guess)。在括号内是两个用逗号分隔的参数:这些是函数的输入。第一个输入或参数是 guess。这是用户所做的猜测。第二个是 answer,这是用户试图猜测的数字。然后函数比较 guess 和 answer 并告诉用户他们是否正确或猜测得太低或太高。这个函数的伟大之处在于它可以与任何数值猜测和答案(1 到 10,1 到 1,000,000)一起工作。通过使用参数,你使代码更加灵活。
了解函数的最佳方式是通过实践。以下是一些函数的要点:
-
使用一个描述函数的简单名称。
-
在函数内部添加关于你的函数的注释。
-
当你想在程序中使用它们时返回值。
以下是一些函数的禁忌:
-
使用复杂的名称。
-
创建只有一行代码的函数。
-
忘记在
def语句的末尾放置冒号。 -
在你的主程序中忘记调用函数。
优秀的编程!你通过使用函数简化代码,正在实现 Python 的禅意。
完成左侧洞穴
要完成左侧洞穴,你需要为 Raspi 的选择添加代码:沿着河岸行走、乘船或游泳(获胜的结局)。你将使每个选择都成为自己的函数,以帮助组织你的代码并保持其整洁。你可以在主程序中调用这些函数,如下一列表所示。
列表 5.5. 为左侧洞穴选择调用函数


查看 第五章 的源代码,以了解这些函数(walk()、boat() 和 swim())的示例。它们的结构类似于 left_cave() 和 wrong_answer() 函数。你可以自由地编写关于 Raspi 发生的事情的描述,或者将结果更改为你希望的方式。
探索右侧洞穴
在这个游戏中,Raspi 有两个初始洞穴选择:左或右。编程右洞穴与左洞穴类似。再次使用地图和流程图作为你的指南。让我们添加右洞穴的逻辑,它从用户在地面上找到一个洞开始(见图 5.8)。
图 5.8. 右洞穴由一系列决策组成。一步走错,Raspi 就会面临死亡。如果用户做出正确的选择,Raspi 将找到宝藏。代码使用 if/elif/else 语句和函数。请参阅第五章的代码文件以获取函数的示例。

右洞穴使用与左洞穴类似的逻辑。你将使用 if、elif 和 else 语句来处理所有可能的选择。与左洞穴一样,请注意,你将在其他 if 语句下缩进 if/elif/else 语句以创建你想要的逻辑。嵌套是指在一组 if 语句内部缩进另一组。当你的逻辑需要在先前的条件为真时才执行时,嵌套 if 语句的技术很有用。在这种情况下,你只想在用户已经决定使用绳子爬进洞中时才给用户选择与龙战斗的机会。现在的逻辑与游戏的流程图相匹配。
让我们通过另一个不同的例子再次看看嵌套。想象一下,你想编写一个程序,在输入正确的秘密名称(“Tim”)和正确的秘密密码(“raspberrypi”)后显示一个秘密信息。如果秘密名称猜对了,那么用户必须猜测秘密密码(见图 5.9)才能看到秘密信息。
图 5.9. if 语句可以嵌套在其他 if 语句中。在这种情况下,只有当用户首先正确猜出秘密名称时,才会提示用户猜测密码。Python 使用缩进来确定哪些语句属于一组,以及哪些 if 语句嵌套在其他语句中。

如果密码正确,用户必须输入他们最喜欢的颜色。如果颜色是红色,程序将显示秘密信息(见图 5.9)。
故障排除
创建 if/elif/else 语句时常见的错误是忘记在 if 语句末尾包含冒号。在这种情况下,当你运行程序时,你会在 IDLE 中看到一个弹出消息说“无效语法”,Python 文本编辑器会将行尾突出显示为红色(见图 5.10)。你可以通过在 if 语句末尾添加冒号来修复这个错误。
图 5.10. 当 if 语句末尾缺少冒号(:)导致无效语法时,IDLE 会突出显示

另一个错误是在创建自己的函数时忘记在def语句的末尾放置冒号。在这种情况下,你会在缺少冒号的行末看到相同的消息(“无效语法”)和红色高亮。
最后,第三个常见的错误是在if语句中比较两个值时使用单个等号(=)。Python 会突出显示错误等号,如图图 5.11 所示。记住,你需要使用双等号(==)来测试两个值的相等性。这返回 True(如果值相等)或 False(如果它们不相等)。单个等号(=)用于将值赋给变量,例如x = 7。
图 5.11. 当只有一个等号时,IDLE 的突出显示

通过将单个等号(=)替换为双等号(==)来修复这个错误。正如你所看到的,小问题可能导致程序出现错误。如果你真的遇到了困难,请让朋友查看你的代码,或者将你的代码发布到论坛并寻求帮助。你会惊讶于其他程序员是多么有帮助!
水果采摘者额外功能:播放视频
除了显示文本,就像洞穴冒险游戏一样,Raspberry Pi 还可以输出声音,显示图像,播放视频。让我们看看如何在你的 Raspberry Pi 上播放视频。参见附录 A 了解如何设置你的 Raspberry Pi 的 Wi-Fi 适配器。你可以在 Pi 上使用许多不同的视频播放器应用程序,但 OMXPlayer 是一个很好的选择。它是专门为 Raspberry Pi 创建的,并预安装在 Raspbian 中。我们将在第八章中探索 OMXPlayer 的音频(或声音)播放功能。
为了展示你的 Pi 的能力,让我们播放一部名为Big Buck Bunny的电影的高清演示视频。^([2]) 它大约 10 秒长,没有声音。打开 LXTerminal,在提示符下输入
²
这是一个开发用于测试视频播放和显示的视频。
omxplayer /opt/vc/src/hello_pi/hello_video/test.h264
你应该看到一个无声的视频播放大约 10 秒钟。享受它!如果你在网上知道一个视频文件(.mp4 或 H.264 格式),只要你有良好的互联网连接,OMXPlayer 就可以播放它。例如,要观看另一部名为Sintel的视频预告片,请确保你已连接到互联网,并输入
omxplayer https://download.blender.org/durian/trailer/sintel_trailer-
720p.mp4
为什么不在网络浏览器中打开电影呢?因为 OMXPlayer 可以更容易地播放它们——它被设计为使用 Pi 的图形处理单元(GPU)来播放视频。这意味着你 Pi 的大部分资源都可以用于其他事情。
直播流:从你的 Pi 探索
你一直在假装探索洞穴。现在让我们看看你是否可以使用你的 Pi 通过从网络摄像头直播视频来探索海洋或太空。你可以通过连接到来自加利福尼亚蒙特雷湾水族馆的实时流来将你的 Pi 变成一种可以看到鲨鱼和海龟的方式。或者,也许你现在想看看地球从国际空间站看起来是什么样子。
通过几个步骤,你可以配置你的 Pi 来播放直播视频。首先,你需要一个名为 Livestreamer 的小工具,它可以接收直播视频流并将其输出给 OMXPlayer 播放,就像你的测试视频一样。让我们确保你有 Python 包安装器。确保你有工作的互联网连接,然后使用 Linux 终端(选择菜单-->附件-->终端)打开 Raspbian 命令行,并安装软件:
sudo apt-get install python-pip
完成后,安装 Livestreamer:
sudo pip install livestreamer
现在你需要一个指向视频直播流的链接。Livestreamer 可以与许多最受欢迎的直播网站一起工作。在这个例子中,你将使用 Ustream,但你也可以使用 YouTube Live 和其他许多网站。如果你访问 Ustream 网站,^([3]),你可以找到直播视频的链接。以下是网站上找到的几个不同链接:
³
在www.ustream.tv/explore/all探索 UStream 的直播视频。
-
在蒙特雷湾水族馆观看鲨鱼和海龟:www.ustream.tv/channel/9600798.
-
查看蒙特雷湾水族馆中生活在海藻床上的海洋生物:www.ustream.tv/channel/9948292.
-
查看国际空间站的视角(如果空间站在地球的阴影中,它可能看起来很暗):www.ustream.tv/channel/9408562.
注意
这些链接可能会随时间变化。你可以通过搜索 Ustream 网站来获取最新的链接。
你在接下来的几个步骤中需要一个互联网连接。你需要确定可用的视频分辨率。对于蒙特雷湾水族馆的直播流,输入
livestreamer http://www.ustream.tv/channel/9600798
出现了一些消息,底部是支持的流分辨率。对于这个直播流,你应该看到一个响应,表明
Available streams: mobile_240p (worst, best)
这意味着mobile_240p是视频流的唯一可用分辨率。这是一个低分辨率的流,但观看起来仍然很有趣。告诉 Livestreamer 使用以下命令将视频发送到 OMXPlayer:
livestreamer http://www.ustream.tv/channel/9600798 mobile_240p --
player omxplayer --fifo
太好了!几秒钟后你应该会看到一个视频打开。它将是低分辨率,但请坐下来观看令人惊叹的现场鱼群直播,包括鲨鱼(见图 5.12)!
图 5.12. Pi 的显示器是一个来自水族馆的实时流。看看那只鲨鱼!通过使用 Livestreamer 和 OMXPlayer,你可以从非洲的水坑和国际空间站等异国他乡的地方直播视频。

注意
注意,你必须输入mobile_240p。你将输入上一步中支持的分辨率之一。
按下 Ctrl-C 停止 Livestreamer 和 OMXPlayer。享受从你的 Pi 上探索世界吧!

挑战
这些挑战集中在改进 Raspi 的洞穴冒险游戏。如果你遇到困难,请查看附录 C 以获取提示和解决方案。
介绍戏剧性的停顿
这个第一个挑战是在 Raspi 的洞穴冒险游戏中通过在 print 和 input 语句之间添加两秒的暂停来增加一些戏剧性。这将创造对接下来会发生什么的期待,并给玩家更多的时间在回答之前阅读信息。
这里有一些如何完成这个任务的提示。首先,Python 有一个内置的 time 模块,它提供了一些用于处理时间的有用函数。在程序顶部,你需要添加一个 import 语句来使用这个内置的 Python 工具箱:
import time
一旦你导入了 time 模块,你可以在程序中调用 sleep 函数:
time.sleep(1)
这个示例代码使程序暂停 1 秒。它采用 time.sleep(seconds) 的形式,其中 seconds 是程序需要暂停的秒数。例如,如果你想显示一条消息,等待 3 秒,然后显示另一条消息,你会写
print("It was a dark, dark cave...")
time.sleep(3)
print("Suddenly, a dragon appears out of the shadows.")
尝试创造一些戏剧性。如果你卡住了,请查阅附录 C 或回顾代码文件。
随机死亡
当游戏具有不可预测性元素时,游戏总是更有趣。尝试通过改进 wrong_answer 函数,随机显示玩家可能遇到死亡的一组可能方式的消息来给你的游戏增加一些惊喜。以下是一些开始时的例子:
-
Raspi 看到地上有一块石头,就把它捡起来。他感到一阵剧痛,然后扔掉了石头。当他倒在地上时,他意识到那不是石头,而是一只有毒的蜘蛛。
-
站在洞穴里,Raspi 看到一个小兔子靠近。Raspi 对这只兔子有一种不好的感觉。突然,兔子攻击了他,咬住了他的脖子。
提示:创建具有不同结尾的 if/elif/else 语句,然后使用 random 模块从可能的结果中选择。
再玩一次?
修改游戏,使其无论以何种方式结束,用户都始终有再次玩的机会。提示:创建一个初始设置为“Y”的变量 play_again。你还需要在你的游戏中添加一个 while 循环,使游戏在 play_again 等于“Y”时重复。
喊叫!
如果你有一副耳机或者你的 Pi 通过 HDMI 线连接到带有内置扬声器的电视,你应该能够播放声音并听到它们。让我们看看一个简单的程序,在 Pi 上播放声音:
import os
scream_file_path =
"/usr/share/scratch/Media/Sounds/Human/Scream-male2.mp3"
os.system("omxplayer " + scream_file_path)
测试程序,你应该会听到尖叫。现在看看你如何将尖叫或其他声音整合到 Raspi 的洞穴冒险中。你可以在 Pi 的 Scratch 文件夹中找到更多声音:/usr/share/scratch/Media/Sounds/。
注意
OMXPlayer 与以 .mp3 结尾的声音文件配合得最好。只有一些以 .wav 结尾的文件才能工作。我们将在第八章中更多地讨论声音文件和 OMXPlayer。第八章。
如果你需要帮助解决这些问题,请参阅附录 C!祝你好运!
摘要
通过将逻辑和指令组合到更复杂的程序中,你可以创建引人入胜的程序:
-
在开始之前,使用流程图来规划复杂的程序。
-
通过使用布尔运算符创建灵活的程序,以便处理意外的输入。
-
使用
if、elif和else语句构建具有多个选择和结果的程序。通过链式连接多个elif语句来创建所需数量的选择。 -
当逻辑中嵌套逻辑时,通过嵌套
if语句来创建依赖于先前选择或条件的决策。 -
通过定义自己的函数并在程序中调用它们来组织代码并减少重复。
第三部分。Pi 和 Python 项目
让我们面对现实。按按钮、播放声音和点亮酷炫的彩色灯是很有趣的!现在你可以用你的 Pi 来让这些事情发生。你将创建使用 Pi 的输入和输出引脚的交互式项目。这使得你的 Pi 成为一种特殊的计算机,它不仅能在屏幕上显示图像,还能控制和感知周围的世界。这个领域被称为物理计算。机器人技术是物理计算的一部分,但想想所有创造性的可能性,比如制作交互式艺术、创建能感知你的存在并打开灯光或播放音乐的智能房间,或者生产一些可以提醒你即将下雨或你的宠物正在喝水的物品。
在第三部分中,你将构建可以使用 Python 和你的 Raspberry Pi 与世界交互的项目。这些项目可能需要一些额外的部件,你可以单独购买或作为套件的一部分购买,例如 CanaKit 终极套件、Adafruit 入门套件或 MCM Electronics 入门套件:
-
包含 SD 卡、电源、线缆、键盘和显示器的 Raspberry Pi 2 Model B
-
面包板
-
Model B+ (40 引脚) 的 GPIO 排线
-
GPIO 扩展板
-
12 根跳线,公对公
-
1 个红色 LED(发光二极管)
-
1 个绿色 LED
-
1 个蓝色 LED
-
3 个按钮
-
3 个 10K 欧姆电阻
-
3 个 180 欧姆电阻(或介于 100 到 300 欧姆之间)
-
头戴式耳机或带电源的计算机扬声器
你从第六章开始,通过使用电子面包板设置你的 Pi,构建一个简单的电路,并使用 Python 控制 LED(灯)。你将学习如何通过 Pi 的输出引脚进行通信,以使某些事情发生。在这种情况下,你将使 LED 灯亮。在第七章中,我们将深入探讨创建一个使用灯光响应玩家输入的交互式猜谜游戏,用不同的颜色告诉他们他们的答案是对是错。在第八章中,你将学习如何通过在面包板上连接一个按钮来监听你的 Pi 的输入引脚,并在按下时做出响应;你将完成一个结合按钮和声音来制作你自己的 DJ Raspi 声音混音器的项目。到那时,目标是让你拥有知识、技能和信心,能够想出并创建你自己的 Pi 和 Python 项目。
第六章。闪烁的 Pi
在本章中,你将学习的内容
-
通过连接器给你的 Pi 赋予与任何东西交流的能力
-
用简单的电/电子电路编程你 Pi 之外的世界
-
使用你之前的 Python 知识编程连接器以创建灯光图案
让机器人运动起来,创建带有传感器的智能家庭,以及设计一个交互式电子艺术展览听起来像是截然不同的主题,但这些都是你可以用你的 Raspberry Pi 做到的事情。在每种情况下,Pi 都可以作为大脑,通过做一些事情与世界互动,比如
-
检查机器人的传感器和控制其电机
-
感知房间的居住者并调整恒温器或灯光
-
作为艺术展示的一部分控制声音、运动和灯光
在本章中,你将设置你的 Pi 来控制称为 发光二极管 (LED) 的小型灯泡。你将使用 Python 使 LED 闪烁。为此,你需要了解一些如何在面包板上构建电路的知识。如果你从未听说过面包板,不要担心!它是一个带有许多孔的小板,这使得构建电路更容易。你还将使用短导线(称为 跳线)来连接某些孔。你甚至将学习如何添加电阻,以防止你的 LED 烧毁。参见图 6.1 了解所需部件及其外观;收集部件,让我们开始吧!
图 6.1. Blinky Pi 项目需要一些在 Raspberry Pi 入门套件中常见或可以在线购买的部件。

为物理计算设置你的 Pi
与大多数计算机相比,你的 Pi 由于其输入和输出引脚,称为 GPIO 引脚而独特。让我们学习如何与这些引脚一起工作。
定义
GPIO 代表 通用输入/输出。这些是 Raspberry Pi 上的引脚,允许它感知和控制周围的事物。
GPIO 引脚
Raspberry Pi 2 Model B 和 Raspberry Pi 1 Model B+ 在电路板的边缘有 40 个引脚,排列成两行,每行 20 个引脚(见图 6.2)。Pi 上的大多数引脚都用于输入和输出,因此它们通常被称为 Pi 的 GPIO 引脚。
图 6.2. Raspberry Pi 2 Model B 在 Pi 板的边缘和角落有一组引脚。

警告
这个项目是为 Raspberry Pi 2 Model B 编写的。较早的 Raspberry Pi 模型只有 26 个引脚。有关与较现代 Pi 板的差异信息,请参阅附录 B。要使用 Raspberry Pi 1 Model B 完成此项目,你可能需要选择不同的引脚来点亮你的 LED。
由于所有引脚看起来都相同,你需要一个钥匙或图表来告诉你每个引脚的作用。图 6.3 显示了标记的引脚。
图 6.3. Raspberry Pi B+ 有 40 个引脚。它们执行不同的功能:一些提供 5 伏或 3.3 伏,一些是地线引脚(0 伏),而许多是输入和输出引脚,你可以编程。

物理引脚与 GPIO 引脚编号
在本书中,我们始终会提到 GPIO 引脚编号,而不是 物理引脚位置。物理引脚从 1 到 40 编号(如图 6.3 中的圆圈所示)。GPIO 引脚编号从 1 到 26,这些编号与物理引脚编号不匹配。例如,GPIO 24 对应于物理引脚 18。始终使用 GPIO 编号,这将使你布线电路和创建程序更容易。
哇,引脚真多!一些引脚用于供电,标有 3V3 或 5V。它们分别产生 3.3 伏或 5 伏。还有 8 个接地引脚和 26 个 GPIO 引脚^([1])——26 个引脚,就像字母表中 26 个字母一样。
¹
奇怪的是,你会发现 GPIO 引脚从 2 号到 27 号编号。0 号和 1 号引脚用于通过一个称为 I2C 的超级特殊协议与其他计算机芯片通信。这些在图 6.3 中标有 ID SDA 和 ID SCL。
GPIO 引脚支持发送电信号(输出)或监听来自传感器的电信号(输入)。在你的身体里,你的大脑可以向你的手发送信号,让你拍打自己的额头(试试看!)——这就像 Pi 的输出一样。信号从 Pi 发出,以在世界上产生某种效果。
输出的对立面是输入。当有人戳你时,你的身体可以通过体内的神经检测到这个戳。一个电信号(输入)被发送到你的大脑,让你知道你被戳了。这就像你的 Pi 可以用来检测世界中的输入或动作一样。
你将在本章和第七章中学习如何输出信号。第八章将涵盖检测来自世界的外部输入,例如检测按钮是否被按下。
让我们准备好连接一些电线!但是等等:直接将 LED 连接到 Raspberry Pi 板上的 GPIO 引脚是不可行的,因为引脚之间的距离太近了。你能做什么呢?你需要更多的空间来构建电路。
将 GPIO 引脚扩展到面包板
为了给你留出空间,你需要将 GPIO 引脚移动到面包板上。这被称为引脚扩展。为此,你需要一根扁平电缆、扩展板和无焊面包板(见图 6.4)。
图 6.4. 为了轻松使用 Pi 的 GPIO 引脚创建项目,你可以使用扁平电缆和扩展板将 Pi 连接到面包板。图中所示的部分是许多 Raspberry Pi 套件中常见的部件示例。

面包板使电路原型设计变得简单。就像公园可能提供宽敞的开放场地,使运动变得容易一样,把面包板想象成一个宽敞的电气运动场,你可以在这里玩电气部件。面包板允许你将电线和组件插入小孔。你可以在面包板上轻松构建和重建电路。
找到你的扩展板,并将其插入面包板的顶部。在按下硬之前对齐引脚(见图 6.5)。你的扩展板可能看起来略有不同,但它们的作用都是一样的。有了扩展板,使用 GPIO 引脚构建电路会更容易。
图 6.5. 小心地对齐扩展板,然后将其牢固地压入面包板中。扩展板上的两排引脚应该跨越中心间隙。

将带状电缆的一端连接到 Pi 的 GPIO 引脚;在按下之前仔细对齐。然后将电缆的另一端连接到面包板上的扩展板(见图 6.6)。扩展板有一个缺口,这样带状电缆就只能以一个方向插入。
图 6.6. 将带状电缆的一端连接到扩展板。将另一端连接到你的 Raspberry Pi。

警告
带状电缆通常有一条标记第一条线的条纹。白色或灰色带状电缆通常使用红色条纹。黑色带状电缆通常有白色条纹。这些标记了电缆上的第一条线。确保这条第一条线连接到你的 Pi 板的边缘,远离 USB 端口。
面包板基础知识
面包板^([2])有一组内部连接,你无法看到。但如果你有 X 光视力,你会看到某些孔是相连的。让我们看看你的面包板上的连接(见图 6.7)。
²
在我们使用的面包板开发之前,人们会在用来切面包的木板上搭建电路(因此得名)。他们需要一个快速连接电路的方法,通过钻孔和使用钉子和电线,他们可以使用面包板尝试不同的电路。
图 6.7. 面包板有内部连接。你需要了解它们才能搭建电路。引脚行是水平相连的,但不是跨越中间的缝隙。称为电源总线的长轨垂直沿着板的两侧运行。

在这个面包板上,行用数字标记(1–30),列用字母标记(左侧为 a–e,右侧为 f–j)。你可以通过说出面包板上的特定孔的行号和字母来引用它。例如,如果你想引用位于第 25 行,c 列的孔,你可以说 25c(见图 6.8)。就像你可能会通过走通道找到体育场中的座位,然后沿着行移动以找到正确的座位一样,你将使用字母和数字来指导你搭建电路。
图 6.8. 要在面包板上找到特定的孔,请使用行和列标签。这是一张面包板的特写,显示了如何找到孔 25c 的位置(我们将把这个孔称为 BB25c,其中BB代表面包板)。

面板孔(BB 孔)
我们将提到行和列,但我们会预先加上字母BB,这样你知道我们谈论的是面包板的位置。图 6.8 显示了 BB25c 的位置。如果我们谈论 GPIO 引脚或连接,我们将在数字前加上GP(GPIO 引脚 21 是 GP21)。
尝试记住面包板上哪些部分是连接的,哪些部分没有连接。如果你忘记了,你总是可以回顾一下图 6.7。例如,注意 BB25 的 a、b、c、d 和 e 都是连接的。同样,BB30 的 f、g、h、i 和 j 也是连接的。但是,板的左侧并没有连接到右侧。例如,BB25e 并没有连接到 BB25f。要连接它们,你需要在 BB25e 和 BB25f 之间放置一个跳线。
你可以在面包板的侧面看到垂直排列的孔。这些是电源总线,提供了将电气元件连接到电源(正极)和地(负极)的简便方法。
电路 101
让我们学习关于电和电路的知识。在最简单的层面上,一个电路是一个回路或路径,其中电能从电源(电源的正极)开始,通过一个或多个电气元件(如灯或电机),然后通过连接回电源的负极来完成回路(或路径)。
什么是电?
电是电荷的流动。通常,它是电子的流动,电子带有负电荷。要使电子流动,你需要有电荷差异。就像磁铁的北极会被另一个磁铁的南极吸引一样——正负电荷也会相互吸引。如果电荷可以自由移动,它就会移动。我们通常认为电路中的电是从电源的正极(+)流向电源的负极(-)。对于你的 Pi 来说,电源来自电源适配器(Micro USB 插头)。Pi 作为电源可以提供+3.3 伏或+5 V(伏特)。它通过物理引脚 1、2 和 4 提供这种电源,但也可以通过任何 26 个 GPIO 引脚发送+3.3 V(你很快就会编程使其这样做)。
电压(伏特)
电压是正负电源之间电电荷差异的度量。当你有两个不同的电荷时,它们会相互吸引(正负相吸)。电荷差异越大,推动电荷通过电路从正极到负极的力(或电压力)就越大。
电压以伏特(V)为单位测量,这个名字是为了纪念亚历山德罗·伏打,他被认为是第一个电池的发明者。9 伏(或 9 V)的电池比 AA 电池具有更大的推动电荷的电场,AA 电池的电压仅为 1.5 V。
电流(安培)
电路中的电流是流动的电荷量。所以,虽然电压是衡量电荷想要流动的程度,但电流是衡量实际流动电荷量的程度。
想象一下,你可以在导线内部,并看到电荷通过它流动。大电流意味着在一段时间内有大量的电荷(通常是电子)沿着导线碰撞并通过。在相同导线中的小电流意味着在相同时间内流动的电荷要少得多。电流以安培(A)为单位测量,以安德烈-玛丽·安培的名字命名。1 安培(或 1A)的电流相当于每秒通过导线的 6.241 × 10¹⁸个电子的电荷量!这是大量的电荷流动。你可以通过增加电路对电荷流动的电阻来减少电路中的电流。
电阻(欧姆)
电路中的电阻是衡量它反对电荷流动(电流)的程度。灯泡、电机和你的身体都有电阻。电阻的相反是电导。金属(铜、银和金)等物质都是良好的导体,这就是为什么我们用金属线构建电路,让电流通过。
有时候你需要控制电流(电荷的流动)。电阻用于此目的;它们由减缓电荷流动的材料制成。最常见的是由碳制成(你将在你的项目中使用这些)。电路的电阻以欧姆为单位测量,以乔治·欧姆的名字命名,并使用希腊符号 omega(Ω)表示。
PI 电路
你可以将树莓派视为从 Pi 的正极提供 3.3V,或者稍后从 GPIO 引脚之一输出。这个+3.3V 是一种试图将电荷推向源负极(-)的力。负极有时被称为地——想象它是一个大型的汇流排或水库,如果有一条路径到达那里,电流就会流向那里。在接下来的几章中,你将使用 LED 和电阻搭建电路。你使用电阻与 LED 一起减少电荷流动(电流),以防止电流过大烧毁 LED。烧毁 LED 会发出难闻的气味!
在你的面包板上,将所有 GPIO 引脚都视为电压(正)的潜在来源。从 GPIO 引脚发出的电路应返回到任何一个多个地(负)连接中。
搭建 LED 电路
你的第一个项目是点亮一个红色 LED。你将使用 GPIO 引脚 21(GPIO21)来控制 LED。你需要以下这些部件:
-
树莓派、扁平电缆和连接到面包板上的扩展板
-
1 个红色 LED(5mm)
-
1 个 180 欧姆电阻
-
1 根跳线(公对公)
你将在面包板上搭建 LED 电路,然后编程使其点亮。图 6.9 显示了电路图。要点亮 LED,你需要从树莓派的 GPIO 引脚 21 通过 LED、通过电阻,然后到地(0V)流动电。
图 6.9. 点亮 LED 项目的电路图

图 6.10 显示了在面包板上构建的 LED 电路。请注意,有多种不同的方法可以创建这个电路——这只是其中一种。让我们一步步来构建电路。
图 6.10。在面包板上构建的 LED 电路。你正在使用 GPIO 引脚 21 作为电源。直到你编程使电压从引脚输出,灯不会亮。

注意
你可能使用的面包板与本书中使用的不同。如果是这样,你的面包板上的编号可能与这里显示的不同。在这种情况下,你需要根据相同的原则创建电路,但使用不同的编号孔。
第 1 步:连接 GPIO 引脚 21 的跳线
树莓派 GPIO 引脚可以输出 3.3V。你可以选择任何引脚,但本项目使用 GPIO 引脚 21。
将你面包板上的 GPIO21 引脚连接到面包板上的一个空行。使用第 25 行。将电线牢固地推入孔中。电线的金属尖端应进入孔中,而不是放在上面。
开关板引脚连接到面包板上的行。我们将参考面包板上的孔(见图 6.11)。将跳线的一端插入 BB20i,另一端插入 BB25a。
图 6.11。开关板有标签,与你的 Pi 引脚相对应。要将电线连接到 GP16,将其插入标记为 BB18f 或 BB18j 的面包板孔中。

第 2 步:添加红色 LED
是时候连接红色 LED 了。LED 只允许电流单向通过,所以正确放置它们很重要。LED 有两个电线或腿。较长的腿称为阳极,连接到电路的正极(见图 6.12)。较短的腿,称为阴极,连接到电路的负极或地线。
图 6.12。LED 有两个腿(电线)从它们中出来。较长的腿称为阳极,连接到电路的正极。较短的腿称为阴极,连接到电路的负极。

使用红色 LED,将较长的腿连接到 BB25e,将较短的腿连接到 BB25f。你可能需要弯曲腿并稍微推一下,才能将它们插入孔中。
第 3 步:连接电阻
拿起你的 180 欧姆电阻.^([3]) 你可以通过其颜色编码的带子来识别电阻。180 欧姆的电阻有棕色、灰色和棕色的颜色带(见图 6.13)。它们后面跟着一个第四个带子,表示电阻的公差或质量。第四个带子的常见颜色是金色(±5%公差)和银色(±10%公差)。
³
如果你没有 180 欧姆的电阻,你可以使用 100 到 330 欧姆之间的电阻。如果你使用值太大的电阻,LED 可能不会亮起或会很暗。尝试使用不同的电阻来调整亮度。
图 6.13. 电阻的值由其彩色带决定。参见侧边栏“电阻颜色代码”中的图表;还有许多在线颜色代码图表。

电阻阻止过多的电流通过您的 LED,从而避免烧毁它。将 180 欧姆电阻的一端插入 BB25j,另一端插入负极(-)电源总线(或地)。
⁴
电流是每秒电荷流动的量度。如果通过 LED 的电流过高,LED 将会烧毁。
电流将通过电阻双向流动,所以您连接的方向无关紧要。记住,负电源总线或地线在面包板的右侧垂直运行。大多数板在其旁边都有一个蓝色条纹。
电阻颜色代码
电阻有颜色代码,可以告诉它们的值和公差。此图表显示了如何读取电阻颜色带。

例如,考虑一个带有红色、紫色、红色和银色带的电阻。按照以下步骤使用图表:
-
查找第一条带和第二条带的数字,并将它们组合起来。在这种情况下,数字是 2 和 7:将它们组合起来,得到 27。请注意,您不需要将数字相加;您将它们视为电阻值的第一个和第二个数字。
-
通过查找第三条带的颜色来找到乘数。在这种情况下,它是 100 欧姆(红色)。
-
将它们全部组合起来:27 × 100 欧姆等于 2,700 欧姆或 2.7K 欧姆(K = 1,000)。
-
第四条带(银色)表示电阻的公差为 ±10%。
一个红色、紫色、红色和银色的电阻是一个公差为 ±10% 的 2.7K 欧姆电阻。在需要查找电阻值时,随时使用这个方便的图表。
就这样!您已经在面包板上构建了一个完成的 LED 电路。现在,是时候编程它了!
软件:blinkLED 程序
通过在菜单 > 编程下选择 Python 3 来打开 IDLE。这将在 Python 3.x Shell 中打开 IDLE。在 Python Shell 中,让我们检查您的 Pi 是否已经安装了所需的 GPIO 库:
>>> import RPi.GPIO as GPIO
如果您没有看到错误,您就可以开始了。如果您看到错误消息说没有名为 RPi.GPIO 的模块,请参阅侧边栏“更新您的 Pi”。
更新您的 Pi
在编程之前,您需要检查您的 Pi 是否已更新。确保您的 Pi 已连接到互联网。通过转到菜单 --> 附件 --> 终端来打开终端程序,并运行以下命令以更新 Raspberry Pi 并确保您有所需的 Raspberry Pi GPIO 软件包。
首先,让我们更新 apt-get 数据库。apt-get 程序负责在您的 Pi 上安装和删除软件。在终端中输入以下命令:
pi@raspberrypi ~ $ sudo apt-get update
您需要等待一段时间,以便下载和安装一些文件。您将在终端中看到许多消息。当命令完成时,您将再次看到终端的$提示符。接下来,要获取最新的 Pi 软件,请输入
pi@raspberrypi ~ $ sudo apt-get upgrade
再次,将下载并安装文件。在一系列消息之后,您将看到有关使用额外磁盘空间升级的警告,以及以下提示:“您想继续吗 [Y/n]?”输入Y并按 Enter 键继续升级。
现在是抓一个三明治和汽水的好时机。更新可能需要 15 分钟或更长时间才能完成。完成之后,您将拥有最新的树莓派软件和 Python 库,包括您需要用于与 GPIO 引脚通信和控制所需的库。
您将要编写一个闪烁 LED 的程序。它将从 GPIO 引脚发送电压(+3.3 V)来点亮 LED,然后关闭它,并重复此操作。首先,在 IDLE 中创建以下新程序。在 Python Shell 中,通过按 Ctrl-N 或选择文件 > 新窗口来启动新程序。
列表 6.1. 闪烁 LED 程序

将程序保存为 blinkLED.py 到您的家目录中。程序不能以您之前使用 IDLE 运行程序的方式运行。
运行程序
从 IDLE 文本编辑器中选择运行 > 运行模块(或按 F5)来运行您的程序。在较旧的 Raspbian 版本中,使用 GPIO 引脚的程序必须以超级用户(或 root)的身份从 Raspbian 命令提示符运行^([5])。如果您在 IDLE 的 Python Shell 中运行程序,您将得到一个错误:
⁵
在 2015 年 10 月,树莓派基金会发布了 Raspbian 版本“Jessie”,允许您直接从 IDLE 使用 GPIO 引脚运行程序。使用“Jessie”,您不需要打开命令提示符。只需按 F5 或在 IDLE 文本编辑器菜单中选择运行 > 运行模块即可运行您的程序。
RuntimeError: No access to /dev/mem. Try running as root!
在这种情况下,您使用sudo命令来完成此操作。要运行 blinkLED.py 程序,打开 LXTerminal 并输入以下命令:
pi@raspberrypi ~ $ sudo python3 blinkLED.py
看看闪烁的 LED 灯!通过调整sleep函数中的值来尝试使灯光闪烁得更快。使用更小的秒数,例如 0.5 或 0.1.^([6]) 要停止程序,请按 Ctrl-C。
⁶
数字太小可能会导致灯光看起来一直亮着,但亮度较低。这是因为您的眼睛只能感知大于大约 1/25 秒的闪烁,或 0.04 秒。
注意
使用 Ctrl-C 停止程序可能会导致灯光保持开启状态(取决于您何时按下它)。此外,下次您运行程序时,您可能会看到运行时错误,但程序仍然可以工作。我们在这里不涉及它,但请在网上查找 Python 命令try/except/finally和GPIO.cleanup()命令。这是一种确保在退出程序时所有 GPIO 引脚都被重置的优雅方式。
故障排除
如果灯光没有闪烁,这里有一些您可以检查的事情:
-
屏幕上是否显示了开和关的消息?如果是这样,可能不是你的代码有问题。检查面包板上的电路。确保扁平电缆连接正确,第一根线连接到 Pi 的边缘,远离 USB 端口。再次检查跳线、LED 和电阻是否连接到正确的孔位。
-
你的 LED 是否插反了?确保较短的腿朝向负极或地线侧。试着把它转过来。
-
仔细检查电路中使用的电阻值。如果电阻太大,LED 灯将不会亮起。100 到 300 欧姆之间的电阻应该可以工作。
-
在你的 Python 程序中查找错误。检查你是否已将
LED_pin_red设置为 21,并且你正在将其设置为HIGH然后设置为LOW。
blinkLED:它是如何工作的
让我们更详细地看看 blinkLED.py 代码是如何工作的。
加载库
import命令加载了你在程序中想要使用的库或工具箱:
import RPi.GPIO as GPIO
import time
这些命令加载了控制 Pi GPIO 引脚的 Python 库。它们还加载了time库,这样你就可以使用sleep函数来控制闪烁的速度。
使用 as 关键字导入库
注意到import RPi.GPIO as GPIO中的as关键字。为什么不能直接输入import RPi.GPIO?
as关键字告诉 Python 将库加载到指定的某个名称下。这有点像给整个库起一个昵称。在这种情况下,是为了让你可以简单地用GPIO来引用RPi.GPIO。
一个例子会使其更清晰。一旦你将RPi.GPIO库导入为GPIO,你可以输入GPIO.setmode(GPIO.BCM)。没有它,你将不得不输入RPi.GPIO.setmode(RPi.GPIO.BCM)。你可以看到使用as GPIO如何节省你一些输入时间!
一旦库加载完成,你就可以设置你的 GPIO 引脚。
设置 GPIO 引脚为输出
要设置 GPIO 引脚,你首先需要告诉 Python Pi,你将按照标准断接器编号方案来引用引脚。这些是断接板上打印的数字。你使用setmode函数:
GPIO.setmode(GPIO.BCM)
BCM 代表 Broadcom——Pi 使用的计算机芯片的制造商。接下来,你告诉你的 Raspberry Pi,你将使用LED_pin_red(GP21)进行输出,这意味着你计划从它发送一些电流:
LED_pin_red = 21
GPIO.setup(LED_pin_red, GPIO.OUT)
GPIO.OUT将 GP21 准备好发送+3.3 伏的电流。
循环和闪烁
最后,你创建一个无限while循环,将 LED 打开(设置GPIO.HIGH)然后关闭(设置GPIO.LOW)。你还使用了 Python 的time库中的sleep方法来添加延迟。注意sleep函数接受一个参数,即休眠或暂停的秒数。在这种情况下,你使用 1 秒:
while True:
GPIO.output(LED_pin_red, GPIO.HIGH)
print("On")
time.sleep(1)
GPIO.output(LED_pin_red, GPIO.LOW)
print("Off")
time.sleep(1)
print命令会在屏幕上显示消息。虽然它们对于使 LED 闪烁不是必需的,但可以帮助调试你的程序。如果你使用它们,屏幕可能会迅速充满消息。设置更长的延迟时间以防止这种情况。如果你在屏幕上看到消息,但 LED 没有点亮,那么你可能在电路中而不是在程序中存在错误。检查你的接线,尝试翻转 LED,或者尝试使用不同的 LED 以检查是否损坏。
添加更多 LED
一个 LED 很有趣,所以三个 LED 肯定更有趣。让我们尝试添加绿色和蓝色 LED,并修改程序来控制它们。以下是你需要的部分:
-
之前的 Raspberry Pi 和电路
-
1 个绿色 LED
-
1 个蓝色 LED
-
2 个 180 欧姆电阻
-
2 根公对公跳线
构建电路
你将遵循之前的过程来添加绿色和蓝色 LED。图 6.14 显示了现在的电路图,图 6.15 显示了面包板上的电路。
图 6.14。三个 LED 的电路图:红色、绿色和蓝色。你将像之前一样使用 180 欧姆的电阻。它们将由不同的 GPIO 引脚控制。红色将使用 21,绿色将使用 22,蓝色将连接到引脚 23。你可以使用任何 26 个不同的 GPIO 引脚。

图 6.15。三个 LED 电路在面包板上构建。每个 LED 及其相应的电阻都排成一行。本例使用第 25、27 和 29 行。

要添加绿色 LED,请按照以下步骤操作:
1. GP22 位于面包板第 8 行的左侧的扩展板上。将其连接到第 27 行:将跳线的一端插入 BB8c,另一端插入 BB27a。
2. 将绿色 LED 的长腿连接到 BB27e,短腿连接到 BB27f。如果需要,弯曲腿。
3. 将一个 180 欧姆的电阻(棕色、灰色和棕色)从 BB27j 连接到负电源总线上的最近孔。
这是添加蓝色 LED 的步骤:
1. GPIO23 位于面包板第 8 行的右侧的扩展板上。将其连接到第 29 行:将跳线的一端插入 BB8i,另一端插入 BB29a。
2. 将蓝色 LED 的长腿连接到 BB29e,短腿连接到 BB29f。如果需要,弯曲腿。
3. 拿一个 180 欧姆的电阻。没错!它是棕色、灰色和棕色的颜色编码。将其从 BB29j 连接到负电源总线上的最近孔。
多个 LED:编程它!
你需要修改程序以添加更多 LED,并使它们同时闪烁。以下列表显示了更新的代码。
列表 6.2。三个闪烁的 LED


将代码保存为 blinkLED3.py,并尝试运行它。打开 LXTerminal,并输入以下命令:
pi@raspberrypi ~ $ sudo python3 blinkLED3.py
太棒了!你正在举办自己的灯光秀!

挑战
尝试这些挑战来练习控制你的树莓派的 GPIO 引脚。每个都提供了一个独特的问题来解决。
波浪模式
修改程序,使每个 LED 依次打开,直到它们都打开。然后,依次关闭每个 LED。提示:尝试调整time.sleep(1)命令的位置。你能使 LED 以波浪模式点亮和熄灭吗?
西蒙说
编写一个函数,该函数可以闪烁 LED,并接受五个参数,代表彩色闪烁的模式。每个参数都是一个表示颜色的字符串:红色、蓝色或绿色。该函数应该以适当的模式闪烁灯光。以下是一些你应该尝试使你的函数生成的西蒙说模式:
红,绿,红,红,蓝
蓝,绿,蓝,绿,红
绿,蓝,蓝,红,绿
随机闪烁
创建一个程序,生成灯光保持开启和关闭的随机持续时间。持续时间应该是介于 0 到 3 秒之间的随机浮点数。提示:你可以使用random方法生成介于 0 和 1.0 之间的随机浮点数。以下是一个示例:
off_random_time = random.random() * 3
为了将这个数字缩放到 0 到 3 之间,你可以将off_random_time乘以 3。如果你在挑战中遇到困难,请查看附录 C 和章节源代码以获取提示和解决方案。
概述
在本章中,你学习了以下内容:
-
树莓派能够与周围的世界互动。通过添加一些额外的部件,你可以将其设置为物理计算项目。
-
树莓派可以发送电信号!你可以通过 GPIO 引脚发送输出,这可以用来点亮 LED 或控制许多其他电子组件(电机、蜂鸣器、继电器等)。
-
面板就像电子的游乐场。它们使创建用于 Pi 的电路变得容易,因为你可以轻松地构建和拆卸电路以用于 Pi。
-
RPi.GPIO库内置了使用 Python 设置和控制 GPIO 引脚输出(电压)的函数。
想象一下使用你的树莓派控制几乎任何电气设备的可能性。更好的是,想象一下根据传感器(输入)使设备工作,这样你就可以创建由你编程的智能设备!
第七章. 点亮猜测游戏
在本章中,你将学习关于
-
通过更深思熟虑的设计和使用函数来简化和提高你的代码
-
构建一个电路来控制一个特殊的 LED(灯泡),可以产生并组合红、绿和蓝光
-
将光的颜色相加以创建新的颜色
-
通过让树莓派使用不同颜色的灯光做出反应来使它生动起来
你的 Raspberry Pi 具有与周围世界互动的独特能力。在上一个章节中,你根据编程模式使灯光闪烁。不错,但这并不是真正的交互式,因为 Pi 总是闪烁你编程的模式。在本章中,让我们看看你是否能创建一个可以通过其 GPIO 引脚对你做出响应的交互式项目。你将利用你关于条件逻辑(if/elif/else)的知识,让你的 Pi 做出决策并做出响应。就像在早期章节中做的那样,你需要收集输入,使用循环,并应用一些其他编程技术来完成它。
你正在制作一个点亮猜测游戏,但不仅仅如此:这个游戏将点亮一个小灯,称为RGB(代表红色、绿色、蓝色)LED,它可以产生任何颜色。你将使用你的 Pi、面包板和电气部件,以及你将要编写的程序。如果你的猜测过高或过低,Pi 将通过闪烁 RGB LED 的不同颜色来让玩家知道他们是否正确。
图 7.1 显示了所需的部件。你会注意到其中一些与第六章中的相同,但你还需要一个 RGB LED。让我们开始吧!
图 7.1. 点亮猜测游戏使用红色、绿色、蓝色(RGB)LED。RGB LED 可以产生许多不同的颜色,因为它内部有三个 LED(红色、绿色和蓝色)。

猜测游戏设计
游戏的目标是猜测一个魔法数字。这次,Pi 将通过点亮不同颜色的 RGB LED 来向用户提供反馈。以下是游戏的一些细节:
-
魔法数字是 1 到 20 之间随机生成的数字。
-
玩家有五次猜测正确数字的机会。
-
如果他们猜对了,RGB LED 会闪烁绿色。
-
如果猜测过高,RGB LED 会闪烁红色。
-
如果猜测过低,RGB LED 会闪烁蓝色。
-
玩家可以选择再次游戏。
图 7.2 显示了游戏的输出示例。
图 7.2. 点亮猜测游戏在每次猜测后对用户做出响应。面包板上的灯亮起,让玩家知道他们的猜测是过高还是过低。

你将分两部分来处理这个项目。第一部分是构建电路(硬件),第二部分是编写程序(软件)。
硬件:构建电路
让我们开始构建!你将在面包板上构建一个电路来控制一种新型 LED,它可以产生你想要的任何颜色。你将首先使用扁平电缆和 GPIO 扩展板将 Pi 的 GPIO 引脚连接到面包板上。如果你需要提醒如何设置,请参考第六章(6.1 节)。你的 Pi 和面包板应该看起来像图 7.3。
图 7.3. Raspberry Pi、扩展板和面包板设置。在你之前,你以为你的桌子很乱!

数字,数字,数字!
如在第六章第六章中首次解释的那样,你需要一种方法来找到面包板上的特定孔,为此,你将使用数字和字母。记住,这就像你可能在音乐会或体育赛事的体育场中找到你的座位一样。
要引用面包板上的特定孔,我们将引用行和列,但我们将添加字母BB来代表面包板。不太难,对吧?找到面包板孔涉及搜索行,然后是列。当引用 GPIO 引脚时,我们将在前面添加字母GP。例如,GPIO 引脚 12 被称为 GP12。
连接 RGB LED
你正在连接一种新型 LED,称为 RGB LED。
定义
RGB LED 是一个由三个 LED 组成的光泡:一个红色(R)、一个绿色(G)和一个蓝色(B),所有这些都位于一个塑料 LED 灯泡外壳中。
RGB LED 几乎可以产生你想要的任何颜色,使用它内部的三个微小的 LED。通过以不同的量供电,你可以混合光线来制造颜色。
RGB LED 有四条腿(或电线)从中伸出,所以你需要弄清楚如何连接它。它比你在第六章第六章中连接的单色 LED 要复杂一些,但使用起来相当简单。
电路草图
点亮猜测游戏项目的电路图显示在图 7.4。要点亮 RGB LED,你需要从你的 Pi 的 GPIO 引脚 12、16 和 21 流过电(+3.3 V),通过每个电阻器,通过 LED,然后到地(0 V)。
图 7.4. 点亮猜测游戏项目的电路图

你将在面包板上构建 RGB LED 电路,然后编程使其点亮。按照以下顺序连接:
1. 将 RGB LED 放入面包板。
2. 连接三条跳线,这些跳线将 GPIO 引脚连接到 LED(每种颜色一条)。
3. 将三个电阻器添加到连接跳线到 LED 的红色、绿色和蓝色腿上。
4. 添加最后的跳线,将 LED 的地线腿连接到负(地)电源总线。
完成后,电路将看起来像你在图 7.5 中看到的那样。让我们一步步来构建这个电路。
图 7.5. 你在面包板上构建的 RGB LED 电路使用 GPIO 引脚 12、16 和 21 来供电 LED。灯不会亮,直到你编程电压从引脚输出。

第 1 步. 添加 RGB LED
在你将其添加到面包板之前,让我们更仔细地看看 RGB LED。记住,里面有三个微小的 LED(红色、绿色和蓝色)。你需要能够弄清楚哪条腿是哪种颜色,哪条是地线。图 7.6 是一个方便的参考。
图 7.6. RGB LED 有很多引脚!最长的引脚是地线。其他的分别是红色、绿色和蓝色。这适用于所谓的 共阴极 RGB LED,这是 Pi 套件中包含的,也是你在电子供应商那里最常找到的。

注意
你需要弯曲 RGB LED 的引脚,以便将它们插入面包板上的孔。尽量将它们弯曲成与孔对齐,然后一次性慢慢推入引脚。
拿起你的 RGB LED,让我们将其插入面包板。你将把它放在面包板上的第 22、24、26 和 28 行,h 列。以下是连接引脚的位置:
-
红色引脚插入孔 BB22h
-
地线引脚(最长引脚)插入孔 BB24h
-
绿色引脚插入孔 BB26h
-
蓝色引脚(最短)插入孔 BB28h
当它插入时,它将看起来像 图 7.7。检查一下是否已经压入面包板,以便所有引脚都能良好连接。
图 7.7. 弯曲 RGB LED 的引脚,并将其插入面包板上的 BB22h、BB24h、BB26h 和 BB28h。最长的引脚插入孔 BB24h。

干得好!你刚刚完成了最困难的部分。
第 2 步:连接 GPIO 跳线
断线板上有数字,这些数字指的是 Raspberry Pi 的 GPIO 编号系统。记住,我们在引脚编号前加上 GPIO 来指代 GPIO 引脚。所以如果我们谈论 GPIO 引脚 12,它就是 GPIO12。
问题:你的面包板上哪个孔紧挨着 GPIO12(GPIO 引脚 12)?
答案:仔细观察,你会看到它旁边的孔是 BB16i 和 BB16j。
注意
跳线颜色不重要,但有时选择与 LED 引脚颜色相匹配的跳线可能会有所帮助。当你解决问题时,这可以帮助你轻松记住哪个 GPIO 引脚控制着 RGB LED 中的每种颜色的光。
现在你已经找到了靠近 GPIO 引脚的孔,你可以开始按照以下步骤连接跳线:
-
从 BB16j 到 BB22a 的跳线(连接 GP12 到 RGB LED 的红色引脚)
-
从 BB18j 到 BB26a 的跳线(连接 GP16 到 RGB LED 的绿色引脚)
-
从 BB20j 到 BB28a 的跳线(连接 GP21 到 RGB LED 的蓝色引脚)
当你添加了电线后,电路将看起来像 图 7.8。
图 7.8. 跳线将 Pi 的 GPIO 引脚连接到 RGB LED。如果你有更早的 Pi 模型,你可以使用其他 GPIO 引脚。只需记住你使用的是哪些引脚,并在编程 Pi 时使用这些数字来打开和关闭 GPIO 引脚。

第 3 步:添加三个电阻
是时候连接你的 180 欧姆电阻了!^([1]) 它应该有棕色、灰色和棕色的条纹,然后是一个第四个金色或银色条纹。记住,电流可以通过电阻双向流动,所以连接的方式并不重要。图 7.9 是一个有用的图表,提醒你如何通过使用彩色条纹来计算电阻的值。
¹
这是一个安全值,不会对你的 Pi 造成损害,并且会使事情变得简单。对于那些追求精度的人来说,从技术上讲,你可能想为每种颜色的 LED(红色、绿色和蓝色)使用稍微不同的电阻,因为每个 LED 都需要不同数量的电流(安培)来使其发光。如果你对 RGB LED 感兴趣,可以查看一些在线电阻计算器和 Pi 论坛。
图 7.9. 电阻上的彩色条纹告诉你电阻有多少电阻。对于这个项目,你想要一个棕色(1)、灰色(8)、棕色(×10)电阻,或者 18×10=180 欧姆电阻。如果没有?任何大约 100 到 300 欧姆的电阻都应该工作得很好。

按以下方式连接电阻:
-
将第一个电阻的一端插入 BB22c,另一端插入 BB22f。
-
将第二个电阻的一端插入 BB26c,另一端插入 BB26f。
-
将第三个电阻的一端插入 BB28c,另一端插入 BB28f。
添加完成后,你会得到一个看起来像图 7.10 的东西。现在你已经准备好进行最后一步了!
图 7.10. 添加你的电阻!确保将它们推入面包板的孔中。如果你不喜欢它们立得那么高,你可以使用剪刀剪掉两端。

第 4 步. 添加跳线到地
记住,地线沿着面包板右侧垂直运行,旁边有一个蓝色条纹。从 BB24j 到负极(-)电源总线或地线(任何靠近蓝色条纹的孔都可以)添加一个跳线。图 7.11 显示了它的样子。
图 7.11. 跳线已添加,以连接 RGB LED 的地线与 Raspberry Pi 的地线。跳线可以连接到地线轨道上的任何位置(通常旁边有一个蓝色条纹)。

哇哦!你已经在面包板上完成了 RGB 电路。电路完成后,是时候编写你的程序来测试它了。
使用 RGB LED 进行颜色混合
你可以通过打开或关闭 GPIO 引脚 12、16 和 21 来编程 RGB LED,使其变红、绿或蓝。但 RGB LED 可以通过混合不同量的红、绿和蓝光来制造更多颜色。例如,你可以混合等量的红光和蓝光来制作漂亮的洋红色。或者,为了使 LED 变黄,你可以混合等量的绿光和红光。电视也是基于同样的原理。这个概念被称为加色法,意味着混合不同量的不同颜色的光来制造新的颜色。

等等!你的 Pi 只能打开或关闭 LED(你将它们设置为HIGH或LOW)!你怎么能制作出可能是 80%红色和 20%蓝色的东西,比如树莓红色?这是可能的,但你需要学习如何快速脉冲 Pi 的 GPIO 输出。这被称为脉冲宽度调制(PWM)。在网上查找有关如何使用RPi.GPIO模块进行 PWM 以及创建你想要的几乎任何颜色的信息。
软件:LEDGuessingGame 程序
你正在创建一个猜数字的游戏。正如本章开头所提到的,你将根据以下简单规则(你可以随意修改以符合你的喜好)来设计游戏玩法:
-
魔法数字是 1 到 20 之间的随机生成的数字。
-
玩家有五次机会猜对数字。
-
如果他们猜对了,RGB LED 会闪烁绿色。
-
如果他们猜得太高,RGB LED 会闪烁红色。
-
如果他们猜得太低,RGB LED 会闪烁蓝色。
-
五次猜测后,游戏结束。
-
玩家可以选择是否再次玩游戏。
正如你在前面的章节中看到的,编程通常是将复杂问题分解成更小的问题,然后逐一解决。让我们先快速绘制一个程序应该做什么的示意图(见图 7.12)。
图 7.12. 显示猜测游戏应该如何工作的流程图。注意,如果你猜得太低、太高或正确,你会闪烁 LED。你还给玩家选择是否想要再次玩游戏的机会。

在接近这个程序时,让我们看看你是否可以通过将代码组织成函数来简化代码,特别是当你有可以轻松分离的代码块时。记住,你可以使用函数来组织代码并简化它。你将创建三个函数来处理每个闪烁灯,以简化程序的主要部分:
-
flash_red—使 RGB LED 闪烁红色 -
flash_blue—使 RGB LED 闪烁蓝色 -
flash_green—使 RGB LED 闪烁绿色
你还将创建一个函数,用于在游戏结束时显示一条消息。
现在你已经有了计划,让我们按照以下顺序编写代码:
1. 导入库,创建闪烁和游戏结束函数,并设置 RGB LED 输出引脚。
2. 显示标题和简介,创建循环,并获取和检查最多五次猜测。
3. 添加逻辑,允许用户决定是否想要再次玩游戏。
让我们开始吧!通过选择菜单>编程下的 Python 3 来打开 IDLE。这将在 Python 3.x Shell 中打开 IDLE。在 Python Shell 中,通过按 Ctrl-N 或选择文件>新建窗口来启动一个新程序。
设置 RGB LED 的 GPIO 引脚
在 IDLE 3 文本编辑器中,你首先需要加载所需的 Python 库,创建函数,并准备你的 Pi 向 RGB LED 发送电流(见图 7.13)。
图 7.13. 程序首先导入你将需要使用的 Python 库,设置 Pi 的 GPIO 引脚以点亮 LED,并定义你需要的函数。

设置你的 Pi 的 GPIO 引脚
你需要让你的 Pi 准备好输出到 GPIO 引脚,并告诉 Pi 你计划使用哪些引脚(参见 清单 7.1)。如果你还记得之前的接线,你正在使用这些引脚来控制 RGB LED 内部的三个 LED:
-
GP12 用于红色 LED
-
GP16 用于绿色 LED
-
GP21 用于蓝色 LED
之后,你将编写控制这些引脚的代码。让我们先导入用于 Raspberry Pi 的 GPIO 库,并设置 GPIO 引脚,以便它们可以输出电压来控制 RGB LED。
列表 7.1. 设置 Pi 的 GPIO 引脚


太好了!你已经通过导入 time 和 random 库开始了,因为你将需要它们来闪烁 LED 并在游戏开始时帮助你生成随机数。你定义了你使用的引脚变量,甚至添加了一个变量 BlinkTime,它说明了你将闪烁灯光的时间。最后,你告诉你的 Pi 你想要使用三个引脚作为输出。现在让我们编写函数。
创建函数以简化代码
你需要三个函数来闪烁 RGB LED 内部的三个 LED,以及一个用于游戏结束的函数。将闪烁函数命名为 flash_red、flash_blue 和 flash_green,如下所示。
列表 7.2. 闪烁不同颜色 LED 的函数


在代码中,你创建了四个函数:
-
flash_red() -
flash_green() -
flash_blue() -
game_over()
这三个闪烁函数在 RGB LED 中闪烁不同颜色的 LED。闪烁是通过使用 for 循环和 sleep 函数来实现的,同时将 GPIO 引脚的输出从 HIGH(开)切换到 LOW(关)。想象一下,这就像站在一个开关旁边,打开然后关闭,五次。
在你继续之前,请将程序保存为 LEDGuessingGame.py 到你的家目录中。
何时使用函数
信不信由你,我们并不总是知道何时创建一个函数。这种确定的能力是随着编写程序的经验和看到模式而获得的技能。以下是一些决定将什么做成函数的提示:
-
你是否需要重复使用一组指令,变化很小?
-
你是否有大量代码块使你的程序难以阅读?
函数可以简化你的代码,并使其更容易更新。
重构你的函数
你注意到闪烁 LED 的函数非常相似吗?每个函数中的大部分代码都是相同的,除了 GPIO 引脚,所以让我们看看你是否可以改进这段代码,使其更简单。这个过程称为 重构。
如果将三个函数重写为一个单一函数,如列表 7.3 所示,这个新函数接受一个参数LED_pin,它代表你想要控制的 GPIO 引脚号。它可以是你用于 RGB LED 颜色的任何 GPIO 引脚。例如,如果LED_pin是 16,则对应于 GPIO 引脚 16,应该闪烁绿灯。
列表 7.3. 将三个闪烁函数重构为一个单一函数

在这种情况下,你正在重构一组非常相似的功能,这些功能可以合并为一个接受参数(LED_pin)的单个函数。这个参数使函数更加灵活或动态,因此它可以取代三个单独的函数。
主游戏循环和逻辑
程序的下一部分创建主游戏循环(见图 7.14)。你将执行以下操作:
-
设置游戏。
-
显示给玩家看的标题和说明。
-
创建一些变量,并获取一个随机数。
-
创建循环和猜测逻辑。
图 7.14. 在显示游戏标题和说明后,你需要定义变量来存储重要的游戏信息,包括玩家试图猜测的随机数。游戏的主循环被重复执行以允许用户进行五次猜测;它也会闪烁灯光。

游戏设置
让我们看看你需要为游戏准备的一些变量:
-
number_in_my_head存储一个随机数(一个介于 1 和 20 之间的整数),玩家试图猜测这个数。 -
count_guesses帮助你计数并跟踪玩家已经做了多少次猜测。 -
play_again跟踪玩家是否想要再次玩的状态。你将使用布尔类型来表示这个,因为它应该始终是 True(是的,让我们再玩一次)或 False(不,我们不再玩)。
下一列表添加了这三个变量并设置了它们。你还创建并显示了标题和游戏说明。
列表 7.4. 创建变量并显示游戏标题和说明
# A random number for our game
number_in_my_head = random.randint(1,20)
count_guesses = 1 # Counter for the number of guesses
# Used to keep track of whether they want to play again
play_again = True
title = """
**********************************************************************
Light Up Guessing Game
**********************************************************************
"""
print(title)
intro = """
Game Play:
I'm thinking of a number between 1 and 20\. You have five guesses to guess it.
After each guess, my light will blink.
Red ---> Your guess is too high!
Green ---> Your guess is correct!
Blue --> Your guess is too low
"""
太棒了!变量为猜测游戏逻辑奠定了基础。它就像房子的地基——你需要它来建造其余的部分。
猜测游戏循环和逻辑
代码包含两个循环,一个嵌套在另一个内部。外循环给用户提供了再次玩的机会——我们将其称为“再次玩循环”。在这个循环内部还有一个循环,给玩家五次猜测的机会——我们将其称为“猜测游戏循环”。
主游戏循环包括获取猜测、检查猜测、闪烁 RGB LED 的适当颜色,然后重复直到玩家猜对或用完所有五次猜测。下一列表显示了猜测游戏循环的程序和检查猜测的逻辑。
列表 7.5. 猜测游戏循环

猜测游戏循环包含以下逻辑
-
跟踪猜测次数。
-
获取一个猜测。
-
检查猜测是否正确、过高或过低。
响应玩家的逻辑在哪里?它在循环中。每次你得到一个猜测,一系列的if/elif语句会检查猜测是否正确、过高或过低。根据哪个情况为 True,flash()函数会被调用以闪烁相应颜色的 LED。如果用户猜对了数字,RGB LED 会闪烁绿色,然后break命令会退出while循环。
注意到你在while循环中添加了一个else语句。当猜测次数超过限制(count_guesses大于 5)时,else语句会被触发,并调用game_over函数。else块仅在while条件检查为 False 时发生(在这种情况下,当猜测次数超过 5 时)。
在下一节中,你将看到如何给玩家提供再次玩游戏的选择。
添加再次游戏循环和逻辑
你想要添加一个功能,让用户选择是否想要再次玩游戏。为此,你需要另一个循环,它围绕在猜数字游戏循环周围(参见图 7.15)。再次游戏循环需要重复猜数字游戏循环,直到用户回答他们想要再次玩游戏。
图 7.15. 再次游戏循环被包裹在猜数字游戏循环中。当玩家用完他们的猜测或猜对了数字后,他们会被告知是否想要再次玩游戏。根据他们的回答,游戏将重新开始或结束。

列表 7.6. 再次游戏循环


太棒了!你已经组装了一个控制 RGB LED 的电路,并编写了 Python 代码来使游戏与之交互。现在,让我们测试它。
玩游戏
将代码保存为 LEDGuessingGame.py,并尝试运行它。从 IDLE 文本编辑器中选择运行 > 运行模块(或按 F5)来运行你的程序。如果你有一个较旧的 Raspbian 版本(在 2015 年 10 月之前),打开终端并输入以下命令:
pi@raspberrypi ~ $ sudo python3 LEDGuessingGame.py
太棒了!你应该能看到你的猜数字游戏启动。让我们测试一下它是否工作。尝试猜测数字。尝试猜错,只是为了确保game_over函数工作。
注意
记住,任何使用 GPIO 引脚的程序都必须以超级用户(或 root)的身份从 Raspbian 命令提示符运行。sudo命令让你这样做。如果你尝试在 IDLE 的 Python Shell 中运行程序,那么你会得到一个以“RuntimeError: No access to /dev/mem. Try running as root!”结尾的错误。
故障排除
如果每次猜测后灯光没有闪烁,这里有一些你可以检查的事情:
-
检查面包板上的电路。扁平电缆是否正确连接,第一根线连接到 Pi 的边缘,远离 USB 端口?
-
请再次确认跳线、RGB LED 和电阻是否连接到面包板上的正确孔位。你的 RGB LED 是否插反了(较短的腿朝向负极或地线侧)?如果你不确定,可以试着将它翻转过来。
-
检查你的 Python 程序中的错误。如有必要,编辑程序以添加一些
print语句,以便你可以看到哪些部分正在工作。例如,在内层循环中处理五个猜测的部分,你可以使用print函数显示count_guesses的值:print(count_guesses) -
在
flash函数中尝试添加一个print消息,以确保它被调用。例如,你可以添加print("Blinking the LED")
如果你喜欢玩你的游戏,尝试一些额外的挑战来增加乐趣!

挑战
这些挑战使用了你已经连接好的 RGB LED。如果你无法解决它们,请查看 附录 C 以获取提示和解决方案。
游戏赢家
在游戏中编写一个函数,当用户正确猜出数字时,该函数会创建一个闪烁动画。例如,你可以尝试快速闪烁 RGB LED 的不同颜色。
复活节彩蛋
上一个是不是太简单了?那么,试试这个:在你的游戏中创建一个复活节彩蛋。创建逻辑,以便如果有人输入某个特定的词(可能是 Spam),程序会显示一条秘密消息并以疯狂的方式闪烁灯光。
温暖和寒冷
扩展你程序的逻辑,使闪烁的速度表明玩家的猜测是接近还是远离正确答案。作为一个提示,想想你设置的闪烁速度。比如说,一个猜测偏离了 10(玩家猜测 15,而魔法数字是 5)。你希望灯光闪烁缓慢。你可以取差值(忽略任何负号)并除以 10。这将使闪烁速度是差值的十分之一,或者如果你偏离了 10(相当慢),每秒闪烁一次。如果玩家的猜测偏离了 2,灯光将每二十分之一秒闪烁一次(相当快)。这样,闪烁速度就可以告诉玩家他们的猜测是接近还是远离。
达斯·维达惊喜
看看你是否能在玩家没有正确猜出数字时,让达斯·维达的形象出现。这里有一个提示来帮助你开始。安装名为 fim 的 Linux 图像查看软件,^([2]),这是一个允许你从 Raspbian 命令行打开图像的程序。要安装 fim,确保你的 Pi 已连接到互联网,然后打开终端并使用以下命令:
²
fim 是 fbi 的改进版本,是 Linux 上的图像查看软件,可以从命令行运行。
pi@raspberrypi ~ $ sudo apt-get -y install fim
接下来,下载达斯·维达的图片,让游戏在屏幕上显示它。假设你已经下载了一个名为 Darth_Vader.jpg 的图片。你可以使用以下 Python 命令来显示它:
import os
os.system("fim Darth_Vader.jpg")
祝你好运!愿原力与你同在!
摘要
在本章中,你学习了
-
通过程序中的 GPIO 引脚与 Pi 交互,Pi 可以以丰富和令人兴奋的方式做出反应。
-
函数、循环和条件语句可以与你的 Pi 的输出能力结合,创建出能够对人和环境做出反应的程序。
-
RGB LED 非常酷,因为它们可以制造出不同的颜色,实际上是将三个 LED 封装在一个小包装中。
-
一个
while循环可以有一个else语句,允许你在循环条件不再为真时控制发生的事情。 -
可以将一个再次播放循环包裹在主游戏循环中,以便用户可以反复玩游戏。
-
重构是一个听起来很高级的词,实际上只是意味着通过寻找使代码更有效率的途径来简化或缩短你的代码。不过要小心,你不想简化得太多以至于代码变得难以理解(记住 Python 的禅宗!)
第八章. DJ Raspi
在本章中,你将
-
通过让 Pi 在按钮按下时与你交互来响应输入信号
-
了解电子按钮以及如何使用它们在面包板上构建电路
-
运行 Raspbian 操作系统命令,以便你的程序可以播放音乐、显示视频等
-
使用 Python 存储称为列表的信息集合
-
探索如何在你的 Pi 上播放声音并将其变成音乐机器
我们没有考虑我们的五种感官(味觉、嗅觉、触觉、听觉和视觉),但没有它们,我们就无法感受到、了解并与周围的世界互动。想想你的 Pi 就像一个人,直到现在,他只有有限的感官。到目前为止,你的 Pi 只能对按键和鼠标点击做出反应。
就像疯狂科学家将某物带来生命一样,在本章中,你将开始一个项目,为你的 Pi 连接一个新的触觉感官。好吧,可能不会像创造一个仿生生物那样疯狂,但按钮给 Pi 带来了触觉。你将把几个按钮连接到 Pi 的 GPIO 引脚上(回想一下,GPIO 代表通用输入/输出,因此这是 Pi 感知和影响环境的方式)。然后,你将编写程序让 Pi 对按钮按下做出反应。激动人心的时刻即将到来!
这个项目只是你为你的 Pi 提供各种不同感官体验的一个小缩影。能够检测周围环境的电子组件被称为传感器。按钮是最简单的传感器之一,因为它可以检测触摸。你还能添加哪些传感器呢?以下是一些想法:
-
一个可以使用称为计算机视觉的特殊软件跟踪球或人脸的摄像头,该软件可以识别物体(这与微软 Kinect 的工作方式类似)
-
超人类能力,如接近传感器,可以检测附近有人行走(就像用来在杂货店开门时触发门的传感器)
-
一个麦克风,以便它能听到
所有这些都可以用 Pi 实现,一些解决问题的决心,以及一点尝试新事物的勇气。
项目概述
在本章中,你将把你的 Pi 变成 DJ Raspi——一个当你按下按钮时播放不同声音的音乐电脑。你将在面包板上连接两个微型按钮,并找出如何编写代码使按钮播放声音。稍后,如果你想的话,你可以向你的 Pi 添加其他传感器并编程它们。这个项目将给你一个如何处理传感器输入的例子。图 8.1 显示了你需要准备的部件。
图 8.1。DJ Raspi 项目需要几个不同的部件,将你的 Pi 变成音乐播放器。跳线长度和颜色无关紧要。

收集所需部件,准备享受乐趣。你会发现其中一些与第六章和第七章中的相同,但你还需要一些新物品。这些大多数都包含在树莓派入门套件中,但你也可以在网上电子零售商那里找到它们。你将分两部分来完成这个项目:构建电路(硬件)和编写程序(软件)。让我们开始吧!
设置 Pi 以播放声音
首先,让我们让你的 Pi 准备好播放声音。Pi 可以通过耳机插孔(也称为3.5 毫米音频端口)或通过 HDMI 输出声音。在你开始之前,插入你的耳机、带电源的电脑扬声器,或者,如果你愿意,通过 HDMI 线连接内置扬声器的电视。
所有声音并不相同:音频格式
如果你想要给某人留一条秘密信息,你可以选择几种不同的方式将信息变成秘密代码。你可以使用不同的符号来代表单词,或者你可能替换字母或改变字母的位置。有无数种不同的编码方式。
类似地,人们想出了许多不同的方式来存储声音(或音频文件)。这些方式(称为格式)是压缩或编码声音信息的不同方式,以便于在计算机或音乐播放器上存储。有时声音被编码,只能在某些音乐播放器上播放。
这里有一些常见的格式:
-
MP3 —在大多数音频播放器中最常用的音频文件格式。文件以 .mp3 结尾。
-
WAV 或 WAVE —代表波形音频文件格式。它在许多 Windows 计算机上使用。这些文件以 .wav 结尾。
-
Ogg —一个为流媒体应用开发的开放格式。文件以 .ogg 结尾。
每种格式都使用不同的方法来压缩或缩小声音,使其更小以便存储。Pi 有许多不同的软件应用程序用于播放音频。每个都可以播放不同的格式。如果你想了解更多关于不同播放器和它们最适合什么的信息,请查看树莓派论坛。
你将专注于从你的 Pi 上播放 MP3,因为这是一种常见的音频文件格式。你能用什么来播放它们?
OMXPlayer 和 MP3s
当你在电脑上观看电影或听音乐时,你可能使用 iTunes 或 Windows Media Player。Raspbian 有自己的等效程序,称为 OMXPlayer,可以播放声音或视频。幸运的是,它能够播放 MP3 文件(或 MP3s)——这是最常见的音频格式之一。
定义
OMXPlayer 是为 Raspberry Pi 创建的视频和音频播放器。
如果你没有 MP3,你可以使用 Pi 上已有的声音测试 OMXPlayer。Scratch 软件附带的一些文件夹中包含相当多的 MP3 文件。打开文件管理器,转到此文件夹查看一些文件:/usr/share/scratch/Media/Sounds/Vocals/。在文件夹中,你会看到 MP3 和 WAV 格式的文件(见图 8.2)。
图 8.2. 当你在 Pi 上安装 Raspbian 时,它附带 Scratch,其中包含许多声音文件,包括人声、音效、动物声音和鼓点。

要使用 OMXPlayer 播放 MP3,请打开终端,并输入
pi@raspberrypi ~ $ omxplayer /usr/share/scratch/Media/Sounds/Vocals/
Oooo-badada.mp3
你应该听到一段女性演唱的简短音乐片段。享受这首歌吧!
注意
在终端中,按上箭头和下箭头可以循环查看之前的命令。按一下上箭头然后按回车键可以再次运行最后一个命令。
太棒了!你的 Pi 现在可以和你说话了。
故障排除
如果你的扬声器或耳机已经插上,但听不到任何声音?OMXPlayer 应该会自动检测是否将声音输出到 3.5 毫米音频输出或 HDMI。如果它没有这样做,请尝试以下命令用于耳机插孔(3.5 毫米音频输出):
pi@raspberrypi ~ $ omxplayer –o local /usr/share/scratch/Media/Sounds/
Vocals/Oooo-badada.mp3
–o 是一个特殊的开关或 标志,它让 OMXPlayer 知道你想告诉它什么。在这种情况下,–o 代表 输出,它告诉 OMXPlayer 你希望将声音输出到何处。在这种情况下,你将其设置为 -o local,这样声音就会输出到 3.5 毫米(耳机插孔)输出。
开关(标志)
开关,如用于输出的 –o,像选项或程序的特殊控制一样。在命令行界面中使用时很常见。通常,你可以通过让命令打印出其帮助信息来获取程序有哪些开关。大多数你可以在命令行中运行的程序,当你输入程序名然后 –h 时,都会给你一个所有开关或标志的列表。–h 开关代表 帮助。尝试用 OMXPlayer 来试试:
pi@raspberrypi ~ $ omxplayer –h
你将看到一系列你可以用来控制视频和音频文件播放方式的选项。尝试在其他命令行程序中使用 -h 来查看你得到的结果。
如果你需要指定将声音发送到显示器上的扬声器,那么请使用 –o 开关并指定 hdmi 以输出到 HDMI 端口:
pi@raspberrypi ~ $ omxplayer –o hdmi /usr/share/scratch/Media/Sounds/
Vocals /Oooo-badada.mp3
现在你已经知道你可以播放音乐,让我们构建电路并编写一些代码来创建你的 DJ Raspi!
硬件:构建电路
建造时间!你正在面包板上构建一个电路来检测或监听按钮。当按钮被按下时,你的电路将向你的 Pi 的 GPIO 引脚发送电流。你将首先使用扁平电缆和 GPIO 扩展板将 Pi 的 GPIO 引脚连接到面包板。如果你需要回忆如何设置,请参阅第六章(6.1 节)。
关于数字的提醒
就像在体育场里找座位一样,我们将使用前缀BB来指代面包板上的孔。所以位于第 25 行,第 a 列的孔是BB25a。同样,我们将使用前缀GP来指代 Pi 的 GPIO 引脚,然后是引脚号。所以 GPIO 引脚 24 简称为GP24。
焊接按钮
让我们开始焊接按钮。按钮有很多不同的类型,但你会使用一个迷你按钮(见图 8.3)。这些按钮通常与跳线、电阻和 LED 一起出现在 Raspberry Pi 套件中。如果你需要购买,你可以在许多在线电子产品零售商那里以低于汉堡包的价格购买 10 个或 20 个的包装。收集好零件后,让我们组装电路。
图 8.3. 当你按下中间的黑按钮时,迷你按钮会发出清脆的点击声。按下它就像闭合开关一样,完成电路。

电路草图
DJ Raspi 的电路图显示在图 8.4 中。为了监听按钮是否被按下,你需要从你的 Pi 到按钮流动电(+3.3 V)。当按钮被按下时,电流将通过按钮并分流。一小部分电流将流向 GPIO 引脚 6(GP06),其余的将通过 10K 欧姆电阻然后流向地(0 V)。让我们在面包板上组装起来。
图 8.4. DJ Raspi 项目中的第一个按钮的电路图显示了电流如何通过电路流动。按钮是一个开关,当按下或闭合时,允许电流流向 GP06 和地(-)。

让我们在面包板上构建按钮电路,并编程你的 Pi 以知道何时按下按钮。你将通过以下顺序连接按钮,使你的 Pi 能够感觉到按钮被按下:
1. 将迷你按钮添加到面包板上。
2. 从 3.3 伏特连接一根跳线到按钮上。你将使用沿着面包板侧面的正电源总线(+)。
3. 将电阻从按钮连接到负电源总线(-),也称为地。
4. 将第二根跳线从按钮连接到 GP06(GPIO 引脚 6)。
一个按钮的完整电路看起来就像你在图 8.5 中看到的那样。
图 8.5。迷你按钮将从正电源轨连接到 3.3 伏特。当按钮被按下时,电流通过按钮并分流。一部分电流流向 GP06(GPIO 引脚 6),其余的电流通过电阻然后流向负电源总线(-)。

不要忘记,当你按下按钮时,什么也不会发生。你必须编程你的树莓派来响应这种新发现的触觉。让我们一步步来构建电路:
第 1 步。添加迷你按钮
在我们继续之前,让我们看看按钮是如何工作的。如果你有 X 光眼镜,你会看到按钮顶部的左右引脚是相连的。同样,按钮底部的左右引脚也是相连的。按钮的顶部和底部是不相连的。
但当你按下按钮时,图 8.6 展示了会发生什么。按下按钮会使一个小金属棒向下移动,使得顶部和底部相连。我们说开关是闭合的。当你松开按钮时,按钮中的弹簧会将金属棒推回,开关再次打开。拿起你的迷你按钮,让我们将其插入到面包板上。
图 8.6。在按钮中,引脚在顶部相连,而在底部则是分别相连的。当按钮被按下时,顶部和底部通过一个小金属棒相连。

注意
你需要将按钮非常牢固地推入面包板。如果按钮引脚没有与面包板孔对齐,你可能会不小心弯曲一些按钮引脚。不用担心——你可以将它们弯曲回来再试一次。如果引脚断裂,请使用新的按钮。
你将把按钮放在面包板列 d 和 g 的行 23 和 25 上。连接引脚:
-
顶部引脚:BB23d 和 BB23g
-
底部引脚:BB25d 和 BB25g
当按钮插入时,它看起来像图 8.7。再次确认它已经按下并推入面包板,以确保所有引脚都能良好连接。干得好——你刚刚完成了最棘手的部分!
图 8.7。将按钮与面包板孔对齐,然后按下它进入面包板。确保你按下它,使按钮引脚向下进入面包板孔并良好连接。如果你不小心弯曲了引脚,不用担心!只需将它们弯曲回来再试一次。

第 2 步。从 3.3 伏特连接一根跳线到按钮。
你需要将按钮连接到电流源。你将使用面包板边缘的正电源轨作为电源(你也可以直接将跳线连接到扩展板上的 3V3 引脚)。
将跳线从正电源总线(+)连接到BB25a。记住,你可以将跳线连接到电源轨上的任何孔(它旁边有一条红线)。当你添加了电线后,它看起来像图 8.8。
图 8.8. 跳线将电源(3.3 伏特)连接到按钮的底部。

太棒了!现在电流已经到达按钮的底部腿。
第 3 步. 添加 10K 欧姆电阻
是时候连接您的 10K 欧姆电阻了。它有棕色、黑色和橙色的带子,后面跟着一个金色或银色的第四个带子。记住,电流可以通过电阻双向流动,所以您放置的方向无关紧要。
您正在将电阻从按钮的顶部连接到负电源总线(-)。这是一组带有蓝色条纹的孔,沿着面包板的边缘运行。
将电阻的一端插入BB23i,另一端插入负电源总线(-)。您可以选择蓝色线上的任何孔。一旦添加了电阻,您将得到类似图 8.9 的外观。现在您已经准备好进行最后一步了。
图 8.9. 添加电阻。确保其两端被推入面包板孔中。

第 4 步. 将跳线添加到 GPIO 引脚
需要一小部分电流到达一个 GPIO 引脚(您将使用 GP06),因此您需要从按钮的顶部到 GPIO 引脚旁边的孔的跳线。为了建立这个连接,请从BB23a到BB16a添加一个跳线。图 8.10 显示了其外观。
图 8.10. 跳线将按钮的顶部连接到 GP06。稍后,您将设置您的 Pi 以监听此 GPIO 引脚上的电输入。

当按钮被按下时,一小部分电流将流向 GP06 并通过电阻流向地。目前还没有发生任何事情,但接下来您将编写一个 Python 程序来检测这种电流并播放一些声音。
添加第二个按钮
让我们在板上添加第二个按钮。图 8.11 显示了完成后的样子。
图 8.11. 在第一个按钮下方添加第二个按钮。布线方式相同,但您将将其连接到 GP19(GPIO 引脚 19)。任何可用的 GPIO 引脚都可以,但请记住,您的代码将必须反映您选择的 GPIO 引脚。

要添加另一个按钮,您将创建相同的电路,但将按钮放置在面包板上的第 28 行和第 30 行。您将按钮连接到 GP19。
第 1 步. 添加迷你按钮
将按钮插入,使顶部腿位于BB28d和BB28g,底部腿位于BB30d和BB30g。
第 2 步. 从 3.3 伏特连接跳线到按钮
您需要将来自正电源总线(+)的电源连接到按钮的底部。电源轨是带有红色线条的孔线。从正电源总线(+)的任何位置插入一个跳线到BB30a。
第 3 步. 添加 10K 欧姆电阻
为了防止按下按钮时电流过多,您需要添加一个电阻。与之前一样,您将添加一个 10K 欧姆电阻(颜色带为棕色、黑色和橙色),将按钮的顶部连接到负电源总线(-)。
将电阻的一端插入BB28i,另一端插入负电源总线(-)。蓝色线上的任何孔都可以。
步骤 4。将跳线连接到 GPIO 引脚
最后,当按钮被按下时,需要电流流向 GPIO 引脚。对于第二个按钮,您使用 GP19。从BB28a连接跳线到BB18a(GP19)。
太棒了!第二个按钮已连接,您已完成了按钮电路。让我们称第一个按钮为按钮 1。它连接到 GP06。第二个按钮,按钮 2,连接到 GP19。现在一切都已经连接好,让我们为它编写代码!
软件:DJ Raspi 程序
您的项目是将您的树莓派变成一个由按钮控制的出色音乐播放器。以下是它的工作方式:
-
按下按钮 1 使树莓派播放随机音乐片段。
-
按下按钮 2 使树莓派播放随机声乐(唱歌)声音。
您需要以下设备之一来听到声音:
-
耳机
-
有源电脑扬声器
-
您的树莓派通过 HDMI 连接到内置扬声器的电视。
让我们思考一下这个程序将如何工作。图 8.12 显示了一个逻辑的快速图。
图 8.12。一个流程图,显示了 DJ Raspi 程序应该如何工作。程序必须在开始时收集声音列表,然后检查按钮是否被按下。按钮将反复检查。

让我们按以下顺序编写代码:
1. 设置您的树莓派以侦听来自按钮的输入。
2. 收集音乐和声乐声音的列表。
3. 编写一个循环来检查按钮。如果它们被按下,则播放随机声音。
您将在过程中尝试使用函数来简化您的代码。
让我们开始!通过选择菜单>编程下的 Python 3 来打开 IDLE。在 Python Shell 中,通过按 Ctrl-N 或选择文件>新建窗口来启动一个新程序。
设置树莓派:初始化按钮
在 IDLE 文本编辑器中,您将首先加载您将需要使用的 Python 库。您还将设置树莓派的几个 GPIO 端口以侦听来自按下按钮的电信号。在流程图中,这是初始化按钮的第一步(见图 8.13)。
图 8.13。第一步是设置按钮作为输入。这意味着您的树莓派将准备好检查是否检测到任何电压输入,这将在按钮被按下时发生。

当您设置 GPIO 端口时,您使用GPIO.IN来告诉树莓派您计划将该端口用作输入。为了准备树莓派以输入 GPIO 引脚,您需要告诉它您计划使用哪些引脚。根据电路,您正在使用以下引脚作为输入:
-
GP06 用于按钮 1
-
GP19 用于按钮 2
以下列表显示了您如何使用GPIO.setup命令将 GPIO 引脚设置为输入。
列表 8.1。设置 GPIO 引脚为输入

你可能会注意到你导入了新的os模块。我们将在下一节讨论为什么你需要它,当你收集声音文件列表时。
获取声音列表
列表无处不在。你列出你需要做的事情、要买的礼物、你想去的地方,以及你最喜欢的东西,比如你最喜欢的 10 部电影或书籍。
你的 DJ Raspi 需要一个声音文件的列表:一个用于音乐片段(或循环)和一个用于人声。根据设计,你需要从你的 Pi 上的一个文件夹中获取文件列表,然后你需要从列表中选择一个随机声音文件并播放它(参见图 8.14)。
图 8.14。DJ Raspi 程序的下一步是获取一组声音文件。稍后,你将添加使用按钮触发从列表中播放随机声音的部分。

在 Python 中,你可以轻松地创建列表或事物组。让我们看看一些例子。
让我们创建一个篮球运动员名字的列表。通过在菜单>编程下选择 Python 3.x Shell 来打开 IDLE。在 Python Shell 中,创建一个列表:
>>> basketball_players = ["Kevin Durant", "LeBron James", "Chris Paul",
"John Wall"]
按照这种方式打印列表,你就会看到里面的内容:
>>> print(basketball_players)
['Kevin Durant', 'LeBron James', 'Chris Paul', 'John Wall']
要创建一个项目列表,将它们放入一组方括号([])中,并用逗号分隔每个项目(参见图 8.15)。对于字符串列表,列表中的每个项目都必须用引号包围。很简单!这就是 Python 的方式。
图 8.15。你通过使用方括号括起来的一组事物来创建列表。列表中的每个项目都应该用逗号分隔。Python 甚至允许你创建包含不同类型数据的列表,如字符串和整数。

尝试创建一个名为favorite_numbers的列表,如下所示:
>>> favorite_numbers = [22, 27, 49, 121, 2, 25]
使用print显示列表的内容:
>>> print(favorite_numbers)
[22, 27, 49, 121, 2, 25]
注意
当制作数字列表时,你不需要使用任何引号。
享受制作你最喜欢的东西的列表!
列表可以做的更多事情
你可以用列表做很多事情!让我们试几个。
你可以通过向列表中添加更多项目来使列表更长。为此,请使用append方法。让我们向basketball_players列表中添加 Stephen Curry 的名字。以下是使用append来完成此操作的方法:
>>> basketball_players.append("Stephen Curry")
使用print来查看结果:
>>> print(basketball_players)
['Kevin Durant', 'LeBron James', 'Chris Paul', 'John Wall', 'Stephen Curry']
太棒了!要从列表中删除一个项目,你可以使用remove方法。如果你想从列表中移除 John Wall,可以这样写
>>> basketball_players.remove("John Wall")
再次打印列表以查看它是否工作:
>>> print(basketball_players)
['Kevin Durant', 'LeBron James', 'Chris Paul', 'Stephen Curry']
太棒了!如果你需要按字母顺序或从低到高对列表进行排序,你可以使用sort方法,如下所示:
>>> favorite_numbers.sort()
通过将列表打印到屏幕上来检查它是否工作:
>>> print(favorite_numbers)
[2, 22, 25, 27, 49, 121]
数字都排序了!这也适用于字符串列表。如果你对basketball_players列表进行排序,它将根据每个字符串的第一个字母按字母顺序排列。Python 为列表提供了许多内置方法。
查阅在线 Python 文档^([a])以获取更多关于列表的操作。然后坐下来享受思考你可以在未来的程序中使用它们的所有可能性。
^a
前往 Python 网站获取有关列表操作的信息:
docs.python.org/3.4/tutorial/datastructures.html。
对于你的 DJ Raspi,让我们看看如何
-
获取列表中存储的项目值。
-
获取列表的长度。
获取列表中存储的项目值
让我们从一个新的篮球运动员列表开始:
basketball_players = ["Kevin Durant", "LeBron James", "Chris Paul",
"Stephen Curry"]
如你所见,列表存储信息。你可能不知道的是,列表中的每个位置都有一个称为索引的数字。列表中第一个项目的索引是零(0)。第二个项目的索引是 1。第三个项目的索引是 2,以此类推。要获取basketball_players列表中的第三个项目,你将输入
>>> print(basketball_players[2])
Chris Paul
如果你想要搜索列表,并让 Python 告诉你项目在列表中首次出现的位置索引,你可以使用index方法:
>>> basketball_players.index("Kevin Durant")
0
>>> basketball_players.index("Stephen Curry")
3
如果项目不在列表中,Python 会给出错误信息:
>>> basketball_players.index("Me")
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
basketball_players.index("Me")
ValueError: 'Me' is not in list
注意
记住,列表的索引从 0 开始计数,而不是 1!例如,basketball_players[1]将给你"Lebron James",这是列表中的第二个项目。
图 8.16 展示了列表的索引示例以及如何获取列表中的特定项。
图 8.16. 可以将事物集合存储在列表中。你可以使用索引从列表中检索项目,索引代表项目在列表中的位置。列表的索引从 0 开始。

获取列表的长度
最后,有时你已经将信息加载到列表中,需要一种方法来检查列表的长度。使用len()函数来完成:
>>> yummy_snacks = ["chips", "popcorn", "donuts", "cheese",
"pretzels", "spam"]
>>> print(len(yummy_snacks))
6
干得好——你已掌握了列表的基础知识。现在让我们看看如何创建 MP3 列表。
使用 os 库构建声音文件列表
要使 DJ Raspi 项目工作,你需要
1. 从你的 Pi 上的文件夹中抓取两组声音文件列表。
2. 在 DJ Raspi 程序中,使用 OMXPlayer 从 Python 播放声音文件。
让我们学习如何。
Pi 通过一个名为os模块(OS 代表操作系统)的 Python 模块具有这两种能力。使用它,你可以从 Python 程序中运行操作系统命令(你可以在终端窗口中输入的命令)。这太棒了,因为它意味着你可以获取文件列表,也可以调用 OMXPlayer 来播放特定文件——这正是你所需要的!
从文件夹中获取文件列表:使用 listdir()
如你在第 8.1 节中看到的,你的 Pi 上已经有一些声音文件。你将使用这两个文件夹中的文件:
-
/usr/share/scratch/Media/Sounds/Music Loops/
-
/usr/share/scratch/Media/Sounds/Vocals/
os库提供了一个内置函数os.listdir(some_path),用于获取some_path路径下的文件列表。要获取 Scratch 音乐循环和声乐的列表,使用以下命令:
# Folders with sound files
path_music = "/usr/share/scratch/Media/Sounds/Music Loops/"
path_vocals = "/usr/share/scratch/Media/Sounds/Vocals/"
# Creating two lists with the files in the folders
sounds_music = os.listdir(path_music)
sounds_vocals = os.listdir(path_vocals)
如果你打印列表,你将得到类似这样的内容:
print(sounds_music)
['Cave.mp3', 'Techno.mp3', 'HipHop.mp3', 'Triumph.mp3', 'Medieval2.mp3',
'HumanBeatbox2.mp3', 'DripDrop.mp3', 'Xylo3.mp3', 'GuitarChords1.mp3',
'DrumSet2.mp3', 'Xylo2.mp3', 'DrumSet1.mp3', 'Garden.mp3',
'GuitarChords2.mp3', 'Jungle.mp3', 'Xylo1.mp3', 'Eggs.mp3',
HumanBeatbox1.mp3', 'Drum.mp3', 'DrumMachine.mp3', 'Techno2.mp3',
'Medieval1.mp3', 'xylo4.mp3']
print(sounds_vocals)
['Oooo-badada.mp3', 'Singer1.wav', 'BeatBox1.wav', 'Ya.wav',
'BeatBox2.wav', 'Come-and-play.mp3', 'Hey-yay-hey.mp3',
'Doy-doy-doy.mp3', 'Singer2.wav', 'Got-inspiration.mp3',
'Join-you.mp3', 'Sing-me-a-song.mp3']
哇——你有一些看起来很棒的列表!但是等等:看起来sounds_vocals有 WAV(.wav)文件和 MP3。让我们过滤掉 WAV 文件,这样你只剩 MP3。
仅过滤 MP3 文件
要过滤列表,你可以使用 Python 的列表推导功能。列表推导是一种快速创建列表的方法。当你使用它时,你可以包括某些条件或应用于列表项的操作,例如确保列表中的所有文件都以.mp3 结尾。让我们看看如何使用列表推导从旧列表创建新列表,但只保留以.mp3 结尾的文件:
sounds_music = [sound for sound in sounds_music if
sound.endswith('.mp3')]
sounds_vocals = [sound for sound in sounds_vocals if sound.endswith
('.mp3')]
列表推导式内部有一个for循环。在这种情况下,Python 正在遍历原始声音列表中的声音文件列表。对于列表中的每个项目,Python 只有在它符合以.mp3 结尾的条件时,才会将其添加到新的声音列表中。
按钮被按下时播放声音
在你的计划中的下一步是编写代码,当按钮被按下时,将从你的列表中播放一个随机声音。你需要将其放在一个循环中,以便反复检查按钮是否被按下(见图 8.17)。让我们首先创建游戏的标题和创建主游戏循环。
图 8.17. DJ Raspi 程序的主要部分是检查按钮的循环。你将使用一个while循环来反复检查按钮。如果其中一个被按下,你将告诉 Raspbian 使用 OMXPlayer 播放一个随机声音。

检查按钮的循环
首先,让我们添加一些代码来显示标题屏幕和 DJ Raspi 的说明。你可以随意使标题屏幕更华丽!
列表 8.2. DJ Raspi 标题屏幕

现在让我们编写代码来反复检查是否按下了任一按钮。当按钮被按下时,GPIO 引脚将给你一个 True 的响应,然后你可以调用一个函数来播放一个随机的 MP3。
列表 8.3. DJ Raspi 游戏循环

代码反复检查按钮 1 或按钮 2 是否被按下。如果按钮 1 被按下,代码将播放一个随机的音乐声音。如果按钮 2 被按下,代码将播放一个随机的声乐(唱歌)声音。如果两个都没有被按下,代码将循环回来再次检查。循环永远不会结束,所以你需要按 Ctrl-C 来退出程序。
播放声音:使用 Python 中的操作系统命令
你已经准备好播放你的声音了!os模块将允许你运行操作系统命令(你通常在终端中运行的命令)。要播放sounds_music列表中的第一个声音,你可以写
os.system("omxplayer -o local '" + path_music + sounds_music[0] + " &")
在本章的后面部分,我们将解释为什么该命令的末尾有一个和号(&)。此命令的结果将与在 Raspbian 命令行中键入以下内容相同:
omxplayer –o local "/usr/share/scratch/Media/Sounds/Music Loops/Cave.mp3"
注意
记住,如果你要将声音输出到 HDMI(如果你的电视有扬声器),你需要将–o local更改为–o hdmi。
太棒了!让我们回顾一下你到目前为止学到的内容:
-
你的 Pi 可以使用 OMXPlayer 播放 MP3 格式的声音。
-
Python 可以将事物集合存储为列表。
-
Python 的
os库有一个名为listdir(path)的函数,可以给你一个文件夹中的声音列表。 -
Python 的
os库中有一个os.system(command)函数,可以从 Python 中运行操作系统命令,例如使用 OMXPlayer 播放声音。
函数!
让我们思考一下如何为 DJ Raspi 编写函数。你需要创建两个函数:
-
get_MP3_sounds—此函数将从指定的文件夹中获取以 .mp3 结尾的声音列表。你将告诉该函数(传递一个参数)你想要获取 MP3 声音文件的文件夹名称。该函数将返回一个声音列表。 -
play_random_sound—此函数将接受一个声音列表,随机选择一个数字,然后使用os.system告诉 Raspbian 使用 OMXPlayer 播放声音。
图 8.18 展示了这些函数在流程图中的位置。
图 8.18. 有两个地方可以创建函数,以便你可以重用代码。一个函数创建声音文件列表,另一个函数在按下按钮时播放随机声音。

为什么不将其作为一个单独的函数呢?一个原因是你只需要在程序开始附近加载一次声音文件列表。每次按下按钮时,你都会播放声音文件。列表 8.4 展示了 get_MP3_sounds 和 play_random_sound 函数的代码。
注意
记得将这些函数放在程序的开头附近。它们必须在第一次使用之前添加。
在此列表的末尾,你使用(或调用)get_MP3_sounds 两次以获取你的音乐和声乐声音文件列表。
列表 8.4. 加载和播放声音文件的函数

你可能已经注意到,此行添加了一些额外的东西:
os.system("omxplayer -o local '" + sound_path +
"/" + sound_filesound_files[random_sound_index] + "' &")
此行将运行 OMXPlayer 的命令与你的声音文件路径 (sound_path) 以及你想要播放的随机声音文件 (sound_filesound_files[random_sound_index]) 相结合。在最后,你添加一个和号 (&)。和号告诉 Raspbian 在后台运行命令。这样你就可以快速按下一个按钮,然后按下另一个按钮。
同时做多件事:遇到和号 (&)
当你播放声音时,你希望能够像 DJ 一样快速地按下按钮,并且让声音重叠以创建有趣的音乐。通常,你的 Pi 会播放一个声音,当它播放完毕后,让你播放另一个。这不是你想要的。以下是一个播放两个声音的例子。你只能在第一个命令完成后才能运行第二个命令:
omxplayer /usr/share/scratch/Media/Sounds/Vocals/Oooo-badada.mp3
omxplayer /usr/share/scratch/Media/Sounds/Vocals/Hey-yay-hey.mp3
幸运的是,你的树莓派可以同时做几件事情。你可能同时打开几个不同的窗口。每个窗口都连接到在树莓派上运行的某些底层代码或指令集。这些底层代码集被称为进程或线程。Raspbian,像其他现代操作系统一样,管理这些进程并为每个进程分配其唯一的 ID 号。命令末尾放置的符号&告诉你的树莓派以另一个进程的形式在后台运行该命令,与任何其他进程并行。
再次尝试这两个命令,但这次使用符号“&”:
omxplayer /usr/share/scratch/Media/Sounds/Vocals/Oooo-badada.mp3 &
omxplayer /usr/share/scratch/Media/Sounds/Vocals/Hey-yay-hey.mp3 &
注意每个命令末尾的符号&。这样,树莓派就会播放你的声音,但代码不会在播放声音之前等待,然后再做其他事情。在 OMXPlayer 命令末尾添加一个符号&会使按钮在后台播放每个声音。移除符号&可以一次播放一个声音。因为这是操作系统的一个特性,所以使用符号执行命令作为它们自己的独特进程的概念也适用于你已知或将要学习的其他 Linux 命令。
太好了!你已经准备好测试你的项目了!
测试:DJ Raspi 的第一次演出
将代码保存为 DJRaspi.py,然后尝试运行它。从 IDLE 文本编辑器中选择运行 > 运行模块(或按 F5)来运行你的程序。如果你有较旧的 Raspbian 版本(2015 年 10 月之前),使用 GPIO 引脚的程序必须以超级用户(或 root)的身份从 Raspbian 命令提示符运行。打开终端,并输入以下命令:
pi@raspberrypi ~ $ sudo python3 DJRaspi.py
你应该看到标题屏幕显示。通过按按钮来测试它,看看它们是否工作。
注意
记住,任何使用 GPIO 引脚的程序都必须以超级用户(或 root)的身份从 Raspbian 命令提示符运行。
信不信由你,程序第一次就能完美运行的情况很少。如果它没有,请阅读以下“故障排除”部分,并检查你的电路和程序,以尝试找出如何让它工作。
故障排除
如果你按下按钮时声音没有播放,这里有一些你可以检查的事情:
-
检查面包板上的电路。扁平电缆是否正确连接,第一根线是否连接到你的树莓派边缘,远离 USB 端口?
-
仔细检查跳线、按钮和电阻是否在正确的孔中,并且完全压入面包板。
-
你的程序是否打印了“你按了 #1!”和“你按了 #2!”?如果是这样,你就知道你的电路是正常工作的,要么是加载声音文件的代码有问题,要么是你的扬声器或耳机不工作。尝试从终端运行以下命令之一来检查扬声器是否工作。对于插入 3.5 毫米音频输出的耳机或扬声器:
omxplayer –o local /usr/share/scratch/Media/Sounds/Vocals/ Oooo-badada.mp3对于通过 HDMI 连接的电视扬声器:
omxplayer –o hdmi /usr/share/scratch/Media/Sounds/Vocals/ Oooo-badada.mp3 -
检查你的 Python 程序中的错误。尝试在你的函数中添加一些
print语句,以确保它们正确地获取 MP3 文件列表。
如果你喜欢创建 DJ Raspi,请查看按钮挑战。

挑战
尝试这些按钮活动,增加乐趣!
双按钮按下惊喜
给你的程序一个惊喜的按钮组合。看看你是否可以同时按下两个按钮来播放一组新的声音效果。
提示:当你想要同时满足两个条件时,可以使用和号(&)。如果第一个和第二个条件都为真,if 语句才会为真。它看起来像这样:
if GPIO.input(button_pin1) & GPIO.input(button_pin2):
print("Both buttons are pressed!")
这里是 Pi 上一些 Scratch 声音效果路径:
path_effects = "/usr/share/scratch/Media/Sounds/Effects/"
尤达魔法八球
有一个很经典的玩具叫做魔法八球。当你摇晃它时,它会显示一个问题的答案。问它一个问题,你会得到一些真正神奇的建议。魔法八球有 20 个不同的答案,从“肯定如此”到“我的消息来源说不是”。
注意
我不建议使用魔法八球来就重大生活问题提供建议!
你的挑战是制作一个魔法八球程序:
-
大声提出一个问题,然后按下一个按钮。
-
按下按钮会使你的 Pi 从文件夹中随机选择一个尤达剪辑并播放。
要开始,找到一些尤达的简短语音文件。一个可以找到这些文件的地方是 soundboard.com。搜索“yoda”看看是否能找到一些好的剪辑(你需要创建一个账户来下载它们供个人使用)。
奖励:尝试给你的 Pi 添加一个方便的按钮,每次按下它都会播放蒙提·派森的声音剪辑。
继续探索
现在,你已经给了 Pi 一种新的触觉感知,你只需要更改几行代码就可以制作许多其他项目,例如这些:
-
每次按下按钮时都会显示不同的数字照片的交互式显示屏
-
你自己的 Raspberry Pi 电影播放器,按下按钮即可播放剪辑或电影
-
一个 MP3 音乐播放器,可以播放你最喜欢的歌曲
你还可以将按钮扩展到传感器,例如被动红外(PIR)传感器或摄像头。例如,PIR 传感器可以检测传感器附近的运动。这些非常适合创建 Pi 安全系统或在你家门口吓唬人的东西。也许你想触发一个电影,让一个恐怖的僵尸头出现,或者产生令人毛骨悚然的尖叫声。你唯一的限制是你的想象力和淘气的想法。
概述
在本章中,你学习了
-
Pi 可以通过 GPIO 引脚的输入能力感知其周围的环境。这为 Pi 拥有类似人类甚至超人的感官创造了无限可能。
-
Python 列表使得存储和检索诸如数字、声音文件、图像和视频等集合的事物变得容易。
-
按钮作为简单的开关,向你的 Pi 的 GPIO 引脚发送少量电流,它可以检测到。在连接按钮或其他传感器时,你无需担心!
-
Python 程序可以使用
os库运行 Raspbian 命令。这为你的程序打开了众多可能性,从播放音乐到显示或录制视频,显示或拍照,以及从网站获取信息。
你已经完成了一次学习 Python 编程和如何使用你的 Raspberry Pi 的伟大冒险。但前方还有更多的兴奋等待着你。查看附录 D 以获取更多你可以用你的 Pi 实现的项目想法。有了你的 Raspberry Pi、Python 知识以及一点无畏,可能性是无限的!
附录 A. Raspberry Pi 故障排除
在本附录中,你将学习如何解决设置 Raspberry Pi 时常见的问题。我们将涵盖常见的 Pi 启动(或引导)问题,包括如何修复 Pi 的 SD 卡问题或设置新的 SD 卡。
确保你的 Pi 有电源
有时 Pi 不会启动。在你尝试像为 Pi 创建新的 SD 卡这样的极端措施之前,检查 Pi 的电源:
-
当你插入你的 Pi 时,Pi 的红色电源灯亮了吗?在你的 Pi 板上寻找一个小红色灯(LED)。所有的 Pi 都有,但如果你看不到 Pi 板,你可能需要取下你的外壳。红色电源灯告诉你你的 Pi 正在接收电源。当你插入 Pi 时,它应该亮起,并且在你使用整个过程中保持亮着。如果它没有亮起,这意味着你的 Pi 没有接收电源。检查电源是否已插入。如果你使用的是电源插座,请检查它是否已打开。遗憾的是,一些电源插座制作得不好。如果问题是电源问题,请购买一个新的电源插座。
-
在红色灯旁边,当你插入 Pi 时,绿色活动灯(LED)是否闪烁很多?闪烁是 Pi 正在做某些工作的标志。绿色活动灯应该开启和关闭,有时快速闪烁,当 Pi 启动时。当它完成启动后,绿色灯会关闭,并且只有在 Pi 正在积极做某事,如打开游戏或 Python 时才会亮起。如果绿色灯亮起并保持亮着,但屏幕上没有显示任何内容,这很可能是 SD 卡的问题。跳转到 A.4 部分学习如何创建新的 SD 卡。
如果你怀疑是电源问题,购买一个新的电源插座并尝试使用它。为 Pi 提供足够的电功率(2 安培)和正确的电压(5 伏特)对于 Pi 正常工作非常重要。
检查你的电视或显示器连接
如果你插入 Pi 后红色灯保持亮着,绿色灯亮起并关闭,但你没有在电视或显示器上看到任何图像,那么是时候检查你的屏幕连接了。以下是一些根据你使用的电视或显示器类型需要调查的事项。
如果你从 Pi 连接 HDMI 线缆到电视或显示器,尝试以下事项:
-
确保电视或显示器已打开。
-
确保电视或显示器已设置为正确的输入。它们通常有多个输入,你必须按一个输入按钮来选择正确的输入。否则,屏幕将显示无内容或检测不到输入的消息。
-
如果你有多余的 HDMI 线缆,尝试使用它来查看是否是线缆的问题。
如果你的设置需要你使用适配器将 Pi 连接到电视或显示器,那么你可能需要确保你的适配器工作正常或类型正确。有两种常见的适配器类型:
-
HDMI-to-DVI 适配器 —此适配器用于将 Raspberry Pi 的 HDMI 线缆连接到具有数字视觉接口(DVI)端口的显示器。有时您可能会购买一个不起作用的适配器。如果可能,尝试将您的 Pi 连接到另一个使用 HDMI 的电视或显示器,以检查是否是适配器的问题。再次提醒,如果红灯亮起且绿灯闪烁,但您在屏幕上什么也看不到,那么很可能是显示器连接的问题。
-
HDMI-to-VGA 适配器 —较旧的显示器没有 HDMI 或 DVI 端口,可能只有视频图形阵列(VGA)端口。您唯一的选项可能是购买一个 HDMI-to-VGA 适配器来将 Pi 连接到显示器。并非所有 HDMI-to-VGA 适配器都适用。您最好的选择是从销售 Raspberry Pi 的商店购买一个标明适用于 Pi 的适配器。如果您不确定,请尝试仅使用 HDMI 线缆将 Pi 连接到另一台电视或显示器进行测试,以确定是否是您的问题。
如果执行了所有这些步骤后您仍然看不到图片,那么很可能是您的 SD 卡有问题。
Pi 启动但随后停止
您可能还会遇到的问题是,您的 Raspberry Pi 开始启动,您在屏幕上看到一系列消息,然后消息停止,但 Pi 没有达到 Raspbian 桌面或命令行。如果是这种情况,那么很可能是 SD 卡已损坏。但另一个原因是您的 GPIO 引脚中可能存在问题。
如果您在连接到 Pi 的面包板上构建电路(请参阅第六章章节 6–8 章中的示例),如果连接不当,Pi 可能无法完全启动。为了确定这是否是问题,请从 Pi 上断开扁平电缆和面包板,然后再次尝试开机。如果问题仍然存在,那么很可能是 SD 卡的问题。
将 Pi 设置为新的 SD 卡
仍然无法启动?SD 卡问题是一个常见原因。如果 Pi 在信息存储(或写入)时关闭,SD 卡可能会停止工作,或者它可能会因老化而损坏。
注意
当 SD 卡失败时,您需要从头开始,并且您将丢失卡上任何数据或新安装的应用程序。将来,您可以创建 SD 卡的备份。查看在线论坛了解如何进行此操作。
如果您认为这是问题所在,您有几个选择:
1. 使用 Raspberry Pi 新出厂软件(NOOBS)清洁和重置您的 SD 卡。
2. 从销售 Raspberry Pi 的许多在线商店之一购买一张新卡。它们的价格大约为 10 美元。
让我们回顾一下如何使用 NOOBS 清洁和设置您的 SD 卡。执行这些步骤需要另一台计算机,例如 Windows PC 或 Mac。
重新格式化您的 SD 卡
格式化是将存储器设置起来以便可以在其上放置信息的过程。要重新格式化 SD 卡并使用 NOOBS 的新版本设置,请执行以下操作:
1. 使用您的另一台电脑,从 SD 协会网站:
www.sdcard.org下载并安装 SDFormatter 软件。在网站上,查找下载部分,下载适用于 Windows 或 Mac 的 SDFormatter 的适当版本。按照安装说明在您的电脑上加载软件。2. 将 SD 卡插入电脑。注意插入后分配给 SD 卡的驱动器字母:它可能是 E:、F:或类似。
注意
对于树莓派 2 型和 B+型号,SD 卡是 microSD 卡,因此您需要一个 microSD 到 SD 卡适配器才能将其插入电脑的 SD 卡槽。您可以在网上购买此类适配器。
3. 打开 SDFormatter,选择您的 SD 卡的正确驱动器字母,然后点击格式化(见图 A.1)。它将询问您是否要继续。接受警告以重新格式化 SD 卡。
图 A.1. 使用 SD 协会网站提供的 SDFormatter 软件清理(或重新格式化)您的 SD 卡。在 SDFormatter 中,选择您的 SD 卡的驱动器字母,然后点击格式化以清除您的卡片。这个过程意味着您将从头开始——您将丢失在 Pi 上保存或安装的所有内容——但有时这是唯一的选择。
4. 访问树莓派网站
www.raspberrypi.org/downloads,点击链接下载 NOOBS 压缩文件。这是一个大文件,所以下载时可以准备些小吃。5. 解压 NOOBS 压缩文件,并将所有解压的文件拖到 SD 卡上。
6. 文件复制完成后,将 SD 卡从电脑中取出,放入树莓派中。连接键盘、鼠标和显示器后,插入树莓派以查看是否启动。如果无法启动,可能需要从销售树莓派的本地或在线商店购买新的 NOOBS SD 卡。
未涵盖的问题
这里不可能涵盖所有内容,所以请上网查找!大量故障排除信息发布在树莓派论坛上。如果您遇到问题,请在互联网上搜索“树莓派故障排除”,您将找到许多资源。虽然我们都是特别的,但很少遇到其他人没有发现的问题。很可能,许多其他人也遇到了同样的问题,所以请阅读论坛,从树莓派用户社区的多样性中受益所有知识!
附录 B. Raspberry Pi 端口和旧版板
在本附录中,您将找到有关一些 Raspberry Pi 端口和连接的信息,这些信息我们在第一章中没有讨论。我们的重点是 Raspberry Pi 2 Model B。我们将更详细地介绍以下连接和端口:
-
使用 USB 无线网卡进行无线互联网连接
-
3.5 mm 音频/视频端口
-
摄像机串行接口(CSI)端口
-
以太网端口
-
电视或显示器连接选项
在本附录的 B.2 节中,我们将回顾旧版 Raspberry Pi 1 模型与 Raspberry Pi 2 Model B 之间的关键差异。我们将更多地关注这些流行但较旧的模式:
-
Raspberry Pi 1 Model B rev 2(2012 年 9 月发布)
-
Raspberry Pi 1 Model B+(2014 年 7 月发布)
让我们更仔细地看看端口和连接。
Raspberry Pi 端口
Raspberry Pi 有许多不同的端口,您可以将许多不同的东西连接到它。在第一章中,我们介绍了您将使用的常见端口,但在这里我们将讨论一些其他端口。为了参考,图 B.1 显示了 Raspberry Pi 2 Model B 的端口及其典型用途。
图 B.1. Raspberry Pi 2 Model B 有许多不同的输入和输出端口,允许您连接键盘或鼠标、显示器,甚至高清摄像头。

现在,让我们更详细地看看一些我们在第一章或后续章节中没有涉及的一些端口和连接。
连接到无线网络
连接到互联网的一个首选方式是使用 USB 无线网卡。一旦连接,您就可以上网冲浪,从 Pi 商店下载应用程序,或从另一台电脑远程登录到您的 Pi。我们大多数人没有将 Pi 设置在以太网电缆附近,因此无线连接是最佳且唯一的选择。让我们看看如何操作。
插入您的 USB 无线网卡
关闭您的 Raspberry Pi,将 USB 无线网卡插入其中一个 USB 端口。有许多不同的 USB 无线网卡可以用于 Pi。大多数套件都附带一个,但如果您需要购买一个,请参考 Raspberry Pi 论坛(见[www.raspberrypi.org/forums/](https://www.raspberrypi.org/forums/))以研究那些已知可以工作的型号。销售 Raspberry Pi 的商店也倾向于销售兼容的 USB 无线网卡。
配置您的 Wi-Fi 连接
要首次连接到 Wi-Fi 网络,请按照以下步骤操作:
在右上角,点击网络图标(看起来像两个小电脑相连)。您将看到可用的 Wi-Fi 网络列表(见图 B-2)。
图 B.2. 网络连接图标位于 Raspbian 桌面右上角。点击它允许您查看附近的无线网络。

点击您想要连接的 Wi-Fi 网络名称。
点击 Wi-Fi 网络名称将弹出一个小窗口。输入预共享密钥(也称为 Wi-Fi 密码)并点击“确定”以连接(见图 B.3)。网络图标将更改为 Wi-Fi 图标,显示 Wi-Fi 信号的强度。
图 B.3. 输入网络的预共享密钥并点击“确定”以连接到它。

太棒了!打开网页浏览器,例如您的树莓派的 Epiphany 网页浏览器,并访问您最喜欢的网站以享受您的新 Wi-Fi 连接。
故障排除
如果您无法连接,请检查您输入的预共享密钥是否正确。如果正确,并且您的网页浏览器显示错误消息“无法解析主机名”,那么您的树莓派可能需要更新其 IP 地址。IP 地址是一系列唯一的数字,无线路由器将其分配给您的树莓派和其他网络设备。要更新树莓派的 IP 地址,请打开终端并输入以下两个命令:
pi@raspberrypi ~ $ sudo dhclient -v -r eth0
pi@raspberrypi ~ $ sudo dhclient -v eth0
如果您仍然无法连接到互联网,请联系设置或管理网络的人以获取帮助。
3.5mm 音频/视频端口
不论是贝多芬、Lady Gaga 还是 Minecraft 中的爬行者爆炸声,您都希望在您的树莓派上听声音。认识一下 3.5mm 音频/视频端口(见图 B.4)。这个端口是一个黑色带圆形孔的连接器^([1])。它之所以得名是因为孔的直径为 3.5mm。连接耳机或一套带电源的电脑扬声器来听树莓派的声音。
¹
在较旧版本的树莓派上,端口可能是蓝色而不是黑色。
图 B.4. 树莓派的 3.5mm 音频/视频端口用于连接耳机或扬声器以播放声音。如果您购买 3.5mm 到 RCA 复合视频适配器,它也可以作为低质量视频输出使用。

小贴士
如果您连接电脑扬声器,请使用带电源的扬声器,例如与台式电脑或 iPod 一起使用的类型。从树莓派 3.5mm 音频/视频端口输出的声音仅足够一对耳机或耳塞使用。如果您想让房间里的人都能听到您的音乐,请连接一套带内置放大器的带电源扬声器,以增强声音。
从树莓派 1 Model B+和树莓派 2 Model B 开始,此端口也可以用于输出视频信号。视频信号不是像 HDMI 端口那样的高分辨率,但在紧急情况下,它是一个选项。输出视频信号是复合视频或单通道视频,意味着所有视频信号都通过一根线输出。这是许多旧款 DVD 播放器和视频游戏机曾经使用过的。您可以购买一根插入端口的电缆,另一端有 RCA 连接器,以便将您的树莓派连接到旧电视。
摄像头串行接口:连接摄像头
如果您想尝试时间流逝摄影或设置一个相机来拍摄野生动物或宠物的照片,您将需要将一个相机添加到您的 Pi 上。将高清数字相机添加到 Raspberry Pi 的最佳方式是使用 Raspberry Pi 相机模块。由 Raspberry Pi 基金会创建,它通常不包含 Pi 套件,因此您需要单独购买。该模块包含一个安装在电路板上的 500 万像素相机,并附带一根短扁平电缆(参见图 B.5)。
图 B.5. Raspberry Pi 相机模块是由 Raspberry Pi 基金会创建的,用于拍摄高清数字照片和视频。该相机通过连接到 Camera Serial Interface 端口的扁平电缆连接到 Pi。相机模块可以使用 Python 进行编程,用于自然摄影或创建您自己的家庭监控系统。

相机连接到 Pi 的 Camera Serial Interface (CSI) 端口(参见图 B.6),可以拍摄静态照片或高清视频。该模块能够轻松连接到 Pi 并录制高清视频,同时比使用 USB 相机消耗更少的处理能力。
图 B.6. Raspberry Pi 相机可以连接到 CSI 端口,该端口位于 HDMI 端口和 3.5 毫米音频/视频端口之间。要连接相机,您需要抬起黑色连接器,插入扁平电缆(金属接触面向 HDMI 端口),然后再次按下黑色连接器。

要连接相机模块,请按照以下步骤操作:
1. 通过抬起黑色塑料连接器的顶部部分来打开 Pi 上的 CSI 连接器。
2. 将扁平电缆的末端插入 CSI 连接器。扁平电缆上的光亮金属触点应朝向远离以太网端口,朝向 HDMI 端口(参见图 B.6)。
3. 将黑色塑料连接器推回原位以关闭它,夹紧扁平电缆到连接器中。
小贴士
Pi 相机板附带一根短扁平电缆。如果您需要更长的电缆,您可以在像 Adafruit 这样的在线商店找到延长电缆。
一旦连接了相机模块,您需要启用它。打开终端以进入 Raspbian 命令行模式。输入命令以打开 Raspberry Pi 配置菜单:
pi@raspberrypi ~ $ sudo raspi-config
当出现蓝色屏幕和 Raspberry Pi 配置菜单时,选择选项 5:启用相机。选择启用,然后在主配置菜单中选择完成。您的 Pi 将询问您是否要现在重启;选择是。当 Pi 重启后,通过打开终端并输入
pi@raspberrypi ~ $ raspistill -t 3000 -o PiPhoto.jpg
这将在 3 秒后打开相机并拍照。–t 3000部分告诉raspistill程序等待的时间——在这种情况下,它设置为 3,000 毫秒或 3 秒。图片被保存到名为 PiPhoto.jpg 的文件中。你可以通过打开文件管理器并查看 pi\home 文件夹来查看文件。查看在线资源以获取更多你可以用你的相机做的事情,包括使用 PiCamera,这是一个用于控制相机的 Python 库。
如果你考虑在夜间拍摄视频或照片,有一个 Pi 相机模块的替代版本,称为 Pi NoIR(近红外)相机模块。它使用相同的 CSI 端口并以相同的方式连接。一个区别是,你需要在你要拍摄的目标上照射红外光源。有了 Pi NoIR,你就可以用 Pi 进行一些夜间恶作剧的新可能性。
以太网端口
有互联网连接可以让你使用 Pi 浏览网页和下载软件;你甚至可以从另一台电脑控制你的 Pi。你的树莓派的以太网端口位于 USB 端口旁边(参见图 B.7)。使用以太网端口是连接树莓派到互联网的简单方法。唯一的问题是,你需要将 Pi 放在以太网线缆可以到达的地方。
图 B.7. 树莓派的以太网端口支持将 Pi 连接到家庭网络。从你的 Pi 到你的路由器或调制解调器连接一根以太网线缆以访问互联网。当你的 Pi 连接到网络时,你可以使用特殊的程序(如 SSH 和 VNC Server)从另一台电脑远程连接到 Pi。

电视或显示器连接选项
如果你的电视或显示器有 HDMI 端口或 DVI 端口,连接树莓派到电视或显示器是最容易的;这已在第一章中介绍。但如果你没有这些端口怎么办?还有其他方法可以将 Pi 连接起来。让我们首先识别你可能在电视或显示器后面看到的几种不同类型的端口,然后学习如何将 Pi 连接到它们。
识别端口并建立连接
花时间研究你的电视或显示器上的连接。尝试识别视频端口,并将它们与图 B.8 中的连接器图片进行比较。
图 B.8. 电视和显示器上常见的视频输入端口类型。树莓派可以连接到这些端口中的任何一个。一些端口(DVI、VGA、RCA [或复合] 和分量)需要使用带有 Pi 的特殊适配器或转换器。

对于某些端口,你可能需要购买一个适配器,将一种类型的端口转换为另一种类型。我们将介绍 VGA、RCA 和分量端口。有关 HDMI 和 DVI 端口的连接,请参阅第一章。
RCA 端口
这种类型的端口是一个黄色、圆形的连接器。它通常位于红白 RCA 音频连接器旁边。
您需要购买一根特殊的线缆,一端是 3.5 毫米四极插头,另一端是 RCA 复合视频和音频线缆。将线缆插入 3.5 毫米音频/视频端口,并将另一端插入您屏幕的复合视频输入。通常,屏幕旁边会有红白音频输入插头。如果您想同时有声音,请连接红白 RCA 音频插头(参见图 B.9)。
图 B.9. Raspberry Pi 可以通过 RCA 视频线连接到电视或显示器。该线缆从 Pi 的 3.5 毫米音频/视频端口连接到电视或显示器上的 RCA 视频输入端口。使用 RCA 连接会产生低质量的图像,但如果您没有支持 HDMI 的电视或显示器,这可以是一个不错的选择。

VGA 端口
VGA 端口顶部和底部是平的,侧面向内倾斜。端口有三排五个圆形针孔。不建议使用带有 VGA 端口的电视或显示器连接 Pi,因为您需要购买一个适配器,并且可能遇到配置 Pi 以检测您的显示器的问题。如果您决定尝试此选项,您将需要一个 HDMI 到 VGA 适配器。您还需要更新您的 Raspberry Pi 的配置设置。本书中未涵盖此内容,但 Raspberry Pi 论坛可以为您提供有关更改配置设置以使用 HDMI 到 VGA 适配器的更多信息。
组件视频输入
电视上的组件视频端口有一组三个圆形插头,分别是绿色、蓝色和红色。由于转换器的额外成本以及您可能需要额外配置 Pi 以成功连接到您的显示器,因此不建议使用此端口。如果您决定使用此选项,您将需要一个组件到 HDMI 转换器。这样的转换器应附带其自身的电源供应。避免那些不带电源供应的转换器,因为它们与您的 Pi 不兼容。转换器的价格大约为 50 美元,所以如果您有其他选择,请节省您的钱——尝试使用不同的电视或显示器,或者将这笔钱用于为您的 Pi 购买新的或二手的 LCD 或 LED 显示器。
在端口被覆盖的情况下,让我们来检查 Raspberry Pi 2 Model B 和旧型号板子之间的差异。
旧型号板子
Raspberry Pi 是由 Raspberry Pi 基金会制造的,在过去几年中已经发布了多个版本和型号。我们将展示并讨论这些板子之间的主要差异。
Raspberry Pi 1 Model B
Raspberry Pi 1 Model B 是许多人都喜爱的 Pi 版本。Pi 最初是为了帮助培养新一代的程序员和黑客而设计的,但它意外地受到许多爱好者和企业家的欢迎,因为他们可以用它做很多事情并制造出很多产品。该板子看起来与 Raspberry Pi 2 Model B 略有不同(参见图 B.10)。
图 B.10。Raspberry Pi 1 Model B 非常受欢迎。它被用于从科学研究到艺术和教育的各种应用。

下面是 Raspberry Pi 1 Model B 和 Raspberry Pi 2 Model B 之间的一些关键区别:
-
USB 端口 —Pi 1 Model B 只有两个 USB 端口。这使得连接键盘、鼠标和 USB Wi-Fi 适配器变得具有挑战性。一个很好的解决方案是使用带电 USB 集线器来连接更多的 USB 设备。
-
RCA(或复合)视频输出 —Pi 1 Model B 有一个专用的 RCA 连接器,可以连接到老式电视。Pi 2 Model B 将此集成到 3.5 mm 音频/视频端口中。
-
片上系统 —早期的 Pi Model B 使用单核 700 MHz 处理器,而 Pi 2 Model B 使用四核 900 MHz 处理器。因此,新模型的速度大约快四倍。
-
内存卡槽 —Pi 1 Model B 使用标准尺寸的 SD 卡。Pi 2 Model B 使用带有弹簧机构的 mini-SD 卡槽,以安全地固定卡片。
-
GPIO 引脚 —早期 Model B 的引脚数量和编号方式不同。旧型号只有 20 个引脚;新型号有 40 个引脚。如果你在使用 Pi 1 Model B,请参考在线参考资料以了解引脚编号。
Raspberry Pi 1 Model B+
在 Raspberry Pi 1 Model B 之后推出了 Raspberry Pi 1 Model B+。这些板子看起来非常不同。相比之下,如果你将 Raspberry Pi 1 Model B+与后来的 Raspberry Pi 2 Model B 进行比较,它们几乎完全相同——在可用的端口和端口位置方面,它们完全一样。图 B.11 展示了 Raspberry Pi 1 Model B+。
图 B.11。Raspberry Pi 1 Model B+是 Raspberry Pi 1 Model B 的重大改进。它将 USB 端口数量从两个增加到四个,增加了 GPIO 引脚,并改为使用 microSD 内存卡槽。Raspberry Pi 1 Model B+的端口与 Raspberry Pi 2 Model B 的端口相同。

与 Raspberry Pi 2 Model B 的关键区别如下:
-
片上系统 —B+型号拥有一颗 700 MHz 的单核处理器,而 Pi 2 Model B 则拥有四核 900 MHz 的处理器。
-
工作内存(RAM) —B+型号有 512 MB,而 Pi 2 Model B 有 1 GB。
其他板子
我们没有涵盖 Raspberry Pi Model A 或 A+,但许多端口是相同的。主要区别在于 Model A 和 A+只有一个 USB 端口,没有以太网端口,并且工作内存(RAM)更少——256 MB。当你的项目需要一个比 Model B 或 B+功耗更低的更小计算机时,Model A 和 A+非常有用。
附录 C. 章节挑战的解决方案
在这个附录中,你可以找到每个章节末尾提出的挑战的答案。对于需要比一页能容纳的更多代码行的挑战,我提供了提示和代码片段。解决方案的完整程序可以在与本书配套的代码下载中找到。代码中包含注释,以帮助您理解程序的设计和功能。挑战的解决方案按章节组织。让我们开始吧!
第一章
在第一章结束时,你将进行一次寻宝游戏:
-
松鼠 —要找到松鼠游戏,请选择菜单 > 游戏 > Python 游戏。选择你希望如何输出声音(音频)后,你将看到一系列 Python 游戏。松鼠游戏位于列表中间附近。赢得游戏,并实现欧米茄松鼠。
-
计算器 —选择菜单 > 附件 > 计算器。89 × 34 等于 3,026。
-
关机 —通过选择菜单 > 关机来关闭或重新启动你的树莓派。关机菜单允许你选择关闭、重启或注销。
-
黑色桌面 —要将桌面背景更改为黑色,请右键单击桌面上的任何位置,然后选择桌面首选项。在桌面首选项窗口中,屏幕中间查找背景颜色标签。单击白色框以选择新的背景颜色。单击“确定”以选择颜色,然后单击“关闭”以关闭桌面首选项窗口。
-
Scratch 奖励 —要打开 Scratch,请选择菜单 > 编程 > Scratch。当 Scratch 打开时,通过将程序块拖动到脚本区域为你的猫精灵构建一个程序。图 C.1 展示了一个示例,当按下空格键时,猫会来回跳舞 10 次。
图 C.1. 通过将程序块拖动到脚本区域,使猫在 Scratch 中跳舞。
![图片]()
第二章
本章的挑战是关于在屏幕上显示字符和一些数学运算。
矩阵
通过使用 print 函数和乘法运算符创建一个由 1 和 0 组成的屏幕,如下所示:
matrix = "0100101101001100100110001011001011110000010101"
print(matrix * 100)
建造砖墙
要解决这个问题,创建一个名为 brick 的变量,并给它一个如下的字符字符串:
brick = "|__"
print(brick * 1000)
要让砖块看起来像树莓,你可以尝试
brick = "|_o88{_"
print(brick*300)
用你的想象力来想象这是一个侧放的树莓砖。括号是树莓顶部的叶子。
π电子
你正在尝试计算每秒需要多少个电子才能等于流入你的树莓派中的 1 安培。使用 Python 的计算如下:
>>> electron_charge = 1.60 * 10**-19
>>> electrons_flowing = 1 / electron_charge
>>> print(electrons_flowing)
6.249999999999999e+18
答案是 6,250,000,000,000,000,000。那可是一大堆电子!
第三章
这些挑战是关于收集输入、合并字符串和在屏幕上显示文本。
骑士传说创作者 3000
要制作这个程序,你首先需要打印一个标题,然后从玩家那里收集一系列单词:

接下来,你将输入单词与故事连接起来。你可以逐句这样做,以使代码更容易理解:
sentence1 = "There was a brave knight, " + player_name + ", who was
sent on a quest to vanquish the " + adjective + " evildoer,
" + famous_person + ". "
sentence2 = "Riding on his/her trusty " + animal + ", the brave " +
player_name + " traveled to the faraway land of " + vacation_place
+ ". "
sentence3 = player_name + " battled valiantly against " + famous_person +
"'s army using his " + sharp_thing + " until he defeated them. "
sentence4 = "Emerging victorious, " + player_name + " exclaimed, '" +
exclamation + "!!!' I claim the land of " + vacation_place + " in the
name of Python."
最后,让我们将句子连接起来,并将故事显示在屏幕上:
tale = sentence1 + sentence2 + sentence3 + sentence4
print(tale)
潜意识信息
你试图创建一个隐藏在大量字符显示中的信息。你首先询问人的名字和他们想要的东西:

接下来,创建一个由字母、数字和符号组成的模式,你将在其中隐藏信息:
weird_characters = "*#ad@32*)23 )@*sad# 2&^ 32⁴²³!"
最后,你通过在屏幕上打印出消息前后字符的模式来创建完整的消息:“你真的很想为[player_name]买[thing]”,但将其隐藏:

第四章
本章的挑战是关于使用你的一些新技能,如if/then(或条件)语句,以及像random模块这样的工具箱。
石头、纸牌、剪刀!
对于这个挑战,你首先导入random模块,创建一个标题,并定义你将要需要的任何变量:
import random
play_again = "Yes"
choices = ["Rock","Paper","Scissors"]
接下来,你想要显示标题,然后启动一个while循环,该循环将收集玩家的选择并获取一个随机的电脑选择:

你接下来想要显示两个选择,并使用一个if语句来测试玩家和电脑的选择是否相同。如果不相同,你想要检查你是否拥有以下玩家对电脑的组合之一:
-
石头(玩家)胜过剪刀(电脑)
-
剪刀(玩家)胜过纸牌(电脑)
-
纸牌(玩家)胜过石头(电脑)
你将所有这些都在while循环中编程,因为你想要它重复,直到玩家想要再玩。在循环的末尾,玩家被问是否想要再玩一次:

你创建了一个大的if语句,用于测试player_choice和computer_choice是否形成以下获胜组合之一。每个组合都被括号括起来,你使用or在它们之间。这确保了如果任何一个组合是正确的,获胜信息将被显示。
第五章
介绍戏剧性停顿
你在第五章(kindle_split_014.html#ch05)中得到了一些关于如何做到这一点的良好提示。在这里不显示太多代码,我建议你前往代码下载区查看其外观。
随机死亡
在这个挑战中,你正在为你的冒险家 Raspi 创建一个更随机和有趣的结局。为此,你需要在程序顶部导入random模块,定义一些用于不同结局的新变量,并创建一个结局列表。这将允许电脑选择一个数字:
import time
import random
demise1 = """Raspi sees a rock on the ground and picks it up. He feels a
sharp pinch and drops the rock. Just then he realizes it wasn't a rock
but a poisonous spider as he collapses to the ground."""
demise2 = """Standing in the cave, Raspi sees a small rabbit approach
him. Raspi gets a bad feeling about this rabbit. Suddenly, the
rabbit attacks him, biting his neck."""
demise3 = """Whoa, is that a piece of gold? As Raspi walks over to it,
he doesn't see a hole in the floor. Suddenly, he falls down the hole,
never to be heard from again."""
endings = [demise1, demise2, demise3]
你使用三引号,称为字符串字面量,来创建跨越多行的字符串。你还将三个不同的结局存储在一个名为endings的列表中。
最后,为了解决这个挑战,将wrong_answer函数更改为获取一个随机数,选择一个结局,并将其显示在屏幕上:

查看代码下载以了解它们是如何一起工作的。
再玩一次?
要添加再玩一次选项,在程序顶部添加一个新变量,并将其设置为 "Y" 以开始:
play_again = "Y"
接下来,将所有你的洞穴选择逻辑放入 while 循环中。while 循环将取决于 play_again 的值,但你会使用字符串函数 upper() 将 play_again 值全部转换为大写。这有助于用户不小心输入 y 而不是 Y:
while play_again.upper() == "Y":
在 while 循环结束时,你还需要询问用户是否想要再玩一次。将他们的响应存储在 play_again 变量中:
print("Do you want to play again?")
play_again = input("Enter Y for yes or N for no: ")
这个挑战的另一个部分是添加尖叫声(或任何你想要的其他声音)。首先,确保你导入了 os 模块,并设置一个包含声音文件的变量:
import os
scream_file_path =
"/usr/share/scratch/Media/Sounds/Human/Scream-male2.mp3"
在 wrong_answer 函数中添加一行新代码,调用 OMXPlayer 并告诉它播放尖叫声:
os.system("omxplayer " + scream_file_path)
运行程序以测试它!将其添加到游戏中所有其他游戏结束部分,使其更加有趣!
注意
确保你的扬声器或耳机已连接,否则你将听不到任何声音。
第六章
波形模式
让我们逐个开启每个 LED。然后,当它们都开启后,你将逐个关闭它们。每个灯光通过将其状态设置为 HIGH(开启)或 LOW(关闭)来开启或关闭。你通过在每条命令之间添加时间延迟来创建序列:

你可以调整睡眠时间以获得更快或更慢的动画。
Simon says
在这个挑战中,你需要创建一个程序,使灯光按照经典游戏 Simon 的模式闪烁。和之前一样,程序需要导入 GPIO 和时间模块,并正确设置 GPIO 引脚。请参阅代码下载以获取完整的代码列表。首先定义 simon_says 函数:

这创建了一个包含所有颜色的列表,并逐个遍历它们。对于每一个,函数都会检查其值并开启和关闭该颜色的 LED。要使用该函数,你需要调用它,并给它你想要创建的模式,以及一些有用的信息:

去吧,Simon,出发!
随机闪烁
这个挑战是关于在 0 到 3 秒之间随机闪烁 LED 的。让我们看看如何做到这一点。我不会展示程序的上半部分,即 GPIO 引脚的典型设置;请参阅代码下载以获取完整的代码列表。在程序顶部,别忘了导入 random 模块,以便你可以使用它来生成随机数:
import random
要完成这个挑战,你需要创建两个变量,并将介于 0 和 3 之间的随机数存储在它们中。这些变量是灯光应该开启和关闭的时间长度:
on_random_time = random.random() * 3
off_random_time = random.random() * 3
接下来,你可以使用 sleep 函数和随机时间来使灯光闪烁。将此放在循环中,确保每次通过循环时都创建新的随机开启和关闭时间:

关闭和开启时间每次通过循环时都会改变。享受一些有趣的闪烁吧!
第七章
本章挑战涉及使用你的猜测游戏和控制 RGB LED。
游戏赢家
让我们编写一个函数来快速闪烁 RGB LED 三种不同的颜色。定义一个新的函数叫做winning_flash:

如果你需要帮助确定在哪里添加这个函数并在代码中调用它,请查看代码下载以获取更多答案。你需要在guess等于number_in_my_head时添加到if语句中,这样你就能在获胜时得到一个精彩的闪烁庆祝。
复活节彩蛋
要在你的程序中创建一个复活节彩蛋,你需要让代码检查玩家是否输入了特定的值而不是通常的数字猜测。编辑 LED 猜测游戏程序的主要逻辑部分,首先检查是否输入了秘密单词。如果没有,程序将继续将输入文本转换为整数,并检查猜测是否正确、过高或过低。如果玩家输入了单词Spam,你将调用一个easter_egg函数:

作为一项特别奖励,你可以创建一个显示 Spam 歌曲或你想要的任何信息的easter_egg函数。

在easter_egg函数中,你调用一个crazy_flash函数。这里展示的函数会使 RGB LED 快速闪烁紫色和绿色。这与你创建的winning_flash函数类似:

创建你自己的easter_egg和crazy_flash函数,或者查看代码下载以获取可以修改的示例。
更热和更冷
如果你感觉更冷或者离正确答案更远,就让我们把猜测游戏中的闪烁速度放慢;如果你感觉更热或者离正确答案更近,就加快闪烁速度。添加一些计算,使得blink_time由猜测值与正确答案之间的差异决定:

abs函数获取绝对值——一个数字与零之间的距离。你需要这样做,因为你不能告诉你的 Pi 设备睡眠负数时间。那会很愚蠢!你需要在两种情况下都进行这个加法:当玩家的猜测值高于或低于实际数字时。你将数字除以 10 来加快blink_time,并确保你的灯光不会闪烁得太慢。
最后,一个很好的细节是向游戏说明中添加额外信息,让玩家知道闪烁速度可以给他们提供接近或远离答案的提示。查看代码下载以获取示例。
Darth Vader 惊喜
使用你在第七章中学到的知识和一些新东西,让我们看看你能否在游戏中失败时在屏幕上弹出 Darth Vader 的图像。接下来的几个步骤你需要一个互联网连接。从网上下载一张好的 Darth Vader 图像,并确保将其保存到你的 Python 程序所在的 home\pi 文件夹中。特别注意文件名。
下载图片后,在你的 Raspberry Pi 上安装fim图片查看软件:
pi@raspberrypi ~ $ sudo apt-get -y install fim
注意
确保在程序顶部包含一行来导入os模块。
完成后,在终端中测试fim是否工作:
pi@raspberrypi ~ $ fim Darth_Vader.jpg
注意
当fim正在运行时,你需要按 Esc(escape)键退出。
当你退出fim时,屏幕将显示图像的残留部分。这是一个有趣的问题,你可以通过抓住你的窗口的标题栏并在屏幕上滑动它来擦除图像残留并恢复到正常的 Raspbian 桌面外观。
在猜谜游戏中,因为你需要从你的 Python 程序中调用fim,所以在程序顶部添加一行来导入os模块:
import os
接下来,编辑game_over函数以显示图像。game_over函数仅在玩家猜错五次时调用:
def game_over():
print("You lost!")
print("Better luck next time!")
time.sleep(2)
os.system("fim –a Darth_Vader.jpg")
注意,你使用带有–a选项的fim来显示达斯·维德。此选项会自动调整图像以填充整个屏幕。以下是一些你可以在屏幕上显示图像时使用的命令来旋转或调整图像大小:
| Option | 结果 |
|---|---|
| +/- | 放大/缩小 |
| A | 自动缩放 |
| F | 翻转 |
| M | 镜像 |
| R/r | 顺时针/逆时针旋转 10 度 |
| Esc/q | 退出 |
测试一下看看是否工作!
第八章
看看你能用按钮做些什么有趣的事情。
双击按钮惊喜
这个挑战涉及从章节中获取项目,并在同时按下两个按钮时使项目发生新的不同的事情。在这种情况下,你将让你的 Pi 播放打击乐声音,以配合你的声音和音乐。你不需要更改任何接线,因为你已经有了两个按钮。
首先,让我们在程序顶部添加一些代码来创建存储音效的路径:
path_effects = "/usr/share/scratch/Media/Sounds/Effects/"
接下来,从文件夹中获取效果列表,并将列表存储在变量sounds_effects中。将此放在加载其他列表的旁边:
sounds_effects = get_MP3_sounds(path_effects)
最后,你需要让程序检查按钮 1 和按钮 2 是否被按下。你将修改主游戏循环,首先检查两个按钮是否都被按下。你使用if/elif语句来做这件事。使用布尔“与”运算符(&)来使这个if语句仅在按钮 1 和按钮 2 都被按下时为真。如果不是,该语句将接下来检查按钮 1,最后检查按钮 2:

让我们测试一下看看是否工作!如果你需要关于程序的更多详细信息,请查看代码下载。
约达魔法 8 球
在你开始编写这个挑战的编程代码之前,你需要处理硬件。因为这个挑战只需要一个按钮,所以从面包板上移除按钮 2 及其跳线电阻。现在你的面包板上应该只剩下一个按钮,连接到 GPIO 6。
接下来,收集一组尤达声音。一旦您创建了一个免费账户,您就可以从 Soundboard 下载声音。对于这个示例解决方案,您将使用五个声音文件,但请随意使用您想要的任何文件。确保它们是 MP3 声音文件,这样它们才能与 OMXPlayer 一起工作。本示例解决方案中的尤达声音文件如下:
-
Fear in You.mp3
-
I am strong.mp3
-
No.mp3
-
Patience.mp3
-
Use the Force.mp3
与经典的魔法 8 球游戏类似,答案有时清晰,有时奇怪或不清晰。
正如 DJ Raspi 项目一样,您需要为此项目导入几个模块,设置 Pi 的 GPIO 引脚用于输入(检测电信号),并创建一些变量。最值得注意的是,您需要为包含您的尤达声音文件的文件夹创建一个变量:

使用来自您的 DJ Raspi 项目的相同get_MP3_sounds和play_random_sound函数。您可以对play_random_sound函数进行的一个小改进是隐藏 OMXPlayer 在屏幕上显示的消息(它们使得阅读游戏告诉您做什么变得更困难)。将这一行更改为将所有输出消息重定向到空或空位置:
def play_random_sound(sound_path, sound_files):
random_sound_index = random.randint(0,len(sound_files)-1)
# print("Playing: " + sound_files[random_sound_index])
os.system("omxplayer -o local '" + sound_path +
"/" + sound_files[random_sound_index] + "' >/dev/null")
这是一个能够重用代码的绝佳例子!接下来,您将从文件夹中收集 MP3 尤达声音列表。
sounds_yoda = get_MP3_sounds(path_yoda)
在打印出漂亮的标题后,然后向玩家展示说明并进入主循环,该循环检查按钮是否被按下。在这个循环中,您调用play_random_sound函数,这样树莓派就会对玩家的提问做出回答:

在尤达的帮助下享受做出您未来决策的乐趣!
附录 D. 树莓派项目
在本附录中,你可以找到关于你可以用树莓派做的项目的简短讨论和描述。目标是让你开始行动。这不是一套详细的说明,而是关于如何制作这些项目的提示和基本步骤。
万圣节头部
万圣节可以是一个使用树莓派为你的家创建有趣或恐怖展示的鼓舞人心的时刻。让我们面对现实——在万圣节吓人是件有趣的事情。这个项目是关于建立一个系统,用来惊喜那些来你门口的万圣节糖果收集者。当他们接近时,他们的动作会触发一个运动传感器,显示一个说话或唱歌的视频。视频被投影到一个放在门旁边的泡沫塑料头上。
这里是你需要为此项目准备的东西:
-
带面包板、扩展板和扁平电缆的树莓派
-
被动红外(PIR)运动传感器
-
投影仪
-
有源电脑扬声器
-
泡沫塑料头(一个或多个)
-
小桌子:一个用于 Pi 和投影仪,另一个用于泡沫塑料头
-
延长线和电源插座
-
唱歌或说话的头部视频
构建此项目,以下是步骤:
1. 将你的树莓派连接到面包板,并添加 PIR 传感器。这类似于你在第八章中添加迷你按钮的方式。第八章
2. 下载一个带有说话或唱歌的头部视频,或者录制你自己的。编写一个 Python 程序,当 PIR 传感器被触发时播放视频。这类似于 DJ Raspi 程序,当按钮被按下时播放声音。
3. 使用传感器和视频一起测试你的程序。
4. 在你前门大约 10 英尺远的地方设置一张小桌子。在桌子上,设置你的树莓派、带有 PIR 传感器的面包板、扬声器和投影仪。将 PIR 传感器放置在可以检测到有人接近门的位置。使用延长线提供所需的电力。(只有当预报没有雨时才设置此设备!)
5. 在门旁边再设置一张小桌子或一个盒子。将泡沫塑料头放在上面。调整头部的位置,使得投影仪的视频显示在头部上。测试并调整投影仪和头部位置,确保一切对齐。当视频播放时,头部看起来就像活了一样!
这里有一些可能有助于这个项目的关键资源:
-
访问 SparkFun 网站www.sparkfun.com,并搜索 PIR 传感器。这家公司有很多优秀的组件,可以帮助你制作几乎任何你想象的电子产品项目。
-
你可以使用带有空白选项的 OMXPlayer 使整个屏幕变黑(全黑),如下所示:
pi@raspberrypi ~ $ omxplayer –b singheads.mp4
时间流逝摄影
你可以轻松地将一个高清相机连接到 Raspberry Pi,该相机能够拍摄数字照片或视频(有关更多信息,请参阅附录 B [kindle_split_020.html#app02])。在这个项目中,你将探索如何设置 Pi 来拍摄时间流逝照片。
时间流逝摄影通常涉及拍摄一系列照片,然后将它们拼接成视频。这些单独的照片可能是在几秒、几分钟、几小时或几天后拍摄的。这种技术通常用于展示某事加速发生的视图。以下是一些时间流逝场景的例子:
-
冰川在一年内缓慢后退
-
太阳的升起和落下,以及月亮的升起和落下
-
植物的生长
这里有一些简单的步骤,帮助你开始时间流逝摄影项目:
1. 使用 Pi 相机套件设置 Raspberry Pi,并测试其是否正常工作。
2. 你的时间流逝主题决定了你需要如何安装 Pi 相机。相机没有附带外壳或任何固定方式,因此你需要设计一种类型的支架。纸板、热胶、工艺棒和胶带都是制作支撑相机的优秀材料。乐高积木也可以是一种有用的材料。
如果你打算将相机长时间放在户外,考虑你是否需要为 Raspberry Pi 防水。外卖食品剩下的塑料容器可以制作成很好的外壳;你只需要在容器上打孔以供电线通过,并用热胶密封任何缝隙。
3. 规划如何为 Pi 提供电力。这可能决定了你设置 Pi 和相机的地方。
4. 编程 Raspberry Pi 拍照并将照片存储在文件夹中。打开 LXTerminal,为 Python 3.X 安装
picamera模块:
pi@raspberrypi ~ $ sudo apt-get install python3-picamera
为了让你开始,你可以使用这样的程序来捕捉一系列照片。以下示例每 3 分钟拍摄一张照片:

当相机完成拍照后,你可以按 Ctrl-C 来结束程序。
注意
此程序将图像保存到程序运行的文件夹中。你应该为你的时间流逝项目创建一个文件夹,并从该文件夹运行程序。
接下来,你需要将图像组合成视频。你可以使用一个名为 mencoder 的应用程序将图像转换为电影。按照以下步骤安装它:
pi@raspberrypi ~ $ sudo apt-get install mencoder
然后,你将创建一个简单的文本文件,其中包含你想要组合的所有图像的名称。你可以使用列表命令 (ls),选择所有以 .jpg 结尾的文件,并将列表输出到文本文件中:
pi@raspberrypi ~ $ ls image*.jpg > list.txt
接下来使用 mencoder 将所有单个图像组合成时间流逝电影。以下示例创建了一个名为 TimeLapseMovie.avi 的电影:
pi@raspberrypi ~ $ mencoder -nosound -ovc lavc -lavcopts
vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=1920:1080 -o
TimeLapseMovie.avi -mf type=jpeg:fps=24 mf://@list.txt
完成后,你可以使用 OMXPlayer 播放电影:
pi@raspberrypi ~ $ omxplayer TimeLapseMovie.avi
你可以在线阅读有关 mencoder 选项的更多信息。
Raspberry Pi 机器人
通过使用 Pi 的 GPIO 功能添加伺服电机和传感器,Raspberry Pi 可以轻松地变成一个机器人。Pi 可以用 Python 编程来做出决策,从传感器获取输入,并控制伺服电机与世界交互。
虽然您可以从头开始组装自己的机器人,但有一些 Raspberry Pi 机器人套件可以使这个过程变得容易得多。对于这个项目,我们将讨论使用 Dexter Industries 的 GoPiGo 套件。这是一个价格合理、设计精良的套件,几小时内就能让您控制 Pi 移动。您可以添加超声波传感器(检测其前面的物体)并编写 Python 程序,使 Pi GoPiGo 机器人能够自主(独立)地使用您之前学到的相同的 if/else 语句在房间内导航。
我们将介绍构建 GoPiGo 的基本步骤(您可以在 www.dexterindustries.com/GoPiGo 上在线阅读完整说明):
1. 按照在线说明构建您的 GoPiGo 机器人。将 Raspberry Pi 连接到机器人:它倒置放在 GoPiGo 板的顶部。Pi 通过 GPIO 引脚与 GoPiGo 板通信。
2. 将 GoPiGo SD 卡插入您的 Pi。SD 卡包含一个定制的 Raspbian 发行版。将 Pi 连接到键盘、鼠标、USB Wi-Fi 适配器和电视或显示器。稍后您将能够从另一台计算机远程连接到 GoPiGo。使用提供的电池组供电。启动 Pi,并将 GoPiGo 连接到您的无线网络。
3. 设置您的计算机以从另一台计算机远程访问您的 Pi。这意味着您将能够从家中的另一台 Windows 或 Mac 计算机上看到您的 Raspbian 桌面。为此,您需要使用名为 VNC 的软件。您需要在 Raspberry Pi 上安装 VNC 服务器,然后在您的计算机上安装 VNC 客户端。Adafruit 网站上有一些很好的教程,例如如何进行此操作。访问
learn.adafruit.com,并搜索“安装 VNC。”4. 使用 VNC,从您的家用 Windows 或 Mac 计算机上连接到您的 Raspberry Pi。一旦您确认 VNC 服务器和客户端运行正常,您可以从显示器、键盘和鼠标上断开 Pi,只留下 USB Wi-Fi 适配器连接。您的 GoPiGo 准备就绪,可以移动了!
5. 在您的 Windows 或 Mac 上的 VNC 客户端中,打开 Pi 上的 LXTerminal。使用
cd命令将目录更改为桌面上的 GoPiGo Python 文件夹:
cd Desktop/GoPiGo/Software/Python/
运行 GoPiGo 测试控制器 Python 程序:
sudo python basic_test_all.py
程序启动后,您可以使用以下键来移动 GoPiGo 在房间内:
| w | 向前移动 |
|---|---|
| a | 向左转 |
| s | 向后移动 |
| d | 向右转 |
| x | 停止 |
| t | 增加速度 |
| g | 减少速度 |
太棒了!你已经将你的树莓派变成了一个机器人。添加传感器并编写程序来在房间内导航,或者连接一个树莓派摄像头并将视频流传输到另一台计算机,这样你就可以看到你的树莓派所看到的内容了。






浙公网安备 33010602011771号