# 2022-11-19 第三天 Python入門實作班上課記錄
###### tags: `python`
#### 猜數字
1. 隨機產生四個不重覆數字
2. 建立一個可以一直猜的迴圈
3. 一個用來記錄次數的變數
4. 接收使用者的輸入
5. 比對答案,並告知幾A幾B
6. 紀錄次數
7. 猜對離開,並顯示結果(猜了幾次)
```python=
import random
a = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
random.shuffle(a)
answer = a[0] + a[1] + a[2] + a[3]
print(f'答案是:{answer}')
guess_count = 0 # 紀錄猜了幾次
while True:
player = input('請猜一個四位數的數字(0~9),不可重複:')
guess_count += 1 # 增加猜的次數
# 判斷書入的是不是數字
try:
int(player)
except:
# print('輸入的不是數字,請重新猜')
raise Exception('亂猜,不能玩')
# 判斷是不是四個數字,如果不是,請使用者重猜
if len(player) != 4:
print('數字不四個,請重新猜')
continue
# 判斷數字有沒有重複(如果有重複,請使用者重猜)
if len(set(player)) > 4:
print('數字有重覆,請重新猜')
continue
# 猜對
if answer == player:
break
# 比較
how_many_A = 0
how_many_B = 0
# 比對有幾個A
if answer[0] == player[0]:
how_many_A += 1
if answer[1] == player[1]:
how_many_A += 1
if answer[2] == player[2]:
how_many_A += 1
if answer[3] == player[3]:
how_many_A += 1
if player[0] in answer and player[0] != answer[0]:
how_many_B += 1
if player[1] in answer and player[1] != answer[1]:
how_many_B += 1
if player[2] in answer and player[2] != answer[2]:
how_many_B += 1
if player[3] in answer and player[3] != answer[3]:
how_many_B += 1
print(f'{how_many_A}A{how_many_B}B, 你已經猜了{guess_count}次')
print(f'猜對了,總共猜了{guess_count}次')
```
> **進階練習:**
> 1. 判斷使用者輸入的數字是不是四個
> 2. 判斷使用者輸入的數字有沒有重覆
## 例外(exception)捕捉
```python=
# 例外(exception)捕捉
a = 0
try:
a = int(input('請輸入一個數字:'))
a /= 0
except ValueError: # 如果try裡面的程式碼都正常執行的話,except裡面的程式碼不會被執行
print('Ooops, 轉型失敗')
except ZeroDivisionError:
print('除數不能不能為0')
print(f'你輸入的數字是:{a}')
```
#### raise
```
raise Exception('Message')
```
raise可以用來產生一個例外,把程式中斷,通常只有在程式的錯誤無法被糾正的情況下。
#### 練習
1. 幫猜數字遊戲加上判斷使用者輸入如果不是數字,就請重猜。
## `range()`函式
`range()`用來產生一個連續整數
```
print(list(range(1, 10, 2)))
times = 0
while times < 10:
print('*', end='')
times += 1
print()
for i in range(10):
print('*', end='')
```
## 函式
建立函式,並傳入參數:
```python=
def compare(a1, a2): # 參數對於函式來說,就是函式內部的變數,外部無法存取
print(a1, a2)
compare(1, 2)
compare('a', 'b')
compare(True, False)
```
> **注意:**
> 1. 函式定義時有幾個參數,呼叫時就要傳入幾個參數
> 2. 函式需要被呼叫才會執行函式內的程式碼
#### 預設參數和指定參數
```python=
# 定義沒有參數的函式
def func1():
print('Hi')
print('World')
func1() # 呼叫函式
a = func1()
print('func1=', a)
def func2():
print('Hi')
print('World')
return 'OK' # 回傳資料給呼叫端
func2()
a = func2()
print('func2=', a)
# 預設參數
def my_func(a, b, c = '沒傳c', d = '沒傳d'):
print(f'a={a}')
print(f'b={b}')
print(f'c={c}')
print(f'd={d}')
my_func('t', 'e')
# 指定參數,傳入的參數順序可以跟定義不同
my_func(c = '1', d = '2', a = '3', b = '4')
print('test', end='')
```
#### 練習
1. 建立一個函式max, 傳入兩個整數參數,然後回傳較大的那個
```python=
def max(num1, num2):
if num1 > num2:
return num1
else:
return num2
a = max(222, 333)
print(a)
a = max(987, 654)
print(a)
```
2. 建立一個函式swap,傳入兩個參數後,交換順序回傳。
```python=
def swap(a1, a2):
return a2, a1 # ('apple', 'aaron')
a = 'aaron'
b = 'apple'
a, b = swap(a, b)
print(f'a={a}')
print(f'b={b}')
```
##
1. 寫一函式get_score:
- 有一個參數msg
- 呼叫input()並把msg給input當題示串
- 將input函式收到的字串轉成int型態
- 回傳轉型成int型態的整數
```python=
a = get_score('請輸入一個整數:')
print('你輸入的是:', a, type(a))
a = get_score('請再輸入一個整數:')
print('你輸入的是:', a, type(a))
```
2. 建立一個無窮迴圈,裡面呼叫get_score(),請把回傳的整數都存到一個叫data的list裡面。
```python=
def get_score(msg):
a = input(msg)
b = int(a)
return b
data = []
while True:
num = get_score('請輸入一個數字:')
data.append(num)
print(data)
```
3. 當使用者輸入非數字時,離開迴圈
```python=
def get_score(msg):
a = input(msg)
b = int(a)
return b
data = []
while True:
try:
num = get_score('請輸入一個數字:')
except:
break
data.append(num)
print(data)
```
4. 當離開迴圈後, 顯示:
- 最大值
- 最小值
- 最大奇數值
- 最小偶數值
- 平均值
```
def get_score(msg):
a = input(msg)
b = int(a)
return b
data = []
while True:
try:
num = get_score('請輸入一個數字:')
except:
break
data.append(num)
print(data)
print('目前的資料為:', data)
data.sort()
print('排序後資料為:', data)
print('最大數字為:', data[-1])
print('最小數字為:', data[0])
for n in data:
if n % 2 == 0:
print('最小偶數為:', n)
break
data = data[::-1]
for n in data:
if n % 2 == 1:
print('最大奇數為:', n)
break
print('平均值為:', sum(data) / len(data))
```
> **補充:**
> 最大奇數可以使用單行語法改寫:
> `print('最大奇數為:', [n for n in data[::-1] if n % 2 == 1][0])`
## 字串處理
- join
- replace
- split
- upper
- lower
- capitalize
- title
- strip
```
# - join
# - replace
# - split
# - upper
# - lower
# - capitalize # 字串第一個英文字母變大寫
# - title # 字串每一個英文單字第一個字母變大寫
# - strip
a = ' Aaron,test,123 '
b = '.'.join(a)
print(b)
b = a.replace('o', 'K')
print(b)
b = a.split(',')
print(b)
b = a.upper()
print(b)
b = a.lower()
print(b)
b = a.capitalize()
print(b)
b = a.title()
print(b)
b = a.strip()
print(b)
```
#### 練習
```python=
a = '2022年11月19日 23:00' # => 2022-11-18
b = a.replace('年', '-')
b = b.replace('月', '-')
b = b.replace('日', '')
b = b.split(' ')[0]
print(b)
```
或連續呼叫:
```python=
print(a.replace('年', '-').replace('月', '-').replace('日', '').split(' ')[0])
```
## 一級函式
```
def max(a1, a2):
if a1 > a2:
return a1
else:
return a2
a = max # 這裡沒有小括號
print(a(3, 7))
def a1():
print('Hi, I\'m Aaron')
def a2():
print('Hi, I\'m Andy')
def a3():
print('Hi, I\'m Andy')
def a4(x):
x()
a4(a1) # None
a4(a2)
a4(a3)
```
## LAMBDA
```python=
def max(a1, a2):
if a1 > a2:
return a1
else:
return a2
```
可以用lambda改寫:
```python=
max = lambda a1, a2: a1 if a1 > a2 else a2
```
呼叫方式跟函式一樣:
```python=
print(max(3, 4))
```
## 檔案處理
#### 寫入檔案
```python=
while True:
student = []
student.append(input('請輸入姓名:'))
student.append(input('請輸入國文成績:'))
student.append(input('請輸入英文成績:'))
student.append(input('請輸入數學成績:'))
with open('school.txt', 'a') as my_file:
my_file.write(','.join(student) + '\n')
```
#### 讀入檔案
```python=
with open('school.txt', 'r') as my_file:
for line in my_file:
student = line.replace('\n', '').split(',')
print(student)
```