Skip to content

Instantly share code, notes, and snippets.

@alice1017
Last active May 27, 2017 02:54
Show Gist options
  • Select an option

  • Save alice1017/3aefcbb7f3ab409db6774cec9498e8ce to your computer and use it in GitHub Desktop.

Select an option

Save alice1017/3aefcbb7f3ab409db6774cec9498e8ce to your computer and use it in GitHub Desktop.
対話的な電卓プログラム(メモリー機能つき)
#!/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