[PYTHON] python 숫자 식을 LaTeX로 변환하기
PYTHONpython 숫자 식을 LaTeX로 변환하기
다음과 같이 유효한 파이썬 구문을 사용하여 문자열을 변환해야합니다.
'1+2**(x+y)'
동등한 LaTeX를 얻으십시오 :
$1+2^{x+y}$
나는 sympy의 latex 함수를 시도했지만 문자열 형식이 아닌 실제 표현을 처리한다.
>>> latex(1+2**(x+y))
'$1 + 2^{x + y}$'
>>> latex('1+2**(x+y)')
'$1+2**(x+y)$'
그러나 이것을하기 위해서 x와 y를 타입 "심볼"로 선언해야합니다.
컴파일러 모듈에서 파서를 사용하여 좀 더 직선적 인, 바람직하게 할 수있는 무언가를 원한다.
>>> compiler.parse('1+2**(x+y)')
Module(None, Stmt([Discard(Add((Const(1), Power((Const(2), Add((Name('x'), Name('y'))))))))]))
마지막으로, 왜 그런가 : 나는 라텍스 스 니펫을 생성하여 mathjax를 사용하여 웹 페이지에 표시 할 수 있어야합니다.
해결법
-
==============================
1.sympy.latex를 eval과 함께 사용할 수 있습니다.
sympy.latex를 eval과 함께 사용할 수 있습니다.
s = "1+2**(x+y)" sympy.latex(eval(s)) # prints '$1 + {2}^{x + y}$'
변수를 심볼로 선언해야하지만, 실제로 문제가 발생하면 모든 것을 파싱하고 처음부터 라텍스를 생성하는 것보다 파서를 작성하는 것이 훨씬 쉽습니다.
-
==============================
2.sympy를 포함하지 않는 다소 길지만 여전히 불완전한 방법이 있습니다. \ frac {-b - \ sqrt {b ^ {2} -}로 변환 된 (-b-sqrt (b ** 2-4 * a * c)) / 4 \; \; c}} {2 \; a}로 렌더링하고 다음과 같이 렌더링합니다.
sympy를 포함하지 않는 다소 길지만 여전히 불완전한 방법이 있습니다. \ frac {-b - \ sqrt {b ^ {2} -}로 변환 된 (-b-sqrt (b ** 2-4 * a * c)) / 4 \; \; c}} {2 \; a}로 렌더링하고 다음과 같이 렌더링합니다.
기본적으로 AST를 생성하고 AST 노드에 해당하는 라텍스 연산을 생성합니다. 부족한 곳에서 그것을 확장하는 방법에 대한 충분한 아이디어가 있어야합니다.
import ast class LatexVisitor(ast.NodeVisitor): def prec(self, n): return getattr(self, 'prec_'+n.__class__.__name__, getattr(self, 'generic_prec'))(n) def visit_Call(self, n): func = self.visit(n.func) args = ', '.join(map(self.visit, n.args)) if func == 'sqrt': return '\sqrt{%s}' % args else: return r'\operatorname{%s}\left(%s\right)' % (func, args) def prec_Call(self, n): return 1000 def visit_Name(self, n): return n.id def prec_Name(self, n): return 1000 def visit_UnaryOp(self, n): if self.prec(n.op) > self.prec(n.operand): return r'%s \left(%s\right)' % (self.visit(n.op), self.visit(n.operand)) else: return r'%s %s' % (self.visit(n.op), self.visit(n.operand)) def prec_UnaryOp(self, n): return self.prec(n.op) def visit_BinOp(self, n): if self.prec(n.op) > self.prec(n.left): left = r'\left(%s\right)' % self.visit(n.left) else: left = self.visit(n.left) if self.prec(n.op) > self.prec(n.right): right = r'\left(%s\right)' % self.visit(n.right) else: right = self.visit(n.right) if isinstance(n.op, ast.Div): return r'\frac{%s}{%s}' % (self.visit(n.left), self.visit(n.right)) elif isinstance(n.op, ast.FloorDiv): return r'\left\lfloor\frac{%s}{%s}\right\rfloor' % (self.visit(n.left), self.visit(n.right)) elif isinstance(n.op, ast.Pow): return r'%s^{%s}' % (left, self.visit(n.right)) else: return r'%s %s %s' % (left, self.visit(n.op), right) def prec_BinOp(self, n): return self.prec(n.op) def visit_Sub(self, n): return '-' def prec_Sub(self, n): return 300 def visit_Add(self, n): return '+' def prec_Add(self, n): return 300 def visit_Mult(self, n): return '\\;' def prec_Mult(self, n): return 400 def visit_Mod(self, n): return '\\bmod' def prec_Mod(self, n): return 500 def prec_Pow(self, n): return 700 def prec_Div(self, n): return 400 def prec_FloorDiv(self, n): return 400 def visit_LShift(self, n): return '\\operatorname{shiftLeft}' def visit_RShift(self, n): return '\\operatorname{shiftRight}' def visit_BitOr(self, n): return '\\operatorname{or}' def visit_BitXor(self, n): return '\\operatorname{xor}' def visit_BitAnd(self, n): return '\\operatorname{and}' def visit_Invert(self, n): return '\\operatorname{invert}' def prec_Invert(self, n): return 800 def visit_Not(self, n): return '\\neg' def prec_Not(self, n): return 800 def visit_UAdd(self, n): return '+' def prec_UAdd(self, n): return 800 def visit_USub(self, n): return '-' def prec_USub(self, n): return 800 def visit_Num(self, n): return str(n.n) def prec_Num(self, n): return 1000 def generic_visit(self, n): if isinstance(n, ast.AST): return r'' % (n.__class__.__name__, ', '.join(map(self.visit, [getattr(n, f) for f in n._fields]))) else: return str(n) def generic_prec(self, n): return 0 def py2tex(expr): pt = ast.parse(expr) return LatexVisitor().visit(pt.body[0].value)
-
==============================
3.SymPy를 사용할 수 있습니다. 문자열을 sympify () 함수에 먼저 전달하면 유효한 SymPy 표현식으로 변환됩니다 (즉, 기호 생성 등). 그래서 너는 할 수있어.
SymPy를 사용할 수 있습니다. 문자열을 sympify () 함수에 먼저 전달하면 유효한 SymPy 표현식으로 변환됩니다 (즉, 기호 생성 등). 그래서 너는 할 수있어.
>>> latex(sympify('1+2**(x+y)')) 1 + 2^{x + y}
S ()는 또한 sympify ()의 지름길이기도합니다. 즉, latex (S ( '1 + 2 ** (x + y)'))도 작동합니다.
-
==============================
4.Geoff Reedy 우수 답변에 대한 약간의 수정 :
Geoff Reedy 우수 답변에 대한 약간의 수정 :
class GenerateSymbols(defaultdict): def __missing__(self, key): self[key] = sympy.Symbol(key) return self[key]
전에는 새 항목을 사전에 추가하지 않았습니다. 이제 이것을 식과 함께 사용할 수 있습니다.
d= GenerateSymbols() eq = '(-b-sqrt(b**2-4*a*c))/(2*a)'
LaTeX로 변환하기 전에 더 단순화 할 수 있습니다.
sympy.latex(sympy.simplify(eval(eq,d)))
당신은 이것을 얻습니다 :
'$- \\frac{b + \\operatorname{sqrt}\\left(- 4 a c + b^{2}\\right)}{2 a}$'
-
==============================
5.Tom10의 답을 바탕으로 기호를 생성하고 eval을 호출 할 때 사용할 사전을 정의 할 수 있습니다.
Tom10의 답을 바탕으로 기호를 생성하고 eval을 호출 할 때 사용할 사전을 정의 할 수 있습니다.
from collections import defaultdict class GenerateSymbols(defaultdict): def __missing__(self, key): return sympy.Symbol(key)
그럼 당신이 사용한다면
sympy.latex(eval('1+2**(x+y)',GenerateSymbols()))
변수에 대한 기호를 미리 작성하는 것에 대해 걱정할 필요가 없습니다.
from https://stackoverflow.com/questions/3867028/converting-a-python-numeric-expression-to-latex by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Opencv python을 사용하여 비디오 스트리밍에서 프레임 단위로 비디오 이미지를 처리하는 방법 (0) | 2018.10.20 |
---|---|
[PYTHON] 파이썬에서 함수에 타임 아웃을 추가하는 법 (0) | 2018.10.20 |
[PYTHON] Beautifulsoup - nextSibling (0) | 2018.10.20 |
[PYTHON] numpy 배열로 NaN 값을 전달하는 가장 효율적인 방법 (0) | 2018.10.20 |
[PYTHON] 여러 개의 독립적 인 셀러리 대기열을 유지하는 방법 (0) | 2018.10.20 |