2009年1月21日水曜日

Pythonで日本語文字列を扱う

Pythonで日本語文字列を置換しようとする度にググるのでいい加減まとめておく。
前提としてPython 2.6.1だと、文字列は全部Unicodeだと見なされる。で、Unicodeじゃない文字列は単なるバイト列として扱われる。
(Python 2.6.1対応。Python 3.0では未確認)

まず、日本語(たぶんマルチバイト文字全般)の処理方法。
# -*- coding: utf-8 -*-
先頭にこれを書いて、ソースはutf-8で保存する。

# -*- coding: utf-8 -*-
str = "こんにちは世界"
print str
strは当然utf-8で保存されてるし、出力もそう。
Windowsのコンソールなんかでやると文字化けする。

# -*- coding: utf-8 -*-
str = "こんにちは世界"
print str.decode('utf-8')
pythonはユニコードが標準らしい。utf-8をデコードして(ユニコードにして)やる。
Windowsのコンソールだとちゃんと表示する。

# -*- coding: utf-8 -*-
str = u"こんにちは世界"
print str
最初からハードコーディングするならこっちが簡単。uを付けるとユニコードになる。
やっぱりWindowsのコンソールだとちゃんと表示する。

# -*- coding: utf-8 -*-
str = u"こんにちは世界"
print str.encode('utf-8')
意味はないけど、ユニコードをutf-8にエンコードすることも出来る。
Windowsのコンソールだとちゃんと(?)文字化けする。(化け方はさっきと同じ)

# -*- coding: utf-8 -*-
str = "こんにちは世界"
print unicode(str, 'utf-8')
実は、ユニコードへの変換を受け持つ関数(constructor)もある。
encode, decodeよりも判りやすいかも。実は便利な機能付き。
# -*- coding: utf-8 -*-
import sys
str = "\x80こんにちは世界"
print unicode(str, 'utf-8', errors='ignore')

try:
  print unicode(str, 'utf-8', errors='replace')
except:
  print sys.exc_info()[:]

try:
  print unicode(str, 'utf-8', errors='strict')
except:
  print sys.exc_info()[:]

errorsにオプションが指定できる。
ignoreを設定すると、変なのが混じってたら無視してくれる。
replaceは、置き換え文字列(REPLACEMENT CHARACTER, U+FFFD)に置き換えてくれる。Windowsだとcp932でエンコードできねえって怒られる。
strictは、そのまんま処理する。当然デコードできねえって怒られる。(これがデフォルト値)

ファイルを読み込んだり書き出したりするときの文字コードで覚えておくのは次のくらいかな。
euc-jp, utf-8, cp932, shift-jis

個人的には、pythonの文字列に戻してやるdecodeと、書き出すときのencodeを使うのが判りやすいと思う。(変な制御コードが入ってるかもしれないから、エラー処理は必要になっちゃうけど)
文字コードの自動判別とか無理しないで、ちゃんと指定するのが良さそう。

参考:

2008年11月18日火曜日

Rainmeterのスキン、10-Foot HUDの天気予報カスタマイズ


Rainmeterは、時刻とかの表示ツールだけど、lifehacker.jpで紹介されてた10-foot HUDはいい感じ。壁紙に時計がくっつくみたいで便利。
いじると判るんだけど、結構癖がある。スキンと言うよりも、URLを指定して正規表現で情報を抜き出したりもできるっぽい。
Weather-BlackとかのEditしようとすると、.iniファイルが直接開かれてちょっととまどうので、以下にやってみた情報を出しておく。


まず、コメントが ; らしいことは見たら判る。次に、Weather.comでお天気コードを探せと言われる。
;Find your weather code at Weather.com (like UKXX0296 below) and replace the one in this URL.

色々やった結果、日本を指定してそっから近い場所を探すのがよさそう。(クリックしづらいので根気よく探そう)

たとえば青森だと天気予報のページは http://www.weather.com/outlook/travel/businesstraveler/local/JAXX0004 になる。
だから、青森はJAXX0004というお天気コードなのが判る。
あとは、Weather-Black.iniの該当箇所を書き換える。(Weather-White.iniも同じ)
URL=http://xoap.weather.com/weather/local/JAXX0004?cc=*&unit=m&dayf=6
&unit=mを抜くと華氏表示になるけど、日本人なら摂氏じゃないかな。だからそのままで良い。

あと、[MeterTemp]の所に、Postfix="ー"って表示があるけど、これどうも°が文字化けしてるっぽい。
Postfix="°"
こうしてやる。人によっては℃とかが良いかも。
(日本語表示させたいとかは、見たら判るはずだから省略。僕は、英語のままで使ってる)
***
Weather.comの書式が変わったらしい。追記を参考に修正して欲しい。



2008年10月21日火曜日

荷物の分類

整理のコツ。

4つの容器に、ラベルを貼る。
捨てる(Throw Away):要らないモノ。好きじゃないモノ。ぐちゃぐちゃと台所にあるもの。
あげる(Give Away):寄付か友達に--どちらにせよ、良いことだし要らないものをはき出せる。
しまう(Put Away):他の部屋に入る?でも持ってくために片付けを止めないで!寄り道するから。この箱に入れてあとでやろう。
とっとく(Keep or Toss?):ソレ、どうするか決まらない?この箱に入れてテストしよう:ソレについて考えないか探しにいかなければ、遠慮せずに放り出そう。毎月チェックしよう。
http://www.squidoo.com/homemaking
より抜き書き

これで整理が進む。ハズ。

2008年9月11日木曜日

batの威力

Windowsのコンソールでスクリプト走らせると、どうしてもスクリプト内で完結してしまいがち。
(pythonだとos.walkとかでフォルダの中を走査したり)

でも、bat使って連続してファイル読み込ませると、状況見ながらリファクタリングできることに気がついた。
なんかボトルネックになってるところを発見したときに、そこを直すと、次に実行されるときには治ったやつが実行されるので便利。

for %%A in (%1) do python hoge.py < %%A
とか覚えとくと便利。

for %%A in (%2) do %1 < %%A
は、うっかり変なコマンド走らせて吃驚したのでやらない方が良さそう。

2008年9月9日火曜日

PythonでSQLiteを使う(データを書き込む)

・データを書き込む

カーソルを作成したので、データベースにテーブルを作る準備ができました。テーブルの作成には、必要なステートメントを入れて、カーソルからexecuteメソッドを呼ばなければなりません。名前(name)とメアド(email)を保存するテーブルを作ってみましょう。ついでに、それぞれの列(row)に、ユニークな番号を振るようにもしてみましょう:

>>> cursor.execute('CREATE TABLE names (id INTEGER PRIMARY KEY, name VARCHAR(50), email VARCHAR(50))')

これでテーブルが出来ました。同様にして、データの追加もexecuteメソッドで行うことが出来ます:

>>> cursor.execute('INSERT INTO names VALUES (null, "john Doe", "jdoe@jdoe.zz")')
>>> cursor.execute('INSERT INTO names VALUES (null, "Mary Sue", "msue@msue.yy")')

カーソルから、最後に登録した列(row)番号を得ることも出来ます。たぶん必要でしょう:

>>> cursor.lastrowid
2

そうそう、「ユーザの入力に応じてデータベースに入れたい」と言うでしょ。明らかに、ユーザの入力はそのままでは危ないです。悪意あるユーザは、簡単にクエリーを操ってデータベースに通せるし、深刻なダメージをデータベースに与えることが出来ます。これは許容できません。でも、ありがたいことにpysqliteにはセキュリティを確保する手段があります。ある人の名前(name)とメアド(email)を、2つの変数で持っているとしましょう:

>>> name = "Luke Skywalker"
>>> email ="use@the.force"

このとき、(自分たちで定義したんだから)これらはまあ安全です。でも、いつもそうだとは言えないでしょう。安全なクエリーに変数を入れたい時は、単にその場所にクエスチョンマークを入れればいいだけです。すると、pysqliteが残りをやってくれます(paramstyleを参照のこと):

>>> cursor.execute('INSERT INTO names VALUES (null, ?, ?)', (name, email))

今、私たちは変更を加えたので、保存しなければなりません。(もしくは、データベースに変更を通知しなければなりません)これには、コネクションのcommitメソッドを呼び出します:

>>> connection.commit()

もしも、変更したにもかかわらずcommitを呼ばず、コネクションを閉じようとすると、pysqliteはエラーを返すでしょう。こういう行動は、トラブルのもとになります。でも、やってしまった変更を保存したくないときもあるでしょう。そんなときは、rollbackメソッドを使います。(色々保存せずに電源を切るというやり方もありますけど)例えば、もう一列テーブルに加えるとしましょう:

>>> cursor.execute('INSERT INTO names VALUES (null, "Bobby John", "bobby@john.qq")')

この変更を無かったことにしたい、としましょう。我々は単にrollbackメソッドを呼べば良いのです:

>>> connection.rollback()

ほら、これで変更は消えました。
次のステップでは検索をしてみましょう。

2008年8月12日火曜日

パノラマ写真に関して

単一のレンズで全方位を映せるレンズをオリンパスが出してるが、これからはいろんなレンズで撮った画像を1枚にまとめられる技術の方が重要なのではないだろうか。
その手の技術は、技術者には普通のことなんだろうけれども、あんまりよく知らなかったので調べてみよう。

パノラマ写真をつくる
技術としてのSIFTに関して

・パノラマ写真を作るで紹介されているソフト
  1. autopano-sift
  2. hugin
  3. Enblend
説明をざっと見た感じでは、autopano-siftで特徴点の算出、huginで画像の変形、Enblendで画像の合成を行っているようだ。
何れもLinux版、Windows版ともにある。フリーでこういうものが開発されてるのはすごいなあ。見習いたい。
SIFTとか画像処理の根幹の部分は、こらからさらに重要になってくるような気がする。音声処理も。素人が処理できるレベルまでPCのスペックが上がってきてるので楽しそう。データマイニングも面白そうだし。

2008年7月15日火曜日

javascriptでクロージャ

クロージャとか、無名関数とか、引数として関数を渡すとか、javascriptって色々できるな。
難しそうだからさわってなかったけど、その場だけでごりごり書くときに便利そう。


/* New document created: 6.2.2008 18:34:27 */

function map(fn, a)
{
for (i = 0; i < a.length; i++)
{
a[i] = fn(a[i]);
}
}

function reduce(fn, a, init)
{
var s = init;
for (i = 0; i < a.length; i++)
s = fn( s, a[i] );
return s;
}

function sum(a)
{
return reduce(function(x, y){ return x+y; }, a, 0);
}

function cntYear(x) //Closure
{
var i = 0;
return function()
{
i = i + 1;
return x + i;
}
}

var a = [1, 2, 3];
map( function(x){return x*2;}, a );
map( alert, a );

years = new Array(400);
map( cntYear(2008), years );
map( function(x){ if(x%400==0 || x%100!=0 && x%4==0){return 1;}else{return 0;} }, years);
alert(sum(years));