1

1+2*3-4/5 のような基本的な 4 つの演算子を使用して式を解決できる電卓を作成しようとしていますが、機能せず、何が問題なのかわかりません。私のコードを確認してください。私がそれを実行すると、8行で無限の数のエラーが発生します。return ret(parts[0]) * ret(parts[2]) コードは次のとおりです

def ret(s):
    s = str(s)
    if s.isdigit():
        return float(s)
    for c in ('*','/','+','-'):
        parts = s.partition(c)
        if c == '*':
            return ret(parts[0]) * ret(parts[2])
        elif c == '/':
            return ret(parts[0]) / ret(parts[2])
        elif c == '+':
            return ret(parts[0]) + ret(parts[2])
        elif c == '-':
            return ret(parts[0]) - ret(parts[2])
print(ret('1+2'))

エラーのトレースバックは次のように終了します。

  File "C:\Python33\calc.py", line 8, in ret
    return ret(parts[0]) * ret(parts[2])
  File "C:\Python33\calc.py", line 2, in ret
    s = str(s)
RuntimeError: maximum recursion depth exceeded while calling a Python object
4

9 に答える 9

1

入力文字列は関係なく分割し、演算子がそこにあるかどうかを確認することはありません。.partition()入力にパーティション文字が存在しない場合は、空の文字列を返します。

 >>> '1+1'.partition('*')
 ('1+1', '', '')

したがって、呼び出すことはできますが、そのような演算子が存在するかどうかs.partition('*')決して確認しないでください。その結果、。が無条件に呼び出されます。存在するかどうかに関係なく、常に電話をかけます。ret()ret(parts[0]) * ret(parts[2])*s

解決策は、最初に演算子をテストするか、の戻り値を確認することです.partition()。後者はおそらく最も簡単です:

for c in ('+','-','*','/'):
    parts = s.partition(c)
    if parts[1] == '*':
        return ret(parts[0]) * ret(parts[2])
    elif parts[1] == '/':
        return ret(parts[0]) / ret(parts[2])
    elif parts[1] == '+':
        return ret(parts[0]) + ret(parts[2])
    elif parts[1] == '-':
        return ret(parts[0]) - ret(parts[2])

演算子の順序を逆にしたことに注意してください。はい、足し算と引き算の前に掛け算と割り算を適用する必要がありますが、ここでは逆に作業しています。式を小さな部分に分割し、部分式が処理されたときに操作が適用されます。

割り当ての解凍を使用して、の3つの戻り値.partition()をより簡単な名前に割り当てることができます。

for c in ('+','-','*','/'):
    left, operator, right = s.partition(c)
    if operator == '*':
        return ret(left) * ret(right)
    elif operator == '/':
        return ret(left) / ret(right)
    elif operator == '+':
        return ret(left) + ret(right)
    elif operator == '-':
        return ret(left) - ret(right)

次に、算術演算と同じ演算を実行する関数を備えたモジュールを使用して、これらすべてを単純化できます。マップは次のことを行う必要があります。operator

import operator
ops = {'*': operator.mul, '/': operator.div, '+': operator.add, '-': operator.sub}

for c in ('+','-','*','/'):
    left, operator, right = s.partition(c)
    if operator in ops:
        return ops[operator](ret(left), ret(right))
于 2013-02-27T10:23:41.493 に答える
1

あなたが間違っている主なことはc、分割された演算子ではなく値をチェックしていることです。実際の操作に left と right を使用することで、結果をアンパックしs.partitionて少し簡単にすることもできます。

def ret(s):
    s = str(s)
    if s.isdigit():
        return float(s)
    for c in ('-','+','*','/'):
        left, op, right = s.partition(c)
        if op == '*':
            return ret(left) * ret(right)
        elif op == '/':
            return ret(left) / ret(right)
        elif op == '+':
            return ret(left) + ret(right)
        elif op == '-':
            return ret(left) - ret(right)
print(ret('1+2'))

また、最初に足し算と引き算を行い、次に掛け算と割り算を行うため、操作の順序を逆にする必要があります。

つまり、 のような式がある場合、それを次のよう4+4*3に分割したいということです。

ret(4) + ret(4 * 3)

これは再帰呼び出しであるため、優先順位が最も高い演算子をコール スタックの最後にして、関数が返されたときに最初に実行されるようにする必要があります。

例として:

print(ret('1+2*6'))
print(ret('3*8+6/2'))

出力

13.0
27.0
于 2013-02-27T10:19:55.447 に答える
0

あなたのコードでは、 の結果に条件がないs.partition(c)ため、パーティションの結果が('anything', '', '')最初の if で再帰を行う場合でも.

編集済み

于 2013-02-27T10:28:15.697 に答える
0

あなたの派遣は間違っています。関数を定義した方法では、常に「*」で分割しようとします。これは、基本的に同じ引数で ret 関数を再帰的に呼び出します...

最初に、引数文字列に「演算子」が存在するかどうかを確認する必要があります。

もう一度考えてみて!

于 2013-02-27T10:22:05.633 に答える
0

これは簡単な python 電卓プログラムです。自由に使用してください。

#Python calculator

def menu():
    print ("Welcome to calculator.py")
    print ("your options are:")
    print (" ")
    print ("1) Addition")
    print ("2) Subtraction")
    print ("3) Multiplication")
    print ("4) Division")
    print ("5) Quit calculator.py")
    print (" ")
    return input ("Choose your option: ")

def add(a,b):
    print (a, "+", b, "=", a + b)

def sub(a,b):
    print (b, "-", a, "=", b - a)

def mul(a,b):
    print (a, "*", b, "=", a * b)

def div(a,b):
    print (a, "/", b, "=", a / b)

loop = 1
choice = 0
while loop == 1:
    choice = menu()
    if choice == 1:
        add(input("Add this: "),input("to this: "))
    elif choice == 2:
        sub(input("Subtract this: "),input("from this: "))
    elif choice == 3:
        mul(input("Multiply this: "),input("by this: "))
    elif choice == 4:
        div(input("Divide this: "),input("by this: "))
    elif choice == 5:
        loop = 0

print ("Thank you for using calculator.py!")
于 2013-10-13T16:39:30.483 に答える