2017-03-12 5 views
0

文字列形式の括弧で囲まれた等式の様々なレイアウトの入力が与えられると、 '(3-7)/5'、私はそれが評価の任意の時点で、それが非整数の数を含むかどうかを調べるために探しています。例えばeval()中に文字列中に非整数値が存在するかどうかをチェックする。

'(3/2)+1'はすぐにfloatが含まれており、2.5ていることを、十分に評価されたときfloatまま。しかし、'(5/2)*2'のようなものは簡単に浮動小数点であり、eval()関数では評価中に非整数が存在しないにもかかわらず、'(4/2)+3'が評価後の浮動小数点になります。

これを解決しようとすると、/演算子の文字列を検索し、その除算を含む最小の括弧を見つけることができました。したがって、'(2+1)/4'の場合は、を評価してから、非整数除算をチェックする必要があります。

どのような考えですか?

+0

'sympy'とその' simplify'メソッドを見てください。 – Daniel

+0

'int(eval(expr))== eval(expr)'以上のものを探していますか?ここで何を達成しようとしていますか? – Eric

+0

@Eric多かれ少なかれ、リストや表現のセットを与えられて、評価/簡素化の間に任意の時点で非整数値を含むものを失格/除去する必要があります。 – MonkeyFodder

答えて

2

残念ながら、このような値を生成することができるものは多すぎます。たとえば、**は平方根を計算するために使用でき、一般にevalに渡される内容は何でもかまいません。

私はevalを使用することはまったく良いアプローチではないと思います。 ast.parse関数を使用して式を表すAST (abstract syntax tree)を取得し、それを評価するための独自の単純なインタープリタを作成することができます。この通訳では、各ステップで必要なすべてのチェックを行うことができます。あなただけの単純な式を処理する場合それは本当にそんなにない仕事の少しですが、

from ast import * 

def simple_expr_eval(expr): 
    if not isinstance(expr, Expression): 
     raise TypeError('should be an expression') 
    return simple_eval(expr.body) 

def simple_eval(expr): 
    handlers = { 
     BinOp: simple_eval_binop, 
     UnaryOp: simple_eval_unaryop, 
     Num: simple_eval_number, 
     # ... 
    } 
    return handlers[type(expr)](expr) 

def simple_eval_binop(binop): 
    if binop.op is Mult: 
     left = simple_eval(binop.left) 
     right = simple_eval(binop.right): 
     return left * right 
    elif binop is Div: 
     # here you could check whether left/right produces a floating point... 
     raise ValueError('Floating operation during evaluation') 
    # ... 


あなたのような何かを書くだろう。これらの関数では、式の評価方法を変更するために、ノードを単純化/交換することが自由です。

evalの評価モード(つまり、eval(your_expr, '<fake-filename>', 'eval'))を指定してコードを解析する必要があります。

関連する問題