您現在的位置是:首頁 > 技術教程

30分鐘學會用Python編寫簡單程序

曙光部落格2022-08-20 08:34:39【技術教程】

學習目標

知道有序的軟件開發過程的步驟。

了解遵循輸入、處理、輸出(IPO)模式的程序,並能夠以簡單的方式修改它們。

了解構成有效Python標識符和表達式的規則。

能夠理解和編寫Python語句,將信息輸出到屏幕,為變量賦值,獲取通過鍵盤輸入的信息,並執行計數循環。

軟件開發過程

運行已經編寫的程序很容易。較難的部分實際上是先得到一個程序。計算機是非常實在的,必須告訴它們要做什麼,直至最後的細節。編寫大型程序是一項艱巨的挑戰。如果沒有系統的方法,幾乎是不可能的。

創建程序的過程通常被分成幾個階段,依據是每個階段中產生的信息。簡而言之,你應該做以下工作。

分析問題確定要解決的問題是什麼。嘗試盡可能多地了解它。除非真的知道問題是什麼,否則就不能開始解決它。

確定規格說明准確描述程序將做什麼。此時,你不必擔心程序“怎麼做”,而是要確定它“做什麼”。對於簡單程序,這包括仔細描述程序的輸入和輸出是什麼以及它們的相互關系。

創建設計規劃程序的總體結構。這是描述程序怎麼做的地方。主要任務是設計算法來滿足規格說明。

實現設計將設計翻譯成計算機語言並放入計算機。在本書中,我們將算法實現為Python程序。

測試/調試程序試用你的程序,看看它是否按預期工作。如果有任何錯誤(通常稱為“缺陷”),那麼你應該回去修復它們。定位和修復錯誤的過程稱為“調試”程序。在調試階段,你的目標是找到錯誤,所以應該嘗試你能想到的“打破”程序的一切可能。記住這句老格言:“沒有什麼能防住人犯傻,因為傻子太聰明了。”

維護程序繼續根據用戶的需求開發該程序。大多數程序從來沒有真正完成,它們在多年的使用中不斷演進。

示例程序:溫度轉換器

讓我們通過一個真實世界的簡單例子,來體驗軟件開發過程的步驟,其中涉及一個虛構的計算機科學學生Susan Computewell。

Susan正在德國學習一年。她對語言沒有任何問題,因為她能流利地使用許多語言(包括Python)。她的問題是,很難在早上弄清楚溫度從而知道當天該穿什麼衣服。Susan每天早上聽天氣報告,但溫度以攝氏度給出,她習慣了華氏度。

幸運的是,Susan有辦法解決這個問題。作為計算機科學專業的學生,她去任何地方總是帶著她的筆記本計算機。她認為計算機程序可能會幫助她。

Susan開始分析她的問題。在這個例子中,問題很清楚:無線電廣播員用攝氏度報氣溫,但Susan只能理解華氏溫度。

接下來,Susan考慮可能幫助她的程序的規格說明。輸入應該是什麼?她決定程序將允許她輸入攝氏溫度。輸出呢?程序將顯示轉換後的華氏溫度。現在她需要指定輸出與輸入的確切關系。

蘇珊快速估算了一下。她知道0攝氏度(冰點)等於32華氏度,100攝氏度(沸點)等於212華氏度。有了這個信息,她計算出華氏度與攝氏度的比率為(212−32)/(100−0) = (180/100) = 9/5。使用F表示華氏溫度,C表示攝氏溫度,轉換公式的形式為F= (9/5)C+k,其中k為某個常數。代入0和32分別作為C和F,Susan立即得到k= 32。所以最後的關系公式是F= (9/5)C+ 32。這作為規格說明似乎足夠了。

請注意,這描述了能夠解決這個問題的許多可能程序中的一個。如果Susan有人工智能(AI)領域的背景,她可能會考慮寫一個程序,用語音識別算法實際收聽收音機播音員,獲得當前的溫度。對於輸出,她可以讓計算機控制機器人進入她的衣櫃,並根據轉換後的溫度選擇適當的服裝。這將是一個更有野心的項目,一點也不誇張!

當然,機器人程序也會解決問題分析中識別的問題。規格說明的目的,是准確地決定這個特定的程序要做什麼,從而解決一個問題。Susan知道,最好是先弄清楚她希望構建什麼,而不是一頭鑽進去開始編程。

Susan現在准備為她的問題設計一個算法。她馬上意識到這是一個簡單算法,遵循標准模式“輸入、處理、輸出”(IPO)。她的程序將提示用戶輸入一些信息(攝氏溫度),處理它,產生華氏溫度,然後在計算機屏幕上顯示結果,作為輸出。

Susan可以用一種計算機語言來寫她的算法。然而,正式將它寫出來需要相當的精度,這常常會扼殺開發算法的創造性過程。作為替代,她用“偽代碼”編寫算法。偽代碼只是精確的英語,描述了程序做的事。這意味著既可以交流算法,又不必讓大腦承擔額外的開銷,正確寫出某種特定編程語言的細節。

下面是Susan的完整算法:

輸入攝氏度溫度(稱為celsius)

計算華氏度為(9/5)celsius + 32

輸出華氏度

下一步是將此設計轉換為Python程序。這很直接,因為算法的每一行都變成了相應的Python代碼行。

# convert.py

# A program to convert Celsius temps to Fahrenheit

# by: Susan Computewell

defmain():

celsius = eval(input("What is the Celsius temperature? "))

fahrenheit =9/5* celsius +32

print("The temperature is", fahrenheit,"degrees Fahrenheit.")

main()

看看你是否能弄清楚這個程序的每一行做了什麼。如果一些部分不是很清楚,也不要擔心,下一節將詳細討論。

完成程序後,Susan測試它,看看它工作得如何。她使用她知道正確答案的輸入。下面是兩個測試的輸出:

Whatisthe Celsius temperature?

The temperatureis32.0degrees Fahrenheit.

Whatisthe Celsius temperature?100

The temperatureis212.0degrees Fahrenheit.

你可以看到,Susan用值0和100來測試她的程序。看起來不錯,她對解決方案感到滿意。她特別高興的是,似乎沒有必要調試(這很不尋常)。

程序要素

既然已經知道了編程過程,你就“幾乎”准備好開始自己編寫程序了。在此之前,你需要更完整的基礎,了解Python的基本知識。接下來的幾節將討論一些技術細節,這對編寫正確程序至關重要。這種材料看起來有點乏味,但你必須掌握這些基礎,然後再進入更有趣的領域。

1 名稱

你已經看到,名稱是編程的重要組成部分。我們為模塊命名(例如convert),也為模塊中的函數命名(例如main)。變量用於為值命名(例如celsius和fahrenheit)。從技術上講,所有這些名稱都稱為“標識符”。Python對標識符的構成有一些規則。每個標識符必須以字母或下劃線(“_”字符)開頭,後跟字母、數字或下劃線的任意序列。這意味著單個標識符不能包含任何空格。

根據上述規則,以下都是Python中的合法名稱:

x

celsius

spam

spam2

SpamAndEggs

Spam_and_Eggs

標識符區分大小寫,因此對Python來說,spam、Spam、sPam和SPAM是不同的名稱。在大多數情況下,程序員可以自由選擇符合這些規則的任何名稱。好的程序員總是試圖選擇一些名字,它們能描述被命名的東西。

需要注意一件重要的事情:一些標識符是Python本身的一部分。這些名稱稱為“保留字”或“關鍵字”,不能用作普通標識符。Python關鍵字的完整列表如表1所列。

表1  Python關鍵字

False

class

finally

is

return

Python還包括相當多的內置函數,例如我們用過的print函數。雖然在技術上可以將內置的函數名稱標識符用於其他目的,但這通常是一個“非常糟糕”的主意。例如,如果你重新定義print的含義,那麼就無法再打印信息。你也會讓所有閱讀程序的Python程序員感到非常困惑,他們預期print指的是內置函數。內置函數的完整列表可在附錄A中找到。

2 表達式

程序操作數據。到目前為止,我們已經在示例程序中看到了數字和文本兩種不同類型的數據。我們將在後面的節中詳細討論這些不同的數據類型。現在,你只需要記住,所有的數據必須以一些數字格式存儲在計算機上,不同類型的數據以不同的方式存儲。

產生或計算新數據值的程序代碼片段稱為“表達式”。最簡單的表達式是字面量。字面量用於表示特定值。在chaos.py中,你可以找到數字3.9和1。convert.py程序包含9、5和32。這些都是數字字面量的例子,它們的含義顯而易見:32就是代表32(數字32)。

我們的程序還以一些簡單的方式處理文本數據。計算機科學家將文本數據稱為“字符串”。你可以將字符串視為可打印字符的序列。Python中通過將字符括在引號("")中來表示字符串字面量。如果你回頭看看我們的示例程序,可以發現一些字符串字面量,例如"Hello"和"Enter a number between 0 and 1:"。這些字面量產生的字符串包含引號內的字符。請注意,引號本身不是字符串的一部分。它們只是告訴Python創建一個字符串的機制。

將表達式轉換為基礎數據類型的過程稱為“求值”。在Python shell中鍵入表達式時,shell會計算表達式並打印出結果的文本表示。請考慮以下簡短的交互:

>>>32

32

>>>"Hello"

'Hello'

>>>"32"

'32'

請注意,當shell顯示字符串的值時,它將字符序列放在單引號中。這樣讓我們知道該值實際上是文本而不是數字(或其他數據類型)。在最後一次交互中,我們看到表達式"32"產生一個字符串,而不是一個數字。在這種情況下,Python實際上是存儲字符“3”和“2”,而不是數字32的表示。如果你現在不太明白,不要太擔心。我們在後面的節中討論這些數據類型時,你的理解就會變得更加清晰。

一個簡單的標識符也可以是一個表達式。我們使用標識符作為變量來給名字賦值。當標識符作為表達式出現時,它的值會被取出,作為表達式的結果。下面是與Python解釋器的交互,展示了變量作為表達式:

>>> x =5

>>> x

5

>>> print(x)

5

>>> print(spam)

Traceback (most recent call last):

File"", line1,in

NameError:name'spam'isnotdefined

首先,變量x被賦值為5(使用數字字面量5)。在第二行交互中,我們要求Python對表達式x求值。作為響應,Python shell打印出5,這是剛才賦給x的值。當然,如果我們明確要求Python用print語句打印x,也會得到相同的結果。最後一個交互展示了如果嘗試使用未賦值的變量,會發生什麼。Python找不到值,所以它報告NameError。這說明沒有該名稱的值。這裡的要點是,變量總是必須賦一個值,然後才能在表達式中使用。

較復雜、較有趣的表達式可以通過組合較簡單的表達式和操作符來構造。對於數字,Python提供了一組標准的數學運算:加法、減法、乘法、除法和乘方。相應的Python運算符為“+”“-”“*”“/”和“**”。下面是一些來自chaos.py和convert.py的復雜表達式的例子:

3.9* x *(1 - x)

9/5 * celsius + 32

空格在表達式中沒有作用。最後一個表達式如果寫成9/5*celsius+32,結果完全相同。通常,在表達式中加一些空格讓它更容易閱讀,是個好方法。

Python的數學運算符遵循的優先級和結合律,與你在數學課上學到的相同,包括使用括號來改變求值的順序。在自己的程序中構建復雜表達式應該沒什麼困難。請記住,只有圓括號在數字表達式中是允許的。如果需要,可以嵌套使用它們,創建如下的表達式:

((x1 - x2) / 2*n) + (spam / k**3)

順便說一句,Python還提供了字符串的運算符。例如,可以“加”字符串。

>>>"Bat"+"man"

'Batman'

這被稱為“連接”。如你所見,效果是創建一個新的字符串,把兩個字符串“粘”在一起。

3 輸出語句

既然有了基本的構建塊(標識符和表達式),你就可以更完整地描述各種Python語句。 你已經知道信息可以使用Python的內置函數print在屏幕上顯示。到目前為止,我們已經看了幾個例子,但我還沒有詳細解釋打印功能。像所有的編程語言一樣,Python對每個語句的語法(形式)和語義(意義)有一套精確的規則。計算機科學家已經開發了復雜的符號表示法,稱為“元語言”,用於描述編程語言。在本書中,我們將依靠一個簡單的模板符號表示法來說明各種語句的語法。

因為print是一個內置函數,所以print語句與任何其他函數調用具有相同的一般形式。我們鍵入函數名print,後面帶上括號中列出的參數。下面是用我們的模板符號時print語句看起來的樣子:

print(,, ...,)

print()

這兩個模板展示了兩種形式的print語句。第一個表示print語句可以包含函數名print,後面帶上帶括號的表達式序列,用逗號分隔。模板中的尖括號符號()用於表示由Python代碼的其他片段填充的“槽”。括號內的名稱表示缺少什麼,expr表示一個表達式。省略號(“...”)表示不確定的序列(在這個例子中是表達式)。你實際上不會輸入圓點。第二個版本的print語句表明,不打印任何表達式的print也是合法的。

就語義而言,print語句以文本形式顯示信息。所有提供的表達式都從左到右求值,結果值以從左到右的方式顯示在輸出行上。默認情況下,在顯示的值之間放置一個空格字符。作為示例,下面print語句的序列:

print(3+4)

print(3, 4, 3 + 4)

print()

print("The answer is", 3 + 4)

產生的輸出為:

7

347

The answeris7

最後一個語句說明了,字符串字面量表達式如何經常在print語句使用,作為標記輸出的方便方法。

注意,連續的print語句通常顯示在屏幕的不同行上。空print(無參數)生成空行輸出。在背後,真正發生的是,在打印所有提供的表達式之後,print函數自動附加某種結束文本。默認情況下,結束文本是表示行結束的特殊標記字符(表示為“/n”)。我們可以通過包含一個附加參數顯式地覆蓋這個默認值,從而改變這種行為。這裡使用命名參數的特殊語法,或稱為“關鍵字”參數。

包含指定結束文本的關鍵字參數的print語句的模板如下:

print(,, ...,, end="/n")

命名參數的關鍵字是end,它使用“=”符號賦值,類似於變量賦值。注意,在模板中我已經顯示其默認值,即行末字符。這是一種標准方式,用於顯示在未明確指定某個其他值時,關鍵字參數具有的值。

print語句中的end參數有一個常見用法,即允許多個print構建單行輸出。例如:

print("The answer is", end=" ")

print(3 + 4)

產生單行輸出:

The answeris7

注意,第一個print語句的輸出如何以空格(" ")而不是行末字符結束,第二個語句的輸出緊跟在空格之後。

4 賦值語句

Python中最重要的語句之一是賦值語句。我們在前面的例子中已經看到了一些。

簡單賦值

基本賦值語句具有以下形式:

=

這裡variable是一個標識符,expr是一個表達式。賦值的語義是,右側的表達式被求值,然後產生的值與左側命名的變量相關聯。

下面是我們已經看到的一些賦值:

x=3.9* x * (1- x)

fahrenheit=9/5* celsius +32

x=5

變量可以多次賦值。它總是保留最新賦的值。下面的交互式Python會話展示了這一點:

>>> myVar =

>>> myVar

>>> myVar =7

>>> myVar

7

>>> myVar = myVar +1

>>> myVar

8

最後一個賦值語句展示了如何使用變量的當前值來更新它的值。在這個例子中,我只是對以前的值加1。記住,變量的值可以改變,這就是為什麼它們被稱為變量的原因。

有時,將變量看作計算機內存中的一種命名的存儲位置是有幫助的,我們可以在其中放入一個值。當變量更改時,舊值將被刪除,並寫入一個新值。圖1展示了用這個模型來描繪x=x+ 1的效果。這正是賦值在某些計算機語言中工作的方式。這也是查看賦值效果的一種非常簡單的方式,你會在整本書中看到類似這樣的圖片。

圖1x=x+ 1的視圖,變量就像盒子

Python賦值語句實際上與“變量盒子”模型略有不同。在Python中,值可能最終放在內存中的任何位置,而變量用於引用它們。對變量賦值就像把一個黃色小粘貼便簽放在值上,並說“這是x”。圖2給出了一個更准確的Python賦值的效果。箭頭用於顯示變量引用的值。請注意,舊值不會被新值擦除,變量只需切換到引用新值。效果就像將粘貼便簽從一個對像移動到另一個對像一樣。這是賦值在Python中實際工作的方式,所以你會看到這樣一些粘貼便簽樣式的圖片散布在本書中。

30分鐘學會用Python編寫簡單程序 30分鐘學會用Python編寫簡單程序 程序開發 

圖2

x=x+ 1的(Python)視圖,變量就像便簽

順便說一句,即使賦值語句不直接導致變量的舊值被擦除和覆蓋,你也不必擔心計算機內存中充滿“被丟棄”的值。如果一個值不再被任何變量引用,它就不再有用。Python將自動從內存中清除這些值,以便空間可以用於存放新值。這就像檢查你的衣櫃,拋出沒有粘貼便簽標記的東西。實際上,這個自動內存管理的過程確實被稱為“垃圾收集”。

賦值輸入

輸入語句的目的是從程序的用戶那裡獲取一些信息,並存儲到變量中。一些編程語言有一個特殊的語句來做到這一點。在Python中,輸入是用一個賦值語句結合一個內置函數input實現的。輸入語句的確切形式,取決於你希望從用戶那裡獲取的數據類型。對於文本輸入,語句如下所示:

= input(

)

這裡的

是一個字符串表達式,用於提示用戶輸入。提示幾乎總是一個字符串字面量(即引號內的一些文本)。

當Python遇到對input的調用時,它在屏幕上打印提示。然後,Python暫停並等待用戶鍵入一些文本,鍵入完成後按鍵。用戶輸入的任何東西都會存儲為字符串。請考慮以下簡單的交互:

>>> name = input("Enter your name: ")

Enter yourname:John Yaya

>>> name

'John Yaya'

執行input語句導致Python打印輸出提示“Enter your name:”,然後解釋器暫停,等待用戶輸入。在這個例子中,我鍵入John Yaya。結果,字符串“John Yaya”被記在變量name中。對name求值將返回我鍵入的字符串。

如果用戶輸入是一個數字,我們需要形式稍復雜一點的input語句:

=eval(input(

))

這裡我添加了另一個內置的Python函數eval,它“包裹”了input函數。你可能會猜到,eval是“evaluate(求值)”的縮寫。在這種形式中,用戶鍵入的文本被求值為一個表達式,以產生存儲到變量中的值。舉例來說,字符串“32”就變成數字32。如果回頭看看示例程序,到目前為止,你會看到幾個例子,我們像這樣從用戶那裡得到了數字。

x= eval(input("Please enter a number between 0 and 1: "))

celsius= eval(input("What is the Celsius temperature? "))

重要的是要記住,如果希望得到一個數字,而不是一些原始文本(字符串),需要對input進行eval。

如果你仔細閱讀示例程序,可能會注意到所有這些提示結尾處的引號內的空格。我通常在提示的末尾放置一個空格,以便用戶輸入的內容不會緊接著提示開始。放上空格可以讓交互更容易閱讀和理解。

雖然我們的數字示例特別提示用戶輸入數字,但在這個例子中,用戶鍵入的只是一個數字字面量,即一個簡單的Python表達式。事實上,任何有效的表達式都是可接受的。請考慮下面與Python解釋器的交互:

>>> ans = eval(input("Enter an expression: "))

Enter anexpression:3+4*5

>>> print(ans)

23

>>>

這裡,提示輸入表達式時,用戶鍵入“3 + 4 * 5”。Python對此表達式求值(通過eval),並將值賦給變量ans。打印時,我們看到ans的值為23,與預期一樣。在某種意義上,input-eval組合就像一個延遲的表達式。示例交互產生完全相同的結果,就像我們簡單地寫成ans = 3 + 4 * 5一樣。不同的是,表達式由用戶在語句執行時提供,而不是由程序員在編程時輸入。

注意:eval函數功能非常強大,也有“潛在的危險”。如本例所示,當我們對用戶輸入求值時,本質上是允許用戶輸入一部分程序。Python將盡職盡責地對他們輸入的任何內容求值。了解Python的人可以利用這種能力輸入惡意指令。例如,用戶可以鍵入記錄計算機上的私人信息或刪除文件的表達式。在計算機安全中,這被稱為“代碼注入”攻擊,因為攻擊者將惡意代碼注入正在運行的程序中。

作為一名新程序員,編程給自己個人使用,計算機安全不是很大的問題。如果你坐在一台運行Python程序的計算機前面,你可能擁有對系統的完全訪問權限,並且可以找到更簡單的方法來刪除所有文件。然而,如果一個程序的輸入來自不受信任的來源,例如來自互聯網上的用戶,使用eval可能是災難性的。

同時賦值

有一個賦值語句的替代形式,允許我們同時計算幾個值。它看起來像這樣:

,, ...,=,, ...,

這稱為“同時賦值”。語義上,這告訴Python對右側所有表達式求值,然後將這些值賦給左側命名的相應變量。下面是一個例子:

sum, diff = x+y, x-y

這裡,sum得到x和y的和,diff得到x和y的差。

這種形式的賦值初看很奇怪,但實際上非常有用。這裡有一個例子:假設有兩個變量x和y,你希望交換它們的值。也就是說,你希望將當前存儲在x中的值存儲在y中,將當前存儲在y中的值存儲在x中。首先,你可能認為這可以通過兩個簡單的賦值來完成:

x= y

y= x

這不行。我們可以一步一步地跟蹤這些語句的執行,看看為什麼。

假設x和y開始的值是2和4。讓我們檢查程序的邏輯,看看變量是如何變化的。以下序列用注釋描述了在執行這兩個語句時變量會發生什麼:

# 變量 x y

# 初始值 2 4

x= y

# 現在是 4 4

y= x

# 最後是 4 4

看到第一個語句將y的值賦給x,從而修改了x的原始值嗎?當我們在第二步將x的值賦給y時,最終得到了原始y值的兩個副本。

完成交換的一種方法是引入一個附加變量,它暫時記住x的原始值。

temp= x

x= y

y= temp

讓我們來看看這個序列是如何工作的。

# 變量 x y temp

# 初始值 2 4 暫時無值

temp= x

# 2 4 2

x= y

# 4 4 2

y= temp

# 4 2 2

從x和y的最終值可以看出,在這個例子中,交換成功。

這種三變量交換的方式在其他編程語言中很常見。在Python中,同時賦值語句提供了一種優雅的選擇。下面是更簡單的Python等價寫法:

x, y = y, x

因為賦值是同時的,所以它避免了擦除一個原始值。

同時賦值也可以用單個input從用戶那裡獲取多個數字。請考慮下面的程序,它求出考試平均分:

# avg2.py

# A simple program to average two exam scores

# Illustrates use of multiple input

defmain():

print("This program computes the average of two exam scores.")

score1, score2 = eval(input("Enter two scores separated by a comma: "))

average = (score1 + score2) /2

print("The average of the scores is:", average)

main()

該程序提示用逗號分隔兩個分數。假設用戶鍵入86,92。input語句的效果就像進行以下賦值:

score1, score2 = 86, 92

我們已經為每個變量獲得了一個值。這個例子只用了兩個值,但可以擴展到任意數量的輸入。

當然,我們也可以通過單獨的input語句獲得用戶的輸入:

score1= eval(input("Enter the first score: "))

score2= eval(input("Enter the second score: "))

某種程度上,這可能更好,因為單獨的提示對用戶來說信息更准確。在這個例子中,決定采用哪種方法在很大程度上是品位問題。有時在單個input中獲取多個值提供了更直觀的用戶接口,因此在你的工具包中,這是一項好技術。但要記住,多個值的技巧不適用於字符串(非求值)輸入,如果用戶鍵入逗號,它只是輸入字符串中的一個字符。逗號僅在隨後對字符串求值時,才成為分隔符。

確定循環

你已經知道,程序員用循環連續多次執行一系列語句。最簡單的循環稱為“確定循環”。這是會執行一定次數的循環。也就是說,在程序中循環開始時,Python就知道循環(或“迭代”)的次數。例如,前面介紹的chaos程序用了一個總是執行10次的循環:

foriinrange(10):

x = 3.9 * x * (1 - x)

print(x)

這個特定的循環模式稱為“計數循環”,它用Python的for語句構建。在詳細分析這個例子之前,讓我們來看看什麼是for循環。

Python的for循環具有以下一般形式:

forin:

循環體可以是任意Python語句序列。循環體的範圍通過它在循環頭(for in :部分)下面的縮進來表示。

關鍵字for後面的變量稱為“循環索引”。它依次取sequence中的每個值,並針對每個值都執行一次循環體中的語句。通常,sequence部分由值“列表”構成。列表是Python中一個非常重要的概念,你將在後續節中了解更多。現在只要知道,可以在方括號中放置一系列表達式,從而創建一個簡單的列表。下列交互示例有助於說明這一點:

你能看到這兩個例子做了什麼嗎?依次使用列表中的每個值執行了循環體。列表的長度決定了循環執行的次數。在第一個例子中,列表包含4個值,即0至3,並且簡單地打印了這些連續的i值。在第二個例子中,odd取前5個奇數的值,循環體打印了這些數字的平方。

現在,讓我們回到這一節開始的例子(來自chaos.py)再看一下循環頭:

foriinrange(10):

將它與for循環的模板進行比較可以看出,最後一個部分range(10)必定是某種序列。事實上,range是一個內置的Python函數,用於“當場”生成一個數字序列。你可以認為range是一種數字序列的隱性描述。要明白range實際上做了什麼,我們可以要求Python用另一個內置函數list,將range轉換為一個簡單的舊式列表:

>>> list(range(10))# turns range(10) into an explicit list

[,1,2,3,4,5,6,7,8,9]

你看到這裡發生了什麼嗎?表達式range(10)產生數字0到9的序列。使用range(10)的循環等價於使用那些數字的列表的循環。

foriin[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:

一般來說,range()將產生一個數字序列,從0開始,但不包括的值。如果你想一想,就會發現表達式的值確定了結果序列中的項數。在chaos.py中,我們甚至不關心循環索引變量使用了什麼值(因為i沒有在循環體中的任何位置引用)。我們只需要一個長度為10的序列,讓循環體執行10次。

正如前面提到的,這種模式稱為“計數循環”,它是使用確定循環的一種很常見的方式。如果你希望在程序中做一定次數的某些事,請用一個帶有合適range的for循環。下面一個反復出現的Python編程習語,你需要記住:

forinrange():

表達式的值確定了循環執行的次數。索引變量的名稱實際上並不重要,程序員經常使用i或j作為計數循環的循環索引變量。只要確保使用的標識符沒有用於任何其他目的,否則你可能會不小心清除稍後需要的值。

循環的有趣和有用之處在於,它們改變程序“控制流”的方式。通常我們認為計算機是嚴格按順序執行一系列指令。引入循環會導致Python退回去並重復執行一些語句。類似for循環的語句稱為“控制結構”,因為它們控制程序其他部分的執行。

一些程序員發現,用圖片的方式來思考控制結構是有幫助的,即所謂的“流程圖”。流程圖用一些框來表示程序的不同部分,並用框之間的箭頭表示程序運行時的事件序列。圖3用流程圖描述了for循環的語義。

30分鐘學會用Python編寫簡單程序 30分鐘學會用Python編寫簡單程序 程序開發 

圖3 for循環的流程圖

如果你在理解for循環時遇到困難,可能會發現學習流程圖很有用。流程圖中的菱形框表示程序中的決定。當Python遇到循環頭時,它檢查序列中是否有項。如果答案為“是”,則循環索引變量被賦予序列中的下一項,然後執行循環體。一旦循環體完成,程序返回到循環頭並檢查序列中的下一個值。如果沒有更多的項,循環就退出,程序移動到循環之後的語句。

示例程序:終值

我們用另一個編程過程的例子來結束本文。我們希望開發一個程序來確定投資的終值。我們將從對問題的分析開始。你知道存入銀行賬戶的錢會賺取利息,這個利息隨著時間的推移而累積。從現在起10年後,一個賬戶將有多少錢?顯然,這取決於我們開始有多少錢(本金)以及賬戶賺多少利息。給定本金和利率,程序應該能夠計算未來10年投資的終值。

我們繼續制定程序的確切規格說明。記住,這是程序做什麼的描述。輸入應該是什麼?我們需要用戶輸入初始投資金額,即本金。我們還需要說明賬戶賺多少利息。這取決於利率和計復利的頻率。處理此問題的一種簡單方法是讓用戶輸入年度百分比率。無論實際利率和復利頻率如何,年利率告訴我們一年內的投資收益。如果年利率為3%,那麼100美元的投資將在一年的時間內增長到103美元。用戶應如何表示年利率3%?有一些合理的選擇。讓我們假設用戶提供一個小數,因此利率將輸入為0.03。

這樣就得到以下規格說明:

程序 終值

輸入

principal 投資於美元的金額。

APR 以十進制數表示的年度百分比利率。

輸出 投資10年後的終值。

關系 一年後的價值由principal(1 + apr)給出。該公式需要應用10次。

接下來為程序設計一個算法。我們將使用偽代碼,這樣就可以闡明我們的想法而又不必擔心Python的所有規則。對於我們的規格說明,算法看起來很簡單。

打印介紹

輸入本金的金額(principal)

輸入年度百分比利率(apr)

重復10次:

principal = principal *(1 + apr)

輸出principal的值

如果你知道一些金融數學(或者只是一些基本代數)的知識,可能會意識到,在這個設計中並不一定要用循環。有一個公式可以利用乘冪一步算出終值。我在這裡用了一個循環來展示另一個計數循環,另一個原因是這個版本適合進行一些修改,在本文末尾的編程練習中將討論。無論如何,這個設計說明有時算法的計算方式可以讓數學更容易。知道如何計算一年的利息,就讓我們能計算未來任意年數的利息。

既然我們已經在偽代碼中想明白了這個問題,現在該利用我們的Python新知識開發一個程序了。算法的每一行都轉換為一條Python語句:

打印介紹(print語句,第2.4節)

print("This program calculates the future value")

print("of a 10-year investment.")

輸入本金的金額(數值input,第2.5.2節)

principal =eval(input("Enter the initial principal: "))

輸入年度百分比利率(數值input,第2.5.2節)

apr =eval(input("Enter the annual interest rate: "))

重復10次:(計數循環,第2.6節)

foriinrange(10):

計算principal = principal * (1 + apr)(簡單賦值,第2.5.1節)

principal = principal * (1 + apr)

輸出principal的值(print語句,第2.4節)

print("The value in 10 years is:", principal)

該程序中的所有語句類型都已在本文中詳細討論過。如果有任何問題,請回頭查看相關說明。特別要注意的是,計數循環模式用於應用10次利息公式。

就到這裡了。下面是完成的程序:

# futval.py

# A program to compute the value of an investment

# carried 10 years into the future

defmain():

print("This program calculates the future value")

print("of a 10-year investment.")

principal = eval(input("Enter the initial principal: "))

apr = eval(input("Enter the annual interest rate: "))

foriinrange(10):

principal = principal * (1+ apr)

print("The value in 10 years is:", principal)

main()

注意,我添加了幾個空行來分隔程序的輸入、處理和輸出部分。策略性地放置“空行”能讓程序更具有可讀性。

這就是我所舉的例子,測試和調試是留給你的練習。

小結

本文介紹了開發程序的過程,以及實現簡單程序所需的許多Python細節。下面是一些要點的快速小結。

編寫程序需要一種系統的方法來解決問題,包括以下步驟。

1.問題分析:研究需要解決的問題。

2.程序規格說明:確定程序要做什麼。

3.設計:用偽代碼編寫算法。

4.實現:將設計翻譯成編程語言。

5.測試/調試:查找和修復程序中的錯誤。

6.維護:讓程序保持最新,滿足不斷變化的需求。

許多簡單的程序遵循輸入、處理、輸出(IPO)的模式。

程序由標識符和表達式構成的語句組成。

標識符是一些名稱,它們以下劃線或字母開頭,後跟字母、數字或下劃線字符的組合。Python中的標識符區分大小寫。

表達式是產生數據的程序片段。表達式可以由以下部件組成:

字面量字面量是特定值的表示。例如,3是數字3的字面量表示。

變量變量是存儲值的標識符。

運算符運算符用於將表達式組合為更復雜的表達式。例如,在x+ 3 *y中,使用了運算符+和*。

數字的Python運算符包括加法(+)、減法(-)、乘法(*)、除法(/)和乘冪(**)等常見的算術運算。

Python輸出語句print將一系列表達式的值顯示在屏幕上。

在Python中,使用等號(=)表示將值賦給變量。利用賦值,程序可以從鍵盤獲得輸入。Python還允許同時賦值,這對於利用單個提示獲取多個輸入值很有作用。

eval函數可用來對用戶輸入求值,但它是一種安全風險,不應該用於未知或不可信來源的輸入。

確定循環是執行次數已知的循環。Python的for語句是一個循環遍歷一系列值的確定循環。Python列表通常在for循環中用於為循環提供一系列值。

for語句的一個重要用途是實現計數循環,這是專門設計的循環,以便將程序的某些部分重復特定的次數。Python中的計數循環通過使用內置的range函數,來產生適當大小的數字序列。

判斷對錯

1.編寫程序的最好方法是立即鍵入一些代碼,然後調試它,直到它工作。

2.可以在不使用編程語言的情況下編寫算法。

3.程序在寫入和調試後不再需要修改。

4.Python標識符必須以字母或下劃線開頭。

5.關鍵詞是好的變量名。

6.表達式由文字、變量和運算符構成。

7.在Python中,x=x+ 1是一個合法的語句。

8.Python不允許使用單個語句輸入多個值。

9.計數循環被設計為迭代特定次數。

10.在流程圖中,菱形用於展示語句序列,矩形用於判斷點。

多項選擇

1.以下項不是軟件開發過程中的一個步驟。

a.規格說明     b.測試/調試    c.決定費用     d.維護

2.將攝氏度轉換為華氏度的正確公式是。

a.F= 9/5(C) + 32         b.F= 5/9(C) − 32

c.F=B2− 4ACd.F= (212 – 32)/(100 – 0)

3.准確描述計算機程序將做什麼來解決問題的過程稱為。

a.設計       b.實現     c.編程       d.規格說明

4.以下項不是合法的標識符。

a.     b.     c.     d.

5.下列不在表達式中使用。

a.變量      b.語句      c.操作符    d.字面量

6.生成或計算新數據值的代碼片段被稱為。

a.標識符     b.表達式    c.生成子句     d.賦值語句

7.以下項不是IPO模式的一部分。

a.輸入       b.程序      c.處理       d.輸出

8.模板描述了。

a.一般循環         b.賦值語句

c.流程圖             d.計數循環

9.以下項是最准確的Python賦值模型。

a.粘貼便簽     b.變量盒子    c.同時       d.塑料尺

10.在Python中,獲取用戶輸入通過一個特殊的表達式來實現,稱為。

a.       b.     c.同時賦值     d.

討論

1.列出並用你自己的語言描述軟件開發過程中的六個步驟。

2.寫出chaos.py程序(第1.6節),並識別程序的各部分如下:

圈出每個標識符。

為每個表達式加下劃線。

在每一行的末尾添加注釋,指示該行上的語句類型(輸出、賦值、輸入、循環等)。

3.解釋確定循環、for循環和計數循環幾個概念之間的關系。

4.顯示以下片段的輸出:

a.

b.

c.

d.

5.先寫出一個算法的偽代碼而不是立即投入Python代碼,為什麼是一個好主意?

6.除end之外,Python的函數還支持其他關鍵字參數。其中一個關鍵字參數是。你認為參數是什麼?(提示:是分隔符的縮寫。通過交互式執行或通過查閱Python文檔來檢驗你的想法)。

7.如果執行下面的代碼,你認為會發生什麼?

print("start")

foriinrange(0):

print("Hello")

print("end")

看看本文的for語句的流程圖,幫助你弄明白。然後在程序中嘗試這些代碼,檢驗你的預測。

編程練習

1.一個用戶友好的程序應該打印一個介紹,告訴用戶程序做什麼。修改convert.py程序(第2.2節),打印介紹。

2.在許多使用Python的系統上,可以通過簡單地點擊(或雙擊)程序文件的圖標來運行程序。如果你能夠以這種方式運行convert.py程序,你可能會發現另一個可用性問題。 程序在新窗口中開始運行,但程序一完成,窗口就會消失,因此你無法讀取結果。在程序結束時添加一個輸入語句,讓它暫停,給用戶一個讀取結果的機會。下面這樣的代碼應該有效:

input("Press the key to quit.")

3.修改程序(第2.5.3節),找出三個考試成績的平均值。

4.使用循環修改程序(第2.2節),讓它在退出前執行5次。每次通過循環,程序應該從用戶獲得另一個溫度,並打印轉換的值。

5.修改程序(第2.2節),讓它計算並打印一個攝氏溫度和華氏度的對應表,從0℃到100℃,每隔10℃一個值。

6.修改程序(第2.7節),讓投資的年數也由用戶輸入。確保更改最後的消息,以反映正確的年數。

7.假設你有一個投資計劃,每年投資一定的固定金額。修改,計算你的投資的總累積值。該程序的輸入將是每年投資的金額、利率和投資的年數。

8.作為APR的替代方案,賬戶所產生的利息通常通過名義利率和復利期數來描述。例如,如果利率為3%,利息按季度計算復利,則該賬戶實際上每3個月賺取0.75%的利息。請修改程序,用此方法輸入利率。程序應提示用戶每年的利率(rate)和利息每年復利的次數(periods)。要計算10年的價值,程序將循環10 * periods次,並在每次迭代中累積rate/period的利息。

9.編寫一個程序,將溫度從華氏溫度轉換為攝氏溫度。

10.編寫一個程序,將以千米為單位的距離轉換為英裡。1千米約為0.62英裡。

11.編寫一個程序以執行你自己選擇的單位轉換。確保程序打印介紹,解釋它的作用。

12.編寫一個交互式Python計算器程序。程序應該允許用戶鍵入數學表達式,然後打印表達式的值。加入循環,以便用戶可以執行許多計算(例如,最多100個)。注意:要提前退出,用戶可以通過鍵入一個錯誤的表達式,或簡單地關閉計算器程序運行的窗口,讓程序崩潰。在後續圖書節中,你將學習終止交互式程序的更好方法。

本文摘自《Python程序設計(第3版)》。

文章評論

    共有條評論來說兩句吧...

    用戶名:

    驗證碼:

Interserver Webhosting and VPS
Dynadot
TurnKey Internet
COM for just $5.98 at Namecheap