Three Weeks: An Experiment

The Gist

I am going to write a blog post every day for three weeks, and they can’t completely suck.

Some background: I am the target market for self help books. I constantly wish I were doing more to improve my self and my life, and I frequently dream up big schemes, then (maybe) execute on them for a day or two. Something pulls me out of the pattern and it’s over. The dream is forgotten, and I move on.

I’ve tried a number of approaches:

  • Just do everything
  • Do whatever single thing interests me that day
  • Commit to big specific projects I think I want to do
  • Start with small things and slowly ratchet them up
  • Try to get people to care if I fail
  • Change my sleep schedule for some reason

Regular pitfalls include:

  • Missing a single thing leads to a feeling of failure, and I give up
  • Failing to have a specific interest on a given day
  • Overcommitting my time, or getting mired in setup
  • Deciding which things to start with is hard
  • Other people are rarely motivated to see my plans through
  • There’s always a reason to stay up late or to sleep in

The Next Grandiose Scheme

I would bet that you’ve heard about 21 days being the time required to form a habit, right? Go to google and type in “21 days”, it’s probably in the first two predictive results. My plan is simple enough that I’ve ignored it for years. It goes like this:

  1. Focus on a single thing for three full weeks.
  2. Repeat.

My plans on the order of “do a billion things” have never been a truly successful, so it makes sense to give things a try one-at-a-time.

Logic

Since these are relatively small packets of time, I’m able to choose topics I might otherwise fear are wasteful. I should also be able to set realistic, objective goals for where I’d like to arrive at after three weeks of focused effort. I can also freely fail at focusing and just try again — one of the intended results of performing this experiment multiple times is that my ability to drill down and focus on something new should improve. Right now I tend to get watery-eyed and feel like a nap after an hour of focus.

Documentation of the three-week effort brings some other things to the table. There’s a well-known method (I’ll call it the Seinfeld method) where a success-to-be plots a big red X on a calendar every day they’ve performed the task they want to improve at. I don’t have a big calendar in my house (though I may get one), but I do have a blog. It’s like putting my big red X marks on the lawn, and telling all of my neighbours why. But I’d hate to get half-way into a three-week sprint and fail to blog about it. Thus, my first sprint should force me to be blogging every day. In a way, I’m combining some of the earlier strategies:

  • This is a small start.
  • I’m telling others.
  • I’m working on something that interests me.

As time goes on, my writing should improve, and you will have the chance of learning something, since I’ll often report on my activities by explaining them.

Off on a tangent: a hack I’ve learned is to trick myself into starting a large project by convincing myself to do one very easy but related task, then riding its momentum. An example is doing the dishes: rather than set out to “do all of the dishes”, I just decide to rinse a single dish that is nearly clean. Once the water is running and I’m rinsing the dish, I may as well wipe it. Now I have a wet cloth and running water, and I’ll reflexively grab another easy looking dish. As the pile grows, momentum builds.

Once more for effect

So this is my first easy dish: just write a blog post today. That’s all I have to be aware of each day, and on Monday, May 28th, I’ll find another easy dish to start.

 

My take-way from TEDxGuelphU

Water is amazing. Artists can have some great insights to share. Cartwheels fill time like nothing else. Dancing is a great equalizer. Straws are weak (in the face of elastics). Hagfish slime is cool. It’s worth thinking about how to change the world. Science, economics, happiness, conflict, the beautiful world itself, and money all have tremendous and difficult to understand roles to play in accomplishing complex positive changes, but through our connected nature and a collective sense of shared responsibility, we might just have a chance.

I extend my thanks to all you speakers, guests, committee members, tech crew members, hospitality staff, and everyone else who help make sharing ideas possible. Good show. Now let’s not relax too long, because the world won’t wait around.

Correction: I do know what subsets are, I swear

A few months ago, I wrote a post entitled “A nice way to generate all subsets within python“, and you know what? There were some issues with that post. They were pointed out to me by one Owen Jacobson, and I feel like a dork, but not the good kind – more like a fail-dork, or something. Maybe the word for that is fdork.

Anyway, the issues, in Owen’s words, are:

1. from imports in functions have gone away in Python 3; I’d put those at module scope, instead. The other alternative is to use import collections as c within the function and to qualify references, as with c.Iterable.

(I know, imports within functions are an attractive idea, but the resulting semantics are very odd. The first call to a function might, or might not, alter the interpreter’s global state depending on what other imports have already run, and might, or might not, take significantly longer than usual depending on how quickly imports are resolved! Not fun, as I learned to my detriment.)

2. This seems like a great place to use generators and the yield expression. It’d put the decision about whether or not to hold n! permutations in memory or simultaneously or not out in the caller’s context, where there’s more information to make that decision against, and it’d replace four lines of code with one: return c.permute(args).

3. Neither function actually returns all of the subsets of the set formed by their respective argument lists; they return all permutations, instead.

I would like to briefly respond, and by that, I mean own up.

To the first point: neat! This makes a lot of sense – I have been staying away from reading about Python 3 at all, which is not very wise.

To the second point: that’s really smart. It didn’t even occur to me to write this as a generator, partly because I’m not super familiar with the nitty-gritty of generators in python, but upon seeing this I am all “ohhhh, yeah”.

Finally, to the third point: Owen is right; the code I wrote totally doesn’t produce all subsets, so what gives?!

I believe that my initial thought was to use the ‘all_subsets’ function (which should have been named ‘all_permutations’ from the start) to generate all permutations of an n-bit string, which I would then use to generate all subsets. In the past, I’ve made much uglier approaches to generating every bitstring — particularly by calculating each successive permutation manually. This felt like a nice shortcut! The problem is that I only implemented half of it, and then forgot what my original thought was. And then forgot to actually think about what I was saying.

Lessons learned:

1. Make sure you’ve finished what you set out to do before blogging about it, or at least, make sure your posts and reality are approximately congruent.

2. Even if a technology’s adoption (e.g. Python 3) feels infinitely distant, it isn’t too soon to become acquainted with it and to think about writing code which will be less broken when I have to update it. New technology usually exists to solve problems, and in that respect, often points to smart idioms which I can adopt now.

3. Generators are very sensible things to use in utility functions that produce more than a single piece of data. They allow the program to move along faster, and reduce immediate storage requirements, placing the decision in the hands of the function’s user whether or not holding their full result in memory is necessary. I should read up a bit more about how to use them in Python.

4. Owen’s pretty sharp. Thanks for the awesome response 🙂

Possible Parallel Projects

Tuesday, November 1st: 12:01 PM

I am considering two possibilities for my project: an n-dimensional parallel prefix scan OR a ruby library for pilot for my CIS 3090 project… I’ll list some pros and cons!

n-dimensional parallel prefix scan:
pros:

  • may be less work
  • would be super cool
  • could be really useful
  • teaches me some math
  • teaches me some algorithms

cons:

  • really hard; I might not be able to do this
  • could be a lot of “hidden work”
  • risk doing this “wrong”
  • might just not be very fast!

2. Ruby port of pilot library:
pros:

  • have to get to know pilot intimately
  • easy to incrementalize
  • open source project to maintain
  • get way better at ruby

cons:

  • have to get to know pilot intimately
  • probably a ridiculous amount of work
  • not very “original”

Hmmmm…

A nice way to generate all subsets within python.

Disclaimer: this post has some lousy code and a serious factual error. Throughout, I am speaking about a method of generating all permutations of a set, while saying that I’m speaking about generating all subsets of a set! I have written a newer post which integrates content from a comment by Owen Jacobson, along with a short response explaining just what the heck I was thinking. This post has been left intact aside from this disclaimer for the sake of posterity!

Recently on hackernews, I saw this amazing bunch of vimfu (learned some nifty tricks from it too!), and so I went to check out Jim Dennis’ other answers. Nothing quite so popular, but some worthy reads about “what qualifies a person as a kernel developer” and “can I run a .so compiled in red hat under ubuntu?” – the one that inspired this post though, is the classic “how to generate all subsets of a set?

Jim suggests using python’s itertools module (in addition to bitmasking on the subset-representation), and I’ve never had cause to look at itertools before. Boy, how I wish I had! I quickly whipped up the following (after reading about argument packing/unpacking:

There’s probably reasons why it’s ugly, and certainly ways to do it better. What I like about this though is that it handles pretty much anything you throw at it, aside from a single non-iterable object I suppose! So calling “all_subsets(1,2,3,4)”, or “all_subsets(‘funny’)”, or “all_subsets([1,2,3,4])” or “all_subsets({‘a’:1,’b’:2})”, or even all_subsets(1) all work and spit out a list of tuples of the permutations.

A possible extension would be to convert back into the form originally provided – but I think that a standard form of return may be more useful. Regardless, this is a neat tool that I will keep in my box.

Edit: I made a modification to the above, so that it can work with any iterable or non-iterable object: