Python 程式設計與問題求解(原書第2版)
Fundamentals of Python:First Programs,Second Edition

第1章
引言
完成本章的學習之後,你将能夠做到以下幾點:
● 描述算法的基本特征。
● 解釋在計算機體系結構中硬體和軟體是如何協作的。
● 總結計算機的發展簡史。
●編寫并運作一個簡單的Python 程式。
作為本書的讀者,你一定至少玩過一款電子遊戲,并且聽過數字音樂。很有可能的是,用微波爐裡準備了零食後,你已經看完一部數字電影了。一天之中,你會撥打電話、發送或接收短信、拍照或在手機上浏覽并查詢你最喜愛的社交網絡。你和你的朋友會使用台式電腦或筆記本電腦完成一些高中或大學裡比較重要的課程。
以上提及的這些活動都依賴于一個共同點:計算機技術。計算機技術幾乎無處不在,不僅在家中,在學校和我們工作、休閑的地方也存在。計算機技術在娛樂、教育、醫療、制造、通信、政府和商業等諸多領域中均扮演着重要的角色。有人說,我們擁有數字生活方式,我們生活在一個以資訊為基礎的經濟資訊時代。而有的人甚至聲稱,自然本身就是對DNA 中存在的資訊結構和亞原子粒子之間的關系進行計算的。
盡管我們沒有具體設想實際的計算機是什麼樣子,但不難想象如果世界沒有了計算機将是什麼樣子。同樣不可思議的是,人類幾千年來都沒有使用計算機技術,而僅僅在最近的三十幾年,計算機技術已經遍及我們所了解的整個世界。
在下面的章節中,你将學習計算機科學,這是對令這項新技術和這個新世界成為可能的計算方法的研究。你還将學習如何有效和适當地利用計算機來改善自己和他人的生活。
1.1 計算機科學的兩種基本思想:算法和資訊處理
跟大多數的研究領域一樣,計算機科學涉及一系列廣泛的互相關聯的思想。其中最基本的兩個思想是算法和資訊處理。本節會對這兩個基本思想做簡要介紹,後面的章節中會詳細地介紹它們。
1.1.1 算法
在當代的計算裝置發明之前,人們早就已經開始進行計算了,而且許多人依然在使用現在看來比較“原始”的計算裝置。例如,考慮一下在信用卡、袖珍電腦或收銀機出現之前,商家是如何為市場上的顧客找零錢的。找零錢是一項複雜的活動,這可能需要你花費一些時間來學習如何去做,并且每一次都需要集中精力去做。讓我們考慮一下這個過程中都涉及什麼。
一種方法是,計算出購買價格和顧客給商家的貨币金額之間的差額。這個計算的結果就是商家必須傳回給顧客的總金額。例如,如果你以2.39 美元的價格從農民手裡購買了一打雞蛋,并且給農民一張10 美元的鈔票,那麼她應該向你返還7.61 美元。是以,她要選擇适當的硬币和鈔票湊成7.61 美元,這些累加上2.39 美元時,正好10 美元。
另一種方法是,商家從購買價格開始逐漸追加到給定的金額。首先,選擇硬币将金額湊成整數美元(在本例中,購買價格2.39 美元,首先需要0.61 美元來湊3 美元,是以需要3 美分、1 鎳和4 便士的硬币),然後選擇适量的美元将金額湊成5 美元(在本例中,需要2 美元),接下來還需要5 美元湊成10 美元來完成交易。正如你在本書中将會看到的那樣,有很多可能的方法或算法可用于解決同樣的問題,而如何從中選出最好的一個将是你通過練習獲得的技能。
很少有人可以在不借助手工輔助工具(如鉛筆和紙)的情況下做三位數字減法。正如你在國小裡學到的,可以按照一系列明确的步驟用鉛筆和紙做減法。這樣的運算你可能已經做過多次了,不過不會想到列出所涉及的具體步驟。編制這樣的清單來解決問題是計算機科學家一直在做的事情。例如,以下步驟描述了使用鉛筆和紙張計算兩個數字相減的過程:
步驟1:寫下這兩個數字,其中較大數字在較小數字之上,并且數字右對齊排列。
步驟2:假設你将從最右邊的一列數字開始,從右向左每一列依次計算。
步驟3:寫下目前數字列中的兩位數字之間的差,如有需要,跟左邊一列上的數字借1。
步驟4:直到最左邊一列算完,停止。否則,移動到左側的下一列,然後傳回到步驟3。
如果計算智能體(在這裡是指人)能按照這些簡單的步驟正确地執行,則整個過程結束後就會得到給定問題的正确解決方案。假設在步驟3 中,智能體已經知道如何計算任何給定列中的兩個數字之間的差,以及可能需要的借位操作。
在找零錢的過程中,大多數人可以找出代表正确找零數的硬币和紙币的組合,而不需要任何人工輔助。但是,涉及的心算仍然可以用前面的分步驟方式描述,如果對找零的正确性存在争議,可以把步驟寫在紙上。
每一組描述像這樣的計算過程的步驟序列稱為一個算法。打個比方,算法就像一個配方。它提供了一套指令,告訴我們如何做某些事情,比如找零錢、烤面包或者組裝一件家具。更确切地說,算法描述了一個以解決問題為導向的過程。算法也是計算機科學的基本思想之一。算法具有以下特征:
● 算法由有限數量的指令組成。
●算法中每條單獨的指令都有明确的定義。這意味着指令所描述的動作能被有效實施或者被計算智能體執行。例如,任何具備算術能力的計算智能體都可以計算兩個數字之間的差。是以,“計算兩個數之差”的算法步驟可被明确定義。而“用0 除以一個數”這樣的步驟沒有明确的定義,因為沒有計算智能體可以執行。
● 算法描述一個過程,這個過程在得到問題的解決方案之後停止。例如,在計算智能體寫下最左列中的兩個數字之差後,減法過程停止。
●算法解決一類問題。例如,描述如何找零的算法應該适用于差額大于或等于0 美元的任意兩筆金額。
建立一個描述如何找零的步驟序列對你來說應該算不上什麼主要成就,但是将一項任務分解成多個組成部分是計算機程式員的主要工作之一。一旦編寫算法來描述特定類型的計算,就可以建構一台計算機來執行計算。換句話說,如果我們能夠開發一種算法來解決問題,就可以自動完成解決問題的任務。有時沒有必要寫一個計算機程式來自動完成變更任務,因為你已經可以很容易地做出改變了。但是,假設你需要完成一件更複雜的任務,例如排序100 個名字的清單,在這種情況下,電腦程式将非常友善。
計算機可以運作一小組算法來執行專門的任務,例如操作微波爐。但是我們也可以建構另一種計算機,就像放在你桌面上的電腦一樣,它們能夠執行任何算法描述的任務。這些電腦是真正的通用問題解決機器。它們不像我們以前建構過的任何機器,它們構成了我們生活的全新世界的基礎。
在本書後面的部分,我們将介紹用于表達算法的符号和一些設計算法的建議。你會發現算法和算法思想是任何計算機系統的關鍵基礎。
1.1.2 資訊處理
自從幾千年前人類首先學會寫作以來,他們就已經在處理資訊。資訊本身在曆史中采取過許多形式,從古代美索不達米亞的泥土上的印記,到古希臘的第一個書面文本,到歐洲文藝複興以來大量生産的書籍、報刊和雜志上的印刷文字,到過去350 年中使用的現代數學和科學的抽象符号。然而,直到最近,人們才開發出通過建構計算機來自動處理資訊的能力。在現代計算機世界中,資訊通常也被稱為資料。但是,什麼是資訊?
像數學計算一樣,資訊處理可以用算法來描述。在我們之前做出改變的例子中,減法步驟涉及操縱用于表示數字和金錢的符号。在執行任何算法的指令時,計算智能體處理資訊。計算智能體從一些給定的資訊(稱為輸入)開始,根據定義好的規則來轉換這些資訊,并産生新的資訊,即輸出。
認識到描述資訊處理的算法也可以表示為資訊是很重要的。計算機科學家已經能夠以一種可被機器有效執行的形式表示算法。他們還設計了真正的機器,稱為電子數字計算機,它們能夠執行算法。
最近,計算機科學家發現了如何将諸如圖像、音樂、人類言語和視訊等許多其他事物表示為資訊。如果沒有這種新的資訊處理,我們現在熟知的許多媒體和通信裝置将是不可能的。後面的章節中會詳細地介紹這些成果。
■.練習
這些簡短的節末練習旨在激發你對計算的思考。
- 列出三種常見類型的計算智能體。
- 編寫一個算法來描述更改過程的第二部分(計算出硬币和賬單)。
- 編寫描述一個常見任務的算法,例如烘焙蛋糕或操作DVD 播放器。
- 描述一個沒有明确定義的指令,是以不能作為算法中的一個步驟。舉一個這樣的指令的例子。
- 為什麼說筆記本電腦是一種通用的問題解決機器?
- 列出使用計算機的四台裝置并描述它們處理的資訊。(提示:考慮裝置的輸入和輸出。)
1.2 現代計算機系統的結構
現在簡單介紹一下現代計算機系統的結構。現代計算機系統由硬體和軟體組成。硬體由執行算法所需的實體裝置組成。軟體是這些算法的集合,表示為程式,特别是程式設計語言。在接下來的讨論中,我們将重點讨論典型台式計算機系統中的硬體和軟體,盡管在其他計算機系統中也可以找到類似的元件,例如手持裝置和ATM (自動取款機)。
1.2.1 計算機硬體
計算機的基本硬體元件是存儲器、中央處理器(CPU)和一組輸入/ 輸出裝置,如圖1-1 所示。
人類使用者主要與輸入和輸出裝置互動。輸入裝置包括鍵盤、滑鼠、觸控闆、麥克風和觸摸屏。常見的輸出裝置包括顯示器和揚聲器。計算機還可以通過各種端口與外部世界通信,這些端口将計算機連接配接到網絡以及智能手機和數位相機等其他裝置。大多數輸入裝置的目的是将人類處理的資訊(如文本、圖像和聲音)轉換為用于計算處理的資訊。大多數輸出裝置的目的是将處理的結果轉換回人類可用的形式。
建立計算機存儲器的目的是以電子形式表示和存儲資訊。具體而言,資訊存儲為二進制數字(1 和0)的模式。要了解這是如何工作的,請考慮一個基本裝置,如電燈開關,它隻能處于兩種狀态之一,開或關。現在假設有一排開關控制着16 盞小燈。通過關閉或打開開關,可以将16 位二進制數字的任何模式表示為打開或關閉小燈的模式。我們将在本書後面看到,計算機科學家已經發現如何以二進制形式表示任何資訊,包括文本、圖像和聲音。
現在,假設有8 排燈,每排16 個。我們可以選擇任意一排燈,檢查或更改該集合中每個燈的狀态。我們剛剛開發了一種微型計算機存儲器。存儲器有8 個單元,每個單元可以存儲16 位二進制資訊。圖1-2 顯示了該模型的示意圖,其中存儲單元填充有二進制數字。這種存儲器有時也稱為主存儲器、内部存儲器或随機存取存儲器(RAM)。
存儲在存儲器中的資訊可以表示任何類型的資料,例如數字、文本、圖像或聲音,或者程式的指令。我們還可以在記憶體中存儲一個編碼為計算機二進制指令的算法。一旦資訊被存儲在記憶體中,我們通常想用它做點什麼,也就是說,我們想處理它。負責處理資料的計算機部分是中央處理器(CPU)。這種裝置有時也稱為處理器,由電子開關組成,用來執行簡單的邏輯、算術和控制操作。CPU 通過從存儲器中提取二進制指令、解碼并執行它們來執行算法。執行指令可能還需要從記憶體中擷取其他二進制資訊(資料)。
處理器可以非常快速地定位計算機主存儲器中的資料。然而,這些資料隻有在電力進入計算機時才存在。如果電源故障或關閉,主存儲器中的資料将丢失。顯然,需要更永久性的記憶體來儲存資料。這種更持久的記憶體稱為外部或輔助記憶體,它有幾種形式。錄音帶和硬碟等磁存儲媒體允許位模式作為模式存儲在磁場中。半導體存儲媒體(例如閃存棒)與光學存儲媒體(例如CD 和DVD)以不同的技術實作幾乎相同的功能。這些輔助存儲媒體中的一些可以容納比計算機的内部存儲器大得多的資訊量。
1.2.2 計算機軟體
你已經知道計算機是一種通用的解決問題的機器。要解決任何可計算的問題,計算機必須能夠執行任何算法。因為不可能預見存在算法解決方案的所有問題,是以無法将所有潛在的算法“硬連線”到計算機硬體中。相反,我們在硬體處理器中建構一些基本操作,并需要任何算法來使用它們。這些算法被轉換成二進制形式,然後與它們的資料一起加載到計算機的存儲器中。之後處理器可以通過運作硬體的更基本的操作來執行算法的指令。
存儲在記憶體中以便以後執行的任何程式都稱為軟體。存儲在計算機記憶體中的程式必須用二進制數字表示,也稱為機器代碼。對人類來說,一次将機器代碼加載到計算機記憶體中一個數字将是一項乏味且容易出錯的任務。如果能自動完成這個過程,每次都能把它做好,那将會很友善。為此,計算機科學家開發了另一個程式,叫作加載器,來執行這項任務。加載器将一組機器語言指令作為輸入,并将它們加載到适當的存儲位置。加載程式完成後,機器語言程式就可以執行了。顯然,加載程式無法将自身加載到記憶體中,是以這是必須硬連線到計算機的算法之一。
現在有了加載程式,我們就可以加載和執行其他程式,這些程式使程式的開發、執行和管理變得更加容易。這種類型的軟體稱為系統軟體。系統軟體最重要的例子是計算機的作業系統。你可能已經熟悉了至少一個最流行的作業系統,比如Linux、蘋果的macOS 和微軟的Windows 。作業系統負責管理和排程多個并發運作的程式。它還管理計算機的存儲器,包括外部存儲器,并管理CPU、輸入/ 輸出裝置和網絡上其他計算機之間的通信。任何作業系統的一個重要部分是檔案系統,它允許人類使用者将資料和程式組織在永久存儲器中。作業系統的另一個重要功能是提供使用者界面,即人類使用者與計算機軟體互動的方式。基于終端的界面接受鍵盤輸入,并在顯示器螢幕上顯示文本輸出。圖形使用者界面(GUI)圍繞桌面隐喻來組織顯示器螢幕,在Windows 中,這些隐喻包含檔案夾、檔案和應用程式的圖示。這種類型的使用者界面還允許使用者使用諸如滑鼠的定點裝置來操縱圖像。觸摸屏界面支援用手勢(例如使用者手指的捏和刷)更直接地操縱這些視覺元素。以口頭和其他方式對口頭指令做出反應的裝置也變得越來越普遍。
另一種主要類型的軟體叫作應用軟體,或簡稱應用(APP)。應用程式是為特定任務設計的程式,例如編輯文檔或顯示網頁。應用程式包括Web 浏覽器、文字處理器、電子表格、資料庫管理器、圖形設計包、音樂制作系統和遊戲,以及數百萬個其他應用程式。當你開始學習寫計算機程式時,你将首先集中精力寫簡單的應用程式。
你已經了解到,計算機硬體隻能執行以二進制形式(即機器語言)編寫的指令。然而,編寫機器語言程式将是一項非常乏味、容易出錯的任務。為了簡化編寫計算機程式的過程,計算機科學家開發了進階程式設計語言來表達算法。這些語言類似英語,程式員可以用别人能了解的形式表達算法。
程式員通常從在文本編輯器中編寫進階語言語句開始。然後,程式員運作另一個稱為翻譯器的程式,将進階程式代碼轉換為可執行代碼。因為程式員甚至在編寫進階代碼時也可能犯文法錯誤,是以翻譯器在完成翻譯過程之前會檢查文法錯誤。如果檢測到這類錯誤,翻譯器通過錯誤消息警告程式員。然後程式員必須修改程式。如果翻譯過程成功而沒有文法錯誤,程式可以由運作時系統執行。運作時系統可以直接在硬體上執行程式,或者運作另一個稱為解釋器或虛拟機的程式來執行程式。圖1-3 顯示了編碼過程中使用的步驟和軟體。
- 列舉兩個輸入裝置和兩個輸出裝置。
- 中央處理器(CPU)做什麼?
- 硬體存儲器中的資訊如何表示?
- 基于終端的界面和圖形使用者界面有什麼差別?
- 翻譯器在程式設計過程中扮演什麼角色?
1.3 計算系統簡史
現在我們已經了解了計算和計算機系統的一些基本概念,接下來花點時間來研究它們在曆史上是如何形成的。圖1-4 總結了計算曆史上的一些主要發展,下面的讨論提供了關于這些發展的更多細節。
1.3.1 在電子數字計算機之前
古代數學家開發了第一批算法。“算法”這個詞來自一位波斯數學家穆罕默德·伊本·穆薩·阿爾·赫瓦裡茲米的名字,他在9 世紀時寫了幾本數學教科書。大約2300 年前,幾何的發明者、希臘數學家歐幾裡得開發了一種計算兩個數字最大公約數的算法。
古代也出現了一種叫作算盤的裝置。算盤幫助人們執行簡單的算術。使用者通過在木棍網格上滑動珠子來計算總和和差異(見圖1-5a)。算盤上的珠子構成了資料。
17 世紀,法國數學家布萊斯·帕斯卡(1623—1662 年)建造了第一批使加法過程自動化的機械裝置之一(見圖1-5b)。加法操作嵌入機器内的齒輪配置中。使用者通過旋轉一些輪子輸入兩個要相加的數字,總和或輸出數出現在另一個旋轉輪上。德國數學家戈特弗裡德威廉·萊布尼茨(1646—1716 年)建造了另一台機械電腦,包括其他算術功能,如乘法。萊布尼茨和牛頓一起發明了微積分,他接着提出了用符号計算的想法,這是我們最基本和最普遍的智力活動之一。他主張使用一種通用語言,通過計算可以解決任何問題。
19 世紀早期,法國工程師約瑟夫·瑪麗·雅卡爾(1752—1834 年)設計并制造了一台自動編織過程的機器(見圖1-5c)。在此之前,編織圖案中的每一行都必須手工設定,這是一個非常煩瑣、容易出錯的過程。這台織機被設計成接受一組穿孔卡片形式的輸入,每張卡片都描述了一排布料圖案。盡管它仍然是一個完全機械的裝置,但卻擁有以前的裝置所缺乏的東西——自動執行算法的能力。這組卡片表達了控制織機行為的算法或指令集。如果織機操作員想要生産不同的圖案,他隻需要用不同的一套卡片來運作機器。
英國數學家查爾斯·巴貝奇(1792—1871 年)将可程式設計計算機的概念向前推進了一步,他設計了一種機器模型,從概念上來說,它與現代通用計算機非常相似。巴貝奇将他的機器——他稱之為分析引擎——視為一種機械裝置。他的設計需要四個功能元件:一個執行算術運算的工廠,一個儲存資料和程式的商店,一個運作穿孔卡片指令的操作員,以及一個在穿孔卡片上産生結果的輸出。可悲的是,巴貝奇的電腦從未被制造出來。巴貝奇本人去世時,這個項目因缺乏資金而夭折。
在19 世紀的最後二十年裡,一位名叫赫爾曼·霍爾瑞斯(1860—1929 年)的美國人口普查局統計員開發了一種自動處理美國人口普查資料的機器。霍爾瑞斯的機器具有與巴貝奇的分析引擎相同的部件,它隻接受一組穿孔卡片作為輸入,然後對卡片進行計數和分類。他的機器大大縮短了産生美國人口統計結果的時間。尋求自動化資料處理的政府和商業組織很快采用了霍爾瑞斯的穿孔卡片機。霍爾瑞斯也是一家最終成為IBM(國際商業機器)的公司的創始人之一。
同樣在19 世紀,英國中學教師喬治·布爾(1815—1864 年)發展了一套邏輯系統。這個系統包括一對值——真值和假值,以及對這些值的三個原始操作——與、或、非。布爾邏輯最終成為設計處理二進制資訊的電子電路的基礎。
半個世紀後的20 世紀30 年代,英國數學家艾倫·圖靈(1912—1954 年)探索了算法和計算的理論基礎和局限性。圖靈的主要貢獻是發展了一種通用機器的概念,它可以專門用來解決任何可計算的問題,并證明了一些問題是計算機無法解決的。
1.3.2 第一台電子數字計算機(1940 ~1950)
20 世紀30 年代末,麻省理工學院的數學家和電氣工程師克勞德·香農(1916—2001 年)寫了一篇題為“繼電器和開關電路的符号分析”的經典論文。在這篇論文中,他展示了其他系統中的操作和資訊(如算術)如何被簡化為布爾邏輯,然後被簡化為硬體。例如,如果布爾值TRUE 和FALSE 被寫為二進制數字1 和0,則可以編寫一個邏輯操作序列,計算兩個二進制數字字元串的和。建構電子數字計算機所需要的隻是将二進制數字表示為開/ 關的電子開關以及表示其他電路中的邏輯運算的能力。
二戰中戰鬥人員的需求推動了計算機硬體的發展。美國、英國和德國的幾個科學家和工程師團隊在20 世紀40 年代獨立創造了第一代通用數字電子計算機。所有這些科學家和工程師都利用香農的創新,用電子開關裝置來表達二進制數字和邏輯運算。這些團體中有一個在霍華德·艾肯指導下的哈佛大學團隊。他們的計算機名為Mark I ,于1944 年開始運作,在戰争期間為美國海軍做數學工作。Mark I 被認為是電動機械裝置,因為它使用磁鐵、繼電器和齒輪的組合來存儲和處理資料。
賓夕法尼亞大學的普雷斯佩爾·埃克特和約翰·毛克利上司的另一個團隊生産了一台名為ENIAC(電子數字積分器和電腦)的計算機。ENIAC 計算了戰争結束時美國陸軍炮兵的彈道表。ENIAC 完全使用電子元件,它比Mark I 快了近一千倍。
另外兩台電子數字計算機比ENIAC 稍早完成。它們是1942 年由愛荷華州立大學的約翰·阿坦索夫和克利福德·貝裡建造的ABC(阿坦索夫-貝裡計算機),以及1943 年由艾倫·圖靈手下一個在英格蘭工作的團隊建造的Colossus。建立ABC 是為了求解聯立線性方程組。盡管ABC 的功能比ENIAC 的功能要窄得多,但ABC 現在被視為第一台電子數字計算機。直到最近,Colossus 的存在一直是絕密的,在戰争期間,它被用來破解強大的德國Enigma 密碼。
第一代電子數字計算機,有時稱為大型計算機,由真空管、電線和插頭組成,充滿了整個房間。雖然它們比人類在計算方面要快得多,但按照我們目前的标準,它們的速度非常慢,而且容易崩潰。此外,早期的計算機極難程式設計。為了進入或修改程式,一組勞工必須通過拔掉和重新接上電線來重新排列真空管之間的連接配接。每個程式都是通過硬連線到計算機上來加載的。有成千上萬的電線,很容易出錯。
第一批計算機的存儲器隻存儲資料,而不是處理資料的程式。正如我們已經看到的,存儲程式的想法最早出現在100 年前雅卡爾的織機和巴貝奇的分析引擎設計中。1946 年,約翰·馮·諾依曼意識到程式指令也可以二進制形式存儲在電子數字計算機的存儲器中。他在普林斯頓的研究小組開發了首批現代存儲程式計算機之一。
盡管計算機的尺寸、速度和應用自早期以來已經發生了巨大的變化,但是電子數字計算機的基本結構和設計仍然非常穩定。
1.3.3 第一種程式設計語言(1950 ~1965)
今天的計算機使用者運作着許多程式,由數百萬行代碼組成,執行三四十年前看似神奇的任務。但是第一台數字電子計算機沒有我們今天認為的軟體。一些相對簡單和小型的應用程式的機器代碼必須手工加載。随着對更大和更複雜應用程式的需求的增長,對加速程式設計過程的工具的需求也在增長。
在20 世紀50 年代早期,計算機科學家意識到可以用符号代替機器代碼,第一種彙編語言出現了。程式員會在鍵控打孔機上輸入操作的助記碼,如ADD 和OUTPUT,以及資料變量,如工資和費率。按鍵為每條指令在一張小卡片上打一組孔。程式員随後将一疊疊卡片交給系統操作員,系統操作員将它們放在一個叫作讀卡器的裝置中。這種裝置将卡片上的孔轉換成計算機記憶體中的模式。然後,彙編器将記憶體中的應用程式翻譯成機器代碼并執行。
彙編語言程式設計是對機器代碼程式設計的有效改進。彙編語言中使用的符号對人們來說更容易閱讀和了解。另一個優點是,彙程式設計式可以在程式實際執行之前捕獲一些程式設計錯誤。然而,與傳統數學符号相比,彙編符号仍然顯得有點晦澀難懂。為了解決這個問題,IBM 的程式員約翰·巴克斯于1954 年開發了FORTRAN (公式翻譯語言)。程式員,其中許多是數學家、科學家和工程師,現在可以使用傳統的代數符号。FORTRAN 程式員仍然在打孔機上輸入程式,但是計算機在程式被編譯器翻譯成機器代碼後執行了這些程式。
FORTRAN 被認為是數值和科學應用的理想選擇。然而,表達資料進行中使用的資料類型——特别是文本資訊——是很困難的。例如,FORTRAN 在處理包括人名、位址、社會保險号碼以及公司和其他機構的财務資料在内的資訊時并不實用。20 世紀60 年代早期,由格蕾絲·霍珀少将率領的團隊開發了COBOL(通用面向業務的語言),用于美國政府的資料處理。銀行、保險公司和其他機構很快在資料處理應用中采用了它。
同樣在20 世紀50 年代末和60 年代初,麻省理工學院的計算機科學家約翰·麥卡錫開發了一種強大而優雅的表示計算的符号LISP(清單處理)。基于遞歸函數的理論(第6 章中涉及的主題),LISP 抓住了符号資訊處理的本質。麥卡錫的學生史蒂夫·塞盧斯在1960 年為LISP 編寫了第一個解釋器。解釋器直接接受LISP 表達式作為輸入,評估并列印結果。早期,LISP 主要用于實驗室,他們的研究領域被稱為人工智能。最近,LISP 被吹捧為解決任何困難或複雜問題的理想語言。
盡管FORTRAN 和LISP 是第一批進階程式設計語言,但它們已經存活了幾十年。它們都經曆了許多修改來提高能力,并且已經成為許多其他程式設計語言開發的模型。相比之下,COBOL 不再被積極使用,而是主要以遺留程式的形式存活下來,這些程式仍然需要維護。
這些新的進階程式設計語言有一個共同的特點:抽象。在科學或任何其他研究領域,抽象允許人類将複雜的想法或實體簡化為更簡單的想法或實體。例如,在FORTRAN 中,一組10 個彙編語言指令可能會被一個僅由5 個符号組成的等效代數表達式代替。換句話說,用更少的資源說更多的話,就是在使用抽象。在計算的其他領域,例如硬體設計和資訊架構,也可以找到抽象的使用。複雜性實際上并沒有消失,但是抽象隐藏了它們。通過抽象抑制分散注意力的複雜性,計算機科學家可以概念化、設計和建構更加複雜的系統。
1.3.4 內建電路、互動和分時(1965 ~1975)
20 世紀50 年代末,真空管被半導體取代,成為在計算機硬體中實作電子開關的機制。作為固态器件,半導體比真空管小得多,更可靠,更耐用,制造成本也更低。是以,計算機的硬體元件通常在實體尺寸上變得更小、更可靠和更便宜。電子開關越小越多,處理速度越快,存儲資訊的記憶體容量也越大。
20 世紀60 年代早期,內建電路的發展使得計算機工程師能夠制造更小、更快、更便宜的計算機硬體元件。他們完善了在非常薄的矽晶片上蝕刻半導體和其他固态元件的照相工藝,将整個處理器和存儲器留在單個晶片上。1965 年,計算機晶片制造商英特爾的創始人之一戈登·摩爾做出了一個稱為摩爾定律的預測。該預測指出,硬體的處理速度和存儲容量将會增加,其成本将每18 個月降低至約為原來的1/2。這一趨勢已經持續了50 多年。例如,在1965 年,一個晶片上大約有50 個電子元件,而到2000 年,一個晶片可以容納4000 多萬個元件。沒有內建電路,人類就不會在1969 年登月,也不會有我們現在日常使用的功能強大、價格低廉的手持裝置。
20 世紀60 年代出現了一台大辦公桌大小的小型計算機。開發和運作程式的方式也在改變。在此之前,一台計算機通常隻配有一名操作員,并被限制在一個區域内。程式員在另一個房間或建築中的打孔機上編寫程式。然後,他們将一疊疊卡片交給電腦操作員,電腦操作員将它們裝入讀卡器,并在電腦上按順序編譯和運作程式。然後,程式員傳回,得到以新的卡片堆疊或列印輸出的形式表示的輸出結果。這種操作模式也稱為批處理,可能會導緻程式員等待數天,得到包括錯誤消息在内的操作結果。
處理速度和記憶體容量的提高使得計算機科學家能夠開發出第一個分時作業系統。程式設計語言LISP 的建立者麥卡錫認識到,一個程式可以自動化人類系統操作員執行的許多功能。當記憶體(包括磁性二級存儲)變得足夠大,可以同時容納幾個使用者的程式時,它們可以被安排并行處理。與程式相關聯的每個程序将運作一段時間,然後将CPU 交給另一個程序。所有的活動程序将由CPU 重複循環,直到完成。
幾個使用者現在可以通過在連接配接到一台計算機的獨立終端輸入指令來同時運作自己的程式。随着處理器速度的不斷提高,每個使用者都産生了分時計算機系統完全屬于自己的錯覺。
到20 世紀60 年代末,程式員可以在終端輸入程式,也可以看到程式輸出立即顯示在CRT (陰極射線管)螢幕上。與它的前身相比,這種新的計算機系統不僅互動性強,而且使用者更容易使用。
許多相對中小型的機構(如大學)能夠負擔得起計算機,這些機器不僅用于資料處理和工程應用,還用于計算機科學新的快速發展領域的教學和研究。
1.3.5 個人計算和網絡(1975 ~1990)
20 世紀60 年代中期,斯坦福研究所(SRI)的計算機科學家道格拉斯·恩格爾巴特第一個意識到摩爾定律的終極含義之一:最終,也許在一代人的時間内,硬體元件将變得足夠小,并且足夠便宜,能夠為每個人批量生産一台個人計算機。這些個人電腦将采取什麼形式?其所有者将如何使用它們?20 年前,1945 年,恩格爾巴特在《大西洋月刊》上讀到了一篇題為“我們可能認為”的文章,這篇文章已經提出了這個問題并給出了一些答案。作者——麻省理工學院的科學家範尼瓦爾·布什——預測,計算裝置将成為資訊的儲存庫,最終成為所有人類知識的儲存庫。計算裝置的所有者将通過使用指點裝置浏覽内容來查閱内容,并且他們幾乎可以随意向知識庫提供資訊。恩格爾巴特贊同個人電腦的主要目的是提高人類智力的觀點,他在職業生涯的剩餘時間裡設計了能夠實作這一目标的電腦系統。
在20 世紀60 年代後期,恩格爾巴特制造了第一個定點裝置,或稱滑鼠。他還設計了在位圖顯示屏上顯示視窗、圖示和下拉菜單的軟體。他示範了計算機使用者不僅可以在鍵盤上輸入文本,還可以直接操縱螢幕上代表檔案、檔案夾和計算機應用程式的圖示。
但是對恩格爾巴特來說,個人計算并不意味着獨立計算。他參加了第一次将計算機連接配接到網絡的實驗,他相信不久人們将會使用計算機來交流、分享資訊,并在團隊項目上進行合作。
恩格爾巴特在SRI 的一台小型計算機上開發了他的第一個實驗系統,他稱之為NLS(線上系統)增強系統。20 世紀70 年代初,他搬到施樂帕洛阿爾托研究中心,與艾倫·凱上司的團隊合作開發了第一個台式計算機系統。這個被稱為Alto 的系統具有恩格爾巴特增強功能的許多特征,還有電子郵件和一個功能正常的超文本(網際網路的前身)。凱的團隊還開發了一種名為Smalltalk 的程式設計語言,旨在為新電腦建立程式,并向兒童教授程式設計。凱的目标是開發一台大筆記本大小的個人電腦,他稱之為Dynabook。不幸的是,施樂公司的管理層對影印機比對凱的研究小組遠見卓識的工作更感興趣。然而,一位名叫史蒂夫·喬布斯的年輕企業家參觀了施樂實驗室,并看到了Alto 在運作。大約十年後的1984 年,蘋果電腦公司——史蒂夫·喬布斯創立的著名公司——推出了Macintosh,這是第一款成功批量生産的帶有圖形使用者界面的個人電腦。
當凱的團隊忙于在他們的研究實驗室裡建構未來的計算機系統時,幾十名業餘愛好者聚集在舊金山附近,成立了Homebrew 電腦俱樂部,這是第一個個人計算機使用者團體。他們聚在一起分享個人計算的想法、程式、硬體和應用。第一台大規模生産的個人電腦Altair 出現于1975 年。Altair 包含英特爾的8080 處理器——第一個微處理器晶片。但是從外部來看,Altair 的樣子和行為更像早期電腦的微縮版,而不是Alto。程式及其輸入必須通過翻轉開關輸入,輸出由一組燈顯示。然而,Altair 小到足以讓個人計算愛好者帶回家,最終,人們又發明了輸入/ 輸出裝置來支援文本和聲音的處理。
Osborne 和Kaypro 是首批批量生産的互動式個人電腦。他們誇耀自己的顯示屏和鍵盤很小,軟碟驅動器用于加載系統軟體、應用軟體和使用者資料檔案。早期的個人計算應用是文字處理器、電子表格和遊戲,如Pac - Man 和Space war !。這些計算機還運作CP / M (微機控制程式),這是第一個基于PC 的作業系統。
20 世紀80 年代初,一位名叫比爾·蓋茨的大學辍學者和他的合作夥伴保羅·艾倫開發了他們自己的作業系統軟體,他們稱之為MS -DOS(微軟磁盤作業系統)。然後,他們與大
型計算機制造商IBM 達成協定,為該公司打算批量生産的新系列電腦提供MS-DOS。這項交易對蓋茨的公司微軟來說是非常有利的。微軟每售出一台電腦都會收到一筆費用,而且在提供運作于其作業系統上的應用軟體方面也有領先優勢。IBM PC 被迅速銷售給個人和機構,使MS -DOS 成為世界上使用最廣泛的作業系統。幾年之内,蓋茨和艾倫成為億萬富翁,十年之内,蓋茨成為世界首富,并且一直持續了13 年。
同樣在20 世紀70 年代,美國政府開始支援網絡的開發,将軍事設施和研究型大學的計算機連接配接起來。第一個這樣的網絡被稱為ARPANET (進階研究項目代理網絡),連接配接了SRI、加州大學洛杉矶分校、加州大學聖巴巴拉分校和猶他大學的四台計算機。鮑勃·梅特卡夫是施樂公司凱團隊的研究員,他開發了一種名為以太網的軟體協定,用于運作計算機網絡。以太網允許計算機在組織内部的區域網路(LAN)中通信,也允許計算機通過廣域網(WAN )與其他組織中的計算機通信。到20 世紀80 年代中期,ARPANET 已經發展成為我們現在所說的網際網路,連接配接了世界各地大型機構、小型組織和個人擁有的計算機。
1.3.6 咨詢、通信和電子商務(1990 ~2000)
20 世紀90 年代,計算機硬體成本持續下降,處理速度和記憶體容量飙升。諸如CD光牒(CD)和數字視訊CD光牒(DVD)之類的光學存儲媒體被開發以用于大容量存儲。圖像、聲音和視訊的數字化和計算處理變得可行和廣泛。到2000 年年底,整個電影都可以用數字裝置拍攝、制作和回放。《玩具總動員》是第一部完全由電腦制作的長篇動畫電影,出現于1995年。創造逼真的整體環境三維動畫的能力催生了一種叫作虛拟現實的新技術。新的裝置出現了,如平闆掃描器和數位相機,這些裝置可以與更傳統的麥克風和揚聲器一起使用,以支援幾乎任何類型資訊的輸入、數字化和輸出。
桌上型電腦和筆記本電腦現在不僅可以完成有用的工作,還可以為使用者提供新的個人表達方式。在這十年中,計算機作為通信工具快速崛起,包括電子郵件、即時消息、公告欄、聊天室和網際網路。
也許這一時期最有趣的故事是關于網際網路的創造者蒂姆·伯納斯-李。20 世紀80 年代末,在瑞士日内瓦歐洲核子研究中心從事研究的理論實體學家伯納斯-李開始研究一些利用計算機共享資訊的想法。計算機工程師已經将計算機與網絡連接配接了幾年,在世界各地的研究團體中交換檔案和收發電子郵件已經很普遍了。然而,硬體、作業系統、檔案格式和應用程式的巨大差異仍然使得不擅長程式設計的使用者難以通路和共享這些資訊。伯納斯-李對創造一種共享資訊的通用媒體感興趣,這種媒體不僅對科學家來說很容易使用,而且對任何其他能夠操縱鍵盤和滑鼠并在顯示器上檢視資訊的人來說也很容易使用。
伯納斯-李熟悉範尼瓦爾·布什對網絡咨詢系統的設想,恩格爾巴特關于自然語言系統擴充的工作,以及第一個廣泛使用的超文本系統。其中一個系統——蘋果電腦的HyperCard——将超文本的範圍擴大到了超媒體。HyperCard 允許作者不僅将文本,還将圖像、聲音、視訊和可執行應用程式組織成連結資訊網絡。然而,HyperCard 資料庫僅位于獨立計算機上,這些連結無法将超高速緩存資料從一台計算機傳送到另一台計算機。此外,支援軟體隻在蘋果電腦上運作。
伯納斯-李意識到網絡可以将超媒體系統的覆寫範圍擴充到任何連接配接到網絡的計算機,進而使他們的資訊在全球範圍内可用。為了保持其與特定作業系統的獨立性,新媒體需要有分發和呈現資訊的通用标準。為了確定這種中立和獨立,任何私人公司或政府都不能擁有這種媒體并規定标準。
伯納斯-李于1992 年為這種新媒體(我們現在稱之為網際網路)建構了軟體。該軟體使用了許多現有的機制在網際網路上傳輸資訊。人們通過在稱為Web 伺服器的計算機上釋出檔案來為Web 貢獻資訊。這些計算機上的Web 伺服器軟體負責響應檢視存儲在Web 伺服器上的資訊的請求。為了在網絡上檢視資訊,人們使用一種叫作Web 浏覽器的軟體。為了響應使用者的指令,Web 浏覽器通過網際網路向适當的Web 伺服器發送資訊請求。伺服器通過将資訊發送回浏覽器的計算機(稱為Web 用戶端)進行響應,在浏覽器中顯示或呈現資訊。
盡管伯納斯-李寫了第一個網絡伺服器和網絡浏覽器軟體,但他做出了另外兩項更重要的貢獻。首先,他設計了一套稱為HTTP(超文本傳輸協定)的規則,允許任何伺服器和浏覽器互相對話。其次,他設計了一種語言——HTML(超文本标記語言),它允許浏覽器将資訊結構化顯示在網頁上。然後,他免費向任何人提供所有這些資源。
伯納斯-李發明并免費開放了這種通用資訊媒體,這是一項真正了不起的成就。今天,全世界有數百萬台Web 伺服器在運作。任何擁有适當教育訓練和資源的人——公司、政府、非營利組織和個人——都可以啟動一個新的Web 伺服器或在其中獲得空間。現在,Web 浏覽器軟體不僅在桌上型電腦和筆記本電腦上運作,也在手機等手持裝置上運作。
網際網路、網絡和相關軟體技術的發展也在20 世紀後半葉改變了制造業、零售業和金融業。計算機支援的自動化極大地提高了生産率(同時消除了許多人的高薪工作)。公司建立并完善了從原材料到成品再到零售的貨物生産和分銷鍊,這些鍊的成本效益和範圍越來越大。計算機技術在很大程度上促進了沃爾瑪等大型超市的擴張和亞馬遜等線上商店的崛起(同時也迫使許多當地零售商停業,并創造了一批沒有福利的兼職員工)。
使網上商店無處不在的被稱為Web 應用的技術,在向人們提供軟體服務的方式上帶來了一場革命。人們可以通過Web 浏覽器獲得對特定服務的通路,而不是購買和運作安裝在自己計算機上的特定應用軟體。提供此服務的Web 應用程式運作在提供商營業地的遠端計算機或伺服器上。Web 浏覽器為數百萬使用者扮演了用戶端、前端或使用者界面的角色,以通路給定服務的同一伺服器應用程式。用戶端/ 伺服器應用程式已經被用于電子郵件、布告闆和網際網路上的聊天室,是以這項技術在出現時隻需簡單地部署在網絡上。
這十年的最後一次重大發展發生在斯坦福大學的一個計算機實驗室,兩位研究所學生謝爾蓋·布林和拉裡·佩奇開發了索引和搜尋網絡的算法。他們的工作成果給詞典增添了一個新動詞:谷歌。今天,世界經濟和研究的大部分都依賴于谷歌的各種搜尋平台。
1.3.7 移動應用和普适計算(2000 ~現今)
随着上一個千年臨近尾聲,計算機硬體在尺寸和成本上繼續縮小,并且提供了更多的記憶體和更快的處理速度。對數百萬人來說,筆記本電腦變得更小、更快、更實惠。第一個被稱為個人數字助理(PDA)的手持計算裝置開始出現。這些裝置的應用僅限于簡單的視訊遊戲、位址簿、待辦事項清單和筆記記錄,它們必須通過電纜連接配接到筆記本電腦或台式電腦以傳輸資訊。
與此同時,随着數百萬人開始使用第一部手機,蜂窩技術的應用變得廣泛。與今天的智能手機相比,這些允許通過簡單的機械鍵盤進行通話的裝置還顯得“愚蠢”。但是蜂窩技術為即将到來的發展提供了基礎。大約在同一時間,無線技術支援計算機通過空中與具有網際網路連接配接的基站通信。移動計算和無處不在的計算的條件已經具備,隻等待那些能讓它們有用和受歡迎的裝置和應用。
沒有人能比史蒂夫·喬布斯(蘋果電腦的創始人)更好地預見到移動計算可能帶來的裝置和應用類型。在他生命的最後十幾年裡,喬布斯從蘋果公司引進了幾款裝置和技術,不僅革新了計算機,也革新了人們從事文化追求的方式。這些裝置是:iPod,最初是一個數字音樂播放器,但後來演變成一個手持通用計算裝置;iPhone,為iPod 增加了手機技術及功能;iPad,實作了艾倫·凱個人筆記本電腦的夢想。所有這些裝置都使用觸摸屏和語音識别技術,這消除了對體積龐大的機械鍵盤的需求。
相關的軟體技術以蘋果的iLife 套件的形式出現,這是一組應用程式,允許使用者組織各種類型的媒體(音樂、照片、視訊和書籍)。蘋果的iTunes 、iBooks 和App Stores,這些供應商網站允許開發者銷售移動媒體和應用程式。十年來讓使用者通路Web 應用程式的Web 浏覽器成為移動計算領域的另一種應用程式。
新的千年見證了數字領域的另一個重要補充:社交網絡應用。盡管各種網際網路論壇(如聊天室和布告闆系統)已經使用了幾十年,但并不普遍。2004 年,哈佛大學的學生馬克·紮克伯格在大學宿舍裡推出Facebook,改變了這一切。該應用程式允許學生加入網絡共享他們的個人資料,釋出消息、照片和視訊,并且通常作為“朋友”進行交流。Facebook 的規模迅速擴充到超過10 億使用者。社交網絡技術現在包括許多其他變體,例如LinkedIn、Twitter 、Tumblr 、Flickr 和Instagram。
最後,我們還要提一下被稱為大資料的技術的興起。政府、企業和黑客出于各種目而不斷監控網際網路流量,這個“點選流”可以被“挖掘”來了解使用者的偏好和興趣。例如,線上商店可能會在使用者上網購物時看到類似的産品後,立即在他的Facebook 頁面上做廣告。資料科學領域的研究人員已經發明了處理大量資料以發現趨勢和預測結果的算法。
總結一下這段不那麼短暫的曆史,一個趨勢将過去幾十年的計算聯系在一起:快速進步。過程和事物已經變得自動化、可程式設計、更小、更快、高度互聯,并且易于可視化和解釋。
如果你想了解更多關于計算曆史的資訊,請參考本章末尾列出的文獻。我們現在開始介紹Python 程式設計。
1.4 開始Python 程式設計
圭多·範·羅瑟姆在20 世紀90 年代早期發明了Python 程式設計語言。Python 是一種進階通用程式設計語言,用于解決現代計算機系統上的問題。Python 語言和許多支援工具都是免費的,Python 程式可以在任何作業系統上運作。你可以從www.python.org 下載下傳Python 及其文檔和相關材料。下載下傳和安裝Python 的說明見附錄A。在本節中,我們将向你展示如何建立和運作簡單的Python 程式。
1.4.1 在互動式shell 中運作代碼
Python 是一種解釋語言,你可以在名為shell 的互動式程式設計環境中運作簡單的Python 表達式和語句。打開Python shell 最簡單的方法是啟動IDLE(內建開發環境)。這是Python 安裝附帶的內建程式開發環境。執行此操作時,将打開一個名為Python Shell 的視窗。圖1-6 顯示了macOS 上的shell 視窗,在Windows 系統或Linux 系統上運作的shell 視窗看起來應該與這個相似。請注意,此螢幕截圖中出現的Python 版本是3.6.1。本書假設你将使用Python 3 而不是Python 2 。這兩個版本之間有很大的差異,本書中使用的許多示例不适用于Python 2。
在shell 視窗中包含一條打開消息,後面跟着一個特殊符号>>>,稱為shell 提示符。shell 提示符下的光标等待你輸入Python 指令。請注意,通過在shell 提示符下輸入help 或從視窗的下拉菜單中選擇幫助,便可以立即獲得幫助。
當你輸入表達式或語句時,Python 會對其進行計算并顯示結果(如果有的話),然後顯示新的提示符。接下來的幾行顯示了對幾個表達式和語句的求值。
注意Python 代碼中顔色的使用。IDLE 程式設計環境使用顔色編碼來幫助讀者挑選代碼中的不同元素。在這個例子中,引号内的項目是綠色的,标準函數的名稱是紫色的,程式注釋是紅色的,IDLE 對使用者指令的響應是藍色的,剩餘的代碼是黑色的。表1-1 列出了本書所有程式代碼中使用的顔色編碼方案。
Python shell 對于嘗試用短表達式或語句來學習該語言的新特性以及查閱該語言的文檔非常有用。要退出Python shell,你可以選擇視窗的關閉框,或者按下Control + D 組合鍵。
本節的其餘部分将探讨開發更複雜和更有趣的程式的方法。
1.4.2 輸入、處理和輸出
大多數有用的程式接受來自某個來源的輸入,處理這些輸入,然後最終将結果輸出到某個目的地。在基于終端的互動式程式中,輸入源是鍵盤,輸出目的地是終端顯示器。Python shell 本身就是這樣一個程式,它的輸入是Python 表達式或語句,它的處理會評估這些項目,它的輸出是shell 中顯示的結果。
程式員也可以使用列印功能強制輸出一個值。使用此函數的最簡單形式如下所示:
本示例向你展示了使用print函數的基本文法(或文法規則)。尖括号(< >)符号包含一種短語。在實際Python 代碼中,你将使用該類型短語的示例來替換這種文法形式,包括尖括号。在這種情況下,
是任何Python表達式的簡寫,例如
3+4。
運作print函數時,Python 首先計算表達式,然後顯示其值。在前面顯示的示例中,print用于顯示一些文本。下面是另一個例子:
在這個例子中,文本“Hi there”是我們希望Python 顯示的文本。在程式設計術語中,這段文字被稱為字元串。在Python 代碼中,字元串總是用引号括起來。但是,print函數顯示不帶引号的字元串。
你還可以編寫一個列印函數,該函數包含兩個或多個用逗号分隔的表達式。在這種情況下,print函數會評估表達式,并在一行中顯示結果,用單個空格分隔。帶有兩個或更多表達式的print語句的文法如下所示:
注意這個文法示例中的省略号(...)。省略号表示你可以在第一個表達式之後包含多個表達式。無論輸出一個或多個表達式,print函數總是以換行符結束其輸出。換句話說,它顯示表達式的值,然後将光标移動到視窗的下一行。
要在與上一行相同的行上開始下一個輸出,可以将表達式end="",即“用空字元串而不是換行符結束行”,放在表達式清單的末尾,如下所示:
在Python 中建立程式時,你經常希望程式向使用者請求輸入。你可以通過使用input 函數來做到這一點。此功能使程式停止并等待使用者從鍵盤輸入值。當使用者按下return 或enter 鍵時,該函數接受輸入值,并使其可供程式使用。以這種方式接收輸入值的程式通常會将其儲存以供進一步處理。
下面的示例接收來自使用者的輸入字元串并儲存它以供進一步處理。使用者的輸入是黑色的。
輸入功能執行以下操作:
● 顯示輸入提示。在這個例子中,提示是"Enter your name:"。
●接收在鍵盤上輸入的稱為字元的擊鍵字元串,并将該字元串傳回給shell。輸入函數如何知道使用什麼作為提示?括号中的文本"Enter your name:"是input函數的一個參數,它告訴input函數如何用于提示。參數是函數完成工作所需的資訊。通過将函數傳回的字元串配置設定給變量name 來儲存。具有輸入功能的指派語句的形式如下:
變量辨別符簡稱變量,它隻是一個值的名稱。當變量在input語句中收到它的值時,變量就會引用這個值。如果使用者在最後一個示例中輸入了名稱
“Ken Lambert”,變量名的值如下所示:
input函數總是根據使用者的擊鍵建立一個字元串并将其傳回到程式中。輸入代表數字的字元串後,程式員必須将它們從字元串轉換成合适的數字類型。在Python 中,為此有兩個類型轉換函數,分别稱為int(整數)和float(浮點數字)。下一個例子輸入兩個整數并顯示它們的總和:
注意,調用int函數時,輸入函數會傳回每個結果。将這兩個數字相加,然後輸出它們的總和。表1-2 總結了本節介紹的函數。
1.4.3 編輯、儲存和運作腳本
雖然在shell 提示符下以互動方式嘗試短Python 表達式和語句很容易,但是編寫、編輯和儲存檔案中更長、更複雜的程式更友善。然後,我們可以在IDLE 中運作這些程式檔案或腳本,也可以在作業系統的指令提示符下運作,而不打開IDLE。腳本檔案也是Python 程式分發給他人的方式。最重要的是,正如你從寫學期論文中知道的,檔案允許你安全和永久地儲存若幹小時的工作。
要以這種方式編寫和執行程式,請執行以下步驟:
- 從shell 視窗的“檔案”菜單中選擇“建立視窗”選項。
- 在新視窗中,按照希望Python 執行它們的順序,在單獨的行上輸入Python 表達式或語句。
- 在任何時候,你都可以通過選擇檔案/ 儲存來儲存檔案。如果要這樣做,你應該使用.py 擴充碼。例如,你的第一個程式檔案可能被命名為myprogram. py .
-
要以Python 腳本運作此代碼檔案,請從“運作”菜單中選擇“運作子產品”或按F5 鍵。
步驟4 中的指令從儲存的檔案中讀取代碼并執行。如果Python 執行代碼中的任何print 函數,你将像往常一樣在shell 視窗中看到輸出。如果代碼請求任何輸入,解釋器将暫停以等待你的輸入。否則,程式執行會在背景繼續。當解釋器執行完最後一條指令後,它退出并傳回shell 提示符。
圖1-7 顯示了一個IDLE 視窗,其中包含一個完整的腳本,提示使用者輸入矩形的寬度和高度,計算矩形的面積,并輸出結果。
腳本當腳本從IDLE 視窗運作時,它會在圖1-8 所示的shell 視窗中産生與使用者的互動。
與在Python 解釋器的提示下直接輸入程式相比,這可能是一種互動程度稍低的執行程式的方式。但是,從IDLE 視窗運作腳本将允許你建構一些複雜的程式,測試它們,并将它們儲存在程式庫中,以便重用或與他人共享。
1.4.4 幕後:Python 是如何工作的
無論你是将Python 代碼作為腳本運作還是在shell 中互動運作,Python 解釋器都會做大量工作來執行程式中的指令。這項工作可以分成一系列步驟,如圖1-9 所示。
- 解釋器讀取Python 表達式或語句,也稱為源代碼,并驗證其是否格式良好。在這一步中,解釋器表現得像一個嚴格的英語老師,拒絕任何不遵守文法規則的句子。一旦解釋器遇到這樣的錯誤,它就會停止并顯示一條錯誤消息。
- 如果Python 表達式格式良好,解釋器會将其翻譯成一種名為位元組碼的低級語言的等效形式。當解釋器運作腳本時,它會将其完全翻譯成位元組碼。
- 位元組碼随後被發送到另一個軟體元件中執行,該元件稱為Python 虛拟機(PVM)。如果在此步驟中發生另一個錯誤,執行也會停止,并顯示一條錯誤消息。
- 描述當程式員在Python shell 裡輸入字元串“Greetings!”時會發生什麼。
- 編寫一行代碼,提示使用者輸入自己的名字,并将使用者輸入儲存在名為name 的變量中。
- 什麼是Python 腳本?
- 解釋當你的計算機運作Python 程式時,幕後發生了什麼。
1.5 檢測和糾正文法錯誤
程式員在編寫程式時不可避免地會犯拼寫錯誤,Python 解釋器幾乎總能檢測到這些錯誤。這種錯誤稱為文法錯誤。術語文法是指在語言中形成句子的規則。當Python 在程式中遇到文法錯誤時,它會停止執行,并顯示錯誤消息。Python shell 的以下示例顯示了幾種類型的文法錯誤和相應的錯誤消息:
第一條語句為變量Length配置設定一個輸入值。下一條語句試圖列印變量Length的值。Python 回應說這個名字沒有定義。雖然程式員可能想寫變量Length,但是Python 隻能讀取程式員實際輸入的内容。這是一個很好的例子,說明一台計算機隻能讀取它接收的指令,而不能讀取我們打算給它的指令。
下一條語句試圖列印拼寫正确的變量的值。但是,Python 仍然會生成錯誤消息。
在此錯誤消息中,Python 解釋了這一行代碼意外縮進。事實上,在print之前還有一個額外的空格。縮進在Python 代碼中非常重要。在shell 提示符或腳本中輸入的每一行代碼必須從最左邊的列開始,沒有前導空格。此規則的唯一例外發生在控制語句和定義中,其中嵌套語句必須縮進一個或多個空格。
你可能會認為跟蹤程式中的縮進會很痛苦。然而,作為補償,Python 語言比其他程式設計語言簡單得多。是以,要遇到和糾正的文法錯誤類型更少,要學習的文法也更少!
在我們的最後一個例子中,程式員試圖添加兩個數字,但是忘記了第二個數字:
在後面的章節中,你将了解更多其他類型的程式錯誤以及如何修複産生這些錯誤的代碼。
- 假設你的腳本試圖列印尚未指派的變量的值,Python解釋器會有什麼反應?
- 如果米蘭達忘記在一行結束前完成算術表達式的代碼,Python解釋器會有什麼反應?
- 為什麼Python 代碼生成的文法錯誤類型少于其他程式設計語言的代碼?
1.6 拓展閱讀
1.7本章小結
● 計算機科學最基本的思想之一是算法。算法是解決問題的一系列指令。計算智能體可以執行這些指令以在有限的時間内解決問題。
● 計算機科學的另一個基本思想是資訊處理。實際上,現實世界對象之間的任何關系都可以表示為資訊或資料。計算智能體按照算法中描述的步驟操作資訊并對其進行轉換。
●真正的計算智能體可以由硬體裝置構成。這些裝置包括中央處理單元(CPU)、存儲器以及輸入和輸出裝置。CPU 包含執行算法描述的指令的電路。記憶體包含代表二進制數字的開關。存儲在存儲器中的所有資訊都以二進制形式表示。鍵盤和平闆掃描器等輸入裝置以及顯示器和揚聲器等輸出裝置在計算機記憶體和外部世界之間傳輸資訊。這些裝置還在二進制形式和人類可以使用的形式之間傳遞資訊。
● 一些真正的計算機,如手表和手機中的計算機,是專門用于一小部分任務的,而台式或膝上型計算機是一種通用的解決問題的機器。
● 軟體提供了在通用硬體裝置上運作不同算法的手段。軟體一詞可以指用于開發程式的編輯器和解釋器,用于管理硬體裝置的作業系統,用于與人類使用者通信的使用者界面,以及文字處理器、電子表格、資料庫管理器、遊戲和媒體處理程式等應用程式。
●軟體是用程式設計語言編寫的。Python 等語言是進階語言,它們類似于英語,允許作者向其他人清晰地表達自己的算法。一種叫作“解釋器”的程式将Python 語言編寫的程式翻譯成可以在真實計算機上執行的低級語言程式。
●Python shell 提供了一個指令提示符,用于評估和檢視Python 表達式和語句的結果。IDLE 是一個內建開發環境,允許程式員将程式儲存在檔案中,并加載到shell 中進行測試。
●Python 腳本是儲存在檔案中并從終端指令提示符運作的程式。互動式腳本由一組輸入語句、處理這些輸入的語句和輸出結果的語句組成。
●當Python 程式被執行時,它被翻譯成位元組碼。該位元組碼随後被發送到Python 虛拟機(PVM)以供進一步解釋和執行。
●文法是在程式設計語言中形成正确表達式和語句的一組規則。當解釋器在Python 程式中遇到文法錯誤時,它會停止執行,并顯示錯誤消息。文法錯誤的兩個例子是對一個變量的引用,在第一個例子中,該變量還沒有值,在第二個例子中,多了一個意想不到的縮進。
1.8 複習題
- 以下哪個是算法的例子?
- 字典 b. 食譜
- 一套組裝公用小屋的說明 d. 文字處理器中的拼寫檢查器
- 以下哪項包含資訊?
- 我祖母的瓷器櫃 b. 一張音頻CD光牒
- 一台冰箱 d. 一本書
- 一台運作中的計算機
- 以下哪項是通用計算裝置?
- 手機 b. 便攜式音樂播放器
- 筆記本電腦 d. 可程式設計恒溫器
-
以下哪項是輸入裝置?
a. 揚聲器 b. 麥克風
- 以下哪項是輸出裝置?
- 數位相機b. 鍵盤
- 平闆掃描器d. 顯示器
- 中央處理器的目的是什麼?
- 存儲資訊b. 接收來自人類使用者的輸入
- 解碼并執行指令d. 将輸出發送給人類使用者
- 下列哪一項用程式設計語言翻譯和執行指令?
- 編譯程式b. 文本編輯器
- 加載器d. 解釋器
- 以下哪一項在Python 程式中輸出資料?
- 輸入語句b. 指派語句
- 列印語句d. 主函數
- IDLE 用來做什麼?
- 編輯Python 程式b. 将Python 程式儲存到檔案中
- 運作Python 程式d. 所有上述情況
- 在一種語言中,用于造句的一組規則被稱為什麼?
- 語義b. 語用
- 文法d. 邏輯
1.9 程式設計項目
- 打開Python shell,輸入以下表達式并觀察結果:
- 8 b. 8 * 2
- 8 ** 2 d. 8 / 12
- 8 // 12 f. 8 / 0
- 編寫一個Python 程式,列印(顯示)你的姓名、位址和電話号碼。
- 在shell 提示符下評估以下代碼:print("Your name is",name)。然後給name 配置設定一個合适的值,并再次評估語句。
- 打開一個IDLE 視窗,輸入圖1-7 中計算矩形面積的程式。按F5 鍵将程式加載到shell 中,并糾正出現的任何錯誤。用不同的輸入測試程式至少三次。
- 修改上一題的程式來計算三角形的面積。對三角形的底邊和高度給出适當的提示,并适當更改變量的名稱。然後,使用公式 來計算面積。從IDLE 視窗測試程式。
帶你讀《Python 程式設計與問題求解(原書第2版)》之一:引言第1章 - 編寫并測試一個計算圓的面積的程式。這個程式應該請求一個代表半徑的數字作為使用者的輸入。它應該使用公式 來計算面積,然後輸出适當标注的結果。
帶你讀《Python 程式設計與問題求解(原書第2版)》之一:引言第1章 - 編寫并測試一個接受使用者名(作為文本)和年齡(作為數字)作為輸入的程式。程式應該輸出包含使用者姓名和年齡的句子。
- 在shell 提示符下使用input函數輸入語句。當提示要求你輸入時,請輸入一個數字。然後,嘗試将數字加1,觀察結果,并解釋發生了什麼。
- 在shell 提示符下使用input函數輸入語句。當提示要求你輸入時,輸入你的名字,觀察結果,并解釋發生了什麼。
- 在shell 提示符下輸入表達式help()。按照說明浏覽主題和子產品。