Tag: "programming"

Here are all posts that have been tagged with "programming".

There is also an Atom feed for this tag.

Hosting a naked (no-www) domain on dotcloud, GAE, etc.

Some platform-as-a-service providers like Google App Engine, dotCloud, etc. don't allow you to host a naked domain (example.com), and only serve requests from the www subdomain (www.example.com).

However, there is a neat hosted service called wwwizer which will redirect your no-www domain to your www domain, for free.

Here are my steps for hosting a naked domain with wwwizer on dotCloud. I also threw Cloudflare into the mix because they have a nice interface for editing DNS records and some other cool features (CDN, DoS protection, etc.). Using Cloudflare is not required for wwwizer to work.

  1. Add the domain to Cloudflare
  2. Cloudflare will copy your existing DNS records
  3. Cloudflare will provide you with two new name servers (x.ns.cloudflare.com and y.ns.cloudflare.com). Delete all your existing NS records and replace them with the two Cloudflare name servers.
  4. Wait until the nameservers switch over, you will get a message in the Cloudflare admin area. You can also check an HTTP response from your server, the "Server" HTTP header should say "cloudflare".

To host the site on dotCloud you then make these two changes from within Cloudflare:

  1. Set the A record for example.com (the naked domain) to (wwwizer.com)
  2. Set the A record for www to the IP address of gateway.dotcloud.com

Now your naked domain example.com will redirect to www.example.com, which will be hosted by dotCloud. Step #6 is the only part that is specific to dotCloud, just change this to whatever your PaaS provider tells you to, and you should be all set.

How to parse the output of git log

Here is how to get the output of "git log" in an easy to parse format and build a python dict from the result. You could then convert the dict to JSON, XML, HTML, etc.

First, look at the git-log man page and find the section on "Pretty Formats." There are different codes to use (like printf) for the commit metadata (e.g. %an for author name).

Store these codes, along with the corresponding field names in two lists:

GIT_COMMIT_FIELDS = ['id', 'author_name', 'author_email', 'date', 'message']
GIT_LOG_FORMAT = ['%H', '%an', '%ae', '%ad', '%s']

Then, join the format fields together with "\x1f" (ASCII field separator) and delimit the records by "\x1e" (ASCII record separator). These characters are not likely to appear in your commit data, so they are pretty safe to use for parsing.

GIT_LOG_FORMAT = '%x1f'.join(GIT_LOG_FORMAT) + '%x1e'

Then run git log --format="..." with your format string, split the fields, and make a dict from them:

p = Popen('git log --format="%s"' % GIT_LOG_FORMAT, shell=True, stdout=PIPE)
(log, _) = p.communicate()
log = log.strip('\n\x1e').split("\x1e")
log = [row.strip().split("\x1f") for row in log]
log = [dict(zip(GIT_COMMIT_FIELDS, row)) for row in log]


$ python commits.py
[{'author_email': 'skryskalla@gmail.com',
  'author_name': 'stevek',
  'date': 'Sat Feb 18 12:58:00 2012 -0800',
  'id': 'f1dc488e092e5e725c2ec3b7afc3962f0ba707d3',
  'message': 'third commit'},
 {'author_email': 'skryskalla@gmail.com',
  'author_name': 'stevek',
  'date': 'Sat Feb 18 12:57:54 2012 -0800',
  'id': '1bf26e9aa0cb8c9b95b579695c6af349319a88ab',
  'message': 'second commit'},
 {'author_email': 'skryskalla@gmail.com',
  'author_name': 'stevek',
  'date': 'Sat Feb 18 12:57:47 2012 -0800',
  'id': '9c2db5dffa7c70358ab78b6092539ce26006775b',
  'message': 'this is the first commit'}]

Full working example.

Perl - how to get the keys of a constant hashref

How do you get the keys of a constant hashref in perl?

$> use constant A => { 1 => 100, 2 => 200, 3 => 300}
$> A
{ 1 => 100, 2 => 200, 3 => 300 }

$> keys A
ERROR: Type of arg 1 to keys must be hash (not constant item) at (eval
13) line 3, at EOF
$> keys %A
$> (keys %{A})
Ambiguous use of %{A} resolved to %A at (eval 18) line 1, <IN> line 8.

To get the keys of a constant hashref you first need to learn that a constant is actually a function. You can leave off the parentheses to call a function in perl, but in this case you have to call the function to make perl happy.

$> (keys %{A()})
(1, 3, 2)

Ltchinese 0.1 release

I've given one of my old projects, ltchinese, an official release on PyPI, the Python Package Index.

I followed this excellent guide to make the package and publish it to PyPI. This is my first real open source Python package.

ltchinese is a small library of tools I built up when creating some of my Chinese language learning pages Ocrat mirror site, Mandarin phonetics table, etc.). It would be useful for developers that are building tools or web apps that deal with the Chinese language. It also includes a programmatic interface to some of the data on my site.

There is also documentation available (which is hosted by PyPI, cool).

I also got my first bit of feedback that someone was able to use the library for something useful. Thank you Vathanan!

Psychological randomness

If you ask a person to give you a 'random' number from 1 to 20, you are more likely to hear some numbers than others. There have been experiments that numbers like 13 or 17 sound more random than numbers like 10 or 20. For example:

Results revealed that for the entire sample the greatest percentage of tickets chosen for the first four selections were "random" tickets. Further, the most commonly cited reason for selecting and changing a lottery ticket was perceived randomness. -- Underlying cognitions in the selection of lottery tickets

Despite having an equal chance of being picked from a hat, certain combinations of numbers are perceived as more random than others.

Aside: Also see The Secret Lives of Numbers for something related, and awesome. It's shows how popular numbers are in search results. Phone numbers, tax forms, zip codes, famous dates, etc. show up more often than other more 'random' numbers and create some interesting patterns.

So, sometimes psychological randomness is more important than true randomness when dealing with perception.

One of the things I dislike about the program I use to play music (Foobar 2000) is that that the "Random song" button will pick the same song twice in a row. For a random number generator, that is a fine result, all numbers should have an equal chance of being picked. However, for the purpose of a music player, we don't want a "real" random number. Most people use a "Random" or "Shuffle" feature to listen to new songs. How often do you want to hear the same song twice in a row? If you want to hear the same song twice, why would you even use the "Random" feature in the first place?

I think "psychological randomness" should be one of the primary goals for any shuffle / random feature.

The easiest thing to do would be to keep a list of recently played tracks (at least ten), and when picking the next song, re-pick if the song is on that list. Another thing you could do is keep a shuffled version of the original list (a random permutation, then pick songs in order from that list.

But, once you start going down this path, it could be hard to stop! Would it be 'random' for two songs from the same artist to play? Same album? The more data you look at about the song (artist, album, title, user rating, genre, lyrics, mood), the smarter your randomization could be. You could build your own Recommendation system based on that song metadata, like Pandora.

Illustration of a grassy knoll