2009年11月14日

Python Hack-a-thon

Python Hack-a-thonに参加中。
発表資料的なものを作ったので、おいとく。

2009年11月5日

delegateのシグネチャを調べる


delegateのシグネチャを調べる方法を探している人がいたので、調べてみた。



class Program
{
static void Main(string[] args)
{
Type t = typeof(MyEventHandler);
Console.WriteLine(t);
MethodInfo m = t.GetMethod("Invoke");
Console.WriteLine(m.ReturnType);
foreach (var p in m.GetParameters())
{
Console.WriteLine(p);
}
}
}


public delegate bool MyEventHandler(object sender);


ildasmで調べてみると、
Invokeメソッドがdelegateの宣言と一致してるようなので、リフレクションでパラメータと戻り値の型を調べればOKっぽい。

2009年10月31日

screenの中でscreenを起動しないようにする方法

気になったので、やってみた。
screen起動中は環境変数TERMがscreenとなっているので、これを利用する。

#!/bin/sh
if [ "$TERM" == "screen" ] ; then
echo "already in screen"
exit
fi

exec /opt/local/bin/screen

mac portsの場合ね。
これを$HOME/bin にでも入れとけばOK

2009年10月19日

PythonでEnum型してみた


PythonでEnumを書いてみた人がいたので、ちょっと考えてみた。


Enumって型の種類なんで、Enum型というものをまず定義せにゃならんのじゃないかと。
ってことは、メタクラスの出番ですね。分かります。


使い方は、doctestのサンプルの通り。
StandardEnumを継承したclass宣言内で、列挙します。
Pythonは識別子だけのステートメントなんて持ってないので、値は明示的に指定しましょう:-)



# -*- coding:utf-8 -*-
"""
>>> class SampleEnum(StandardEnum):
... A = 1
... B = 2
... C = 3
...
>>> SampleEnum.A
<SampleEnum.A value=1>
>>> for e in SampleEnum:
... print e
...
<SampleEnum.A value=1>
<SampleEnum.B value=2>
<SampleEnum.C value=3>
>>> SampleEnum.A == SampleEnum.A
True
>>> SampleEnum.A == SampleEnum.B
False
"""


class EnumType(type):

def __init__(cls, name, bases, dct):
super(EnumType, cls).__init__(name, bases, dct)
cls._values = []

for key, value in dct.iteritems():
if not key.startswith('_'):
v = cls(key, value)
setattr(cls, key, v)
cls._values.append(v)

def __iter__(cls):
return iter(cls._values)


class StandardEnum(object):

__metaclass__ = EnumType

def __init__(self, k, v):
self.v = v
self.k = k

def __repr__(self):
return "<%s.%s value=%s>" % (self.__class__.__name__, self.k, self.v)


if __name__ == '__main__':
import doctest
doctest.testmod()


定義順を保ために、_valuesを使ってるけど、実際のところ値を使った方が、直感的かもしれない。ふつうは昇順に定義するだろうしね。



2009年7月8日

GAEでPOSTパラメータを柔軟に受け取る

GAEに限らないけど、キャッチーにしたいので。
PHPとかで、パラメータ名を"a[]"にすると配列として複数のパラメータを受け取れるというアレ。
とりあえずformencodeを使えばいいかな。

>>> import formencode.variabledecode
>>>
>>> params = {"names-1.fname":"John",
... "names-1.lname":"Doe",
... "names-2.fname":"Jane",
... "names-2.lname":"Brown",
... "names-3":"Tim Smith",
... "action save":None,
... "action.option":"overwrite",
... "action.confirm":"yes",
... }
>>>
>>> print formencode.variabledecode.variable_decode(params)
{'action': {'option': 'overwrite', 'confirm': 'yes'}, 'names': [{'lname': 'Doe', 'fname': 'John'}, {'lname': 'Brown', 'f
name': 'Jane'}, 'Tim Smith'], 'action\tsave': None}

formencode.variabledecode – Turn flat HTML form submissions into nested structures — FormEncode v1.2.2 documentation


書き忘れてましたが

もう自由人じゃないですよ。

2009年6月21日

twitterのユーザーリストを一気にフォローする


offに参加すると、その後フォロー祭りになったりするんだけど、かったるいのでバッチ処理した。
既にフォローしてるかどうかを判別するのは面倒なので、全部friendships.createを呼んでみた。
どうせ既にフォローしてるなら、403 Forbiddenになるので、問題ないだろう。



入力のファイルは、各行が、@[ユーザー名]となっている想定。



import sys
import httplib
import time

urltmpl = '/friendships/create/%s.xml'
user, password = sys.argv[1].split(':', 1)
basic_auth = (user + ':' + password).encode('base64')
print basic_auth
headers = {"Authorization": "Basic %s" % basic_auth}
print headers
f = open(sys.argv[2])
twitters = [t.strip().lstrip('@') for t in f if t.strip() != '']
f.close()

for t in twitters:
path = urltmpl % t
print t
conn = httplib.HTTPConnection("twitter.com")
conn.request("POST", path, '', headers)
res = conn.getresponse()
print res.status, res.reason
time.sleep(3)


考えてみたら、urlに埋め込む前にパーセントエンコーディングするべきだな。
ユーザー名にマルチバイトって使えるんだか知らないけど。