【Python】オブジェクト指向で作るメンタルログ

IT

こんにちは!Yuinaです✨

自分の心の状態を客観的に見える化し、整理できる「メンタルログ」を作ってみることにしました。

このブログでは、Pythonのクラスや継承を使って、自分専用のメンタルルーティンをどう設計したかを紹介します。

プログラミングと心のケア、両方に興味がある方に参考になれば嬉しいです。

オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識

新品価格
¥2,376から
(2025/7/20 13:46時点)

環境とコードの構造

構造はこんな感じです!

環境はこちらです。

・言語:Python3

・エディタ:VSCODE

・OS:MAC(M3チップ)

よろしくお願いいたします!

コードはこちら

main.py

from routines.negative_reflection import NegativeReflectionRoutine
from routines.present_moment import PresentMomentRoutine
from routines.breathing import BreathingRoutine
from routines.gratitude import GratitudeRoutine

import json
import os
from logger import MentalLogger # 修正:正しい相対パスに変更

# 設定ファイルを読み込む関数
def load_settings():
config_path = os.path.join("config", "settings.json")
if not os.path.exists(config_path):
print(f"❌ 設定ファイルが見つかりません: {config_path}")
return {
"routine_order": ["breathing", "gratitude"],
"default_emotion": 3
}
with open(config_path, "r", encoding="utf-8") as f:
return json.load(f)

# メイン処理
def main():
print("🧠 メンタルルーティン開始!")

# 設定読み込み
settings = load_settings()

# ロガー初期化(DBファイルはプロジェクトルートにある前提)
logger = MentalLogger("mental_log.db")

# ルーティンマッピング
routine_map = {
"breathing": BreathingRoutine,
"gratitude": GratitudeRoutine,
"present_moment": PresentMomentRoutine,
"negative_reflection": NegativeReflectionRoutine,
}

# ルーティンを順番に実行
for r_name in settings.get("routine_order", []):
cls = routine_map.get(r_name)
if not cls:
print(f"⚠️ 未知のルーティン名: {r_name}")
continue

routine = cls()
result = routine.run()

# 結果から感情とメモを取得
emotion = result.get("emotion", settings.get("default_emotion", 3))
note = result.get("note", "")

# DBに保存
logger.save_log(emotion, note)

# DB接続終了
logger.close()
print("✅ メンタルルーティン終了!")

# スクリプトが直接実行されたときのみ実行
if __name__ == "__main__":
main()

routines/base.py

from datetime import datetime

#基本Routineクラス定義
class BaseRoutine:
def __init__(self, name, frequency=1, next_scheduled=None):
#項目名
self.name = name
#頻度
self.frequency = frequency
#次のスケジュール
self.next_scheduled = next_scheduled or datetime.now()

def run(self):
raise NotImplementedError("run() はサブクラスで定義してね!")

#今の時刻が、次にやるべき時間を過ぎてるかどうか
def is_due(self):
return datetime.now() >= self.next_scheduled

routines/breathing.py

from routines.base import BaseRoutine

# 呼吸ルーティンのクラス定義(BaseRoutine を継承)
class BreathingRoutine(BaseRoutine):
def __init__(self):
# 親クラスにルーティン名「深呼吸」を渡して初期化
super().__init__("深呼吸")

# ルーティンを実行するメソッド
def run(self):
# ユーザーに深呼吸を促すメッセージを表示
print("💨 3回ゆっくり深呼吸してみましょう...")

# 実際に深呼吸をしてEnterを押してもらう
input("完了したらEnterを押してね:")

# 結果(感情スコアと一言メモ)を辞書形式で返す
return {
"emotion": 2, # 2 = 少し落ち着いた、という感情スコア
"note": "深呼吸で少し落ち着いた" # ログ用のメモ
}

routines/gratitude.py

from routines.base import BaseRoutine

# 感謝ルーティンのクラス定義(BaseRoutineを継承)
class GratitudeRoutine(BaseRoutine):
def __init__(self):
# ベースクラスの初期化:ルーティン名「感謝ルーティン」で登録
super().__init__("感謝ルーティン")

def run(self):

print("🌸 今日感謝していることを3つ書いてみましょう!")
gratitude_list = []

# 3つの感謝エントリを順番に取得
for i in range(1, 4):
entry = input(f"{i}つ目: ")
gratitude_list.append(entry)

# 入力された感謝リストをまとめて1つの文字列にする
note = "感謝リスト: " + ", ".join(gratitude_list)

# フィードバックメッセージを表示
print("素敵ですね!感謝の気持ちを大切に✨")

# 感情スコア(3:普通)と感謝リストを返す
return {
"emotion": 3, # 固定値(あとで感情入力受け取りに拡張できる)
"note": note # 日記として保存する文字列
}

routine/negative_reflection.py

from routines.base import BaseRoutine

class NegativeReflectionRoutine(BaseRoutine):
def __init__(self):
super().__init__("ネガティブ感情整理")

def run(self):
print("🌀 今日モヤモヤ・つらかったことを振り返ってみましょう")

# ネガティブな出来事を自由記述
event = input("何があった?(できるだけ詳しく)\n")

# 感情の正体を言語化
emotion = input("💭 どんな気持ちになった?(例:怒り、不安、悲しみ)\n")

# 原因を内省
reason = input("🔍 なぜそう感じたと思う?(自分の期待、他人の言動、状況など)\n")

# 今振り返って「どうしたらよかった?」を考える
learn = input("💡 次に同じことがあったら、どうしたい?どう言いたい?\n")

note = (
"【ネガティブ整理】\n"
f"- 出来事: {event}\n"
f"- 感情: {emotion}\n"
f"- 原因: {reason}\n"
f"- 学び/対処案: {learn}"
)

print("🕊 書き出せてえらいです。自分を責めすぎず、少しずつ整理していきましょう。")

return {
"emotion": 1, # 1=しんどい気持ち
"note": note
}

routines/present_moment.py

from routines.base import BaseRoutine

class PresentMomentRoutine(BaseRoutine):
def __init__(self):
super().__init__("今ここルーティン")

def run(self):
print("👁️‍🗨️ 未来や過去ではなく、今この瞬間を観察してみましょう")

body = input("🦶 体で何を感じてる?(例:足の重さ、息の流れ):")
sound = input("👂 周りの音は?:")
thought = input("🧠 今、頭にどんな考えが浮かんでる?:")

note = f"【今ココ観察】\n- 体感覚: {body}\n- 音: {sound}\n- 思考: {thought}"
print("🌸 OKです。思考から離れて、ただ『今』を感じる練習、すばらしいです。")

return {
"emotion": 3,
"note": note
}

db/logger.py

import sqlite3
from datetime import datetime

class MentalLogger:
def __init__(self, db_path="mental_log.db"):
#DBに接続(なければ新規作成)
self.conn = sqlite3.connect(db_path)
#テーブルがなければ作成する
self._create_table()

def _create_table(self):
#ログ記録ゆおのテーブル作成
self.conn.execute("""
CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
emotion INTEGER,
diary TEXT
)
""")

#SQLコマンドを確定
self.conn.commit()

def save_log(self, emotion: int, diary: str):
#現在の時刻を取得(create_time)
now = datetime.now().isoformat()
self.conn.execute(
#DBにログをインサートする
"INSERT INTO logs (timestamp, emotion, diary) VALUES (?, ?, ?)",
(now, emotion, diary)
)
self.conn.commit() #データインサート確定

def close(self):
self.conn.close()

db/show_logs.py

import sqlite3
import os

def show_logs(db_path="mental_log.db"):
# スクリプトのあるディレクトリに基づいて絶対パスを作成
full_path = os.path.abspath(db_path)

# ファイルが存在しなければエラー表示して終了
if not os.path.exists(full_path):
print(f"❌ DBファイルが見つかりません: {full_path}")
return

# SQLiteに接続
conn = sqlite3.connect(full_path)
cur = conn.cursor()

# logsテーブルの存在チェック
cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='logs'")
if not cur.fetchone():
print("⚠️ テーブル 'logs' は存在しません。")
conn.close()
return

# logsテーブルからすべての行を取得(時系列順に)
cur.execute("SELECT * FROM logs ORDER BY timestamp DESC")
rows = cur.fetchall()

if not rows:
print("📭 ログがまだありません。")
else:
print(f"📘 {len(rows)} 件のログを表示します:\n")
for row in rows:
print(f"📝 id: {row[0]}")
print(f"🕒 時刻: {row[1]}")
print(f"📊 感情スコア: {row[2]}")
print(f"📓 メモ:\n{row[3]}\n{'-' * 40}")

# 接続を閉じる
conn.close()

# スクリプトが直接実行されたときのみログ表示
if __name__ == "__main__":
# 必要に応じて、db_path を変更してね
show_logs("mental_log.db")

scripts/notify.sh(いずれLINEと連携したいので)

#!/bin/bash
echo "📩 通知を送信中(LINE APIに接続...)"

ゲーム作りで楽しく学ぶ オブジェクト指向のきほん

新品価格
¥2,465から
(2025/7/20 13:47時点)

出力結果

main.pyの出力結果はこのようになりました。

いい感じに振り返りできそうです。

こちらはmental_show.pyの出力結果です。

データベース(mental_log.db)にも記録されました。

まとめ

今回は、クラスや継承を使ったメンタルログを作成しました。

今後はAPIを利用してLINEでも使えるようにしたいです。

ありがとうございました!

タイトルとURLをコピーしました