Progress on my Google+ and LJ backups

Since Google is going to shut down Google+, I decided it was time to really make a home for my LiveJournal backup and my Google+ backup.

Working on them has been very nostalgic, even moreso for LiveJournal. I have really fond memories of my conversations with my LiveJournal friends. Love you guys so much! Always will.

I'm happier with my LiveJournal backup, too. Here are some of the features:

  • Overall design reminiscent of my LiveJournal layout, including nested replies, embedded media, and lj-cuts. But no ads!
  • If the page width is too big, keeps the post width short enough for better readability.
  • As you decrease the page width, the post test wraps. If with page width is very small, as on a phone, the sidebar moves to top and bottom, leaving the entire width for the post.
  • Removed spam, most dead replies, and useless auto-posts from Twitter. (If a Tweet started a conversation though, I kept it.)
  • Entire site is static. No frameworks. All the responsiveness was done with CSS grid, max-width, and one @media (max-width) conditional.
  • Accessibility! Use single-finger swiping on touch devices, or keyboard navigation if you have a keyboard.

Here are a few of the posts that were fun for me to revisit:

I better stop. Those were good times.

One note on Google+, I liked it way better when it looked more like the picture here, and wish they'd accepted my suggestion. Would've made a big difference for users like me.

In Case of Link-Rot

If anything should happen to this journal, a backup of it should eventually appear at this location.

I don't expect or plan for anything to happen to this journal, of course! But it's always good to have a contingency plan.

Theoretically, if something did happen to this journal, you're reading this from the Google cache of the page or on the waybackmachine or something similar.

Getting Shit Done

I came across an old LifeHacker article Get Shit Done Blocks Distracting Web Sites So You Can Do As the Name Instructs, that mentions a productivity script, get-shit-done. So I went to the github repository only to discover that the Python script was no longer functional. I didn't have permission to fix the script at the site, so here's a quick note-to-self to get around to that. Until then...

[Edit]: There's a better, live branch at GitHub. Use leftnode's version.

Here's an archive of my changes before I discovered leftnode's branch.

  • The syntax errors were fixed. (Like the "play" string in the dictionary at the end that was supposed to be the play method.)

  • It's more Windows friendly. Changing the "hosts" file doesn't require a network driver restart in Windows.

  • You no longer have to specify an argument, "work" or "play." It'll just toggle modes every time you run it now.

  • When reverting to "play" mode, it retains whatever was in the hosts file after the endToken now.

  • I removed the bit of code that optionally reads in from an ini file. The ini file format (the keys, in particular) struck me as awkward.

#!/usr/bin/env python

import sys
import getpass
import subprocess
import os

def exit_error(error):
    print >> sys.stderr, error
    exit( 1 )

restartNetworkingCommand = ["/etc/init.d/networking", "restart"]
# Windows users may have to set up an exception for write access
# to the hosts file in Windows Security Essentials.
hostsFile = '/etc/hosts'
startToken = '## start-gsd'
endToken = '## end-gsd'
siteList = ['', '',
            '', '', '',
            '', '',
            '', '', '',
            '', '', '',
            '', '', '',
            '', '',
            '', '', '',
            '', '', '',
            '', '',
            '', '']

def rehash():
    if sys.platform != 'cygwin':

def work():
    with open( hostsFile, 'a' ) as hFile:
        print >> hFile, startToken
        for site in siteList:
            print >> hFile, "\t" + site
            if site.count( '.' ) == 1:
                print >> hFile, "\twww." + site
        print >> hFile, endToken

def play( startIndex, endIndex, lines ):
    with open(hostsFile, "w") as hFile:
        hFile.writelines( lines[0:startIndex] )
        hFile.writelines( lines[endIndex+1:] )

if __name__ == "__main__":
    if sys.platform != 'cygwin' and getpass.getuser() != 'root':
        exit_error( 'Please run script as root.' )

    # Determine if our siteList is already present.
    startIndex = -1
    endIndex = -1
    with open(hostsFile, "r") as hFile:
        lines = hFile.readlines()
        for i, line in enumerate( lines ):
            line = line.strip()
            if line == startToken:
                startIndex = i
            elif line == endToken:
                endIndex = i

    if startIndex > -1 and endIndex > -1:
        play( startIndex, endIndex, lines )

Fifth Grade Homework - Nine digit pandigital prime number

Yesterday my daughter in the fifth grade got the following homework assignment "arrange the digits one through nine into a nine-digit prime number." (Note, since zero wasn't included, it's not really a pandigital number.)

So I asked her how she'd start. She started the way I'd want her to, by excluding the digits 2, 4, 5, 6, and 8 from the units place. And then...

...we got nuthin'.

What did the teacher want? Could we use the computer to test answers? Did the teacher teach some tricks I don't know about? Maybe.

After trying and failing to construct a few nine-digit nearly pandigital prime numbers, I finally gave into every programmer's temptation.

The brute-force tactic! Test them all! In Python, it looks like this:

import itertools

l = '123456789'
for p in itertools.permutations( l ):
    n = int( ''.join(p) )
    if isprime( n ): # find an implementation on the web
        print "Found it!", n

We ran it and... What the hey‽ There isn't any such prime‽ What kind of stunt is this teacher trying to pull?

Prepopulating lists with objects in Python

Dear self,

Never admit to the world you lost a couple of hours thinking that the following line created a list of objects.

    l = [Obj()] * n

It doesn't. It creates a list of references to one object.

What you meant to write was this:

    l = [Obj() for _ in range(n)]

You dummy.

David and the Terrible, Horrible, No Good, Very Bad Day

Today was to be errand day.  But an out-of-town family member needed to drop by so his young daughter could take naps and play with my kids while he was stuck in the neighborhood on business.  That was OK, I just wouldn't run quite so many errands then.

The credit card company (for our only credit card) emailed me to verify that the last few purchases were fraudulent.  They were.  We cancelled the credit card, and will now update all the accounts with recurring charges, and will wait for the new cards in the mail.

The kids wanted to watch TV, but the remote wasn't working.  I replaced the batteries, but the remote still didn't work.  I tried a few flavors of new sets of batteries and factory resets, but they failed, too.  (It's a TiVo remote, and the resets rely on an amber light turning on and staying solid, but the amber light flashes in my case, and never goes solid, even when holding down the special combination of buttons.)  So no watching T.V. for the kids and our guests today.

My son left his new jacket at the community pool yesterday, and when we went there to retrieve it today, it wasn't there.  The pool area has no lost-and-found.  Any clothes left there that get picked up by the janitorial staff get thrown away. (They're usually wet underwear and such. Nobody's going to want to pick that up and store it in lost-and-found.)

I had to set a "home" user environment variable on my Windows computer so that ffmpeg could render the gource movie of my lifestream.  But that broke the automatic backup script that I have run from cygwin.  I was done with the movie, so I went to my System Properties  window, selected the "HOME" User variable, and clicked on the Delete button ... wait for it ... under the the System environment variables group.  That's right, I deleted whatever default selected System-wide environment variable was there for the whole family.  I have no idea what I just permanently deleted. The computer might be good and screwed at this point.

I took my kids to get their haircuts today, since their usual person should be back from vacation.  Not only was she not back yet, they don't know when she'll be back, and the line for haircuts was over an hour long.  We left without the haircuts.

I went to Best Buy and Fry's looking for a replacement TiVo remote. No luck.

Our Rock Band drum set broke.  (OK, that was yesterday.  But I may as well pile it in there.)

Today can DIAF.

Transparency vs. Anonymity released an infographic that was brilliantly designed.  It's informative, addresses a hotly contested issue, has plenty of high value keywords, some statistics and - the biggest reason for getting mentioned here - is wrong.

Their Transparency vs. Anonymity infographic provides the following two rationales:

For Transparency, Mark Zuckerberg says:
You have one identity... Having two identities for yourself is an example of a lack of integrity.
For Anonymity, Moot says:
The cost of failure is really high when you're contributing as yourself.
What the...?  No.  Here, let me contradict the statements of experts and billion-dollar company founders with anecdotes from a nobody.

On Transparency

I fall solidly into the Transparency camp.  The only reason I don't come up on the front page when you search for me on Google is because another David Blume used SEO practices.

But don't lump me in with Mark Zuckerberg.  I have dozens of identities.  I'm a coder, a rock climber, a father, a husband, a son, a video game player, a web surfer, a comic book reader, an artist, an employee, etc.  Online, each of those facets of my life belong to different domains.  There's no reason those online identities need to be the same one.  Some of them are, but only because I want to be discoverable.  I've chosen that my username from some domains is the same at some others.
Regarding content creation: Sure, I want credit for the stuff I've made, but I'd be just as happy no matter how the money lands into my wallet, or how the comments and "likes" pile up on my webpage, "anonymous" ID or not.  I've chosen to groom/maintain my identities, and I like seeing which ones garner favor with like-minded individuals, whether they're anonymous or not.
Being transparent is mostly about being discoverable for me.

On Anonymity

OK.  So Moot says anonymity is useful because "the cost of failure is really high when you're contributing as yourself."  What the what?  That's like the least important reason to be anonymous.  Let's look at where the content creators are: Mobile phone apps, youtube, deviantart, flickr, nanowrimo, etsy, the internet.  I really don't think their big concern is that one of their apps or illustrations being unpopular is going to hurt their real-life identity.
It hurts anyway when your peers don't appreciate what you've put your heart into.  That's regardless of which identity you've chosen for them to see.  How often do you choose to abandon your identity because something you contributed under it failed?  Sure, it happens, but it's gotta be super rare.  Usually, we just learn from these failures under the same identity and move on.  It's too much of a bother to create a new identity because of one bad contribution and to try and re-friend those who you liked under the old identity.
No, the best reason for anonymity is to avoid unwanted contact from creeps.  I'm transparent, so I'm at a risk if the terrible eye of Anonymous turns my way.  (I love you, Anonymous.  You're the best. <3)  But then again, my online identity is pretty benign, and I'm an old guy.  Not really a prime target for predators.

But, I haven't allowed my children to choose transparency yet.  They don't know the costs, and their online skin isn't thick yet.  Their online gaming IDs are anonymous, and that's mostly because of John Gabriel's Greater Internet Dickwad Theory.
Being anonymous is mostly about avoiding unwanted attention from tracking to your other identities.

It sure isn't because "the cost of failure of your contributions is really high."
Under the bridge, I'm a troll.  Out here, I'm somebody else.

Would You Like To Tweet This?

I just visited a Twitter Statistics page that had a persistent popup window in the bottom right corner that looks like this:

It's got a non-standard shape, ample background space obscuring the page, a close/minimize box, a polite question in a static text field, and a radio control cluster of one choice, "Yes."

So, do I select the "Yes" radio button, then scroll that little window up so I can see an "OK" and "Cancel" button?

I bet all the other websites on the internet feel so foolish for just having "Retweet" buttons.

Why have an simple button with a clear one-word instruction when you can have an overlay obscuring the main page with window controls, static text, and a radio cluster to do the exact same thing?