Diary?::2006-06-25

00:29

家計簿付けるのが面倒で仕方がない。でもこればっかりは仕方がない。とりあえず集計を取るスクリプトは書いてあるので計算自体はノーコストなんだが、そもそも自分がいくら使ったか記録するという行為が面倒きわまりない。

03:13

数ヵ月前に書き捨てたスクリプト (こういうのに限って持続的にメンテする必要が出てくるんだよなあ) の手直しをしていると、本当に Python 選んでよかったなと思う。 Python は出来ることの多さに反比例するかの如くコードの書き方が没個性になっていくが、本当に個性が必要なのは作られるソフトウェア (というかそれを使って提供されるサービスや作られる作品) なので、別にコードの書き方が通り一遍のお約束になっても全然問題ない。

ところで俺はかつて C++ と Java が世界の全てだったころ (大学 2 年ぐらいだったか?) 、次のような文法の言語を考えたことがある。

Int Array x = Int Array (1,2,3,4)
Int i
x.for(i){
  print(i)
}

Ruby なんかのイテレータっぽい印象なんだが (でも確実に違う発想だった。あんまり覚えてないけど) 、今思うと当時の俺は本当に何もわかってなかったな。これじゃどこがループなのか一目でわからんよ。 for や while で行が始まっていれば、それはすなわちループだと瞬時にわかる。それが少しでも損なわれるのは何か嫌な感じだ。

そう考えると Python から map, filter, reduce を抹殺しようというのは頷ける話かもしれない。単純にループ (及びリストの閉包/ジェネレータ式) で置換可能であれば、そっちの方が普遍的な書き方になる。でも俺は reduce の方が畳み込み処理だってすぐにわかるし格好いいから好きだけどな (ちなみに sum はまったく代用品にはならない) 。

全然関係ないけど、先に出した妄想言語では型同士を実行時に結合させるなどというアホなアイディアがあった。さっきの例は Int 型の配列ではなく、新たな Int Array 型を作っていたのだ! 当時の俺は C++ に毒されていたとはいえ、 template の劣化コピーを思い付くなんざ最低だな。

もっと関係ないけど、 Java の Generics はちょっとどうかと思うよ。いや、腐っても Generics だから追加されるのは大歓迎なんだけど。

輪をかけて関係ないけど、俺が Smalltalk とその周辺にあまり興味がないのはどうも GUI 環境ありきな気がするから (文法もかなり変だと思うが、別に知見を広げるために触る程度ならそれは致命的な問題ではない) 。 Windows と Linux をほぼ同時に触って、結局 CUI が優れているという理由で Linux を選んだ俺のような人間はきっと Smalltalk の世界にはいてはいけないのだろう。

さらに関係ないところまで脱線する。例えば Windows でファイル名を変更しようと思った場合、ファイルをいったん選択して少しだけ待った後に再度選択すると、ファイル名を編集できるようになる。でもこれって本当にわかりやすい? 俺は最悪だと思うんだけど。右クリックは別の問題があって、左とか右とかそんなところから機能が類推できるか馬鹿野郎。メインボタンとオプションボタンとか、せめてそれぐらいのネーミングは出来なかったのか? 本当に PC に触ったことのない人にそういう質問をされて、相手を納得させる自身は俺にはないよ。

GUI にしろ CUI にしろインターフェースの設計者の脳味噌におがくずが詰まっていたら終わりなわけで、やはり UI 設計ってのはきちんと学ばねばならない分野だろう。ところで俺が思い付く良い UI 設計の定義というのは、使い手の予想/期待とアプリケーションの挙動をなるべく一致させること。だから今のはてなダイアリーの記事のソート方法は最低だし、コマンドラインオプションの -h にヘルプ以外の機能を持たせるべきではないし、他の言語で使われている言葉を全く別物の概念の説明に使うべきではない。

話を Python に戻すと、 Python は今のところもっとも良くできたインターフェースの言語だと思う。よい UI というのはユーザがやりたいと思ったことを出来るだけ迅速に発見できるようになっているものだが、もしも自分の読んでいるコードがシンタックスシュガーだらけの言語だったらそれを探すのに苦労する恐れが強い。ブロック表現におけるインデントの強制はそれをサポートするものだし (それには制御構造の始まりを示す : も役に立っている) 、行頭のキーワードで何が起こっているのかがわかるのも良い設計だ。 assert a == b, "Error message" を支持する人間はいても、 a == b assert "Error message" なんてやりたがる奴がいるとは思えない。とにかくアウトラインで大まかな判断をさせろってことだ。

いつもどおり Python を賛美する文章が書けたのでいい加減寝よう。

16:54

Grip で CD が再生できねえ。まあどうせリッピングするから関係ないけど。ってか、 portage に TTA がないじゃん。なんだか Gentoo で野良ビルドするのは気が退けるが、こればっかりは仕方がない。

18:41

最近コンソメスープをよく作ってる。作り方は信じられないぐらい簡単だが一応書いておく。

  1. 玉葱、人参、レタスを適当に切る。他の野菜も入れたければどうぞ
    • オプションとしてウィンナーやベーコンを入れてもいい
  2. とりあえず煮る。水の量は適当。
  3. 頃合を見計らってコンソメを投入する
    • タイミングは適当でいい
    • 分量も適当。多少へまっても食えなくなるわけじゃないから安心しろ
  4. 出来上がり

それなりに旨く、野菜が摂れ、そして腹にたまる。何よりスープが一品付くと食卓が少し豪華に見えるのが素晴らしい。

23:02

最近 Java ばっか書いてるので (というかそれが仕事だからな) 、リハビリとして Python で TSV ファイルの入出力を書いてみる。元ネタは Pythonでタブ区切りデータを出力する方法

class xsv_writer:
  def __init__(self, fname, sep=","):
    self._sep = sep
    self._file = file(fname, 'wb')

  def write(self, seq):
    self._file.write('%s%s' % (self._sep.join([self._escape(str(i)) for i in seq]),'\n'))

  def _escape(self, s):
    return s.replace('\\', '\\\\').replace('\r', '\\r').replace('\n', '\\n')
 
  def close(self):
    self._file.close()

class xsv_reader:
  def __init__(self, fname, sep=','):
    self._sep = sep
    self._data = iter(file(fname, 'rb'))

  def next(self):
    return [self._unescape(i) for i in self._data.next().split(self._sep)]

  def __iter__(self):
    return self
  
  def _unescape(self, s):
    return s.replace('\\\\', '\\').replace('\\r', '\r').replace('\\n', '\n')

class xsv(xsv_writer, xsv_reader):
  def __init__(self, fname, sep=',', mode='r'):
    if mode == 'r':
      xsv_reader.__init__(self, fname, sep)
    elif mode == 'w':
      xsv_writer.__init__(self, fname, sep)
    else:
      raise IOError('invalid mode: %s' % mode)

タブ区切りどころか任意のセパレータに対応させてみた。当然あんまりテストしてません。

追記: セパレータのエスケープをしていないのは単に面倒だったのと、任意のセパレータが選べるんだからそれで誤魔化せよって事で。

Written by Kuwata Chikara
Creative Commons