月別アーカイブ: 4月 2010

[GoF]Singletonパターンをpythonで書いてみた

Singletonパターンをpython2.6で書いてみた。
初回のみインスタンス生成する。
この部分が、マルチスレッドではうまくいかないかもしれない?
(複数のスレッドから同時アクセスしたいなら、あらかじめ生成しておくべきか)

# -*- coding: utf-8 -*-

class Senario(object): # これがsingletonなクラス。某エロゲ会社を想定。
    __writer = None
    
    def __new__(cls):
        return object.__new__(cls)
    
    @classmethod
    def get_instance(cls): # 実体を取得します。
        if cls.__writer is None:
            cls.__writer = cls()
        return cls.__writer # シナリオライターを返却。
    
    instance = property(get_instance)

            
if __name__ == "__main__":
    (abisubouto, darekare) = (None, None) # 2本のソフトがあります
    abisubouto = Senario.instance # シナリオ取得その1
    darekare = Senario.instance # シナリオ取得その2        
    # この時点で、阿鼻巣暴徒==誰彼が成立します。
    
    if abisubouto is darekare:
        print("同じ")
    else:
        print("違う")
    assert abisubouto is darekare

__metaclass__を使う方法もあるようだ。
実用するならこっちのがいいかも。

# -*- coding: utf-8 -*-

class Singleton(type):
    '''
    以下のサイトで紹介されている実現方法を参考にした。
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412551
    
Python で Singleton/シングルトン パターン
''' def __init__(self, *args): type.__init__(self, *args) self._instance = None def __call__(self, *args): if self._instance is None: self._instance = type.__call__(self, *args) return self._instance class Senario(object): # これがsingletonなクラス。某エロゲ会社を想定。 __metaclass__ = Singleton # このクラスをSingletonベースにする意味? def __init__(self, *args): self.__writer = "chou sensei" def get_instance(self): return self.__writer instance = property(get_instance) if __name__ == "__main__": (abisubouto, darekare) = (None, None) # 2本のソフトがあります abisubouto = Senario().instance # シナリオ取得その1 darekare = Senario().instance # シナリオ取得その2 # この時点で、阿鼻巣暴徒==誰彼が成立します。 if abisubouto is darekare: print("同じ") else: print("違う") assert abisubouto is darekare

参考にしたサイト:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412551
http://memo.jj-net.jp/154

[GoF]FactoryMethodパターンをpythonで書いてみた

FactoryMethodパターンをpython2.6で書いてみた。
__metaclass__にabcを指定して抽象クラスを実現。
具象クラスで抽象メソッドを実装していないと、実行エラーになるようになる。

# -*- coding: utf-8 -*-

import abc # クラス抽象化を行うためのモジュール(requires python2.6 or later)


class System3p9(object): # 製品です
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def h_scene(self): # エロゲ必須要素
        pass # return ハァハァ


class Alicesoft(object): # 作成者です
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def create(self): # SYSTEM3.9なゲームを作ります
        pass # return System3p9


class Tsumamigui(System3p9): # 具体的作成者(作成者を継承)
    
    def __init__(self):
        pass
    
    def h_scene(self): # えちシーンを"実装"します。
        return Hitoduma()


class Staff(Alicesoft): # 具体的作成者(作成者を継承)
    
    def __init__(self):
        pass
    
    def create(self):
        return Tsumamigui() # SYSTEM3.9なゲームを"実際に"作ります。


class Hitoduma(object):
    
    def __init__(self):
        pass
    
    def __str__(self):
        return u"人妻で(;´Д`)ハァハァ"


if __name__ == "__main__":
    
    eroge = Staff().create()
    print(eroge.h_scene())
    

[GoF]TemplateMethodパターンをpythonで書いてみた

TemplateMethodパターンをpython2.6で書いてみた。
pythonにはenumがないので、ネットで調べて知ったテクニックを使ってenumの代替を実現している。

# -*- coding: utf-8 -*-

class Struct(object):
    def __init__(self, **entries):
        self.__dict__.update(entries) # ハッシュマップ作成

Enum = Struct
Looklike = Enum(loli=u"ロリ", adult=u"おとな") # 見た目


class Hajirusu(object): # これがテンプレ
    __age = 18 # 祖父倫対策
    __looklike = Looklike.loli # お兄ちゃん直撃
    
    def __init__(self):
        pass
        
    def get_age(self):
        return Hajirusu.__age
    
    def get_looklike(self):
        return Hajirusu.__looklike

    age = property(get_age)
    looklike = property(get_looklike)
    

class Shiorichan(Hajirusu): # はじるすを継承
    __name = u"しおり"   # しおりちゃん実装
    
    def __init__(self):
        super(Shiorichan, self).__init__()
        
    def get_name(self):
        return Shiorichan.__name
    
    def get_age(self):
        return super(Shiorichan, self).age

    def get_looklike(self):
        return super(Shiorichan, self).looklike
    
    name = property(get_name)
    age = property(get_age)
    looklike = property(get_looklike)


class Saorichan(Hajirusu): # はじるすを継承
    __name = u"さおり"   # さおりちゃん実装
    
    def __init__(self):
        super(Saorichan, self).__init__()
        
    def get_name(self):
        return Saorichan.__name
        
    def get_age(self):
        return super(Saorichan, self).age

    def get_looklike(self):
        return super(Saorichan, self).looklike
    
    name = property(get_name)
    age = property(get_age)
    looklike = property(get_looklike)


if __name__ == "__main__":
    
    heroines_list = [Shiorichan(), Saorichan()]
    
    print(u"めいぼ")
    for heroine in heroines_list:
        print(u"なまえ:{0} ねんれい:{1}さい みため:{2}".
              format(heroine.name, heroine.age, heroine.looklike))

[GoF]Adaptorパターンをpythonで書いてみた

Adaptorパターンをpython2.6で書いてみた。

# -*- coding: utf-8 -*-

class ErogeCD(object):
    def __init__(self, name):
        self.__name = name
    
    def __str__(self):
        return self.__name


class RenewalErogeDVD(object):
    def __init__(self, cd):
        self.__cd = cd
                
    def __str__(self):
        return str(self.__cd)
    

class Nekonekosoft(object):
    def __init__(self):
        pass
    
    def sell_cd(self, name):
        return ErogeCD(name) # エロゲCD「みずいろ」を生成
    
    def sell_renewaldvd(self, cd):
        return RenewalErogeDVD(cd) # DVD版を再販します
    
    
if __name__ == "__main__":
    
    maker = Nekonekosoft()
    
    mizuiro_cd = maker.sell_cd(u"みずいろ")
    print(u"CD版 {0}".format(mizuiro_cd))
    
    mizuiro_dvd = maker.sell_renewaldvd(mizuiro_cd)
    print(u"DVDリニューアル版 {0}".format(mizuiro_dvd))
    

[GoF]Iteratorパターンをpythonで書いてみた

Iteratorパターンをpython2.6で書いてみた。

# -*- coding: utf-8 -*-

class Eroge(object):
    def __init__(self, name):
        self.__name = name
    
    def __str__(self):
        return self.__name


class ErogeShelf(object):
    def __init__(self):
        self.__games = []
        self.__last = 0
    
    def __iter__(self):
        return ErogeShelfIterator(self)
    
    def __len__(self):
        return self.__last

    def append(self, eroge):
        self.__games.append(eroge)
        self.__last += 1
    
    def eroge_at(self, i):
        return self.__games[i]
    
        
class ErogeShelfIterator(object):
    def __init__(self, erogeshelf):
        self.__erogeshelf = erogeshelf
        self.__index = 0
    
    def next(self):
        if self.__hasnext():
            eroge = self.__erogeshelf.eroge_at(self.__index)
            self.__index += 1
            return eroge
        else:
            raise StopIteration

    def __hasnext(self):
        return True if (len(self.__erogeshelf) > self.__index) else False
    

if __name__ == "__main__":
    
    erogeshelf = ErogeShelf()
    erogeshelf.append(Eroge(u"君望"))
    erogeshelf.append(Eroge(u"はじるす"))
    erogeshelf.append(Eroge(u"水月"))
    erogeshelf.append(Eroge(u"みずいろ"))
        
    myeyes = iter(erogeshelf) # マイコレクションをCheck it!
    
    # 外部イテレータとして
    while True: # 目先に何かある間、ループします。
        try:
            if str(myeyes.next()) == u"はじるす": # ロリハケーン!
                print(u"(;´Д`)ハァハァ") # ハァハァ
        except StopIteration:
            # 要素が残っていないならば、
            # next()はStopIteration例外を発生させる
            break
    
    # 内部イテレータとして
    for eroge in erogeshelf:
        if str(eroge) == u"はじるす":
            print(u"(;´Д`)ハァハァ") # ハァハァ

リストを使う場合は、これで十分。

# -*- coding: utf-8 -*-

if __name__ == "__main__":
    
    # リストの場合
    erogeshelf =  [u"君望", u"はじるす", u"水月", u"みずいろ"] # 悲惨な棚があります。    
    
    # 外部イテレータとして
    myeyes = iter(erogeshelf) # マイコレクションをCheck it!

    while True: # 目先に何かある間、ループします。
        try:
            if str(myeyes.next()) == u"はじるす": # ロリハケーン!
                print(u"(;´Д`)ハァハァ") # ハァハァ
        except StopIteration:
            # 要素が残っていないならば、
            # next()はStopIteration例外を発生させる
            break
    
    # 内部イテレータとして
    for eroge in erogeshelf:
        if str(eroge) == u"はじるす":
            print(u"(;´Д`)ハァハァ")

[GoF]GoFデザインパターンをpythonで書いてみる

今更ながら、「エロゲで学ぶデザインパターン」(http://home.1555.info/pukiwiki/index.php?エロゲで学ぶデザインパターン)に触発されて、
これまた今更マスターしようと思っているpythonで、
デザインパターンの復習とpythonの練習をかねて書いてみる。
元ネタは実行できるように書かれていない(コードが長くなるから?)が、
ここではあえて実行できる形にするつもり。

つづく

LinkStationHG(Debian化済み)にSubversionを導入する

Debian化したLinkStationHGにSubversionを導入する。
今後は、Subversionサーバとして活用していく。
 
以下に、その手順を記録する。
 

1. Apache2の導入 
 
 (1) Apache2を入れる
   # aptitude install apache2 apache2-doc
 
 (2) WEBブラウザでアクセスできる事を確認する
 
 
2. Subversionの導入と設定
 
 (1) Subversionを入れる
   # aptitude install subversion subversion-tools libapache2-svn
 
 (2) Apache2の設定をSubversionに対応するように変更する
   # nano /etc/apache2/mods-available/dav_svn.conf
    <Location /svn>
     # Uncomment this to enable the repository
     DAV svn
     SVNParentPath /mnt/svn
  
     Options Indexes
     Order allow,deny
     allow from all
     
     AuthType Basic
     AuthName "Subversion Repository"
     AuthUserFile /etc/apache2/dav_svn.passwd
     <LimitExcept GET PROPFIND OPTIONS REPORT>
      Require valid-user
     </LimitExcept>
 
    </Location>
 
 (3) モジュールを使うように設定する

   # a2enmod dav_svn

 
 (4) 認証用のパスワードファイルを作成する

   # htpasswd -c /etc/apache2/dav_svn.passwd [username]

 
 (5) Apache2を再起動する

   # /etc/init.d/apache2 restart

 
 (6) Subversion用のディレクトリを作成する
   # mkdir /mnt/svn
   # chmod 770  /mnt/svn
  
 (7) Subversion用のリポジトリを作成する
   # mkdir /mnt/svn/[リポジトリ名]
   # chown -R www-data:www-data /mnt/svn
   # svnadmin create /mnt/svn/[リポジトリ名]
   # chown -R www-data:www-data /mnt/svn
   # svn mkdir -m ‘setup trunk’ http://localhost/svn/[リポジトリ名]/trunk
   # svn mkdir -m ‘setup branches’ http://localhost/svn/[リポジトリ名]/branches
   # svn mkdir -m ‘setup tags’ http://localhost/svn/[リポジトリ名]/tags
  
 (8) Subversionのlsで確認する
 
 
3. 動作の確認
 
 (1) WEBブラウザから確認する
 
 (2) SVNクライアント(TortoiseSVNなど)から確認する
 
 
 

LinkStationHGをdebian化する

LinkStationHGが退役して、もう半年になった。
はっきりいってもう用済みだが、捨てるのはもったいないし、だからといって売り物にもならない。
 
そこで、Debian化してしまうことにした。
 
以下に、その手順を記録する。
 
注意:
 LinkStationHGはLAN経由でパーティションを切り直せない。さらに、システム用は376MBくらいしかない。
 ちょっとしたシステムソフトをインストールするだけで、すぐにいっぱいになる。
 
 
参考:
 LinkStationHGをわざわざDebian化する技 (http://www10.plala.or.jp/ariel-h/linkstation/)
 

1. 準備
 
 (1) Buffalo社から最新ファームウェアファイル(今回の場合は HD-HGLAN_Fw169b)をダウンロードする
 
 (2) 玄箱/HG用のDebianイメージファイルをダウンロードする
  イメージファイルをダウンロードできるサイト → http://www.revulo.com/kuro-box/Debian/Install.html
  イメージファイル名(今回の場合)      → debian-etch-2.6.25.1-kuroHG-20090317.tgz
 
 (3) LinkStationを分解して内蔵HDDのパーティションを全部削除する
 
 (4) イメージファイルを加工する
  [手順1] イメージファイル名を tmpimage.tgz にリネームする
  [手順2] tmpimage.tgz をZIP圧縮して image.dat にリネームする
  [手順3] 最新ファームウェアファイルの同名ファイルに上書きする
 
 (5) クロスケーブル(または独立したネットワーク)でPCとLinkStationを接続して以下のようにPCのネットワーク情報を設定する
  [PCのネットワーク情報]
    IPアドレス           → 192.168.11.1
    サブネットマスク        → 255.255.255.0
    デフォルトゲートウェイアドレス → 192.168.11.1
 

2. Debian化
 
 (1) Buffalo社からダウンロードした最新ファームウェアファイルに同梱されている HD-HGLAN FWUpdate.exe を実行する
 
 (2) LinkStationを検索してファームウェア更新が実行されるのでしばらく待つ
 
 (3) 「ファームウェアの更新に失敗しました。」と表示されたら成功
 
 (4) LinkStationに接続するためにPCのネットワーク情報を設定する
  [PCのネットワーク情報]
    IPアドレス           → 192.168.0.XXX (100はLinkStationのIPアドレスなので除外)
    サブネットマスク        → 255.255.255.0
    デフォルトゲートウェイアドレス → 192.168.0.XXX (100はLinkStationのIPアドレスなので除外)
 
 (5) LinkStationにtelnet接続してログイン
  [LinkStationのネットワーク情報]
    IPアドレス    → 192.168.0.100
 
  [LinkStationのログイン情報]

    ログインユーザ名 → tmp-kun

    パスワード    → tmp-kun
 

3. 各種設定変更
 
 (1) rootのパスワード変更

    Password: root
    # passwd
    ログアウトして確認
 
 (2) ユーザ追加
    # useradd [username]
    # passwd [username]
    ログアウトして確認
 
 (3) デフォルトユーザ削除 
    # userdel tmp-kun
 
 (4) ネットワーク設定
    $ su
    # nano /etc/hosts
     192.168.0.100  KURO-BOX  ←  変更する(ex. 192.168.2.100  KURO-BOX)
    
    # nano /etc/hosts.allow
     ALL: 192.168.0.0/255.255.0.0  ←  変更する(ex. ALL: 192.168.2.0/255.255.255.0)
    
    # nano /etc/resolv.conf
     nameserver 192.168.0.1  ←  変更する(ex. 192.168.2.1)
    
    # nano /etc/network/interfaces
     address  192.168.0.100  ←  変更する(ex. 192.168.2.100)
     network  192.168.0.0  ←  変更する(ex. 192.168.2.0)
     broadcast  192.168.0.255  ←  変更する(ex. 192.168.2.255)
     gateway  192.168.0.1  ←  変更する(ex. 192.168.2.1)

4. 設定後の動作確認
 
 (1) LinkStationの電源長押しで電源OFF出来る事を確認
 
 (2) LinkStationが電源ON出来る事を確認
 
 (3) LinkStationを導入したいネットワークにつなげてログインできる事を確認
 
 
5. Debianのアップグレードとssh導入
 
 (1) パッケージリストを最新にする
    # aptitude update
 (2) インストール済みのパッケージをアップグレードする
    # aptitude upgrade
 (3) sshを入れる
    # aptitude install ssh
 
 (4) sshでログインしなおしてからtelnetを削除する
    # aptitude purge telnetd telnet