2013-10-30 5 views
5

私は数学の数式と方程式をたくさん入力しましたが、それぞれについてラテックス表現をプリントアウトしたいと思います。これまで私はSageとsympyを試してきましたが、難しい部分は表現の中で言葉を並べ替えないことです。だから、Pythonの数学式をラテックスに、逐語的に(並べ替え、ファクタリングなどなし)

、私の入力は、この、Pythonで-ed evalことができるものである場合:私はこのようなものになります出力したい

(C - A*x)/B 

\frac{C - A x}{B} 

ドン't wantは次のようなものです:

\frac{-(A x - C)}{B} 
\frac{1}{B}(C - A x) 
etc... 

これは達成できますか?私はゆっくりと...希望を失ってい


EDIT:

入力式は、一般的な解決策を探していくつか含む平方根、ネストされた括弧、指数など多様です。ここで

これまでに動作しないものです:

1)セージ:

sage: var('A B C x y') 
(A, B, C, x, y) 
sage: latex(y == (C - A*x)/B) 
y = -\frac{A x - C}{B} 

2)sympy:

>>> from sympy import * 
>>> x = Symbol('x') 
>>> A = Symbol('A') 
>>> B = Symbol('B') 
>>> C = Symbol('C') 
>>> latex((C - A*x)/B) 
'\\frac{1}{B} \\left(- A x + C\\right)' 
+0

望ましくない出力を与えるコードを提供するかもしれませんか? – alko

+0

@alko私はSageとsympyの例を含めるように編集しました – frnhr

答えて

1

あなたはシンボルや演算子を作成することによってこれを行うことができます\標準のPythonデータモデル(http://docs.python.org/2/reference/datamodel.html)を実装するクラス。その後

class Symbol(object): 
    def __init__(self, name): 
     self._name = name 

    def __str__(self): 
     return str(self._name) 

    def __div__(self, other): 
     return Div(self, other) 

    def __mul__(self, other): 
     return Mult(self, other) 

    def __add__(self, other): 
     return Add(self, other) 

    def __sub__(self, other): 
     return Sub(self, other) 

    def __rdiv__(self, other): 
     return Div(other, self) 

    def __rmul__(self, other): 
     return Mult(other, self) 

    def __radd__(self, other): 
     return Add(other, self) 

    def __rsub__(self, other): 
     return Sub(other, self) 

class Operation(Symbol): 
    def __init__(self, a, b, op): 
     self._a = a 
     self._b = b 
     self._op = op 

    def __str__(self): 
     return self._op.format(self._a, self._b) 

class Add(Operation): 
    precedence = 0 

    def __init__(self, a, b): 
     super(Add, self).__init__(a, b, "{0} + {1}") 

class Sub(Operation): 
    precedence = 0 
    def __init__(self, a, b): 
     super(Sub, self).__init__(a, b, "{0} - {1}") 

class Mult(Operation): 
    precedence = 1 
    def __init__(self, a, b): 
     if isinstance(a, Operation) and a.precedence < Mult.precedence: 
      a_form = "({0})" 
     else: 
      a_form = "{0}" 
     if isinstance(b, Operation) and b.precedence < Mult.precedence: 
      b_form = "({1})" 
     else: 
      b_form = "{1}" 
     super(Mult, self).__init__(a, b, a_form + " " + b_form) 

class Div(Operation): 
    precedence = 1 
    def __init__(self, a, b): 
     super(Div, self).__init__(a, b, "\\frac{{{0}}}{{{1}}}") 


A = Symbol('A') 
B = Symbol('B') 
C = Symbol('C') 
x = Symbol('x') 

独自のパーサを書くのショート
>>> print (C - A * x)/(B) 
\frac{C - A x}{B} 
>>> print (C * (A + B)) 
C (A + B) 
>>> print (C * (A + B + A + B + C + x)) 
C (A + B + A + B + C + x) 
+0

これは、 'x *(y + z)'のような括弧を保持しません。 – jwodder

+0

真。これは、データモデルのすばやく汚れた例です。カッコを保持するには、操作の順序を処理するために、組み合わせメソッドでより多くのデータを保持する必要があります。 –

+0

オペレータの優先順位を維持するために編集 –

3

、私が唯一の現実的な方法とを信じて、あなたが括弧を経由して並べ替えることができますが、これは、Pythonの演算子の優先順位の同じ順序で物事を維持しますpython's built-in compile() functionを使用して、返された抽象構文ツリーを処理することです。

+1

これは、同様の質問に対するこの回答によく似ています:http://stackoverflow.com/a/3874621/236195これはあなたの持っているものですか?念頭に置いたり、何か他に – frnhr

+0

@frnhrはい、それはまさに私が考えていたものです。 –