Implement dose tracking functionality and enhance CSV migration

- Added a new migration script to introduce dose tracking columns in the CSV.
- Updated DataManager to handle new dose tracking columns and methods for adding doses.
- Enhanced MedTrackerApp to support dose entry and display for each medicine.
- Modified UIManager to create a scrollable input frame with dose tracking elements.
- Implemented tests for delete functionality, dose tracking, edit functionality, and scrollable input.
- Updated existing tests to ensure compatibility with the new CSV format and dose tracking features.
This commit is contained in:
William Valentin
2025-07-28 20:52:29 -07:00
parent d5423e98c0
commit e35a8af5c1
14 changed files with 1790 additions and 500 deletions
+122 -15
View File
@@ -26,9 +26,13 @@ class DataManager:
"sleep",
"appetite",
"bupropion",
"bupropion_doses",
"hydroxyzine",
"hydroxyzine_doses",
"gabapentin",
"gabapentin_doses",
"propranolol",
"propranolol_doses",
"note",
]
)
@@ -48,9 +52,13 @@ class DataManager:
"sleep": int,
"appetite": int,
"bupropion": int,
"bupropion_doses": str,
"hydroxyzine": int,
"hydroxyzine_doses": str,
"gabapentin": int,
"gabapentin_doses": str,
"propranolol": int,
"propranolol_doses": str,
"note": str,
"date": str,
},
@@ -96,21 +104,45 @@ class DataManager:
return False
# Find the row to update using original_date as a unique identifier
df.loc[
df["date"] == original_date,
[
"date",
"depression",
"anxiety",
"sleep",
"appetite",
"bupropion",
"hydroxyzine",
"gabapentin",
"propranolol",
"note",
],
] = values
# Handle both old format (10 columns) and new format (14 columns)
if len(values) == 14:
# New format with dose columns
df.loc[
df["date"] == original_date,
[
"date",
"depression",
"anxiety",
"sleep",
"appetite",
"bupropion",
"bupropion_doses",
"hydroxyzine",
"hydroxyzine_doses",
"gabapentin",
"gabapentin_doses",
"propranolol",
"propranolol_doses",
"note",
],
] = values
else:
# Old format - only update the user-editable columns
df.loc[
df["date"] == original_date,
[
"date",
"depression",
"anxiety",
"sleep",
"appetite",
"bupropion",
"hydroxyzine",
"gabapentin",
"propranolol",
"note",
],
] = values
df.to_csv(self.filename, index=False)
return True
except Exception as e:
@@ -129,3 +161,78 @@ class DataManager:
except Exception as e:
self.logger.error(f"Error deleting entry: {str(e)}")
return False
def add_medicine_dose(self, date: str, medicine_name: str, dose: str) -> bool:
"""Add a medicine dose to today's entry."""
from datetime import datetime
try:
df: pd.DataFrame = self.load_data()
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
dose_entry = f"{timestamp}:{dose}"
# Find or create entry for the given date
if df.empty or date not in df["date"].values:
# Create new entry for today with default values
new_entry = {
"date": date,
"depression": 0,
"anxiety": 0,
"sleep": 0,
"appetite": 0,
"bupropion": 0,
"bupropion_doses": "",
"hydroxyzine": 0,
"hydroxyzine_doses": "",
"gabapentin": 0,
"gabapentin_doses": "",
"propranolol": 0,
"propranolol_doses": "",
"note": "",
}
df = pd.concat([df, pd.DataFrame([new_entry])], ignore_index=True)
# Add dose to the appropriate medicine
dose_column = f"{medicine_name}_doses"
mask = df["date"] == date
current_doses = df.loc[mask, dose_column].iloc[0]
if current_doses:
df.loc[mask, dose_column] = current_doses + "|" + dose_entry
else:
df.loc[mask, dose_column] = dose_entry
# Mark medicine as taken (set to 1)
df.loc[mask, medicine_name] = 1
df.to_csv(self.filename, index=False)
return True
except Exception as e:
self.logger.error(f"Error adding medicine dose: {str(e)}")
return False
def get_today_medicine_doses(
self, date: str, medicine_name: str
) -> list[tuple[str, str]]:
"""Get list of (timestamp, dose) tuples for a medicine on a given date."""
try:
df: pd.DataFrame = self.load_data()
if df.empty or date not in df["date"].values:
return []
dose_column = f"{medicine_name}_doses"
doses_str = df.loc[df["date"] == date, dose_column].iloc[0]
if not doses_str:
return []
doses = []
for dose_entry in doses_str.split("|"):
if ":" in dose_entry:
timestamp, dose = dose_entry.split(":", 1)
doses.append((timestamp, dose))
return doses
except Exception as e:
self.logger.error(f"Error getting medicine doses: {str(e)}")
return []