Consecutive pairs is a valid hand in this Chinese Poker

What is this?

This is a fun card game that’s easy to learn. Each player tries to discard all the cards in their hand. When someone discards their last card, the others are penalized points for the cards left in their hands.


Before playing, the players agree to play to a certain score maximum. (Usually 100.) Once any player reaches the maximum the game is over. The player with the lowest score is the winner.

Chinese Poker is played with a standard deck of 52 playing cards. Three 2s and one ace are removed, leaving a deck with 48 cards. Suits and color…

Card Catalog by DocBrownX on Flickr CC-BY

tl;dr: Make these changes

In your .bashrc add:

shopt -s histappend

And add the following cronjob:

T=$(mktemp); tac "$HOME/.bash_history" | awk '!x[$0]++' | tac > "$T" && mv "$T" "$HOME/.bash_history"

Using the duplicate lines in your history

There’s an old Unix meme to share your most frequently used commands by issuing the following command:

$ history | awk '{print $2}' | sort | uniq -c | sort -nr | head -5

And you’d get an ordered list of commands like so:

31 nethack
24 python3
21 git
14 http
11 jq

It’s fun! And it’s interesting to work out what’s happening in that command. But once you realize there…

Yesterday I fixed an eight-year-old security bug in my bespoke password vault.

After a user logs in, the server issues a new Cookie for them. It’s sure to restrict itself with Morsels like domain and max-age. The Python code looks like this:

my_cookie = Cookie.SimpleCookie()
my_cookie['sess'] = data()
my_cookie['sess']['max-age'] = 30*60
my_cookie['sess']['domain'] = ''

Under the hood, the cookie goes to the client in the response like this:

Set-Cookie: sess="eX1lWwUEdHZ...";; Max-Age=1800

Then, when the client makes subsequent requests, the server populates its Cookie object with the cookie data.

if os.environ.has_key('HTTP_COOKIE'):

This is all boiler-plate and perfectly fine. The…

With Google+ going away, I made backups of both my LiveJournal and my Google+ accounts. Here’s why I love the backups:

User Experience

  • They’re super fast. Just static HTML5 (except for the search functionality), no frameworks, no libraries.
  • You can navigate from the keyboard. Either the arrow keys, gaming WASD keys, or Vim’s HJKL keys. Whatever you like. Go left and right to navigate HTML pages, up and down to navigate posts within pages.
  • They’re mobile-responsive. They use CSS grid to make the main column featured and readable regardless of screen width. …

Or, My most egregious one-liner ever

Some of my cronjobs run on a shared hosting server where I don’t have access to /etc/logrotate or /var/log, so I can’t use logrotate to manage their logs.

They write log lines to files in a log directory in my home directory. All I’ll ever want from these logs is the most recent few lines anyway. To ensure those log files don’t grow without bounds, I wrote a one-liner cron job that keeps them within the 200 most recent lines.

This is the cron job command:

find $HOME/log -maxdepth 1 -name \*\.log -type f ! -executable -exec sh -c 'MAX=200…

tl;dr: Don’t delete user accounts without (always) notifying the user.

I pass nearby their headquarters on my way to work. I took this shot.

I had an active eBay account, and was proud of my good reputation, curated by transactions from before 2004 to 2015. But then the account went idle in 2015, and I got an email that said,

Unfortunately, since you haven’t used your eBay account for a while, it will be deleted if you don’t sign in within 30 days from the day this email was sent.

No worries, I signed in and browsed a bit, and my account was reset as active.

Since then, I hadn’t always signed in to…

I have a rarely-used email account for password resets and such. Since that’s all it’s for I don’t monitor it regularly, because it should only get email when I request the password reset myself.

But then what if it gets email for another reason? I’d want to know. So I wrote a one-off little script that monitors the email account, and updates an RSS feed, so I’ll see an entry in my feed reader, which I do monitor daily.

It’s been working fine for years. No need to change anything. Except I decided I wanted to update it from Python…

Photo from Rocklin Lyons on Flicker cc by-nc

Do you really know what freedom means
It’s a government 45 and an M-16
It’s 13 months in a jungle sopping wet
It’s helping Vietnam celebrate Tet

How deep in your pockets will you really reach
to keep your precious Freedom of Speech
You read the papers you watch the news
You tell the lies we pay the dues

You wear ties and give the world a speech
but we know the truth about China Beach
And that’s all right cause we were kids then
but behind these walls we are full grown men

So raise that flag to show…

Image from Han N (xhan104) on flickr (cc by-nc-nd)

I came across a Raspberry Pi Stack Exchange question where I had the same question, but it was closed as off-topic. How to install Python 3.7 with SSL?

The problem is that if you compile Python 3.7 on Raspbian Jessie, that Python won’t build the module _ssl. And since it won’t do that, pip won’t work, because pip requires a newer OpenSSL library than Jessie provides. Running python3 -m pip install anything would fail with:

pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

Sure enough, checking the version:

$ openssl version…

I can log in to my home’s router from anywhere and configure the local network as needed, including stopping YouTube and Netflix when the kids need to do homework.

tl;dr Use port forwarding and ssh tunneling

I have a Raspberry Pi at home serving a website. My Internet Service Provider assigns my home’s IP address dynamically. So that Pi also updates a name server so that the website can always be found with a name. (My Asus router can also do this with a subdomain at

I recently realized I could use port forwarding to my Pi to get to the Router’s admin page when I’m…

David Blume

A rock-climbing father of two and software developer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store