iT邦幫忙

0

Day 16:歷史紀錄查詢——查看過去的健康資料

  • 分享至 

  • xImage
  •  

一、前言

在第十五天的學習中,我已經將 Streamlit 表單與 CSV 資料保存功能整合,讓使用者可以輸入每日健康習慣,並將資料保存至 health_records.csv。這代表系統已經具備基本的資料新增功能,不再只是暫時顯示輸入結果。

然而,只有新增資料還不夠。如果使用者想知道自己前幾天喝了多少水、睡了多久,或是最近的運動習慣有沒有改變,就需要能夠重新讀取並查看過去保存的紀錄。

因此,今天的學習目標是建立歷史紀錄查詢功能,利用 Pandas 讀取 CSV 檔案,再透過 Streamlit 將資料呈現在網頁中,讓使用者可以查看所有紀錄、依日期篩選資料,並快速找到自己想查詢的內容。

二、歷史紀錄查詢的設計需求

在開始撰寫程式之前,需要先思考使用者查看歷史資料時會有哪些需求。

本次系統將設計以下功能:

https://ithelp.ithome.com.tw/upload/images/20261027/20178903AFRoBi2q5c.png

透過這些功能,使用者可以更方便地查看自己的健康紀錄,也能為後續的平均值計算、每週運動分析與資料視覺化建立基礎。

三、使用 Pandas 讀取 CSV 檔案

在第十一天的學習中,我已經認識 pd.read_csv(),知道它可以將 CSV 檔案中的表格資料讀取成 Pandas DataFrame。

今天將再次運用這個方法,取得先前保存的健康紀錄。

import pandas as pd
from pathlib import Path

FILE_PATH = Path("health_records.csv")

if FILE_PATH.exists():
records = pd.read_csv(FILE_PATH)
print(records)
else:
print("目前還沒有健康紀錄。")

這段程式會先確認 CSV 檔案是否存在。

如果檔案存在,就讀取其中的資料並顯示;如果檔案尚未建立,則提示目前沒有健康紀錄,避免程式因為找不到檔案而直接中斷。

這個判斷很重要,因為使用者第一次開啟系統時,可能還沒有新增任何資料。

四、將歷史紀錄顯示在 Streamlit 網頁

完成資料讀取後,接下來要將資料從終端機搬到網頁介面中。

Streamlit 提供 st.dataframe(),可以將 Pandas DataFrame 以互動式表格呈現,讓使用者直接在網頁上查看資料。

import streamlit as st
import pandas as pd
from pathlib import Path

FILE_PATH = Path("health_records.csv")

st.title("個人健康習慣追蹤系統")
st.header("歷史健康紀錄")

if FILE_PATH.exists():
records = pd.read_csv(FILE_PATH)

if records.empty:
    st.info("目前還沒有健康紀錄,請先新增資料。")
else:
    st.dataframe(
        records,
        use_container_width=True
    )

else:
st.info("目前還沒有健康紀錄,請先新增資料。")

完成後,將程式儲存為 app.py,並在終端機執行:

python -m streamlit run app.py

如果你的環境使用 python3,也可以執行:

python3 -m streamlit run app.py

開啟網頁後,如果 CSV 中已經有資料,就會顯示健康紀錄表格;如果檔案不存在或沒有任何資料,則會顯示提醒訊息。

這樣就完成了最基本的歷史紀錄查詢介面。

五、依日期排序歷史紀錄

當健康紀錄越來越多時,如果資料順序不一致,就不容易快速找到最近的紀錄。

因此,可以將日期欄位轉換成日期型態,再按照日期排序,讓最新的紀錄顯示在前面。

records["date"] = pd.to_datetime(
records["date"],
errors="coerce"
)

records = records.dropna(subset=["date"])

records = records.sort_values(
by="date",
ascending=False
)

st.dataframe(
records,
use_container_width=True
)

其中:

pd.to_datetime():將日期文字轉換成日期型態。

errors="coerce":遇到無法解析的日期時,將其轉換成缺失值。

dropna(subset=["date"]):移除日期無法解析的紀錄,避免錯誤日期影響查詢。

sort_values():依指定欄位排序。

ascending=False:採用由新到舊的順序。

在實際系統中,移除無效日期前應考慮是否需要保留原始資料供檢查。本例是為了示範基本的排序處理,並不會直接修改原始 CSV 檔案。

六、加入日期範圍篩選功能

除了查看全部紀錄,使用者也可能只想查看某段時間內的健康資料,例如上週的運動情況,或某幾天的睡眠時間。

因此,可以利用 Streamlit 的日期選擇器,讓使用者選擇查詢的開始日期與結束日期。

import streamlit as st
import pandas as pd
from pathlib import Path
from datetime import date

FILE_PATH = Path("health_records.csv")

st.title("個人健康習慣追蹤系統")
st.header("歷史健康紀錄查詢")

if not FILE_PATH.exists():
st.info("目前還沒有健康紀錄,請先新增資料。")

else:
records = pd.read_csv(FILE_PATH)

if records.empty:
    st.info("目前還沒有健康紀錄,請先新增資料。")

else:
    records["date"] = pd.to_datetime(
        records["date"],
        errors="coerce"
    )

    records = records.dropna(subset=["date"])

    if records.empty:
        st.warning("目前沒有可供查詢的有效日期紀錄。")

    else:
        min_date = records["date"].min().date()
        max_date = records["date"].max().date()

        start_date = st.date_input(
            "開始日期",
            value=min_date,
            min_value=min_date,
            max_value=max_date
        )

        end_date = st.date_input(
            "結束日期",
            value=max_date,
            min_value=min_date,
            max_value=max_date
        )

        if start_date > end_date:
            st.error("開始日期不能晚於結束日期。")

        else:
            filtered_records = records[
                (records["date"].dt.date >= start_date)
                & (records["date"].dt.date <= end_date)
            ]

            filtered_records = filtered_records.sort_values(
                by="date",
                ascending=False
            )

            st.write(
                "符合條件的紀錄筆數:",
                len(filtered_records)
            )

            if filtered_records.empty:
                st.info("這段日期範圍內沒有健康紀錄。")
            else:
                st.dataframe(
                    filtered_records,
                    use_container_width=True
                )

這段程式會先取得目前資料中最早與最晚的日期,再讓使用者選擇查詢範圍。

接著,系統會比較每筆資料的日期是否落在指定區間內,並將符合條件的紀錄顯示在網頁中。

例如,如果使用者選擇 10 月 20 日至 10 月 25 日,系統就會顯示這段期間內的紀錄。

需要注意的是,這裡的日期範圍會受到現有資料的最早及最晚日期限制。如果未來希望查詢沒有紀錄的日期區間,也可以再調整日期選擇器的限制方式。

七、整理歷史紀錄查詢頁面

完成上述功能後,歷史紀錄查詢頁面就具備了以下能力:

自動讀取先前保存的 CSV 資料。

在網頁中顯示所有健康紀錄。

將日期整理成統一格式。

依照日期由新到舊排序。

依照指定日期範圍篩選資料。

顯示符合條件的紀錄筆數。

在沒有資料或日期無效時顯示提示訊息。

這些功能能讓使用者更容易掌握自己的紀錄,也讓資料不再只是被保存,而是真正能被查詢與使用。

需要注意的是,上述程式片段是不同階段的示範。如果要整合成正式的 app.py,應將它們合併成同一份完整程式,而不是將每一段都重複貼上執行。

八、今日實作與測試

今天可以透過以下步驟確認系統是否正常運作:

先使用第十五天的表單新增至少兩筆不同日期的健康紀錄。

確認 health_records.csv 已經建立,且資料內容正確。

在 Streamlit 網頁中開啟歷史紀錄查詢功能。

確認全部紀錄是否能正常顯示。

測試日期排序,確認較新的紀錄會顯示在前面。

選擇不同的開始日期與結束日期,確認篩選結果是否正確。

測試尚未建立 CSV 檔案或查詢結果為空的情況,確認系統會顯示適當的提示訊息。

如果以上測試都能正常完成,就代表系統已經具備基本的歷史紀錄查詢能力。

九、今日成果與學習心得

透過今天的學習,我將第十五天建立的資料保存功能進一步延伸,讓健康習慣追蹤系統不僅能新增資料,也能重新讀取與查詢過去的紀錄。

今天複習了 Pandas 的資料讀取與排序方法,並學習使用 Streamlit 的互動式表格與日期選擇器,完成歷史資料呈現及日期範圍篩選。

這項功能讓系統開始具備基本的資料管理能力,也為後續的健康數據統計與圖表分析提供了資料來源。

不過,目前系統還沒有提供修改或刪除既有紀錄的功能。如果使用者輸入錯誤,仍然需要直接處理資料檔案,操作上不夠方便。

十、下一步學習方向

Day 17 將學習「資料修改與刪除——完善基本紀錄管理功能」。

接下來會進一步設計修改與刪除功能,讓使用者可以針對既有的健康紀錄進行調整,或移除不需要的資料,逐步完成健康習慣追蹤系統的基本資料管理流程。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言