Beeminding books, and my desire for a charges API

Inspired by @shanaqui, I have been Beeminding the books I read for the past few years. The intent being not to force myself to read anything I dislike (I readily archive the goal if the book isn’t one I want to continue), but to keep myself from wandering from one shiny and exciting book to another and never finishing anything. It works pretty well: since starting doing this in late 2020 I’ve finished way more of the books I’ve started.

Recently, a question popped into my head: how much money have I spent on finishing books? I’m happy to have spent the money, of course: paying is not punishment. Quite the opposite, I want to be able to brag: I spent $X and in exchange I got to complete all these books instead of forgetting to continue them halfway through. Beyond the general benefits Beeminder gives me, this is a specific major win I can credit Beeminder with.

Unfortunately, I don’t really have an easy way to get this data. If only there were a charges API! If I could pull all instances of Beeminder charging me from some API, each with the slug of the goal the charge was for, I could write a few lines of bash, using curl and jq to pull all my goals, find those tagged book, and do the join.

I enjoy doing this kind of ad-hoc scripting to answer interesting questions, especially those of the quantified self variety. For instance, I have nice graphs I’ve generated of things like number of Beeminder data points per year, showing my use of Beeminder over time, and also correlating it with various things going on in my life.

So it’s a bit disappointing that I can’t answer this question as easily as some others, with a bit of scripting. I could work around this by exporting my payment history and my honey money balance history and extracting goal slugs using regexes, but that would be more manual than is ideal—I’d like to have a little script I could run whenever that gives me the up-to-date value.

Ideally there’d be an API endpoint I could call, /api/v1/users/me/charges.json or whatever, that would return a list of objects with the keys amount, timestamp, and slug, and maybe also things like status or payment_type, but that’s less important.

Others have asked for this in the past, but hopefully my specific use-case helps give a motivation for how this could be worth building.

9 Likes

I would also love a charges api. The forfeit app implemented that feature under the total forfeited section:

3 Likes

Not an api, of course, but your payment history is available, including an option to have the whole of it emailed to you, which arrives as both json and csv.

Fun fact: I’ve spent $6,032 on Beeminder payments over the past 14 years, which is about one pound sterling (GBP) a day invested in meeting my goals! One percent of that ($65) seems to have been on reading goals, which you can see summarised here.

8 Likes

That’s an impressive reading summary page!

You’re right that it’s possible to export payment history, though nowadays it’s a bit more difficult: with honey money, the payment history is no longer tied to goals in the way I’d need it to be for queries like this one.

It’s still possible, by the complicated expedient of scraping the HTML of the honey money balance log table, extracting from it the relevant rows, and combining that data with the pre-honey-money payment history so as to include derailments from both eras. It’s a lot less automated than a script that hits the API, but I could do it with a bit of work. Still, an API for this would be so much more convenient.

4 Likes

The introduction of the honey-money complication is probably a good reason/trigger/excuse to rationalise access to payment history via an API.

6 Likes

Hi @zzq , how did you Beemind reading books?

Did you use an Odometer goal for pages read?

Or Do More?

Time Spent using a Do More?

2 Likes

All my reading goals, and most of my goals in general, are really simple: I enter a 1 datapoint for days in which I do the goal, and otherwise I don’t. For books, that means I enter a 1 if I read any amount of the book, without a strict view on what the correct amount is to read. This works because I trust myself, and because these are interesting books I actually enjoy reading. If I were tempted to just read one page and say “that’s enough for today”, then obviously that’s a book I’m not getting anything out of and should abandon. In practice the amount I read of a book each day depends on the specific book—some books are very dense, some books are easier to read, some books are nicely broken up into chapters that are each suitable for a reading session. I read enough each day to make me feel justified in my choice to read the book, and I record on Beeminder that I’ve done so via a 1 datapoint for the day.

4 Likes

HI @philip , I agree with @zzq that your reading summary page is indeed impressive.

How are you Beeminding your reading goal read – pjh – beeminder ?

I’m guessing it’s a Do More Goal?

Can you please explain what your code means?

For example, for * 2023–01/02 · Munger · Poor Charlie’s Almanack , the summary page has two boxes of “10”. What does that mean?

I tried clicking to Darius Jahandarie but Chrome is giving me a “Your connection is not private” message:

Is it safe to proceed?

I would like model Darius Jahandarie’s and your Reading Summary code.

I have a problem of finishing online courses. I currently have an Odometer goal for finishing this course on memory techniques https://www.beeminder.com/experientiallearner/mmm_exercises.png where I have a +1 due in 2 days.

I’m not just reading text, watching the videos, but doing the exercises, hence the beeminder goal name mmm_exercises – experientiallearner – beeminder .

When I complete doing the current 8th of 32 Total lessons, I will enter 8.

1 Like

Thanks for the explanation. I think I might incorporate a 1 datapoint for days.

The problem is I don’t trust myself lol

1 Like

Hey EL, thanks for asking.

pjh/read is indeed a Do More goal, but customised with an aggregation method of nonzero, which means that I can enter the number of pages read in the datapoint, and the graph treats all numbers (other than zero) as +1. So I’m beeminding the number of days on which I read something at all, while also keeping track of the number of pages in case future-me cares about the data.

I’ve tried beeminding number of pages in the past, but it didn’t work well for me, partly because of the reasons that @zzq mentioned. Some folks get good mileage out of using a timer and tracking the number of minutes spent reading. I mostly track non-fiction and foreign-language reading, and sometimes have had special-purpose goals like pages-read-in-french or the Beeminder pandemic book reading of the Priory of the Orange Tree.

The ‘code’ listing of the detail is three fields: a date range, the author(s), and the book’s title. The date range in the example you gave was meant to show that I started reading it the year before, e.g. in 2023, and wrapped over the end of the calendar year.

The blocks of little squares are calendar years, with one square per day. The numbers in the little squares are the number of pages read on that day. From which you could be alternately impressed or disappointed with my reading!

It looks like @djahandarie’s althack website no longer exists. You can see a remnant of it here on the wayback machine, which shows something of the base that I started from. He was much more disciplined than me at reading one book at a time

3 Likes

Just remembered this post: 150 books in 2015 - #12 by philip

Apparently at the time I was beeminding pages per day, and then converted the goal to ‘nonzero’ to track days instead. (I would have derailed, but support doubtless helped me put the red line back where it belonged)

2 Likes