Skip to content

Commit cc0f646

Browse files
committed
Bug Fixes
- Fixed a bug where if you pressed start/stop timer or break buttons in a rapid succession the timer would go up really fast - Fixed a bug where most productive day would show as a 0 if there wasn't any data - Fixed a bug where history wouldn't reset after resetting data
1 parent c93f363 commit cc0f646

5 files changed

Lines changed: 70 additions & 43 deletions

File tree

Package/data_management.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ def get_weekday():
106106
for i in range(2, 9):
107107
if self.worksheet["W" + str(i)].value != 0:
108108
weekdays_dict[self.worksheet["W" + str(i)].value] = self.day_name_list[i-2]
109-
self.best_weekday = weekdays_dict[max(weekdays_dict)]
109+
if weekdays_dict:
110+
self.best_weekday = weekdays_dict[max(weekdays_dict)]
111+
else:
112+
self.best_weekday = ""
110113
get_weekday()
111114

112115

@@ -215,18 +218,6 @@ def calculate_duration(self) -> float:
215218
def increase_goal_streak(self) -> None:
216219
self.goal_amount += 1
217220

218-
219-
def reset_data(self, workbook, worksheet) -> None:
220-
self.workbook = workbook
221-
self.worksheet = worksheet
222-
223-
self.initialize_new_file_variables()
224-
self.customize_excel()
225-
226-
self.workbook.save(self.app.data_file)
227-
228-
print("Data reset.")
229-
230221

231222
def clear_graph_lists(self) -> None:
232223
self.date_list.clear()

Package/timer_management.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@ def __init__(self, App, window):
88

99

1010
def initialize_variables(self):
11+
self.timer_start_cooldown = False
12+
self.break_start_cooldown = False
1113
self.timer_running = False
1214
self.break_running = False
1315
self.timer_time = 0
1416
self.break_time = 0
1517

1618

1719
def timer_mechanism(self, timer_button, break_button, time_display_label):
20+
if self.timer_start_cooldown:
21+
return
22+
self.timer_start_cooldown = True
23+
24+
self.window.after(1000, self.enable_timer_start)
25+
1826
self.time_display_label = time_display_label
1927
if not self.timer_running:
2028
self.app.lock_widgets()
@@ -40,6 +48,13 @@ def _update_time(self):
4048

4149

4250
def break_mechanism(self, break_button, timer_button, break_display_label):
51+
if self.timer_time < 1 or self.break_start_cooldown:
52+
return
53+
54+
self.break_start_cooldown = True
55+
56+
self.window.after(1000, self.enable_break_start)
57+
4358
self.break_display_label = break_display_label
4459
if not self.break_running:
4560
self.break_running = True
@@ -49,11 +64,19 @@ def break_mechanism(self, break_button, timer_button, break_display_label):
4964
self._update_break_time()
5065
elif self.break_running:
5166
self.break_running = False
52-
self.break_button.configure(text="Start")
67+
break_button.configure(text="Start")
5368

5469

5570
def _update_break_time(self):
5671
if self.break_running:
5772
self.break_time += 1
5873
self.break_display_label.configure(text=str(datetime.timedelta(seconds=self.break_time)))
59-
self.window.after(1000, self._update_break_time)
74+
self.window.after(1000, self._update_break_time)
75+
76+
77+
def enable_timer_start(self):
78+
self.timer_start_cooldown = False
79+
80+
81+
def enable_break_start(self):
82+
self.break_start_cooldown = False

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ Welcome to Study Time Tracker, an application designed to help you manage your s
1010
- **History**: Review past study sessions in the history tab to track your productivity.
1111
- **Eye Care Setting**: Enable the 20/20/20 setting to take breaks and care for your eyes during long study sessions.
1212
- **Color Settings**: Customize the app's color theme to suit your preferences.
13-
13+
- **Notes**: Keep track of important information, ideas, or reminders related to your study sessions.
14+
- **And More**
1415
## Installation
1516

1617
1. Clone the repository:
@@ -44,8 +45,6 @@ Welcome to Study Time Tracker, an application designed to help you manage your s
4445
4546
## Upcoming Features
4647
47-
- **Pomodoro Timer**: Introduce a Pomodoro technique timer to help users study with intervals of focused work and short breaks.
48-
- **Notes**: Allow users to take notes during their study sessions to jot down important points or ideas.
4948
- **Achievements**: Implement an achievement system to reward users for meeting study goals and maintaining consistent study habits.
5049
5150
## Contributing

main.py

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def _goal_gui_setup(self) -> None:
218218
goal_label = ctk.CTkLabel(goal_frame, text="Goal", font=(font_family, font_size), text_color=(light_font_color, font_color))
219219
goal_label.place(anchor="nw", relx=0.05, rely=0.05)
220220

221-
self.goal_dropdown = ctk.CTkComboBox(goal_frame, values=["1 minutes", "30 minutes", "1 hour", "1 hour, 30 minutes", "2 hours", "2 hours, 30 minutes", "3 hours", "3 hours, 30 minutes",
221+
self.goal_dropdown = ctk.CTkComboBox(goal_frame, values=["30 minutes", "1 hour", "1 hour, 30 minutes", "2 hours", "2 hours, 30 minutes", "3 hours", "3 hours, 30 minutes",
222222
"4 hours", "4 hours, 30 minutes", "5 hours", "5 hours, 30 minutes", "6 hours"], variable=self.default_choice,
223223
state="readonly", width=200, height=30, dropdown_font=(font_family, int(font_size*0.75)), border_color=(light_border_frame_color, border_frame_color),
224224
font=(font_family, int(font_size)), fg_color=(light_border_frame_color, border_frame_color), button_color=(light_border_frame_color, border_frame_color))
@@ -339,8 +339,8 @@ def _history_gui_setup(self) -> None:
339339
history_label_frame.pack(pady=(frame_padding*1.2, frame_padding))
340340
history_label_frame.grid_propagate(False)
341341

342-
history_data_frame = ctk.CTkScrollableFrame(history_frame_frame, fg_color=(light_frame_color, frame_color), width=WIDTH-(frame_padding*4), height=500+frame_padding*4, corner_radius=10)
343-
history_data_frame.pack(padx=frame_padding)
342+
self.history_data_frame = ctk.CTkScrollableFrame(history_frame_frame, fg_color=(light_frame_color, frame_color), width=WIDTH-(frame_padding*4), height=500+frame_padding*4, corner_radius=10)
343+
self.history_data_frame.pack(padx=frame_padding)
344344

345345
start_label = ctk.CTkLabel(history_label_frame, text="Start", font=(font_family, int(font_size*1.25)), text_color=(light_font_color, font_color), fg_color="transparent", width=(WIDTH-(frame_padding*4))/5, height=30)
346346
start_label.grid(row=0, column=0, pady=widget_padding_y)
@@ -353,31 +353,31 @@ def _history_gui_setup(self) -> None:
353353
subject_label = ctk.CTkLabel(history_label_frame, text="Subject", font=(font_family, int(font_size*1.25)), text_color=(light_font_color, font_color), fg_color="transparent", width=(WIDTH-(frame_padding*4))/5, height=30)
354354
subject_label.grid(row=0, column=4, pady=widget_padding_y)
355355

356-
start_frame = ctk.CTkFrame(history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
356+
start_frame = ctk.CTkFrame(self.history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
357357
start_frame.grid(row=1, column=0)
358358
start_frame.pack_propagate(False)
359359
self.start_text = ctk.CTkLabel(start_frame, font=(font_family, font_size), text_color=(light_font_color, font_color), text="-")
360360
self.start_text.pack()
361361

362-
end_frame = ctk.CTkFrame(history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
362+
end_frame = ctk.CTkFrame(self.history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
363363
end_frame.grid(row=1, column=1)
364364
end_frame.pack_propagate(False)
365365
self.end_text = ctk.CTkLabel(end_frame, font=(font_family, font_size), text_color=(light_font_color, font_color), text="-")
366366
self.end_text.pack()
367367

368-
duration_frame = ctk.CTkFrame(history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
368+
duration_frame = ctk.CTkFrame(self.history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
369369
duration_frame.grid(row=1, column=2)
370370
duration_frame.pack_propagate(False)
371371
self.duration_text = ctk.CTkLabel(duration_frame, font=(font_family, font_size), text_color=(light_font_color, font_color), text="-")
372372
self.duration_text.pack()
373373

374-
break_frame = ctk.CTkFrame(history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
374+
break_frame = ctk.CTkFrame(self.history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
375375
break_frame.grid(row=1, column=3)
376376
break_frame.pack_propagate(False)
377377
self.break_text = ctk.CTkLabel(break_frame, font=(font_family, font_size), text_color=(light_font_color, font_color), text="-")
378378
self.break_text.pack()
379379

380-
subject_frame = ctk.CTkFrame(history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
380+
subject_frame = ctk.CTkFrame(self.history_data_frame, fg_color="transparent", width=(WIDTH-(frame_padding*4))/5)
381381
subject_frame.grid(row=1, column=4)
382382
subject_frame.pack_propagate(False)
383383
self.subject_text = ctk.CTkLabel(subject_frame, font=(font_family, font_size), text_color=(light_font_color, font_color), text="-")
@@ -640,7 +640,7 @@ def create_total_time_graph(self, frame):
640640
fig, ax = plt.subplots(figsize=(5, 5))
641641

642642
# Plot
643-
ax.plot(dates, cumulative_times, marker='o', color=self.data_manager.color)
643+
ax.plot(dates, cumulative_times, color=self.data_manager.color)
644644

645645
fig, ax = plt.subplots()
646646
ax.plot(dates, cumulative_times, color=self.data_manager.graph_color)
@@ -677,9 +677,9 @@ def clear_frame(self, frame):
677677

678678
def create_graphs(self) -> None:
679679
self.statistics_frame.grid_propagate(False)
680+
plt.close("all")
680681
self.clear_frame(self.statistics_facts_frame)
681682
self.clear_frame(self.statistics_graph_frame)
682-
#self.WINDOW.after(10, self.statistics_scroll_frame._parent_canvas.yview_moveto, 1.0)
683683

684684
self.create_time_spent_graph(self._graph_gui_frame(0, 0))
685685
self.create_weekday_graph(self._graph_gui_frame(0, 1))
@@ -697,7 +697,7 @@ def create_graphs(self) -> None:
697697
self.create_funfact(0, 2, "Average study Start Time", "00:00")
698698
self.create_funfact(0, 3, "Goal Met in", "0%", "of Sessions")
699699
self.create_funfact(0, 4, "Favorite subject", "")
700-
self.create_funfact(0, 5, "Most Productive Day", "0")
700+
self.create_funfact(0, 5, "Most Productive Day", "")
701701

702702
else:
703703
self.create_funfact(0, 0, "Average Study Duration", round(self.data_manager.total_duration/self.data_manager.data_amount, 1), "Minutes")
@@ -871,17 +871,7 @@ def save_data(self) -> None:
871871

872872
#Only be able to save if time is higher than 1m
873873
if time_in_minutes >= 1:
874-
self.frequency_input.configure(state="normal")
875-
self.frequency_input.delete("end")
876-
self.duration_input.configure(state="normal")
877-
self.duration_input.delete("end")
878-
self.autobreak_button.configure(state="normal", fg_color=button_color)
879-
self.break_button.configure(state="normal", fg_color=button_color, command=lambda: self.timer_manager.break_mechanism(self.break_button, self.timer_button, self.break_display_label), hover=True)
880-
self.subject_button.configure(state="normal", fg_color=button_color)
881-
self.goal_button.configure(state="normal", fg_color=button_color)
882-
self.goal_dropdown.configure(state="normal")
883-
self.subject_selection.configure(state="normal")
884-
self.autobreak_switch.configure(state="normal")
874+
self.unlock_widgets()
885875

886876
if time_in_minutes >= self.goal:
887877
self.data_manager.increase_goal_streak()
@@ -905,7 +895,7 @@ def save_autobreak(self) -> None:
905895
if "." in frequency_input:
906896
frequency_input = (frequency_input.split(".")[0]).replace(".", "")
907897

908-
if len(frequency_input) == 0:
898+
if len(frequency_input) == 0 or int(frequency_input) == 0:
909899
frequency_input = self.data_manager.autobreak_frequency
910900
else:
911901
if self.data_manager.autobreak_frequency != self.frequency_input.cget("placeholder_text"):
@@ -918,7 +908,7 @@ def save_autobreak(self) -> None:
918908
if "." in duration_input:
919909
duration_input = (duration_input.split(".")[0]).replace(".", "")
920910

921-
if len(duration_input) == 0:
911+
if len(duration_input) == 0 or int(duration_input) == 0:
922912
duration_input = self.data_manager.autobreak_duration
923913
else:
924914
if self.data_manager.autobreak_duration != self.duration_input.cget("placeholder_text"):
@@ -1039,9 +1029,17 @@ def reset_data(self) -> None:
10391029
self.timer_manager.timer_running = False
10401030
self.timer_manager.break_running = False
10411031
self.reset_gui_values()
1032+
self.clear_hisotry()
10421033

10431034
self._file_setup()
10441035

1036+
print("Data reset.")
1037+
1038+
1039+
def clear_hisotry(self):
1040+
for widget in self.history_data_frame.winfo_children():
1041+
widget.destroy()
1042+
10451043

10461044
def scroll(self, direction: str) -> None:
10471045
if self.scrolling:
@@ -1132,6 +1130,20 @@ def lock_widgets(self):
11321130
self.break_button.configure(state="disabled", fg_color = "grey", command=None, hover=False)
11331131

11341132

1133+
def unlock_widgets(self):
1134+
self.frequency_input.configure(state="normal")
1135+
self.frequency_input.delete("end")
1136+
self.duration_input.configure(state="normal")
1137+
self.duration_input.delete("end")
1138+
self.autobreak_button.configure(state="normal", fg_color=button_color)
1139+
self.break_button.configure(state="normal", fg_color=button_color, command=lambda: self.timer_manager.break_mechanism(self.break_button, self.timer_button, self.break_display_label), hover=True)
1140+
self.subject_button.configure(state="normal", fg_color=button_color)
1141+
self.goal_button.configure(state="normal", fg_color=button_color)
1142+
self.goal_dropdown.configure(state="normal")
1143+
self.subject_selection.configure(state="normal")
1144+
self.autobreak_switch.configure(state="normal")
1145+
1146+
11351147
def save_on_quit(self) -> None:
11361148
self.save_data()
11371149
print("Data saved on exit.")

requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
CTkMessagebox==2.5
12
customtkinter==5.2.2
3+
darkdetect==0.8.0
24
DateTime==5.4
35
matplotlib==3.8.2
46
openpyxl==3.1.2
57
pandas==2.1.4
6-
winotify==1.1.0
8+
winotify==1.1.0

0 commit comments

Comments
 (0)