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

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

ただいまの
回答率

90.49%

  • Python

    8019questions

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

  • Python 3.x

    6431questions

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

電卓ソフトについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 904

szbhdulla

score 9

前提・実現したいこと

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

  • 四則演算のみ
  • 正の数のみ扱える
  • ()は使えない
  • 0除算の対処も一応しました
  • 計算式を読み取る
    といったことまでは出来るのですが、現段階でどのようなところを改善すれば良いでしょうか?

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

該当のソースコード

#coding: utf-8

import sys
form = input().rstrip()

opePluMin = []    #+と-をいれる
opeProDiv = []    #*と/をいれる

#符号をsearchする
for target in ['+','-','*','/']:
    index = -1
    while True:
        index = form.find(target, index+1)
        if index == -1:
            break
        if (target=='+' or target=='-'):
            opePluMin.append(index)
        if (target=='*' or target=='/'):
            opeProDiv.append(index)

#並び替える
opePluMin.sort()
opeProDiv.sort()

#符号場所一覧
opeNum = opePluMin+opeProDiv
opeNum.sort()

#print(opePluMin)
#print(opeProDiv)
#print(opeNum)

#データをストック
data = []
j = 0
for i in range(len(opeNum)):
    data.append(int(form[j:opeNum[i]]))
    j = opeNum[i]+1
data.append(int(form[j:]))
#print(data)

#乗除算処理
for i in opeProDiv:
    #opeNum中のアドレス
    opeAdd = opeNum.index(i)
    #実際の演算子
    sign = form[i]
    if sign=='*':
        data[opeAdd] *= data[opeAdd+1] * 1.0
    elif sign=='/':
        try:
            data[opeAdd] /= data[opeAdd+1] * 1.0
        except ZeroDivisionError:
            print("ZeroDivisionError!!")
            exit()
    del data[opeAdd+1]
    del opeNum[opeAdd]
#    print(data)


#和差処理
for i in opePluMin:
    sign = form[i]
    if sign=='+':
        data[0] += data[1]
    elif sign=='-':
        data[0] -= data[1]
    del data[1]
#    print(data)

print(">> " + str(data[0]))

試したこと

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

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

言語 Python 3
OS   archlinux

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • sharow

    2017/01/14 10:12

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

    キャンセル

  • szbhdulla

    2017/01/15 19:37

    修正しました

    キャンセル

回答 2

checkベストアンサー

+3

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


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

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    Pythonの処理速度について

    処理速度に関して、Pythonの処理が並んでいるのを発見しました。 https://wiki.python.org/moin/TimeComplexity 多くはO(1)の

  • 解決済

    【Python】標準入出力におけるリスト格納について

    前提・実現したいこと ここに質問したいことを詳細に書いてください (例)PHP(CakePHP)で●●なシステムを作っています。 ■■な機能を実装中に以下のエラーメッセージが

  • 受付中

    python FizzBuzz

    こんにちは。Pythonのプログラムに関する質問ですが、 変数xの値が 3の倍数ならfizz 5の倍数ならbuzz 15の倍数ならfizzbuzz するプログラムを作って

  • 受付中

    ターミナルで実行するのに時間がかかりすぎる

    ターミナルで実行するのに時間がかかりすぎます。 画像圧縮のアルゴリズムを書いています。 N × N ピクセルのグレースケール画像があり各ピクセルの画素値は 0 から 255

  • 解決済

    文字列を比較して配列に格納できない

    ans配列の要素の文字列の最初の文字がlinesの要素の最初の文字と一致するならlinesの2番目の要素('A'/'B'/'C'/'D')をline_alpha配列に格納する、とい

  • 解決済

    配列の要素のインデックスが取れない

    配列の要素を2つ削除できないです。 lines = [3, 4, 0, 1, 8, 2, 7, 3, 10, 2, 7, 0, 10, 10, 10, 9, 1, 3] fo

  • 解決済

    python 文字列を判定する方法

    何らかのstr型が連続して格納されている配列(例['100'],['.'],['abc'])の各要素を判定し、数値ならint型に変換後次要素の判定に移る、数値ではないのであればfa

  • 解決済

    python path 条件を指定し、抜きだし

    1803/H28-6m/XBRL/1803_H28-6m_4Q.xbrl 1803/H29-3m/XBRL/1803_H29-3m_4Q.xbrl 1803/H29-6m/XBRL

同じタグがついた質問を見る

  • Python

    8019questions

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

  • Python 3.x

    6431questions

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