Add logging and refactored code

This commit is contained in:
William Valentin
2025-07-20 13:10:17 -07:00
parent a5791d8fe4
commit 351d3633fe

View File

@@ -9,11 +9,15 @@ import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import sys import sys
from dotenv import load_dotenv from PIL import Image, ImageTk
from init import logger
from constants import LOG_LEVEL
class MedTrackerApp: class MedTrackerApp:
def __init__(self, root): def __init__(self, root):
self.root = root self.root = root
self.root.resizable(True, True) self.root.resizable(True, True)
self.root.title("Thechart - medication tracker") self.root.title("Thechart - medication tracker")
@@ -24,14 +28,14 @@ class MedTrackerApp:
# self.root.geometry(f"{screen_width}x{screen_height}") # self.root.geometry(f"{screen_width}x{screen_height}")
# self.root.configure(background='gold') # self.root.configure(background='gold')
# self.root.lift() # self.root.lift()
# self.root.attributes("-topmost", True)
self.filename = "thechart_data.csv" # self.root.geometry("800x600")
if len(sys.argv) > 1: if len(sys.argv) > 1:
script_name = sys.argv[0] script_name = sys.argv[0]
first_argument = sys.argv[1] first_argument = sys.argv[1]
if logger.level == logging.DEBUG: if LOG_LEVEL == "DEBUG":
logger.debug(f"Script name: {script_name}") logger.debug(f"Script name: {script_name}")
logger.debug(f"First argument: {first_argument}") logger.debug(f"First argument: {first_argument}")
@@ -44,6 +48,13 @@ class MedTrackerApp:
f" Using default file: {self.filename}" f" Using default file: {self.filename}"
) )
make_icon(
app=self.root,
img="/home/will/Code/thechart/chart-671.png",
logger=logger,
)
self.filename = "thechart_data.csv"
self.initialize_csv() self.initialize_csv()
main_frame = ttk.Frame(self.root, padding="10") main_frame = ttk.Frame(self.root, padding="10")
@@ -70,7 +81,11 @@ class MedTrackerApp:
) )
self.anxiety_var = tk.IntVar() self.anxiety_var = tk.IntVar()
ttk.Scale( ttk.Scale(
input_frame, from_=0, to=10, orient=tk.HORIZONTAL, variable=self.anxiety_var input_frame,
from_=0,
to=10,
orient=tk.HORIZONTAL,
variable=self.anxiety_var,
).grid(row=1, column=1, sticky="ew") ).grid(row=1, column=1, sticky="ew")
ttk.Label(input_frame, text="Sleep Quality (0-10):").grid( ttk.Label(input_frame, text="Sleep Quality (0-10):").grid(
@@ -78,7 +93,11 @@ class MedTrackerApp:
) )
self.sleep_var = tk.IntVar() self.sleep_var = tk.IntVar()
ttk.Scale( ttk.Scale(
input_frame, from_=0, to=10, orient=tk.HORIZONTAL, variable=self.sleep_var input_frame,
from_=0,
to=10,
orient=tk.HORIZONTAL,
variable=self.sleep_var,
).grid(row=2, column=1, sticky="ew") ).grid(row=2, column=1, sticky="ew")
ttk.Label(input_frame, text="Appetite (0-10):").grid( ttk.Label(input_frame, text="Appetite (0-10):").grid(
@@ -149,22 +168,24 @@ class MedTrackerApp:
row=6, column=0, sticky="w", padx=5, pady=2 row=6, column=0, sticky="w", padx=5, pady=2
) )
self.date_var = tk.StringVar() self.date_var = tk.StringVar()
ttk.Entry(input_frame, textvariable=self.date_var, justify="center").grid( ttk.Entry(
row=6, column=1, sticky="ew", padx=5, pady=2 input_frame, textvariable=self.date_var, justify="center"
) ).grid(row=6, column=1, sticky="ew", padx=5, pady=2)
button_frame = ttk.Frame(input_frame) button_frame = ttk.Frame(input_frame)
button_frame.grid(row=7, column=0, columnspan=2, pady=10) button_frame.grid(row=7, column=0, columnspan=2, pady=10)
ttk.Button(button_frame, text="Add Entry", command=self.add_entry).pack( ttk.Button(
side="left", padx=5 button_frame, text="Add Entry", command=self.add_entry
) ).pack(side="left", padx=5, fill="both", expand=True)
ttk.Button(button_frame, text="Quit", command=self.on_closing).pack( ttk.Button(button_frame, text="Quit", command=self.on_closing).pack(
side="left", padx=5 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=1, padx=10, pady=10, sticky="nsew") table_frame.grid(row=1, column=1, padx=10, pady=10, sticky="nsew")
self.tree = ttk.Treeview( self.tree = ttk.Treeview(
@@ -217,7 +238,9 @@ class MedTrackerApp:
# --- 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=0, columnspan=2, padx=10, pady=10, sticky="nsew") graph_frame.grid(
row=0, column=0, columnspan=2, padx=10, pady=10, sticky="nsew"
)
self.fig, self.ax = plt.subplots() self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvasTkAgg(figure=self.fig, master=graph_frame) self.canvas = FigureCanvasTkAgg(figure=self.fig, master=graph_frame)
@@ -263,28 +286,28 @@ class MedTrackerApp:
row=1, column=0, sticky="w", padx=5, pady=2 row=1, column=0, sticky="w", padx=5, pady=2
) )
ttk.Scale( ttk.Scale(
edit_win, from_=1, to=10, variable=dep_var, orient=tk.HORIZONTAL edit_win, from_=0, to=10, variable=dep_var, orient=tk.HORIZONTAL
).grid(row=1, column=1, sticky="ew") ).grid(row=1, column=1, sticky="ew")
ttk.Label(edit_win, text="Anxiety:").grid( ttk.Label(edit_win, text="Anxiety:").grid(
row=2, column=0, sticky="w", padx=5, pady=2 row=2, column=0, sticky="w", padx=5, pady=2
) )
ttk.Scale( ttk.Scale(
edit_win, from_=1, to=10, variable=anx_var, orient=tk.HORIZONTAL edit_win, from_=0, to=10, variable=anx_var, orient=tk.HORIZONTAL
).grid(row=2, column=1, sticky="ew") ).grid(row=2, column=1, sticky="ew")
ttk.Label(edit_win, text="Sleep:").grid( ttk.Label(edit_win, text="Sleep:").grid(
row=3, column=0, sticky="w", padx=5, pady=2 row=3, column=0, sticky="w", padx=5, pady=2
) )
ttk.Scale( ttk.Scale(
edit_win, from_=1, to=10, variable=slp_var, orient=tk.HORIZONTAL edit_win, from_=0, to=10, variable=slp_var, orient=tk.HORIZONTAL
).grid(row=3, column=1, sticky="ew") ).grid(row=3, column=1, sticky="ew")
ttk.Label(edit_win, text="Appetite:").grid( ttk.Label(edit_win, text="Appetite:").grid(
row=4, column=0, sticky="w", padx=5, pady=2 row=4, column=0, sticky="w", padx=5, pady=2
) )
ttk.Scale( ttk.Scale(
edit_win, from_=1, to=10, variable=app_var, orient=tk.HORIZONTAL edit_win, from_=0, to=10, variable=app_var, orient=tk.HORIZONTAL
).grid(row=4, column=1, sticky="ew") ).grid(row=4, column=1, sticky="ew")
ttk.Label(edit_win, text="Treatment:").grid( ttk.Label(edit_win, text="Treatment:").grid(
@@ -329,12 +352,16 @@ class MedTrackerApp:
ttk.Label(edit_win, text="Note:").grid( ttk.Label(edit_win, text="Note:").grid(
row=6, column=0, sticky="w", padx=5, pady=2 row=6, column=0, sticky="w", padx=5, pady=2
) )
ttk.Entry(edit_win, textvariable=note_var).grid(row=6, column=1, sticky="ew") ttk.Entry(edit_win, textvariable=note_var).grid(
row=6, column=1, sticky="ew"
)
ttk.Label(edit_win, text="Date:").grid( ttk.Label(edit_win, text="Date:").grid(
row=7, column=0, sticky="w", padx=5, pady=2 row=7, column=0, sticky="w", padx=5, pady=2
) )
ttk.Entry(edit_win, textvariable=date_var).grid(row=7, column=1, sticky="ew") ttk.Entry(edit_win, textvariable=date_var).grid(
row=7, column=1, sticky="ew"
)
# Save and Cancel buttons # Save and Cancel buttons
save_btn = ttk.Button( save_btn = ttk.Button(
@@ -356,7 +383,9 @@ class MedTrackerApp:
) )
save_btn.grid(row=8, column=0, padx=5, pady=10) save_btn.grid(row=8, 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
)
cancel_btn.grid(row=8, column=1, padx=5, pady=10) cancel_btn.grid(row=8, column=1, padx=5, pady=10)
delete_btn = ttk.Button( delete_btn = ttk.Button(
edit_win, edit_win,
@@ -403,7 +432,9 @@ class MedTrackerApp:
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!", parent=self.root) messagebox.showinfo(
"Success", "Entry updated successfully!", parent=self.root
)
self.clear_entries() self.clear_entries()
self.load_data() self.load_data()
@@ -451,7 +482,9 @@ class MedTrackerApp:
] ]
) )
messagebox.showinfo("Success", "Entry added successfully!", parent=self.root) messagebox.showinfo(
"Success", "Entry added successfully!", parent=self.root
)
self.clear_entries() self.clear_entries()
self.load_data() self.load_data()
@@ -494,7 +527,10 @@ class MedTrackerApp:
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( df = pd.read_csv(
self.filename, self.filename,
@@ -529,16 +565,28 @@ class MedTrackerApp:
df["depression"], df["depression"],
marker="o", marker="o",
linestyle="-", linestyle="-",
label="Depression", label="Depression (0:good, 10:bad)",
) )
self.ax.plot( self.ax.plot(
df.index, df["anxiety"], marker="o", linestyle="-", label="Anxiety" df.index,
df["anxiety"],
marker="o",
linestyle="-",
label="Anxiety (0:good, 10:bad)",
) )
self.ax.plot( self.ax.plot(
df.index, df["sleep"], marker="o", linestyle="-", label="Sleep" df.index,
df["sleep"],
marker="o",
linestyle="dashed",
label="Sleep (0:bad, 10:good)",
) )
self.ax.plot( self.ax.plot(
df.index, df["appetite"], marker="o", linestyle="-", label="Appetite" df.index,
df["appetite"],
marker="o",
linestyle="dashed",
label="Appetite (0:bad, 10:good)",
) )
self.ax.legend() self.ax.legend()
self.ax.set_title("Medication Effects Over Time") self.ax.set_title("Medication Effects Over Time")
@@ -548,31 +596,20 @@ class MedTrackerApp:
self.canvas.draw() self.canvas.draw()
def setup_logging() -> logging.Logger: def make_icon(app: tk.Tk, img: str, logger: logging.Logger) -> None:
load_dotenv() try:
log_file = os.getenv("LOG_FILE", "/tmp/thechart.log") icon_image = Image.open(img)
if not os.path.exists(os.path.dirname(log_file)): icon_image = icon_image.resize(
os.makedirs(os.path.dirname(log_file), exist_ok=True) size=(32, 32), resample=Image.Resampling.NEAREST
)
log_level = os.getenv("LOG_LEVEL", "INFO").upper() icon_photo = ImageTk.PhotoImage(image=icon_image)
if log_level not in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]: app.iconphoto(True, icon_photo)
log_level = "DEBUG" app.wm_iconphoto(True, icon_photo)
except FileNotFoundError:
logging.basicConfig( logger.warning("Icon file not found.")
level=getattr(logging, log_level),
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler(log_file),
logging.StreamHandler(sys.stdout),
],
)
logger = logging.getLogger()
return logger
if __name__ == "__main__": if __name__ == "__main__":
logger = setup_logging()
root = tk.Tk() root = tk.Tk()
app = MedTrackerApp(root) app = MedTrackerApp(root)
root.mainloop() root.mainloop()