---
# System prepended metadata

title: Python_cheatsheet
tags: [Python]

---



# 主題

[TOC]

---


## 1. **基本語法與變數**

```python=
a = 10        # int
b = 3.14      # float
c = float(a)  # convert to float
d = int(b)    # convert to int

is_active = True  # bool (Boolean)
is_closed = False

# Print multiple variables
print(a, b, is_active)

# Mathematical operators
x, y = 5, 2    # Assign multiple variables
print(x + y)   # Addition, output: 7
print(x - y)   # Subtraction, output: 3
print(x * y)   # Multiplication, output: 10
print(x / y)   # Division, output: 2.5
print(x // y)  # Floor division, output: 2
print(x % y)   # Modulus (remainder), output: 1
print(x ** y)  # Exponentiation (power), output: 25

# Assignment operators
x += 5    # same as x = x + 5
print(x)  # output: 10

# Checking variable types
print(type(a))  # <class 'int'>
print(type(b))  # <class 'float'>
print(type(is_active))  # <class 'bool'>
``` 


- **資料型別**: `int`, `float`, `str`, `bool`, `list`, `tuple`, `dict`, `set`
- **數學運算符**: `+`, `-`, `*`, `/`, `//` (整除), `%` (餘數), `**` (次方)

## 2. **條件判斷與邏輯運算**

```python
# Simple if-else statement
age = 18
if age >= 18:
    print("You are an adult.")
else:
    print("You are a minor.")

# Nested if-else statement
score = 85
if score >= 90:
    print("Grade: A")
elif score >= 80:
    print("Grade: B")
elif score >= 70:
    print("Grade: C")
else:
    print("Grade: F")

# Using 'and' and 'or' in logical conditions
is_student = True
is_employed = False

# Logical AND: both conditions must be True
if is_student and is_employed:
    print("You are a working student.")
else:
    print("You are either not a student or not employed.")

# Logical OR: one of the conditions must be True
if is_student or is_employed:
    print("You are either a student or employed.")
else:
    print("You are neither a student nor employed.")

# Using 'not' to negate a condition
has_access = False
if not has_access:
    print("Access denied.")

# Combining comparison and logical operators
salary = 4000
if salary > 3000 and salary < 5000:
    print("Your salary is between 3000 and 5000.")

# Ternary conditional operator (inline if-else)
x = 10
y = 20
max_value = x if x > y else y
print(f"The maximum value is {max_value}")  # Output: 20

# Checking multiple conditions using 'in'
day = "Saturday"
if day in ["Saturday", "Sunday"]:
    print("It's the weekend!")
else:
    print("It's a weekday.")

# Comparing strings
name = "Alice"
if name == "Alice":
    print("Hello, Alice!")
else:
    print("You are not Alice.")

# Using is to compare objects
a = [1, 2, 3]
b = a
if a is b:
    print("a and b are the same object.")  # True

c = [1, 2, 3]
if a is not c:
    print("a and c are not the same object.")  # True

# Chained comparison
number = 15
if 10 < number < 20:
    print("The number is between 10 and 20.")
```

## 3. **字串操作**

這裡是更多 **字串操作** 的範例程式碼，涵蓋各種常見的字串方法：

```python
# 字串連接
s1 = "Hello"
s2 = "World"
s3 = s1 + " " + s2
print(s3)  # Output: Hello World

# 重複字串
s4 = "Hi! " * 3
print(s4)  # Output: Hi! Hi! Hi! 

# 字串長度
s = "Python"
print(len(s))  # Output: 6

# 字串索引和切片
print(s[0])  # Output: P (first character)
print(s[-1])  # Output: n (last character)
print(s[1:4])  # Output: yth (slicing from index 1 to 3)

# 檢查子字串是否存在
text = "The quick brown fox"
print("quick" in text)  # Output: True
print("slow" not in text)  # Output: True

# 字串轉大小寫
s = "Hello Python"
print(s.lower())  # hello python
print(s.upper())  # HELLO PYTHON
print(s.title())  # Hello Python

# 去除前後空白
s = "   Python   "
print(s.strip())  # "Python"
print(s.lstrip())  # "Python   " (去除左邊空白)
print(s.rstrip())  # "   Python" (去除右邊空白)

# 字串替換
s = "I love Python"
new_s = s.replace("Python", "coding")
print(new_s)  # Output: I love coding

# 分割字串
sentence = "apple,banana,orange"
fruits = sentence.split(",")
print(fruits)  # Output: ['apple', 'banana', 'orange']

# 字串連接
fruits_joined = "-".join(fruits)
print(fruits_joined)  # Output: apple-banana-orange

# 字串是否為數字
num_str = "12345"
alpha_str = "abc123"
print(num_str.isdigit())  # Output: True
print(alpha_str.isdigit())  # Output: False

# 字串是否為字母
print(alpha_str.isalpha())  # Output: False (因為包含數字)
print("abc".isalpha())  # Output: True

# 開頭與結尾檢查
s = "Python programming"
print(s.startswith("Python"))  # Output: True
print(s.endswith("ing"))  # Output: True

# 轉換字串為list每個字元
s = "Hello"
char_list = list(s)
print(char_list)  # Output: ['H', 'e', 'l', 'l', 'o']

# 找出子字串的位置
index = s.find("lo")
print(index)  # Output: 3

# 字串格式化 (舊方式)
name = "Alice"
age = 25
print("My name is %s and I am %d years old." % (name, age))  # Output: My name is Alice and I am 25 years old.

# 字串格式化 (新方式 - f-strings)
print(f"My name is {name} and I am {age} years old.")  # Output: My name is Alice and I am 25 years old.

# 檢查是否為大寫或小寫
print("HELLO".isupper())  # Output: True
print("hello".islower())  # Output: True

# 反轉字串
s = "Python"
reversed_s = s[::-1]
print(reversed_s)  # Output: nohtyP
```

## 4. **迴圈**

這裡是更多關於 **迴圈** 的範例，涵蓋了 `for` 和 `while` 迴圈的多種用法，包括 `break`、`continue`、`else` 和 `pass` 等結構：

```python
# 基本的 for 迴圈
for i in range(5):
    print(i)
# Output: 0, 1, 2, 3, 4

# 基本的 while 迴圈
count = 0
while count < 5:
    print(count)
    count += 1
# Output: 0, 1, 2, 3, 4

# 使用 break 終止迴圈
for i in range(10):
    if i == 5:
        break  # 當 i 等於 5 時，終止迴圈
    print(i)
# Output: 0, 1, 2, 3, 4

# 使用 continue 跳過本次迴圈的剩餘部分
for i in range(5):
    if i == 2:
        continue  # 當 i 等於 2 時，跳過該次迴圈
    print(i)
# Output: 0, 1, 3, 4

# 使用 else 配合 for 迴圈 (當迴圈完整執行後執行 else)
for i in range(3):
    print(i)
else:
    print("Loop completed.")
# Output: 0, 1, 2
#         Loop completed.

# 使用 else 配合 break 結構 (else 只在未遇到 break 時執行)
for i in range(5):
    if i == 3:
        break
    print(i)
else:
    print("This won't be printed.")
# Output: 0, 1, 2

# 迴圈中使用 pass (佔位符，不執行任何操作)
for i in range(5):
    if i == 3:
        pass  # 佔位符，什麼都不做
    print(i)
# Output: 0, 1, 2, 3, 4

# 巢狀迴圈 (Nested Loops)
for i in range(3):
    for j in range(2):
        print(f"i: {i}, j: {j}")
# Output: 
# i: 0, j: 0
# i: 0, j: 1
# i: 1, j: 0
# i: 1, j: 1
# i: 2, j: 0
# i: 2, j: 1

# 使用 range() 的不同參數
for i in range(1, 10, 2):  # 起始點 1，結束點 10，步長 2
    print(i)
# Output: 1, 3, 5, 7, 9

# 遍歷 list
my_list = ["apple", "banana", "cherry"]
for fruit in my_list:
    print(fruit)
# Output: apple, banana, cherry

# 使用 enumerate() 同時取得索引與值
for index, fruit in enumerate(my_list):
    print(f"Index {index}: {fruit}")
# Output:
# Index 0: apple
# Index 1: banana
# Index 2: cherry

# 反向迴圈
for i in reversed(range(5)):
    print(i)
# Output: 4, 3, 2, 1, 0

# 遍歷字典
my_dict = {"name": "Alice", "age": 25}
for key, value in my_dict.items():
    print(f"{key}: {value}")
# Output:
# name: Alice
# age: 25

# 無限迴圈 (while loop) - 小心使用！
# while True:
#     print("This will print forever unless broken!")

# 使用 break 停止無限迴圈
i = 0
while True:
    if i >= 5:
        break  # 當 i 等於或大於 5 時，結束迴圈
    print(i)
    i += 1
# Output: 0, 1, 2, 3, 4

# 使用 continue 在 while 迴圈中跳過本次迴圈
i = 0
while i < 5:
    i += 1
    if i == 3:
        continue  # 跳過 i 等於 3 的這次迴圈
    print(i)
# Output: 1, 2, 4, 5
```


## 5. **函式**

這裡是各種 **函式** 的範例，涵蓋了 **無回傳值、有回傳值、有參數、參數預設值、`*args`、`**kwargs`、巢狀函式** 等等情況：

```python
# 1. 無回傳值的函式
def greet():
    print("Hello, World!")

greet()  # Output: Hello, World!

# 2. 有回傳值的函式
def add(a, b):
    return a + b

result = add(2, 3)
print(result)  # Output: 5

# 3. 有參數的函式
def multiply(x, y):
    return x * y

print(multiply(4, 5))  # Output: 20

# 4. 有參數預設值的函式
def greet_person(name="Guest"):
    print(f"Hello, {name}!")

greet_person()        # Output: Hello, Guest!
greet_person("Alice") # Output: Hello, Alice!

# 5. 可變參數 *args (接收多個參數，會形成 tuple)
def sum_all(*args):
    total = 0
    for num in args:
        total += num
    return total

print(sum_all(1, 2, 3, 4, 5))  # Output: 15

# 6. 可變關鍵字參數 **kwargs (接收多個命名參數，會形成 dict)
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, job="Engineer")
# Output:
# name: Alice
# age: 30
# job: Engineer

# 7. 巢狀函式 (函式中定義函式)
def outer_function(text):
    def inner_function():
        print(f"Inner function: {text}")
    inner_function()

outer_function("Hello from outer function!")
# Output: Inner function: Hello from outer function!

# 8. 使用巢狀函式閉包 (Closure)
def outer_closure(msg):
    def inner_closure():
        print(f"Message: {msg}")
    return inner_closure

# 這時候 outer_closure() 回傳 inner_closure 函式，並記住了 msg 的值
my_func = outer_closure("This is a closure example")
my_func()  # Output: Message: This is a closure example

# 9. 函式回傳多個值
def get_stats(a, b):
    sum_value = a + b
    diff_value = a - b
    return sum_value, diff_value

sum_result, diff_result = get_stats(10, 5)
print(f"Sum: {sum_result}, Difference: {diff_result}")
# Output: Sum: 15, Difference: 5

# 10. 函式作為參數傳遞 (高階函式)
def apply_function(func, x, y):
    return func(x, y)

def subtract(a, b):
    return a - b

print(apply_function(subtract, 10, 5))  # Output: 5

# 11. 匿名函式 (Lambda)
square = lambda x: x ** 2
print(square(5))  # Output: 25

# Lambda 與高階函式配合使用
nums = [1, 2, 3, 4, 5]
squared_nums = list(map(lambda x: x ** 2, nums))
print(squared_nums)  # Output: [1, 4, 9, 16, 25]
```


## 6. **容器**

這裡是關於 **list**、**dict**、**set**、**tuple** 的詳細程式碼範例，涵蓋了 **indexing**、**slicing**、是否可變（mutable）、是否可迭代（iterable）等性質：

```python
# List: Mutable, Ordered, Iterable
my_list = [1, 2, 3, 4, 5]

# Indexing and slicing
print(my_list[0])      # Output: 1 (first element)
print(my_list[-1])     # Output: 5 (last element)
print(my_list[1:4])    # Output: [2, 3, 4] (slice from index 1 to 3)

# Modifying elements (mutable)
my_list[2] = 10
print(my_list)  # Output: [1, 2, 10, 4, 5]

# Adding elements
my_list.append(6)       # Add to the end
my_list.insert(2, 7)    # Insert at index 2
print(my_list)  # Output: [1, 2, 7, 10, 4, 5, 6]

# Removing elements
my_list.remove(10)      # Remove first occurrence of 10
popped_value = my_list.pop(3)  # Remove element at index 3
print(popped_value)     # Output: 4 (popped element)
print(my_list)          # Output: [1, 2, 7, 5, 6]

# Iterating over a list
for item in my_list:
    print(item)
# Output: 1, 2, 7, 5, 6

# List comprehension
squared_list = [x**2 for x in my_list]
print(squared_list)  # Output: [1, 4, 49, 25, 36]


# Tuple: Immutable, Ordered, Iterable
my_tuple = (1, 2, 3, 4, 5)

# Indexing and slicing
print(my_tuple[0])      # Output: 1
print(my_tuple[-1])     # Output: 5
print(my_tuple[1:4])    # Output: (2, 3, 4)

# Cannot modify elements (immutable)
# my_tuple[2] = 10  # This will raise a TypeError

# Tuple with one element
single_element_tuple = (1,)
print(single_element_tuple)  # Output: (1,)

# Tuple packing and unpacking
packed_tuple = 1, 2, 3  # Tuple packing without parentheses
a, b, c = packed_tuple  # Tuple unpacking
print(a, b, c)          # Output: 1 2 3

# Iterating over a tuple
for item in my_tuple:
    print(item)
# Output: 1, 2, 3, 4, 5


# Dictionary: Mutable, Unordered, Iterable (keys, values, items)
my_dict = {"name": "Alice", "age": 25, "job": "Engineer"}

# Accessing elements by key
print(my_dict["name"])      # Output: Alice
print(my_dict.get("age"))   # Output: 25

# Adding/Modifying elements
my_dict["age"] = 30         # Modify the value of an existing key
my_dict["city"] = "New York"  # Add a new key-value pair
print(my_dict)  # Output: {'name': 'Alice', 'age': 30, 'job': 'Engineer', 'city': 'New York'}

# Removing elements
del my_dict["city"]          # Remove a key-value pair
removed_value = my_dict.pop("job")  # Remove and return the value of the key 'job'
print(removed_value)         # Output: Engineer
print(my_dict)               # Output: {'name': 'Alice', 'age': 30}

# Iterating over a dictionary
# Iterate over keys
for key in my_dict:
    print(key)
# Output: name, age

# Iterate over values
for value in my_dict.values():
    print(value)
# Output: Alice, 30

# Iterate over key-value pairs
for key, value in my_dict.items():
    print(f"{key}: {value}")
# Output: name: Alice, age: 30

# Dictionary comprehension
squared_dict = {x: x**2 for x in range(5)}
print(squared_dict)  # Output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}


# Set: Mutable, Unordered, Iterable, No Duplicates
my_set = {1, 2, 3, 4, 5}

# Adding elements
my_set.add(6)
print(my_set)  # Output: {1, 2, 3, 4, 5, 6}

# Removing elements
my_set.remove(4)  # Raises KeyError if element not found
my_set.discard(10)  # Does not raise an error if element not found
print(my_set)  # Output: {1, 2, 3, 5, 6}

# Set operations
another_set = {5, 6, 7, 8}

# Union: All unique elements from both sets
union_set = my_set | another_set
print(union_set)  # Output: {1, 2, 3, 5, 6, 7, 8}

# Intersection: Elements common to both sets
intersection_set = my_set & another_set
print(intersection_set)  # Output: {5, 6}

# Difference: Elements in my_set but not in another_set
difference_set = my_set - another_set
print(difference_set)  # Output: {1, 2, 3}

# Symmetric Difference: Elements in either set, but not both
symmetric_diff_set = my_set ^ another_set
print(symmetric_diff_set)  # Output: {1, 2, 3, 7, 8}

# Iterating over a set
for item in my_set:
    print(item)
# Output: 1, 2, 3, 5, 6

# Set comprehension
squared_set = {x**2 for x in range(5)}
print(squared_set)  # Output: {0, 1, 4, 9, 16}


# Comparisons:
print(isinstance(my_list, list))  # Output: True (my_list is a list)
print(isinstance(my_tuple, tuple))  # Output: True (my_tuple is a tuple)
print(isinstance(my_dict, dict))  # Output: True (my_dict is a dictionary)
print(isinstance(my_set, set))  # Output: True (my_set is a set)

# Mutable vs Immutable
# List, Dictionary, Set are mutable
my_list[0] = 99
my_dict["name"] = "Bob"
my_set.add(10)
print(my_list, my_dict, my_set)  # Mutations are allowed

# Tuple is immutable
# my_tuple[0] = 99  # This will raise a TypeError

# Iterable: All these types are iterable
for i in my_list:
    print(i)  # Output: Iterates over list elements

for i in my_tuple:
    print(i)  # Output: Iterates over tuple elements

for i in my_dict:
    print(i)  # Output: Iterates over dictionary keys

for i in my_set:
    print(i)  # Output: Iterates over set elements
```

#### **特性總結**：
- **List**: 可變（Mutable）、有序（Ordered）、可迭代（Iterable）
- **Tuple**: 不可變（Immutable）、有序（Ordered）、可迭代（Iterable）
- **Dictionary**: 可變（Mutable）、無序（Unordered）、可迭代（Iterable, 針對 keys, values, items）
- **Set**: 可變（Mutable）、無序（Unordered）、可迭代（Iterable），且元素不重複

這些範例展示了每種容器類型的主要操作、是否可變以及是否可迭代，並展示了它們的 **indexing**、**slicing**、元素操作和集合操作等特性。

## 7. **例外處理**

這裡是更多關於 **例外處理** 的範例程式碼，涵蓋了基本的 `try-except`、捕捉多個例外、`else` 和 `finally` 區塊、自定義例外、嵌套例外處理等：

```python
# 基本的 try-except 結構
try:
    x = 10 / 0
except ZeroDivisionError as e:
    print(f"Error occurred: {e}")
# Output: Error occurred: division by zero

# 捕捉多個例外
try:
    num = int(input("Enter a number: "))  # 可能會丟出 ValueError
    result = 10 / num                     # 可能會丟出 ZeroDivisionError
except ValueError as ve:
    print(f"Invalid input: {ve}")
except ZeroDivisionError as zde:
    print(f"Cannot divide by zero: {zde}")
# 當輸入不是數字或除以0時會顯示對應的錯誤訊息

# 使用 else：當沒有發生例外時執行
try:
    num = int(input("Enter a non-zero number: "))
    result = 10 / num
except ZeroDivisionError:
    print("Cannot divide by zero.")
except ValueError:
    print("Invalid input.")
else:
    print(f"Division successful, result is: {result}")
# 當除法成功時，else 區塊會執行

# 使用 finally：無論有沒有發生例外，finally 都會執行
try:
    file = open("example.txt", "r")
    data = file.read()
except FileNotFoundError as fnfe:
    print(f"File not found: {fnfe}")
finally:
    print("Closing file.")
    # 假設有開啟的檔案，這裡可以放置 file.close() 來確保檔案會被正確關閉
# Output: Closing file. （無論檔案是否存在）
```

### 說明：
1. **try-except** 基本結構：用於捕捉例外，並在發生例外時執行特定的處理邏輯。
2. **捕捉多個例外**：可以根據不同的例外類型來定義不同的 `except` 區塊。
3. **else 區塊**：當沒有發生例外時執行。
4. **finally 區塊**：無論有無發生例外，`finally` 區塊的程式碼都會被執行，常用於釋放資源（如關閉檔案）。

## 8. **Numpy 使用範例**

這裡是更多 **Numpy 使用範例** 的程式碼，涵蓋了 **基本陣列操作、常見的數學運算、陣列變形、隨機數生成、統計計算、條件選擇、線性代數運算** 等常見操作：

```python=
import numpy as np

# 創建陣列
arr = np.array([1, 2, 3, 4, 5])
print(arr)  # Output: [1 2 3 4 5]

# 創建多維陣列
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix)
# Output:
# [[1 2 3]
#  [4 5 6]]

# 創建特殊陣列
zeros = np.zeros((3, 3))  # 3x3 全零矩陣
ones = np.ones((2, 4))    # 2x4 全一矩陣
identity = np.eye(3)      # 3x3 單位矩陣
full_matrix = np.full((2, 2), 7)  # 2x2 每個元素為7的矩陣
print(zeros)
print(ones)
print(identity)
print(full_matrix)

# 使用 arange 和 linspace 生成數列
arr_arange = np.arange(0, 10, 2)  # 生成 0 到 10 之間的數字，間隔為 2
arr_linspace = np.linspace(0, 1, 5)  # 生成 0 到 1 之間 5 個等間距數字
print(arr_arange)  # Output: [0 2 4 6 8]
print(arr_linspace)  # Output: [0.   0.25 0.5  0.75 1. ]

# 陣列形狀與變形
arr_reshaped = np.reshape(matrix, (3, 2))  # 重塑 2x3 矩陣為 3x2
print(arr_reshaped)
# Output:
# [[1 2]
#  [3 4]
#  [5 6]]

# 也可以使用 .reshape() 或 .resize() 來變形陣列

# 基本陣列運算
arr = np.array([1, 2, 3, 4])
print(arr + 10)  # 每個元素加 10，Output: [11 12 13 14]
print(arr * 2)   # 每個元素乘 2，Output: [2 4 6 8]
print(arr ** 2)  # 每個元素平方，Output: [ 1  4  9 16]

# 陣列之間的運算
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print(arr1 + arr2)  # Output: [5 7 9]
print(arr1 * arr2)  # Output: [ 4 10 18] (element-wise)

# 陣列的索引與切片
arr = np.array([10, 20, 30, 40, 50])
print(arr[0])       # Output: 10 (第一個元素)
print(arr[1:4])     # Output: [20 30 40] (從索引 1 到 3 的元素)
arr[1:3] = 100      # 改變索引 1 和 2 的值
print(arr)          # Output: [ 10 100 100  40  50]

# 多維陣列的索引
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix[0, 2])  # Output: 3 (第一列第三個元素)
print(matrix[:, 1])  # Output: [2 5] (所有行的第二列元素)

# 隨機數生成
random_arr = np.random.rand(3, 3)  # 生成 3x3 的隨機數矩陣（範圍 [0, 1] 之間）
random_int_arr = np.random.randint(0, 10, size=(2, 2))  # 生成 2x2 隨機整數矩陣
print(random_arr)
print(random_int_arr)

# 隨機打亂陣列
shuffled_arr = np.random.permutation(arr)
print(shuffled_arr)  # 隨機打亂 arr 中的元素

# 統計運算
arr = np.array([1, 2, 3, 4, 5])
print(np.mean(arr))  # 平均值，Output: 3.0
print(np.sum(arr))   # 總和，Output: 15
print(np.std(arr))   # 標準差，Output: 1.4142135623730951
print(np.min(arr))   # 最小值，Output: 1
print(np.max(arr))   # 最大值，Output: 5

# 矩陣運算
matrix = np.array([[1, 2], [3, 4]])
print(np.transpose(matrix))  # 矩陣轉置
print(np.linalg.inv(matrix))  # 矩陣求逆

# 點積 (dot product)
vec1 = np.array([1, 2])
vec2 = np.array([3, 4])
dot_product = np.dot(vec1, vec2)
print(dot_product)  # Output: 11 (1*3 + 2*4)

# 矩陣相乘 (Matrix multiplication)
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])
matrix_mult = np.dot(matrix1, matrix2)
print(matrix_mult)
# Output:
# [[19 22]
#  [43 50]]

# 使用條件選擇元素
arr = np.array([10, 20, 30, 40, 50])
print(arr[arr > 25])  # Output: [30 40 50] (選擇大於 25 的元素)

# 使用 np.where 作為條件運算
arr = np.array([1, 2, 3, 4, 5])
result = np.where(arr > 3, arr, -1)  # 如果大於 3，保留原值，否則設為 -1
print(result)  # Output: [-1 -1 -1  4  5]

# 陣列展平
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
arr_flattened = arr_2d.ravel()  # 將 2D 陣列展平成 1D 陣列
print(arr_flattened)  # Output: [1 2 3 4 5 6]

# 堆疊陣列
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr_vstack = np.vstack((arr1, arr2))  # 垂直堆疊
arr_hstack = np.hstack((arr1, arr2))  # 水平堆疊
print(arr_vstack)
# Output:
# [[1 2 3]
#  [4 5 6]]
print(arr_hstack)  # Output: [1 2 3 4 5 6]

# 分割陣列
arr = np.array([1, 2, 3, 4, 5, 6])
split_arr = np.split(arr, 3)  # 將陣列分割成 3 個部分
print(split_arr)  # Output: [array([1, 2]), array([3, 4]), array([5, 6])]

# Broadcasting 範例 (自動擴展)
arr = np.array([1, 2, 3])
matrix = np.array([[1, 2, 3], [4, 5, 6]])
result = matrix + arr  # arr 自動擴展為 [[1, 2, 3], [1, 2, 3]]
print(result)
# Output:
# [[2 4 6]
#  [5 7 9]]

# 生成對角矩陣
diag_matrix = np.diag([1, 2, 3])
print(diag_matrix)
# Output:
# [[1 0 0]
#  [0 2 0]
#  [0 0 3]]

# 使用 meshgrid 生成網格點 (常用於繪圖)
x = np.linspace(0, 1, 3)
y = np.linspace(0, 1, 3)
X, Y = np.meshgrid(x, y)
print(X)
print(Y)
# Output:
# X: [[0.  0.5 1. ]
#     [0.  0.5 1. ]
#     [0.  0.5 1. ]]
# Y: [[0.  0.  0. ]
#     [0.5 0.5 0.5]
#     [1.  1.  1. ]]
```

### **說明**：
- **陣列生成**：使用 `np.array()`、`np.zeros()`、`np.ones()`、`np.eye()` 等方法生成不同類型的陣列。
- **陣列運算**：支援加減乘除、指數運算、矩陣點積等。
- **隨機數生成**：使用 `np.random` 生成隨機數矩陣、整數等。
- **統計運算**：如 `mean`、`sum`、`std` 等可對陣列進行統計計算。
- **矩陣運算**：包含轉置、逆矩陣、矩陣乘法等操作。
- **條件運算**：使用 `np.where()` 或條件索引進行篩選操作。
- **陣列變形與展平**：使用 `reshape()`、`ravel()` 等來調整陣列形狀。
- **陣列堆疊與分割**：可使用 `vstack()`、`hstack()`、`split()` 對陣列進行堆疊與分割。


```python
# 條件運算
filtered = arr[arr > 1]  # 篩選大於1的元素
```

### 9. **Pandas 使用範例** (強調部分)
這裡是更多 **Pandas** 使用範例的程式碼，涵蓋了 **DataFrame** 和 **Series** 的基本操作、資料讀取與匯出（如 `to_csv` 和 `read_html`）、資料篩選、處理缺失值、數據統計等常見操作。

### **Pandas 基礎介紹**

```python
import pandas as pd

# 創建 Series（單一欄位的資料結構）
s = pd.Series([1, 3, 5, 7, 9])
print(s)
# Output:
# 0    1
# 1    3
# 2    5
# 3    7
# 4    9
# dtype: int64

# 創建 DataFrame（多欄位的資料結構）
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'San Francisco', 'Los Angeles']
}
df = pd.DataFrame(data)
print(df)
# Output:
#       Name  Age           City
# 0    Alice   25       New York
# 1      Bob   30  San Francisco
# 2  Charlie   35    Los Angeles

# 讀取某欄的資料（Series）
print(df['Name'])
# Output:
# 0      Alice
# 1        Bob
# 2    Charlie
# Name: Name, dtype: object
```

### **DataFrame 操作**

```python
# 新增一欄資料
df['Salary'] = [50000, 60000, 70000]
print(df)
# Output:
#       Name  Age           City  Salary
# 0    Alice   25       New York   50000
# 1      Bob   30  San Francisco   60000
# 2  Charlie   35    Los Angeles   70000

# 刪除一欄資料
df = df.drop(columns=['Salary'])
print(df)

# 選擇特定列
print(df.loc[1])  # 使用 loc 根據標籤選取（行標籤 1）
# Output:
# Name                 Bob
# Age                   30
# City       San Francisco
# Name: 1, dtype: object

# 選擇特定多列
print(df.loc[[0, 2]])  # 選擇第 0 和第 2 行

# 使用 iloc 根據索引選取
print(df.iloc[1])  # 使用 iloc 根據數字索引選取
# Output:
# Name                 Bob
# Age                   30
# City       San Francisco
# Name: 1, dtype: object

# 選取特定範圍
print(df.iloc[0:2])  # 選取第一行和第二行

# 篩選資料
filtered_df = df[df['Age'] > 25]  # 篩選年齡大於 25 的資料
print(filtered_df)

# 修改資料
df.at[1, 'City'] = 'Chicago'  # 修改某一個值
print(df)

# 檢查是否有缺失值
print(df.isnull())  # 檢查缺失值
```

### **處理缺失值**

```python
# 創建包含缺失值的 DataFrame
data_with_nan = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, None, 35, 40],
    'City': ['New York', 'San Francisco', None, 'Chicago']
}
df_nan = pd.DataFrame(data_with_nan)

# 檢查缺失值
print(df_nan.isnull())
# Output: 顯示 True 表示缺失值，False 表示非缺失值

# 填補缺失值
df_nan_filled = df_nan.fillna('Unknown')  # 用 'Unknown' 填補所有缺失值
print(df_nan_filled)

# 移除有缺失值的列
df_nan_dropped = df_nan.dropna()  # 刪除包含缺失值的列
print(df_nan_dropped)
```

### **資料讀取與匯出**

```python
# 從 CSV 讀取資料
df_from_csv = pd.read_csv('data.csv')
print(df_from_csv)

# 匯出 DataFrame 為 CSV
df.to_csv('output.csv', index=False)  # index=False 代表不匯出索引欄位

# 從 Excel 讀取資料
df_from_excel = pd.read_excel('data.xlsx', sheet_name='Sheet1')
print(df_from_excel)

# 從 HTML 表格讀取資料
html_tables = pd.read_html('https://example.com')
print(html_tables[0])  # 如果有多個表格，選擇第一個

# 匯出 DataFrame 為 Excel
df.to_excel('output.xlsx', index=False)
```

### **統計與數據分析**

```python
# 統計摘要
print(df.describe())
# Output:
#              Age
# count   3.000000
# mean   30.000000
# std     5.000000
# min    25.000000
# 25%    27.500000
# 50%    30.000000
# 75%    32.500000
# max    35.000000

# 計算每個欄位的平均值
print(df['Age'].mean())  # Output: 30.0

# 計算總和
print(df['Age'].sum())  # Output: 90

# 計算唯一值
print(df['City'].unique())  # Output: ['New York', 'San Francisco', 'Chicago']

# 計算每個值出現的次數
print(df['City'].value_counts())
# Output:
# New York         1
# San Francisco    1
# Chicago          1
# Name: City, dtype: int64
```

### **資料操作**

```python
# 排序
df_sorted = df.sort_values(by='Age', ascending=False)  # 根據 Age 排序
print(df_sorted)

# groupby 操作
grouped_df = df.groupby('City').mean()  # 根據 City 分組，計算平均值
print(grouped_df)

# 合併 DataFrame
data1 = {'ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie']}
data2 = {'ID': [1, 2, 4], 'Salary': [50000, 60000, 70000]}
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)

# 使用 merge 來合併兩個 DataFrame
merged_df = pd.merge(df1, df2, on='ID', how='inner')  # 內部連接 (inner join)
print(merged_df)
# Output:
#    ID     Name  Salary
# 0   1    Alice   50000
# 1   2      Bob   60000

# Left join
merged_left = pd.merge(df1, df2, on='ID', how='left')
print(merged_left)
# Output:
#    ID     Name   Salary
# 0   1    Alice  50000.0
# 1   2      Bob  60000.0
# 2   3  Charlie      NaN
```

### **Pandas 其他進階操作**

```python
# 計算 rolling average（移動平均）
df['Age_rolling_avg'] = df['Age'].rolling(window=2).mean()
print(df)
# Output:
#       Name   Age           City  Age_rolling_avg
# 0    Alice  25.0       New York              NaN
# 1      Bob  30.0      San Francisco           27.5
# 2  Charlie  35.0        Chicago              32.5

# 使用 apply 將函數應用到每個元素
df['Age_squared'] = df['Age'].apply(lambda x: x ** 2)
print(df)
# Output:
#       Name   Age           City  Age_squared
# 0    Alice  25.0       New York        625.0
# 1      Bob  30.0      San Francisco     900.0
# 2  Charlie  35.0        Chicago       1225.0

# Pivot Table
pivot_df = df.pivot_table(values='Age', index='City', aggfunc='mean')
print(pivot_df)
# Output:
#                    Age
# City                  
# Chicago           35.0
# New York          25.0
# San Francisco     30.0
```

### **特性總結**：
- **Series** 是一個一維陣列，包含數值和標籤（索引）。
- **DataFrame** 是一個表格結構，包含多個 **Series**，每欄位擁有相同的索引。
- Pandas 提供了豐富的資料處理功能

，包括 **讀取與匯出資料**（如 CSV、Excel、HTML）、**資料篩選與處理缺失值**、**統計運算與分析**，以及各種 **進階資料操作**。

這些範例展示了 **Pandas** 的多種操作方式，適用於日常的資料處理與分析工作。

### 10. **Matplotlib 基本繪圖**

這裡是更多 **Matplotlib** 使用範例，涵蓋了 **折線圖、散佈圖、長條圖、直方圖** 以及其他基本繪圖技巧。

#### **基本設定**

```python
import matplotlib.pyplot as plt
import numpy as np

# 基本設置（設置風格）
plt.style.use('seaborn-darkgrid')  # 可選擇不同風格
```

### **折線圖 (Line Plot)**

```python
# 創建數據
x = np.linspace(0, 10, 100)  # 從 0 到 10 生成 100 個等間距點
y = np.sin(x)

# 繪製折線圖
plt.plot(x, y, label='sin(x)', color='b')  # 設置線條顏色為藍色
plt.title("Sine Wave")  # 設置標題
plt.xlabel("X Axis")  # 設置 x 軸標籤
plt.ylabel("Y Axis")  # 設置 y 軸標籤
plt.legend()  # 顯示圖例
plt.grid(True)  # 顯示網格線
plt.show()
```

#### **散佈圖 (Scatter Plot)**

```python
# 創建隨機數據
np.random.seed(0)
x = np.random.rand(50)
y = np.random.rand(50)
colors = np.random.rand(50)  # 每個點不同的顏色
sizes = 1000 * np.random.rand(50)  # 每個點不同的大小

# 繪製散佈圖
plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
plt.colorbar()  # 顯示顏色條
plt.title("Random Scatter Plot")
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.show()
```

#### **長條圖 (Bar Chart)**

```python
# 創建數據
categories = ['A', 'B', 'C', 'D', 'E']
values = [5, 7, 3, 8, 6]

# 繪製水平長條圖
plt.bar(categories, values, color='skyblue')  # 可選擇顏色
plt.title("Bar Chart Example")
plt.xlabel("Categories")
plt.ylabel("Values")
plt.show()

# 繪製水平長條圖
plt.barh(categories, values, color='lightgreen')  # 水平長條圖
plt.title("Horizontal Bar Chart Example")
plt.xlabel("Values")
plt.ylabel("Categories")
plt.show()
```

#### **直方圖 (Histogram)**

```python
# 創建隨機數據
data = np.random.randn(1000)  # 生成 1000 個常態分佈的隨機數

# 繪製直方圖
plt.hist(data, bins=30, color='purple', alpha=0.7)  # bins 設置直方圖的分箱數量
plt.title("Histogram Example")
plt.xlabel("Data")
plt.ylabel("Frequency")
plt.show()
```

#### **多圖顯示 (Subplots)**

```python
# 創建多個子圖
fig, axs = plt.subplots(2, 2, figsize=(10, 8))  # 2x2 的子圖，設置圖形大小

# 第一個子圖: 折線圖
axs[0, 0].plot(x, y, color='r')
axs[0, 0].set_title("Sine Wave")

# 第二個子圖: 散佈圖
axs[0, 1].scatter(x, y, color='b')
axs[0, 1].set_title("Scatter Plot")

# 第三個子圖: 長條圖
axs[1, 0].bar(categories, values, color='g')
axs[1, 0].set_title("Bar Chart")

# 第四個子圖: 直方圖
axs[1, 1].hist(data, bins=20, color='m')
axs[1, 1].set_title("Histogram")

# 調整子圖之間的間距
plt.tight_layout()
plt.show()
```

#### **雙軸圖 (Dual-Axis Plot)**

```python
# 創建數據
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 創建雙軸圖
fig, ax1 = plt.subplots()

# 繪製第一條折線 (sin(x))
ax1.plot(x, y1, 'b-', label='sin(x)')
ax1.set_xlabel('X Axis')
ax1.set_ylabel('sin(x)', color='b')
ax1.tick_params('y', colors='b')

# 創建第二條 y 軸，共用 x 軸
ax2 = ax1.twinx()
ax2.plot(x, y2, 'r--', label='cos(x)')
ax2.set_ylabel('cos(x)', color='r')
ax2.tick_params('y', colors='r')

# 顯示圖例
fig.tight_layout()
plt.show()
```

#### **標註資料點 (Annotations)**

```python
# 創建數據
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 繪製折線圖
plt.plot(x, y, label='sin(x)')
plt.title("Annotated Sine Wave")

# 標註特定點
plt.annotate('Local max', xy=(np.pi/2, 1), xytext=(np.pi/2 + 1, 1.5),
             arrowprops=dict(facecolor='black', shrink=0.05))

plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.legend()
plt.show()
```

#### **儲存圖像到檔案**

```python
# 繪製一個基本的折線圖
plt.plot(x, y, label='sin(x)')
plt.title("Sine Wave")

# 儲存圖像為 PNG 檔案
plt.savefig('sine_wave.png', dpi=300)  # 設置解析度為 300 DPI
plt.show()
```

#### **更多 Matplotlib 設置**

- **顏色**：使用 `'b'`、`'g'`、`'r'` 等代表藍色、綠色、紅色，或直接使用顏色名稱如 `'blue'`、`'green'`。
- **標記**：使用 `'o'` 表示圓點，`'^'` 表示三角形，`'s'` 表示方形。
- **線型**：使用 `'-'`（實線）、`'--'`（虛線）、`'-.'`（點線）等。
- **字體大小**：`plt.title("Title", fontsize=16)` 設置標題字體大小。

#### **特性總結**：
- **折線圖**：適合連續數據的展示。
- **散佈圖**：適合顯示兩個變數之間的關係。
- **長條圖**：適合展示類別數據的比較。
- **直方圖**：適合展示數據的分佈。
- **多圖顯示**：可以在同一視窗內展示多個子圖，方便對比不同圖表。
- **雙軸圖**：同時顯示兩個不同的 y 軸數據。

這些範例展示了 **Matplotlib** 的多種繪圖功能，適用於資料可視化、數據分析和報告生成。

## 11. **Requests 模組** (發送 HTTP 請求)

```python
import requests

response = requests.get("https://example.com")
print(response.status_code)  # 200 為成功
print(response.content)  # 取得回應內容
```

### 12. **BeautifulSoup** (解析 HTML)

```python
from bs4 import BeautifulSoup
html = "<html><head><title>Web Scraping</title></head><body></body></html>"
soup = BeautifulSoup(html, 'html.parser')
print(soup.title.string)  # Output: Web Scraping
```

### 13. **SQLite3**

**SQLite** 是一個輕量級的嵌入式資料庫管理系統，它非常適合於小型應用或測試環境。它不需要獨立的伺服器軟體，資料庫存放在一個單一檔案中。**Python** 提供了內建的 `sqlite3` 模組來與 SQLite 互動，使得在 Python 中操作 SQLite 資料庫變得非常簡單。

下面我們來看看如何使用 **Python 的 sqlite3 模組** 來進行 SQLite 資料庫的操作。

### **1. 連接到資料庫**

```python
import sqlite3

# 建立或連接到 SQLite 資料庫（資料庫檔案為 example.db）
conn = sqlite3.connect('example.db')

# 建立 Cursor 物件來執行 SQL 語句
cursor = conn.cursor()
```

- 如果檔案不存在，這個語句會自動創建一個 `example.db` 檔案。
- `cursor` 物件用來執行 SQL 語句並管理資料庫中的資料。

### **2. 建立資料表**

```python
# 建立一個名為 users 的資料表，包含三個欄位 id, name, age
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER NOT NULL
)
''')
conn.commit()  # 確保資料表的建立被寫入資料庫
```

- `CREATE TABLE` 用來創建資料表，`IF NOT EXISTS` 防止表已經存在時重複創建。
- `PRIMARY KEY AUTOINCREMENT` 保證 `id` 欄位自動增長並且唯一。

### **3. 插入資料**

```python
# 插入單條資料
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30))
conn.commit()  # 提交改變

# 插入多條資料
users_data = [('Bob', 25), ('Charlie', 35), ('David', 40)]
cursor.executemany("INSERT INTO users (name, age) VALUES (?, ?)", users_data)
conn.commit()  # 提交改變
```

- `?` 是參數的佔位符，用來防止 SQL 注入攻擊。
- 使用 `executemany()` 可以一次插入多條資料。

### **4. 查詢資料**

```python
# 查詢所有用戶資料
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()  # 獲取所有查詢結果
for row in rows:
    print(row)

# 查詢特定條件的資料
cursor.execute("SELECT * FROM users WHERE age > ?", (30,))
filtered_rows = cursor.fetchall()
for row in filtered_rows:
    print(row)
```

- `SELECT *` 用來查詢資料表中的所有欄位資料。
- `fetchall()` 會返回所有查詢結果，結果是一個包含每條資料的 tuple 列表。

### **5. 更新資料**

```python
# 更新某個用戶的年齡
cursor.execute("UPDATE users SET age = ? WHERE name = ?", (28, 'Alice'))
conn.commit()  # 提交更改
```

- 使用 `UPDATE` 語句來修改資料，`SET` 用來設置要更新的欄位和新值。

### **6. 刪除資料**

```python
# 刪除特定條件的資料
cursor.execute("DELETE FROM users WHERE name = ?", ('Bob',))
conn.commit()  # 提交更改
```

- 使用 `DELETE` 語句來刪除資料，注意此操作不可撤銷。

### **7. 使用 `with` 語法管理連接**

```python
# 使用 with 語法自動關閉資料庫連接
with sqlite3.connect('example.db') as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    rows = cursor.fetchall()
    for row in rows:
        print(row)
```

- 使用 `with` 語法可以自動管理連接和資源釋放，不需要手動關閉資料庫。

### **8. 例外處理**

```python
try:
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()

    # 執行一些操作
    cursor.execute("SELECT * FROM non_existing_table")  # 查詢不存在的表

except sqlite3.Error as e:
    print(f"An error occurred: {e}")

finally:
    if conn:
        conn.close()  # 確保連接被關閉
```

- `sqlite3.Error` 是所有 SQLite 相關錯誤的基礎類別，使用 `try-except-finally` 可以更安全地處理資料庫操作。

### **9. 關閉連接**

```python
# 當所有操作結束後，記得關閉資料庫連接
conn.close()
```

### **總結：**

- **SQLite** 是一個輕量級的資料庫系統，非常適合應用於小型項目和測試環境。
- 使用 **Python 的 sqlite3 模組** 可以方便地進行資料庫操作，如建立表、插入資料、查詢、更新和刪除資料。
- **常見操作** 包含建立資料庫連接、使用游標執行 SQL 語句、處理例外、管理連接資源等。

這些範例展示了如何通過 **Python** 操作 **SQLite** 資料庫，適用於小型應用、快速原型設計以及不需要完整伺服器的情境。
