呼称: テキストデータをコンソールに表示するスライドショウ 第1版
目的: プレゼンでコーディングデモをスムーズに行うツールを開発する
特徴: ファイルを読み込んで標準出力へ出力する
用例: 特になし
備考: 第1版は cat コマンドのようなもの
JUS の Haskell 勉強会で id:nobsun が説明されていたスライドショウのツールを python で作成してみることにしました。いきなり最終形を作るのではなく、段階的に機能を追加して開発するスタイルがおもしろいなと感じました。私もそれを踏襲してやってみます。おそらく標準モジュールだけで作成できそうな気がするので、python3 で挑戦してみます。
実際は、普通にコーディングして、その後で 2to3 で変換しているだけです(^ ^;;
#!/usr/bin/env python """ SlideShow 01 with Python3 """ import sys ######################################################################### # Exit Status Value ######################################################################### status = [ 'normal' , 'invalid_args' , 'open_file' ] ######################################################################### # Script Main ######################################################################### def main(): try: check_option() f = open_file(sys.argv[1], 'r', True) for line in f: print(line, end='') f.close() except OptionError as err: sys.exit(status.index(err.status)) except EnvError as err: sys.exit(status.index(err.status)) sys.exit(status.index('normal')) ######################################################################### # Functions ######################################################################### def check_option(): if len(sys.argv) < 2: raise OptionErrorUsage('invalid arguments') def open_file(file, mode, do_exit=None): try: f = open(file, mode) except IOError as err: f = Null() if do_exit: raise EnvErrorOpenFile(err) return f ######################################################################### # Class Definition ######################################################################### class Null(object): def __new__(cls, *args, **kwargs): # Singleton for 1 instance if '_inst' not in vars(cls): cls._inst = super(Null, cls).__new__(cls, *args, **kwargs) return cls._inst def __init__(self, *args, **kwargs): pass def __call__(self, *args, **kwargs): return self def __repr__(self): return 'Null()' def __iter__(self): return iter(()) def __bool__(self): return False def __getattr__(self, name): return self def __setattr__(self, name): return self def __delattr__(self, name): return self ######################################################################### # Exceptions ######################################################################### class MyError(Exception): """Base class for all exceptions""" def __init__(self, msg, value=None): self.status = value if msg: sys.stderr.write('%s\n' % (msg)) class OptionError(MyError): pass class OptionErrorUsage(OptionError): def __init__(self, msg): OptionError.__init__(self, msg, 'invalid_args') self.usage() def usage(self): print("Usage: %s filename" % (sys.argv[0])) class EnvError(MyError): pass class EnvErrorOpenFile(EnvError): def __init__(self, err): msg = 'Cannot open: %s' % (err.filename) EnvError.__init__(self, msg, 'open_file') if __name__ == '__main__': main()
実行結果。
$ python3.0 SlideShow01_30.py t.txt a bb ccc dddd eeeee $ python3.0 SlideShow01_30.py invalid arguments Usage: SlideShow01_30.py filename $ python3.0 SlideShow01_30.py detarame Cannot open: detarame
2to3 による diff 出力。
--- SlideShow01_26.py (original) +++ SlideShow01_26.py (refactored) @@ -22,11 +22,11 @@ check_option() f = open_file(sys.argv[1], 'r', True) for line in f: - print line, + print(line, end='') f.close() - except OptionError, err: + except OptionError as err: sys.exit(status.index(err.status)) - except EnvError, err: + except EnvError as err: sys.exit(status.index(err.status)) sys.exit(status.index('normal')) @@ -36,15 +36,15 @@ ######################################################################### def check_option(): if len(sys.argv) < 2: - raise OptionErrorUsage, 'invalid arguments' + raise OptionErrorUsage('invalid arguments') def open_file(file, mode, do_exit=None): try: f = open(file, mode) - except IOError, err: + except IOError as err: f = Null() if do_exit: - raise EnvErrorOpenFile, err + raise EnvErrorOpenFile(err) return f ######################################################################### @@ -59,7 +59,7 @@ def __call__(self, *args, **kwargs): return self def __repr__(self): return 'Null()' def __iter__(self): return iter(()) - def __nonzero__(self): return False + def __bool__(self): return False def __getattr__(self, name): return self def __setattr__(self, name): return self def __delattr__(self, name): return self @@ -80,7 +80,7 @@ OptionError.__init__(self, msg, 'invalid_args') self.usage() def usage(self): - print "Usage: %s filename" % (sys.argv[0]) + print("Usage: %s filename" % (sys.argv[0])) class EnvError(MyError): pass class EnvErrorOpenFile(EnvError):