天天看點

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

點選檢視第一章 點選檢視第二章

第3章

循環和選擇語句

完成本章的學習之後,你将能夠做到以下幾點:

● 寫一個循環來重複一系列固定的動作。

● 寫一個循環周遊字元串中的字元序列。

● 寫一個向下計數的循環和一個向上計數的循環。

● 寫一個入口控制的循環,當一個條件為假時,該循環停止。

● 使用選擇語句在程式中進行選擇。

● 構造适當的條件,為條件控制的循環選擇語句。

● 使用邏輯運算符構造複合布爾表達式。

● 使用選擇語句和break語句退出不受入口控制的循環。

到目前為止,本書中研究的所有程式都是由一條接一條執行的指令短序列組成的。即使我們允許指令序列相當長,這種程式也不會很有用。像人類一樣,計算機必須能夠重複執行一系列動作,并且必須能夠選擇在特定情況下要執行的操作。本章集中讨論控制語句——允許計算機選擇或重複一個動作的語句。

3.1 确定疊代:for循環

我們從重複語句開始研究控制語句,重複語句也稱為循環,它可以重複一個動作。動作的每一次重複都被稱為傳遞或疊代。有兩種類型的循環:重複一個動作預定次數的循環(确定疊代);執行該動作直到程式确定它需要停止的循環(不定疊代)。在本節中,我們将研究Python的for循環,這是最容易實作确定疊代的控制語句。

3.1.1 執行語句給定次數

在《科學怪人》中,當弗蘭肯斯坦博士的怪物蘇醒過來時,他不停地喊道:“它還活着!它還活着!”一台計算機可以輕松地列印這些感歎詞,不僅僅是兩次,而是十幾次或一百次,你不需要寫兩次、十幾次或一百次輸出語句就可以做到這一點。下面是一個for循環,它運作相同的輸出語句四次:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這個循環反複調用一個函數——print函數。第一行的常數4告訴循環調用這個函數的次數。如果我們想列印10或100個感歎句,隻需将4改為10或100。這種for循環的文法格式是

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

循環中的第一行代碼有時稱為循環頭。目前,循環頭中唯一相關的資訊是整數表達式,它表示循環執行的疊代次數。冒号(:)結束循環頭。循環體包括循環頭下面剩餘代碼行中的語句。這些語句在循環的每一遍中按順序執行。注意,循環體中的語句必須縮進并對齊在同一列中。IDLE的shell或script視窗将自動縮進循環頭下的行,但是如果縮進中出現了一個空格,你可能會看到文法錯誤。如果移動到下一行代碼時沒有自動縮進,最好縮進四個空格。

現在讓我們探索Python的幂運算符如何在循環中實作。回想一下,這個運算符計算一個數字的給定的幂。例如,表達式2**3計算值

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

,或2*2*2。下面的代碼使用循環來計算非負指數的幂運算。我們使用三個變量來指定數字、指數和乘積。乘積最初是1。每次通過循環時,乘積乘以該數,并重置為結果。為了追蹤這個過程,乘積的值在每一次循環中都輸出一次。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

正如你所看到的,如果指數為0,循環體将不會執行,并且product的值将保持為1,這是任何數字的零次幂的值。

例子中變量的使用證明了我們的指數循環是一種解決一般問題的算法。這個特定循環的使用者不僅可以将2次幂提升到3次幂,還可以計算任何數字的任何非負幂,隻需用不同的值替換變量number和exponent。

3.1.2 計數控制循環

當Python執行剛才讨論的for循環類型時,它會從0開始計數到循環頭整數表達式的值減去1。每次通過循環時,循環頭的變量都綁定到此計數的目前值。以下代碼段示範了這一點:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在一系列數字中計數的循環也稱為計數控制循環。計算中經常使用每次傳遞的計數值。例如,考慮4的階乘,即1×2×3×4=24。計算此值的代碼段以1的乘積開始,并将此變量重置為每次循環中乘以循環計數加1的結果,如下所示:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,count+1的值用于每次傳遞,以確定使用的數字是1到4,而不是0到3。

為了從明确的下限開始計數,程式員可以在循環頭中提供第二個整數表達式。當向range提供兩個參數時,計數的範圍從第一個參數到第二個參數減1。以下代碼段使用這個變量來簡化循環體中的代碼:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在這個版本中唯一需要注意的是range的第二個參數,它應該指定一個比所需計數上限大1的整數。以下是for循環的這個版本的形式:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

從一系列值中累計一個結果值是計算中常見的操作。下面是一個求和的例子,它累加從下限到上限的一系列數字的總和:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,我們使用變量theSum而不是sum來累加代碼中的數字之和。因為sum是Python中内置函數的名稱,是以在我們的代碼中避免将這樣的名稱用于其他目的是一個好主意。

3.1.3 增量指派

像x=x+1或x=x+2這樣的表達式經常出現在循環中,Python為它們提供了縮寫形式。指派符号可以與算術和級聯運算符相結合,以提供增量指派操作。以下是幾個例子:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

所有這些例子都有這樣的格式:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

相當于

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,和=之間沒有空格。增量指派操作和标準指派操作具有相同的優先順序。

3.1.4 循環錯誤:大小差一錯誤

for循環不僅易于編寫,而且不容易出錯。一旦文法正确,我們隻需要關注一個可能的錯誤:循環無法執行預期的疊代次數。因為這個數字通常是隻差一的,是以這個錯誤被稱為大小差一錯誤。大多數情況下,當程式員錯誤地指定循環的上限時,就會産生大小差一錯誤。程式員可能希望下面的循環從1到4計數,但是它卻從1到3計數:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,這不是文法錯誤,而是邏輯錯誤。與文法錯誤不同,Python解釋器不會檢測到邏輯錯誤,隻有仔細檢查程式輸出的程式員才會檢測到。

3.1.5 周遊資料序列的内容

雖然我們一直使用for循環作為一個簡單的計數控制循環,但是循環本身通路由range函數生成的一系列數字中的每個數字。以下代碼段顯示了這些序列:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在本例中,函數range生成的數字序列被送到Python的list函數,該函數傳回一種特殊類型的序列,稱為清單。字元串也是字元序列。通過運作for循環,可以通路任何序列中包含的值,如下所示:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在循環的每一次傳遞中,變量都綁定到或配置設定到序列中的下一個值,從第一個值開始,到最後一個值結束。下面的代碼段周遊或通路兩個序列中的所有元素,并列印其中包含的值,用空格隔開:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.1.6 指定range函數的步長

到目前為止,我們已經看到的計數控制循環都是通過一系列連續的數字進行計數。然而,在一些程式中,我們可能希望循環跳過一些數字,也許每隔一個或每隔三個通路一次。Python中range函數的一個變體包括第三個參數,它允許你跳過一些數字。第三個參數指定一個步長值,或者range函數内使用的數字之間的間隔,如下例所示:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

現在,假設你必須計算1到10之間偶數的總和。下面是解決這個問題的代碼:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.1.7 向下計數的循環

到目前為止,我們所有的循環都從下限向上計數。偶爾,有的問題需要以從上限向下到下限的相反方向計數。例如,目前10名的單曲被發行時,它們可能會按從最低(第10)到最高(第1)的順序出現。在以下代碼中,循環顯示從10到1的計數,以說明如何做到這一點:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

當步長參數為負數時,range函數生成從第一個參數向下到第二個參數加1的一系列數字。是以,在這種情況下,第一個參數應該表示上限,第二個參數應該表示下限減1。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.2 格式化輸出文本

在開始下一個案例研究之前,我們需要更仔細地檢查輸出文本的格式。許多資料處理應用程式需要具有表格格式的輸出,如電子表格或數字資料表中使用的輸出。在這種格式中,數字和其他資訊在可以左對齊或右對齊的列中對齊。如果一列資料的值從最左邊的字元開始垂直對齊,則該列資料是左對齊的。如果資料列的值從最右邊的字元開始垂直對齊,則資料是列右對齊的。為了保持資料列之間的邊距,左對齊要求在資料右側添加空格,而右對齊要求在資料左側添加空格。如果一列資料的兩邊有相等數量的空格,則該列資料是居中對齊的。

格式化字元串中給定資料的資料字元和附加空格的總數稱為字段寬度。

print函數自動開始列印第一個可用列中的輸出資料。以下示例顯示指數7至10以及10^7至10^10的值,print函數産生的兩列格式如下:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,當指數達到10時,第二列的輸出移位一個空格,看起來不整齊。如果左列是左對齊的,右列是右對齊的,輸出看起來會更整潔。當我們格式化輸出浮點數時,通常希望指定要顯示的精度位數以及字段寬度。當顯示精确到兩位數的金融資料時,這一點尤為重要。

Python包括一個通用格式化機制,允許程式員為不同類型的資料指定字段寬度。以下代碼展示了在字段寬度為6的情況下字元串"four"的左對齊和右對齊:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

第一行代碼右對齊字元串,左邊用兩個空格填充。下一行代碼通過在字元串右側放置兩個空格來實作左對齊。

此操作的最簡單形式如下:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

其中包含格式字元串、格式運算符%和要格式化的單個資料值。格式字元串可以包含字元串資料和其他關于資料格式的資訊。在示例中,為了格式化字元串資料值,我們在格式化字元串中使用了符号%s。當字段寬度為正時,資料是右對齊的;當字段寬度為負時,資料是左對齊的。如果字段寬度小于或等于基準的列印長度(以字元為機關),則不會添加對齊。運算符%使用此資訊建構并傳回格式化字元串。

要格式化整數,則使用字母d而不是s。要格式化一系列資料值,需要建構一個格式字元串,其中包含每個資料的格式代碼,并将資料值放在%運算符後面的元組中。此操作的第二個版本形式如下:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

有了格式操作,我們求10的幂的循環現在可以以精确對齊的列顯示數字。第一列在字段寬度為3時左對齊,第二列在字段寬度為12時右對齊。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

float類型資料值的格式資訊具有以下形式:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

其中,.是可選的。以下代碼顯示一個浮點數字的輸出,分别為沒有格式字元串和有格式字元串:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

下面是使用格式字元串的另一個小示例,即使用字段寬度6和精度3來格式化浮點值3.14:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,Python在字元串中添加了一個表示精度的數字,并在數字左邊填充一個空格,以使字段寬度為6。這個寬度包括小數點所占的位置。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.3 案例研究:投資報告

據說複利是世界第八大奇迹。下面這個計算投資報告的案例研究顯示了原因。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

請求

編寫一個計算投資報告的程式。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

分析

該程式的輸入如下:

● 初始投資金額(浮點數)。

● 年數(整數)。

● 利率(以整數表示的百分比)。

該程式使用一種簡化形式的複利,其中利息每年計算一次,并加到投資總額中。程式的輸出是一份表格形式的報告,顯示了投資期限内每年的年份、該年度賬戶的初始餘額、該年度賺取的利息以及該年度的年末餘額。表格的第一行用适當的标題标記。在表格輸出之後,程式列印該期間的投資餘額總額和利息收入總額。建議的使用者界面如圖3-1所示。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

設計

程式的四個主要部分執行以下任務:

1.接收使用者輸入并初始化資料。

2.顯示表格的标題。

3.計算每年的結果,并在表格中顯示為一行。

4.顯示總數。

程式的第三部分用循環實作計算及結果的顯示。下面是程式僞代碼的一個稍微簡化的版本,沒有關于格式化輸出的細節:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,起始餘額是指原始輸入餘額,也指每年開始的餘額。在這一點上忽略輸出的細節讓我們專注于正确的計算。我們可以将這段僞代碼翻譯成Python程式來檢查計算過程。程式的粗略草稿叫作原型。一旦确信原型正在産生正确的數字,就可以回到設計中,并制定輸出格式的細節。

輸出的格式要将數字在列中很好地對齊。我們使用格式字元串來右對齊每行輸出上的所有數字。我們還将格式字元串用于表标題中的字元串标簽。經過反複試驗,我們得出了年份、起始餘額、利息和結束餘額的字段寬度,分别為4、18、10和16。我們也可以在标題的格式字元串中使用這些寬度。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

實作(編碼)

程式代碼顯示了設計中描述的每一個主要部分,以行尾注釋作為劃分。注意,其中使用了許多變量來跟蹤程式使用的各種金額。明智的是,我們為這些變量選擇了明确描述其目的的名稱。print語句中的格式字元串相當複雜,但是我們已經努力對它們進行格式化,以便它們包含的資訊仍然可讀性較高。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

測試

測試包含循環的程式時,我們應該首先關注決定疊代次數的輸入。在我們的項目中,這個值是年數。我們輸入一個值,産生盡可能少的疊代次數,然後将這個數字增加1,再然後使用稍大的數字,如5,最後使用接近最大預期的數字,如50(在我們的問題領域,這可能是投資的最大現實周期)。其他輸入的值,如我們這個項目中的投資金額和利率,應該相當小,并在測試的這個階段保持不變。如果程式為所有這些輸入産生了正确的輸出,我們可以确信循環工作正常。

在下一階段的測試中,我們将檢查其他輸入對結果的影響,包括它們的格式。我們知道,項目中的另外兩項投入——投資和利率——已經在值較小時産生了正确的結果。一個合理的政策可能是用最小和最大的年數以及最小的利率來測試大量投資,然後用最大的年數和最大的合理利率來測試。表3-1給出了程式的這些測試資料集。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.4 選擇:if語句和if-else語句

我們已經看到,計算機可以處理長長的指令序列,并且可以重複這樣做。然而,并非所有的問題都能以這種方式解決。在某些情況下,計算機可能會面臨兩種不同的行動方案,而不是直接執行下一條指令。計算機必須停下來檢查或測試一個條件,這個條件表達了關于當時狀态的一種假設。如果條件為真,計算機執行第一個動作并跳過第二個動作。如果條件為假,計算機跳過第一個動作并執行第二個動作。

換句話說,計算機不是盲目前進,而是通過對環境條件做出反應來鍛煉智能。在本節中,我們将探讨幾種類型的選擇語句或控制語句,它們允許計算機進行選擇。但是首先,我們需要考慮計算機如何測試條件。

3.4.1 布爾類型、比較和布爾表達式

在Python程式中測試條件之前,你需要了解布爾資料類型,這是以19世紀英國數學家喬治·布爾的名字命名的。布爾資料類型僅包含兩個資料值——真和假。在Python中,布爾字面量可以用幾種方式編寫,但是大多數程式員更喜歡使用标準值True和False。

簡單的布爾表達式包括布爾值True或False、綁定到這些值的變量、傳回布爾值的函數調用或比較。選擇語句中的條件通常采取比較的形式。例如,你可以比較值A和值B,看看哪一個更大。比較的結果是布爾值。值A大于值B是真,否則是假。要寫進行比較的表達式,你必須熟悉Python的比較運算符,如表3-2所示。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

以下代碼顯示了一些示例比較及其值:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意“==”表示相等,而“=”表示指派。正如你在第2章中所了解的,在計算Python中的表達式時,你需要了解優先級,即運算符在複雜表達式中的應用順序。比較運算符在加法之後但在指派之前應用。

3.4.2 if-else語句

if-else語句是最常見的選擇語句類型。它也被稱為雙路選擇語句,因為它指導計算機在兩種不同的行動方案中做出選擇。

if-else語句通常用于檢查輸入是否有錯誤,并在必要時使用錯誤消息進行響應。另一種選擇是,如果輸入有效,則繼續執行計算。

例如,假設一個程式輸入圓的面積,并計算和輸出其半徑。這個程式的合法輸入應該是正數。但是,使用者仍然可以錯誤地輸入零或負數。因為程式别無選擇,隻能使用這個值來計算半徑,是以它可能會崩潰(停止運作)或産生無意義的輸出。以下代碼段展示了如何使用if-else語句定位(陷入)此錯誤并對其做出響應:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

以下是Python中if-else語句的文法:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

if-else語句中的條件必須是布爾表達式,即計算結果為真或假的表達式。這兩個可能的動作都由一系列語句組成。注意,每組語句必須相對于if和else符号縮進至少一個空格。最後,注意條件後面的冒号(:)和else這個詞。圖3-2顯示了if-else語句語義的流程圖。在圖中,包含問号的菱形表示條件。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

以下示例列印兩個輸入數字的最大值和最小值。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

Python包括max和min兩個函數,是以不必使用if-else語句。在以下示例中,函數max傳回其參數中的最大值,而min傳回其參數中的最小值:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.4.3 單路選擇語句

最簡單的選擇形式是if語句。這種類型的控制語句也稱為單路選擇語句,因為它由一個條件和一系列語句組成。如果條件為真,則運作語句序列。否則,程式将跳到整個選擇語句之後的下一一個語句。以下是if語句的文法:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

圖3-3顯示了if語句語義的流程圖。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

簡單的if語句通常用于在條件不正确時阻止執行某個操作。例如,負數的絕對值是對那個數字的算術求反,否則就是那個數字本身。以下代碼使用簡單的if語句将變量值重置為絕對值:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.4.4 多路if語句

偶爾,程式會面臨測試幾個條件的情況,這些條件需要兩個以上的行動方案。例如,考;慮将數字等級轉換為字母等級的問題。表3-3顯示了一個簡單的評分方案,該方案基于兩個假設:數字評分範圍從0到100,字母評分為A、B、C和F。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

用語言來說明:使用這種方案的算法會聲明,如果數字大于89,則字母等級為A,否則如果數字等級大于79,則字母等級為B……否則(預設情況下)字母等級為F。測試幾個條件并做出相應響應的過程可以用代碼通過多路選擇語句來描述。下面是一個簡短的Python腳本,它使用這樣的語句來确定和列印與輸入數字等級相對應的字母等級:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

多路if語句考慮每個條件,直到一個條件為真或者所有條件為假。當條件為True時,相應的操作為執行目前條件下的語句并跳到整個選擇語句的末尾。如果沒有條件為True,則執行else之後的操作。

多路if語句的文法如下:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

縮進再次幫助人類讀者和Python解釋器看到這個控制語句的邏輯結構。圖3-4顯示了具有兩個條件和else子句的多路if語句的語義流程圖。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.4.5 邏輯運算符和複合布爾表達式

如果兩個條件中的任何一個是真的,通常必須采取行動。例如,程式的有效輸入通常位于給定的範圍内,超過這個範圍的任何輸入都應該被錯誤資訊拒絕,低于這個範圍的任何輸入也應該以類似的方式處理。以下代碼段隻接受等級轉換腳本的有效輸入,否則會顯示錯誤消息:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,前兩個條件與相同的操作相關聯。換句話說,如果第一個條件為真或者第二個條件為真,程式輸出相同的錯誤消息。這兩個條件可以組合成使用邏輯運算符or的布爾表達式。得到的複合布爾表達式稍微簡化了代碼,如下所示:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

描述這種情況的另一種方式是,如果數字大于等于0且小于等于100,那麼我們希望程式執行計算并輸出結果;否則,它應該輸出錯誤消息。邏輯運算符and可用于構造不同的複合布爾表達式來表示此邏輯:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

Python包括所有三個布爾或邏輯運算符:and,or,not。and運算符和or運算符都需要兩個操作數。and運算符在兩個操作數都為真時傳回True,否則傳回False。or運算符僅在兩個操作數都為False時傳回False,否則傳回True。not運算符需要一個操作數,如果為假,則傳回其邏輯否定,如果為真,則傳回False。

每個運算符的行為可以在該運算符的真值表中完全指定。真值表中第一行下面的每一行都包含操作數的值和将運算符應用于操作數所産生的值的一種可能組合。第一行顯示了操作數和正在計算的表達式。圖3-5顯示了and、or和not的真值表。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

以下例子驗證了圖3-5真值表中的一些值:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在第2章中,你看到乘法和除法比加法和減法有更高的優先級。這意味着優先級較高的運算符會首先被計算,即使它們出現在優先級較低的運算符右側。同樣的想法也适用于比較運算符、邏輯運算符和指派運算符。邏輯運算符在比較運算符之後但在指派運算符之前進行計算。not運算符的優先級高于and運算符,and運算符的優先級高于or運算符。是以,在.我們的示例中,not A and B為假,而not (A and B)為真。雖然通常不必擔心大多數代碼中的運算符優先級,但你可能會看到如下代碼,其中顯示了所有不同類型的運算符:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

表3-4總結了本書到目前為止所讨論的運算符的優先級。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.4.6 短路計算

Python虛拟機有時在計算完所有操作數之前就知道布爾表達式的值。例如,在表達式AandB中,如果A是假的,那麼表達式也是假的,沒有必要考慮B。

同樣,在表達式AorB中,如果A是真的,那麼表達式也是真的,沒有必要考慮B。這種計算盡快停止的方法被稱為短路計算。

有時短路計算是有利的。考慮以下示例:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

如果使用者輸入0進行計數,則該條件包含一個除以零的潛在計算;然而,由于短路計算,避免了除以零的情況發生。

3.4.7 測試選擇語句

選擇語句為程式添加了額外的邏輯,但它們也為額外的邏輯錯誤打開了大門。是以,在測試包含選擇語句的程式時要特别小心。

第一條經驗法則是確定選擇語句中所有可能的分支或選項都得到執行。如果測試資料包含使每個條件為真以及使每個條件為假的值,則能夠保證這一點。在我們的等級轉換示例中,測試資料應該包括産生每個字母等級的數字。

在測試所有操作之後,你還應該檢查所有條件。例如,當一個條件包含兩個數字的比較時,試着用相等的操作數、減1的左操作數和加1的左操作數來測試程式,以捕捉邊界情況下的錯誤。

最後,你需要使用産生所有可能的操作數值組合的資料來測試包含複合布爾表達式的條件。作為測試複合布爾表達式的藍圖,使用該表達式的真值表。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.5 條件疊代:while循環

前面我們研究了for循環,它執行一組語句,執行次數由程式員指定。然而,在許多情況下,循環中的疊代次數是不可預測的。這個循環最終完成了工作,但是隻有當條件改變時才如此。例如,程式可能會要求使用者輸入一組值。在這種情況下,隻有使用者知道她将輸入的内容。程式的輸入循環接收這些值,直到使用者輸入終止輸入的特殊值或标記。這種類型的過程稱為條件疊代,這意味着隻要條件保持為真,這個過程就會繼續重複。在本節中,我們将探讨while循環并用此來描述條件疊代。

3.5.1 while循環的結構和行為

條件疊代要求在循環中測試一個條件,以确定循環是否應該繼續。這種條件被稱為循環的繼續條件。如果繼續條件為假,則循環結束。如果繼續條件為真,則循環中的語句将再次執行。while循環是為這種類型的控制邏輯量身定制的。以下是它的文法:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

該語句的形式幾乎與單路選擇語句的形式相同。但是,使用保留字while而不是if表示隻要條件保持為真,語句序列可能會執行多次。

顯然,為了使循環的繼續條件為假,最終必須在循環體内發生一些事情。否則,循環将永遠持續下去,這種錯誤稱為無限循環。循環主體中至少有一條語句必須更新影響條件值的變量。圖3-6顯示了while循環語義的流程圖。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

下面的示例是一個簡短的腳本,提示使用者輸入一系列數字,計算它們的總和,并輸出結果。當使用者簡單地按下Return或Enter鍵時,程式停止輸入過程,而不是強迫使用者輸入一定數量的值。程式将此值識别為空字元串。我們首先以僞代碼算法的形式給出一個粗略的草稿:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,有兩個輸入語句,一個在循環頭之前,一個在循環體的底部。第一條輸入語句将變量初始化為循環條件可以測試的值。這個變量也稱為循環控制變量。第二條輸入語句獲得其他輸入值,包括終止循環的輸入值。還要注意,輸入必須以字元串形式接收,而不是數字形式,是以程式可以測試空字元串。如果字元串不是空的,我們假設它代表一個數字,并将它轉換成一個浮點數。下面是這個腳本的Python代碼,包括示例運作的結果:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

在這次運作中,有四個輸入,包括空字元串。現在,假設我們再次運作腳本,使用者在第一次提示時輸入空字元串。while循環的條件不成立,它的循環體根本不執行!總和列印為0.0。

while循環也被稱為入口控制循環,因為它的條件是在循環的頂部測試的。這意味着循環中的語句可以執行零次或更多次。

3.5.2 使用while循環的計數控制

你也可以将while循環用于計數控制的循環。接下來的兩段代碼分别顯示了for循環和while循環的相同求和運算。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

盡管兩個循環産生了相同的結果,但還是存在折中。第二段代碼明顯更複雜,它包括一個布爾表達式和兩個引用變量count的額外語句。這個循環控制變量必須顯式地在循環頭之前初始化,并在循環體中增加。變量count也必須在顯式連續條件下檢查。對于程式員來說,這種額外的手工勞動不僅耗時,而且可能是循環邏輯中新錯誤的來源。

相比之下,for循環在循環頭中簡潔地指定控制資訊,并在幕後自動操作。然而,我們很快就會看到while循環是唯一的解決方案。是以,你必須掌握while循環的邏輯,并且要知道它們可能産生的邏輯錯誤。

以下示例顯示了倒計時腳本的兩個版本,從上限10到下限1。請你自己思考哪一個更容易了解和正确編寫。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.5.3 whileTrue循環和break語句

雖然while循環可能很難正确編寫,但可以簡化其結構,進而提高可讀性。本節的第一個示例腳本包含兩個輸入語句,是一種不錯的改進。如果我們在循環内接收第一個輸入并且測試顯示繼續條件為假,則可以簡化此循環的結構。這意味着将實際測試推遲到循環中間。Python包含break語句,允許我們在程式中進行此更改。這是修改後的腳本:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

首先要注意的是循環的進入條件是布爾值True。有些讀者可能會對這種情況感到震驚,這似乎意味着循環永遠不會退出。但是,這種情況非常容易編寫,并保證循環體至少執行一次。在此循環中,接收輸入資料,然後在單路選擇語句中測試循環的終止條件。如果使用者想要退出,則輸入将等于空字元串,break語句将導緻退出循環。否則,控制将繼續到選擇語句後面處理輸入的兩個語句。

我們的下一個示例修改了等級轉換程式的輸入部分,以繼續從使用者擷取輸入數字,直到其輸入可接受的值。該循環的邏輯類似于前一個示例的邏輯。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

運作以上代碼的互動如下:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

一些計算機科學家認為,延遲退出的while True循環違反了while循環的精神。但是,在循環體必須至少執行一次的情況下,這種技術簡化了代碼并且實際上使程式的邏輯更清晰。如果你沒有被這種推理說服并仍想測試循環頂部的繼續和退出條件,則可以使用布爾變量來控制循環。以下是使用布爾變量的數字輸入循環的一個版本:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

有關此問題的經典讨論,請參閱EricRoberts的文章,“LoopExitsandStructuredProgramming:ReopeningtheDebate”,ACMSIGCSEBulletin,Volume27,Number1,March1995,pp.268-272。

雖然break語句在控制至少一次疊代的循環時非常有用,但是你應該主要将它用作這些循環的單一出口點。

3.5.4 随機數

到目前為止,我們的算法所做的選擇完全是由給定的條件決定的,這些條件要麼是真的,要麼是假的。許多情況下,比如遊戲,在做出的選擇中包含一些随機性。例如,我們可以擲硬币來決定誰在足球比賽中開球,硬币正面朝上或反面朝上的機率相等。同樣,在許多遊戲中,骰子滾動時,數字1到6正面朝上的機率相等。為了在計算機應用中模拟這種随機性,程式設計語言包括用于生成随機數的資源。Python的random子產品支援多種方法,但是最簡單的方法是用兩個整數參數調用random.randint函數。函數random.randint從兩個參數之間的數字中傳回一個随機數(包括這兩個參數本身)。以下代碼模拟骰子滾動10次:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

盡管在這個簡單的調用集中重複了一些值,但是在大量調用的過程中,值的分布接近真正的随機性。

我們現在可以使用random.randint、選擇和循環來開發一個簡單的猜謎遊戲。在啟動時,使用者輸入範圍内的最小數字和最大數字。然後計算機從這個範圍中選擇一個數字。在每次循環中,使用者輸入一個數字,試圖猜測計算機選擇的數字。程式的回應是“你猜對了”“太大了,再試一次”或者“太小了,再試一次”。當使用者最終猜到正确的數字時,程式會祝賀他,并告訴他猜測的總數。下面是程式的代碼及其示例運作:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

注意,我們的代碼旨在允許使用者智能猜測數字,從兩個初始數字之間的中點開始,每次不正确的猜測都會消除一半的剩餘數字。理想情況下,使用者應該能夠在不超過log2(最大值-最小值+1)次的嘗試中猜出正确的數字。你将在練習和程式設計項目中探索log2的概念。

3.5.5 循環邏輯、錯誤和測試

你已經看到while循環通常是條件控制循環,這意味着它的繼續與否取決于給定條件是真還是假。循環可能是最複雜的控制語句,為了確定它們的正确執行,需要仔細設計和測試。測試while循環必須結合用于for循環和選擇語句的測試元素。測試while循環期間要排除的錯誤包括初始化不正确的循環控制變量、未能在循環中正确更新該變量以及未能在繼續狀态下正确測試該變量。此外,如果程式員隻是忘記更新控制變量,結果導緻出現無限循環,這甚至不符合算法的條件!要停止在測試期間似乎挂起的循環,請在終端視窗或IDLE中鍵入Control+C。

真正的條件控制循環易于設計和測試。如果繼續條件可以在循環入口進行檢查,那麼就在那裡進行檢查,并提供産生0、1和至少5次疊代的測試資料。

如果循環必須運作至少一次,請使用while True循環,并延遲對終止條件的檢查,直到它在循環主體中可用。確定在循環中會發生一些事情,以允許檢查條件并最終到達break語句。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

3.6 案例研究:近似平方根

袖珍電腦或Python math子產品的使用者不必考慮如何計算平方根,但是建構電腦或為該子產品編寫代碼的人肯定會考慮。在這個案例研究中,我們深入其中,看看如何做到這一點。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

編寫一個計算平方根的程式。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這個程式的輸入是一個正浮點數或整數。輸出是一個浮點數,代表輸入數的平方根。為了便于比較,我們同時使用math.sqrt輸出Python對平方根的計算。以下是使用者互動過程示例:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

17世紀,艾薩克·牛頓爵士發現了一種近似正數平方根的算法。回想一下,正數x的平方根y是數字y,是以y^2=x。牛頓發現,如果對y的初始估計是z,那麼通過将z的平均值與x/z相加,可以獲得對y的更好估計。這個估計可以通過該規則反複變換,直到達到滿意的估計。

在Python解釋器中的快速編碼展示了這種連續近似的方法。令x為25,初始估計z為1。然後我們用牛頓的方法将z重置為一個更好的估計值,并檢查z是否接近實際平方根5。以下是代碼記錄:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

經過三次變換後,z的值正好等于5,即25的平方根。為了包含具有無理數平方根的數字,例如2和10,我們可以将初始猜測設為1.0來産生浮點結果。

我們現在開發了一種算法來自動化連續變換的過程,因為可能有很多變換,我們不想把它們都寫出來。到底需要多少次這樣的運算取決于我們希望最終近似值接近實際平方根的程度。這個接近值叫作容差,可以在任何給定時間與x的值和我們估計的平方之間的差進行比較。若二者之差大于容差,這一過程繼續,否則會停止。容差通常很小,例如0.000001。

我們的算法允許使用者輸入數字,使用循環應用牛頓法計算平方根,并列印這個值。下面是僞代碼,後面是具體解釋。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

因為初始估計是1.0,是以循環必須計算至少一個新的估計。是以,我們使用一個while True循環。這個循環在确定估計值是否足夠接近容內插補點以停止該過程之前變換估計值。當我們估計的平方與原始數字之間的內插補點小于或等于容內插補點時,該過程應該停止。注意,這種差異可能是正的也可能是負的,是以我們在檢查之前使用abs函數來獲得其絕對值。

while循環更傳統的用法是将差異與循環頭中的容差進行比較。然而,必須在循環之前将內插補點初始化為一個大的、相當無意義的值。這裡介紹的算法更清晰、更簡單地展現了逐次逼近法的邏輯。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這個程式的代碼很簡單。

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章
帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這個程式的有效輸入是正整數和浮點數。Python本身對平方根的最準确計算為評估我們自己的算法的正确性提供了一個基準。我們至少應該提供幾個完美的平方數,比如4和9,以及平方根不精确的數字,比如2和3。還應該包括介于1和0之間的數字,例如0.25。因為我們的算法的準确性也取決于容差的大小,是以也可以在測試期間改變這個值。

3.7 本章小結

● 控制語句決定程式中其他語句的執行順序。

● 确定疊代是執行一組語句的過程,執行次數是固定的、可預測的。for循環是一種簡單友善的控制語句,描述了确定的疊代。

● for循環由循環頭和循環體的語句組成。循環頭包含控制主體執行次數的資訊。

● for循環可以通過一系列整數計數,這種循環稱為計數控制環路。

● 在for循環的計數控制執行期間,循環體中的語句可以使用循環頭的變量引用計數的目前值。

● Python的range函數在計數控制的for循環中生成數字序列。此函數可以接收一個、兩個或三個參數。單個參數M指定數字0到M-1的序列。兩個參數M和N指定數字M到N-1的序列。當S為正時,三個參數M、N和S指定數字M到N-1的序列,按S步進;當S為負時,則為M到N+1。

● for循環可以周遊和通路序列中的值。示例序列是字元串和數字清單。

● 格式化字元串及其運算符%允許程式員使用字段寬度和精度格式化資料。

● 當一個循環沒有執行預期的疊代次數時,就會出現大小差一錯誤,即多了一個或少了一個。這個錯誤可能是由計數控制循環中不正确的下限或上限引起的。

● 布爾表達式包含值True或False、綁定到這些值的變量、使用關系運算符的比較或使用邏輯運算符的其他布爾表達式。布爾表達式計算為真或假,用于在程式中形成條件。

● 邏輯運算符and、or和not用于構造複合布爾表達式。這些表達式的值可以通過構造真值表來确定。

● Python在複合布爾表達式中使用短路計算。對or的操作數的求值在第一個真值處停止,而對and的操作數的求值在第一個假值處停止。

● 選擇語句是允許程式進行選擇的控制語句。選擇語句包含一個或多個條件和相應的操作。計算機沒有直接進行下一步操作,而是檢查一個條件。如果條件為真,計算機将執行相應的操作,然後移動到選擇語句之後的操作。否則,計算機會移動到下一個條件(如果有),或者移動到選擇語句之後的操作。

● 雙路選擇語句也稱為if-else語句,有一個條件和兩個可選的操作過程。單路選擇語句也稱為if語句,具有單個條件和單個操作過程。多路選擇語句也稱為擴充if語句,至少有兩個條件和三個可選的操作過程。

● 條件疊代是在條件成立時執行一組語句的過程。當條件變為假時,疊代停止。因為不能總是預測何時會發生這種情況,是以疊代次數通常無法預測。

● while循環用于描述條件疊代。這個循環由循環頭和一組循環體語句組成。循環頭包含循環的繼續條件,隻要繼續條件為真,循環體就會執行。

● while循環是一個入口控制循環。這意味着在循環入口測試繼續條件,如果它是假的,循環的主體将不會執行。是以,while循環可以描述零次或更多次疊代。

● break語句可用于從主體退出while循環。當循環必須執行至少一次疊代時,通常使用break語句。在這種情況下,循環頭的條件是值True。break語句嵌套在測試終止條件的if語句中。

● 任何for循環都可以轉換為等效的while循環。在計數控制的while循環中,程式員必須初始化和更新循環控制變量。

● 當循環的繼續條件從未變為假,并且沒有提供其他出口點時,就會出現無限循環。無限循環的主要原因是程式員未能正确更新循環控制變量。

● 函數random.randint傳回兩個參數指定範圍内的随機數。

3.8 複習題

1.循環頭為for count in range(10),其循環體中的語句執行多少次? 

a.9次

b.10次

c.11次

2.for循環便于: 

a.在程式中做出選擇

b.以可預測的次數運作一組語句

c.通過一系列數字進行計數

d.描述條件疊代

3.for count in range(5):print(count,end=“ “)循環的輸出是什麼? 

a.12345

b.1234

c.01234

4.當range函數接收到兩個參數時,第二個參數指定了什麼? 

a.整數序列的最後一個值

b.整數序列的最後一個值加1

c.整數序列的最後一個值減1

5.考慮以下代碼段:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

 這段代碼列印什麼值? 

a.4

b.5

6.使用and運算符的布爾表達式在以下哪種情況下傳回True: 

a.兩個操作數都為真

b.一個操作數為真

c.兩個操作數都不為真

7.預設情況下,while循環是一個: 

a.入口控制循環

b.出口控制循環

8.考慮以下代碼段:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這段代碼的輸出是什麼?

a.1 2 3 4 5

b.2 3 4 5

c.5 4 3 2 1

d.5 4 3 2

9.考慮以下代碼段:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

下列哪一項描述了此代碼中的錯誤?

a.循環一次後終止

b.循環控制變量沒有正确初始化

c.比較的方式有問題

d.循環是無限的

10.考慮以下代碼段:

帶你讀《Python 程式設計與問題求解(原書第2版)》之三:循環和選擇語句第3章

這個循環執行多少次疊代?

a.不執行

b.至少1次

c.零次或者多次

d.10次

3.9 程式設計項目

1.編寫一個程式,接收三角形三條邊的長度作為輸入。程式輸出應該表明三角形是否是等邊三角形。

2.編寫一個程式,接收三角形三條邊的長度作為輸入。程式輸出應該表明三角形是否是直角三角形。回想畢達哥拉斯定理,在直角三角形中,一邊的平方等于另兩邊的平方之和。

3.修改3.5節中的猜謎遊戲程式,以便使用者想到計算機必須猜的數字。計算機必須做出不超過指定最小次數的猜測,并且必須通過輸入誤導提示來防止使用者作弊。(提示:使用math.log函數計算輸入下限和上限後所需的最小猜測次數。)

4.做一項科學實驗:丢下一個球,看看它反彈多高。一旦确定了球的“彈性”,這個比率就代表彈性指數。例如,如果一個球從10英尺的高度跌落,反彈6英尺高,則指數為0.6,一次反彈後,球行進的總距離為16英尺。如果球繼續彈跳,兩次彈跳後的距離将是10英尺+6英尺+6英尺+3.6英尺=25.6英尺。注意,每次連續彈跳的行進距離是指球回到地面的距離加上該距離乘以0.6。編寫一個程式,讓使用者輸入球落下的初始高度和允許球繼續彈跳的次數。輸出應該是球行進的總距離。

5.某地的生物學家需要一個程式來預測種群增長。輸入将是生物體的初始數量、增長率(大于0的實數)、達到這個速度所需的小時數以及種群增長的小時數。例如,可以從500個有機體的種群開始,增長率為2,以及達到該增長率所需的6小時的生長周期。假設沒有一種生物死亡,這意味着這一種群每6小時就會增加一倍。是以,在6小時的生長後,将有1000個生物,12小時後,将有2000個生物。編寫一個接收這些輸入并顯示總種群預測的程式。

6.德國數學家戈特弗裡德·萊布尼茨提出了以下方法來近似π的值:

π/4=1-1/3+1/5-1/7+...

編寫一個程式,允許使用者指定這個近似中使用的疊代次數,并顯示結果值。

7.大多數學區的教師都是按時間表支付工資的,該時間表根據他們的教學經驗提供工資。例如,列克星敦學區的初任教師第一年可能會得到30000美元。在第一年之後的每一年,直到10年,教師都會獲得比之前增加2%的收入。編寫一個程式,以表格形式為學區的教師顯示工資計劃。輸入包括起薪、加薪百分比和年數。時間表中的每一行都應該包含該年度的年份和薪資。

8.兩個正整數(A和B)的最大公約數(GCD)是可以整除這兩個整數的最大數字。歐幾裡得算法可用于尋找兩個正整數的最大公約數。你可以按以下方式使用此算法: 

a.計算大數字除以小數字的餘數。 b.用較小的數字替換較大的數字,用剩餘的數字替換較小的數字。 c.重複此過程,直到較小的數字為零。

此時較大的數字是A和B的GCD。編寫一個程式,讓使用者輸入兩個整數,然後列印使用歐幾裡得算法查找GCD過程中的每個步驟。

9.編寫一個程式,從使用者那裡接收一系列數字,并允許使用者按下Enter鍵來表示輸入完成。使用者按下Enter鍵後,程式應該列印數字和它們的平均值。

10.TidBit電腦商店的信貸計劃規定了10%的首付和12%的年利率。每月付款是列出的購買價格的5%減去首付款。編寫一個以購買價格為輸入的程式。該程式應該顯示一個表格,其中有适當的标題,顯示貸款期限内的付款時間表。表格的每一行都應該包含以下項目:

●月份(從1開始)

●目前欠款總額

●當月所欠利息

●當月所欠本金

●當月付款

●付款後剩餘餘額

一個月的利息金額等于餘額×利率/12。一個月的本金金額等于每月付款減去所欠利息。

11.在“幸運七”的遊戲中,玩家擲骰子,如果點數加起來是7,則赢4美元,否則将損失1美元。為了吸引玩家,遊戲推廣商說有很多赢的方法:(1,6),(2,5),等等。然而做一點數學分析就知道,沒有足夠的方法來確定玩家赢得這場遊戲。然而,因為許多人一提到數學就眼花缭亂,是以你的挑戰是編寫一個程式來證明玩這個遊戲是徒勞的。你的程式應該把玩家想要投入的錢作為輸入,并且玩到錢輸光為止。程式應該列印玩家輸光前的擲骰數,以及所剩餘的最大金額。