import csv from pathlib import Path DATA_FILE = Path("") def load_rows(path=DATA_FILE): """讀取 CSV;utf-8-sig 也能正確處理政府資料常見的 BOM。""" with open(path, encoding="utf-8-sig", newline="") as file: return list(csv.DictReader(file)) def parse_count(value): """將數字欄位轉成整數或浮點數;空白或非數字代表未知,不當成 0。""" cleaned = (value or "").strip().replace(",", "") if not cleaned or cleaned == "-": return None try: return int(cleaned) except ValueError: try: return float(cleaned) except ValueError: return None def analyze_extremes(rows, field): """找出指定欄位在各統計期中最高與最低的年份與數值。""" valid_rows = [] for row in rows: period = row.get("統計期", "").strip() val = parse_count(row.get(field)) if period and val is not None: valid_rows.append((period, val)) if not valid_rows: return None, None max_item = max(valid_rows, key=lambda item: item[1]) min_item = min(valid_rows, key=lambda item: item[1]) return max_item, min_item def print_text_chart(rows, field, label, limit=10): """在 Console 印出簡單長條圖,讓數字趨勢便於檢視。""" valid_rows = [] for row in rows: period = row.get("統計期", "").strip() val = parse_count(row.get(field)) if period and val is not None: valid_rows.append((period, val)) if not valid_rows: print(f"沒有符合條件的資料:{label}") return visible = valid_rows[-limit:] largest = max(value for _, value in visible) print(f"\n=== {label} 近期趨勢與長條圖 ===") print(f"統計期 人數 | 比例長條") for period, value in visible: bar_length = round(value / largest * 24) if largest else 0 print(f"{period:<6} {value:>10,} | {'█' * bar_length}") def main(): rows = load_rows() fields = list(rows[0]) if rows else [] print("=== 資料分析:人口統計資料 ===") print(f"讀入 {len(rows)} 列資料") print(f"欄位:{', '.join(fields)}") print() targets = [ ("", "全部總計人口"), ("", "男性人口"), ("", "女性人口") ] for field, label in targets: max_item, min_item = analyze_extremes(rows, field) if max_item and min_item: print(f"【{label}分析】") print(f" - 最高:{max_item[0]}(共 {max_item[1]:,} 人)") print(f" - 最低:{min_item[0]}(共 {min_item[1]:,} 人)") print() # 範例:印出總計人口的近期長條圖 # print_text_chart(rows, "人口數/總計[人]", "全部總計人口") if __name__ == "__main__": main()