質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3571閲覧

電卓ソフトについて

szbhdulla

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/01/13 21:20

編集2017/01/15 10:37

###前提・実現したいこと
Pythonは自然言語の解析がシやすいと聞いて、一昨日からPythonの勉強を始めたので出来る限り自然に入力出来る電卓のプログラムを作りました。現在は、、、

  • 四則演算のみ
  • 正の数のみ扱える
  • ()は使えない
  • 0除算の対処も一応しました
  • 計算式を読み取る

といったことまでは出来るのですが、現段階でどのようなところを改善すれば良いでしょうか?

また、Pythonでの注意点などがあれば教えていただきたいです。

###該当のソースコード

python

1#coding: utf-8 2 3import sys 4form = input().rstrip() 5 6opePluMin = [] #+と-をいれる 7opeProDiv = [] #*と/をいれる 8 9#符号をsearchする 10for target in ['+','-','*','/']: 11 index = -1 12 while True: 13 index = form.find(target, index+1) 14 if index == -1: 15 break 16 if (target=='+' or target=='-'): 17 opePluMin.append(index) 18 if (target=='*' or target=='/'): 19 opeProDiv.append(index) 20 21#並び替える 22opePluMin.sort() 23opeProDiv.sort() 24 25#符号場所一覧 26opeNum = opePluMin+opeProDiv 27opeNum.sort() 28 29#print(opePluMin) 30#print(opeProDiv) 31#print(opeNum) 32 33#データをストック 34data = [] 35j = 0 36for i in range(len(opeNum)): 37 data.append(int(form[j:opeNum[i]])) 38 j = opeNum[i]+1 39data.append(int(form[j:])) 40#print(data) 41 42#乗除算処理 43for i in opeProDiv: 44 #opeNum中のアドレス 45 opeAdd = opeNum.index(i) 46 #実際の演算子 47 sign = form[i] 48 if sign=='*': 49 data[opeAdd] *= data[opeAdd+1] * 1.0 50 elif sign=='/': 51 try: 52 data[opeAdd] /= data[opeAdd+1] * 1.0 53 except ZeroDivisionError: 54 print("ZeroDivisionError!!") 55 exit() 56 del data[opeAdd+1] 57 del opeNum[opeAdd] 58# print(data) 59 60 61#和差処理 62for i in opePluMin: 63 sign = form[i] 64 if sign=='+': 65 data[0] += data[1] 66 elif sign=='-': 67 data[0] -= data[1] 68 del data[1] 69# print(data) 70 71print(">> " + str(data[0])) 72

###試したこと
出来る限りの計算をしてエラーが出ないか確かめました

###補足情報(言語/FW/ツール等のバージョンなど)
言語 Python 3
OS archlinux

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sharow

2017/01/14 01:12

インデントが崩れています。おそらくソースにタブ文字とスペースが混在していて、タブ文字だけが抜けているのではないでしょうか。タブ文字は環境によってはうまくコピペできなかったり、勝手にスペースに変換されたりします。(PythonのPEP8:スタイルガイドではスペースを使うことを推奨しています)
guest

回答2

0

ベストアンサー

電卓の入力は「自然言語」というわけではないですが、それはともかく回答します。


ご質問のコードでは、機能拡張が難しいです。たとえば、お手もとの (リアルな) 電卓の取説には「数字 [] [] [=]」なんていう操作が書いてあったりしませんか。ご質問のコードでこの操作ができるようにするには、プログラムの全体に手を入れないといけなくなります。

拡張しやすくするには、プログラムを次の3つの層に分割して作るといいです。

  1. トークナイザ: 入力から、意味のある記号 (トークン) を取り出して一つずつ返す。
  2. パーサ: トークンを一つ一つ受け取って、トークンの組み合わせから処理を決める。
  3. 処理: 実際に計算をし、結果を出力する。

トークンは+-などの記号、数字 (1文字とは限らない) などです。関数電卓にするのならcoslnなどもいりますね。Pythonのマニュアルにトークナイザの書き方の例が載っています。

パーサは、簡単に言うと電卓の言語の「文法」を決めます。パーサは内部状態を持っていて、トークンを一つ読み込むたびに、トークンの種類によって決まる新たな内部状態に移ります。内部状態によって、次にどんな処理をするかを決めています。ご質問のコードではopePluMinopeProDivという変数が、パーサの内部状態に当たります (上のリアルな電卓の例を見ると、この部分は改良の余地がありそうです)。

処理は、トークナイザやパーサ以外の部分です。電卓の場合、アキュムレータ (結果を保存する変数) があって、アキュムレータの値に対して処理をした結果をまたアキュムレータに格納するようになっています。どんな処理をするかはパーサで決定ずみですから、処理の種類別にアキュムレータの操作方法を定義した関数を用意すればいいはずです。

以上のようなことを意識してプログラムを書けば、拡張性の高いプログラムになるはずです。参考になれば。

投稿2017/01/14 08:28

ikedas

総合スコア4227

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

小数、負の数値、多重括弧、組み込み関数(sinなど)、変数代入、変数参照、関数定義、関数利用などです。

投稿2017/01/13 23:58

hikochang

総合スコア648

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問