iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
ChatGPT & Codex

AI 時代的輕量化開發:ChatGPT 打造 LINE 多模態記帳與續訂預警 Agent系列 第 18

[Day 18] 消費資料也能做 Data Aggregation?SubWise 實作每日支出分析

  • 分享至 

  • xImage
  •  

前言

前幾天完成消費分析功能後,SubWise 已經能夠計算分類支出、找出最高支出類別、追蹤消費筆數,並找出最高單筆消費。但實際檢視使用情境時,還有一個非常直覺且核心的問題:「我這段期間到底哪一天花得最多?」

「最高單筆消費」與「最高單日消費」代表完全不同的消費行為。單筆消費 NT$150 可能是最貴的一餐,但若某一天累積了多筆小額支出(例如午餐、交通、咖啡等),單日總額達到 NT$410,那一天才是真正讓荷包失血的關鍵。因此今天的開發重點,是在 analysis_service.py 補上每日消費加總最高單日消費這兩項統計。


今日實作實錄

一、建立「每日消費加總」函式

新增 calculate_daily_totals(records),將指定期間內同一日期的消費金額進行彙整:

def calculate_daily_totals(records):
    daily_totals = {}
    for record in records:
        record_date = record.get("Date")
        if not record_date:
            continue
        record_date = str(record_date).strip()
        amount = record.get("Amount", 0)
        try:
            amount = float(amount)
        except (ValueError, TypeError):
            continue
        daily_totals[record_date] = daily_totals.get(record_date, 0) + amount
    return daily_totals

此函式以日期字串作為 key 進行累加,將原始紀錄轉換為 { '2026-08-08': 200.0, '2026-08-11': 410.0 } 的乾淨結構,不僅簡化後續比對,也為未來的每日趨勢圖表奠定基礎。

二、建立「最高單日消費」函式

有了每日加總數據後,新增 get_highest_expense_day(daily_totals),快速找出消費總額最高的一天:

def get_highest_expense_day(daily_totals):
    if not daily_totals:
        return None
    highest_date = max(daily_totals, key=daily_totals.get)
    return {
        "date": highest_date,
        "amount": daily_totals[highest_date]
    }

這個指標與原本的「最高單筆消費」形成互補:最高單筆消費回答「哪一次買東西最貴?」,最高單日消費回答「哪一天整體支出最高?」。兩者結合讓分析不再侷限於單筆極端值,而是能呈現單日的累積消費壓力。

三、整合進 Analysis Service 分層架構

依循既有的責任分工架構,將新函式串接至 get_expense_analysis()format_analysis_result()

get_expense_analysis()
├── filter_expenses()
├── calculate_expense_total()
├── calculate_category_totals()
├── calculate_category_percentages()
├── get_top_category()
├── calculate_daily_average()
├── get_highest_expense()
├── calculate_daily_totals()       ← 今天新增
├── get_highest_expense_day()      ← 今天新增
└── compare_monthly_expenses()
↓
format_analysis_result()

此處刻意在分析字典中完整保留 daily_totalshighest_expense_day,未來若要擴充「每日支出排行」或繪製趨勢圖,即可直接取用而無需重新讀取 Google Sheets。

四、補強無資料顯示與 LINE 格式化輸出

format_analysis_result() 中新增顯示區塊,並妥善處理無資料情境:

📊 SubWise 消費分析

📅 分析期間:month
💵 總支出:NT$930
🧾 消費筆數:9 筆
📊 平均每日:NT$49

🔥 最高支出類別:
• Food:NT$830 (89.2%)

💳 最高單筆消費:
• NT$150|Food|Lunch

🔥 最高單日消費:
• 2026-08-11:NT$410

📂 分類支出:
• Food:NT$830 (89.2%)
• Transport:NT$100 (10.8%)

若當日無任何消費紀錄,則一致顯示「目前沒有消費資料」,維持輸出的穩定與一致性。


測試結果

先執行語法檢查:python -m py_compile analysis_service.py 確認無語法錯誤。接著針對三種期間進行單元測試:

  • 本月daily_totals 正確彙整,最高日為 {'date': '2026-08-11', 'amount': 410.0}
    https://ithelp.ithome.com.tw/upload/images/20260819/20178527kQlCHNE0si.png

  • 本週:正確回傳當週唯一有消費紀錄的 {'date': '2026-08-13', 'amount': 320.0}
    https://ithelp.ithome.com.tw/upload/images/20260819/20178527MHDjFScrgd.png

  • 今天(無資料):daily_totals{},最高日為 None
    https://ithelp.ithome.com.tw/upload/images/20260819/20178527i9y3mcX6DJ.png

最後透過 process_ai_message('幫我分析這個月的消費') 進行端到端整合測試,確認「最高單日消費」已無縫接進 LINE → Gemini → analysis_service → Google Sheets → LINE 的完整對話分析流程。

今日完成

  • 建立 calculate_daily_totals(),完成每日消費加總
  • 建立 get_highest_expense_day(),找出指定期間內總額最高的單日消費
  • 將新指標整合至 get_expense_analysis()format_analysis_result()
  • 補強無消費資料時的例外防護與顯示格式
  • 完成本地多期間測試與 LINE Agent 整合測試

目前 SubWise 的消費分析已經涵蓋:

分析項目 功能
📅 分析期間 今天/本週/本月
💵 總支出 計算期間總消費
🧾 消費筆數 統計消費次數
📊 平均每日 計算每日平均支出
🔥 最高支出類別 找出花最多錢的類別
📂 分類支出 顯示各類別金額與比例
💳 最高單筆消費 找出期間內最昂貴的單筆
🔥 最高單日消費 找出期間內花費最多的單日
📊 月度比較 比較本月與上月變化
💡 智慧消費提醒 根據分析結果提供洞察提醒
🛡️ 無資料處理 沒有消費紀錄時正常回覆

明日預告

分析維度逐步健全後,明天 Day 19 我們將聚焦於互動體驗與主動提醒——探討如何在使用者記帳的當下,即時比對歷史常態並主動提示消費異常,讓 SubWise 從「被動查詢」更進一步走向「主動輔助」的智慧理財助理。我們明天見!


上一篇
[Day 17] 消費分析再進化!SubWise 揪出最高單筆消費與支出重點
系列文
AI 時代的輕量化開發:ChatGPT 打造 LINE 多模態記帳與續訂預警 Agent18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言