ninjam はじめてみた

先月辺りから。

楽器: Gibson ES-335, Monster Cable JAZZ, Line6 PODx3 pro

      • -

ソースコードも公開されてるので、コード・リーディングも開始。

  • 開発言語は C++
  • 共通ライブラリの WDL 内に null soft の jnetlib
  • Chat機能

- IRCクライアントみたいなコマンドがある
- /me ... 自分の状態を通知する。独り言コマンド? e.g. /me brb phone
- /msg ... 私信。個人宛メッセージ。 ( /msg username message )
- /clear ... 会話ログのクリア
- 他、管理者コマンドっぽいもの /admin, /kick, /bpi, /bpm, /topic

Python - dictproxy

immutable な辞書が必要になったので。

from ctypes import pythonapi, py_object
from _ctypes import PyObj_FromPtr

PyDictProxy_New = pythonapi.PyDictProxy_New
PyDictProxy_New.argtypes = (py_object,)
PyDictProxy_New.rettype = py_object

def make_dictproxy(obj):
    assert isinstance(obj,dict)
    return PyObj_FromPtr(PyDictProxy_New(obj))

from types import DictProxyType as dictproxy

使い方: makedictproxy(辞書オブジェクト)
dictproxy は isinstance でのチェック用。

dictproxy({}) # TypeError, インスタンス生成出来ない。

追記:
書き終わってから、types.DictProxyType がある事に気付く。(コード修正)
元のコードは、dictproxy = type(type('',(),{}).__dict__) だった。

更に後から気付いたけど。
毎回無名のクラスが作られるのさえ気にしなければ、これでも良かった。

make_dictproxy = lambda dictobj: type('',(),dictobj).__dict__


追記2

dictproxy は == immutable dict ではないので、
誤用だからデータ保護等の用途には使わないほうがいいらしい。
ImmutableDict クラス作る方が確実。

 a = dict(val=20)
 b = make_dictproxy(a);
 a['val'] = 10
 print a, b

引数に直接リテラルで記述すると隠せるけど。
問題は、make_dictproxy 側で使い方をチェック出来ない事とか。

 d = make_dictproxy({
  ...
 })

[Python] module maze

#!/usr/bin/env python

import new
from random import choice, randint
from string import ascii_lowercase

def randword(n=8):
    return ''.join([choice(ascii_lowercase) for _ in xrange(randint(1,n))])

__all_modules = []
def generate_module_maze(module, num=8, depth=0):
    if depth > 0:
        k = randint(1,num)
        for n in xrange(k):
            name = randword()
            new_module = new.module(name, '')
            __all_modules.append(new_module)
            setattr(module, name, new_module)
            generate_module_maze(new_module, num, depth-1)
        for n in xrange(num - k):
            old_module = choice(__all_modules)
            name = old_module.__name__
            setattr(module, name, old_module)

root = new.module('root')
generate_module_maze(root, depth=5)
choice(__all_modules).__doc__ = 'GOAL'
#def answer():
#    return [m for m in __all_modules if m.__doc__ == 'GOAL'][0]
del __all_modules

if __name__ == '__main__':
    import maze
    # Find the module which has docstring 'GOAL'
    print dir(maze.root)

FileField 日本語ファイル名


- 開発版(0.97pre)だとファイル名が日本語の時、ファイル名が変更されてしまう。
- メール送信(django.core.mail利用)時の添付ファイルでも同様の現象あり。

 class JFileField(models.FileField):
     def get_filename(self, filename):
         return filename.decode('utf-8') # デコードは適当

[Python][Django] dummy settings / and debug SMTP sessions

 # 初期化
 # dummy/__init__.py
 DJANGO_SETTINGS_MODULE = 'dummy.settings'
 import os
 os.environ['DJANGO_SETTINGS_MODULE'] = DJANGO_SETTINGS_MODULE
 from django.conf import settings
 settings._import_settings()
 __all__ = ['settings']
 # 設定
 # dummy/settings.py
 EMAIL_HOST = "mail.example.com"
 EMAIL_PORT = 25
 EMAIL_HOST_USER = "foo"
 EMAIL_HOST_PASSWORD = "********"
 EMAIL_USE_TSL = False
 # メール送信(debug smtp) サンプル
 import dummy
 from smtplib import SMTP
 from django.core.mail import send_mail

 SMTP.debuglevel = 1

 if __name__ == '__main__':
   send_mail("test mail", "Hello.", "me@example.com", ["you@example.net"])

[Python] ブロック・ローカルな変数

実装してみた。

from __future__ import with_statement
from contextlib import contextmanager
import inspect

@contextmanager
def lexical_scope(*args):
    frame = inspect.currentframe().f_back.f_back
    saved = frame.f_locals.keys()
    try:
        if not args: yield
        elif len(args) == 1: yield args[0]
        else: yield args
    finally:
        f_locals = frame.f_locals
        for key in (x for x in f_locals.keys() if x not in saved):
            del f_locals[key]
        del frame


if __name__ == '__main__':

    with lexical_scope(1,2,3) as (a,b,c):
        d = 4
        print a,b,c,d

    # Check, there are no 'a', 'b', 'c' and 'd' variables.
    print dir()

遅延リストを使った解

 from itertools import imap, izip, cycle

 fizz = cycle(['','','Fizz'])
 buzz = cycle(['','','','','Buzz'])

 for num,text in izip(xrange(1,101), imap(''.join,izip(fizz,buzz))):
     print text or num
  • xrange ... xrange(1,101) 1から100までの数値範囲の遅延リスト
  • cycle ... 無限リストを生成。
  • izip ... 複数のリストから要素のペアのリストを生成。(組み込み関数zipの遅延評価版)
  • imap ... リストの各要素を関数で評価した結果のリストを返す。(組み込み関数mapの遅延評価版)
  • ''.join ... 文字列を結合する関数。(string.joinだと空白が入る為、str.__add__でも可)

追記:
fizz,buzzの要素を毎回結合するよりも、
予めfizzとbuzzの各要素を結合したものをcycleで無限リストにする方が効率良い。
zip関数の生成する結果のリストは短い方のリストに長さが揃えられる点に注意。
無限リストのスライス作成にはitertoolsのislice関数を使う。
fizzbuzz = cycle(islice(imap(''.join,izip(fizz,buzz)),15))

      • -

いろんな言語での回答
http://programming.reddit.com/info/10d7w/comments