I have had a meta goal for keeping ahead of the road across my goals for a while. This way I can make sure that I still do the average on a list of goals but I get to choose what to do more of on a specific day. Plus helps to avoid the stress of having every single one in the red every day and burning the buffer due to acrasia rather than saving it for emergencies. This post is not to argue why something like this is useful (I know there are various modes of using Beeminder) but to suggest a new concept of how to implement that meta goal.
For years, I have been doing it by summing the “days until derailment,” first manually, then, since recently, using API and Python. Here I described my approach in my personal journaling thread.
What I always found annoying about using the days-until-derailment as a proxy is how such a meta goal behaves around flat spots / lower-rate spots / post-derailment respites. The thing is, if I am really interested in how far ahead of the road I am, it is “how far above the road” I am, because progress in Beeminder graphs is moving up. And when we have monotonously increasing (do-more or odometer) or monotonously decreasing (whittle-down) goals, no upcoming changes in the road, simple geometry suggests that “how far above the road the latest datapoint is” is absolutely synonymous to “how soon a horizontal line from the latest datapoint crashes into the road unless more progress is done”. Works perfectly.
But as soon as there are any changes in the road planned, these things stop to be the same, geometrically speaking. Consequently:
- a derailment immediately ups the meta goal with the number equal to the number of days of the post-derailment respite. So, a derailment on one goal automatically decreases the positive effect of the meta goal on every other goal in the list on the day after derailment.
- introduced flat spots or lower-rate spots actually start affecting the meta goal as many days ahead of the planned break as I have “days until derailment on that goal”. Which is not how a flat spot should work. If I add one for travel, I want a lowered load exactly on the days when I travel, not a week before. But this is what I get currently. And then the normal load instead of the lowered load on the last days of the break, as far as the goal’s impact on the meta goal is concerned.
- because of #2, it is impossible to time a break on the meta goal for such days away like when travelling, so I necessarily derail every time after such days.
While using days-until-derailment had the upside of using an easily available, already visibly displayed value when I was still counting the sum manually, now that I am having Python calculate it for me anyways, it’s not that important anymore.
So, I came up with an implementation that actually takes into account how far ahead of plan = above the road I am. Thus, the flat spots work when they are expected to, not several days earlier. The tricky question was what to use as the baseline value when converting the vertical distance from the road into “days ahead of plan”. I decided that it will be the highest rate for all segments between today and the goal end date. This is based on the assumption (that might be not true for other use cases) that there is some rate which is normally in use for a goal, which is only lowered to 0 or to a decreased number in specific situations, but otherwise it is the rate that the user strives to. I.e. the lower-rate spots are treated as abnormalities that will be eventually over. (Well, if someone is on a higher-rate spot at some point, then when it ends (and the rate for the remaining lifetime of the goal is lower), nothing awful will happen either, there will be just an extra boost to the meta goal on the next day. Like the #1 consequence above in the previous-concept meta goal, but by definition much rarer than upon every derailment.)
Anyways, if anybody would like to also use my idea, here’s the link to my repository where I posted an anonymized copy of my code (co-authored by ChatGPT). Considerations about usage copied from “readme” part there:
This code helps calculate the current value for a meta goal based on how far above the road are latest datapoints across a list of goals.
Before using, mark the list of the goals which you need to take into account with a unique tag. (It only makes sense to take into account some goals and not others. For example, it doesn’t work for do-less goals. Works best for goals where the direction of data accumulation is monotonous. E.g. odometer or do-more goals where the total can only become higher and whittle-down goals where the total can only become lower. Should work fine with odometer resets.)
Set up a goal that will accept the meta values as an odometer goal. I use the rate of 0.1, just for it to be non-zero, but the rate is not important here, since the pressure will be not from this goal’s rate but from the rates of all the goals that are taken into account.
The datapoint that is posted takes into account 10 goals with closest-to-the-road latest datapoints. Think of it as a score on the scale of 0 to 100, where 0 is “at least 10 goals are in the red today” and 100 as “all goals are at least 10 days ahead of the plan”. In my experience, it make little sense to actually strive to achieve the 90+ range, as then the freedom to work more one this or that goal disappears. Instead, it is the journey that is the destination
Add your INFO in the second cell with code.
After the last cell, you can see a recap confirming that the datapoint has been posted and a list of goals that you can work on that contribute to the meta goal.