溫馨提醒:這是教學用的簡化版,並非真實商品定價或醫療建議。實務需要大量統計資料、法規與精算檢核。
import csv
from math import pow
# 1) 基礎保費:按年齡帶(示意金額,單位:TWD/年)
AGE_BASE = [
(18, 29, 6000),
(30, 39, 7200),
(40, 49, 9000),
(50, 59, 12000),
(60, 65, 16000)
]
# 2) BMI 分級與對應風險加成(僅示意)
# 例如 0.15 代表 +15%
BMI_BANDS = [
("體重過輕", None, 18.5, 0.10),
("正常", 18.5, 24.0, 0.00),
("過重", 24.0, 27.0, 0.15),
("肥胖 I", 27.0, 30.0, 0.30),
("肥胖 II", 30.0, 35.0, 0.60),
("肥胖 III", 35.0, None, 1.00),
]
SMOKER_LOADING = 0.40 # 吸菸者 +40%(示意)
def bmi_value(height_cm: float, weight_kg: float) -> float:
h_m = height_cm / 100.0
return weight_kg / pow(h_m, 2)
def bmi_class_and_loading(bmi: float):
for name, lo, hi, ld in BMI_BANDS:
if (lo is None or bmi >= lo) and (hi is None or bmi < hi):
return name, ld
return "未定義", 0.0
def base_premium_by_age(age: int) -> int:
for lo, hi, base in AGE_BASE:
if lo <= age <= hi:
return base
# 若超出範圍,給予簡單外推(示意)
if age < AGE_BASE[0][0]:
return AGE_BASE[0][2]
return int(AGE_BASE[-1][2] * 1.3)
def quote_premium(profile: dict):
age = profile["age"]
h = profile["height_cm"]
w = profile["weight_kg"]
smoker = profile.get("smoker", False)
bmi = round(bmi_value(h, w), 1)
bmi_cls, bmi_ld = bmi_class_and_loading(bmi)
base = base_premium_by_age(age)
total_loading = bmi_ld + (SMOKER_LOADING if smoker else 0.0)
premium = round(base * (1 + total_loading))
breakdown = {
"name": profile.get("name", ""),
"age": age,
"height_cm": h,
"weight_kg": w,
"smoker": "是" if smoker else "否",
"BMI": bmi,
"BMI分級": bmi_cls,
"基礎保費": base,
"風險加成(%)": f"{int(total_loading*100)}%",
"年保費_估": premium
}
return breakdown
# 3) 測試三位被保人(你可以自行修改)
people = [
{"name": "Alice", "age": 29, "height_cm": 165, "weight_kg": 56, "smoker": False}, # 正常
{"name": "Bob", "age": 43, "height_cm": 175, "weight_kg": 88, "smoker": False}, # 過重/肥胖I邊緣
{"name": "Carol", "age": 37, "height_cm": 160, "weight_kg": 95, "smoker": True}, # 肥胖II + 吸菸
]
rows = [quote_premium(p) for p in people]
# 列印結果
print("=== BMI 保費模擬(示意)===")
for r in rows:
print(f"{r['name']:>5}|年齡:{r['age']:>2} |BMI:{r['BMI']:>4}({r['BMI分級']})"
f"|基礎保費:{r['基礎保費']:>6}|加成:{r['風險加成(%)']:>4}|估算年保費:{r['年保費_估']:>6}|吸菸:{r['smoker']}")
# 4) 輸出 CSV,方便後續視覺化或做報告
with open("premium_quote.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
print("\n✅ 已輸出報價列表:premium_quote.csv")