# 流程
###### tags: `python`
程式執行的三種邏輯:「循序」、「判斷」與迴圈,程式不會永遠從頭到尾全部執行,而是會因為時間、情況或是使用者的操作而產生不同的執行結果,因此有了「判斷」因狀況不同而執行不同的程式碼或是重複執行相同一段程式碼數次。
### `if`分支判斷
格式:
```
if 條件式:
條件成立執行的程式碼
```
> **注意**
> 流程內的程式碼一定要縮排。
分支判斷可以用來根據判斷來決定是否要執行某一段程式碼,例如:
```
import datetime
if datetime.date.today().weekday() != 0:
print('今天不是Blue Monday.')
```
1. 呼叫`datetime.date.today().weekday()`會回傳今天是星期幾,0 = 星期一,6 = 星期日,中間以此類推。
2. 因為`datetime`是Python內建的外部模組,所以必先`import datetime`這個模組。
3. 記得在`if`判斷式的最後加上冒號「:」代表是判斷式區塊程式碼的開頭,接下來區塊程式碼必須全部縮排一個TAB或至少一個空白以上(建議是4個空白字元),每一行都必須對齊,也不可以混用TAB與空白字元,否則會出現錯誤無法執行。
4. 如果沒有縮排,代表該程式碼不屬於`if`判斷式區塊內的程式碼。
```
import datetime
import random
print(datetime.date.today().weekday()) # 取得星期, 從0開始代表星期
weekday = datetime.date.today().weekday()
if weekday == 5:
print('今天星期六')
input('輸入y開始算命:')
# 隨機取得1~3之間整數
n = random.randint(1, 3)
if n == 1:
print('恭喜,下周一買威力彩會中獎.')
if n == 2:
print('今天出門要注意安全')
if n == 3:
print('今天會撿到錢')
```
###### 多重分支
格式:
```
if 條件1:
條件1成立執行的程式碼
elif 條件2:
條件2成立執行的程式碼
...
elif 條件n:
條件n成立執行的程式碼
else:
所有條件都不成立要執行的程式碼
```
例如:
```
score = int(input('請輸入成績: '))
if score >= 90:
print('讚')
elif 90 > score >= 80:
print('不錯,再加油!')
elif 80 > score >= 70:
print('還可以')
elif 70 > score >= 60:
print('及格邊緣')
else:
print('不及格,要多加油')
```
會輸出:
```
請輸入成績: 100
讚
```
##### if...else
如果只是單純的判斷後結果只有兩種「是」或「不是」,Python有個更簡潔的語法,例如:
```
b = 5
print('偶數' if b % 2 == 0 else '奇數')
```
判斷是成立,會回傳`if`前面的值,否則回傳`else`後面的值,等同於:
```
b = 5
if b % 2 == 0:
print('偶數')
else:
print('奇數')
```
更多範例:
```
print('判斷===============================')
a = -5
if a > 0:
print('條件成立1')
print('條件成立2')
print('條件成立3')
print('XXXXX')
import datetime
import random
print(datetime.date.today().weekday()) # 取得星期, 從0開始代表星期
weekday = datetime.date.today().weekday()
if weekday == 5:
print('今天星期六')
start = input('輸入y開始算命:')
if start == 'y':
# 隨機取得1~3之間整數
n = random.randint(1, 3)
# if n == 1:
# print('恭喜,下周一買威力彩會中獎.')
# if n == 2:
# print('今天出門要注意安全')
# if n == 3:
# print('今天會撿到錢')
if n == 1:
print('恭喜,下周一買威力彩會中獎.')
elif n == 2:
print('今天出門要注意安全')
elif n == 3:
print('今天會撿到錢')
else:
print('系統錯誤')
else:
print('取消算命')
print('下午------------------------------------------')
user_data = int(input('請輸入一個數字:'))
# if user_data % 2 == 1:
# print(user_data, '是奇數')
# if user_data % 2 == 0:
# print(user_data, '是偶數')
# if user_data % 2 == 1:
# print(user_data, '是奇數')
# else:
# print(user_data, '是偶數')
print('奇數' if user_data % 2 == 1 else '偶數')
n = random.randint(1, 5)
user_data = int(input('請猜一個1~5之間的數字:'))
# if n == user_data:
# print('Bingo')
# if n != user_data:
# print('答案是:', n)
# if n == user_data:
# print('Bingo')
# else:
# print('答案是:', n)
print('Bingo' if n == user_data else '答案是:', n)
weekday = datetime.date.today().weekday() # 取得今天星期幾
if weekday == 0:
print('今天是星期一')
elif weekday == 1:
print('今天是星期二')
elif weekday == 2:
print('今天是星期三')
elif weekday == 3:
print('今天是星期四')
elif weekday == 4:
print('今天是星期五')
elif weekday == 5:
print('今天是星期六')
elif weekday == 6:
print('今天是星期日')
else:
print('今天是芥末日')
```
##### 練習
1. 寫一程式,使用者可以輸入一個整數,然後告訴使用者輸入的是奇數還是偶數。
2. 寫一個猜數字遊戲,電腦隨機產生1~5之間的數字,然後讓使用者猜,猜到則回應:Bingo,沒猜到則直接顯示答案。
3. 開發一個猜拳遊戲,由使用者輸入0=剪刀,1=石頭,2=布,電腦則隨機產生0~2數字後來跟使用者比較,並回應是電腦贏還是玩家贏或是平手。
#### 單行if
##### 語法
```
運算式1 if 條件運算式 else 運算式2
```
==如果條件運算式結果為True,則執行運算1,反之執行運算式2==,其效果等同於:
```
if 條件運算式:
運算式1
else:
運算式2
```
例如:
```
score = 80
if score >= 60:
print('及格')
else:
print('不及格')
```
使用單行if可以寫成:
```
score = 80
print('及格') if score >= 60 else print('不及格')
```
但是有個限制,運算式1和運算式2中不可以有「指派運算子」或「算術指派運算子」,例如:
```
if data >= 0:
result = data
else:
result = data * -1
```
不可以寫成:
```
result = data if data > 0 else result = data * -1
```
而是:
```
result = data if data > 0 else data * -1
```
#####
### `while`迴圈
格式:
```
while 條件式:
程式碼1
程式碼2
...
程式碼n
```
範例:
```
import random
n = 0
while n != 1: # 如果不是1就會跑迴圈
n = random.randint(0, 9) # 產生0到9的整數
print(n)
print('出現1了,結束迴圈.')
```
輸出範例:
```
8
8
1
出現1了,結束迴圈.
```
更多範例:
```
i = 0
while i <= 20:
print(i)
i += 1
print('迴圈結束')
n = int(input('您想要算多少的階層: ')) # 使用者想要算的階層
index = 1 # 階層的起點
result = 0 # 階層的總和
while index <= n:
result += index
index += 1
print(n, '的階層為:', result)
```
印出list內所有元素:
```
a = [3, 4, 5, 6, 7]
i = 0
while i < len(a):
print(a[i])
i += 1
```
九九乘法:
```
i = 1
while i <= 9:
print('2 x ', i, '=', 2*i)
i += 1
```
輸出為:
```
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
```
畫出6x6正方形:
```
i = 0
while i < 6:
j = 0
while j < 6:
print('*', end='')
j += 1
print('')
i += 1
```
##### 練習:
1. 使用者輸入一數字,然後畫面上輸出相同數量的*
2. [3, 9, 87, 168, 100],請使用while迴圈計算該list內元素總和。
3. 請使用while迴圈輸出完整的九九乘法表。
例如:
```
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
...
9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
```
抽籤範例:
```
import random
students = ['Aaron', 'Apple', 'Amber', 'Astrid', 'Andy', 'Abner', 'Alan']
while len(students) > 0:
print('參與學生: ', students)
input('輸入y開始抽:')
i = random.randint(0, len(students) - 1)
print("--------------------\n恭喜", students[i], "被抽中了!!\n--------------------\n")
del students[i]
print('結束了.')
```
### `for in` 迭代
如果想要從字串、list、tuple、set或是map中一個一個值取出來做處理(此作法又稱為迭代),可以使用for in迴圈。
格式:
> ```
> for 變數 in 要迭代的群集:
> 處理迭代出來的變數
> ...
> ```
例如迭代list:
```
data = [1, 2, 3]
for e in data:
print(e)
```
會輸出:
```
1
2
3
```
說明:
for in迴圈會迭代data群集變數裡的每個值,一個一個取出來,放到e這個變數裡,迴圈每跑一次就會取出一個值放到e變數。
```
print('for in --------------------------------------')
for x in a:
print('迭代:', x)
b = (3, 5, 6, 8, 9)
for x in b:
print('迭代tuple', x)
c = {'A': 0, 'B': 1, 'C': 2}
for x in c:
print('迭代map的keys', x)
for x in c.values():
print('迭代map的values', x)
for x, y in c.items():
print('迭代map', x, ':', y)
print('取出偶數----------------')
a = (1, 4, 99, 125, 88)
for b in a:
if b % 2 == 0:
print(b)
b = {3, 8, 8, 9}
total = 0
for x in b:
total += x
print(total)
```
##### range()函式
range()函式用來產生數字,格式為:
> ``` range(start, stop[, step])```
>
> start省略時預設為0,step省略時預設為1
例如:
```
range(5) # 產生0~5的數字
range(1, 6, 2) # 產生1, 3, 5
```
##### zip()函式
zip()函式用來將兩個序列內的元素,像拉鍊一樣一對一配對起來並產生一個新的list,每個配對的元素為tuple,例如:
```
a = [1, 2, 3]
b = ['one', 'two', 'three']
c = zip(a, b)
print(list(c))
```
會輸出:
```
[(1, 'one'), (2, 'two'), (3, 'three')]
```
```
a = ['小明', '小白', '小黃']
b = [200, 234, 278]
for item in zip(a, b):
print(item)
for name, grade in zip(a, b):
print(name, ' = ', grade)
```
輸出:
```
('小明', 200)
('小白', 234)
('小黃', 278)
小明 = 200
小白 = 234
小黃 = 278
```
學校有學生 小明, 小白, 小黃, 小花, 小A參加歌唱比賽,需要抽籤決定順序,請幫忙寫一程式來公平的決定順序
輸入範例:
```
小明 : 6
小白 : 2
小黃 : 3
小花 : 5
小A : 1
小莉 : 4
```
程式碼如下:
```
print('抽籤決定順序------------------------')
'''
'''
import random
students = ['小明', '小白', '小黃', '小花', '小A', '小莉']
seqs = list(range(1, len(students) + 1 ))
random.shuffle(seqs)
for name, seq in zip(students, seqs):
print(name, ': ', seq)
```
##### enumerate()函式
迭代時會產生序列的索引值,例如:
```
b = ['one', 'two', 'three']
for e in enumerate(b):
print(e)
```
結果為:
```
(0, 'one')
(1, 'two')
(2, 'three')
```
##### 練習
1. 請用迭代取出`a = [1, 4, 99, 125, 88]`並顯示在畫面上。
### 流程改變
#### `pass`
如果在某個程式碼區塊不想做任何事情,或是之後才會寫些程式碼,就可以先放個`pass`,例如:
```
if is_ok:
print('完成')
else:
pass
```
`pass`什麼事情都不會做,就只是用來維持程式碼結構的完整性。
#### `break`
用來跳離迴圈,迴圈內只要遇到`break`都會立即結束迴圈。
#### `continue`
用在迴圈內,在迴圈內只要遇到`continue`就會直接忽略迴圈內剩下的程式碼,馬上進行下一次的迴圈(或迭代)。
例如:
```
text = input('請輸入英文單字: ')
for t in text:
if t.isupper():
continue
print(t, end='')
```
會輸出:
```
請輸入英文單字: AbCdEf
bdf
```
範例:
```
print('pass------------------------------------')
a = 5
if a == 1:
print('好')
elif a == 2:
print('很好')
elif a == 3:
pass
elif a == 4:
print('可以')
else:
print('都行')
print('break & continue----------------------------------------')
a = 0
while a < 10:
a += 1
if a == 5:
break
print(a)
print('===')
a = 0
while a < 10:
a += 1
if a == 5:
continue
print(a)
while True:
a = input('請輸入quit結束迴圈')
if a == 'quit':
break
# 請將使用者輸入的字串過濾掉大寫
text = input('請輸入英文字串: ')
for c in text:
if c.isupper(): # 判斷c裡面的英文字是否為大寫
continue
print(c, end='')
```
### `for` Comprehension
##### 語法
```
[運算式 for 變數 in 群集 <if 條件運算式>]
```
將一個list經過計算轉換後存到另一個list是很常見的操作,Python針對這樣的動作提供了更簡潔的語法,for Comprehension。
例如:將一個list內的值全部平方
一般寫法:
```
a = [1, 2, 3, 4, 5]
b = []
for e in a:
b.append(e ** 2)
print(b)
```
輸出:
```
[1, 4, 9, 16, 25]
```
for Comprehension寫法:
```
a = [1, 2, 3, 4, 5]
b = [e ** 2 for e in a]
print(b)
```
##### 結合條件式
例如:取得list中的偶數存到新的list
原本的寫法:
```
a = [3, 7, 88, 123, 20, 204, 99]
b = []
for e in a:
if e % 2 == 0:
b.append(e)
print(b)
```
輸出:
```
[88, 20, 204]
```
for Comprehension寫法:
```
a = [3, 7, 88, 123, 20, 204, 99]
b = [e for e in a if e % 2 == 0]
print(b)
```
##### sum()函式
計算指定序列內數字的加總,例如:
```
a = sum([1, 2, 3])
print(a)
```
會得到6
##### 練習
1. 用一行程式碼,將[921, 834, 765]內的值全部減去100。
2. 有一班級學生成績為[87, 99, 31, 65, 42],請用一行程式碼完成將成績低於60分的分數顯示到畫面上。