pythonがPEMDAS の後に続くと考えて、各ステップを印刷する方法があるかどうかを知りたいと思います。自分のライブラリを構築しなくても、この問題を解決する際に各ステップを印刷することはできますか?数学的表現をステップに分解する
print_steps('(3+7-2)*4/(3+32)')
括弧指数部、乗除算、および加算と減算
pythonがPEMDAS の後に続くと考えて、各ステップを印刷する方法があるかどうかを知りたいと思います。自分のライブラリを構築しなくても、この問題を解決する際に各ステップを印刷することはできますか?数学的表現をステップに分解する
print_steps('(3+7-2)*4/(3+32)')
括弧指数部、乗除算、および加算と減算
を「ライブラリー」はかなり軽量になります
class verbose_number:
def __init__(self, value): self.value = value
def operate(self, operator, other):
other = getattr(other, 'value', other)
result = eval('self.value %s other' % operator)
print('%r %s %r = %r' % (self.value, operator, other, result))
return self.__class__(result)
def __add__(self, other): return self.operate('+', other)
def __sub__(self, other): return self.operate('-', other)
def __mul__(self, other): return self.operate('*', other)
def __div__(self, other): return self.operate('/', other)
def __floordiv__(self, other): return self.operate('//', other)
def __truediv__(self, other): return self.operate('/', other)
def __pow__(self, other): return self.operate('**', other)
def __mod__(self, other): return self.operate('%', other)
def __neg__(self): return self.__class__(-self.value)
def __pos__(self): return self.__class__(+self.value)
def __repr__(self): return repr(self.value)
def __int__(self): return int(self.value)
def __float__(self): return float(self.value)
今すぐverbose_number
インスタンスを必要とする任意の算術計算が印刷され、別のverbose_number
を返すので、計算ステップを印刷されますこれは私が最初 NUMをしたという事実に頼っていること
>>> from __future__ import division
>>> (verbose_number(3)+7-2)*4/(3+32)
3 + 7 = 10
10 - 2 = 8
8 * 4 = 32
3 + 32 = 35
32/35 = 0.9142857142857143
注:ステップバイ表現式はverbose_number
です。アプローチの改良は、解析する文字列式のための便利なルーチンを書くことです:これは、それによってすべての手順がされることを保証し、verbose_number
コンストラクタ呼び出しに文字列内のすべての数値リテラルを回すことによって動作
import re
def print_steps(expression):
return eval(re.sub(r'([0-9\.]+([eE]-?[0-9]+)?)', r'verbose_number(\1)', expression))
Pythonのパーサーが式の中でどこから始まっても冗長です。あなたの例を評価するためにそれを使用する方法は次のとおりです。
>>> print_steps('(3+7-2)*4/(3+32)')
3 + 7 = 10
10 - 2 = 8
8 * 4 = 32
3 + 32 = 35
32/35 = 0.9142857142857143
いいえ。 dis.dis
でも、バイトコードにコンパイルされる前にすべてが単一の定数に単純化されているので、個々のステップが表示されることはありません。
>>> def f():
... return (3+7-2)*4/(3+32)
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 10 (0.9142857142857143)
3 RETURN_VALUE
あなたはそれの把握を取得するためにast.parse
とast.dump
を使用することができます。
import ast
ast.dump(ast.parse('(3+7-2)*4/(3+32)', mode='eval'))
きれいにフォーマットした場合、出力は次のようになります。ジェズのanswerに触発さ
Expression(
body=BinOp(
left=BinOp(
left=BinOp(
left=BinOp(
left=Num(n=3),
op=Add(),
right=Num(n=7)
),
op=Sub(),
right=Num(n=2)
),
op=Mult(),
right=Num(n=4)
),
op=Div(),
right=BinOp(
left=Num(n=3),
op=Add(),
right=Num(n=32)
)
)
)
私はいくつかの線形ステップにダンプを変換するために、次の解決策を考え出した:
import operator
Expression = lambda body: body
Num = lambda n: n
USub = lambda : ('-', operator.neg)
Add = lambda : ('+', operator.add)
Sub = lambda : ('-', operator.sub)
Mult = lambda : ('*', operator.mul)
Div = lambda : ('/', operator.truediv)
FloorDiv = lambda : ('//', operator.floordiv)
def UnaryOp(op, operand):
print(op[0], operand)
result = op[1](operand)
print(' =', result)
return result
def BinOp(left, op, right):
result = op[1](left, right)
print(left, op[0], right, '=', result)
return result
eval(ast.dump(ast.parse('(3+7-2)*4/(3+32)', mode='eval')))
それは印刷します:
3 + 7 = 10
10 - 2 = 8
8 * 4 = 32
3 + 32 = 35
32/35 = 0.9142857142857143
astviewerを使用すると、ツリーをグラフィカルに表現できます。たとえばastviewer.main.view(source_code='(3+7-2)*4/(3+32)', mode='eval')
のために、あなたは与える:
このコードは型エラーです。 – ForceBru