---
# System prepended metadata

title: 選擇結構
tags: [python]

---

# 選擇結構
###### tags: `python`

## Relational Operators 比較運算子
有六種比較運算子，他們運算的結果都會是`True`或是`False`。
`<` : 是否小於
`>` : 是否大於
`<=`: 是否小於等於
`>=`: 是否大於等於
`==`: 是否等於
`!=`: 是否不等於

例如 (3 < 2)是錯的，那麼這個運算就會得到 `False`的結果；(7 > 2)是對的，就會得到`True`。


## The if Statement

```python=
if(condition):
    do_something
```
```python=
if(condition):
    do_something
elif(condition2):
    do_something
```
```python=
if(condition):
    do_something
elif(condition2):
    do_something
else:
    do_something_else
```
`if`小括號內寫條件，若條件成立，則做冒號後面的事情。「同一個縮排」內可以做任何事情，甚至繼續寫`if`進行別的判斷也可以！
`elif`代表 else if，用`elif`的話，前者不成立，才會往下判斷，判斷到成立的，就不會繼續判斷了。
可以試試看連續使用`if`跟使用`if, elif`的差別。

### 倍數判斷
寫一個程式，判斷輸入的整數是否為2的倍數。
```flow
st=>start: Start
e=>end: 是2的倍數
cond=>condition: iNum%2 == 0?
iNum=>inputoutput: 輸入一個整數iNum
e2=>end: 不是2的倍數

st->iNum->cond
cond(yes)->e
cond(no)->e2
```




```python=
iNum = int(input())
if(iNum%2==0):
    print("%d是2的倍數" % iNum)
else:
    print("%d不是2的倍數" % iNum)
```

試試看，改編這個程式變成輸入兩個值，`n`, `iNum`。判斷`iNum`是否為`n`的倍數。


### 成績判斷
寫一個程式，判斷輸入的成績：
1. 60分以上，通過。
2. 40分以上，但不足60分，可以補考。
3. 未滿40分，不能補考，要重修。

```flow
in=>inputoutput: 輸入一個成績 score
cond1=>condition: score >= 60
cond2=>condition: score >= 40
ok=>end: 通過
補=>end: 可以補考
修=>end: 重修

in->cond1
cond1(yes)->ok
cond1(no)->cond2
cond2(yes)->補
cond2(no)->修
```
註：不是只有一種寫法哦！嘗試不同的流程圖，並做出不同的程式！

### BMI計算

```flow
in=>inputoutput: 輸入身高height、體重weight
cal=>operation: BMI=體重/身高平方
cond1=>condition: BMI低於18.5
cond2=>condition: BMI介於18.5至24
too_light=>end: 過輕
normal=>end: 正常
overweight=>end: 過重

in->cal->cond1
cond1(yes)->too_light
cond1(no)->cond2
cond2(yes)->normal
cond2(no)->overweight

```

```python=
height = 183
weight_now = 54
BMI = weight_now / (height/100) / (height/100)
print("%.2f" % (BMI))

# 18.5<=BMI<24
weight_low = 18.5*(height/100)*(height/100)
weight_high = 24*(height/100)*(height/100)

print("以身高%.2f公分而言，體重介於 %.2f 到 %.2f 之間是正常體重" % (height, weight_low, weight_high))
if(weight_now < weight_high and weight_now > weight_low):
  print("您的體重正常唷<3")
# else if
elif(weight_now < weight_low):
  print("你的體重過輕!快吃胖胖")
else(weight_now > weight_high):
  print("你的體重很不錯，繼續吃!")
```
試試看將身高、體重用`input()`讓使用者自行輸入！

## Logic Operators 邏輯運算子

在很多程式語言中，如果我們想要進行連續比較，例如 (1 < 2 < 3)，要將其拆開成 (1 < 2) 且 (2 < 3)。原因是，比較運算子也是一種二元運算，一次只能對兩個元進行運算，所以會先算(1 < 2)得到 true，但(true < 3) 沒辦法進行運算。
如果我們將其拆開就變成 (1 < 2)得到true， (2 < 3) 得到true，兩者同時都是true 所以結果為true。
沒錯，邏輯值可以與邏輯值進行運算，常見的運算是「or 或」 跟 「and 且」。
「或」只要一個對，就是對；「且」要兩者都對，才算對。

註：在Python中，可以直接連續寫哦！例如：`1 < 2 < 3`是`true`


| OR | T | F |
| -------- | -------- | -------- |
| T     | T     | T     |
|F|T|F|

|AND|T|F|
|-|-|-|
|T|T|F|
|F|F|F|

### 判斷是否為2且3的倍數
```python=
iNum = 60
if (iNum%2 == 0 and iNum%3 == 0):
    print("%d是2的倍數，也是3的倍數。")
elif (iNum%2 == 0):
    print("%d是2的倍數但不是3的倍數。")
elif (iNum%3 == 0):
    print("%d是3的倍數但不是2的倍數。")
else:
    print("%d不是2的倍數也不是3的倍數。")
```
- 試試看將`iNum`改成其他數字，如63、62、61，想想他們的差異。
- 如果把條件調換順序會發生什麼事？為什麼？

## 巢狀結構Nesetd Structure
`if`裡面完整地包含另一個`if`，我們就稱它作巢狀結構。

### Bad Practice
巢狀結構如果太多層會變得難以閱讀，像這個例子：
[心理測驗](https://colab.research.google.com/drive/1NH6ZnoWgo5ARn4XQXOX8_OvV2EXixLHv?usp=sharing)