-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
266 lines (234 loc) · 9.94 KB
/
Copy pathmain.py
File metadata and controls
266 lines (234 loc) · 9.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
"""
PyWORKOUT CLI
Copyright (C) 2021-2026 @willtheorangeguy
"""
# pylint: disable=redefined-builtin, too-many-branches, too-many-statements, too-many-locals
import os
import subprocess
import sys
import time
from datetime import datetime
try:
import config as config_mod
import history as history_mod
except ImportError: # installed as part of the package
from . import config as config_mod
from . import history as history_mod
def _play_video(path):
"""Open a video file with the OS default player."""
if sys.platform == "win32":
os.startfile(path) # pylint: disable=no-member
else:
opener = "open" if sys.platform == "darwin" else "xdg-open"
subprocess.call([opener, path])
def _now_line(start_time):
"""Return the standard 'current time / elapsed' status line."""
now = datetime.now()
return (
"The current time is: "
+ str(time.strftime("%H:%M:%S"))
+ ". "
+ str(now - start_time)
+ " has elapsed."
)
def _elapsed_for(presented, index):
"""Seconds an item was on screen: until the next item, or until now."""
start_ts = presented[index]["ts"]
if index + 1 < len(presented):
end_ts = presented[index + 1]["ts"]
else:
end_ts = datetime.now()
return end_ts - start_ts
def workout(preselect=None, config_path=None):
"""PyWorkout interactive CLI."""
workouts = config_mod.load_config(config_path)
order = config_mod.group_order(workouts)
# Per-workout state.
select = None
start_time = None
presented = [] # [{"name", "ts", "kind"}], kind in {"exercise", "video"}
def exercises_done():
"""Number of exercise activities presented so far."""
return sum(1 for p in presented if p["kind"] == "exercise")
def present_exercise():
"""Show the next exercise (or the 'all done' message) for the group."""
items = workouts[select]["exercises"]
total = len(items)
index = exercises_done()
if index < total:
name, reps = items[index]
percent = int(index / total * 100)
print("You have completed: " + str(percent) + "%")
print(
"Please complete 2 Sets of "
+ str(reps)
+ " Reps of "
+ str(name)
)
presented.append({"name": name, "ts": datetime.now(), "kind": "exercise"})
else:
print("You have completed all the workouts for this set!")
print("Run the `end` command to finish the workout. \n")
def print_completed():
"""Print every presented activity with the time it took."""
for i, item in enumerate(presented):
elapsed = _elapsed_for(presented, i)
print(str(i + 1) + ". " + str(item["name"]) + "\t(" + str(elapsed) + ")")
# Welcome banner.
print(" WELCOME TO PyWORKOUT")
print("Please select a group from those below.")
for i, key in enumerate(order):
print(str(i + 1) + ". " + key.capitalize())
print(
"A reminder that today is: "
+ datetime.today().strftime("%A")
+ ". Consider option "
+ str(int(datetime.today().strftime("%w")) + 1)
+ "."
)
# Group selection (skipped when a valid group is preselected via CLI).
if preselect is not None and preselect.lower() in workouts:
select = preselect.lower()
print(workouts[select]["display"] + " muscle group selected!\n")
else:
while select is None:
choice = str(input("\nGroup? ")).lower()
if choice == "quit":
sys.exit()
matched = None
for i, key in enumerate(order):
if choice == key or choice == str(i + 1):
matched = key
break
if matched is None:
print("Sorry that is incorrect. Please try again! \n")
else:
select = matched
print(workouts[select]["display"] + " muscle group selected!\n")
# Command loop.
while True:
activity = str(input("What do you want to do? ")).lower()
if activity == "list":
for i, (name, reps) in enumerate(workouts[select]["exercises"]):
print(
str(i + 1)
+ ". "
+ str(name)
+ "\t 2 Sets of "
+ str(reps)
+ " Reps"
)
print("")
elif activity == "start":
start_time = datetime.now()
presented.clear()
print("You have started the " + select + " muscle group. ")
print("The current time is: " + str(time.strftime("%H:%M:%S")))
present_exercise()
print("")
elif activity == "next":
if start_time is None:
print("Run the `start` command first! \n")
continue
print("You are in the " + select + " muscle group. ")
print(_now_line(start_time))
present_exercise()
print("")
elif activity == "skip":
if not presented:
print("Nothing to skip yet. Run `start` first. \n")
continue
print("You are in the " + select + " muscle group. ")
print(_now_line(start_time))
presented.pop()
print("Activity skipped! Run the `next` command to move on. \n")
elif activity == "end":
if start_time is None:
print("Run the `start` command first! \n")
continue
now = datetime.now()
duration = now - start_time
print("You have completed the " + select + " muscle group.")
print("It took " + str(duration) + " to complete this workout.")
print("The following activities were completed (time elapsed):")
print_completed()
history_mod.record_workout(
select, duration.total_seconds(), [p["name"] for p in presented]
)
print("Congratulations! \n")
elif activity == "stats":
if start_time is None:
print("Run the `start` command first! \n")
continue
print("You are in the " + select + " muscle group. ")
print(_now_line(start_time))
print("The following activities have been completed (time elapsed):")
print_completed()
print("The following activities still need to be completed:")
remaining = workouts[select]["exercises"][exercises_done():]
for i, (name, _reps) in enumerate(remaining):
print(str(i + 1) + ". " + str(name))
print("")
elif activity == "video":
if start_time is not None:
print("You are in the " + select + " muscle group. ")
print(_now_line(start_time))
path = workouts[select].get("video") or ""
if path:
_play_video(path)
presented.append(
{"name": select.capitalize() + " Video", "ts": datetime.now(), "kind": "video"}
)
else:
print(
"No video configured for "
+ select
+ ". Set one in your config (run with --init-config)."
)
print("")
elif activity == "history":
print(history_mod.format_history())
print("")
elif activity == "license":
print("PyWorkout Copyright (C) 2021-2026 @willtheorangeguy")
print(
"This program comes with ABSOLUTELY NO WARRANTY; for details view the license."
)
print("This is free software, and you are welcome to redistribute it")
print("under certain conditions; view the license for details. \n")
elif activity == "quit":
sys.exit()
elif activity == "help":
print("PyWorkout - (C) 2021-2026")
print("Any of these options are available: ")
print("list Lists the workout activities by muscle group.")
print("start Starts the workout and displays the first workout activity.")
print("next Moves to the next workout activity.")
print("skip Skips the current workout activity.")
print("end Completes the workout and display full workout statistics.")
print("stats Shows workout statistics at any point.")
print("video Opens the workout video assigned to each muscle group.")
print("history Shows your past completed workouts.")
print("license Show the license.")
print("help Prints this help text.")
print("quit Ends the program.")
print(
"More documentation can be found on Github. Enjoy using the program! \n"
)
else:
print("Sorry that is not an option. Please see this list of options below:")
print("list Lists the workout activities by muscle group.")
print("start Starts the workout and displays the first workout activity.")
print("next Moves to the next workout activity.")
print("skip Skips the current workout activity.")
print("end Completes the workout and display full workout statistics.")
print("stats Shows workout statistics at any point.")
print("video Opens the workout video assigned to each muscle group.")
print("history Shows your past completed workouts.")
print("license Show the license.")
print("help Prints a similar help text.")
print("quit Ends the program. \n")
if __name__ == "__main__":
# Running `python main.py` launches the interactive REPL directly.
# For command-line flags use the `pyworkout` script or `python -m PyWorkout`.
workout()