pythonのスコープではまる

ちょっとはまった。結局オブジェクト作って解決しといたけど気持ち悪いので少し調べた。(でも未解決)

クロージャでカウンタを考える。Open Source WEBを参考に

perlだと

sub make_counter {
  my $c = $_[0] || 0;
  return sub { $c++ }
}

gaucheだとこんな感じ

(define (make-counter n)
  (let1 c n
    (lambda () (inc! c))))

でもpythonだとだめなの

def make_counter(n):
    c = n
    def counter():
        c = c + 1
        return c
    return counter

スコープの洗礼をうけた。参照できても代入できないのでglobalにする必要が。

def make_counter(n):
    c = n
    def counter():
        global c
        c += 1
        return c
    return counter

ctr = make_counter(5)
ctr()
ctr()

Traceback (most recent call last):
  File "C:\home\kzfm\test.py", line 10, in <module>
    ctr()
  File "C:\home\kzfm\test.py", line 5, in counter
    c += 1
NameError: global name 'c' is not defined

とかいってglobalでも駄目だ。

pythonでクロージャ

昨日の続き

ウィキペディアによるとリストを参照すればいいらしいので。

def make_counter(n):
    c = []
    c.append(n)
    def counter():
        l = c.pop()
        l += 1
        c.append(l)
        return l
    return counter

ctr1 = make_counter(5)
ctr2 = make_counter(3)
print "ctr1: ", ctr1()
print "ctr1: ", ctr1()
print "ctr1: ", ctr1()
print "ctr2: ", ctr2()
print "ctr2: ", ctr2()
print "ctr1: ", ctr1()

さて実行

$ ./make_counter.py 
ctr1:  6
ctr1:  7
ctr1:  8
ctr2:  4
ctr2:  5
ctr1:  9

おーできた。でもこれだったらクラスのほうが分かりやすいなぁ。

class Counter:

    def __init__(self,num):
        self.c = int(num)

    def count(self):
        self.c += 1
        return self.c

LEGBルールってなんか分かりにくいな。単なる慣れなのか?

gzipでMemoryError

pythonのgzipモジュールで読み込んで処理してたらメモリエラー。

MemoryError
gzip: sample.gz: invalid compressed data--format violated

おー、圧縮ファイル壊れてる。3G位ある圧縮ファイルで、つくんのに5日かかったのでちょっと凹んだ。

早く帰りたかったのでperlでちょこっと分割してtelnetで分散処理するスクリプト書いちゃったけど(これだと半日で終わるかな)。

家に帰ってきてからpythonでtelnetするモジュールを探してみた

みんなのPython Webアプリ編 を予約した

楽しみ。

ProductName みんなのPython Webアプリ編 [みんなのシリーズ]
柴田 淳
ソフトバンククリエイティブ / ¥ 2,604 ()
在庫あり。

pythonのdatetimeモジュール

6.10 datetime -- 基本的な日付型および時間型みながら。

>>> import datetime
>>> datetime.date.today()
datetime.date(2007, 7, 28)
>>> d = datetime.date.today()
>>> d.month
7
>>> d.day
28
>>> d.year
2007

で、matplotlibにはグラフを描きやすいようにmatplotlib.datesというモジュールがあって何日おきとか何年おきとかそんな感じの目盛りが簡単にうてる。

METAMORPHOSE 07 届いた

来月末に修善寺で行なわれるメタモのコンピが届いたヨ。

ProductName METAMORPHOSE 07
オムニバス
インディーズ・メーカー / ¥ 3,200 (2007-07-25)
在庫あり。

lindstromはやっぱええわ。あと、vvvv使いらしいtriponが気になる。

っていうかVJだけど、NintendoDSのタッチパッド使ったりとかWiiリモコンでVJやったりとかみると新しいデバイス使ってあれこれすんのは楽しそう。っていうか、DJの動きとかフロアの動きをゴニョゴニョして映像を生成したりとかはあるんだろうか?

IronPythonなんかつかってみると面白いことできるんじゃないかナァ。つうわけで、IronPython入れてみることにする。

Fedora7にmatplotlib-0.90.1をインストール

Fedora7用のrpmがないのでsrc.rpmをとってきて

rpmbuild --rebuild --define 'pyver 2.5' wxPython2.8-2.8.4.0-1.src.rpm

でいいと思うんだけど、rpm -Uvhで入れようとすると

エラー: 依存性の欠如:
    libiconv.so.2 は wxPython2.8-gtk2-unicode-2.8.4.0-1.i386 に必要とされています

と怒られる。so.2も在るし、ldconfigもきちんとしてるのに、、、、謎だ。

と思ったらこれrpmで入れてなかったわ。

結局tarballから入れた。

os.walk

かなり出遅れで、どう書くみてるので、なんかおーとかほーとかしか言葉が出ないんだけど、知らない言語の勉強になっていい。

pythonで再帰的にディレクトリとかファイルを探索するにはos.walkを使うらしい。

>>> import os
>>> for f in os.walk('.'):
...     print f[0]

f[0]にファイルのリストがf[1]にはディレクトリのリストが詰まって戻ってくる。

getopt

最近ずっと職場の正規WSでたいして使いやすくない(生産性のあがらない)GUIでクリックしまくりーな地味な解析作業をしてるが、いい加減いやになってきたので、スクリプトを書くことにした。

が、正規WSはRHEL3なのでpythonが2.2だった。というわけで、getoptモジュールをつかってコマンドオプションの解析ルーチンを書いてみた。

めんどい、やたらめんどい。自分でhelpメッセージを書けない身体になってることに気付いた。あとコードがなんか汚く見えてくる。optparseは楽でよいと再確認。

あと、どう書く?のお題もチャレンジする、pythonで。

networkxとpython-twitterでネットワーク描く

twitterのネットワークをグラフにして書き出してみる。python-twitternetworkxを使用。日本語のフォントの指定の仕方(pylabのほうだと思う)がわからなかったので日本語は表示されていない。

from pylab import *
from networkx import *
import twitter

myname= USERNAME
mypassword = PASSWORD

api = twitter.Api(username=myname,password=mypassword)
friends = api.GetFriends()
G = XGraph()

for friend in friends:
    G.add_edge(myname,friend.name)

for friend in friends[-3:]:
    for user in api.GetFriends(friend.id):
            G.add_edge(friend.name,user.name)

#pos=spring_layout(G)
pos=random_layout(G)
#pos = shell_layout(G)

draw_networkx_nodes(G,pos,node_size=100,node_color='b')
draw_networkx_edges(G,pos,width=1)
draw_networkx_labels(G,pos,font_size=8,font_family='sans-serif',font_color='r')

xticks([])
yticks([])
savefig("twitter.png") 
show()

spring

springにするとやたらとCPUを食うのでちょっと大きくなると厳しい。というわけで、自分のフォロワーのフォロワーは3つだけにした。他のレイアウトも試してみたが、スプリングのほうがよさげ。

spring

ランダムだと何みてるか分からんし。

spring

シェルはちょっと視覚的に面白みがない。

コンファレンスのアカウントから幾つかつないで、ネットワークを描くのが楽しそう。あとは、エッジの数が少ないのは枝刈りしないと、僕のR4だと結構厳しいし、視覚的にも見辛くなるかな。