大家好,小編來為大家解答以下問題,如何用python做軟件開發(fā),用python開發(fā)軟件的步驟,今天讓我們一起來看看吧!
?
參與文末每日話題討論,贈送異步新書
異步圖書君
學習目標
知道有序的軟件開發(fā)過程的步驟。
了解遵循輸入、處理、輸出(IPO)模式的程序,并能夠以簡單的方式修改它們神碼ai偽原創(chuàng)。
了解構(gòu)成有效Python標識符和表達式的規(guī)則。
能夠理解和編寫Python語句,將信息輸出到屏幕,為變量賦值,獲取通過鍵盤輸入的信息,并執(zhí)行計數(shù)循環(huán)。
軟件開發(fā)過程
運行已經(jīng)編寫的程序很容易。較難的部分實際上是先得到一個程序。計算機是非常實在的,必須告訴它們要做什么,直至最后的細節(jié)。編寫大型程序是一項艱巨的挑戰(zhàn)。如果沒有系統(tǒng)的方法,幾乎是不可能的。
創(chuàng)建程序的過程通常被分成幾個階段,依據(jù)是每個階段中產(chǎn)生的信息。簡而言之,你應該做以下工作。
分析問題確定要解決的問題是什么。嘗試盡可能多地了解它。除非真的知道問題是什么,否則就不能開始解決它。
確定規(guī)格說明準確描述程序?qū)⒆鍪裁?。此時,你不必擔心程序"怎么做”,而是要確定它"做什么”。對于簡單程序,這包括仔細描述程序的輸入和輸出是什么以及它們的相互關系。
創(chuàng)建設計規(guī)劃程序的總體結(jié)構(gòu)。這是描述程序怎么做的地方。主要任務是設計算法來滿足規(guī)格說明。
實現(xiàn)設計將設計翻譯成計算機語言并放入計算機。在本書中,我們將算法實現(xiàn)為Python程序。
測試/調(diào)試程序試用你的程序,看看它是否按預期工作。如果有任何錯誤(通常稱為"缺陷”),那么你應該回去修復它們。定位和修復錯誤的過程稱為"調(diào)試”程序。在調(diào)試階段,你的目標是找到錯誤,所以應該嘗試你能想到的"打破”程序的一切可能。記住這句老格言:"沒有什么能防住人犯傻,因為傻子太聰明了?!?/p>
維護程序繼續(xù)根據(jù)用戶的需求開發(fā)該程序。大多數(shù)程序從來沒有真正完成,它們在多年的使用中不斷演進。
示例程序:溫度轉(zhuǎn)換器
讓我們通過一個真實世界的簡單例子,來體驗軟件開發(fā)過程的步驟,其中涉及一個虛構(gòu)的計算機科學學生Susan Computewell。
Susan正在德國學習一年。她對語言沒有任何問題,因為她能流利地使用許多語言(包括Python)。她的問題是,很難在早上弄清楚溫度從而知道當天該穿什么衣服。Susan每天早上聽天氣報告,但溫度以攝氏度給出,她習慣了華氏度。
幸運的是,Susan有辦法解決這個問題。作為計算機科學專業(yè)的學生,她去任何地方總是帶著她的筆記本計算機。她認為計算機程序可能會幫助她。
Susan開始分析她的問題。在這個例子中,問題很清楚:無線電廣播員用攝氏度報氣溫,但Susan只能理解華氏溫度。
接下來,Susan考慮可能幫助她的程序的規(guī)格說明。輸入應該是什么?她決定程序?qū)⒃试S她輸入攝氏溫度。輸出呢?程序?qū)@示轉(zhuǎn)換后的華氏溫度?,F(xiàn)在她需要指定輸出與輸入的確切關系。
蘇珊快速估算了一下。她知道0攝氏度(冰點)等于32華氏度,100攝氏度(沸點)等于212華氏度。有了這個信息,她計算出華氏度與攝氏度的比率為(212?32)/(100?0) = (180/100) = 9/5。使用F表示華氏溫度,C表示攝氏溫度,轉(zhuǎn)換公式的形式為F= (9/5)C+k,其中k為某個常數(shù)。代入0和32分別作為C和F,Susan立即得到k= 32。所以最后的關系公式是F= (9/5)C+ 32。這作為規(guī)格說明似乎足夠了。
請注意,這描述了能夠解決這個問題的許多可能程序中的一個。如果Susan有人工智能(AI)領域的背景,她可能會考慮寫一個程序,用語音識別算法實際收聽收音機播音員,獲得當前的溫度。對于輸出,她可以讓計算機控制機器人進入她的衣柜,并根據(jù)轉(zhuǎn)換后的溫度選擇適當?shù)姆b。這將是一個更有野心的項目,一點也不夸張!
當然,機器人程序也會解決問題分析中識別的問題。規(guī)格說明的目的,是準確地決定這個特定的程序要做什么,從而解決一個問題。Susan知道,最好是先弄清楚她希望構(gòu)建什么,而不是一頭鉆進去開始編程。
Susan現(xiàn)在準備為她的問題設計一個算法。她馬上意識到這是一個簡單算法,遵循標準模式"輸入、處理、輸出”(IPO)。她的程序?qū)⑻崾居脩糨斎胍恍┬畔ⅲ〝z氏溫度),處理它,產(chǎn)生華氏溫度,然后在計算機屏幕上顯示結(jié)果,作為輸出。
Susan可以用一種計算機語言來寫她的算法。然而,正式將它寫出來需要相當?shù)木龋@常常會扼殺開發(fā)算法的創(chuàng)造性過程。作為替代,她用"偽代碼”編寫算法。偽代碼只是精確的英語,描述了程序做的事。這意味著既可以交流算法,又不必讓大腦承擔額外的開銷,正確寫出某種特定編程語言的細節(jié)。
下面是Susan的完整算法:
輸入攝氏度溫度(稱為celsius)
計算華氏度為(9/5)celsius + 32
輸出華氏度
下一步是將此設計轉(zhuǎn)換為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()
看看你是否能弄清楚這個程序的每一行做了什么。如果一些部分不是很清楚,也不要擔心,下一節(jié)將詳細討論。
完成程序后,Susan測試它,看看它工作得如何。她使用她知道正確答案的輸入。下面是兩個測試的輸出:
Whatisthe Celsius temperature?
The temperatureis32.0degrees Fahrenheit.
Whatisthe Celsius temperature?100
The temperatureis212.0degrees Fahrenheit.
你可以看到,Susan用值0和100來測試她的程序??雌饋聿诲e,她對解決方案感到滿意。她特別高興的是,似乎沒有必要調(diào)試(這很不尋常)。
程序要素
既然已經(jīng)知道了編程過程,你就"幾乎”準備好開始自己編寫程序了。在此之前,你需要更完整的基礎,了解Python的基本知識。接下來的幾節(jié)將討論一些技術細節(jié),這對編寫正確程序至關重要。這種材料看起來有點乏味,但你必須掌握這些基礎,然后再進入更有趣的領域。
1 名稱
你已經(jīng)看到,名稱是編程的重要組成部分。我們?yōu)槟K命名(例如convert),也為模塊中的函數(shù)命名(例如main)。變量用于為值命名(例如celsius和fahrenheit)。從技術上講,所有這些名稱都稱為"標識符”。Python對標識符的構(gòu)成有一些規(guī)則。每個標識符必須以字母或下劃線("_”字符)開頭,后跟字母、數(shù)字或下劃線的任意序列。這意味著單個標識符不能包含任何空格。
根據(jù)上述規(guī)則,以下都是Python中的合法名稱:
x
celsius
spam
spam2
SpamAndEggs
Spam_and_Eggs
標識符區(qū)分大小寫,因此對Python來說,spam、Spam、sPam和SPAM是不同的名稱。在大多數(shù)情況下,程序員可以自由選擇符合這些規(guī)則的任何名稱。好的程序員總是試圖選擇一些名字,它們能描述被命名的東西。
需要注意一件重要的事情:一些標識符是Python本身的一部分。這些名稱稱為"保留字”或"關鍵字”,不能用作普通標識符。Python關鍵字的完整列表如表1所列。
表1 Python關鍵字
False
class
finally
is
return
Python還包括相當多的內(nèi)置函數(shù),例如我們用過的print函數(shù)。雖然在技術上可以將內(nèi)置的函數(shù)名稱標識符用于其他目的,但這通常是一個"非常糟糕”的主意。例如,如果你重新定義print的含義,那么就無法再打印信息。你也會讓所有閱讀程序的Python程序員感到非常困惑,他們預期print指的是內(nèi)置函數(shù)。內(nèi)置函數(shù)的完整列表可在附錄A中找到。
2 表達式
程序操作數(shù)據(jù)。到目前為止,我們已經(jīng)在示例程序中看到了數(shù)字和文本兩種不同類型的數(shù)據(jù)。我們將在后面的節(jié)中詳細討論這些不同的數(shù)據(jù)類型?,F(xiàn)在,你只需要記住,所有的數(shù)據(jù)必須以一些數(shù)字格式存儲在計算機上,不同類型的數(shù)據(jù)以不同的方式存儲。
產(chǎn)生或計算新數(shù)據(jù)值的程序代碼片段稱為"表達式”。最簡單的表達式是字面量。字面量用于表示特定值。在chaos.py中,你可以找到數(shù)字3.9和1。convert.py程序包含9、5和32。這些都是數(shù)字字面量的例子,它們的含義顯而易見:32就是代表32(數(shù)字32)。
我們的程序還以一些簡單的方式處理文本數(shù)據(jù)。計算機科學家將文本數(shù)據(jù)稱為"字符串”。你可以將字符串視為可打印字符的序列。Python中通過將字符括在引號("")中來表示字符串字面量。如果你回頭看看我們的示例程序,可以發(fā)現(xiàn)一些字符串字面量,例如"Hello"和"Enter a number between 0 and 1:"。這些字面量產(chǎn)生的字符串包含引號內(nèi)的字符。請注意,引號本身不是字符串的一部分。它們只是告訴Python創(chuàng)建一個字符串的機制。
將表達式轉(zhuǎn)換為基礎數(shù)據(jù)類型的過程稱為"求值”。在Python shell中鍵入表達式時,shell會計算表達式并打印出結(jié)果的文本表示。請考慮以下簡短的交互:
>>>32
32
>>>"Hello"
'Hello'
>>>"32"
'32'
請注意,當shell顯示字符串的值時,它將字符序列放在單引號中。這樣讓我們知道該值實際上是文本而不是數(shù)字(或其他數(shù)據(jù)類型)。在最后一次交互中,我們看到表達式"32"產(chǎn)生一個字符串,而不是一個數(shù)字。在這種情況下,Python實際上是存儲字符"3”和"2”,而不是數(shù)字32的表示。如果你現(xiàn)在不太明白,不要太擔心。我們在后面的節(jié)中討論這些數(shù)據(jù)類型時,你的理解就會變得更加清晰。
一個簡單的標識符也可以是一個表達式。我們使用標識符作為變量來給名字賦值。當標識符作為表達式出現(xiàn)時,它的值會被取出,作為表達式的結(jié)果。下面是與Python解釋器的交互,展示了變量作為表達式:
>>> x =5
>>> x
5
>>> print(x)
5
>>> print(spam)
Traceback (most recent call last):
File"", line1,in
NameError:name'spam'isnotdefined
首先,變量x被賦值為5(使用數(shù)字字面量5)。在第二行交互中,我們要求Python對表達式x求值。作為響應,Python shell打印出5,這是剛才賦給x的值。當然,如果我們明確要求Python用print語句打印x,也會得到相同的結(jié)果。最后一個交互展示了如果嘗試使用未賦值的變量,會發(fā)生什么。Python找不到值,所以它報告NameError。這說明沒有該名稱的值。這里的要點是,變量總是必須賦一個值,然后才能在表達式中使用。
較復雜、較有趣的表達式可以通過組合較簡單的表達式和操作符來構(gòu)造。對于數(shù)字,Python提供了一組標準的數(shù)學運算:加法、減法、乘法、除法和乘方。相應的Python運算符為"+”"-”"*”"/”和"**”。下面是一些來自chaos.py和convert.py的復雜表達式的例子:
3.9* x *(1 - x)
9/5 * celsius + 32
空格在表達式中沒有作用。最后一個表達式如果寫成9/5*celsius+32,結(jié)果完全相同。通常,在表達式中加一些空格讓它更容易閱讀,是個好方法。
Python的數(shù)學運算符遵循的優(yōu)先級和結(jié)合律,與你在數(shù)學課上學到的相同,包括使用括號來改變求值的順序。在自己的程序中構(gòu)建復雜表達式應該沒什么困難。請記住,只有圓括號在數(shù)字表達式中是允許的。如果需要,可以嵌套使用它們,創(chuàng)建如下的表達式:
((x1 - x2) / 2*n) + (spam / k**3)
順便說一句,Python還提供了字符串的運算符。例如,可以"加”字符串。
>>>"Bat"+"man"
'Batman'
這被稱為"連接”。如你所見,效果是創(chuàng)建一個新的字符串,把兩個字符串"粘”在一起。
3 輸出語句
既然有了基本的構(gòu)建塊(標識符和表達式),你就可以更完整地描述各種Python語句。 你已經(jīng)知道信息可以使用Python的內(nèi)置函數(shù)print在屏幕上顯示。到目前為止,我們已經(jīng)看了幾個例子,但我還沒有詳細解釋打印功能。像所有的編程語言一樣,Python對每個語句的語法(形式)和語義(意義)有一套精確的規(guī)則。計算機科學家已經(jīng)開發(fā)了復雜的符號表示法,稱為"元語言”,用于描述編程語言。在本書中,我們將依靠一個簡單的模板符號表示法來說明各種語句的語法。
因為print是一個內(nèi)置函數(shù),所以print語句與任何其他函數(shù)調(diào)用具有相同的一般形式。我們鍵入函數(shù)名print,后面帶上括號中列出的參數(shù)。下面是用我們的模板符號時print語句看起來的樣子:
print(,, ...,)
print()
這兩個模板展示了兩種形式的print語句。第一個表示print語句可以包含函數(shù)名print,后面帶上帶括號的表達式序列,用逗號分隔。模板中的尖括號符號()用于表示由Python代碼的其他片段填充的"槽”。括號內(nèi)的名稱表示缺少什么,expr表示一個表達式。省略號("...”)表示不確定的序列(在這個例子中是表達式)。你實際上不會輸入圓點。第二個版本的print語句表明,不打印任何表達式的print也是合法的。
就語義而言,print語句以文本形式顯示信息。所有提供的表達式都從左到右求值,結(jié)果值以從左到右的方式顯示在輸出行上。默認情況下,在顯示的值之間放置一個空格字符。作為示例,下面print語句的序列:
print(3+4)
print(3, 4, 3 + 4)
print()
print("The answer is", 3 + 4)
產(chǎn)生的輸出為:
7
347
The answeris7
最后一個語句說明了,字符串字面量表達式如何經(jīng)常在print語句使用,作為標記輸出的方便方法。
注意,連續(xù)的print語句通常顯示在屏幕的不同行上??誴rint(無參數(shù))生成空行輸出。在背后,真正發(fā)生的是,在打印所有提供的表達式之后,print函數(shù)自動附加某種結(jié)束文本。默認情況下,結(jié)束文本是表示行結(jié)束的特殊標記字符(表示為" ”)。我們可以通過包含一個附加參數(shù)顯式地覆蓋這個默認值,從而改變這種行為。這里使用命名參數(shù)的特殊語法,或稱為"關鍵字”參數(shù)。
包含指定結(jié)束文本的關鍵字參數(shù)的print語句的模板如下:
print(,, ...,, end=" ")
命名參數(shù)的關鍵字是end,它使用"=”符號賦值,類似于變量賦值。注意,在模板中我已經(jīng)顯示其默認值,即行末字符。這是一種標準方式,用于顯示在未明確指定某個其他值時,關鍵字參數(shù)具有的值。
print語句中的end參數(shù)有一個常見用法,即允許多個print構(gòu)建單行輸出。例如:
print("The answer is", end=" ")
print(3 + 4)
產(chǎn)生單行輸出:
The answeris7
注意,第一個print語句的輸出如何以空格(" ")而不是行末字符結(jié)束,第二個語句的輸出緊跟在空格之后。
4 賦值語句
Python中最重要的語句之一是賦值語句。我們在前面的例子中已經(jīng)看到了一些。
簡單賦值
基本賦值語句具有以下形式:
=
這里variable是一個標識符,expr是一個表達式。賦值的語義是,右側(cè)的表達式被求值,然后產(chǎn)生的值與左側(cè)命名的變量相關聯(lián)。
下面是我們已經(jīng)看到的一些賦值:
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。記住,變量的值可以改變,這就是為什么它們被稱為變量的原因。
有時,將變量看作計算機內(nèi)存中的一種命名的存儲位置是有幫助的,我們可以在其中放入一個值。當變量更改時,舊值將被刪除,并寫入一個新值。圖1展示了用這個模型來描繪x=x+ 1的效果。這正是賦值在某些計算機語言中工作的方式。這也是查看賦值效果的一種非常簡單的方式,你會在整本書中看到類似這樣的圖片。
圖1x=x+ 1的視圖,變量就像盒子
Python賦值語句實際上與"變量盒子”模型略有不同。在Python中,值可能最終放在內(nèi)存中的任何位置,而變量用于引用它們。對變量賦值就像把一個黃色小粘貼便簽放在值上,并說"這是x”。圖2給出了一個更準確的Python賦值的效果。箭頭用于顯示變量引用的值。請注意,舊值不會被新值擦除,變量只需切換到引用新值。效果就像將粘貼便簽從一個對象移動到另一個對象一樣。這是賦值在Python中實際工作的方式,所以你會看到這樣一些粘貼便簽樣式的圖片散布在本書中。
圖2
x=x+ 1的(Python)視圖,變量就像便簽
順便說一句,即使賦值語句不直接導致變量的舊值被擦除和覆蓋,你也不必擔心計算機內(nèi)存中充滿"被丟棄”的值。如果一個值不再被任何變量引用,它就不再有用。Python將自動從內(nèi)存中清除這些值,以便空間可以用于存放新值。這就像檢查你的衣柜,拋出沒有粘貼便簽標記的東西。實際上,這個自動內(nèi)存管理的過程確實被稱為"垃圾收集”。
賦值輸入
輸入語句的目的是從程序的用戶那里獲取一些信息,并存儲到變量中。一些編程語言有一個特殊的語句來做到這一點。在Python中,輸入是用一個賦值語句結(jié)合一個內(nèi)置函數(shù)input實現(xiàn)的。輸入語句的確切形式,取決于你希望從用戶那里獲取的數(shù)據(jù)類型。對于文本輸入,語句如下所示:
= input(
)
這里的
是一個字符串表達式,用于提示用戶輸入。提示幾乎總是一個字符串字面量(即引號內(nèi)的一些文本)。
當Python遇到對input的調(diào)用時,它在屏幕上打印提示。然后,Python暫停并等待用戶鍵入一些文本,鍵入完成后按鍵。用戶輸入的任何東西都會存儲為字符串。請考慮以下簡單的交互:
>>> name = input("Enter your name: ")
Enter yourname:John Yaya
>>> name
'John Yaya'
執(zhí)行input語句導致Python打印輸出提示"Enter your name:”,然后解釋器暫停,等待用戶輸入。在這個例子中,我鍵入John Yaya。結(jié)果,字符串"John Yaya”被記在變量name中。對name求值將返回我鍵入的字符串。
如果用戶輸入是一個數(shù)字,我們需要形式稍復雜一點的input語句:
=eval(input(
))
這里我添加了另一個內(nèi)置的Python函數(shù)eval,它"包裹”了input函數(shù)。你可能會猜到,eval是"evaluate(求值)”的縮寫。在這種形式中,用戶鍵入的文本被求值為一個表達式,以產(chǎn)生存儲到變量中的值。舉例來說,字符串"32”就變成數(shù)字32。如果回頭看看示例程序,到目前為止,你會看到幾個例子,我們像這樣從用戶那里得到了數(shù)字。
x= eval(input("Please enter a number between 0 and 1: "))
celsius= eval(input("What is the Celsius temperature? "))
重要的是要記住,如果希望得到一個數(shù)字,而不是一些原始文本(字符串),需要對input進行eval。
如果你仔細閱讀示例程序,可能會注意到所有這些提示結(jié)尾處的引號內(nèi)的空格。我通常在提示的末尾放置一個空格,以便用戶輸入的內(nèi)容不會緊接著提示開始。放上空格可以讓交互更容易閱讀和理解。
雖然我們的數(shù)字示例特別提示用戶輸入數(shù)字,但在這個例子中,用戶鍵入的只是一個數(shù)字字面量,即一個簡單的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組合就像一個延遲的表達式。示例交互產(chǎn)生完全相同的結(jié)果,就像我們簡單地寫成ans = 3 + 4 * 5一樣。不同的是,表達式由用戶在語句執(zhí)行時提供,而不是由程序員在編程時輸入。
注意:eval函數(shù)功能非常強大,也有"潛在的危險”。如本例所示,當我們對用戶輸入求值時,本質(zhì)上是允許用戶輸入一部分程序。Python將盡職盡責地對他們輸入的任何內(nèi)容求值。了解Python的人可以利用這種能力輸入惡意指令。例如,用戶可以鍵入記錄計算機上的私人信息或刪除文件的表達式。在計算機安全中,這被稱為"代碼注入”攻擊,因為攻擊者將惡意代碼注入正在運行的程序中。
作為一名新程序員,編程給自己個人使用,計算機安全不是很大的問題。如果你坐在一臺運行Python程序的計算機前面,你可能擁有對系統(tǒng)的完全訪問權(quán)限,并且可以找到更簡單的方法來刪除所有文件。然而,如果一個程序的輸入來自不受信任的來源,例如來自互聯(lián)網(wǎng)上的用戶,使用eval可能是災難性的。
同時賦值
有一個賦值語句的替代形式,允許我們同時計算幾個值。它看起來像這樣:
,, ...,=,, ...,
這稱為"同時賦值”。語義上,這告訴Python對右側(cè)所有表達式求值,然后將這些值賦給左側(cè)命名的相應變量。下面是一個例子:
sum, diff = x+y, x-y
這里,sum得到x和y的和,diff得到x和y的差。
這種形式的賦值初看很奇怪,但實際上非常有用。這里有一個例子:假設有兩個變量x和y,你希望交換它們的值。也就是說,你希望將當前存儲在x中的值存儲在y中,將當前存儲在y中的值存儲在x中。首先,你可能認為這可以通過兩個簡單的賦值來完成:
x= y
y= x
這不行。我們可以一步一步地跟蹤這些語句的執(zhí)行,看看為什么。
假設x和y開始的值是2和4。讓我們檢查程序的邏輯,看看變量是如何變化的。以下序列用注釋描述了在執(zhí)行這兩個語句時變量會發(fā)生什么:
# 變量 x y
# 初始值 2 4
x= y
# 現(xiàn)在是 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中,同時賦值語句提供了一種優(yōu)雅的選擇。下面是更簡單的Python等價寫法:
x, y = y, x
因為賦值是同時的,所以它避免了擦除一個原始值。
同時賦值也可以用單個input從用戶那里獲取多個數(shù)字。請考慮下面的程序,它求出考試平均分:
# 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()
該程序提示用逗號分隔兩個分數(shù)。假設用戶鍵入86,92。input語句的效果就像進行以下賦值:
score1, score2 = 86, 92
我們已經(jīng)為每個變量獲得了一個值。這個例子只用了兩個值,但可以擴展到任意數(shù)量的輸入。
當然,我們也可以通過單獨的input語句獲得用戶的輸入:
score1= eval(input("Enter the first score: "))
score2= eval(input("Enter the second score: "))
某種程度上,這可能更好,因為單獨的提示對用戶來說信息更準確。在這個例子中,決定采用哪種方法在很大程度上是品位問題。有時在單個input中獲取多個值提供了更直觀的用戶接口,因此在你的工具包中,這是一項好技術。但要記住,多個值的技巧不適用于字符串(非求值)輸入,如果用戶鍵入逗號,它只是輸入字符串中的一個字符。逗號僅在隨后對字符串求值時,才成為分隔符。
確定循環(huán)
你已經(jīng)知道,程序員用循環(huán)連續(xù)多次執(zhí)行一系列語句。最簡單的循環(huán)稱為"確定循環(huán)”。這是會執(zhí)行一定次數(shù)的循環(huán)。也就是說,在程序中循環(huán)開始時,Python就知道循環(huán)(或"迭代”)的次數(shù)。例如,前面介紹的chaos程序用了一個總是執(zhí)行10次的循環(huán):
foriinrange(10):
x = 3.9 * x * (1 - x)
print(x)
這個特定的循環(huán)模式稱為"計數(shù)循環(huán)”,它用Python的for語句構(gòu)建。在詳細分析這個例子之前,讓我們來看看什么是for循環(huán)。
Python的for循環(huán)具有以下一般形式:
forin:
循環(huán)體可以是任意Python語句序列。循環(huán)體的范圍通過它在循環(huán)頭(for in :部分)下面的縮進來表示。
關鍵字for后面的變量稱為"循環(huán)索引”。它依次取sequence中的每個值,并針對每個值都執(zhí)行一次循環(huán)體中的語句。通常,sequence部分由值"列表”構(gòu)成。列表是Python中一個非常重要的概念,你將在后續(xù)節(jié)中了解更多?,F(xiàn)在只要知道,可以在方括號中放置一系列表達式,從而創(chuàng)建一個簡單的列表。下列交互示例有助于說明這一點:
你能看到這兩個例子做了什么嗎?依次使用列表中的每個值執(zhí)行了循環(huán)體。列表的長度決定了循環(huán)執(zhí)行的次數(shù)。在第一個例子中,列表包含4個值,即0至3,并且簡單地打印了這些連續(xù)的i值。在第二個例子中,odd取前5個奇數(shù)的值,循環(huán)體打印了這些數(shù)字的平方。
現(xiàn)在,讓我們回到這一節(jié)開始的例子(來自chaos.py)再看一下循環(huán)頭:
foriinrange(10):
將它與for循環(huán)的模板進行比較可以看出,最后一個部分range(10)必定是某種序列。事實上,range是一個內(nèi)置的Python函數(shù),用于"當場”生成一個數(shù)字序列。你可以認為range是一種數(shù)字序列的隱性描述。要明白range實際上做了什么,我們可以要求Python用另一個內(nèi)置函數(shù)list,將range轉(zhuǎn)換為一個簡單的舊式列表:
>>> list(range(10))# turns range(10) into an explicit list
[,1,2,3,4,5,6,7,8,9]
你看到這里發(fā)生了什么嗎?表達式range(10)產(chǎn)生數(shù)字0到9的序列。使用range(10)的循環(huán)等價于使用那些數(shù)字的列表的循環(huán)。
foriin[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
一般來說,range()將產(chǎn)生一個數(shù)字序列,從0開始,但不包括的值。如果你想一想,就會發(fā)現(xiàn)表達式的值確定了結(jié)果序列中的項數(shù)。在chaos.py中,我們甚至不關心循環(huán)索引變量使用了什么值(因為i沒有在循環(huán)體中的任何位置引用)。我們只需要一個長度為10的序列,讓循環(huán)體執(zhí)行10次。
正如前面提到的,這種模式稱為"計數(shù)循環(huán)”,它是使用確定循環(huán)的一種很常見的方式。如果你希望在程序中做一定次數(shù)的某些事,請用一個帶有合適range的for循環(huán)。下面一個反復出現(xiàn)的Python編程習語,你需要記住:
forinrange():
表達式的值確定了循環(huán)執(zhí)行的次數(shù)。索引變量的名稱實際上并不重要,程序員經(jīng)常使用i或j作為計數(shù)循環(huán)的循環(huán)索引變量。只要確保使用的標識符沒有用于任何其他目的,否則你可能會不小心清除稍后需要的值。
循環(huán)的有趣和有用之處在于,它們改變程序"控制流”的方式。通常我們認為計算機是嚴格按順序執(zhí)行一系列指令。引入循環(huán)會導致Python退回去并重復執(zhí)行一些語句。類似for循環(huán)的語句稱為"控制結(jié)構(gòu)”,因為它們控制程序其他部分的執(zhí)行。
一些程序員發(fā)現(xiàn),用圖片的方式來思考控制結(jié)構(gòu)是有幫助的,即所謂的"流程圖”。流程圖用一些框來表示程序的不同部分,并用框之間的箭頭表示程序運行時的事件序列。圖3用流程圖描述了for循環(huán)的語義。
圖3 for循環(huán)的流程圖
如果你在理解for循環(huán)時遇到困難,可能會發(fā)現(xiàn)學習流程圖很有用。流程圖中的菱形框表示程序中的決定。當Python遇到循環(huán)頭時,它檢查序列中是否有項。如果答案為"是”,則循環(huán)索引變量被賦予序列中的下一項,然后執(zhí)行循環(huán)體。一旦循環(huán)體完成,程序返回到循環(huán)頭并檢查序列中的下一個值。如果沒有更多的項,循環(huán)就退出,程序移動到循環(huán)之后的語句。
示例程序:終值
我們用另一個編程過程的例子來結(jié)束本文。我們希望開發(fā)一個程序來確定投資的終值。我們將從對問題的分析開始。你知道存入銀行賬戶的錢會賺取利息,這個利息隨著時間的推移而累積。從現(xiàn)在起10年后,一個賬戶將有多少錢?顯然,這取決于我們開始有多少錢(本金)以及賬戶賺多少利息。給定本金和利率,程序應該能夠計算未來10年投資的終值。
我們繼續(xù)制定程序的確切規(guī)格說明。記住,這是程序做什么的描述。輸入應該是什么?我們需要用戶輸入初始投資金額,即本金。我們還需要說明賬戶賺多少利息。這取決于利率和計復利的頻率。處理此問題的一種簡單方法是讓用戶輸入年度百分比率。無論實際利率和復利頻率如何,年利率告訴我們一年內(nèi)的投資收益。如果年利率為3%,那么100美元的投資將在一年的時間內(nèi)增長到103美元。用戶應如何表示年利率3%?有一些合理的選擇。讓我們假設用戶提供一個小數(shù),因此利率將輸入為0.03。
這樣就得到以下規(guī)格說明:
程序 終值
輸入
principal 投資于美元的金額。
APR 以十進制數(shù)表示的年度百分比利率。
輸出 投資10年后的終值。
關系 一年后的價值由principal(1 + apr)給出。該公式需要應用10次。
接下來為程序設計一個算法。我們將使用偽代碼,這樣就可以闡明我們的想法而又不必擔心Python的所有規(guī)則。對于我們的規(guī)格說明,算法看起來很簡單。
打印介紹
輸入本金的金額(principal)
輸入年度百分比利率(apr)
重復10次:
principal = principal *(1 + apr)
輸出principal的值
如果你知道一些金融數(shù)學(或者只是一些基本代數(shù))的知識,可能會意識到,在這個設計中并不一定要用循環(huán)。有一個公式可以利用乘冪一步算出終值。我在這里用了一個循環(huán)來展示另一個計數(shù)循環(huán),另一個原因是這個版本適合進行一些修改,在本文末尾的編程練習中將討論。無論如何,這個設計說明有時算法的計算方式可以讓數(shù)學更容易。知道如何計算一年的利息,就讓我們能計算未來任意年數(shù)的利息。
既然我們已經(jīng)在偽代碼中想明白了這個問題,現(xiàn)在該利用我們的Python新知識開發(fā)一個程序了。算法的每一行都轉(zhuǎn)換為一條Python語句:
打印介紹(print語句,第2.4節(jié))
print("This program calculates the future value")
print("of a 10-year investment.")
輸入本金的金額(數(shù)值input,第2.5.2節(jié))
principal =eval(input("Enter the initial principal: "))
輸入年度百分比利率(數(shù)值input,第2.5.2節(jié))
apr =eval(input("Enter the annual interest rate: "))
重復10次:(計數(shù)循環(huán),第2.6節(jié))
foriinrange(10):
計算principal = principal * (1 + apr)(簡單賦值,第2.5.1節(jié))
principal = principal * (1 + apr)
輸出principal的值(print語句,第2.4節(jié))
print("The value in 10 years is:", principal)
該程序中的所有語句類型都已在本文中詳細討論過。如果有任何問題,請回頭查看相關說明。特別要注意的是,計數(shù)循環(huán)模式用于應用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()
注意,我添加了幾個空行來分隔程序的輸入、處理和輸出部分。策略性地放置"空行”能讓程序更具有可讀性。
這就是我所舉的例子,測試和調(diào)試是留給你的練習。
小結(jié)
本文介紹了開發(fā)程序的過程,以及實現(xiàn)簡單程序所需的許多Python細節(jié)。下面是一些要點的快速小結(jié)。
編寫程序需要一種系統(tǒng)的方法來解決問題,包括以下步驟。
1.問題分析:研究需要解決的問題。
2.程序規(guī)格說明:確定程序要做什么。
3.設計:用偽代碼編寫算法。
4.實現(xiàn):將設計翻譯成編程語言。
5.測試/調(diào)試:查找和修復程序中的錯誤。
6.維護:讓程序保持最新,滿足不斷變化的需求。
許多簡單的程序遵循輸入、處理、輸出(IPO)的模式。
程序由標識符和表達式構(gòu)成的語句組成。
標識符是一些名稱,它們以下劃線或字母開頭,后跟字母、數(shù)字或下劃線字符的組合。Python中的標識符區(qū)分大小寫。
表達式是產(chǎn)生數(shù)據(jù)的程序片段。表達式可以由以下部件組成:
字面量字面量是特定值的表示。例如,3是數(shù)字3的字面量表示。
變量變量是存儲值的標識符。
運算符運算符用于將表達式組合為更復雜的表達式。例如,在x+ 3 *y中,使用了運算符+和*。
數(shù)字的Python運算符包括加法(+)、減法(-)、乘法(*)、除法(/)和乘冪(**)等常見的算術運算。
Python輸出語句print將一系列表達式的值顯示在屏幕上。
在Python中,使用等號(=)表示將值賦給變量。利用賦值,程序可以從鍵盤獲得輸入。Python還允許同時賦值,這對于利用單個提示獲取多個輸入值很有作用。
eval函數(shù)可用來對用戶輸入求值,但它是一種安全風險,不應該用于未知或不可信來源的輸入。
確定循環(huán)是執(zhí)行次數(shù)已知的循環(huán)。Python的for語句是一個循環(huán)遍歷一系列值的確定循環(huán)。Python列表通常在for循環(huán)中用于為循環(huán)提供一系列值。
for語句的一個重要用途是實現(xiàn)計數(shù)循環(huán),這是專門設計的循環(huán),以便將程序的某些部分重復特定的次數(shù)。Python中的計數(shù)循環(huán)通過使用內(nèi)置的range函數(shù),來產(chǎn)生適當大小的數(shù)字序列。
判斷對錯
1.編寫程序的最好方法是立即鍵入一些代碼,然后調(diào)試它,直到它工作。
2.可以在不使用編程語言的情況下編寫算法。
3.程序在寫入和調(diào)試后不再需要修改。
4.Python標識符必須以字母或下劃線開頭。
5.關鍵詞是好的變量名。
6.表達式由文字、變量和運算符構(gòu)成。
7.在Python中,x=x+ 1是一個合法的語句。
8.Python不允許使用單個語句輸入多個值。
9.計數(shù)循環(huán)被設計為迭代特定次數(shù)。
10.在流程圖中,菱形用于展示語句序列,矩形用于判斷點。
多項選擇
1.以下項不是軟件開發(fā)過程中的一個步驟。
a.規(guī)格說明 b.測試/調(diào)試 c.決定費用 d.維護
2.將攝氏度轉(zhuǎn)換為華氏度的正確公式是。
a.F= 9/5(C) + 32 b.F= 5/9(C) ? 32
c.F=B2? 4ACd.F= (212 – 32)/(100 – 0)
3.準確描述計算機程序?qū)⒆鍪裁磥斫鉀Q問題的過程稱為。
a.設計 b.實現(xiàn) c.編程 d.規(guī)格說明
4.以下項不是合法的標識符。
a. b. c. d.
5.下列不在表達式中使用。
a.變量 b.語句 c.操作符 d.字面量
6.生成或計算新數(shù)據(jù)值的代碼片段被稱為。
a.標識符 b.表達式 c.生成子句 d.賦值語句
7.以下項不是IPO模式的一部分。
a.輸入 b.程序 c.處理 d.輸出
8.模板描述了。
a.一般循環(huán) b.賦值語句
c.流程圖 d.計數(shù)循環(huán)
9.以下項是最準確的Python賦值模型。
a.粘貼便簽 b.變量盒子 c.同時 d.塑料尺
10.在Python中,獲取用戶輸入通過一個特殊的表達式來實現(xiàn),稱為。
a. b. c.同時賦值 d.
討論
1.列出并用你自己的語言描述軟件開發(fā)過程中的六個步驟。
2.寫出chaos.py程序(第1.6節(jié)),并識別程序的各部分如下:
圈出每個標識符。
為每個表達式加下劃線。
在每一行的末尾添加注釋,指示該行上的語句類型(輸出、賦值、輸入、循環(huán)等)。
3.解釋確定循環(huán)、for循環(huán)和計數(shù)循環(huán)幾個概念之間的關系。
4.顯示以下片段的輸出:
a.
b.
c.
d.
5.先寫出一個算法的偽代碼而不是立即投入Python代碼,為什么是一個好主意?
6.除end之外,Python的函數(shù)還支持其他關鍵字參數(shù)。其中一個關鍵字參數(shù)是。你認為參數(shù)是什么?(提示:是分隔符的縮寫。通過交互式執(zhí)行或通過查閱Python文檔來檢驗你的想法)。
7.如果執(zhí)行下面的代碼,你認為會發(fā)生什么?
print("start")
foriinrange(0):
print("Hello")
print("end")
看看本文的for語句的流程圖,幫助你弄明白。然后在程序中嘗試這些代碼,檢驗你的預測。
編程練習
1.一個用戶友好的程序應該打印一個介紹,告訴用戶程序做什么。修改convert.py程序(第2.2節(jié)),打印介紹。
2.在許多使用Python的系統(tǒng)上,可以通過簡單地點擊(或雙擊)程序文件的圖標來運行程序。如果你能夠以這種方式運行convert.py程序,你可能會發(fā)現(xiàn)另一個可用性問題。 程序在新窗口中開始運行,但程序一完成,窗口就會消失,因此你無法讀取結(jié)果。在程序結(jié)束時添加一個輸入語句,讓它暫停,給用戶一個讀取結(jié)果的機會。下面這樣的代碼應該有效:
input("Press the key to quit.")
3.修改程序(第2.5.3節(jié)),找出三個考試成績的平均值。
4.使用循環(huán)修改程序(第2.2節(jié)),讓它在退出前執(zhí)行5次。每次通過循環(huán),程序應該從用戶獲得另一個溫度,并打印轉(zhuǎn)換的值。
5.修改程序(第2.2節(jié)),讓它計算并打印一個攝氏溫度和華氏度的對應表,從0℃到100℃,每隔10℃一個值。
6.修改程序(第2.7節(jié)),讓投資的年數(shù)也由用戶輸入。確保更改最后的消息,以反映正確的年數(shù)。
7.假設你有一個投資計劃,每年投資一定的固定金額。修改,計算你的投資的總累積值。該程序的輸入將是每年投資的金額、利率和投資的年數(shù)。
8.作為APR的替代方案,賬戶所產(chǎn)生的利息通常通過名義利率和復利期數(shù)來描述。例如,如果利率為3%,利息按季度計算復利,則該賬戶實際上每3個月賺取0.75%的利息。請修改程序,用此方法輸入利率。程序應提示用戶每年的利率(rate)和利息每年復利的次數(shù)(periods)。要計算10年的價值,程序?qū)⒀h(huán)10 * periods次,并在每次迭代中累積rate/period的利息。
9.編寫一個程序,將溫度從華氏溫度轉(zhuǎn)換為攝氏溫度。
10.編寫一個程序,將以千米為單位的距離轉(zhuǎn)換為英里。1千米約為0.62英里。
11.編寫一個程序以執(zhí)行你自己選擇的單位轉(zhuǎn)換。確保程序打印介紹,解釋它的作用。文章來源:http://www.zghlxwxcb.cn/news/detail-739064.html
12.編寫一個交互式Python計算器程序。程序應該允許用戶鍵入數(shù)學表達式,然后打印表達式的值。加入循環(huán),以便用戶可以執(zhí)行許多計算(例如,最多100個)。注意:要提前退出,用戶可以通過鍵入一個錯誤的表達式,或簡單地關閉計算器程序運行的窗口,讓程序崩潰。在后續(xù)圖書節(jié)中,你將學習終止交互式程序的更好方法。文章來源地址http://www.zghlxwxcb.cn/news/detail-739064.html
參與文末每日話題討論,贈送異步新書
異步圖書君
學習目標
知道有序的軟件開發(fā)過程的步驟。
了解遵循輸入、處理、輸出(IPO)模式的程序,并能夠以簡單的方式修改它們神碼ai偽原創(chuàng)。
了解構(gòu)成有效Python標識符和表達式的規(guī)則。
能夠理解和編寫Python語句,將信息輸出到屏幕,為變量賦值,獲取通過鍵盤輸入的信息,并執(zhí)行計數(shù)循環(huán)。
軟件開發(fā)過程
運行已經(jīng)編寫的程序很容易。較難的部分實際上是先得到一個程序。計算機是非常實在的,必須告訴它們要做什么,直至最后的細節(jié)。編寫大型程序是一項艱巨的挑戰(zhàn)。如果沒有系統(tǒng)的方法,幾乎是不可能的。
創(chuàng)建程序的過程通常被分成幾個階段,依據(jù)是每個階段中產(chǎn)生的信息。簡而言之,你應該做以下工作。
分析問題確定要解決的問題是什么。嘗試盡可能多地了解它。除非真的知道問題是什么,否則就不能開始解決它。
確定規(guī)格說明準確描述程序?qū)⒆鍪裁?。此時,你不必擔心程序"怎么做”,而是要確定它"做什么”。對于簡單程序,這包括仔細描述程序的輸入和輸出是什么以及它們的相互關系。
創(chuàng)建設計規(guī)劃程序的總體結(jié)構(gòu)。這是描述程序怎么做的地方。主要任務是設計算法來滿足規(guī)格說明。
實現(xiàn)設計將設計翻譯成計算機語言并放入計算機。在本書中,我們將算法實現(xiàn)為Python程序。
測試/調(diào)試程序試用你的程序,看看它是否按預期工作。如果有任何錯誤(通常稱為"缺陷”),那么你應該回去修復它們。定位和修復錯誤的過程稱為"調(diào)試”程序。在調(diào)試階段,你的目標是找到錯誤,所以應該嘗試你能想到的"打破”程序的一切可能。記住這句老格言:"沒有什么能防住人犯傻,因為傻子太聰明了?!?/p>
維護程序繼續(xù)根據(jù)用戶的需求開發(fā)該程序。大多數(shù)程序從來沒有真正完成,它們在多年的使用中不斷演進。
示例程序:溫度轉(zhuǎn)換器
讓我們通過一個真實世界的簡單例子,來體驗軟件開發(fā)過程的步驟,其中涉及一個虛構(gòu)的計算機科學學生Susan Computewell。
Susan正在德國學習一年。她對語言沒有任何問題,因為她能流利地使用許多語言(包括Python)。她的問題是,很難在早上弄清楚溫度從而知道當天該穿什么衣服。Susan每天早上聽天氣報告,但溫度以攝氏度給出,她習慣了華氏度。
幸運的是,Susan有辦法解決這個問題。作為計算機科學專業(yè)的學生,她去任何地方總是帶著她的筆記本計算機。她認為計算機程序可能會幫助她。
Susan開始分析她的問題。在這個例子中,問題很清楚:無線電廣播員用攝氏度報氣溫,但Susan只能理解華氏溫度。
接下來,Susan考慮可能幫助她的程序的規(guī)格說明。輸入應該是什么?她決定程序?qū)⒃试S她輸入攝氏溫度。輸出呢?程序?qū)@示轉(zhuǎn)換后的華氏溫度?,F(xiàn)在她需要指定輸出與輸入的確切關系。
蘇珊快速估算了一下。她知道0攝氏度(冰點)等于32華氏度,100攝氏度(沸點)等于212華氏度。有了這個信息,她計算出華氏度與攝氏度的比率為(212?32)/(100?0) = (180/100) = 9/5。使用F表示華氏溫度,C表示攝氏溫度,轉(zhuǎn)換公式的形式為F= (9/5)C+k,其中k為某個常數(shù)。代入0和32分別作為C和F,Susan立即得到k= 32。所以最后的關系公式是F= (9/5)C+ 32。這作為規(guī)格說明似乎足夠了。
請注意,這描述了能夠解決這個問題的許多可能程序中的一個。如果Susan有人工智能(AI)領域的背景,她可能會考慮寫一個程序,用語音識別算法實際收聽收音機播音員,獲得當前的溫度。對于輸出,她可以讓計算機控制機器人進入她的衣柜,并根據(jù)轉(zhuǎn)換后的溫度選擇適當?shù)姆b。這將是一個更有野心的項目,一點也不夸張!
當然,機器人程序也會解決問題分析中識別的問題。規(guī)格說明的目的,是準確地決定這個特定的程序要做什么,從而解決一個問題。Susan知道,最好是先弄清楚她希望構(gòu)建什么,而不是一頭鉆進去開始編程。
Susan現(xiàn)在準備為她的問題設計一個算法。她馬上意識到這是一個簡單算法,遵循標準模式"輸入、處理、輸出”(IPO)。她的程序?qū)⑻崾居脩糨斎胍恍┬畔ⅲ〝z氏溫度),處理它,產(chǎn)生華氏溫度,然后在計算機屏幕上顯示結(jié)果,作為輸出。
Susan可以用一種計算機語言來寫她的算法。然而,正式將它寫出來需要相當?shù)木龋@常常會扼殺開發(fā)算法的創(chuàng)造性過程。作為替代,她用"偽代碼”編寫算法。偽代碼只是精確的英語,描述了程序做的事。這意味著既可以交流算法,又不必讓大腦承擔額外的開銷,正確寫出某種特定編程語言的細節(jié)。
下面是Susan的完整算法:
輸入攝氏度溫度(稱為celsius)
計算華氏度為(9/5)celsius + 32
輸出華氏度
下一步是將此設計轉(zhuǎn)換為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()
看看你是否能弄清楚這個程序的每一行做了什么。如果一些部分不是很清楚,也不要擔心,下一節(jié)將詳細討論。
完成程序后,Susan測試它,看看它工作得如何。她使用她知道正確答案的輸入。下面是兩個測試的輸出:
Whatisthe Celsius temperature?
The temperatureis32.0degrees Fahrenheit.
Whatisthe Celsius temperature?100
The temperatureis212.0degrees Fahrenheit.
你可以看到,Susan用值0和100來測試她的程序??雌饋聿诲e,她對解決方案感到滿意。她特別高興的是,似乎沒有必要調(diào)試(這很不尋常)。
程序要素
既然已經(jīng)知道了編程過程,你就"幾乎”準備好開始自己編寫程序了。在此之前,你需要更完整的基礎,了解Python的基本知識。接下來的幾節(jié)將討論一些技術細節(jié),這對編寫正確程序至關重要。這種材料看起來有點乏味,但你必須掌握這些基礎,然后再進入更有趣的領域。
1 名稱
你已經(jīng)看到,名稱是編程的重要組成部分。我們?yōu)槟K命名(例如convert),也為模塊中的函數(shù)命名(例如main)。變量用于為值命名(例如celsius和fahrenheit)。從技術上講,所有這些名稱都稱為"標識符”。Python對標識符的構(gòu)成有一些規(guī)則。每個標識符必須以字母或下劃線("_”字符)開頭,后跟字母、數(shù)字或下劃線的任意序列。這意味著單個標識符不能包含任何空格。
根據(jù)上述規(guī)則,以下都是Python中的合法名稱:
x
celsius
spam
spam2
SpamAndEggs
Spam_and_Eggs
標識符區(qū)分大小寫,因此對Python來說,spam、Spam、sPam和SPAM是不同的名稱。在大多數(shù)情況下,程序員可以自由選擇符合這些規(guī)則的任何名稱。好的程序員總是試圖選擇一些名字,它們能描述被命名的東西。
需要注意一件重要的事情:一些標識符是Python本身的一部分。這些名稱稱為"保留字”或"關鍵字”,不能用作普通標識符。Python關鍵字的完整列表如表1所列。
表1 Python關鍵字
False
class
finally
is
return
Python還包括相當多的內(nèi)置函數(shù),例如我們用過的print函數(shù)。雖然在技術上可以將內(nèi)置的函數(shù)名稱標識符用于其他目的,但這通常是一個"非常糟糕”的主意。例如,如果你重新定義print的含義,那么就無法再打印信息。你也會讓所有閱讀程序的Python程序員感到非常困惑,他們預期print指的是內(nèi)置函數(shù)。內(nèi)置函數(shù)的完整列表可在附錄A中找到。
2 表達式
程序操作數(shù)據(jù)。到目前為止,我們已經(jīng)在示例程序中看到了數(shù)字和文本兩種不同類型的數(shù)據(jù)。我們將在后面的節(jié)中詳細討論這些不同的數(shù)據(jù)類型。現(xiàn)在,你只需要記住,所有的數(shù)據(jù)必須以一些數(shù)字格式存儲在計算機上,不同類型的數(shù)據(jù)以不同的方式存儲。
產(chǎn)生或計算新數(shù)據(jù)值的程序代碼片段稱為"表達式”。最簡單的表達式是字面量。字面量用于表示特定值。在chaos.py中,你可以找到數(shù)字3.9和1。convert.py程序包含9、5和32。這些都是數(shù)字字面量的例子,它們的含義顯而易見:32就是代表32(數(shù)字32)。
我們的程序還以一些簡單的方式處理文本數(shù)據(jù)。計算機科學家將文本數(shù)據(jù)稱為"字符串”。你可以將字符串視為可打印字符的序列。Python中通過將字符括在引號("")中來表示字符串字面量。如果你回頭看看我們的示例程序,可以發(fā)現(xiàn)一些字符串字面量,例如"Hello"和"Enter a number between 0 and 1:"。這些字面量產(chǎn)生的字符串包含引號內(nèi)的字符。請注意,引號本身不是字符串的一部分。它們只是告訴Python創(chuàng)建一個字符串的機制。
將表達式轉(zhuǎn)換為基礎數(shù)據(jù)類型的過程稱為"求值”。在Python shell中鍵入表達式時,shell會計算表達式并打印出結(jié)果的文本表示。請考慮以下簡短的交互:
>>>32
32
>>>"Hello"
'Hello'
>>>"32"
'32'
請注意,當shell顯示字符串的值時,它將字符序列放在單引號中。這樣讓我們知道該值實際上是文本而不是數(shù)字(或其他數(shù)據(jù)類型)。在最后一次交互中,我們看到表達式"32"產(chǎn)生一個字符串,而不是一個數(shù)字。在這種情況下,Python實際上是存儲字符"3”和"2”,而不是數(shù)字32的表示。如果你現(xiàn)在不太明白,不要太擔心。我們在后面的節(jié)中討論這些數(shù)據(jù)類型時,你的理解就會變得更加清晰。
一個簡單的標識符也可以是一個表達式。我們使用標識符作為變量來給名字賦值。當標識符作為表達式出現(xiàn)時,它的值會被取出,作為表達式的結(jié)果。下面是與Python解釋器的交互,展示了變量作為表達式:
>>> x =5
>>> x
5
>>> print(x)
5
>>> print(spam)
Traceback (most recent call last):
File"", line1,in
NameError:name'spam'isnotdefined
首先,變量x被賦值為5(使用數(shù)字字面量5)。在第二行交互中,我們要求Python對表達式x求值。作為響應,Python shell打印出5,這是剛才賦給x的值。當然,如果我們明確要求Python用print語句打印x,也會得到相同的結(jié)果。最后一個交互展示了如果嘗試使用未賦值的變量,會發(fā)生什么。Python找不到值,所以它報告NameError。這說明沒有該名稱的值。這里的要點是,變量總是必須賦一個值,然后才能在表達式中使用。
較復雜、較有趣的表達式可以通過組合較簡單的表達式和操作符來構(gòu)造。對于數(shù)字,Python提供了一組標準的數(shù)學運算:加法、減法、乘法、除法和乘方。相應的Python運算符為"+”"-”"*”"/”和"**”。下面是一些來自chaos.py和convert.py的復雜表達式的例子:
3.9* x *(1 - x)
9/5 * celsius + 32
空格在表達式中沒有作用。最后一個表達式如果寫成9/5*celsius+32,結(jié)果完全相同。通常,在表達式中加一些空格讓它更容易閱讀,是個好方法。
Python的數(shù)學運算符遵循的優(yōu)先級和結(jié)合律,與你在數(shù)學課上學到的相同,包括使用括號來改變求值的順序。在自己的程序中構(gòu)建復雜表達式應該沒什么困難。請記住,只有圓括號在數(shù)字表達式中是允許的。如果需要,可以嵌套使用它們,創(chuàng)建如下的表達式:
((x1 - x2) / 2*n) + (spam / k**3)
順便說一句,Python還提供了字符串的運算符。例如,可以"加”字符串。
>>>"Bat"+"man"
'Batman'
這被稱為"連接”。如你所見,效果是創(chuàng)建一個新的字符串,把兩個字符串"粘”在一起。
3 輸出語句
既然有了基本的構(gòu)建塊(標識符和表達式),你就可以更完整地描述各種Python語句。 你已經(jīng)知道信息可以使用Python的內(nèi)置函數(shù)print在屏幕上顯示。到目前為止,我們已經(jīng)看了幾個例子,但我還沒有詳細解釋打印功能。像所有的編程語言一樣,Python對每個語句的語法(形式)和語義(意義)有一套精確的規(guī)則。計算機科學家已經(jīng)開發(fā)了復雜的符號表示法,稱為"元語言”,用于描述編程語言。在本書中,我們將依靠一個簡單的模板符號表示法來說明各種語句的語法。
因為print是一個內(nèi)置函數(shù),所以print語句與任何其他函數(shù)調(diào)用具有相同的一般形式。我們鍵入函數(shù)名print,后面帶上括號中列出的參數(shù)。下面是用我們的模板符號時print語句看起來的樣子:
print(,, ...,)
print()
這兩個模板展示了兩種形式的print語句。第一個表示print語句可以包含函數(shù)名print,后面帶上帶括號的表達式序列,用逗號分隔。模板中的尖括號符號()用于表示由Python代碼的其他片段填充的"槽”。括號內(nèi)的名稱表示缺少什么,expr表示一個表達式。省略號("...”)表示不確定的序列(在這個例子中是表達式)。你實際上不會輸入圓點。第二個版本的print語句表明,不打印任何表達式的print也是合法的。
就語義而言,print語句以文本形式顯示信息。所有提供的表達式都從左到右求值,結(jié)果值以從左到右的方式顯示在輸出行上。默認情況下,在顯示的值之間放置一個空格字符。作為示例,下面print語句的序列:
print(3+4)
print(3, 4, 3 + 4)
print()
print("The answer is", 3 + 4)
產(chǎn)生的輸出為:
7
347
The answeris7
最后一個語句說明了,字符串字面量表達式如何經(jīng)常在print語句使用,作為標記輸出的方便方法。
注意,連續(xù)的print語句通常顯示在屏幕的不同行上。空print(無參數(shù))生成空行輸出。在背后,真正發(fā)生的是,在打印所有提供的表達式之后,print函數(shù)自動附加某種結(jié)束文本。默認情況下,結(jié)束文本是表示行結(jié)束的特殊標記字符(表示為" ”)。我們可以通過包含一個附加參數(shù)顯式地覆蓋這個默認值,從而改變這種行為。這里使用命名參數(shù)的特殊語法,或稱為"關鍵字”參數(shù)。
包含指定結(jié)束文本的關鍵字參數(shù)的print語句的模板如下:
print(,, ...,, end=" ")
命名參數(shù)的關鍵字是end,它使用"=”符號賦值,類似于變量賦值。注意,在模板中我已經(jīng)顯示其默認值,即行末字符。這是一種標準方式,用于顯示在未明確指定某個其他值時,關鍵字參數(shù)具有的值。
print語句中的end參數(shù)有一個常見用法,即允許多個print構(gòu)建單行輸出。例如:
print("The answer is", end=" ")
print(3 + 4)
產(chǎn)生單行輸出:
The answeris7
注意,第一個print語句的輸出如何以空格(" ")而不是行末字符結(jié)束,第二個語句的輸出緊跟在空格之后。
4 賦值語句
Python中最重要的語句之一是賦值語句。我們在前面的例子中已經(jīng)看到了一些。
簡單賦值
基本賦值語句具有以下形式:
=
這里variable是一個標識符,expr是一個表達式。賦值的語義是,右側(cè)的表達式被求值,然后產(chǎn)生的值與左側(cè)命名的變量相關聯(lián)。
下面是我們已經(jīng)看到的一些賦值:
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。記住,變量的值可以改變,這就是為什么它們被稱為變量的原因。
有時,將變量看作計算機內(nèi)存中的一種命名的存儲位置是有幫助的,我們可以在其中放入一個值。當變量更改時,舊值將被刪除,并寫入一個新值。圖1展示了用這個模型來描繪x=x+ 1的效果。這正是賦值在某些計算機語言中工作的方式。這也是查看賦值效果的一種非常簡單的方式,你會在整本書中看到類似這樣的圖片。
圖1x=x+ 1的視圖,變量就像盒子
Python賦值語句實際上與"變量盒子”模型略有不同。在Python中,值可能最終放在內(nèi)存中的任何位置,而變量用于引用它們。對變量賦值就像把一個黃色小粘貼便簽放在值上,并說"這是x”。圖2給出了一個更準確的Python賦值的效果。箭頭用于顯示變量引用的值。請注意,舊值不會被新值擦除,變量只需切換到引用新值。效果就像將粘貼便簽從一個對象移動到另一個對象一樣。這是賦值在Python中實際工作的方式,所以你會看到這樣一些粘貼便簽樣式的圖片散布在本書中。
圖2
x=x+ 1的(Python)視圖,變量就像便簽
順便說一句,即使賦值語句不直接導致變量的舊值被擦除和覆蓋,你也不必擔心計算機內(nèi)存中充滿"被丟棄”的值。如果一個值不再被任何變量引用,它就不再有用。Python將自動從內(nèi)存中清除這些值,以便空間可以用于存放新值。這就像檢查你的衣柜,拋出沒有粘貼便簽標記的東西。實際上,這個自動內(nèi)存管理的過程確實被稱為"垃圾收集”。
賦值輸入
輸入語句的目的是從程序的用戶那里獲取一些信息,并存儲到變量中。一些編程語言有一個特殊的語句來做到這一點。在Python中,輸入是用一個賦值語句結(jié)合一個內(nèi)置函數(shù)input實現(xiàn)的。輸入語句的確切形式,取決于你希望從用戶那里獲取的數(shù)據(jù)類型。對于文本輸入,語句如下所示:
= input(
)
這里的
是一個字符串表達式,用于提示用戶輸入。提示幾乎總是一個字符串字面量(即引號內(nèi)的一些文本)。
當Python遇到對input的調(diào)用時,它在屏幕上打印提示。然后,Python暫停并等待用戶鍵入一些文本,鍵入完成后按鍵。用戶輸入的任何東西都會存儲為字符串。請考慮以下簡單的交互:
>>> name = input("Enter your name: ")
Enter yourname:John Yaya
>>> name
'John Yaya'
執(zhí)行input語句導致Python打印輸出提示"Enter your name:”,然后解釋器暫停,等待用戶輸入。在這個例子中,我鍵入John Yaya。結(jié)果,字符串"John Yaya”被記在變量name中。對name求值將返回我鍵入的字符串。
如果用戶輸入是一個數(shù)字,我們需要形式稍復雜一點的input語句:
=eval(input(
))
這里我添加了另一個內(nèi)置的Python函數(shù)eval,它"包裹”了input函數(shù)。你可能會猜到,eval是"evaluate(求值)”的縮寫。在這種形式中,用戶鍵入的文本被求值為一個表達式,以產(chǎn)生存儲到變量中的值。舉例來說,字符串"32”就變成數(shù)字32。如果回頭看看示例程序,到目前為止,你會看到幾個例子,我們像這樣從用戶那里得到了數(shù)字。
x= eval(input("Please enter a number between 0 and 1: "))
celsius= eval(input("What is the Celsius temperature? "))
重要的是要記住,如果希望得到一個數(shù)字,而不是一些原始文本(字符串),需要對input進行eval。
如果你仔細閱讀示例程序,可能會注意到所有這些提示結(jié)尾處的引號內(nèi)的空格。我通常在提示的末尾放置一個空格,以便用戶輸入的內(nèi)容不會緊接著提示開始。放上空格可以讓交互更容易閱讀和理解。
雖然我們的數(shù)字示例特別提示用戶輸入數(shù)字,但在這個例子中,用戶鍵入的只是一個數(shù)字字面量,即一個簡單的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組合就像一個延遲的表達式。示例交互產(chǎn)生完全相同的結(jié)果,就像我們簡單地寫成ans = 3 + 4 * 5一樣。不同的是,表達式由用戶在語句執(zhí)行時提供,而不是由程序員在編程時輸入。
注意:eval函數(shù)功能非常強大,也有"潛在的危險”。如本例所示,當我們對用戶輸入求值時,本質(zhì)上是允許用戶輸入一部分程序。Python將盡職盡責地對他們輸入的任何內(nèi)容求值。了解Python的人可以利用這種能力輸入惡意指令。例如,用戶可以鍵入記錄計算機上的私人信息或刪除文件的表達式。在計算機安全中,這被稱為"代碼注入”攻擊,因為攻擊者將惡意代碼注入正在運行的程序中。
作為一名新程序員,編程給自己個人使用,計算機安全不是很大的問題。如果你坐在一臺運行Python程序的計算機前面,你可能擁有對系統(tǒng)的完全訪問權(quán)限,并且可以找到更簡單的方法來刪除所有文件。然而,如果一個程序的輸入來自不受信任的來源,例如來自互聯(lián)網(wǎng)上的用戶,使用eval可能是災難性的。
同時賦值
有一個賦值語句的替代形式,允許我們同時計算幾個值。它看起來像這樣:
,, ...,=,, ...,
這稱為"同時賦值”。語義上,這告訴Python對右側(cè)所有表達式求值,然后將這些值賦給左側(cè)命名的相應變量。下面是一個例子:
sum, diff = x+y, x-y
這里,sum得到x和y的和,diff得到x和y的差。
這種形式的賦值初看很奇怪,但實際上非常有用。這里有一個例子:假設有兩個變量x和y,你希望交換它們的值。也就是說,你希望將當前存儲在x中的值存儲在y中,將當前存儲在y中的值存儲在x中。首先,你可能認為這可以通過兩個簡單的賦值來完成:
x= y
y= x
這不行。我們可以一步一步地跟蹤這些語句的執(zhí)行,看看為什么。
假設x和y開始的值是2和4。讓我們檢查程序的邏輯,看看變量是如何變化的。以下序列用注釋描述了在執(zhí)行這兩個語句時變量會發(fā)生什么:
# 變量 x y
# 初始值 2 4
x= y
# 現(xiàn)在是 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中,同時賦值語句提供了一種優(yōu)雅的選擇。下面是更簡單的Python等價寫法:
x, y = y, x
因為賦值是同時的,所以它避免了擦除一個原始值。
同時賦值也可以用單個input從用戶那里獲取多個數(shù)字。請考慮下面的程序,它求出考試平均分:
# 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()
該程序提示用逗號分隔兩個分數(shù)。假設用戶鍵入86,92。input語句的效果就像進行以下賦值:
score1, score2 = 86, 92
我們已經(jīng)為每個變量獲得了一個值。這個例子只用了兩個值,但可以擴展到任意數(shù)量的輸入。
當然,我們也可以通過單獨的input語句獲得用戶的輸入:
score1= eval(input("Enter the first score: "))
score2= eval(input("Enter the second score: "))
某種程度上,這可能更好,因為單獨的提示對用戶來說信息更準確。在這個例子中,決定采用哪種方法在很大程度上是品位問題。有時在單個input中獲取多個值提供了更直觀的用戶接口,因此在你的工具包中,這是一項好技術。但要記住,多個值的技巧不適用于字符串(非求值)輸入,如果用戶鍵入逗號,它只是輸入字符串中的一個字符。逗號僅在隨后對字符串求值時,才成為分隔符。
確定循環(huán)
你已經(jīng)知道,程序員用循環(huán)連續(xù)多次執(zhí)行一系列語句。最簡單的循環(huán)稱為"確定循環(huán)”。這是會執(zhí)行一定次數(shù)的循環(huán)。也就是說,在程序中循環(huán)開始時,Python就知道循環(huán)(或"迭代”)的次數(shù)。例如,前面介紹的chaos程序用了一個總是執(zhí)行10次的循環(huán):
foriinrange(10):
x = 3.9 * x * (1 - x)
print(x)
這個特定的循環(huán)模式稱為"計數(shù)循環(huán)”,它用Python的for語句構(gòu)建。在詳細分析這個例子之前,讓我們來看看什么是for循環(huán)。
Python的for循環(huán)具有以下一般形式:
forin:
循環(huán)體可以是任意Python語句序列。循環(huán)體的范圍通過它在循環(huán)頭(for in :部分)下面的縮進來表示。
關鍵字for后面的變量稱為"循環(huán)索引”。它依次取sequence中的每個值,并針對每個值都執(zhí)行一次循環(huán)體中的語句。通常,sequence部分由值"列表”構(gòu)成。列表是Python中一個非常重要的概念,你將在后續(xù)節(jié)中了解更多?,F(xiàn)在只要知道,可以在方括號中放置一系列表達式,從而創(chuàng)建一個簡單的列表。下列交互示例有助于說明這一點:
你能看到這兩個例子做了什么嗎?依次使用列表中的每個值執(zhí)行了循環(huán)體。列表的長度決定了循環(huán)執(zhí)行的次數(shù)。在第一個例子中,列表包含4個值,即0至3,并且簡單地打印了這些連續(xù)的i值。在第二個例子中,odd取前5個奇數(shù)的值,循環(huán)體打印了這些數(shù)字的平方。
現(xiàn)在,讓我們回到這一節(jié)開始的例子(來自chaos.py)再看一下循環(huán)頭:
foriinrange(10):
將它與for循環(huán)的模板進行比較可以看出,最后一個部分range(10)必定是某種序列。事實上,range是一個內(nèi)置的Python函數(shù),用于"當場”生成一個數(shù)字序列。你可以認為range是一種數(shù)字序列的隱性描述。要明白range實際上做了什么,我們可以要求Python用另一個內(nèi)置函數(shù)list,將range轉(zhuǎn)換為一個簡單的舊式列表:
>>> list(range(10))# turns range(10) into an explicit list
[,1,2,3,4,5,6,7,8,9]
你看到這里發(fā)生了什么嗎?表達式range(10)產(chǎn)生數(shù)字0到9的序列。使用range(10)的循環(huán)等價于使用那些數(shù)字的列表的循環(huán)。
foriin[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
一般來說,range()將產(chǎn)生一個數(shù)字序列,從0開始,但不包括的值。如果你想一想,就會發(fā)現(xiàn)表達式的值確定了結(jié)果序列中的項數(shù)。在chaos.py中,我們甚至不關心循環(huán)索引變量使用了什么值(因為i沒有在循環(huán)體中的任何位置引用)。我們只需要一個長度為10的序列,讓循環(huán)體執(zhí)行10次。
正如前面提到的,這種模式稱為"計數(shù)循環(huán)”,它是使用確定循環(huán)的一種很常見的方式。如果你希望在程序中做一定次數(shù)的某些事,請用一個帶有合適range的for循環(huán)。下面一個反復出現(xiàn)的Python編程習語,你需要記?。?/p>
forinrange():
表達式的值確定了循環(huán)執(zhí)行的次數(shù)。索引變量的名稱實際上并不重要,程序員經(jīng)常使用i或j作為計數(shù)循環(huán)的循環(huán)索引變量。只要確保使用的標識符沒有用于任何其他目的,否則你可能會不小心清除稍后需要的值。
循環(huán)的有趣和有用之處在于,它們改變程序"控制流”的方式。通常我們認為計算機是嚴格按順序執(zhí)行一系列指令。引入循環(huán)會導致Python退回去并重復執(zhí)行一些語句。類似for循環(huán)的語句稱為"控制結(jié)構(gòu)”,因為它們控制程序其他部分的執(zhí)行。
一些程序員發(fā)現(xiàn),用圖片的方式來思考控制結(jié)構(gòu)是有幫助的,即所謂的"流程圖”。流程圖用一些框來表示程序的不同部分,并用框之間的箭頭表示程序運行時的事件序列。圖3用流程圖描述了for循環(huán)的語義。
圖3 for循環(huán)的流程圖
如果你在理解for循環(huán)時遇到困難,可能會發(fā)現(xiàn)學習流程圖很有用。流程圖中的菱形框表示程序中的決定。當Python遇到循環(huán)頭時,它檢查序列中是否有項。如果答案為"是”,則循環(huán)索引變量被賦予序列中的下一項,然后執(zhí)行循環(huán)體。一旦循環(huán)體完成,程序返回到循環(huán)頭并檢查序列中的下一個值。如果沒有更多的項,循環(huán)就退出,程序移動到循環(huán)之后的語句。
示例程序:終值
我們用另一個編程過程的例子來結(jié)束本文。我們希望開發(fā)一個程序來確定投資的終值。我們將從對問題的分析開始。你知道存入銀行賬戶的錢會賺取利息,這個利息隨著時間的推移而累積。從現(xiàn)在起10年后,一個賬戶將有多少錢?顯然,這取決于我們開始有多少錢(本金)以及賬戶賺多少利息。給定本金和利率,程序應該能夠計算未來10年投資的終值。
我們繼續(xù)制定程序的確切規(guī)格說明。記住,這是程序做什么的描述。輸入應該是什么?我們需要用戶輸入初始投資金額,即本金。我們還需要說明賬戶賺多少利息。這取決于利率和計復利的頻率。處理此問題的一種簡單方法是讓用戶輸入年度百分比率。無論實際利率和復利頻率如何,年利率告訴我們一年內(nèi)的投資收益。如果年利率為3%,那么100美元的投資將在一年的時間內(nèi)增長到103美元。用戶應如何表示年利率3%?有一些合理的選擇。讓我們假設用戶提供一個小數(shù),因此利率將輸入為0.03。
這樣就得到以下規(guī)格說明:
程序 終值
輸入
principal 投資于美元的金額。
APR 以十進制數(shù)表示的年度百分比利率。
輸出 投資10年后的終值。
關系 一年后的價值由principal(1 + apr)給出。該公式需要應用10次。
接下來為程序設計一個算法。我們將使用偽代碼,這樣就可以闡明我們的想法而又不必擔心Python的所有規(guī)則。對于我們的規(guī)格說明,算法看起來很簡單。
打印介紹
輸入本金的金額(principal)
輸入年度百分比利率(apr)
重復10次:
principal = principal *(1 + apr)
輸出principal的值
如果你知道一些金融數(shù)學(或者只是一些基本代數(shù))的知識,可能會意識到,在這個設計中并不一定要用循環(huán)。有一個公式可以利用乘冪一步算出終值。我在這里用了一個循環(huán)來展示另一個計數(shù)循環(huán),另一個原因是這個版本適合進行一些修改,在本文末尾的編程練習中將討論。無論如何,這個設計說明有時算法的計算方式可以讓數(shù)學更容易。知道如何計算一年的利息,就讓我們能計算未來任意年數(shù)的利息。
既然我們已經(jīng)在偽代碼中想明白了這個問題,現(xiàn)在該利用我們的Python新知識開發(fā)一個程序了。算法的每一行都轉(zhuǎn)換為一條Python語句:
打印介紹(print語句,第2.4節(jié))
print("This program calculates the future value")
print("of a 10-year investment.")
輸入本金的金額(數(shù)值input,第2.5.2節(jié))
principal =eval(input("Enter the initial principal: "))
輸入年度百分比利率(數(shù)值input,第2.5.2節(jié))
apr =eval(input("Enter the annual interest rate: "))
重復10次:(計數(shù)循環(huán),第2.6節(jié))
foriinrange(10):
計算principal = principal * (1 + apr)(簡單賦值,第2.5.1節(jié))
principal = principal * (1 + apr)
輸出principal的值(print語句,第2.4節(jié))
print("The value in 10 years is:", principal)
該程序中的所有語句類型都已在本文中詳細討論過。如果有任何問題,請回頭查看相關說明。特別要注意的是,計數(shù)循環(huán)模式用于應用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()
注意,我添加了幾個空行來分隔程序的輸入、處理和輸出部分。策略性地放置"空行”能讓程序更具有可讀性。
這就是我所舉的例子,測試和調(diào)試是留給你的練習。
小結(jié)
本文介紹了開發(fā)程序的過程,以及實現(xiàn)簡單程序所需的許多Python細節(jié)。下面是一些要點的快速小結(jié)。
編寫程序需要一種系統(tǒng)的方法來解決問題,包括以下步驟。
1.問題分析:研究需要解決的問題。
2.程序規(guī)格說明:確定程序要做什么。
3.設計:用偽代碼編寫算法。
4.實現(xiàn):將設計翻譯成編程語言。
5.測試/調(diào)試:查找和修復程序中的錯誤。
6.維護:讓程序保持最新,滿足不斷變化的需求。
許多簡單的程序遵循輸入、處理、輸出(IPO)的模式。
程序由標識符和表達式構(gòu)成的語句組成。
標識符是一些名稱,它們以下劃線或字母開頭,后跟字母、數(shù)字或下劃線字符的組合。Python中的標識符區(qū)分大小寫。
表達式是產(chǎn)生數(shù)據(jù)的程序片段。表達式可以由以下部件組成:
字面量字面量是特定值的表示。例如,3是數(shù)字3的字面量表示。
變量變量是存儲值的標識符。
運算符運算符用于將表達式組合為更復雜的表達式。例如,在x+ 3 *y中,使用了運算符+和*。
數(shù)字的Python運算符包括加法(+)、減法(-)、乘法(*)、除法(/)和乘冪(**)等常見的算術運算。
Python輸出語句print將一系列表達式的值顯示在屏幕上。
在Python中,使用等號(=)表示將值賦給變量。利用賦值,程序可以從鍵盤獲得輸入。Python還允許同時賦值,這對于利用單個提示獲取多個輸入值很有作用。
eval函數(shù)可用來對用戶輸入求值,但它是一種安全風險,不應該用于未知或不可信來源的輸入。
確定循環(huán)是執(zhí)行次數(shù)已知的循環(huán)。Python的for語句是一個循環(huán)遍歷一系列值的確定循環(huán)。Python列表通常在for循環(huán)中用于為循環(huán)提供一系列值。
for語句的一個重要用途是實現(xiàn)計數(shù)循環(huán),這是專門設計的循環(huán),以便將程序的某些部分重復特定的次數(shù)。Python中的計數(shù)循環(huán)通過使用內(nèi)置的range函數(shù),來產(chǎn)生適當大小的數(shù)字序列。
判斷對錯
1.編寫程序的最好方法是立即鍵入一些代碼,然后調(diào)試它,直到它工作。
2.可以在不使用編程語言的情況下編寫算法。
3.程序在寫入和調(diào)試后不再需要修改。
4.Python標識符必須以字母或下劃線開頭。
5.關鍵詞是好的變量名。
6.表達式由文字、變量和運算符構(gòu)成。
7.在Python中,x=x+ 1是一個合法的語句。
8.Python不允許使用單個語句輸入多個值。
9.計數(shù)循環(huán)被設計為迭代特定次數(shù)。
10.在流程圖中,菱形用于展示語句序列,矩形用于判斷點。
多項選擇
1.以下項不是軟件開發(fā)過程中的一個步驟。
a.規(guī)格說明 b.測試/調(diào)試 c.決定費用 d.維護
2.將攝氏度轉(zhuǎn)換為華氏度的正確公式是。
a.F= 9/5(C) + 32 b.F= 5/9(C) ? 32
c.F=B2? 4ACd.F= (212 – 32)/(100 – 0)
3.準確描述計算機程序?qū)⒆鍪裁磥斫鉀Q問題的過程稱為。
a.設計 b.實現(xiàn) c.編程 d.規(guī)格說明
4.以下項不是合法的標識符。
a. b. c. d.
5.下列不在表達式中使用。
a.變量 b.語句 c.操作符 d.字面量
6.生成或計算新數(shù)據(jù)值的代碼片段被稱為。
a.標識符 b.表達式 c.生成子句 d.賦值語句
7.以下項不是IPO模式的一部分。
a.輸入 b.程序 c.處理 d.輸出
8.模板描述了。
a.一般循環(huán) b.賦值語句
c.流程圖 d.計數(shù)循環(huán)
9.以下項是最準確的Python賦值模型。
a.粘貼便簽 b.變量盒子 c.同時 d.塑料尺
10.在Python中,獲取用戶輸入通過一個特殊的表達式來實現(xiàn),稱為。
a. b. c.同時賦值 d.
討論
1.列出并用你自己的語言描述軟件開發(fā)過程中的六個步驟。
2.寫出chaos.py程序(第1.6節(jié)),并識別程序的各部分如下:
圈出每個標識符。
為每個表達式加下劃線。
在每一行的末尾添加注釋,指示該行上的語句類型(輸出、賦值、輸入、循環(huán)等)。
3.解釋確定循環(huán)、for循環(huán)和計數(shù)循環(huán)幾個概念之間的關系。
4.顯示以下片段的輸出:
a.
b.
c.
d.
5.先寫出一個算法的偽代碼而不是立即投入Python代碼,為什么是一個好主意?
6.除end之外,Python的函數(shù)還支持其他關鍵字參數(shù)。其中一個關鍵字參數(shù)是。你認為參數(shù)是什么?(提示:是分隔符的縮寫。通過交互式執(zhí)行或通過查閱Python文檔來檢驗你的想法)。
7.如果執(zhí)行下面的代碼,你認為會發(fā)生什么?
print("start")
foriinrange(0):
print("Hello")
print("end")
看看本文的for語句的流程圖,幫助你弄明白。然后在程序中嘗試這些代碼,檢驗你的預測。
編程練習
1.一個用戶友好的程序應該打印一個介紹,告訴用戶程序做什么。修改convert.py程序(第2.2節(jié)),打印介紹。
2.在許多使用Python的系統(tǒng)上,可以通過簡單地點擊(或雙擊)程序文件的圖標來運行程序。如果你能夠以這種方式運行convert.py程序,你可能會發(fā)現(xiàn)另一個可用性問題。 程序在新窗口中開始運行,但程序一完成,窗口就會消失,因此你無法讀取結(jié)果。在程序結(jié)束時添加一個輸入語句,讓它暫停,給用戶一個讀取結(jié)果的機會。下面這樣的代碼應該有效:
input("Press the key to quit.")
3.修改程序(第2.5.3節(jié)),找出三個考試成績的平均值。
4.使用循環(huán)修改程序(第2.2節(jié)),讓它在退出前執(zhí)行5次。每次通過循環(huán),程序應該從用戶獲得另一個溫度,并打印轉(zhuǎn)換的值。
5.修改程序(第2.2節(jié)),讓它計算并打印一個攝氏溫度和華氏度的對應表,從0℃到100℃,每隔10℃一個值。
6.修改程序(第2.7節(jié)),讓投資的年數(shù)也由用戶輸入。確保更改最后的消息,以反映正確的年數(shù)。
7.假設你有一個投資計劃,每年投資一定的固定金額。修改,計算你的投資的總累積值。該程序的輸入將是每年投資的金額、利率和投資的年數(shù)。
8.作為APR的替代方案,賬戶所產(chǎn)生的利息通常通過名義利率和復利期數(shù)來描述。例如,如果利率為3%,利息按季度計算復利,則該賬戶實際上每3個月賺取0.75%的利息。請修改程序,用此方法輸入利率。程序應提示用戶每年的利率(rate)和利息每年復利的次數(shù)(periods)。要計算10年的價值,程序?qū)⒀h(huán)10 * periods次,并在每次迭代中累積rate/period的利息。
9.編寫一個程序,將溫度從華氏溫度轉(zhuǎn)換為攝氏溫度。
10.編寫一個程序,將以千米為單位的距離轉(zhuǎn)換為英里。1千米約為0.62英里。
11.編寫一個程序以執(zhí)行你自己選擇的單位轉(zhuǎn)換。確保程序打印介紹,解釋它的作用。
12.編寫一個交互式Python計算器程序。程序應該允許用戶鍵入數(shù)學表達式,然后打印表達式的值。加入循環(huán),以便用戶可以執(zhí)行許多計算(例如,最多100個)。注意:要提前退出,用戶可以通過鍵入一個錯誤的表達式,或簡單地關閉計算器程序運行的窗口,讓程序崩潰。在后續(xù)圖書節(jié)中,你將學習終止交互式程序的更好方法。
到了這里,關于用python開發(fā)軟件的步驟,如何用python做軟件開發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!