steveyehtw commited on
Commit
765a856
·
verified ·
1 Parent(s): 46b450b

Update classroom week20

Browse files
classroom_data/templates/week20/main.py CHANGED
@@ -1,12 +1,8 @@
1
- """資料分析:讀取公開資料,查詢各縣市學生人數。"""
2
-
3
  import csv
4
  from pathlib import Path
5
 
6
 
7
- DATA_FILE = Path("data/students_by_county.csv")
8
- SAMPLE_YEAR = "114"
9
- SAMPLE_FIELD = "國小[人]"
10
 
11
 
12
  def load_rows(path=DATA_FILE):
@@ -16,72 +12,83 @@ def load_rows(path=DATA_FILE):
16
 
17
 
18
  def parse_count(value):
19
- """將有人數的欄位轉成整數;空白或非數字代表未知,不當成 0。"""
20
  cleaned = (value or "").strip().replace(",", "")
21
  if not cleaned or cleaned == "-":
22
  return None
23
  try:
24
  return int(cleaned)
25
  except ValueError:
26
- return None
 
 
 
27
 
28
 
29
- def count_by_county(rows, school_year, field):
30
- """依學年度篩選,再回傳各縣市的人數排序。"""
31
- totals = {}
32
  for row in rows:
33
- if row.get("學年度", "").strip() != str(school_year):
34
- continue
35
-
36
- count = parse_count(row.get(field))
37
- county = row.get("縣市別", "").strip()
38
- if county and count is not None:
39
- totals[county] = count
40
-
41
- return sorted(totals.items(), key=lambda item: item[1], reverse=True)
42
-
43
-
44
- def get_count(rows, school_year, county, field):
45
- """取得指定學年度、縣市及欄位的人數;找不到時回傳 None。"""
 
 
 
46
  for row in rows:
47
- if row.get("學年度", "").strip() != str(school_year):
48
- continue
49
- if row.get("縣市別", "").strip() == county:
50
- return parse_count(row.get(field))
51
- return None
52
-
53
-
54
- def print_text_chart(results, limit=8):
55
- """在 Console 印出簡單長條圖,讓每筆數字都能被核對。"""
56
- if not results:
57
- print("沒有符合條件的資料,請檢查學年度和欄位名稱。")
58
  return
59
 
60
- visible = results[:limit]
61
  largest = max(value for _, value in visible)
62
- print("縣市 人數 | 比例長條")
63
- for county, value in visible:
 
64
  bar_length = round(value / largest * 24) if largest else 0
65
- print(f"{county:<6} {value:>8,} | {'█' * bar_length}")
66
 
67
 
68
  def main():
69
  rows = load_rows()
70
  fields = list(rows[0]) if rows else []
71
- print("=== 資料分析:縣市學生人數 ===")
72
  print(f"讀入 {len(rows)} 列資料")
73
  print(f"欄位:{', '.join(fields)}")
74
  print()
75
 
76
- # 範例問題:114 學年度,哪些縣市的國小學生人數最多?
77
- question = f"{SAMPLE_YEAR} 學年度,哪些縣市的 {SAMPLE_FIELD} 最多?"
78
- results = count_by_county(rows, SAMPLE_YEAR, SAMPLE_FIELD)
79
- print(f"範例問題:{question}")
80
- print_text_chart(results)
 
 
 
 
 
 
 
 
81
 
82
- # 你的下一步:換一個學年度、教育階段或可比較的欄位,
83
- # 先寫下預測,再執行並核對其中一筆原始資料。
84
 
85
 
86
  if __name__ == "__main__":
87
- main()
 
 
 
1
  import csv
2
  from pathlib import Path
3
 
4
 
5
+ DATA_FILE = Path("data.csv")
 
 
6
 
7
 
8
  def load_rows(path=DATA_FILE):
 
12
 
13
 
14
  def parse_count(value):
15
+ """將數字欄位轉成整數或浮點數;空白或非數字代表未知,不當成 0。"""
16
  cleaned = (value or "").strip().replace(",", "")
17
  if not cleaned or cleaned == "-":
18
  return None
19
  try:
20
  return int(cleaned)
21
  except ValueError:
22
+ try:
23
+ return float(cleaned)
24
+ except ValueError:
25
+ return None
26
 
27
 
28
+ def analyze_extremes(rows, field):
29
+ """找出指定欄位在各統計期中最高與最低的年份與數值。"""
30
+ valid_rows = []
31
  for row in rows:
32
+ period = row.get("統計期", "").strip()
33
+ val = parse_count(row.get(field))
34
+ if period and val is not None:
35
+ valid_rows.append((period, val))
36
+
37
+ if not valid_rows:
38
+ return None, None
39
+
40
+ max_item = max(valid_rows, key=lambda item: item[1])
41
+ min_item = min(valid_rows, key=lambda item: item[1])
42
+ return max_item, min_item
43
+
44
+
45
+ def print_text_chart(rows, field, label, limit=10):
46
+ """在 Console 印出簡單長條圖,讓數字趨勢便於檢視。"""
47
+ valid_rows = []
48
  for row in rows:
49
+ period = row.get("統計期", "").strip()
50
+ val = parse_count(row.get(field))
51
+ if period and val is not None:
52
+ valid_rows.append((period, val))
53
+
54
+ if not valid_rows:
55
+ print(f"沒有符合條件的資料:{label}")
 
 
 
 
56
  return
57
 
58
+ visible = valid_rows[-limit:]
59
  largest = max(value for _, value in visible)
60
+ print(f"\n=== {label} 近期趨勢與長條圖 ===")
61
+ print(f"統計期 人數 | 比例長條")
62
+ for period, value in visible:
63
  bar_length = round(value / largest * 24) if largest else 0
64
+ print(f"{period:<6} {value:>10,} | {'█' * bar_length}")
65
 
66
 
67
  def main():
68
  rows = load_rows()
69
  fields = list(rows[0]) if rows else []
70
+ print("=== 資料分析:人口統計資料 ===")
71
  print(f"讀入 {len(rows)} 列資料")
72
  print(f"欄位:{', '.join(fields)}")
73
  print()
74
 
75
+ targets = [
76
+ ("人口數/總計[人]", "全部總計人口"),
77
+ ("人口數/男[人]", "男性人口"),
78
+ ("人口數/女[人]", "女性人口")
79
+ ]
80
+
81
+ for field, label in targets:
82
+ max_item, min_item = analyze_extremes(rows, field)
83
+ if max_item and min_item:
84
+ print(f"【{label}分析】")
85
+ print(f" - 最高:{max_item[0]}(共 {max_item[1]:,} 人)")
86
+ print(f" - 最低:{min_item[0]}(共 {min_item[1]:,} 人)")
87
+ print()
88
 
89
+ # 範例:印出總計人口的近期長條圖
90
+ print_text_chart(rows, "人口數/總計[人]", "全部總計人口")
91
 
92
 
93
  if __name__ == "__main__":
94
+ main()