Create workout_tracker.py#1
Conversation
WalkthroughIntroduces a new Tkinter GUI application in workout_tracker.py with a tabbed interface for tracking workouts and viewing analytics. Implements a rest timer, set logging with validation, recent sets management (add/delete), and dynamic analytics (volume, estimated 1RM, total sets). Data stored in-memory as dictionaries; UI updates on changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as WorkoutTrackerApp UI
participant Timer as RestTimer
participant Store as In-Memory Store
participant Analytics as Analytics View
rect rgb(240,248,255)
note over User,UI: Add Set Flow
User->>UI: Enter exercise, weight, reps
User->>UI: Click "Add Set"
UI->>UI: Validate inputs
alt valid
UI->>Store: Append workout dict (exercise, weight, reps, volume, date)
UI->>UI: Update Recent Sets list
UI->>Analytics: Rebuild analytics panels
else invalid
UI-->>User: Show message box (error)
end
end
rect rgb(245,255,250)
note over User,Timer: Rest Timer Controls
User->>Timer: Start
Timer-->>UI: Periodic tick updates (countdown)
User->>Timer: Pause / Reset
Timer-->>UI: Update display (paused/reset)
end
rect rgb(255,250,240)
note over User,UI: Delete Set Flow
User->>UI: Select recent set and click "Delete"
UI->>Store: Remove selected entry
UI->>UI: Refresh Recent Sets list
UI->>Analytics: Recompute and rebuild analytics view
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
workout_tracker.py(1 hunks)
🧰 Additional context used
🪛 Ruff (0.13.1)
workout_tracker.py
106-106: String contains ambiguous ➕ (HEAVY PLUS SIGN). Did you mean + (PLUS SIGN)?
(RUF001)
143-143: Unused lambda argument: e
(ARG005)
223-223: String contains ambiguous × (MULTIPLICATION SIGN). Did you mean x (LATIN SMALL LETTER X)?
(RUF001)
| def start_timer(self): | ||
| if not self.timer_running: | ||
| self.rest_time = self.rest_time_var.get() | ||
| self.timer_seconds = self.rest_time | ||
| self.timer_running = True | ||
| self.start_btn.config(state=tk.DISABLED) | ||
| self.pause_btn.config(state=tk.NORMAL) | ||
| self.run_timer() | ||
|
|
||
| def run_timer(self): | ||
| if self.timer_running and self.timer_seconds > 0: | ||
| self.timer_label.config(text=self.format_time(self.timer_seconds)) | ||
| self.timer_seconds -= 1 | ||
| self.root.after(1000, self.run_timer) | ||
| elif self.timer_seconds == 0: | ||
| self.timer_running = False | ||
| self.start_btn.config(state=tk.NORMAL) | ||
| self.pause_btn.config(state=tk.DISABLED) | ||
| self.timer_label.config(text="0:00") | ||
|
|
||
| def pause_timer(self): | ||
| self.timer_running = False | ||
| self.start_btn.config(state=tk.NORMAL) | ||
| self.pause_btn.config(state=tk.DISABLED) | ||
|
|
||
| def reset_timer(self): | ||
| self.timer_running = False | ||
| self.rest_time = self.rest_time_var.get() | ||
| self.timer_seconds = self.rest_time | ||
| self.timer_label.config(text=self.format_time(self.rest_time)) | ||
| self.start_btn.config(state=tk.NORMAL) | ||
| self.pause_btn.config(state=tk.DISABLED) | ||
|
|
There was a problem hiding this comment.
Pause resumes reset the countdown
Pressing Start after Pause jumps straight back to the full rest duration because start_timer always reloads self.rest_time_var and overwrites self.timer_seconds. That breaks the pause/resume flow and forces users to restart every rest period from scratch. Only reset the counter when the countdown has finished (or before the first run).
Apply this diff to preserve the remaining time on resume:
def start_timer(self):
if not self.timer_running:
- self.rest_time = self.rest_time_var.get()
- self.timer_seconds = self.rest_time
+ if self.timer_seconds <= 0:
+ self.rest_time = self.rest_time_var.get()
+ self.timer_seconds = self.rest_time
self.timer_running = True
self.start_btn.config(state=tk.DISABLED)
self.pause_btn.config(state=tk.NORMAL)
self.run_timer()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def start_timer(self): | |
| if not self.timer_running: | |
| self.rest_time = self.rest_time_var.get() | |
| self.timer_seconds = self.rest_time | |
| self.timer_running = True | |
| self.start_btn.config(state=tk.DISABLED) | |
| self.pause_btn.config(state=tk.NORMAL) | |
| self.run_timer() | |
| def run_timer(self): | |
| if self.timer_running and self.timer_seconds > 0: | |
| self.timer_label.config(text=self.format_time(self.timer_seconds)) | |
| self.timer_seconds -= 1 | |
| self.root.after(1000, self.run_timer) | |
| elif self.timer_seconds == 0: | |
| self.timer_running = False | |
| self.start_btn.config(state=tk.NORMAL) | |
| self.pause_btn.config(state=tk.DISABLED) | |
| self.timer_label.config(text="0:00") | |
| def pause_timer(self): | |
| self.timer_running = False | |
| self.start_btn.config(state=tk.NORMAL) | |
| self.pause_btn.config(state=tk.DISABLED) | |
| def reset_timer(self): | |
| self.timer_running = False | |
| self.rest_time = self.rest_time_var.get() | |
| self.timer_seconds = self.rest_time | |
| self.timer_label.config(text=self.format_time(self.rest_time)) | |
| self.start_btn.config(state=tk.NORMAL) | |
| self.pause_btn.config(state=tk.DISABLED) | |
| def start_timer(self): | |
| if not self.timer_running: | |
| # Only reload the full rest duration if the previous countdown has finished | |
| if self.timer_seconds <= 0: | |
| self.rest_time = self.rest_time_var.get() | |
| self.timer_seconds = self.rest_time | |
| self.timer_running = True | |
| self.start_btn.config(state=tk.DISABLED) | |
| self.pause_btn.config(state=tk.NORMAL) | |
| self.run_timer() |
🤖 Prompt for AI Agents
In workout_tracker.py around lines 163 to 195, start_timer currently always
reloads self.rest_time_var and overwrites self.timer_seconds which causes a
paused timer to restart at full duration; change start_timer so it only
initializes self.rest_time and self.timer_seconds when beginning a new countdown
(e.g., if self.timer_seconds is None or self.timer_seconds == 0), otherwise
leave self.timer_seconds unchanged to preserve remaining time on resume; ensure
reset_timer continues to reload rest_time_var and set timer_seconds for fresh
starts or finished countdowns.
Docstrings generation was requested by @mitsuomkinoshita-tech. * #1 (comment) The following files were modified: * `workout_tracker.py`
|
Note Generated docstrings for this pull request at #2 |
Docstrings generation was requested by @mitsuomkinoshita-tech. * #1 (comment) The following files were modified: * `workout_tracker.py`
|
Note Generated docstrings for this pull request at #3 |
|
@coderabbitai can you confirm that the pause resumes resets the countdown counter? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 13095 @mitsuomkinoshita-tech: I've analyzed the timer code and found an issue with the pause/resume functionality. Here's what's happening: Current Behavior (Bug)Pause does NOT properly resume - it actually resets the countdown. Here's why:
def start_timer(self):
if not self.timer_running:
self.rest_time = self.rest_time_var.get()
self.timer_seconds = self.rest_time # ← This resets to original time!
self.timer_running = True
# ...Reset works correctly - it resets the timer to the configured rest time. Fix RequiredTo make pause/resume work properly, you need to track whether the timer was paused. Here's the corrected code: def __init__(self, root):
# ... existing code ...
self.timer_seconds = 0
self.timer_running = False
self.timer_paused = False # Add this flag
self.rest_time = 90
# ... rest of init ...
def start_timer(self):
if not self.timer_running:
# Only reset if not resuming from pause
if not self.timer_paused:
self.rest_time = self.rest_time_var.get()
self.timer_seconds = self.rest_time
self.timer_paused = False
self.timer_running = True
self.start_btn.config(state=tk.DISABLED)
self.pause_btn.config(state=tk.NORMAL)
self.run_timer()
def pause_timer(self):
self.timer_running = False
self.timer_paused = True # Mark as paused
self.start_btn.config(state=tk.NORMAL)
self.pause_btn.config(state=tk.DISABLED)
def reset_timer(self):
self.timer_running = False
self.timer_paused = False # Clear pause flag
self.rest_time = self.rest_time_var.get()
self.timer_seconds = self.rest_time
self.timer_label.config(text=self.format_time(self.rest_time))
self.start_btn.config(state=tk.NORMAL)
self.pause_btn.config(state=tk.DISABLED)Summary: Currently, pause → start resets the timer instead of resuming. Reset works correctly. The fix adds a |
Summary by CodeRabbit