Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
minversion = "8.0"
testpaths = ["tests"]
addopts = "-q"
23 changes: 13 additions & 10 deletions src/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys
from datetime import date
import click
from src.mood_logger import log_mood, latest_entries
from src.mood_logger import MoodEntry, save_entry, load_entries

@click.group()
def cli():
Expand All @@ -12,16 +12,19 @@ def cli():
@click.argument("note", type=str, required=False)
def log(rating, note):
"""Log your mood with RATING (1–10) and optional NOTE."""
log_mood(rating, note)
click.echo(f"Logged mood {rating}{f' – {note}' if note else ''}")
entry = MoodEntry(date.today().isoformat(), rating, note)
save_entry(entry)
click.echo("Logged!")

@cli.command()
@click.option("--n", default=5, help="How many entries to show.")
def latest(n):
"""Show the last N mood entries."""
entries = latest_entries(n)
for e in entries:
click.echo(f"{e.date}: {e.rating} – {e.note or ''}")
def latest():
"""Show the most recent mood entry."""
entries = load_entries()
if not entries:
click.echo("No entries found.")
return
e = entries[-1]
click.echo(f"{e.date}: {e.rating}{f' – {e.note}' if e.note else ''}")

if __name__ == "__main__":
cli()
25 changes: 24 additions & 1 deletion src/mood_logger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass
from dataclasses import dataclass, asdict
from datetime import date
import csv
import json
from pathlib import Path
from typing import List, Optional

Expand All @@ -11,6 +12,9 @@ class MoodEntry:
rating: int
note: Optional[str] = None

# Default JSON data file stored at the repository root
DATA_FILE = Path(__file__).resolve().parent.parent / "moods.json"

def log_mood(
rating: int,
note: Optional[str] = None,
Expand Down Expand Up @@ -50,3 +54,22 @@ def latest_entries(
for row in rows
]
return entries[-n:]


def load_entries() -> List[MoodEntry]:
"""Load all mood entries from the JSON ``DATA_FILE``."""
path = Path(DATA_FILE)
if not path.exists():
return []
with path.open() as f:
data = json.load(f)
return [MoodEntry(**item) for item in data]


def save_entry(entry: MoodEntry) -> None:
"""Append ``entry`` to ``DATA_FILE``."""
path = Path(DATA_FILE)
entries = load_entries()
entries.append(entry)
with path.open("w") as f:
json.dump([asdict(e) for e in entries], f)
15 changes: 15 additions & 0 deletions tests/test_storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from datetime import date
from src import mood_logger


def test_save_and_load_round_trip(tmp_path, monkeypatch):
data_file = tmp_path / "moods.json"
monkeypatch.setattr(mood_logger, "DATA_FILE", data_file)

entry = mood_logger.MoodEntry(date.today().isoformat(), 8, "feeling good")
mood_logger.save_entry(entry)

assert data_file.exists()

loaded = mood_logger.load_entries()
assert loaded == [entry]