George V. Reilly

Unicode Upside-Down Mapping, Part 2

Yesterday I showed File­For­mat's ɹǝʇɹǝʌuoↃ uʍo◖-ǝpısd∩ ǝpoɔıu∩. Although the lowercase letters generally looked good, several of the uppercase letters and numerals were un­sat­is­fac­to­ry. Looking through the Unicode Table site, I came across the Fraser Lisu alphabet, which is un­for­tu­nate­ly not well supported in most fonts. The following renders in Hack and Source Code Pro in MacVim, but not in the Source Code Pro webfont from Google Fonts:

B: ꓭ u+A4ED  Lisu Letter Gha
D: ꓷ u+A4F7  Lisu Letter Oe
J: ꓩ u+A4E9  Lisu Letter Fa
K: ꓘ u+A4D8  Lisu Letter Kha
L: ꓶ u+A4F6  Lisu Letter Uh
R: ꓤ u+A4E4  Lisu Letter Za
T: ꓕ u+A4D5  Lisu 
continue.

Unicode Upside-Down Mapping

Unicode is so versatile that you can (more or less) invert the Latin alphabet:

ɐqɔpǝɟƃɥıɾʞʃɯuodbɹsʇnʌʍxʎz ∀𐐒Ↄ◖ƎℲ⅁HIſ⋊⅂WᴎOԀΌᴚS⊥∩ᴧMX⅄Z 012Ɛᔭ59Ɫ86
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
68Ɫ95ᔭƐ210 Z⅄XMᴧ∩⊥SᴚΌԀOᴎW⅂⋊ſIH⅁ℲƎ◖Ↄ𐐒∀ zʎxʍʌnʇsɹbdouɯʃʞɾıɥƃɟǝpɔqɐ

Obtained via the ɹǝʇɹǝʌuoↃ uʍo◖-ǝpısd∩ ǝpoɔıu∩. More at Unicode Upside-Down Mapping.

Update: more tomorrow.

URLs from Unicode Strings

[Pre­vi­ous­ly published at the now defunct MetaBrite Dev Blog.]

Some time ago, we made an ill-considered decision to use recipe names for image URLs, which simplified image management with our then-rudi­men­ta­ry tools. For example, the recipe named "Twisted Pasta With Browned Butter, Sage, and Walnuts" becomes a URL ending in "Twist­ed%20­Pas­ta%20With­%20Browned%20But­ter%2C%20Sage%2C%20and%20Wal­nuts.jpg".

Life becomes more in­ter­est­ing when you escape the confines of 7-bit ASCII and use Unicode. How should u"Sautéed crème fraîche Provençale" be handled? The only reasonable thing to do is to first convert the Unicode string to UTF-8 and then hex-encode those octets: "Saut%C3%A9ed%20cr%C3%A8me%20fra%C3%AEche%20Proven%C3%A7ale".

That seems reasonable, but it was giving us in­con­sis­tent results when the images were uploaded to an S3 bucket. When continue.

Nose Test Discovery

I figured out why I saw the following error every time I ran Nose:

======================================================================
ERROR: Failure: TypeError (type() takes 1 or 3 arguments)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../lib/python2.7/site-packages/nose-1.3.7-py2.7.egg/nose/loader.py", line 523, in makeTest
    return self._makeTest(obj, parent)
  File ".../lib/python2.7/site-packages/nose-1.3.7-py2.7.egg/nose/loader.py", line 582, in _makeTest
    return MethodTestCase(obj)
  File ".../lib/python2.7/site-packages/nose-1.3.7-py2.7.egg/nose/case.py", line 345, in __init__
    self.inst = self.cls()
TypeError: type() takes 1 or 3 arguments

It turns out that one module was importing a class called TestApi which had a class­method called run_in­te­gra­tion_tests. The module itself had no tests; it just declared a class called TestO­b­fus­cat­ed­Mix­in, which used some continue.

Recursive Generators in Python 2 and 3

Generators decouple iteration from the code that uses the results of the iteration.

—David Beazley, Generators

[Pre­vi­ous­ly published at the now defunct MetaBrite Dev Blog.]

Python generators have a variety of uses. One such is to lazily evaluate sequences. Another is for coroutines. Yet another is to re­cur­sive­ly traverse a tree or a graph, yielding an iterable sequence.

Consider this simple tree of nodes:

node_tree = Node(
    'a', [
        Node('b', [
            Node('e', [
                Node('g')
 
continue.

psql: could not connect to server

I wanted to clean out my local PostgreSQL database today so that I could restore a database dump taken on another system, but every time I ran the psql utility, I got:

psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

I tried various things, including restarting Postgres several times, but nothing helped. Eventually, I thought to look in /usr/local/var/postgres/server.log, where I saw several error messages indicating that Postgres 9.5 couldn't read data files created with 9.4. At that point, I realized that during my most recent brew continue.

Relative Imports in a Python Script

Have you ever attempted a relative import in a Python script?

$ ./foo/bar/script.py some parameters
Traceback (most recent call last):
  File "foo/bar/script.py", line 16, in <module>
    from .quux import find_vcs
ValueError: Attempted relative import in non-package

I prefer to use absolute imports to minimize ambiguity and confusion, and most of my Python modules begin with:

from __future__ import absolute_import, unicode_literals, print_function

(Using uni­code_lit­er­als and print­_­func­tion makes porting to Python 3 easier.)

I recently read the accepted answer to Python relative imports for the billionth time and the solution to the above ValueError occurred to me: Use python -m package instead:

$ python -m foo.bar.script some parameters

(Assuming that continue.

Installing Python 2.7.11 on Ubuntu

We deploy on Ubuntu 14.04, the most recent Long Term Support release. It comes with Python 2.7.6, but we need Python 2.7.9+ to get the some important SSL fixes and work with a recent version of the Requests library.

Felix Krull maintains a Personal Package Archive for Python 2.7 Updates, which makes it straight­for­ward to upgrade to Python 2.7.11 on supported versions of Ubuntu.

sudo apt-add-repository ppa:fkrull/deadsnakes-python2.7
sudo apt-get update
sudo apt-get install python2.7 python2.7-dev

Be sure not to use Felix Krull's other Python PPA by mistake. I did that on a col­league's machine yesterday. In our attempts to figure out why we still had Python 2.7.6, we managed to mess up the continue.

DVI Not Considered Equal

We got a new monitor today for one of our pairing work­sta­tions. At 2560x1600, it was higher resolution than its pre­de­ces­sor. I dis­con­nect­ed the DVI cable from the old monitor, leaving it connected to one of the video ports on the computer, and connected it to the new monitor. All I could see was static and noise on the screen. After trying a variety of other things, I eventually thought to use the DVI cable that came with the new monitor. It worked!

I had assumed that all DVI cables were in­ter­change­able. Reading the Wikipedia article, I see that at higher res­o­lu­tions, dual link is needed. I hadn't known such a thing continue.

Python Base Class Order

When I declare a derived class that inherits from both a base class and some mixins, I am always tempted to write:

class Derived(Base, Mixin1, Mixin2):
    "Some class"

My reasoning is that Derived is a Base with some Mixin1 and Mixin2 goodness sprinkled on. Generally, that's fine. The exception is when I want one of the mixins to override a method or attribute that's defined in Base. Because the Method Resolution Order is left-to-right, then Base’s im­ple­men­ta­tion will always be found first.

To get the desired behavior of the mixin overriding the base, Base should always appear last in the in­her­i­tance list.

from __future__ import print_function

class Useful(object):
    
continue.
Previous » « Next