I think all of us, as developers, have written some kind of software that solves a unique personal problem. If you haven’t, you should. Sometimes the hardest part is finding a suitable problem of your own to solve. But even small problems can contain interesting design decisions.
In that vein, I found my own suitable problem! I also wrote up a bug-ridden mess to solve it. It worked just fine, given that I’m the only user and I can just mentally work around the bugs. But I think we can do better. Yes, “we,” because I’m going to bring you along for the ride. The hope is we can take a hastily-written program and turn it into something with good maintainability and testability, and also something that can be easily extended later on to add more features. This will be part one, where we examine some of the background information about the application so we’re all on even footing. I don’t know how many parts this will ultimately be, because I didn’t write that far ahead.
Anyway, what is it? Glad you asked. I’m somewhat interested in the world of competitive kettlebell lifting (also called “girevoy sport”). I’m no expert on that discipline, so luckily the article isn’t about that. I won’t be giving any sport-specific advice (nor should I). However, some of the training methodology calls for having pretty tight controls on the timing of lifting and resting. I assumed that there was probably some kind of application available that would allow me to track the lifting and resting time periods, but truthfully I just didn’t want to look around for one. Trying to track it via the various timers on my phone was a pain, and also I would usually have chalky hands (as expected from that style of lifting). I needed something more hands-off to minimize the amount of device interaction I’d have. After a brief amount of thinking, I remembered that I was a software developer and I was perfectly capable of producing something that fit my needs. Thus, a quick and dirty timer was created.
Let’s examine some of the requirements I had before we look at the software itself. This is my preferred approach, anyway. I prefer to spend time thinking through the design of something before even thinking about opening my development environment.
I wasn’t especially interested in using a phone for this kind of work because they tend to be pretty small, and I wanted the visual cues from the program to be readable and immediately obvious. Also, to get them to stand up so you can look at them, you require some kind of secondary device, like a tripod. That’s not to say that I won’t eventually reproduce this in some form for a mobile device, but I didn’t start out with that in mind. (As an aside, while writing this and discussing how a phone wasn’t appropriate, I thought of several ways to implement this on a phone. That may come later!)
I wanted to specify lifting and resting durations, and I also wanted the end of the lift timer to signal the beginning of the rest timer. Also, it was necessary that I had a target for total lifting sets, and a way to automatically count those up. It bears repeating that being as hands-off as possible was my goal. I wanted to kick it off after a small amount of initialization and not worry about it.
Looking around, I noticed that I had a Surface Go handy. Anything I came up with could run on that just fine. It wasn’t a requirement to write it targeting Windows desktop, but it made sense to me at the time. I suppose it still does, in that if I wanted to extend this, there are plenty of suitable laptops in the world. It might not be such a stretch to assume that someone may want to involve their laptop for lifting at home, anyway. (The more I write about this, the more it seems like a phone-based implementation may be workable. Oh well, you’re getting the desktop version first). WPF was my choice for the framework because it seems to be a mature technology with robust support, and it would install on a wide variety of Windows devices. Plus it interested me, so that was a good enough reason.
In summation, my minimum viable approach called for:
- Readable visual cues/communication from the program.
- User-specified lifting and resting duration.
- User-specified total lifting sets.
- Automatic switching between lift and rest timers.
- Automatic counting of lift sets.
- Targeting Windows.
- As little interaction as possible after initial setup.
I think that’s something we can work with. In the next part, we’ll be taking a look at the implementation of the timers, since this whole thing hinges on having two timers behave the way that I’d like them to. If we can’t figure that out, then this project isn’t going anywhere.
(Spoiler: Of course we figure it out.)