LCD-like banners in Python

Back in 1998 or so, I wrote a CD player application for Microsoft Windows in Borland Delphi. It was for a magazine tutorial article, and I wanted a cool LCD-like display to show track elapsed and remaining time. There was a good one available for Delphi, called LCDLabel, written by Peter Czidlina (if you’re reading this, thanks once more for your cooperation).

I’ve been thinking about doing a modern version of the LCD display component for several times over the years, and I even got pretty far with one for OS X in 2010, but then abandoned it because of other projects. A few years ago I did some experiments with the LCD font file and wrote a small Python app to test it.

My most recent idea involving simulated LCD displays is to create a custom component for iOS and OS X in Swift. For that, I dug up the most recent Python project and tried to nail down the LCD font file format, so that I could later use it in Swift. I decided to use JSON.

The LCD font consists of character matrices, typically 5 columns by 7 rows, each describing a character on the LCD panel. The value of a matrix cell is one if the dot should be on, and zero if it should be off. I decided to store each cell value as an integer, even if it is a bit wasteful – but it is easy to maintain, and if you squint a bit, you can see the shape of the LCD character.

So the digit zero would be represented as a 2-dimensional matrix like this:

[
[0,1,1,1,0],
[1,0,0,0,1],
[1,0,0,1,1],
[1,0,1,0,1],
[1,1,0,0,1],
[1,0,0,0,1],
[0,1,1,1,0]
]

The font consists of as many characters as you like, but you need to identify them somehow. In JSON, you can do this with one-character strings, where the sole character is the Unicode code point of the character. So, with some additional useful information, a font with just the numeric digits 0, 1, and 2 would be represented in JSON like this:

{
"name": "Hitachi",
"columncount": 5,
"rowcount": 7,
"characters": {
"\u0030": [
[0,1,1,1,0],
[1,0,0,0,1],
[1,0,0,1,1],
[1,0,1,0,1],
[1,1,0,0,1],
[1,0,0,0,1],
[0,1,1,1,0]
],
"\u0031": [
[0,0,1,0,0],
[0,1,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0],
[0,1,1,1,0]
],
"\u0032": [
[0,1,1,1,0],
[1,0,0,0,1],
[0,0,0,0,1],
[0,0,0,1,0],
[0,0,1,0,0],
[0,1,0,0,0],
[1,1,1,1,1]
]
}

With the font coming along nicely, I wrote a Python script to exercise it, by printing a banner-like message:

import json

def banner(message):
    mats = []
    for ch in message:
        mats.append(characters[ch])

    output = ''
    num_rows = len(mats[0])
    num_cols = len(mats[0][0])

    for r in range(0, num_rows):
        for m in mats:
            for c in range(0, num_cols):
                if m[r] == 1:
                    output += 'X'
                else:
                    output += '.'
            output += ' '
        output += '\n'
        
    return output

font_data = None
with open('lcd-font-hitachi.json') as json_file:
  font_data = json.load(json_file)
  characters = font_data['characters']

print(banner('012'))

Running this Python script would print out a banner like this one:

.XXX. ..X.. .XXX.
X...X .XX.. X...X
X..XX ..X.. ....X
X.X.X ..X.. ...X.
XX..X ..X.. ..X..
X...X ..X.. .X...
.XXX. .XXX. XXXXX

By adding characters to the JSON font file it becomes possible to print text messages instead of just numbers:

X...X ..... .XX.. .XX.. ..... ..X..
X...X ..... ..X.. ..X.. ..... ..X..
X...X .XXX. ..X.. ..X.. .XXX. ..X..
XXXXX X...X ..X.. ..X.. X...X ..X..
X...X XXXXX ..X.. ..X.. X...X ..X..
X...X X.... ..X.. ..X.. X...X .....
X...X .XXX. .XXX. .XXX. .XXX. ..X..

But I think that a custom control for iOS in Swift would see most use in games or applications displaying numeric parameters like volume level, geographical coordinates or RPM.

If you want to learn Python, here is a good book:

Learning Python
Learning Python
by Mark Lutz

Learning Clojure

About one year ago I wrote a multi-part tutorial on Clojure programming, describing how I wrote a small utility called ucdump (available on GitHub).

Here are links to all the parts:

However, Carin Meier’s Living Clojure is excellent in many ways. Get it from O’Reilly (we’re an affiliate):
Living Clojure

My little tutorial started with part zero, in which I lamented how functional programming is made to appear unlearnable by mere mortals, and it kind of snowballed from there. Hope you like it and/or find it useful!

 

Functional programming without feeling stupid, part 5: Project

In the last four installments of Functional programming without feeling stupid I’ve slowly built up a small utility called ucdump with Clojure. Experimentiing and developing with the Clojure REPL is fun, but now it’s time to give some structure to the utility. I’ll package it up as a Leiningen project and create a standalone JAR for executing with the Java runtime.

Creating a new project with Leiningen

You can use Leiningen to create a skeleton project quickly. In my project’s root directory, I’ll say:

lein new app ucdump

Leiningen will respond with:

Generating a project called ucdump based on the 'app' template.

The result is a directory called ucdump, which contains:

.gitignore   README.md    project.clj  src/
LICENSE      doc/         resources/   test/

For now I’m are most interested in the project file, project.clj, which is actually a Clojure source file, and the src directory, which is intended for the app’s actual source files.

Leiningen creates a directory called src/ucdump and seeds it with a core.clj file, but that’s not what actually what I want, for two reasons:

  • I want ucdump to be a good Clojure citizen, so I’m going to put it in a namespace
    called com.coniferproductions.ucdump.
  • My Git repository for ucdump also contains the original Python version of the application, which is in <project-root>/python, and I want the Clojure version to live in <project-root>/clojure.

Continue reading

Functional programming without feeling stupid, part 4: Logic

In the previous parts of “Functional programming without feeling stupid” we have slowly been building ucdump, a utility program for listing the Unicode codepoints and character names of characters in a string. In actual use, the string will be read from a UTF-8 encoded text file.

We don’t know yet how to read a text file in Clojure (well, you may know, but I only have a foggy idea), so we have been working with a single string. This is what we have so far:

(def test-str 
  "Na\u00EFve r\u00E9sum\u00E9s... for 0 \u20AC? Not bad!")
(def test-ch { :offset 0 :character \u20ac })
(def short-test-str "Na\u00EFve")

(defn character-name [x]
  (java.lang.Character/getName (int x)))

(defn character-line [pair]
  (let [ch (:character pair)]
    (format "%08d: U+%06X %s"
      (:offset pair) (int ch)
      (character-name ch))))
    
(defn character-lines [s]
  (let [offsets (repeat (count s) 0)
        pairs (map #(into {} {:offset %1 :character %2}) 
          offsets s)]
    (map character-line pairs)))

I’ve reformatted the code a bit to keep the lines short. You can copy and paste all of that in the Clojure REPL, and start looking at some strings in a new way:

user=> (character-lines "résumé")
("00000000: U+000072 LATIN SMALL LETTER R" 
"00000000: U+0000E9 LATIN SMALL LETTER E WITH ACUTE" 
"00000000: U+000073 LATIN SMALL LETTER S" 
"00000000: U+000075 LATIN SMALL LETTER U" 
"00000000: U+00006D LATIN SMALL LETTER M" 
"00000000: U+0000E9 LATIN SMALL LETTER E WITH ACUTE")

But we are still missing the actual offsets. Let’s fix that now.

Continue reading

Functional programming without feeling stupid, part 3: Higher-order functions

Welcome to the third installment of “Functional programming without feeling stupid”! I originally started to describe my own learnings about FP in general, and Clojure in particular, and soon found myself writing a kind of Clojure tutorial or introduction. It may not be as comprehensive as others out there, and I still don’t think of it as a tutorial — it’s more like a description of a process, and the documented evolution of a tool.

I wanted to use Clojure “in anger”, and found out that I was learning new and interesting stuff quickly. I wanted to share what I’ve learned in the hope that others may find it useful.

Some of the stuff I have done and described here might not be the most optimal, but I see nothing obviously wrong with my approach. Maybe you do; if that is the case, tell me about it in the comments, or contact me otherwise. But please be nice and constructive, because…

…in Part 0 I wrote about how some people may feel put off by the air of “smarter than thou” that sometimes floats around functional programming. I’m hoping to present the subject in a friendly way, because much of the techniques are not obvious to someone (like me) conditioned with a couple of decades of imperative, object-oriented programming. Not nearly as funny as Learn You a Haskell For Great Good, and not as zany as Clojure for the Brave and True — just friendly, and hopefully lucid.

xkcd 1270: Functional
xkcd 1270: Functional. Licensed under Creative Commons Attribution-Non-Commercial License. This is a company blog, so it is kind of commercial by definition. Is that a problem?

In Part 1 we played around with the Clojure REPL, and in Part 2 we started making definitions and actually got some useful results. In this third part we’re going to take a look at Clojure functions and how to use them, and create our own — because that’s what functional programming is all about.

Continue reading

The FIFA World Cup is not internationalized

At the time of this writing, the FIFA World Cup is almost at its final stage. Throughout the whole month of the tournament I have been amazed to find out that while UEFA has consistently made an effort to have the players’ names written as authentically as possible, FIFA hasn’t. Information conveyed to viewers in televised matches is transliterated, making many players’ names appear irritatingly different than their national, conventional spellings.

It can be argued that FIFA has a tougher job with various languages and characters. After all, the 2014 World Cup had Japan, South Korea, Iran, Russia, and Greece, among others. These countries and their languages alone represent half a dozen character sets. There is a point in trying to achieve some sort of baseline transliteration, so that all names are expressed in the Latin character set. In practice this means that Russian, Greek, and other names are transliterated by default. However, names which can be perfectly written in extended Latin should not be transliterated. Now it seems like everything has been folded down to basic ASCII.

There is no technical reason to limit the displays on television screens to what is essentially a 7-bit character set, but this is what the result amounts to. For example, one of the finalists in this World Cup is Germany, and many of the players have characters with umlauts in their names. Here are a few examples:

Oezil should be Özil
Mueller should be Müller
Goetze should be Götze
Hoewedes should be Höwedes

EDIT: Also, the German coach is Joachim Löw, not Loew (or Low, as the content on the official FIFA apps would have us believe).

The players’ jerseys have the truth anyway, and it’s in direct contrast with what you see when somebody scores a goal, gets booked or gets sent off.

So please, FIFA, take a leaf from UEFA’s book and find out how to use modern broadcasting technology to the advantage of all football fans around the world (even if they might call it soccer). You might also start with a good book like “Unicode Explained” by Jukka K. Korpela.

12 12 12

Here we go again… Today is December 12, 2012 in the Gregorian calendar, and people are waxing poetic about how symmetrical, how repetitive and how unique this date is. (Even people who really should know better.) Some people are even getting married today. I wish them the best of luck.

But let me put my science hat on for a moment, and offer the following statement:

The symmetry / reflexivity / repetitiveness / uniqueness of a date expression such as 12/12/12, 11/11/11 etc. ad nauseam, is not axiomatic. It is an artefact of the presentation layer.

In layman’s terms:

It’s not really like that, it’s just written that way.

Continue reading

Unicode is in Your Now

If this blog entry was written 10–15 years ago, the title would have been “Unicode is in Your Future“. Luckily, the Unicode standard has been widely adopted during the last decade, so much so that it has almost become a part of the process and not something that you need to expend very much extra effort on. It is here Now, and has been for some time now.

However, Unicode still isn’t quite as widely understood as it needs to be, and it is often adopted as a black box that nobody can really fix when something goes wrong. Therefore it is not at all bad to try and bring it into perspective.

You need to understand at least why Unicode should be used, and how not to make it more complicated than it is (even though it can still be quite complicated). So keep reading.

Continue reading