Skip to content

Annotating Productivity and Visualizing#162

Closed
nicolae-stroncea wants to merge 4 commits intoActivityWatch:masterfrom
nicolae-stroncea:productivity
Closed

Annotating Productivity and Visualizing#162
nicolae-stroncea wants to merge 4 commits intoActivityWatch:masterfrom
nicolae-stroncea:productivity

Conversation

@nicolae-stroncea
Copy link
Copy Markdown
Member

@nicolae-stroncea nicolae-stroncea commented Dec 17, 2019

  • User can select between: Productive, Not Productive, Neutral. Default is Unknown.
  • The categories are then aggregated, which enables the user to view how productive he was during a certain period.
    Screenshot from 2019-12-17 03-58-35

Screenshot from 2019-12-17 03-58-27
Screenshot from 2019-12-17 03-58-16

Known Issues

  • Will work in a completely new environment(or if defaults are reset), but there are currently bugs if you start it in an environment where Productivity has not yet been set for already existing categories.

@johan-bjareholt
Copy link
Copy Markdown
Member

Will work in a completely new environment(or if defaults are reset), but there are currently bugs if you start it in an environment where Productivity has not yet been set for already existing categories.

Should be simple to fix right? Assuming "Unknown Productivity" if nothing is set

Copy link
Copy Markdown
Member

@johan-bjareholt johan-bjareholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea! needs some more work though

productivity: -1,
parent: [],
},
productivity_description:{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a good way to do it.

Don't ever set "Unknown Productivity", in that case just don't set the productivity for that rule and make the transform skip that rule.

Then for example set 0 as neutral, 1 as productive and -1 as unproductive. Then you could for example later give the productivity score for a day/week/month/year a scale from -1 to 1

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johan-bjareholt
are you saying to completely remove the attribute if it's never set? If we don't set it to anything, then some categories will have a productive attribute, some won't, which might complicate the checking that needs to be done when we're parsing events. What do you think about flipping it instead to: "not productive":-1, "neutral":0, "productive":1, "unknown":2.

Copy link
Copy Markdown
Member

@johan-bjareholt johan-bjareholt Dec 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you saying to completely remove the attribute if it's never set? If we don't set it to anything, then some categories will have a productive attribute, some won't, which might complicate the checking that needs to be done when we're parsing events.

Change the transform to ignore calculating productivity on events which do not have a productivity set.

What do you think about flipping it instead to: "not productive":-1, "neutral":0, "productive":1, "unknown":2.

See my comment below about I'd prefer if it was a range from -1 to 1 rather than static enums.

Copy link
Copy Markdown
Member Author

@nicolae-stroncea nicolae-stroncea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will work in a completely new environment(or if defaults are reset), but there are currently bugs if you start it in an environment where Productivity has not yet been set for already existing categories.

Should be simple to fix right? Assuming "Unknown Productivity" if nothing is set
@johan-bjareholt
That's what I was thinking as well. So I implemented that in in the most recent commit I just pushed. I'm still getting the same error, which is difficult to debug. I'll have to debug further to figure it out.

Screenshot from 2019-12-17 11-39-11

productivity: -1,
parent: [],
},
productivity_description:{
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johan-bjareholt
are you saying to completely remove the attribute if it's never set? If we don't set it to anything, then some categories will have a productive attribute, some won't, which might complicate the checking that needs to be done when we're parsing events. What do you think about flipping it instead to: "not productive":-1, "neutral":0, "productive":1, "unknown":2.

@ErikBjare
Copy link
Copy Markdown
Member

ErikBjare commented Dec 17, 2019

This is really nice work, but I kinda had this use-case in mind when I designed categorization. So I already have some opinions on how I think this should be done, and it's somewhat different.

When I built the categorization stuff, the intention was for the user to be able to create multiple sets of categories. One is the "user set" that we have today, one could be an open/standardized set, and one could be a "Productive/Unproductive" set.

A query would be something like:

events = get_events()
events = categorize(events, cats_user)
events_productive = merge_events_by_key(categorize(events, cats_productivity), "$category")

This has some benefits:

  • The current user-defined set of categories will not match perfectly to productivity levels, this way of doing it gives more flexibility, and doesn't require introducing new object attributes.
  • No new change to server code needed (it was by design), would already work with both aw-server and aw-server-rust.
  • No built-in assumptions in the API about what labels like "productive" and "unproductive" means in value terms (so not a 1 for "productive" and -1 for unproductive, that's an analysis step). I really want to avoid building in assumptions like this in the APIs (and I think @johan-bjareholt will agree). This always annoyed me with RescueTime which calculated the daily productivity score in a really dumb way, (basically: 100 * (productive_time - unproductive_time) / total) which I could write a whole rant about (basically it incentivizes not being on the computer at all if you've already got a little bit of productive time without any unproductive time, it's only natural to slack as you get tired, what's important is the amount of work done).

Note that you can still categorize productivity using previous categorization data, since "$category" is just an event attribute which will be used in categorization.

It makes rules applicable to categories, instead of making specific categories applicable to rules (which is what this way of doing it does).

What do you think @nicolae-stroncea and @johan-bjareholt? Sorry I didn't really write about these plans anywhere before you put a bunch of work in it, but I could build it on top of these changes so it comes to use and you get your credit 🙂

@nicolae-stroncea
Copy link
Copy Markdown
Member Author

This is really nice work, but I kinda had this use-case in mind when I designed categorization. So I already have some opinions on how I think this should be done, and it's somewhat different.

When I built the categorization stuff, the intention was for the user to be able to create multiple sets of categories. One is the "user set" that we have today, one could be an open/standardized set, and one could be a "Productive/Unproductive" set.

A query would be something like:

events = get_events()
events = categorize(events, cats_user)
events_productive = merge_events_by_key(categorize(events, cats_productivity), "$category")

This has some benefits:

* The current user-defined set of categories will not match perfectly to productivity levels, this way of doing it gives more flexibility, and doesn't require introducing new object attributes.

* No new change to server code needed (it was by design), would already work with both aw-server and aw-server-rust.

* No built-in assumptions in the API about what labels like "productive" and "unproductive" means in value terms (so not a 1 for "productive" and -1 for unproductive, that's an analysis step). I really want to avoid building in assumptions like this in the APIs (and I think @johan-bjareholt will agree). This always annoyed me with RescueTime which calculated the daily productivity score in a really dumb way, (basically: `100 * (productive_time - unproductive_time) / total`) which I could write a whole rant about (basically it incentivizes not being on the computer at all if you've already got a little bit of productive time without any unproductive time, it's only natural to slack as you get tired, what's important is the amount of work done).

Note that you can still categorize productivity using previous categorization data, since "$category" is just an event attribute which will be used in categorization.

It makes rules applicable to categories, instead of making specific categories applicable to rules (which is what this way of doing it does).

What do you think @nicolae-stroncea and @johan-bjareholt? Sorry I didn't really write about these plans anywhere before you put a bunch of work in it, but I could build it on top of these changes so it comes to use and you get your credit slightly_smiling_face

@ErikBjare not a problem, I should have probably asked as well to confirm whether there was anything in the works and what the general ideas were on the implementation. The commits are now in the PR's for aw-webui and aw-core, so feel free to take the bits and pieces that fit with your implementation.

@johan-bjareholt
Copy link
Copy Markdown
Member

No built-in assumptions in the API about what labels like "productive" and "unproductive" means in value terms (so not a 1 for "productive" and -1 for unproductive, that's an analysis step). I really want to avoid building in assumptions like this in the APIs (and I think @johan-bjareholt will agree).

Agreed, however if you could weigh it as 1.0 for "very productive", 0.5 for "productive" and -1 for "very unproductive" it would be an acceptable start as we could in the future upgrade that to a smarter algorithm for weighing the productivity.

This always annoyed me with RescueTime which calculated the daily productivity score in a really dumb way, (basically: 100 * (productive_time - unproductive_time) / total) which I could write a whole rant about (basically it incentivizes not being on the computer at all if you've already got a little bit of productive time without any unproductive time, it's only natural to slack as you get tired, what's important is the amount of work done).

I agree that it's stupid that it's so black-and-white (either productive or unproductive and nothing in between). Otherwise I don't see it as a flaw that it's better to leave the computer to avoid slacking at the computer even though your AFK time could potentially be unproductive. Do you have any more reasons?

@ErikBjare
Copy link
Copy Markdown
Member

I just want to add here that ActivityWatch/activitywatch#416 would work really well with my proposal for how this feature should be built (multiple category-sets).

@ErikBjare
Copy link
Copy Markdown
Member

ErikBjare commented Feb 9, 2021

Hey @nicolae-stroncea, I just wanted to tell you how much I appreciate your work on this PR even though it might not be merged.

I'm still not convinced of the best/cleanest way to implement this, but this PR really got the gears turning and I'll try to salvage whatever I can from this PR when we eventually get around to it, so you get your commit-credit where due 🙂


And regarding 'point scoring', I found this post: https://samplesize.one/blog/posts/my_year_in_data/

As I was analysing at my data throughout the year, I was quite disappointed in how little I worked and was looking for a way to increase it. Inspired by this post I decided to gamify my productivity by giving myself points for activities I wanted to do more of. I was hoping that they would act as sources of instantenous pleasure for my monkey brain (which wants fun now and doesn't really care about future me) to make it do things that might be less fun but beneficial in the long run. Given that I already had data on my activities throughout the day, assigning points was pretty straightforward.

I would get:

  • 4 points per hour for the most productive activities (focused work towards uni & self-improvement and exercising)
  • 3 points for reading books
  • 2 points for reading blogs, listening to podcasts, lower intensity work etc
  • 0 points for things that are important but I do them anyway (socialising, sleep etc)
  • -4 points for procrastination

I think it's a pretty neat idea, and I like the approach to simply let the user score their categories themselves. Users could set single-digit points like in the post, or a dollar value, or whatever they like.

@nicolae-stroncea
Copy link
Copy Markdown
Member Author

nicolae-stroncea commented Feb 13, 2021

@ErikBjare I really like the idea of scoring each category. This gives the user full flexibility of choosing whether they want the standard Productive:1, Unproductive:-1, Neutral:0, or something more powerful that is custom to their preferences.

Here's a possible approach:

Implementation:

  1. Every category has a productivity score field that is stored along with the category. Therefore, it is currently stored in localStorage, and in the future will be stored in the db.
  2. productivity score is any whole number(+ve or -ve).
  3. A newly created category has productivity score 0, and newly created subcategory has productivity score of its parent.

New views:

  1. View from this PR: horizontal bar chart of each different productivity score and the total amount of time on it. Note: text will be Score: 0, Score: 1, Score: -4, Score:-2 etc instead of Productive,Unproductive, etc.

image

  1. Productivity Score Number = productivity score x total time with this score / total time. View color can change depending on whether the score is +ve, -ve or 0(neutral)

image

EDIT: To make this even more flexible, the productivity score for a category could be set to any real number. This would not require any added complexity since JavaScript's number type allows floats, and it can be stored as Real data type in SQLite.

EDIT 2: Added images for visualizations.

@nicolae-stroncea
Copy link
Copy Markdown
Member Author

@ErikBjare if above implementation makes sense to you and @johan-bjareholt , I can modify this PR accordingly. I'll be busy for a couple of weeks but I can give this a shot once I free up some time.

@ErikBjare
Copy link
Copy Markdown
Member

@nicolae-stroncea I've rebased this PR on master and adjusted a few things in #258 which makes the implementation a lot simpler (no need to add a transform to the backend).

Once I realized the similarities between the 'productivity score' and the category colors I implemented in #254 it became pretty clear how this should be implemented, and I anticipate we can get it merged pretty soon!

I appreciate you might not have much time in the coming week, but I'd be really grateful if you had a look and reviewed it :)

@nicolae-stroncea
Copy link
Copy Markdown
Member Author

Closing this since #258 was merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants