---
# System prepended metadata

title: 221211 Python 聯課
tags: [code, Python]

---

###### tags: `Python` `code`
# 221211 Python 聯課

## 函數
- Python中用 `def` 來定義 (define) function
- function名稱習慣小寫，用底線 `_` 分隔
- 傳入的參數數量要和設定的一樣

基本上長這樣
```
def 名稱(參數):
    程式

# 呼叫
```

### 基本款
單純呼叫
```python=
def hi():
    print('hello world')
    
hi()
```

### 參數 Argument

#### 必須參數
```python=
def hi(n):
    print('Hello', n)
    
name = input('Name: ')
hi(name)
```

#### 關鍵字參數 Keyword Argument
- 好處：比較清楚自己要傳什麼資料
```python=
def hi(n):
    print('Hello', n)
    
name = input('Name: ')
hi(n=name)
```
#### 預設值參數 Default Argument
- 有傳就用來源端資料，沒有就用預設的
```python=
def hi(n="BB"):
  print('Hello', n)

name = input('Name: ')
hi(name)
```
:::success
**順序**：必須參數 -> 預設值參數
:::

### 回傳
傳參數後接收function回傳的資料
```python=
def plus(x):
    x = x+1
    return x
    
score = int(input('score ?'))
s = plus(score)
print('score:', s)
```


### 浮動長度參數

#### `＊args` 
- 將傳入的資料打包成一個tuple
```python=
def name(*name):
    print('hello', name)
    print(type(name), name)
    for n in name:
        print('hello', n)

name('Tinky Winky', 'Dipsy', 'Po', 'Laa-Laa')
```

#### `＊＊kwargs`
- 將傳入的資料打包成一個dict
- 傳參數的時候全部用類似關鍵字參數傳
- :warning:**只能放在最後**
```python=
def grade(**grade):
    print(type(grade), grade)

grade(exam1=100, exam2=60, exam3=54)
```

#### 小小要注意的地方：參數順序

通常浮動長度參數會寫在後面
```python=
def grade(name, *grade):
    print(name, grade)

grade('Dipsy', 20, 50, 64)
```
如果要寫在前面，後面的請一律用關鍵字參數傳遞
```python=
def grade(*grade, name):
    print(name, grade)

grade(20, 50, 64, name='Dipsy')
```
那我們看看這個範例
```python=
def grade(greeting='hi', *grade, name):
    print(greeting, name, grade)

grade(20, 50, 64, name='Dipsy')
```
第一個沒有傳的時候，程式會把20當作要給greeting的資料
有乖乖傳的話會正常執行，但這樣設定預設值參數的意義就消失了
```python=
def grade(greeting='hi', *grade, name):
    print(greeting, name, grade)

grade('hello', 20, 50, 64, name='Dipsy')
```
就變成都要設定關鍵字參數
```python=
def grade(*grade, greeting='hi', name):
    print(greeting, name, grade)

grade(20, 50, 64, name='Dipsy', greeting='hello')
```
如此一來，這裡的greeting有傳沒傳都會對
```python=
def grade(*grade, greeting='hi', name):
    print(greeting, name, grade)

grade(20, 50, 64, name='Dipsy')
```
:::success
**順序**：必須參數 -> *args -> 預設值參數 -> **kwargs
:::

### `global`

在function中**修改**函數未定義的變數時，要記得用`global`宣告
```python=
a = 1
def p():
  # global a
  print(a)
  a += 1
  print(a)

p()
```

---

## 亂數

一個例題講完全部
```python=
"""
# import 標準函式 "random"

# 隨機產生一個 x ~ y 間的整數
  random.randint(start, stop)
  
# 以step為間隔，隨機產生一個 x ~ y 間的整數
  random.randrange(start, stop, step)

# 從alist中隨機抽取一個元素
  random.choice(seq)
  *seq: In Python, sequence is the generic term for an ordered set.
        ex. string, list, tuple

# 從alist中隨機抽取n個元素(可能重複)
  random.choices(seq, n)

# 從alist中隨機抽取n個元素(不重複)
  random.choices(seq, n)

# 將alist中原本的元素順序打亂(洗牌)
  random.shuffle(alist)
"""
import random
alist = list(range(1, 50))

print('randint')
x = random.randint(1, 2)
print(x)

print('\nrandrange')
x = random.randrange(1, 100, 2)
print(x)

print('\nchoice')
a = random.choice(alist)
print(a)

print('\nchoices')
lst = random.choices(alist, k=6)
print(lst)

print('\nsample')
lst = random.sample(alist, 6)
print(lst)

print('\nbefore shuffle')
print(alist)
print('\nafter shuffle')
random.shuffle(alist)
print(alist)
```
還有另外一種import的方法
```python=
from random import randint

print('randint')
x = randint(1, 2)
print(x)
```

---
### 終極密碼
>提示：`while-loop` `random`
- 產生1~100的數字
- 猜數字，判斷比目標大或小
- 可以先將目標數字印出來，確認自己寫的判斷式是對的

進階
- 告訴他現在要猜的範圍
- 如果猜的數字不在範圍內就輸出錯誤
```python=
from random import randint

num = randint(1, 100)
x = 1
y = 100
print(num)
while True:
  print(f'{x} ~ {y}')
  your_num = int(input('> '))
  if your_num < x or your_num > y:
    print('範圍錯誤')
    continue
  if your_num == num:
    print('correct')
    break
  elif your_num > num:
    y = your_num-1
  elif your_num < num:
    x = your_num+1
```
---
### 販賣機
> 請善用function
> 這是個綜合測驗(連續題)，不會給全部的解答
> 以完成到第三關為基準
> 會定期下去巡，有問題/沒想法時，可以直接到前面找我

#### 第一關
- 三種飲料(價格)：紅茶(10)、奶茶(20)、可樂(25)
- 如果輸入不符，輸出錯誤訊息(程式碼已附上)
- 預設有100元，每次都詢問對方要什麼
- 無限購買，直到錢不夠時離開迴圈，並輸出剩餘金額
```python=
coin = 100
drink_price = {'1': 10, '2': 20, '3': 25}
while True:
  if coin <= 0:
    break
  drink = input('1.紅茶(10) 2.奶茶(20) 3.可樂(25)')[0]
  # print(drink)
  if drink not in '123':
    print('按錯了')
    continue
  price = drink_price[drink]

  if coin >= price:
    coin -= price
  else:
    break
print('$', coin)
```

#### 第二關
> 提示：`continue`
- 餘額不足時，輸出 "餘額不足"
- 新增儲值功能，輸入`c`時讓顧客投錢
- 用一個容器`drink_buy`紀錄顧客買過的飲料
- 無限購買，直到輸入`e`時離開迴圈，並輸出顧客買了哪些飲料
```python=
coin = 100
drink_buy = ?
while True:
    drink = input('1.紅茶(10) 2.奶茶(20) 3.可樂(25) c.儲值 e.離開')
    if drink not in '123ce':
        print('按錯了')
```

#### 第三關
> 提示：`function` `dict` `sorted` `sum` `choice` `random`
- define一個 `show()` 
    - 輸出餘額
    - 輸出總共有幾瓶飲料
    - 輸出目前買了什麼飲料，買最多的先輸出，一樣時按飲料名稱升冪
- 每買五瓶飲料，送一瓶飲料，送什麼隨機選
```python=
coin = 100
drink_buy = {'black_tea':0, 'milk_tea':0, 'coke':0}
def show():
    pass
while True:
    drink = input('1.紅茶(10) 2.奶茶(20) 3.可樂(25) c.儲值 e.離開')
    if drink not in '123ce':
        print('按錯了')
```
#### 第四關
> 提示：`count`
- 定義一個容器`drink_stock`紀錄庫存
- 每次問顧客要甚麼時，都要輸出剩餘數量
- 如果庫存不夠，就輸出"不夠了"
- 如果全部賣完就跳出迴圈
- 所以跳出迴圈的兩個條件：輸入`e` & 沒貨了

---
## 畫圖turtle

- 先開一個新的replit
- 搜尋python with turtle
- 檔名可以叫 `myturtle`

然後就會看到這個
```python=
"""
This is the Template Repl for Python with Turtle.

Python with Turtle lets you make graphics easily in Python.

Check out the official docs here: https://docs.python.org/3/library/turtle.html
"""

import turtle

t = turtle.Turtle()

for c in ['red', 'green', 'blue', 'yellow']:
    t.color(c)
    t.forward(75)
    t.left(90)
```
### 基本款
那我們來分析一下吧~

#### 匯入模組
將module import進來使用，*表示全部
```python=
from turtle import *
```

#### 設定

顏色：可以用內建顏色以及16進位制色碼
```python=
# 背景顏色
Screen().bgcolor('tomato')
Screen().bgcolor('#34d57f')
# 畫筆顏色
color('black')
# 畫筆粗細
pensize(2)
```
內建的顏色

![](https://i.imgur.com/5XHpugU.jpg)

[挑色碼&配色的好網站-colors](https://coolors.co/)

#### 基礎控制

```python=
# 前進 forward(distance)
forward(20)
# 畫圓 circle(radius, extent=?, steps=?)
# extent: The part of the circle in degrees as an arc.
# steps: Divide the shape in the equal number of given steps.
circle(30)
# turn left left(angle)
left(90)
forward(20)
# turn right right(angle)
right(90)
forward(20)
```
### 一些些例子
#### 封閉圖形 [Citation](https://ithelp.ithome.com.tw/articles/10297642?sc=iThelpR)
```python=
color('blue', 'red')
begin_fill()
circle(30)
end_fill()
```
#### 畫愛心
>大家可以去追蹤這個 [instagram帳號](https://www.instagram.com/pythonlearnerr/)
有不少python的東東，也很常出turtle的影片
我會想要教turtle也是因為這個帳號喔~
```python=
from turtle import *

color('black', 'hot pink')
begin_fill()
pensize(3)
left(50)
forward(133)
circle(50, extent=200)
right(140)
circle(50, extent=200)
forward(133)
end_fill()
```
>基本上這些參數都是一筆一筆試出來的，要很有耐心喔
>別忘了可以結合function和for-loops等幫助畫圖

---
#### Citation
[浮動長度參數](https://skylinelimit.blogspot.com/2018/04/python-args-kwargs.html)
[IT邦 turtle](https://ithelp.ithome.com.tw/articles/10297642?sc=iThelpR)
[turtle circle](https://www.geeksforgeeks.org/turtle-circle-method-in-python/)
[turtle example](https://www.instagram.com/pythonlearnerr/)

---
## 講一些數學觀念
![](https://i.imgur.com/ksSMCx4.jpg)
![](https://i.imgur.com/KKHxpxK.jpg)
![](https://i.imgur.com/ZT4DUSz.jpg)
![](https://i.imgur.com/h1BDuwW.jpg)