Documentation of aggregation methods would be nice

None whatsoever. :slight_smile: I was using this for a goal where I wanted to enforce me entering data, while ignoring the value of the data entered. And for that goal, 0 was never a value I would have entered…but it might be for someone else.


What was the upshot of this? I don’t see ‘jolly’ in the list. Has 'binary" been changed to have the ‘nonzero’ behavior? Because the ‘nonzero’ behavior is actually exactly ideal for my exercise goal (though several others work fine too).


The ‘jolly’ function has been deprecated, and removed from the selectable list. Though it still works if that’s what had been set.

Looks as though we haven’t yet made the ‘binary’ vs ‘unary’ distinction in the code.

That should be a quick #UVI though, @dreev. I looked at the code and the only thing stopping me from making the changes is that my dev env is broken and I wouldn’t be able to test it.


Done! Made nonzero a new aggday method and updated the wikified post above.


This is super! But, I don’t see it in the list on my exercise goal. Is there an overnight refresh or something?


Sorry about that! I deployed it for the back end (and thus working via the API) but I forgot to update the dropdown in the UI. Done now!


Awesome. Two of my goals are now sporting it : )

1 Like

Aaaaaand nonzero aggmode breaks pessimistic presumptions on the Do Less goals, apparently. One my goals is still sporting it though : D


Can you point us to the problematic one? (Can move this to if it makes sense to.)

1 Like

Sure thing - I emailed the deets to the support line with your name in the subject.

1 Like

Let me take another stab? If there was some possible universe in which I could get the comments for my aggday, I would have a good use for it.

My new Beelint goal is trying to track the number of goals that are in violation each day, and currently uses min to not fault you for violations that come up during the day. Sort of like how Gmail Zero works.

The problem is that I might go from A,B to B,C and it looks like those are both size 2, but C is new and shouldn’t be counted. I’d like to just count the problems that have been present ALL day. So what I’d really like is an aggday that looks like

lambda comments: len(set.intersection(*[set(c.split(',') if c else set()) for c in comments]))

If there’s no hope I can print/read a state file but I was hoping to keep my thingy stateless. :slight_smile:


skatesum : min(rfin, np.sum(x)), # only count the daily min

Can someone explain this one? What is rfin?

1 Like

Per a daily beemail by @dreev

Thanks to user kyshoc for suggesting a new aggday method that turned out to be super easy to add to the list. I’m not sure I agree it’s a good idea but here’s the use case:

Auto-ratcheting (setting “max safe days”) to never let you accumulate safety buffer only prevents you from getting whole days off. Even set to zero, it still lets you almost get a day off, like having just one more step to get the next day. This new aggday method prevents you from getting more safety buffer at all (than you already have). Like if your road is set to 100/day then anything more than 100 that you report for a day just doesn’t get plotted.

It’s kind of like using a binary goal of “did it or not” but letting you store the richer data about how much exactly you did. The reason I don’t like it is that the graph is not plotting your actual data. But I’ll be interested to hear if anyone else likes it.

It’s called skatesum because it’s used for auto-summing goals like do-more where all datapoints for a day are summed and the cumulative total is plotted, but then that daily sum is capped at the daily rate. So if you’re skating the edge of the road now (meaning the bare minimum due is the full daily average you have to maintain) then you’ll permanently be skating it.

PS: After explaining all that it occurs to me that the right way to do this is to improve and generalize the auto-ratchet feature. But skatesum is what we have in the meantime. If anyone requests it I can throw in a version for non-auto-summing roads.


Thanks! Also, can someone clarify how clocky works?

I’m thinking that if there are 2n or 2n + 1 data points from midnight to midnight, it returns sum over i from 1 to n of f(2i - 1) - f(2i) where f(x) is the xth data point, and just ignores f(2n + 1) to start again at g(1) the next day. (clock in, clock out pairs.)

Or does it include g(1) - f(2n + 1)? Then what does it do for the other g values?

Or does it just sum f(j + 1) - f(j) over j from 1 to m - 1, where there are m data points?


Thanks for asking for that clarification!

# Sum of differences of pairs, eg, [1,2,6,9] -> 2-1 + 9-6 = 1+3 = 4
def clocky(l):
  if len(l) % 2 != 0: l = l[:-1] # ignore last entry if unpaired
  return sum([end-start for [start,end] in partition(l,2,2)])

(The partition function turns a list into a list of pairs.)

Does that answer it? Do you agree with the answer?

1 Like

You definitely answered my question. But the way it’s implemented will only work if you’re never clocked in at midnight. For instance, if I log the start and end time for every meditation session and use clocky to total the times, if I start meditating at 11:30pm and stop at 12:30am, the 11:30pm time will get ignored and the 12:30am time will be treated as a start time, making that day’s numbers inaccurate.

I’m not sure how easy that would be to fix - you’d have to either subtract 24 from any leftover entry and pass it to the next day’s list, or else, anytime a list has an odd number of entries, tack midnight on to the end of that list and start the next day’s list with a midnight entry as well (essentially clocking out at midnight minus epsilon and back in at midnight plus epsilon). Hopefully that can be done without needing to make a bunch of changes to the rest of the code.



Great article. May I suggest an additional item?

interval: max(x) - min(x)

Calculates the largest value minus the smallest value.

Use case: intermittent fasting, which many people do these days, especially on keto diet. I am only supposed to eat within an X hour window every day. This would allow to beemind the window.

Tried clocky, but it’s too prone to human error.

(Edit: if clocky start looked visually different from clocky stop, and if there was some equivalent of stopwatch, that would probably eliminate a lot of clocky errors. As it is, I’ve deleted my clocky goal today).


Hm, would there be a way for aggday interval stuff to be able to cross
midnight?! I have a bajillion things I’d use that for…


I’m pretty amenable to sticking these in and seeing what happens!

@adamwolf, for a version that can sensibly span midnight, are these real numbers in [0,24) where… hmm, I think I’m going to have to see an example walked through before I have my head around this…

1 Like

I was looking at clocky to measure total sleep time: I’d hoped that if I set my deadline to 14:00, then I could add a datapoint of (say) 22:00 for when I went to bed, add the next datapoint for 06:15 when I get up, and because those are logically on the same day (after the 14:00 deadline), it would faithfully report that I’d slept for 08:15 hours.

Sadly it doesn’t work like that at all, it just looks for differences between the datapoints. I’m running a test goal right now, and it’s not even clear to me what it’s going to do for a pair of datapoints like (22:00, 06:15). They are on diferent physical days, but it’s the same logical beeminder day as the deadline for the goal is at 14:00, and just skimming the code I’m not sure how that cashes out.

So: can we have a nice time_interval function that actually works as one would expect here, including intervals that cross midnight (if they’re on the same logical day)?

Pseudocode is something like:

  • for each time, calculate elapsed_time since deadline:
    • if time>deadline elapsed_time = time - deadline
      else elapsed_time = time - deadline + 24
  • take pairwise differences of these elapsed_times