June 10 Project Day
[11:17 am] Today I’m going to work on a personal project and try to document my progress as I go. I’m giving myself a total of 12 pomodoros (at 25 mins each) to get my work done, with a 35 minute break after I complete six.
My goal is in part to get some practical work done, and to a greater extent to intentionally observe how I work throughout a single full(-ish) day.
Pomodoro #1 is dedicated to exploring the project I’ll work on today and coming up with ideas for how to approach things.
The full scale tool I want to build is essentially an automated personal assistant of sorts, but that scope is potentially infinite. So to narrow it down, I’m thinking about working on a checklist management feature.
There are lots and lots of things I need to do every day on a recurring basis, and I tend to use Slack reminder alerts for that purpose. Things like “Take your vitamins with breakfast daily”, “Use the rowing machine every Monday, Wednesday, and Friday”, “Join the #CodeNewbie chat every Wednesday at 9pm”, and so on. These are simple examples, but it’s not uncommon for me to have a dozen or more of these alerts for a single day… and that’s what gets complicated.
When you’re constantly being alerted for each individual thing, it’s easy to start ignoring alerts, especially if you’re distracted. It would be nice to be able to pull up a list and say “OK, what was I supposed to do today, and did I do it or not yet?” — Slack sort of gives you this ability but not in a very clean way for recurring tasks.
There are also other kinds of recurring activities or objectives which have data attached to them, scattered across a thousand different systems. For example, I monitor my blood pressure daily, and then key this information into a Google sheet. I have a slack reminder that tells me to fill it out, but it would be much better to have a small card with a form field on it that shows up every day and simply asks you to fill in the data directly. This would eliminate the separation between the reminder and the actual data entry task, which would reduce friction considerably.
Similarly, I try to hit a 10,000 step walking goal every day. My Fitbit does a great job of tracking this data and it’s obvious when you’ve hit the goal because it does a cheesy little animation and vibrates… but I have to remember to look at either the watch itself or the app on my phone to see where I’m at with things. The problem isn’t tracking or alerting on the information, it’s showing it in the context of everything else that’s going on in my day. So it’d be nice to have these automated cards too, which show where you’re at on various metrics and give you a red/green result alongside everything else you’re tracking for that day.
To make a long story short, I want to be able to easily see things like “Alright, you have all this stuff on your calendar for the rest of the day, and you’re only at 1500 steps. When are you going to do that? 11pm? That’ll suck. Oh and by the way, you’re supposed to row today too.”
The examples I’ve given are mostly around health related metrics because that has been a strong focus for me lately, but my work is full of things like this too. Submit an article to my editor by Friday, spend 1.5 hours doing course prep every evening for a week, so on and so forth. Reminders can tell me when to do these things, calendars can let me plan out a schedule, but I also want to see “Well, did you do this or not? And if not, what was the surrounding context of your day that might have caused things to not work as you’d hoped.”
I feel like I’m getting too far out into the weeds now, so I’ll reel it back in and take the next pomodoro to start designing a single feature that might help with some of these problems. But the grand vision is sort of a smart dashboard that gives you checklists, data monitoring, and survey forms broken down by day, so that if you look in that one place you can see all your personal management chores + information in one place… and then you can mine historical data to keep tuning your routines.
I won’t get anywhere close to building that today, so now I’ll take a few minutes break and ponder what I could build.
Pomodoro #2 is dedicated to designing a single usable feature that I can build a walking skeleton for and then iterate on.
[11:48 am] After a failed attempt to locate my headphones, I’m back at my desk and continuing work. The hunt for the headphones will resume in the next break.
Now I will head over to myBalsamiq and see if I can get some mockups put together for um… something based on the stuff I talked about above.
[12:03 pm] OK, I have a mockup made that looks like hardly anything at all, but switching to a visual mode of thinking about the problem was useful to me…
This is essentially what I want… a todo-list like thing that dynamically figures out what to show on the list depending on the day (and maybe even the time of day… i.e. we could gray out upcoming tasks until they become actionable… but I’m deferring thinking about that until later)
There remains a question of… “what do we do about the checklist items that were missed on a given day?” — For something like “Take Vitamin D”, I’d definitely want that to be shown again on Thursday, because if I was a day late that’s not a big deal but skipping a week is not desireable. For the “Row for 30 mins” item, it’s less clear… some days I’d possibly move that into the next days, other times I’d just skip.
It seems like what might work well is for any checklist item that was missed… we could display an alert on the following day which asks you what action you want to take….
- I actually did it, I just forgot to check the box. So check the box on yesterday’s sheet for me.
- I didn’t do it, and I need to, so add it to my sheet for today.
- I didn’t do it, and I need to, but I can’t do it now, so snooze it until (time + day)
- I didn’t do it, and I don’t plan to, so just leave it unchecked for yesterday and stop complaining about it.
Immediately I’ve found more than enough complexity for this one feature! I think I’ll spend the next pomodoro standing up a web application and doing some very minimal HTML mockups so that I get that out of the way and can do design + implementation in parallel. Break time!
Pomodoro #3 is about getting a (Rails) web app running w. minimal HTML mockups so that I have an implementation test bed to work with.
[12:15pm] Headphones located! This is a practical matter because without them, I tend to wander far from my computer and don’t hear the pomodoro ring to tell me to get back to work. Now I can go anywhere in my house or even into the yard on breaks and still hear the ticking and ringing of the timer.
Alright, time to get a barebones Rails app up and running on Heroku.
Of course this meant immediately spending a few minutes thinking about names, which is a waste of time. I had filled in MyHUD in the mockup but that’s already used and also a bit cheesy. Every name will be used, so let me just use a common name for now. I spun a random word generator until I came across “Drumbeat” and that works for me… and it was surprisingly available as a Heroku app name.
[12:27pm] I sure hope Nokogiri finishes compiling before this Pomodoro wraps up. 😦
[12:35pm] Success! (Ahahaha, can you call it that?)
It’s funny, this simple “Hello World” example made me notice that the default timezone is set to UTC. Because this is an app only for me for now, I’ll set it to my own zone (US East).
[12:41pm] Break time. Didn’t get to do any actual mockups yet, and still need to add bootstrap. Will do that for the next Pomodoro, then!
Pomodoro #4 will continue to focus on preparing HTML mockups live on Heroku
[12:48pm] Back to work!
[12:53pm] I’ve worked on Rails 5.1 apps before but this is the first time I’m setting one up from scratch, forgot jQuery is not included by default anymore (had to do yarn add jquery to enable it).. now bootstrap-sass seems to be working after following README instructions.
[1:04pm] Now realizing that I also need to add the webpacker gem in order for Heroku to compile JS assets and also use yarn, etc. We had a setup guide when I was working with an agency, and I’ve intentionally decided to start from scratch to make my own documents now that I’m working solo… but it probably would have saved me the headache of hitting these little snags.
[1:09pm] Still dealing with asset compilation issues, fun!
[1:11pm] Break time. Looks like I need to run ./bin/rails webpacker:install. Fingers crossed that it’ll work and when I get back I can do something other than fuck around with Rails configuration details.
Pomodoro #5 will focus on preparing HTML mockups for realz
[1:16pm] OK, installing webpacker (and adding jquery again via yarn) seems to have gotten Bootstrap working on Heroku. I could have used a CDN or manually installed bootstrap, but as soon as I wanted to add another JS dependency I would have been hitting these questions anyway. Also, all of the notes above will go into a setup guide to speed this up for me in the future, so not all is lost.
But now I get to work on what I actually came here to do… or so I hope.
[1:25pm] It’s nothing, but it’s something… I’ll take it!
All of this is just hard coded static text. The next step will be to make it do something, I guess. An OK first step would be for it to at least read this data from the server (even if it’s hard coded on that end), ideally asynchronously.
[1:33pm] The following setup will work for now… I don’t want to focus too much on the UI problems yet, because I want to deal with the recurrence logic, persisting these reminder states, alerts for unchecked entries from the previous day, etc…
I will take a few minutes to think through how I want to model reminders and what interactions I’ll implement first, then take my break. Once I return, I’ll focus on “making it do something!”
Pomodoro #6 will focus on functional mockups of interacting with reminders
[1:48pm] OK, now I’m sketching some stuff on paper to try to figure out how to get an interaction of some sort into the mix… I think I’ll start with the recurrence relationships and maybe a date pager of some sort so you can see the list of reminders for each day.
I’m not really trying to figure out how to properly model things because I still am not certain what features this application will have. Instead, I’m bootstrapping a functional prototype because I tend to learn most from actually interacting with an application. I will not feel bad at all if I gut the implementation and completely replace it later, and will gladly cut corners in these early stages to an extreme degree.
[2:03pm] I spent a few minutes thinking, and also dug through the IceCube recurrence library documentation. I started to think about whether one off reminders and recurring reminders could be unified, which is definitely a premature modeling optimization. Then I started to wonder, where are we going to track the “Completed” status? Does that need to be its own model, like ReminderStatus, or something?
It got too confusing. So I’m simplifying for now to an extreme degree… a single Reminder model with date, note, and completed fields. This is not enough, but it’s a starting point. I can experiment with recurrence patterns and generating these reminder records after I get this simple version in place.
So it’s time to go write some migrations and load some seed data into the system.
[2:11pm] Oh, it’s time for my long break now! I’ve got the models built but will go and get a bit of rest, which is probably a good idea at this point.
Pomodoro #7 Continue on modeling reminders
[2:47pm] I’m back! I ended up taking a nap during the break so um… I’m re-establishing my bearings and will be back on track shortly.
[3:01pm] Of course I got the argument order wrong for strptime and of course I needed to look up the patterns for strftime.
[3:05pm] And of course I forgot to run migrations on Heroku.
[3:10pm] Huzzah! Different reminders showing up for different days, based on querying the database. It’s hacked to hell, but it’s starting to at least make me imagine what it’ll really look like…
Break time! (Need to wait a little longer than 5 mins to start #8 because I have food on the way, but back super soon)
Pomodoro #8: Update completed status w. JS
[3:27pm] As I said before, I’m bad at JS. But I think I can handle getting this form to update the records completed status whenever you click a checkbox, so that’s what I’m going to focus on first. If time permits, I’ll add other UI pieces like a date selector of some sort.
[3:50pm] I started with just a basic (non-JS) form submission and realized I’m not even particularly good at that! I really need to practice frontend web dev more.
Took a while looking around at how to deal with checkboxes (because they don’t submit false values, you need to have a blank hidden field in order to track things like a checked box going to unchecked.)
This is done for you by Rails’s check_box method, but not by check_box_tag.
This whole view isn’t following good Rails practices, that much I know. But at least now I know where specifically my weak spots are. Filling them in will be a problem for later.
Pomodoro #9: Continue update completed status from #8
[4:10pm] Progress! I have the form updating the reminder records in the DB, with a manual submission flow (i.e. click a submit button, send a request to rails, redirect back to the form). Now let’s see if I can get the form to submit whenever you click on a checkbox.
(I know, I know, this is only a half measure… later we’ll want to do a remote call to avoid a form refresh, and ideally only update one checkbox at a time, etc… but from an outside-in perspective, this will kind-of-sort-of-work and then I can decide whether to go deeper on getting the JS behavior right or shift to other features.)
[4:17pm] OK! That’s working! The reason I felt that this was an important feature to add, even if I hacked it together inappropriately, is because I’ve gotten used to the idea of web applications automatically updating as you enter data, and I worry that it’d be very easy to forget to press a “save changes” button and then things would get out of sync. I more or less know how to rewrite this to use a proper remote update flow, but I’d be slogging through a bunch of web searches and examples to get there rather than doing it from memory, and so it’s not the best use of my time right now.
Instead, I’ll now add date selectors.
[4:25pm] Is it pretty? Not at all. Is it functional, you bet! Good enough for now.
Pomodoro #10: Take a step back and consider next steps
[4:36 pm] So far I’ve done more reminding myself of basic web dev skills and messing w. configuring various tools than I have done application development/design, and I only have about 1.5 hrs left in my work day. My tool is not really usable for my needs yet… even in a most minimal sort of way. That’s OK but since I probably won’t find another big chunk of time to work on this for at least another week or two, it leaves me wondering… how can I best make use of this bit of time I have remaining?
Is there a path that I can take that will let me start using this application starting today, no matter how simple? I’m not sure.
What I know is I definitely need the recurring reminders, even if they’re pre-processed and then used to manually generate individual reminder records for each day for a set period of time (like two years into the future)… but physically generating individual records from a recurrence pattern will lead to all sorts of problems right out the gate… because it’ll make it a nightmare to update things.
I could potentially add a boolean flag to the individual records, like autogenerated. This would make it possible to do an update to the recurrence pattern set via a mark and sweep… i.e. go through and delete all the records where autogenerated is true, re-run the recurrences from today forward about a year or two, generate new records, etc. This is such a hack that the only reason why I’m thinking about it is because it might get me to a (barely) usable tool today rather than weeks from now. If I sat down to model this properly, I could do a much better job. (This is the kind of stuff I’m actually good at, unlike JS/Web dev… but it takes time!)
But suppose I went that route… then I’d have something like a CSV file that I could check into the repository, with things like this…
"Row 30 minutes",weekly,"M" "Row 30 minutes",weekly,"W" "Row 30 minutes",weekly,"F" "Vitamin B12", daily "Vitamin D", weekly, "W" "Meet with Sue @ 9am",once,2017-06-14
And then if I make a change to this file and check it in, and run a task like rake update_schedule, then it’d generate all the reminder records I needed.
I could even make the update mechanism a little smarter… this is a small total number of reminders no matter what, so I could literally generate the whole new list and then only delete the records that aren’t in the newly generated list… allowing me to preserve the “complete” status.
None of this is sound engineering! But what I’m really more interested in at this point is… will I even use this tool? Is seeing all my reminders in one place and being able to check them off as I complete them valuable? Is it useful to look backwards and forwards through day views rather than having everything lumped in one big list in Slack?
In other words, I sort of want to test out the product before I worry too much about the code. Hmm… I’m convinced that some variant on the above might work. Maybe to make it a bit less annoying, I can persist the CSV file in the database, and create a simple form for updating it. This way I won’t need to go and commit something into git, push a deploy, run a script, etc. just to update my schedule.
Later on, there will definitely be a normal UI for adding, updating, and removing reminders. But that can wait.
I’m also slightly curious about the possibility of supporting Slack-like syntax in a text box, i.e. remind “Buy chia seeds” tomorrow — but I know that’s going to be something that’ll easily turn into a project in of itself.
Alright, I’m convinced some variant of the above is worth a shot. Let’s see what I can get done in the next hour.
Pomodoro #11: Build a CSV-based import script for updating reminders
[5:06pm] Gonna go heads down on this and crank it out rather than giving live updates while I work on it. I’ll post once it’s done.
[5:24pm] Don’t try this at home kids, because it’s wildly unprofessional. But this works for loading individual reminders from a CSV while preserving completed status after import even though it blows out all the old records…
Now to bring in the “weekly” pattern, which probably means it’s time to install IceCube.
Pomodoro #12: Attempt to wrap up CSV import feature
[5:56pm] Huzzah! I have recurring scheduled reminders for “daily, weekly, and once” all working, and deployed to Heroku. I didn’t get to build the web form for updating the CSV data, but I imagine I’ll be able to do that when I find a spare half hour or so in the next couple days.
This is what the configuration file ended up looking like:
note,frequency,details "Vitamin B12",daily "Row 30 mins",weekly,"Mon/Wed/Fri" "Vitamin D",weekly,Tue
Not the most human friendly interface, but something I can live with for a few days, if only to test out the workflow and see whether it’s useful to me or not.
Given that I started the day out with just a vague idea of “I want to build some sort of checklist thingy”–I’m happy with my progress.
I realize from the work today how much I took our playbook for granted when I was working at an agency (i.e. it’s MUCH easier to set up a Rails app when you have a big document that you go through and it says “install this, now update this config file, now install this…” and so on… and so I need to rebuild those as soon as I can.
I also realize that there are a ton of holes in my web development skillset. I tend to do OK when working within already built applications, or when I have people around I can ask for help, but on my own, I’m just not great at anything above the domain logic layer. I need to do some dedicated practice on each of my rough patches and seek feedback if I want to be more self sufficient.
But overall, not bad for a Saturday afternoon of hacking. I learned where some of my gaps are, got a project started that I’ll hopefully keep working on, and made a document that maybe is interesting/useful to you as it shows how I work.
That’s all for now! Thanks for reading.