Last active
May 27, 2017 02:54
-
-
Save alice1017/3aefcbb7f3ab409db6774cec9498e8ce to your computer and use it in GitHub Desktop.
対話的な電卓プログラム(メモリー機能つき)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # coding: utf-8 | |
| # Copyright (c) 2016 Hayato Tominaga | |
| # | |
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| # copies of the Software, and to permit persons to whom the Software is | |
| # furnished to do so, subject to the following conditions: | |
| # | |
| # The above copyright notice and this permission notice shall be included in all | |
| # copies or substantial portions of the Software. | |
| # | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| # SOFTWARE. | |
| # This program need the `coadlib` module: | |
| # coadlib - Console Application Development Library | |
| # https://github.com/alice1017/coadlib | |
| try: | |
| from coadlib import InteractiveApplication | |
| except ImportError: | |
| from consoleADL import InteractiveApplication | |
| description = u"""対話的な電卓プログラムです。このプログラムでは自由に演算子を | |
| 変えることができます。演算子を変える場合には、コンソールに演算子(+|-|*|/|%)を | |
| 入力してください。コンソールに何も入力せずにエンターを押すと、現在の計算結果を | |
| 出力します。""" | |
| app = InteractiveApplication( | |
| name=u"対話的電卓プログラム", | |
| desc=description, | |
| version="0.1.0", padding=4, margin=3, prefix=" > " | |
| ) | |
| app.extensions = ["+", "-", "*", "/", "%", "**" ] | |
| app.ext = "+" # default extension | |
| app.result = 0 | |
| app.memory = [] | |
| STATUS_RESULT = 0 | |
| STATUS_CONTINUE = 1 | |
| STATUS_EXIT = 2 | |
| def is_int(string): | |
| try: | |
| int(string) | |
| return True | |
| except: | |
| return False | |
| def with_ext(response): | |
| want_ext = "" | |
| for ext in app.extensions: | |
| if response.startswith(ext): | |
| want_ext = ext | |
| if want_ext == "": | |
| return False | |
| else: | |
| return True | |
| def is_memory(response): | |
| if response.startswith("memory") or response.startswith("m"): | |
| return True | |
| else: | |
| return False | |
| def calc(number): | |
| # exec 'app.result += 1' | |
| calc_cmd = "app.result {0}= {1}".format(app.ext, number) | |
| exec(calc_cmd) | |
| def memory_mode(cmd=None): | |
| def memory_clear(): | |
| app.memory = [] | |
| return STATUS_CONTINUE | |
| def sum_memory(memory): | |
| app.result = sum(app.memory) | |
| return STATUS_RESULT | |
| if len(app.memory) == 0: | |
| app.write(u"メモリーに何も登録されていません") | |
| return STATUS_CONTINUE | |
| if cmd: | |
| if cmd == "clear": | |
| return memory_clear() | |
| elif cmd == "sum": | |
| return sum_memory(app.memory) | |
| else: | |
| app.write_error(u"エラー:定義されていないmemoryコマンドです") | |
| return STATUS_CONTINUE | |
| else: | |
| app.write(u"メモリーモード:\n現在以下の数字が登録されています") | |
| for i, num in enumerate(app.memory): | |
| app.write("[{0}] {1}".format(i, num)) | |
| app.write(u"実行する内容を選択してください") | |
| app.write(u"[0] 数値を出力する") | |
| app.write(u"[1] 登録されている数値を合計する") | |
| app.write(u"[2] メモリーをクリアする") | |
| res = app.input_console("", int) | |
| if res == 0: | |
| index = app.input_console( | |
| u"出力する数字のインデックスを入力してください", int) | |
| try: | |
| result = app.memory[index] | |
| except: | |
| app.write_error(u"エラー:インデックスの範囲を超えています") | |
| return STATUS_CONTINUE | |
| app.write("{ext} ({res:,}) > {result}".format( | |
| ext=app.ext, res=app.result, result=result)) | |
| calc(result) | |
| return STATUS_CONTINUE | |
| elif res == 1: | |
| return sum_memory(app.memory) | |
| elif res == 2: | |
| return memory_clear() | |
| else: | |
| app.write_error(u"エラー:インデックスの範囲を超えています") | |
| return STATUS_CONTINUE | |
| def _input(): | |
| console_message = "{ext} ({res:,})".format(ext=app.ext, res=app.result) | |
| res = app.input_console(console_message, str, validate=False) | |
| if res == "": | |
| # 何も入力されなかったら結果を返す | |
| return STATUS_RESULT | |
| elif res == "exit": | |
| # exit: プログラムを終了する | |
| return STATUS_EXIT | |
| elif res in app.extensions: | |
| # 演算子が入力されたらapp.extを変更 | |
| app.ext = res | |
| return STATUS_CONTINUE | |
| elif is_int(res): | |
| # 整数が入力されたら計算する | |
| try: | |
| calc(int(res)) | |
| except ZeroDivisionError: | |
| app.write_error(u"エラー:ZeroDivisionError") | |
| return STATUS_CONTINUE | |
| elif with_ext(res): | |
| # 演算子と一緒に整数が入力されたら | |
| # 一時的に演算子を変更し計算する | |
| if res.startswith("**"): | |
| app.ext = res[:2] | |
| number = int(res[2:]) | |
| else: | |
| app.ext = res[0] | |
| number = int(res[1:]) | |
| calc(number) | |
| return STATUS_CONTINUE | |
| elif is_memory(res): | |
| # memoryが入力されたらメモリーモードを起動 | |
| if len(res.split()) == 1: | |
| return memory_mode() | |
| elif len(res.split()) >= 2: | |
| # "memory コマンド"でもメモリーモードを起動できる | |
| # コマンドは(sum|clear) | |
| # if: 'memory clear' -> cmd: clear | |
| cmd = res.split()[1] | |
| return memory_mode(cmd) | |
| else: | |
| app.write_error(u"エラー:認識できない文字列です") | |
| return STATUS_CONTINUE | |
| def add_memory(): | |
| res = int(app._input(u"メモリーに登録しますか? (yes:1/no:2)")) | |
| if res == 1: | |
| app.memory.append(app.result) | |
| app.write(u"登録しました") | |
| return True | |
| elif res == 2: | |
| app.write("") | |
| return False | |
| else: | |
| return False | |
| def main(): | |
| inloop_flag = True | |
| while inloop_flag == True: | |
| result_status = _input() | |
| if result_status == STATUS_RESULT: | |
| app.write(u"合計:{:,}".format(app.result)) | |
| add_memory() | |
| app.ext = "+" | |
| app.result = 0 | |
| continue | |
| elif result_status == STATUS_CONTINUE: | |
| continue | |
| elif result_status == STATUS_EXIT: | |
| inloop_flag = False | |
| return 0 | |
| if __name__ == "__main__": | |
| app.write_usage() | |
| try: | |
| app.exit(main()) | |
| except KeyboardInterrupt: | |
| app.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment