“笨辦法”學Python 3基礎篇系列文章
“笨辦法”學Python 3基礎篇 第一部分-列印與輸入
“笨辦法”學Python 3基礎篇 第二部分-檔案操作
“笨辦法”學Python 3基礎篇 第三部分-函數
“笨辦法”學Python 3基礎篇 第四部分-資料容器與程式結構
“笨辦法”學Python 3基礎篇 第五部分-面向對象的類
“笨辦法”學Python 3基礎篇 第六部分-項目骨架與自動測試
“笨辦法”學Python 3基礎篇 第七部分-搭建簡易的網站
第四部分 資料容器與程式結構
- “笨辦法”學Python 3基礎篇系列文章
- 前言
- 4.1 程式邏輯結構-分支 if、elif、else
-
- 4.1.1 文法格式
- 4.1.2 讓我們來做一個簡易口算訓練器
-
- 4.1.2.1 随機數 - random用法
- 4.1.2.2 生成随機運算符 - if + else + random
- 4.1.2.3 運算函數
- 4.1.2.4 綜合
- 4.2 程式邏輯結構-循環 for 和 while
-
- 4.2.1 for + 清單
- 4.2.2 while + 清單
- 4.2.3 挑戰一個更複雜的口算訓練器
- 4.3 更複雜的清單操作
- 結語
前言
上個禮拜一直在忙本人學校教學大綱修訂的任務,自3月23日至3月30日止,期間耗費了較多精力,是以本來計劃的上周要繼續總結假期學習内容的博文也來不及寫了。昨天又是上課又是開會,回家還得教育孩子,實在是沒精力敲打鍵盤了。今天終于得空,繼續進行Python3 假期學習内容的總結。
本篇主要是總結常用的程式邏輯結構-分支和循環,并将分支、循環和資料容器-清單相結合進行總結。
4.1 程式邏輯結構-分支 if、elif、else
在學C語言或者Verilog HDL語言時,進行算法級的描述常用到的邏輯控制結構為分支結構(也叫做條件結構)和循環結構。分支結構用于進行條件的判斷,進而根據判斷結果做出決定,以 if、elif、else 的使用最常見。循環結構則是用于邏輯的疊代,資料的周遊,以 for、while 的使用最常見。如果我們不想隻局限于列印和輸入,那麼就必然會用到這兩個程式邏輯結構來設計更複雜的功能。
4.1.1 文法格式
不同于C語言,在Python3 中分支的基本文法結構為:
分支結構以 if 開頭,後接布爾表達式和 : 号。行尾冒号的作用是告訴Python接下來你要建立一個新代碼塊,下接的代碼塊必修進行縮進,以此來告訴Python這些代碼處于該段代碼快中,與建立函數時相同。根據布爾表達式的真或假,選擇運作 if 代碼塊還是 elif 代碼塊。如果所有情況都不滿足,則執行預設的 else 代碼塊。
4.1.2 讓我們來做一個簡易口算訓練器
現在,我們可以用分支結構來解決一個簡單的問題:
設計一個簡易整數口算訓練機,提供口算習題并能夠判斷口算結果是否正确
分析這個問題,這樣一個簡單的口算訓練機,需要實作如下功能:
- 用随機數生成口算的操作數;
- 用随機數和分支結構生成運算符(加法和減法);
- 用函數求出正确答案;
- 提問與等待解答;
- 分支結構判斷口算結果,做出對錯決定。
4.1.2.1 随機數 - random用法
為了生成随機數,我們需要import一個叫做 random 的子產品,這是一個Python安裝時就有的系統子產品,不需要額外安裝擴充包。然後通過random子產品去調用不同的随機數生成方法,常用的為:
- random.random() : 傳回生成的一個實數,在[0,1)範圍内;
- random.uniform(num1,num2) : 傳回生成的一個實數,範圍在[num1,num2)之間;
- random.randint(num1,num2): 傳回生成的一個整數,範圍為num1到num2。
來看這樣一段代碼:
import random
print(random.random())
print(random.random()*100)
print(random.uniform(100,101))
print(random.randint(0,100))
第一行代碼為引入random子產品,後面四行代碼分别實作生成[0,1)的随機實數、生成[0,100)的随機實數、生成[100, 101)的随機實數、生成0-100的随機整數。在PowerShell運作後,結果為:
4.1.2.2 生成随機運算符 - if + else + random
在掌握了random子產品生成随機數的方法後,我們就需要将生成的随機數按照數值大小劃分出兩個部分,即[0,50)和[50,100)這兩個部分。每個部分作為一個判斷條件,執行減法函數或加法函數的調用,具體的分支結構(僞代碼)為:
if 随機數處于[0,50) :
調用加法函數add
else :
調用減法函數sub
具體的實作代碼為
import random
def gen():
op1 = random.randint(0, 100)
op2 = random.randint(0, 100)
op3 = random.random()*100
if op3 < 50:
return add(op1, op2)
elif op3 >= 50 and op1 >= op2:
return sub(op1, op2)
else:
return sub(op2, op1)
在這段代碼中,我們通過 gen() 這個函數來負責随機數和随機運算符的生成。op1 和 op2是運算時的兩個操作數,通過op3來判斷生成加法還是減法。如果op3小于50,則調用加法函數實作 op1 + op2;如果op3大于等于50且op1大于op2,傳回sub(op1,op2), 實作 op1 - op2; 否則傳回sub(op2, op1), 實作 op2 - op1。
4.1.2.3 運算函數
運用“笨辦法”學Python 3基礎篇 第三部分-函數
中的設計方法,加法和減法函數功能為:
- print 目前算式
- 等待輸入口算結果
- 分支結構判斷結果
- print 運算結果
具體的代碼為:
from sys import exit
def add(augend, addend):
print(f"{augend} + {addend} = ", end = "")
result = int(input())
if result == augend + addend:
print(f"The result is true.")
exit(0)
else:
print(f"The result is false.")
exit(0)
def sub(augend, subend):
print(f"{augend} - {subend} = ", end = "")
result = int(input())
if result == augend - subend:
print(f"The result is true.")
exit(0)
else:
print(f"The result is false.")
exit(0)
為了計算成功後,能夠退出腳本, 我們引入了exit子產品。通過使用exit(0)來正常退出程式,回到PowerShell。
4.1.2.4 綜合
完成了随機數生成、随機運算符和運算函數後,剩下的就是綜合了。綜合後的代碼為:
from sys import exit
import random
def gen():
op1 = random.randint(0, 100)
op2 = random.randint(0, 100)
op3 = random.random()*100
if op3 < 50:
return add(op1, op2)
elif op3 >= 50 and op1 >= op2:
return sub(op1, op2)
else:
return sub(op2, op1)
def add(augend, addend):
print(f"{augend} + {addend} = ", end = "")
result = int(input())
if result == augend + addend:
print(f"The result is true.")
exit(0)
else:
print(f"The result is false.")
exit(0)
def sub(augend, subend):
print(f"{augend} - {subend} = ", end = "")
result = int(input())
if result == augend - subend:
print(f"The result is true.")
exit(0)
else:
print(f"The result is false.")
exit(0)
print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'Y'):
gen()
else:
print("Coward!")
當然,這裡少不了用分支結構設計一下對話方式,通過輸入Y來執行gen()函數,通過N來輸出字元串。運作PowerShell後得到的結果為
4.2 程式邏輯結構-循環 for 和 while
循環結構是另一種常用的邏輯控制結構。常用到的是for和while。
4.2.1 for + 清單
在開始使用for循環之前,我們需要在某個位置存放循環的結果,也就是需要一個資料的容器。最好的方法是使用清單。清單的定義非常簡單,以 [ 開頭打開清單,然後寫下要放入清單的東西,用逗号隔開,就跟函數的參數一樣,最後需要用右括号 ] 表明清單結束。例如:
- hairs = [‘brown’, ‘blond’, ‘red’]
如果想要周遊hairs這個清單的所有元素,此時我們就需要用到for循環了。for循環的基本文法結構為:
for 變量 in 序列:
代碼
else:
代碼
這裡的序列可以是清單或者字元串, else後面的是可選項。下面我們來看如何周遊hairs這個清單,并列印出每個元素。代碼如下:
hairs = ['brown', 'blond', 'red']
for color in hairs:
print(f"Your hair is {color}!")
for number in range(3):
print(f"My hair is {hairs[number]}, too!")
在這段代碼中,第一個for循環将hairs清單中的元素在每次循環時依次指派給了color,實作了清單元素的周遊。第二個for循環中序列則采用了range(3)函數,實作了0,1,2三個整數的周遊。每周遊一個整數,number變量就指派為該整數并從hairs清單中切片出對應元素。PowerShell運作結果如圖所示。
4.2.2 while + 清單
如果要使用while循環來實作,則首先我們得了解while循環的基本文法結構:
while(布爾條件):
代碼1
else:
代碼2
當布爾條件為真時,執行代碼1;否則執行else的代碼塊。當然else是可以省略的。
用while代替for循環來編列hairs清單遇到最主要的問題是需要找出布爾條件。可以采用計數器+清單元素的個數來作為布爾條件實作循環的結束。具體代碼如下:
hairs = ['brown', 'blond', 'red']
count = 0
while(count < len(hairs)):
print(f"Her hair is {hairs[count]}!")
count += 1
在該段代碼中,定義了一個計數器count,每周遊清單中的一個元素,累計加1。通過len()獲得了清單元素的個數。當計數器count等于清單元素個數時跳出循環。PoweShell運作結果為:
4.2.3 挑戰一個更複雜的口算訓練器
之前我們的口算訓練程式每次隻能做一次運算。現在我們可以用邏輯循環結構來為口算訓練程式添加如下功能:
- 使用者可以設定每次訓練的口算題數;
- 用循環結構重複生成随機口算式子并計分;
- 列印出最終正确率,并退出程式
具體的實作代碼為:
from sys import exit
import random
def gen():
op1 = random.randint(0, 100)
op2 = random.randint(0, 100)
op3 = random.random()*100
if op3 < 50:
return add(op1, op2)
elif op3 >= 50 and op1 >= op2:
return sub(op1, op2)
else:
return sub(op2, op1)
def add(augend, addend):
print(f"{augend} + {addend} = ", end = "")
result = int(input())
if result == augend + addend:
return 1
else:
return 0
def sub(augend, subend):
print(f"{augend} - {subend} = ", end = "")
result = int(input())
if result == augend - subend:
return 1
else:
return 0
print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'N'):
print("Coward!")
exit(0)
else:
print("How many exercises do you want to try?", end='')
count = int(input('> '))
score = 0
while count != 0:
score += gen()
count -= 1
print(f"Your final test score is {score}.")
exit(0)
在這段代碼中,我們對add()和sub()函數做了稍微的修改,不再讓它們列印出每次計算的結果,而是傳回1或者是0。在程式控制段,修改了條件分支的順序,避免了while循環和if條件分支程式塊的文法錯誤。同時,通過count變量實作了口算題的計數,通過while循環實作了正确率score的累計加1。循環結束條件則為計數器遞減為0。最後列印出正确率結果并啟用exit(0)退出程式。
PoweShell的運作結果為:
4.3 更複雜的清單操作
在4.1和4.2節中,我們已經簡單接觸到了清單,實作了清單元素的周遊。當然還可以對清單的元素做很多操作, 比如添加和彈出元素等,具體可參考清單list。
接下來,我們将運用清單添加元素來繼續解決口算練習器的問題:
使用者能夠浏覽上一次口算訓練做錯的題目和自己的答案
為了實作這一功能,我們需要建立一個清單mistakes,用來存儲錯題和正确的答案。然後通過for 循環,周遊mistakes清單中的每個錯題,并列印出來。具體的代碼為:
from sys import exit
import random
def gen():
op1 = random.randint(0, 100)
op2 = random.randint(0, 100)
op3 = random.random()*100
if op3 < 50:
return add(op1, op2)
elif op3 >= 50 and op1 >= op2:
return sub(op1, op2)
else:
return sub(op2, op1)
def add(augend, addend):
print(f"{augend} + {addend} = ", end = "")
result = int(input())
if result == augend + addend:
return 1
else:
mistakes.append(f'{augend} + {addend} = {result}, the right answer is {augend + addend}' )
return 0
def sub(augend, subend):
print(f"{augend} - {subend} = ", end = "")
result = int(input())
if result == augend - subend:
return 1
else:
mistakes.append(f'{augend} - {subend} = {result}, the right answer is {augend - subend}')
return 0
print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'N'):
print("Coward!")
exit(0)
else:
mistakes = []
print("How many exercises do you want to try?", end='')
count = int(input('> '))
success = count
score = 0
while count != 0:
score += gen()
count -= 1
if score == success:
print(f"Congratulations! You got all exercises right!")
exit(0)
else:
print(f"Your final test score is {score}.")
print("Here is your wrong record: ")
for var in mistakes:
print(var)
exit(0)
代碼的修改部分主要為定義了一個名為mistakes的空清單,并在add和sub函數中采用了mistakes.append實作了清單元素的添加(預設從清單末尾添加,具體用法可參考清單list)。結果為:
結語
資料容器更重要的一個概念是:字典。這篇文章由于中途有事,又寫了兩天,沒有來得及寫字典。後面要加快進度,把字典放在後續總結,并多以案例來總結學到的基本程式設計理論,這樣能更快速的消化。