2025年5月8日 星期四

Python 3.x 的內建標準庫

 Python 3.x 的內建標準庫(Standard Library)是一套隨 Python 安裝時就已包含的模組,不需額外安裝就可直接使用。這些模組涵蓋:

  • 數學與統計
  • 檔案處理
  • 作業系統互動
  • 正規表示法
  • 資料壓縮
  • 網路處理
  • 程式設計工具(如時間、日期、迴圈控制)
  • 單元測試
  • 資料結構輔助模組(如 collections)

以下是常見 Python 3.x 標準庫分類與模組代表:

📊 數學與統計

模組功能簡述
math提供數學函數(如 sin, sqrt)
statistics平均數、中位數、標準差等統計
random隨機數與抽樣工具

📁 檔案與資料處理

模組功能簡述
os作業系統操作(檔案、資料夾)
shutil高階檔案操作(複製、搬移)
csv讀寫 CSV 檔案
json讀寫 JSON 格式

🧮 資料結構與演算法輔助

模組功能簡述
collections額外資料型別如 deque, Counter
heapq最小堆排序工具
bisect二分搜尋
array效率較高的陣列(固定型別)

🕒 時間與日期

模組功能簡述
time處理時間戳記、延遲等
datetime處理日期與時間
calendar月曆、閏年等工具

📧 網路與 Web

模組功能簡述
urllib網頁請求與網址處理
httpHTTP 協定處理
socket低階網路連線工具

🔍 正規表示式與字串處理

模組功能簡述
re正規表示式處理
string字元集、格式工具
textwrap文字換行與排版處理

🔒 安全與編碼

模組功能簡述
hashlib加密(MD5、SHA 等)
base64編碼轉換

🧪 測試與除錯

模組功能簡述
unittest單元測試框架
traceback錯誤堆疊追蹤
pdb互動式除錯器

🧰 其他常用工具

模組功能簡述
itertools高效迴圈工具組
functools函數輔助工具(如 LRU cache)
typing型別提示(type hint)
dataclasses自動產生 class 的工具
enum列舉型別


2025年5月7日 星期三

立體摩天輪



import tkinter as tk
from PIL import Image, ImageTk
import math, os

# 畫布與圓形參數
WIDTH, HEIGHT = 600, 600
RADIUS = 200
CENTER_X, CENTER_Y = WIDTH // 2, HEIGHT // 2
ANGLE_STEP = 1  # 每次旋轉角度

# 建立視窗
root = tk.Tk()
root.title("24 車艙繞圓移動 + 中心連線 + 腳架")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()
# ✅ 加上整個摩天輪的支撐腳架(靜態)
foot_base_y = HEIGHT - 50
foot_width = 120

canvas.create_line(CENTER_X, CENTER_Y, CENTER_X - foot_width, foot_base_y, width=6, fill='black')
canvas.create_line(CENTER_X, CENTER_Y, CENTER_X + foot_width, foot_base_y, width=6, fill='black')
canvas.create_line(CENTER_X - foot_width - 50, foot_base_y,
                   CENTER_X + foot_width + 50, foot_base_y,
                   fill='gray', dash=(4, 4))  # 地面線

# 載入 24 張圖片
photos = []
for i in range(24):
    img_path = os.path.join("unit", f"unit{i%7}.png")
    img = Image.open(img_path).resize((40, 60))
    photo = ImageTk.PhotoImage(img)
    photos.append(photo)

# 建立 24 台車艙,每台車對應一條中心線 + 腳架
cars = []
for i in range(24):
    angle = i * 15
    rad = math.radians(angle)
    x = CENTER_X + RADIUS * math.cos(rad)
    y = CENTER_Y + RADIUS * math.sin(rad)

    car_id = canvas.create_image(x, y, image=photos[i])
    line_id = canvas.create_line(CENTER_X, CENTER_Y, x, y, fill='gray', dash=(4, 2))  # 中心連線

    # 加入左右腳架線(初始位置)
    # foot_offset = 20
    # leg1 = canvas.create_line(x, y, x - foot_offset, y + foot_offset, fill='black')
    # leg2 = canvas.create_line(x, y, x + foot_offset, y + foot_offset, fill='black')

    cars.append({
        'id': car_id,
        'angle': angle,
        'photo': photos[i],
        'line': line_id,
    })

# 動畫更新函數
frame = 0  # 全域 frame 計數器

def move_cars():
    global frame
    frame += ANGLE_STEP  # 每次更新一點點角度
    x_scale = -0.6 + 0.6 * abs(math.cos(math.radians(frame)))  # x 縮放因子:0.6~1.0

    for car in cars:
        car['angle'] = (car['angle'] + ANGLE_STEP) % 360
        rad = math.radians(car['angle'])

        # 🚩 加入 x_scale 縮放
        x = CENTER_X + RADIUS * math.cos(rad) * x_scale
        y = CENTER_Y + RADIUS * math.sin(rad)

        # 更新車艙位置
        canvas.coords(car['id'], x, y)

        # 更新中心連線
        canvas.coords(car['line'], CENTER_X, CENTER_Y, x, y)

    canvas.after(30, move_cars)


move_cars()
root.mainloop()

摩天輪 :12 車艙繞圓移動 + 中心連線 + 腳架






 import tkinter as tk

from PIL import Image, ImageTk
import math, os

# 畫布與圓形參數
WIDTH, HEIGHT = 600, 600
RADIUS = 200
CENTER_X, CENTER_Y = WIDTH // 2, HEIGHT // 2
ANGLE_STEP = 2  # 每次旋轉角度

# 建立視窗
root = tk.Tk()
root.title("12 車艙繞圓移動 + 中心連線 + 腳架")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()
# ✅ 加上整個摩天輪的支撐腳架(靜態)
foot_base_y = HEIGHT - 50
foot_width = 120

canvas.create_line(CENTER_X, CENTER_Y, CENTER_X - foot_width, foot_base_y, width=6, fill='black')
canvas.create_line(CENTER_X, CENTER_Y, CENTER_X + foot_width, foot_base_y, width=6, fill='black')
canvas.create_line(CENTER_X - foot_width - 50, foot_base_y,
                   CENTER_X + foot_width + 50, foot_base_y,
                   fill='gray', dash=(4, 4))  # 地面線

# 載入 6 張圖片
photos = []
for i in range(12):
    img_path = os.path.join("unit", f"unit{i%7}.png")
    img = Image.open(img_path).resize((40, 60))
    photo = ImageTk.PhotoImage(img)
    photos.append(photo)

# 建立 6 台車艙,每台車對應一條中心線 + 腳架
cars = []
for i in range(12):
    angle = i * 30
    rad = math.radians(angle)
    x = CENTER_X + RADIUS * math.cos(rad)
    y = CENTER_Y + RADIUS * math.sin(rad)

    car_id = canvas.create_image(x, y, image=photos[i])
    line_id = canvas.create_line(CENTER_X, CENTER_Y, x, y, fill='gray', dash=(4, 2))  # 中心連線

    # 加入左右腳架線(初始位置)
    foot_offset = 20
    leg1 = canvas.create_line(x, y, x - foot_offset, y + foot_offset, fill='black')
    leg2 = canvas.create_line(x, y, x + foot_offset, y + foot_offset, fill='black')

    cars.append({
        'id': car_id,
        'angle': angle,
        'photo': photos[i],
        'line': line_id,
        'leg1': leg1,
        'leg2': leg2
    })

# 動畫更新函數
def move_cars():
    for car in cars:
        car['angle'] = (car['angle'] + ANGLE_STEP) % 360
        rad = math.radians(car['angle'])
        x = CENTER_X + RADIUS * math.cos(rad)
        y = CENTER_Y + RADIUS * math.sin(rad)

        # 更新車艙位置
        canvas.coords(car['id'], x, y)

        # 更新中心連線
        canvas.coords(car['line'], CENTER_X, CENTER_Y, x, y)

        # 更新腳架線(左右分叉)
        foot_offset = 20
        canvas.coords(car['leg1'], x, y, x - foot_offset, y + foot_offset)
        canvas.coords(car['leg2'], x, y, x + foot_offset, y + foot_offset)

    canvas.after(30, move_cars)

move_cars()
root.mainloop()

射擊遊戲 修


 # -*- coding: utf-8 -*-

import pygame

import sys

import random


pygame.init()


# 畫面設定

WIDTH, HEIGHT = 800, 600

WHITE = (255, 255, 255)

BLUE = (0, 200, 255)


screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("射擊遊戲")


# 載入圖片

enemy_img = pygame.image.load("enemy_ship.png")

enemy_img = pygame.transform.scale(enemy_img, (60, 40))


player_image = pygame.image.load("player_turret.jpg")

player_image = pygame.transform.scale(player_image, (80, 60))


# 玩家位置與速度

player_width = 80

player_height = 60

player_x = WIDTH // 2 - player_width // 2

player_y = HEIGHT - player_height - 10

player_speed = 8


# 子彈設定

bullet_width = 5

bullet_height = 10

bullet_speed = 8

bullets = []


# 敵人設定

enemy_rows = 5

enemy_cols = 10

enemy_width = WIDTH // enemy_cols

enemy_height = 40

enemies = []


for row in range(enemy_rows):

    for col in range(enemy_cols):

        x = col * enemy_width + 10

        y = row * enemy_height + 40

        rect = pygame.Rect(x, y, 60, 40)

        enemies.append({'rect': rect, 'alive': True})


# 分數

score = 0

font = pygame.font.SysFont(None, 36)


# 遊戲主迴圈

clock = pygame.time.Clock()

running = True

while running:

    clock.tick(60)


    # 事件處理

    for event in pygame.event.get():

        if event.type == pygame.QUIT:

            running = False

        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:

            bullet_x = player_x + player_width // 2 - bullet_width // 2

            bullet_y = player_y

            bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))


    ss = random.randint(1,10)    

    if ss >= 9:

        bullet_x = player_x + player_width // 2 - bullet_width // 2

        bullet_y = player_y

        bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))


    # 控制玩家左右移動

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT]:

        player_x -= player_speed

    if keys[pygame.K_RIGHT]:

        player_x += player_speed

    player_x += random.randint(-40,60)

    if player_x> WIDTH - player_width:

        for k in range(3):

            bullet_x = player_x + player_width // 2 - bullet_width // 2

            bullet_y = player_y

            bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))

        player_x = 10

    player_x = max(0, min(WIDTH - player_width, player_x))


    # 更新子彈

    for bullet in bullets[:]:

        bullet.y -= bullet_speed

        if bullet.bottom < 0:

            bullets.remove(bullet)


    # 子彈擊中敵人

    for bullet in bullets[:]:

        for enemy in enemies:

            if enemy['alive'] and enemy['rect'].colliderect(bullet):

                enemy['alive'] = False

                bullets.remove(bullet)

                score += 10

                break


    # 畫面更新

    screen.fill(WHITE)


    # 畫敵人

    for enemy in enemies:

        if enemy['alive']:

            screen.blit(enemy_img, enemy['rect'].topleft)


    # 畫玩家炮塔

    screen.blit(player_image, (player_x, player_y))


    # 畫子彈

    for bullet in bullets:

        pygame.draw.rect(screen, BLUE, bullet)


    # 分數

    score_text = font.render(f"Score: {score}", True, (0, 0, 0))

    screen.blit(score_text, (10, 10))


    pygame.display.flip()


pygame.quit()

sys.exit()

射擊遊戲

 import pygame

import sys


pygame.init()


# 畫面設定

WIDTH, HEIGHT = 800, 600

WHITE = (255, 255, 255)

BLUE = (0, 200, 255)


screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("射擊遊戲 - 玩家是飛機")


# 載入圖片

enemy_img = pygame.image.load("enemy_ship.png")

enemy_img = pygame.transform.scale(enemy_img, (60, 40))


player_image = pygame.image.load("player_turret.jpg")

player_image = pygame.transform.scale(player_image, (80, 60))


# 玩家位置與速度

player_width = 80

player_height = 60

player_x = WIDTH // 2 - player_width // 2

player_y = HEIGHT - player_height - 10

player_speed = 8


# 子彈設定

bullet_width = 5

bullet_height = 10

bullet_speed = 8

bullets = []


# 敵人設定

enemy_rows = 5

enemy_cols = 10

enemy_width = WIDTH // enemy_cols

enemy_height = 40

enemies = []


for row in range(enemy_rows):

    for col in range(enemy_cols):

        x = col * enemy_width + 10

        y = row * enemy_height + 40

        rect = pygame.Rect(x, y, 60, 40)

        enemies.append({'rect': rect, 'alive': True})


# 分數

score = 0

font = pygame.font.SysFont(None, 36)


# 遊戲主迴圈

clock = pygame.time.Clock()

running = True

while running:

    clock.tick(60)


    # 事件處理

    for event in pygame.event.get():

        if event.type == pygame.QUIT:

            running = False

        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:

            bullet_x = player_x + player_width // 2 - bullet_width // 2

            bullet_y = player_y

            bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))


    # 控制玩家左右移動

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT]:

        player_x -= player_speed

    if keys[pygame.K_RIGHT]:

        player_x += player_speed

    player_x = max(0, min(WIDTH - player_width, player_x))


    # 更新子彈

    for bullet in bullets[:]:

        bullet.y -= bullet_speed

        if bullet.bottom < 0:

            bullets.remove(bullet)


    # 子彈擊中敵人

    for bullet in bullets[:]:

        for enemy in enemies:

            if enemy['alive'] and enemy['rect'].colliderect(bullet):

                enemy['alive'] = False

                bullets.remove(bullet)

                score += 10

                break


    # 畫面更新

    screen.fill(WHITE)


    # 畫敵人

    for enemy in enemies:

        if enemy['alive']:

            screen.blit(enemy_img, enemy['rect'].topleft)


    # 畫玩家炮塔

    screen.blit(player_image, (player_x, player_y))


    # 畫子彈

    for bullet in bullets:

        pygame.draw.rect(screen, BLUE, bullet)


    # 分數

    score_text = font.render(f"Score: {score}", True, (0, 0, 0))

    screen.blit(score_text, (10, 10))


    pygame.display.flip()


pygame.quit()

sys.exit()

打磚塊

 


import pygame

import sys

import random


pygame.init()


# 畫面設定

WIDTH, HEIGHT = 800, 600

WHITE = (255, 255, 255)

RED = (255, 0, 0)

BLUE = (0, 100, 255)

COLORS = [(255, 100, 100), (255, 200, 0), (0, 200, 100), (100, 100, 255), (200, 0, 200)]


screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("打磚塊遊戲")


# 玩家方塊

player_width = 100

player_height = 20

player_x = WIDTH // 2 - player_width // 2

player_y = HEIGHT - 75

player_speed = 8


# 球

ball_radius = 10

ball_x = WIDTH // 2

ball_y = HEIGHT // 2

ball_x_speed = 12

ball_y_speed = -12


# 磚塊設定(5列×10行)

brick_rows = 5

brick_cols = 10

brick_width = WIDTH // brick_cols

brick_height = 25

bricks = []


for row in range(brick_rows):

    for col in range(brick_cols):

        x = col * brick_width

        y = row * brick_height + 40  # 從 y=40 開始畫

        rect = pygame.Rect(x, y, brick_width - 2, brick_height - 2)

        color = COLORS[row % len(COLORS)]

        bricks.append({'rect': rect, 'color': color, 'alive': True})


# 分數

score = 0

font = pygame.font.SysFont(None, 36)


clock = pygame.time.Clock()

running = True

while running:

    clock.tick(60)


    # 事件處理

    for event in pygame.event.get():

        if event.type == pygame.QUIT:

            running = False


    # 玩家左右控制

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT]:

        player_x -= player_speed

    if keys[pygame.K_RIGHT]:

        player_x += player_speed

    player_x = max(0, min(WIDTH - player_width, player_x))


    # 球移動

    ball_x += ball_x_speed

    ball_y += ball_y_speed


    # 左右牆反彈

    if ball_x - ball_radius <= 0 or ball_x + ball_radius >= WIDTH:

        ball_x_speed = -ball_x_speed


    # 上下邊界反彈

    if ball_y - ball_radius <= 0:

        ball_y_speed = -ball_y_speed


    # 掉到底部,遊戲重置

    if ball_y > HEIGHT:

        ball_x = WIDTH // 2

        ball_y = HEIGHT // 2

        ball_x_speed = 4

        ball_y_speed = -4

        score = 0

        for b in bricks:

            b['alive'] = True


    # 撞玩家方塊

    player_rect = pygame.Rect(player_x, player_y, player_width, player_height)

    if player_rect.collidepoint(ball_x, ball_y + ball_radius) and ball_y_speed > 0:

        ball_y_speed = -ball_y_speed


    # 撞磚塊

    for b in bricks:

        if b['alive'] and b['rect'].collidepoint(ball_x, ball_y):

            b['alive'] = False

            ball_y_speed = -ball_y_speed

            score += 10

            break


    # 畫面更新

    screen.fill(WHITE)


    # 畫磚塊

    for b in bricks:

        if b['alive']:

            pygame.draw.rect(screen, b['color'], b['rect'])


    # 畫玩家與球

    pygame.draw.rect(screen, RED, player_rect)

    pygame.draw.circle(screen, BLUE, (int(ball_x), int(ball_y)), ball_radius)


    # 分數顯示

    score_text = font.render(f"Score: {score}", True, (0, 0, 0))

    screen.blit(score_text, (10, 10))


    pygame.display.flip()


pygame.quit()

sys.exit()