Refactor code

This commit is contained in:
William Valentin
2025-07-15 13:38:35 -07:00
parent f8915f85b0
commit e8d23caa9f

View File

@@ -1,12 +1,14 @@
import tkinter as tk
from tkinter import ttk, messagebox
import csv import csv
import os import os
import tkinter as tk
from datetime import datetime from datetime import datetime
import pandas as pd from tkinter import messagebox, ttk
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class MedTrackerApp: class MedTrackerApp:
def __init__(self, root): def __init__(self, root):
self.root = root self.root = root
@@ -23,55 +25,93 @@ class MedTrackerApp:
input_frame = ttk.LabelFrame(main_frame, text="New Entry") input_frame = ttk.LabelFrame(main_frame, text="New Entry")
input_frame.grid(row=0, column=0, padx=10, pady=10, sticky="ew") input_frame.grid(row=0, column=0, padx=10, pady=10, sticky="ew")
ttk.Label(input_frame, text="Depression (1-10):").grid(row=0, column=0, sticky="w", padx=5, pady=2) ttk.Label(input_frame, text="Depression (1-10):").grid(
row=0, column=0, sticky="w", padx=5, pady=2
)
self.depression_var = tk.IntVar() self.depression_var = tk.IntVar()
ttk.Scale(input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.depression_var).grid(row=0, column=1, sticky="ew") ttk.Scale(
input_frame,
from_=1,
to=10,
orient=tk.HORIZONTAL,
variable=self.depression_var,
).grid(row=0, column=1, sticky="ew")
ttk.Label(input_frame, text="Anxiety (1-10):").grid(row=1, column=0, sticky="w", padx=5, pady=2) ttk.Label(input_frame, text="Anxiety (1-10):").grid(
row=1, column=0, sticky="w", padx=5, pady=2
)
self.anxiety_var = tk.IntVar() self.anxiety_var = tk.IntVar()
ttk.Scale(input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.anxiety_var).grid(row=1, column=1, sticky="ew") ttk.Scale(
input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.anxiety_var
).grid(row=1, column=1, sticky="ew")
ttk.Label(input_frame, text="Sleep Quality (1-10):").grid(row=2, column=0, sticky="w", padx=5, pady=2) ttk.Label(input_frame, text="Sleep Quality (1-10):").grid(
row=2, column=0, sticky="w", padx=5, pady=2
)
self.sleep_var = tk.IntVar() self.sleep_var = tk.IntVar()
ttk.Scale(input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.sleep_var).grid(row=2, column=1, sticky="ew") ttk.Scale(
input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.sleep_var
).grid(row=2, column=1, sticky="ew")
ttk.Label(input_frame, text="Appetite (1-10):").grid(row=3, column=0, sticky="w", padx=5, pady=2) ttk.Label(input_frame, text="Appetite (1-10):").grid(
row=3, column=0, sticky="w", padx=5, pady=2
)
self.appetite_var = tk.IntVar() self.appetite_var = tk.IntVar()
ttk.Scale(input_frame, from_=1, to=10, orient=tk.HORIZONTAL, variable=self.appetite_var).grid(row=3, column=1, sticky="ew") ttk.Scale(
input_frame,
from_=1,
to=10,
orient=tk.HORIZONTAL,
variable=self.appetite_var,
).grid(row=3, column=1, sticky="ew")
ttk.Label(input_frame, text="Note:").grid(row=4, column=0, sticky="w", padx=5, pady=2) ttk.Label(input_frame, text="Note:").grid(
row=4, column=0, sticky="w", padx=5, pady=2
)
self.note_var = tk.StringVar() self.note_var = tk.StringVar()
ttk.Entry(input_frame, textvariable=self.note_var).grid(row=4, column=1, sticky="ew", padx=5, pady=2) ttk.Entry(input_frame, textvariable=self.note_var).grid(
row=4, column=1, sticky="ew", padx=5, pady=2
)
button_frame = ttk.Frame(input_frame) button_frame = ttk.Frame(input_frame)
button_frame.grid(row=5, column=0, columnspan=2, pady=10) button_frame.grid(row=5, column=0, columnspan=2, pady=10)
ttk.Button(button_frame, text="Add Entry", command=self.add_entry).pack(side="left", padx=5) ttk.Button(button_frame, text="Add Entry", command=self.add_entry).pack(
ttk.Button(button_frame, text="Quit", command=self.on_closing).pack(side="left", padx=5) side="left", padx=5
)
ttk.Button(button_frame, text="Quit", command=self.on_closing).pack(
side="left", padx=5
)
# --- Table Frame --- # --- Table Frame ---
table_frame = ttk.LabelFrame(main_frame, text="Log (Double-click to edit)") table_frame = ttk.LabelFrame(main_frame, text="Log (Double-click to edit)")
table_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew") table_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")
self.tree = ttk.Treeview(table_frame, columns=("Timestamp", "Depression", "Anxiety", "Sleep", "Appetite", "Note"), show="headings") self.tree = ttk.Treeview(
table_frame,
columns=("Timestamp", "Depression", "Anxiety", "Sleep", "Appetite", "Note"),
show="headings",
)
self.tree.heading("Timestamp", text="Timestamp") self.tree.heading("Timestamp", text="Timestamp")
self.tree.heading("Depression", text="Depression") self.tree.heading("Depression", text="Depression")
self.tree.heading("Anxiety", text="Anxiety") self.tree.heading("Anxiety", text="Anxiety")
self.tree.heading("Sleep", text="Sleep") self.tree.heading("Sleep", text="Sleep")
self.tree.heading("Appetite", text="Appetite") self.tree.heading("Appetite", text="Appetite")
self.tree.heading("Note", text="Note") self.tree.heading("Note", text="Note")
# --- NEW: Bind double-click event --- # --- NEW: Bind double-click event ---
self.tree.bind("<Double-1>", self.on_double_click) self.tree.bind("<Double-1>", self.on_double_click)
self.tree.pack(side="left", fill="both", expand=True) self.tree.pack(side="left", fill="both", expand=True)
scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.tree.yview) scrollbar = ttk.Scrollbar(
table_frame, orient="vertical", command=self.tree.yview
)
self.tree.configure(yscrollcommand=scrollbar.set) self.tree.configure(yscrollcommand=scrollbar.set)
scrollbar.pack(side="right", fill="y") scrollbar.pack(side="right", fill="y")
# --- Graph Frame --- # --- Graph Frame ---
graph_frame = ttk.LabelFrame(main_frame, text="Evolution") graph_frame = ttk.LabelFrame(main_frame, text="Evolution")
graph_frame.grid(row=0, column=1, rowspan=2, padx=10, pady=10, sticky="nsew") graph_frame.grid(row=0, column=1, rowspan=2, padx=10, pady=10, sticky="nsew")
self.fig, self.ax = plt.subplots() self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvasTkAgg(self.fig, master=graph_frame) self.canvas = FigureCanvasTkAgg(self.fig, master=graph_frame)
self.canvas.get_tk_widget().pack(fill="both", expand=True) self.canvas.get_tk_widget().pack(fill="both", expand=True)
@@ -101,29 +141,59 @@ class MedTrackerApp:
slp_var = tk.IntVar(value=int(slp)) slp_var = tk.IntVar(value=int(slp))
app_var = tk.IntVar(value=int(app)) app_var = tk.IntVar(value=int(app))
note_var = tk.StringVar(value=note) note_var = tk.StringVar(value=note)
# Create form widgets # Create form widgets
ttk.Label(edit_win, text=f"Timestamp: {ts}").grid(row=0, column=0, columnspan=2, padx=5, pady=5) ttk.Label(edit_win, text=f"Timestamp: {ts}").grid(
row=0, column=0, columnspan=2, padx=5, pady=5
ttk.Label(edit_win, text="Depression:").grid(row=1, column=0, sticky="w", padx=5, pady=2) )
ttk.Scale(edit_win, from_=1, to=10, variable=dep_var, orient=tk.HORIZONTAL).grid(row=1, column=1, sticky="ew")
ttk.Label(edit_win, text="Anxiety:").grid(row=2, column=0, sticky="w", padx=5, pady=2)
ttk.Scale(edit_win, from_=1, to=10, variable=anx_var, orient=tk.HORIZONTAL).grid(row=2, column=1, sticky="ew")
ttk.Label(edit_win, text="Sleep:").grid(row=3, column=0, sticky="w", padx=5, pady=2)
ttk.Scale(edit_win, from_=1, to=10, variable=slp_var, orient=tk.HORIZONTAL).grid(row=3, column=1, sticky="ew")
ttk.Label(edit_win, text="Appetite:").grid(row=4, column=0, sticky="w", padx=5, pady=2) ttk.Label(edit_win, text="Depression:").grid(
ttk.Scale(edit_win, from_=1, to=10, variable=app_var, orient=tk.HORIZONTAL).grid(row=4, column=1, sticky="ew") row=1, column=0, sticky="w", padx=5, pady=2
)
ttk.Scale(
edit_win, from_=1, to=10, variable=dep_var, orient=tk.HORIZONTAL
).grid(row=1, column=1, sticky="ew")
ttk.Label(edit_win, text="Note:").grid(row=5, column=0, sticky="w", padx=5, pady=2) ttk.Label(edit_win, text="Anxiety:").grid(
row=2, column=0, sticky="w", padx=5, pady=2
)
ttk.Scale(
edit_win, from_=1, to=10, variable=anx_var, orient=tk.HORIZONTAL
).grid(row=2, column=1, sticky="ew")
ttk.Label(edit_win, text="Sleep:").grid(
row=3, column=0, sticky="w", padx=5, pady=2
)
ttk.Scale(
edit_win, from_=1, to=10, variable=slp_var, orient=tk.HORIZONTAL
).grid(row=3, column=1, sticky="ew")
ttk.Label(edit_win, text="Appetite:").grid(
row=4, column=0, sticky="w", padx=5, pady=2
)
ttk.Scale(
edit_win, from_=1, to=10, variable=app_var, orient=tk.HORIZONTAL
).grid(row=4, column=1, sticky="ew")
ttk.Label(edit_win, text="Note:").grid(
row=5, column=0, sticky="w", padx=5, pady=2
)
ttk.Entry(edit_win, textvariable=note_var).grid(row=5, column=1, sticky="ew") ttk.Entry(edit_win, textvariable=note_var).grid(row=5, column=1, sticky="ew")
# Save and Cancel buttons # Save and Cancel buttons
save_btn = ttk.Button(edit_win, text="Save", command=lambda: self.save_edit( save_btn = ttk.Button(
edit_win, ts, dep_var.get(), anx_var.get(), slp_var.get(), app_var.get(), note_var.get() edit_win,
)) text="Save",
command=lambda: self.save_edit(
edit_win,
ts,
dep_var.get(),
anx_var.get(),
slp_var.get(),
app_var.get(),
note_var.get(),
),
)
save_btn.grid(row=6, column=0, padx=5, pady=10) save_btn.grid(row=6, column=0, padx=5, pady=10)
cancel_btn = ttk.Button(edit_win, text="Cancel", command=edit_win.destroy) cancel_btn = ttk.Button(edit_win, text="Cancel", command=edit_win.destroy)
@@ -133,10 +203,13 @@ class MedTrackerApp:
"""Save the edited data to the CSV file.""" """Save the edited data to the CSV file."""
df = pd.read_csv(self.filename) df = pd.read_csv(self.filename)
# Find the row to update using the timestamp as a unique identifier # Find the row to update using the timestamp as a unique identifier
df.loc[df['timestamp'] == timestamp, ['depression', 'anxiety', 'sleep', 'appetite', 'note']] = [dep, anx, slp, app, note] df.loc[
df["timestamp"] == timestamp,
["depression", "anxiety", "sleep", "appetite", "note"],
] = [dep, anx, slp, app, note]
# Write the updated dataframe back to the CSV # Write the updated dataframe back to the CSV
df.to_csv(self.filename, index=False) df.to_csv(self.filename, index=False)
edit_win.destroy() edit_win.destroy()
messagebox.showinfo("Success", "Entry updated successfully!") messagebox.showinfo("Success", "Entry updated successfully!")
self.load_data() self.load_data()
@@ -148,20 +221,31 @@ class MedTrackerApp:
def initialize_csv(self): def initialize_csv(self):
if not os.path.exists(self.filename): if not os.path.exists(self.filename):
with open(self.filename, mode='w', newline='') as file: with open(self.filename, mode="w", newline="") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow(["timestamp", "depression", "anxiety", "sleep", "appetite", "note"]) writer.writerow(
["timestamp", "depression", "anxiety", "sleep", "appetite", "note"]
)
def add_entry(self): def add_entry(self):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(self.filename, mode='a', newline='') as file: with open(self.filename, mode="a", newline="") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow([timestamp, self.depression_var.get(), self.anxiety_var.get(), self.sleep_var.get(), self.appetite_var.get(), self.note_var.get()]) writer.writerow(
[
timestamp,
self.depression_var.get(),
self.anxiety_var.get(),
self.sleep_var.get(),
self.appetite_var.get(),
self.note_var.get(),
]
)
messagebox.showinfo("Success", "Entry added successfully!") messagebox.showinfo("Success", "Entry added successfully!")
self.clear_entries() self.clear_entries()
self.load_data() self.load_data()
def clear_entries(self): def clear_entries(self):
self.depression_var.set(0) self.depression_var.set(0)
self.anxiety_var.set(0) self.anxiety_var.set(0)
@@ -172,12 +256,12 @@ class MedTrackerApp:
def load_data(self): def load_data(self):
for i in self.tree.get_children(): for i in self.tree.get_children():
self.tree.delete(i) self.tree.delete(i)
if os.path.exists(self.filename) and os.path.getsize(self.filename) > 0: if os.path.exists(self.filename) and os.path.getsize(self.filename) > 0:
try: try:
df = pd.read_csv(self.filename, dtype={'note': str}).fillna('') df = pd.read_csv(self.filename, dtype={"note": str}).fillna("")
# Sort by timestamp to keep order consistent # Sort by timestamp to keep order consistent
df = df.sort_values(by='timestamp').reset_index(drop=True) df = df.sort_values(by="timestamp").reset_index(drop=True)
for index, row in df.iterrows(): for index, row in df.iterrows():
self.tree.insert("", "end", values=list(row)) self.tree.insert("", "end", values=list(row))
self.update_graph(df) self.update_graph(df)
@@ -187,12 +271,24 @@ class MedTrackerApp:
def update_graph(self, df): def update_graph(self, df):
self.ax.clear() self.ax.clear()
if not df.empty: if not df.empty:
df['timestamp'] = pd.to_datetime(df['timestamp']) df["timestamp"] = pd.to_datetime(df["timestamp"])
df.set_index('timestamp', inplace=True) df.set_index("timestamp", inplace=True)
self.ax.plot(df.index, df['depression'], marker='o', linestyle='-', label='Depression') self.ax.plot(
self.ax.plot(df.index, df['anxiety'], marker='o', linestyle='-', label='Anxiety') df.index,
self.ax.plot(df.index, df['sleep'], marker='o', linestyle='-', label='Sleep') df["depression"],
self.ax.plot(df.index, df['appetite'], marker='o', linestyle='-', label='Appetite') marker="o",
linestyle="-",
label="Depression",
)
self.ax.plot(
df.index, df["anxiety"], marker="o", linestyle="-", label="Anxiety"
)
self.ax.plot(
df.index, df["sleep"], marker="o", linestyle="-", label="Sleep"
)
self.ax.plot(
df.index, df["appetite"], marker="o", linestyle="-", label="Appetite"
)
self.ax.legend() self.ax.legend()
self.ax.set_title("Medication Effects Over Time") self.ax.set_title("Medication Effects Over Time")
self.ax.set_xlabel("Date") self.ax.set_xlabel("Date")
@@ -200,7 +296,8 @@ class MedTrackerApp:
self.fig.autofmt_xdate() self.fig.autofmt_xdate()
self.canvas.draw() self.canvas.draw()
if __name__ == "__main__": if __name__ == "__main__":
root = tk.Tk() root = tk.Tk()
app = MedTrackerApp(root) app = MedTrackerApp(root)
root.mainloop() root.mainloop()