---
# System prepended metadata

title: python 作業
tags: [網頁工作坊]

---

# [第2次回家作業](https://docs.google.com/forms/d/e/1FAIpQLScj2JEP_EboRe43duOGxakLX0rL9M8kDD0aihzu_cCbY6nZPQ/viewform)
-----
[git-練習檔](https://github.com/jojoexcel/2nd_homework)
-----
## 是非題
###  1.PEP 8 是 Python 的一個特定版本。
是編碼規範-幫助開發者寫出可讀性高且風格一致的程式。
PEP8==Flake8
###  2. Python 中，變數的命名只能使用小寫字母。
變數可以大小寫,大小寫為不同字
#### 好的變數名稱
建議使用小寫英文字母，例如 score。如果需要組合多個英文單字，可以在單字之間加上底線，例如：english_score。
如果變數的內容不要被修改（ 其他程式語言稱為「常數」，也就是內容不會改變的數 )，變數名稱建議全部用大寫英文字母，例如 MAX_NUMBER。
如果變數名稱包含專有名詞，例如 HTTP、APP，就使用原來的大小寫格式，例如 HTTP_port、APP_port。
###  3. list 和 tuple 都可以包含不同的資料型別。
是的

:::spoiler 

是的，**list（列表）和tuple（元組）**都可以包含不同的資料型別。這兩種資料結構都是用來儲存一組元素的容器，並且可以包含數字、字串、布林值等不同型別的資料。
主要的區別在於：

可變性：
list 是可變的，你可以添加、刪除或修改列表中的元素。
tuple 是不可變的，一旦創建了元組，就不能修改它的內容。

表示方式：
list 使用方括號 [] 來表示，例如：my_list = [1, 2, 'hello', True]。
tuple 使用圓括號 () 來表示，例如：my_tuple = (1, 2, 'hello', True)。
:::
### 4. 在 Python 中，使用 // 來執行整數除法。
在Python中，使用 // 運算符執行的是整數除法，結果將被捨去小數部分，返回一個整數。
```python=01
result = 7 // 2
print(result)
```
這將輸出 5，因為整數除法 11 // 2 的結果是 5.5，捨去小數部分後得到整數 3。
### 5. NoneType 是一種可變動物件(mutable)。
NoneType 是不可變的
```python=01
# 定義一個 NoneType 物件
none_obj = None

# 嘗試改變它的值
try:
    none_obj += 1
except TypeError as e:
    print(f"錯誤: {e}")
```
在這個範例中，我們嘗試將 1 加到 None，但是會收到一個 TypeError，因為 NoneType 物件的值不能被改變。這就證明了 NoneType 是不可變的。

## 單選題
### 01. 在 Python 中，PEP 8 的目的是？
ans PEP 8 的目的是提高 Python 代碼的可讀性。

PEP 8 是 Python Enhancement Proposal 8 的簡稱，是由Python社區制定的一個風格指南，旨在規範 Python 代碼的撰寫風格，使其更易讀、更一致。這有助於不同程式碼作者之間的代碼協作，並提高代碼的可維護性。
### 資料型別
:::success

在 Python 中，基本的資料型別包括數值型別、布林型別、字串型別以及一些基本的容器型別。以下是 Python 的一些基本資料型別：

數值型別：
整數型別（int）： 代表整數，例如：5。
浮點數型別（float）： 代表浮點數，即帶有小數點的數字，例如：3.14。

布林型別：
布林型別（bool）： 代表布林值，即 True 或 False。

字串型別：
字串型別（str）： 代表文字，可以使用單引號或雙引號括起來，例如：'hello' 或 "world"。

容器型別：
列表（list）： 有序的可變容器，可以包含不同型別的元素，例如：[1, 2, 'apple']。
元組（tuple）： 有序的不可變容器，類似於列表，但一旦創建後就不能修改，例如：(1, 2, 'banana')。
集合（set）： 無序的可變容器，不包含重複元素，例如：{1, 2, 3}。
字典（dict）： 鍵-值對的無序容器，用於映射鍵到值，例如：{'key': 'value', 'name': 'John'}。
這些是 Python 中最基本的資料型別
:::

建立 Python 的虛擬機
:::spoiler 建立虛擬環境的基本步驟：
:::success
vscode CTRL+shit+P 輸入「terminal」，並選取「Python: Create Terminal」的選項 
使用以下命令安裝 virtualenv 工具
``` bash=01
pip install virtualenv
```
 專案啟用
``` bash=02
virtualenv .venv
```
:::
:::
Python 套件管理
:::spoiler 套件管理-引用[孝國老師講議](https://hackmd.io/@peterju/Hkd1-AgDn/https%3A%2F%2Fhackmd.io%2F%40peterju%2FSyPue7x_3#%E5%A5%97%E4%BB%B6%E7%AE%A1%E7%90%86)
:::success
pip 是 Python 的套件管理器，可下載位於 PyPI(Python Package Index) 軟體版本庫中的第三方套件。

pip 基本使用
完整的使用方法可下達 pip help 得知，常用的指令如下：

查詢目前安裝的套件有哪些 pip list
查詢哪些套件需要升級 pip list -o
安裝 A 套件 pip install A
更新 A 套件 --upgrade 可用 -U 取代 pip install --upgrade A
查看已安裝的 A 套件資訊 pip show A
移除 A 套件 pip uninstall A
檢查套件的相依性 pip check
將目前使用的套件匯出清單 pip freeze > requirements.txt
根據套件匯出清單安裝套件 pip install -r requirements.txt
:::
:::
### 02. 在 Python 中，區域變數是指？
:::success
Ans :只能在定義它的函式中訪問的變數
:::
區域變數是指只能在定義它的函式（或其他程式結構，例如迴圈或條件語句）中訪問的變數。
:::spoiler  Python的變數
在 Python 中，變數是用來儲存和引用數據的標識符。Python 的變數可以分為不同的類型，包括全域變數、區域變數和類別變數。

全域變數（Global Variables）：
定義：在整個程式中都可以訪問的變數。
```python=01
global_variable = 10

def my_function():
    print(global_variable)

    my_function()  # 可以訪問全域變數
```
區域變數（Local Variables）：
定義：只能在定義它的區域（如函式、迴圈或條件語句）中訪問的變數。
範例：
```python=01
def my_function():
    local_variable = 20
    print(local_variable)

my_function()  # 可以訪問區域變數
```

類別變數（Class Variables）：
定義：屬於類別的變數，對該類別的所有實例共享。

實例變數（Instance Variables）：
定義：屬於類別的實例的變數，每個實例都有自己的一份。
```python=01
class MyClass:
    class_variable = 30

    def __init__(self):
        self.instance_variable = 40

obj1 = MyClass()
print(obj1.class_variable)  # 可以訪問類別變數
print(obj1.instance_variable)  # 可以訪問實例變數
```

這些類型的變數具有不同的作用範圍和生命週期，了解它們的區別有助於寫出更清晰、易於理解和維護的程式碼。
:::
### 03. 在 Python 中，縮排和區塊結構的主要目的是？
:::success

ANS:改善代碼的可讀性。
:::
縮排是 Python 中表示程式碼區塊的方式，而不是使用大括號（如在其他語言中）。這種方式使得程式碼的結構更清晰，並且可以直觀地顯示代碼的層次結構。通過縮排，我們可以清晰地看到哪些代碼屬於某個條件語句、迴圈或函式定義的區塊。

因此，縮排和區塊結構的主要目的是為了提高代碼的可讀性，使得代碼更容易理解和維護。

### 04.下列哪個敘述是正確的？
ANS:Python 中變數的型別是動態的
### 05. 哪個是表示一個空值的特殊Python型別？
ANS:NoneType
### 06. 在 Python 中，字典的元素是以什麼形式存儲的？
在 Python 中，字典的元素是以 Key-Value pairs（鍵-值對） 的形式存儲的。每個鍵都是唯一的，而與每個鍵相關聯的是其對應的值。字典使用大括號 {} 表示，並且鍵和值之間使用冒號 : 分隔。
### 07.Python的保留字
ans def 
:::spoiler 保留字（keywords）
在 Python 中，有一些保留字（keywords），這些保留字有特殊的含義，不能用作變數名稱或其他標識符。以下是 Python 3.x 中的保留字列表：

```python
False      class      finally    is         return
None       continue   for        lambda     try
True       def        from       nonlocal   while
and        del        global     not        with
as         elif       if         or         yield
assert     else       import     pass
break      except     in         raise
```
這些保留字涵蓋了 Python 的基本語法結構、流控制和一些特殊功能的關鍵字。請注意，Python 的保留字是大小寫敏感的，例如 True 和 true 是不同的標識符。

避免使用這些保留字作為變數名稱，以免引起混淆或錯誤。在撰寫程式碼時，IDE（整合開發環境）通常會提供提示，以幫助你避免使用保留字。
:::
###  08.在Python中，如何訪問列表的第一個元素？
ans list[0]
:::spoiler Python 中，有多種方法可以訪問列表的第一個元素。以下是一些可能的方法：

使用索引：

使用索引 0 可以訪問列表的第一個元素。
```python
my_list = [10, 20, 30]
first_element = my_list[0]
```
使用 pop 方法：

使用 pop 方法可以刪除並返回列表的最後一個元素，但如果沒有指定索引，默認移除並返回列表的最後一個元素。
```python
my_list = [10, 20, 30]
first_element = my_list.pop(0)
```
使用切片：

使用切片 [:1] 可以獲取列表的第一個元素，這也是一種方式。
```python
my_list = [10, 20, 30]
first_element = my_list[:1][0]
```
使用 next 函數：

使用 next 函數可以獲取迭代器的下一個元素，對於列表，可以使用 iter 函數將其轉換為迭代器。
```python
my_list = [10, 20, 30]
iterator = iter(my_list)
first_element = next(iterator)
```

這些是一些可能的方法，其中使用索引 0 是最直觀和廣泛接受的方式。選擇方法取決於你的代碼上下文和需求
:::
### 09. 在 Python 中，哪個是可變動物件(mutable)？
ans List
:::spoiler 在 Python 中，物件可以分為兩大類型
:::info 
 可變動物件（Mutable Objects）
 不可變動物件（Immutable Objects）

可變動物件（Mutable Objects）：
可變動物件是指在創建後其內容或狀態可以被修改的物件。主要的可變動物件包括：
```python

#列表（List）：
#列表是有序、可變動的序列，你可以修改、添加或刪除列表中的元素。
my_list = [1, 2, 3]
my_list[0] = 10  # 修改元素
my_list.append(4)  # 添加元素

#字典（Dictionary）：
#字典是一種對應關係的集合，其中的鍵和值都是可變的。
my_dict = {'a': 1, 'b': 2}
my_dict['a'] = 10  # 修改值
my_dict['c'] = 3  # 添加新鍵值對

#集合（Set）：
#集合是無序、可變的集合，可以添加或刪除元素。
my_set = {1, 2, 3}
my_set.add(4)  # 添加元素
my_set.remove(2)  # 刪除元素
```
不可變動物件（Immutable Objects）：
不可變動物件是指在創建後其內容或狀態不能被修改的物件。主要的不可變動物件包括：
```python=
#整數（int）：
my_integer = 42  #整數是不可變的，一旦創建後，其值不能被修改。
#浮點數（float）
my_float = 3.14  #浮點數也是不可變的。
#字串（str）：
my_string = "Hello" #字串是不可變的序列。
#元組（Tuple）：
my_tuple = (1, 2, 3) #元組是不可變的有序序列。
```
不可變動物件的主要特點是一旦創建後就無法修改其內容。這種特性使得在某些情況下更容易理解代碼和防止錯誤
:::
### 10. 如何表示一個空的集合？
ans:set()
在 Python 中，表示一個空的集合使用的是 set()
:::spoiler 相關表示法的說明：
:::success
其他的表示法可能會引起誤解或被解釋成不同的型別。
```python=
#{}: 通常表示一個空的字典，而不是一個空的集合。因此，不建議使用 {} 來表示空集合。
empty_dict = {}
#{ }：這樣的表示法也被解釋為一個空的字典，而不是集合。
another_empty_dict = { }
#{''}：這表示一個包含一個空字串的集合，而不是空集合。
non_empty_set = {''}
#set()：正確的表示法，用來創建一個空的集合。
empty_set = set()
```
:::
### 11. 關於 Python 中的列表（list），以下哪個敘述是正確的？
ans:列表中的元素可以是不同的資料型別
:::spoiler 列表（List）的特性：
```python
#有序性（Ordered）：
#列表是有序的，即元素在列表中的位置是固定的，可以根據索引訪問和操作。
my_list = [1, 2, 3, 4]

#可變性（Mutable）：
#列表是可變的，你可以修改、添加或刪除列表中的元素。
my_list = [1, 2, 3]
my_list[0] = 10  # 修改元素
my_list.append(4)  # 添加元素

#容納不同型別（Heterogeneous）：
#列表可以同時包含不同型別的元素。
mixed_list = [1, 'hello', 3.14, True]

#可迭代性（Iterable）：
#列表是可迭代的，你可以使用迴圈遍歷列表中的元素。
my_list = [1, 2, 3]
for item in my_list:
    print(item)
#1
#2
#3
```
列表的注意事項：
索引從0開始：

在 Python 中，列表的索引從 0 開始，這意味著第一個元素的索引是 0，第二個元素的索引是 1，以此類推。
```python
my_list = [10, 20, 30]
first_element = my_list[0]  # 取得第一個元素
#結果 10
```
適用於大多數場景：
列表是 Python 中使用最廣泛的數據結構之一，適用於許多場景，包括存儲和處理元素集合。

性能注意事項：
對列表進行插入或刪除操作可能涉及元素的移動，這可能會影響性能，尤其是對於包含大量元素的大型列表。在這些情況下，可能需要考慮使用其他數據結構，如 collections.deque。
列表推導（List Comprehension）：

#Python 提供了列表推導的語法，這是一種簡潔的創建列表的方式。
```python=
squares = [x**2 for x in range(5)]
print(squares)
#結果[0, 1, 4, 9, 16]

#可嵌套性（Nested Lists）：
#列表可以嵌套，即在一個列表中包含另一個列表。
nested_list = [[1, 2, 3], [4, 5, 6]]
print(nested_list)
#結果 [[1, 2, 3], [4, 5, 6]]
print(nested_list[0])
#結果 [1, 2, 3]
print(nested_list[1][1])
#結果 5
```
:::
### 12. 在 Python 中，如何向列表中新增一個元素？
* ans 使用 append 方法
:::spoiler 列表 新增  修改  刪除  
新增元素：
```python=
#使用 append 方法：
#append 方法用於在列表的末尾添加一個元素。
my_list = [1, 2, 3]
my_list.append(4)

#使用 insert 方法：
#insert 方法用於在指定索引位置插入一個元素。
my_list = [1, 2, 3]
my_list.insert(1, 10)  # 在索引 1 的位置插入元素 10

#使用 extend 方法或 += 運算符：
#extend 方法用於將一個可迭代的對象的元素添加到列表的末尾。
my_list = [1, 2, 3]
my_list.extend([4, 5, 6])
# 或者使用 +=
my_list += [7, 8, 9]
```

修改元素：
```python=
#通過索引直接賦值：
#通過索引直接賦值可以修改列表中指定位置的元素。
my_list = [1, 2, 3]
my_list[1] = 10  # 修改索引 1 的元素
```
刪除元素：

```python
#使用 del 關鍵字：
#del 關鍵字可以刪除列表中指定索引位置的元素。
my_list = [1, 2, 3, 4, 5]
del my_list[2]  # 刪除索引 2 的元素

#使用 remove 方法：
#remove 方法用於刪除列表中指定值的元素（僅刪除第一次出現的該值）。
my_list = [1, 2, 3, 2, 4]
my_list.remove(2)  # 刪除值為 2 的元素

#使用 pop 方法：
#pop 方法用於刪除並返回指定索引位置的元素。
my_list = [1, 2, 3]
popped_element = my_list.pop(1)  # 刪除索引 1 的元素並返回它
#使用 clear 方法：
#clear 方法用於清空列表，使其變為空列表。
my_list = [1, 2, 3]
my_list.clear()  # 清空列表
```
:::
### 13. 關於 Python 字典中的鍵（key），以下哪個敘述是正確的？
ans 字典的鍵必須是任意不可變的資料型別
### 14. 以下哪個是 Python 中的成員運算子？
ans in
:::spoiler 說明
```python=
#++：
#在 Python 中，++ 不是成員運算子，而是遞增運算子。然而，Python 不支持 ++ 這種遞增運算子，因此應該使用 += 1 來實現遞增。

# 此處示例僅作為說明，實際上不可行
x = 5
x++  # 錯誤，Python 不支持 ++ 遞增運算子  js用法


#in：
#in 是成員運算子，用於測試某個值是否存在於序列（如列表、元組、字串等）中。
my_list = [1, 2, 3, 4]
result = 3 in my_list  # 結果為 True，因為 3 存在於 my_list 中

#!=：
#!= 是不等於運算子，用於比較兩個值是否不相等。
x = 5
y = 10
result = x != y  # 結果為 True，因為 x 不等於 y

#is：
#is 是身份運算子，用於比較兩個對象的身份（即它們是否是同一個對象）。
a = [1, 2, 3]
b = a
result = a is b  # 結果為 True，因為 a 和 b 引用同一個列表對象
#總結來說，成員運算子是 in，而 ++ 不是 Python 支持的遞增運算子，而是應該使用 += 1。
```
:::

	
### 15.在 Python 中，下列哪個敘述描述了集合的特點？
ans 集合中的元素不能通過索引進行訪問

集合是一種無序的、可變的資料結構，且不能通過索引訪問元素，因為集合中的元素沒有固定的位置。集合主要用於存儲唯一的元素，並提供了常見的集合操作，如聯集、交集、差集等。
```python=
my_set = {1, 2, 3, 4, 5, 5, 4, 2, 3, 4, 5, 3, 5, 1}
print(my_set)
# 結果{1, 2, 3, 4, 5}
for element in my_set:
    print(element)
#結果
# 1
# 2
# 3
# 4
# 5
```

## 填充題
### 1. 在 Python 中，區塊的縮排是使用空格或 ______ 進行的
ans Tab
通常是四個空格,少用 Tab
### 2. 在 Python 中，用於表示一個不可變 (immutable)的有序集合的資料型別是 ______
ans tuple
[相關資料型別](###資料型別)
### 3. Python 中的數值型別包括整數、浮點數、複數和 ______。
ans 布林值
### 4. 若要取得字串的最後三個字元，可以使用切片語法是______。
ans 字串[-3:]
### 5. my_list = [10, 20, 30, 40, 50, 60, 70, 80, 90] <br>要如何使用切片語法取得 10 和 90 之間的元素呢？ 
ans my_list[1:-1]  
## 實作題
### 1. 請合併以下兩個字串，再將字串進行反轉 <br>"Hello" 和 "World"
```python
x = "Hello"
y = "World"
p = x + y
a = list(p)
a.reverse()
a = ''.join(a)
print(a)

```
### 2. 請寫一隻可接受使用者不斷輸入英文姓名的程式，直到按下Enter 後結束，輸入的姓名請放入 List 中，結束後請輸出： <br>a. 依字母遞增排序與遞減排序 <br>b. 依字數多寡遞增與遞減排序
```python=
import re


def is_english_name(name):
    # 此正規表示式確保名字只包含英文字母 可以空白
    pattern = re.compile(r'^[a-zA-Z ]+$')
    return bool(pattern.match(name))


def get_names():
    names = []
    while True:
        name = input("請輸入英文姓名（按下 Enter 結束）：")
        if not name:
            break
        # 驗證是否為英文姓名
        if is_english_name(name):
            names.append(name)
        else:
            print("請輸入有效的英文姓名。")
    return names


def print_sorted_names(names, key=None, reverse=False):
    sorted_names = sorted(names, key=key, reverse=reverse)
    print(sorted_names)


# 取得姓名列表
names_list = get_names()

# 依字母遞增排序與遞減排序
print("按字母遞增排序：", end=" ")
print_sorted_names(names_list)

print("按字母遞減排序：", end=" ")
print_sorted_names(names_list, reverse=True)

# 依字數多寡遞增排序與遞減排序
print("按字數遞增排序：", end=" ")
print_sorted_names(names_list, key=len)

print("按字數遞減排序：", end=" ")
print_sorted_names(names_list, key=len, reverse=True)

```
### 3.  請加總與平均(至小數2位)以下字典內的分數，再將結果放入相同的字典內，並新增 total 與 avg 二個 Key-Value pairs <BR>student_scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 90}
```python=
def sum_allvalue(all_value):
    # return sum(all_value)
    sumdate = 0
    for value_x in all_value:
        sumdate += value_x
    return sumdate


def avg_value(all_nu, sumdate):
    #return sumdate / all_nu
    avg = sumdate / all_nu
    return avg


student_scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 90}  # 原始字典
# 初始化總和變數
all_value = student_scores.values()
sumdate = sum_allvalue(all_value)
all_nu = len(student_scores)
avg = avg_value(all_nu, sumdate)

# 輸出總和
print("總和：", sumdate)
print("平均：", avg)
student_scores['total'] = sumdate
student_scores['avg'] = round(avg, 2)
print(student_scores)

```
### 4. 讓使用者可以連續輸入姓名與成績 ，直到按下Enter 後離開，每一筆記錄以字典形式儲存，key 分別為 name 與 grade，再將記錄依序放入列表中，亦即列表中的每一個元素就是一個字典。<BR>離開連續輸入後，請顯示總分與平均 (至小數2位)
```python=
def calculate_average(records):
    total = sum(record['grade'] for record in records)
    average = total / len(records)
    return total, round(average, 2)


# 初始化空列表用於存放記錄
records_list = []

# 連續輸入姓名與成績，直到按下 Enter 離開
while True:
    name = input("請輸入姓名（按下 Enter 結束）：")
    if not name:
        break

    while True:
        grade_input = input("請輸入成績（按下 Enter 回上一層不存這筆）：")
        if not grade_input:  # 如果使用者直接按下 Enter 結束，跳出內層迴圈
            break

        try:
            grade = float(grade_input)
            if 0 <= grade <= 100:
                # 將姓名與成績以字典形式加入列表
                records_list.append({'name': name, 'grade': grade})
                break  # 成績符合要求，跳出內層迴圈
            else:
                print("請輸入有效的成績（介於 0 到 100 之間的數字）。")
        except ValueError:
            print("請輸入有效的數字。")

# 顯示所有記錄
print("\n所有記錄：")
for record in records_list:
    print(record)

# 計算總分與平均值
total_score, average_score = calculate_average(records_list)

# 顯示總分與平均值
print("\n總分：", total_score)
print("平均：", average_score)
	
```

### 5.讓使用者輸入最長的一列星星數(奇數)，然後動態產生以下的星星圖案。
```python=
import os

# 在 Windows 中清屏
os.system('cls')


def print_star(n):
    spaces_list = []  # 用來存儲每一行的 spaces
    for i in range(n): # i會從0開始
        spaces = abs(n // 2 - i)  # 計算前置空白
        stars = n - 2 * spaces  # 星數從1至N setp 2
        print(" " * spaces + "*" * stars)
        spaces_list.append({"列": i + 1, "空白": spaces, "星星": stars})
    # 列印 spaces_list
    print("Spaces List:", spaces_list)

while True:
    x_str = input(r"請輸入最多的星星數：(限奇數) ")
    try:
        n = int(x_str)
         if n % 2 != 0: #判別是否為奇數
            print_start(n)
            break  # 如果條件滿足，跳出循環
        else:
            print("輸入不合法，請確保輸入是奇數。")
    except ValueError:
        print("請輸入有效的數字。")
        
```




