syugyo


```python
new_task = {
    "日付": "2025-01-03",
    "開始時刻": "16:17:00",
    "終了時刻": "16:17:00",
    "カテゴリ": "日常",
    "タスク名": "メール確認",
    "タスク概要": " 作業者のエスコートを実施aa"
}

processor = DataFrameProcessor(r"/Users/ryosuke/Documents/nas_mirror/DevelopingEnv_streamlit/data/daily_report.csv")
processor.read_csv_with_uuid()
processor.add_row_with_dict(new_task)
processor.update_df(new_df)
```


```python
import streamlit as st
import pandas as pd
from datetime import datetime, timedelta
import json
from dataclasses import dataclass

import uuid



class DataFrameProcessor():
    def __init__(self, filepath):
        self.filepath = filepath

    def read_csv_with_uuid(self):
        self.df = pd.read_csv(self.filepath)
        # 各行に UUID を追加してindex列に指定
        self.df["uuid"] = [str(uuid.uuid4()) for _ in range(len(self.df))]
        self.df.set_index("uuid", inplace=True)  # UUID をインデックス化

    def save_df_without_uuid(self):
        self.df.drop(columns=["uuid"], inplace=True)
        self.df.to_csv(self.file_path, index=False)

    def update_df(self, df_part):
        """UUID をキーとして self.df を df_part で更新"""
        self.df.update(df_part)  # 上書き更新

    def add_row_with_dict(self, new_row_dict):
        # uuidを振ってから追加する必要がある
        self.df = pd.concat([self.df, pd.DataFrame([new_row_dict])], ignore_index=True)

    def show_data(self):
        print(self.df)

    def show_information(self):
        pass





# メインアプリ
def main():
    # 初期設定---------------------------------------------------
    # 共通パラメータjsonの読み込み
    try:
        with open("data/common_params.json", "r") as f:
            common_params = json.load(f)
    except FileNotFoundError:
        st.error("共通設定ファイルが見つかりません")

    # 共通変数
    file_path:str = common_params['file_path']['daily_report']


    # 作業記録ファイルの読み込み
    processor = DataFrameProcessor(file_path)
    processor.read_csv_with_uuid()

    # "日付" 列を datetime 型に変換(あとでクラスに反映)
    processor.df["日付"] = pd.to_datetime(processor.df["日付"]).dt.date  # `dt.date` で `datetime.date` 型にする



    # ページ設定---------------------------------------------------
    st.title("📝 作業記録アプリ")
    tab1, tab2, tab3 = st.tabs(["日々作業入力","週報作成" ,"分析"])

    # tab1(作業入力タブ)
    with tab1:
        # 変数定義(tab1用)
        task_category: list = ["日常", "PJ-A", "PJ-B"]


        # streamlit入力フォーム
        with st.form("my_form", clear_on_submit=True, enter_to_submit=False):
            col1, col2, col3, col4 = st.columns(4)
            with col1:
                task_date = st.date_input("日付")
            with col2:
                start_time = st.time_input("開始時刻", datetime.now())
            with col3:
                end_time = st.time_input("終了時刻", datetime.now())
            with col4:
                task_category = st.selectbox("カテゴリ",task_category)
                
            col1, col2 = st.columns([1, 3])
            with col1:
                task_name = st.text_input("タスク名", value="")
            with col2:
                description = st.text_input("タスク詳細")
            

            submitted = st.form_submit_button("記録する")
            if submitted:
                # 追加する行を作成
                new_task = {
                    "日付": task_date,
                    "開始時刻": start_time,
                    "終了時刻": end_time,
                    "カテゴリ": task_category,
                    "タスク名": task_name,
                    "タスク概要": description
                }

                # 行の追加と保存処理
                processor.add_row_with_dict(new_task)
                processor.save_df_without_uuid()
                st.toast(':floppy_disk:保存されました')





        # 過去のデータ閲覧(フィルタリング機能あり)
        with st.expander("生データを見る", expanded=True):
            # フィルタリング条件を取得s
            col1, col2, col3 = st.columns([1, 1, 3])
            with col1:
                filter_num = st.selectbox("表示件数", (5, 10, 15))
            with col2:
                filter_category = st.selectbox("カテゴリ", processor.df["カテゴリ"].unique())
            with col3:
                filter_date = st.date_input(
                    "日付を選択してください",
                    value=None,
                    min_value=processor.df["日付"].min(),
                    max_value=processor.df["日付"].max()
                )

            # フィルタリングの実行
            filtered_df = processor.df.copy()
            if filter_date:
                filtered_df = filtered_df[filtered_df["日付"] == pd.Timestamp(filter_date)]
            if filter_category:
                filtered_df = filtered_df[filtered_df["カテゴリ"] == filter_category]

            filtered_df = filtered_df.head(filter_num)

            # フィルタリングされたdfに削除チェックカラムを追加してを編集可能にして表示
            # 削除チェックカラムの追加
            # 編集可能にして表示
            edited_df = st.data_editor(filtered_df)

            # 保存処理
            if st.button("保存"):
                # 元データに編集内容を反映
                processor.update_df(edited_df)

                # 保存
                processor.save_df_without_uuid()
                st.toast(':floppy_disk:保存されました')



```


```python
日付,カテゴリ,開始時刻,終了時刻,タスク名,タスク概要
2025-01-03,日常,2025-01-04 16:17:00,2025-01-04 16:17:00,メール確認,月曜の朝なのでメールが多めだった、客先からの問い合わせがあり、返信を作成するのに時間がかかった
2025-01-03,PJ-A,2025-01-04 16:18:00,2025-01-04 16:18:00,音響試験の試験規格作成,音響試験の試験規格の作成をした。前の機種からのコピペが多く7割くらいは完成した。
2025-01-03,日常,2025-01-04 16:18:00,2025-01-04 16:18:00,,
2025-01-03,PJ-B,2025-01-04 16:18:00,2025-01-04 16:18:00,エスコート,作業者のエスコートを実施
2025-01-03,日常,2025-01-04 16:18:00,2025-01-04 16:18:00,,
2025-01-03,日常,2025-01-04 16:18:00,2025-01-04 16:18:00,,
2025-01-03,PJ-A,2025-01-04 16:18:00,2025-01-04 16:18:00,正弦波試験の調整,別部署の担当者の予定が合わず確認中。
2025-01-03,日常,2025-01-04 16:18:00,2025-01-04 16:18:00,aあ,
2025-01-04,PJ-B,2025-01-04 16:59:00,2025-01-04 16:59:00,エスコート,エスコートしました
2025-01-04,PJ-B,2025-01-04 17:06:00,2025-01-04 17:06:00,エスコート,エスコートした
2025-01-04,PJ-B,2025-01-04 17:14:00,2025-01-04 17:14:00,エスコート,エスコートした

```