developerWorks の記事にある Python コードを修正してみた
IBM が運営している技術サイト developerWorks には Python の記事がちょくちょく載っているんだけど、Python コードのインデントが崩れていて大変悲しい (最初は日本語版だけかなと思ったら、もとの原文からしてインデントが崩れまくってた)。
そこで、勝手ながら崩れたインデントを修復してみた。今回のターゲットは次の記事。
元記事のインデントがどのくらい崩れているかというと、こんな感じ。ひどいでしょ?
ところで、この記事は2000年に書かれており、Python コードとしては古い書き方をしていた。そこでインデントを修復するだけでなく、より新しい書き方に変更してみた。具体的には、以下のような変更を行っている。
- 1/0 ではなく True/False を使う
- 親クラスを省略せずに object を指定する
- raise の引数を文字列ではなく Exception オブジェクトにする
- string モジュールを使わず、かわりに文字列メソッドを使う
それではインデント修復版をどうぞ。
# -*- coding: utf-8 -*- ## from http://www.ibm.com/developerworks/jp/linux/library/l-python-state/#N101C3 ## ファイル名: statemachine.py class StateMachine(object): def __init__(self): self.handlers = {} self.startState = None self.endStates = [] def add_state(self, name, handler, end_state=False): name = name.upper() self.handlers[name] = handler if end_state: self.endStates.append(name) def set_start(self, name): self.startState = name.upper() def run(self, cargo): try: handler = self.handlers[self.startState] except: raise Exception("must call .set_start() before .run()") if not self.endStates: raise Exception("at least one state must be an end_state") while True: newState, cargo = handler(cargo) if newState.upper() in self.endStates: break else: handler = self.handlers[newState.upper()]
#ここで「cargo」というのは「積み荷」という意味。
#現在の状態から次の状態へ渡す値のことを指している。
もうひとつ。
# -*- coding: utf-8 -*- ## http://www.ibm.com/developerworks/jp/linux/library/l-python-state/#N1026A ## ファイル名: statemachine_test.py from statemachine import StateMachine def ones_counter(val): print "ONES State: ", while True: if val <= 0 or val >= 30: newState = "Out_of_Range" ; break elif 20 <= val < 30: newState = "TWENTIES"; break elif 10 <= val < 20: newState = "TENS"; break else: print " @%2.1f+" % val, val = math_func(val) print " >>" return (newState, val) def tens_counter(val): print "TENS State: ", while True: if val <= 0 or val >= 30: newState = "Out_of_Range"; break elif 1 <= val < 10: newState = "ONES"; break elif 20 <= val < 30: newState = "TWENTIES"; break else: print " #%2.1f+" % val, val = math_func(val) print " >>" return (newState, val) def twenties_counter(val): print "TWENTIES State:", while True: if val <= 0 or val >= 30: newState = "Out_of_Range"; break elif 1 <= val < 10: newState = "ONES"; break elif 10 <= val < 20: newState = "TENS"; break else: print " *%2.1f+" % val, val = math_func(val) print " >>" return (newState, val) def math_func(n): from math import sin return abs(sin(n))*31 if __name__== "__main__": m = StateMachine() m.add_state("ONES", ones_counter) m.add_state("TENS", tens_counter) m.add_state("TWENTIES", twenties_counter) m.add_state("OUT_OF_RANGE", None, end_state=True) m.set_start("ONES") m.run(1)
しかしこのコード、あんまりうまくないよな。こんなレベルのコードを掲載するのは developerWorks としてはどうなの?