PILで_imagingftのインポートエラーが出た場合

PILでTrueTypeFontを使おうとすると、環境によっては

raise ImportError("The _imagingft C module is not installed")

というエラーが出る。
要はPILのコンパイル時にFreeType2がインストールされていなかった事が原因。
Linux(OpenSuse)ならば、「freetype2-devel」パッケージをインストールしてから、PILをインストールすれば解決する。

Pythonで配列内の重複する値を抽出する方法

Rubyで配列内の重複する値を抽出する方法 - 久保清隆のブログ

確かに「重複した値が知りたい」ときって、結構あるんですよね。
Rubyにはinjectという記法(?)があるんですね。
じゃあ、Pythonだとどうなるんだろうと考えてみました。

a = [1, 2, 3, 4, 5, 5, 1]

t = set()
[x for x in a if x in t or t.add(x)]
#=>[5, 1]

Rubyのように1行では書けないけど、分かりやすいコードにはなったかなと。
もっと上手い方法があったら、教えてください。

追記 2011/8/5
そういえばPython2.7以降ならばCounterがあるなと思いだしました。
これなら1行で書けます。

from collections import Counter
a = [1, 2, 3, 4, 5, 5, 1]

[key for key,val in Counter(a).items() if val > 1]
#=>[1, 5]

個人的にはCounterよりも、一番最初の方法の方が好きです。
なんとなく。

追記 順序を保持したまま重複した値を排除する方法

一般的にはset()を使いますが、順序が変わってしまいます。
どこかで聞いた方法ですが、以下の方法で実現できます。

a = [2,1,2,4,3,5,4,1]

sorted(set(a), key=a.index)
#=>[2,1,4,3,5]

よくこんな方法思いつくなぁ・・・

OpenSuse11.4でChromeをインストール

FireFox5に嫌気がさしたので、OpenSuse11.4でChromeをインストールしたのでメモ。

インストール自体は簡単で、以下のサイトからRPMをダウンロードするだけ。

http://www.google.co.jp/chrome/

インストールは無事に完了するが、Chromeが立ち上がらない・・・
どうやら「libpng12.so.0」が足りないようだ、libpng14.0が入っているんだけどなぁ。。。
なので、zypperでインストールする。

sudo zypper in libpng12-0

無事にchromeが立ち上がった。

wxPythonでクリップボード操作

wxPythonクリップボードで少しハマったのでメモ。

wxPythonクリップボード操作をググると、wx.Clipboard()を生成する方法が出てくる。
だが、OpenSuse11.4だとSetData()をするとアプリが終了しなくなるという現象が発生した。
ドキュメントを調べるとwx.TheClipboardでクリップボードを操作する方法もあるようだ、こちらでクリップボードを操作すると不具合が出なかった。

import wx

#wx.Appを作成しないとクリップボードが有効にならない
app = wx.App()

#クリップボードに値をセット
if wx.TheClipboard.Open():
    wx.TheClipboard.SetData(wx.TextDataObject("HogeHoge"))
    wx.TheClipboard.Flush()
    wx.TheClipboard.Close()

#クリップボードから値をゲット
do = wx.TextDataObject()
if wx.TheClipboard.Open():
    wx.TheClipboard.GetData(do)
    wx.TheClipboard.Close()
    print do.GetText()

なんでだ・・・

PILで"decoder jpeg not available"というエラーが出た時

OpenSuseでPILを使った時にこんなエラーが出たのでメモ。

どうやらeasy_install時にlibjpeg-devがない場合にこんなエラーが出る模様。
まず、libjpeg-devをインストール(環境によって最適なパッケージを入れてください)

sudo zypper in libjpeg62-devel

現在、インストールされているPILを削除

sudo rm -rf /usr/local/lib/python2.7/site-packages/PIL-1.1.7-py2.7-linux-i686.egg

easy_installでPILをインストール

sudo easy_install pil

環境はOpenSuse11.4を想定。

新しいファイルだけ上書きコピーする

今までshutilとかでチマチマやってたけど、Windowsなら「xcopy」コマンドを使えばよい事に気付いた。
主なオプションは以下の通り。

/D 新しいファイルだけをコピー
/S /E サブフォルダもコピー
/H 隠しファイルもコピー
/C エラーを無視してコピー
/Y 無条件上書きコピー
/R 読み取り専用ファイルもコピー
/EXCLUDE: 除外したいファイル/フォルダが書かれたファイルを指定

以下、/EXCLUDE:で指定するファイルの例。

\.hg\
\.bzr\
.db
~

上の例では、フォルダは.hgと.bzr、ファイルは.dbや~が付いているファイルが除外される。
(絶対パスで一部でもマッチされる部分があれば除外される)

pythonで書くと以下のとおり、pythonというよりWindowsの機能だが・・・

import subprocess
src = "src_dir"
dst = "dst_dir"
exclude = "exclude.txt"

subprocess.call("xcopy %s %s /D /S /Y /EXCLUDE:%s"%(src, dst, exclude))

※まだ試していないので間違いがあるかも、試したら改めて更新します。