Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
27c3ba4a
Commit
27c3ba4a
authored
Feb 10, 2014
by
Sarina Canelake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pep8/pylint cleanup on symmath/formula.py
parent
d8144b0d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
191 additions
and
145 deletions
+191
-145
common/lib/symmath/symmath/formula.py
+191
-145
No files found.
common/lib/symmath/symmath/formula.py
View file @
27c3ba4a
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Flexible python representation of a symbolic mathematical formula.
Acceptes Presentation MathML, Content MathML (and could also do OpenMath).
Provides sympy representation.
"""
#
# File: formula.py
# Date: 04-May-12 (creation)
# Author: I. Chuang <ichuang@mit.edu>
#
# flexible python representation of a symbolic mathematical formula.
# Acceptes Presentation MathML, Content MathML (and could also do OpenMath)
# Provides sympy representation.
import
os
import
string
# pylint: disable=W0402
...
...
@@ -19,11 +21,8 @@ import sympy
from
sympy.printing.latex
import
LatexPrinter
from
sympy.printing.str
import
StrPrinter
from
sympy
import
latex
,
sympify
from
sympy.physics.quantum.qubit
import
*
from
sympy.physics.quantum.state
import
*
# from sympy import exp, pi, I
# from sympy.core.operations import LatticeOp
# import sympy.physics.quantum.qubit
from
sympy.physics.quantum.qubit
import
Qubit
from
sympy.physics.quantum.state
import
Ket
from
xml.sax.saxutils
import
unescape
import
unicodedata
...
...
@@ -40,53 +39,63 @@ os.environ['PYTHONIOENCODING'] = 'utf-8'
#-----------------------------------------------------------------------------
class
dot
(
sympy
.
operations
.
LatticeOp
):
# my dot product
class
dot
(
sympy
.
operations
.
LatticeOp
):
# pylint: disable=invalid-name, no-member
"""my dot product"""
zero
=
sympy
.
Symbol
(
'dotzero'
)
identity
=
sympy
.
Symbol
(
'dotidentity'
)
#class dot(sympy.Mul): # my dot product
# is_Mul = False
def
_print_dot
(
self
,
expr
):
def
_print_dot
(
_self
,
expr
):
"""Print statement used for LatexPrinter"""
return
r'{((
%
s) \cdot (
%
s))}'
%
(
expr
.
args
[
0
],
expr
.
args
[
1
])
LatexPrinter
.
_print_dot
=
_print_dot
LatexPrinter
.
_print_dot
=
_print_dot
# pylint: disable=protected-access
#-----------------------------------------------------------------------------
# unit vectors (for 8.02)
def
_print_hat
(
self
,
expr
):
return
'
\\
hat{
%
s}'
%
str
(
expr
.
args
[
0
])
.
lower
()
def
_print_hat
(
_self
,
expr
):
"""Print statement used for LatexPrinter"""
return
'
\\
hat{
%
s}'
%
str
(
expr
.
args
[
0
])
.
lower
()
LatexPrinter
.
_print_hat
=
_print_hat
StrPrinter
.
_print_hat
=
_print_hat
LatexPrinter
.
_print_hat
=
_print_hat
# pylint: disable=protected-access
StrPrinter
.
_print_hat
=
_print_hat
# pylint: disable=protected-access
#-----------------------------------------------------------------------------
# helper routines
def
to_latex
(
x
):
if
x
is
None
:
return
''
# LatexPrinter._print_dot = _print_dot
xs
=
latex
(
x
)
xs
=
xs
.
replace
(
r'\XI'
,
'XI'
)
# workaround for strange greek
def
to_latex
(
expr
):
"""
Convert expression to latex mathjax format
"""
if
expr
is
None
:
return
''
expr_s
=
latex
(
expr
)
expr_s
=
expr_s
.
replace
(
r'\XI'
,
'XI'
)
# workaround for strange greek
# substitute back into latex form for scripts
# literally something of the form
# 'scriptN' becomes '\\mathcal{N}'
# note: can't use something akin to the _print_hat method above because we sometimes get 'script(N)__B' or more complicated terms
xs
=
re
.
sub
(
r'script([a-zA-Z0-9]+)'
,
expr_s
=
re
.
sub
(
r'script([a-zA-Z0-9]+)'
,
'
\\
mathcal{
\\
1}'
,
xs
)
expr_s
)
#return '<math>%s{}{}</math>' % (xs[1:-1])
if
x
s
[
0
]
==
'$'
:
return
'[mathjax]
%
s[/mathjax]<br>'
%
(
x
s
[
1
:
-
1
])
# for sympy v6
return
'[mathjax]
%
s[/mathjax]<br>'
%
(
x
s
)
# for sympy v7
if
expr_
s
[
0
]
==
'$'
:
return
'[mathjax]
%
s[/mathjax]<br>'
%
(
expr_
s
[
1
:
-
1
])
# for sympy v6
return
'[mathjax]
%
s[/mathjax]<br>'
%
(
expr_
s
)
# for sympy v7
def
my_evalf
(
expr
,
chop
=
False
):
"""
Enhanced sympy evalf to handle lists of expressions
and catch eval failures without dropping out.
"""
if
type
(
expr
)
==
list
:
try
:
return
[
x
.
evalf
(
chop
=
chop
)
for
x
in
expr
]
...
...
@@ -97,11 +106,11 @@ def my_evalf(expr, chop=False):
except
:
return
expr
#-----------------------------------------------------------------------------
# my version of sympify to import expression into sympy
def
my_sympify
(
expr
,
normphase
=
False
,
matrix
=
False
,
abcsym
=
False
,
do_qubit
=
False
,
symtab
=
None
):
"""
Version of sympify to import expression into sympy
"""
# make all lowercase real?
if
symtab
:
varset
=
symtab
...
...
@@ -113,16 +122,13 @@ def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False
'Q'
:
sympy
.
Symbol
(
'Q'
),
# otherwise it is a sympy "ask key"
'I'
:
sympy
.
Symbol
(
'I'
),
# otherwise it is sqrt(-1)
'N'
:
sympy
.
Symbol
(
'N'
),
# or it is some kind of sympy function
#'X':sympy.sympify('Matrix([[0,1],[1,0]])'),
#'Y':sympy.sympify('Matrix([[0,-I],[I,0]])'),
#'Z':sympy.sympify('Matrix([[1,0],[0,-1]])'),
'ZZ'
:
sympy
.
Symbol
(
'ZZ'
),
# otherwise it is the PythonIntegerRing
'XI'
:
sympy
.
Symbol
(
'XI'
),
# otherwise it is the capital \XI
'hat'
:
sympy
.
Function
(
'hat'
),
# for unit vectors (8.02)
}
if
do_qubit
:
# turn qubit(...) into Qubit instance
varset
.
update
({
'qubit'
:
sympy
.
physics
.
quantum
.
qubit
.
Qubit
,
'Ket'
:
sympy
.
physics
.
quantum
.
state
.
Ket
,
varset
.
update
({
'qubit'
:
Qubit
,
'Ket'
:
Ket
,
'dot'
:
dot
,
'bit'
:
sympy
.
Function
(
'bit'
),
})
...
...
@@ -139,17 +145,21 @@ def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False
ophase
=
sympy
.
sympify
(
'exp(-I*arg(
%
s))'
%
sexpr
[
0
])
sexpr
=
[
sympy
.
Mul
(
x
,
ophase
)
for
x
in
sexpr
]
def
to_matrix
(
x
):
# if x is a list of lists, and is rectangular, then return Matrix(x)
if
not
type
(
x
)
==
list
:
return
x
for
row
in
x
:
def
to_matrix
(
expr
):
"""
Convert a list, or list of lists to a matrix.
"""
# if expr is a list of lists, and is rectangular, then return Matrix(expr)
if
not
type
(
expr
)
==
list
:
return
expr
for
row
in
expr
:
if
(
not
type
(
row
)
==
list
):
return
x
rdim
=
len
(
x
[
0
])
for
row
in
x
:
return
expr
rdim
=
len
(
expr
[
0
])
for
row
in
expr
:
if
not
len
(
row
)
==
rdim
:
return
x
return
sympy
.
Matrix
(
x
)
return
expr
return
sympy
.
Matrix
(
expr
)
if
matrix
:
sexpr
=
to_matrix
(
sexpr
)
...
...
@@ -160,11 +170,11 @@ def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False
class
formula
(
object
):
'''
"""
Representation of a mathematical formula object. Accepts mathml math expression
for constructing, and can produce sympy translation. The formula may or may not
include an assignment (=).
'''
"""
def
__init__
(
self
,
expr
,
asciimath
=
''
,
options
=
None
):
self
.
expr
=
expr
.
strip
()
self
.
asciimath
=
asciimath
...
...
@@ -173,14 +183,23 @@ class formula(object):
self
.
options
=
options
def
is_presentation_mathml
(
self
):
"""
Check if formula is in mathml presentation format.
"""
return
'<mstyle'
in
self
.
expr
def
is_mathml
(
self
):
"""
Check if formula is in mathml format.
"""
return
'<math '
in
self
.
expr
def
fix_greek_in_mathml
(
self
,
xml
):
def
gettag
(
x
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
x
.
tag
)
"""
Recursively fix greek letters in passed in xml.
"""
def
gettag
(
expr
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
expr
.
tag
)
for
k
in
xml
:
tag
=
gettag
(
k
)
...
...
@@ -188,40 +207,43 @@ class formula(object):
usym
=
unicode
(
k
.
text
)
try
:
udata
=
unicodedata
.
name
(
usym
)
except
Exception
,
err
:
except
Exception
:
udata
=
None
#print "usym = %s, udata=%s" % (usym,udata)
#
print "usym = %s, udata=%s" % (usym,udata)
if
udata
:
# eg "GREEK SMALL LETTER BETA"
if
'GREEK'
in
udata
:
usym
=
udata
.
split
(
' '
)[
-
1
]
if
'SMALL'
in
udata
:
usym
=
usym
.
lower
()
if
'SMALL'
in
udata
:
usym
=
usym
.
lower
()
#print "greek: ",usym
k
.
text
=
usym
self
.
fix_greek_in_mathml
(
k
)
return
xml
def
preprocess_pmathml
(
self
,
xml
):
r
'''
r
"""
Pre-process presentation MathML from ASCIIMathML to make it more
acceptable for SnuggleTeX, and also to accomodate some sympy
conventions (eg hat(i) for \hat{i}).
This method would be a good spot to look for an integral and convert
it, if possible...
'''
"""
if
type
(
xml
)
==
str
or
type
(
xml
)
==
unicode
:
xml
=
etree
.
fromstring
(
xml
)
# TODO: wrap in try
xml
=
self
.
fix_greek_in_mathml
(
xml
)
# convert greek utf letters to greek spelled out in ascii
def
gettag
(
x
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
x
.
tag
)
def
gettag
(
expr
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
expr
.
tag
)
# f and g are processed as functions by asciimathml, eg "f-2" turns into "<mrow><mi>f</mi><mo>-</mo></mrow><mn>2</mn>"
# this is really terrible for turning into cmathml.
# undo this here.
def
fix_pmathml
(
xml
):
"""
f and g are processed as functions by asciimathml, eg "f-2" turns
into "<mrow><mi>f</mi><mo>-</mo></mrow><mn>2</mn>" this is
really terrible for turning into cmathml. undo this here.
"""
for
k
in
xml
:
tag
=
gettag
(
k
)
if
tag
==
'mrow'
:
...
...
@@ -235,10 +257,13 @@ class formula(object):
fix_pmathml
(
xml
)
# hat i is turned into <mover><mi>i</mi><mo>^</mo></mover> ; mangle this into <mi>hat(f)</mi>
# hat i also somtimes turned into <mover><mrow> <mi>j</mi> </mrow><mo>^</mo></mover>
def
fix_hat
(
xml
):
"""
hat i is turned into <mover><mi>i</mi><mo>^</mo></mover> ; mangle
this into <mi>hat(f)</mi> hat i also somtimes turned into
<mover><mrow> <mi>j</mi> </mrow><mo>^</mo></mover>
"""
for
k
in
xml
:
tag
=
gettag
(
k
)
if
tag
==
'mover'
:
...
...
@@ -255,7 +280,8 @@ class formula(object):
fix_hat
(
xml
)
def
flatten_pmathml
(
xml
):
''' Give the text version of certain PMathML elements
"""
Give the text version of certain PMathML elements
Sometimes MathML will be given with each letter separated (it
doesn't know if its implicit multiplication or what). From an xml
...
...
@@ -266,19 +292,23 @@ class formula(object):
<mi>x</mi>
</mrow>
and returns 'max', for easier use later on.
'''
"""
tag
=
gettag
(
xml
)
if
tag
==
'mn'
:
return
xml
.
text
elif
tag
==
'mi'
:
return
xml
.
text
elif
tag
==
'mrow'
:
return
''
.
join
([
flatten_pmathml
(
y
)
for
y
in
xml
])
raise
Exception
,
'[flatten_pmathml] unknown tag
%
s'
%
tag
if
tag
==
'mn'
:
return
xml
.
text
elif
tag
==
'mi'
:
return
xml
.
text
elif
tag
==
'mrow'
:
return
''
.
join
([
flatten_pmathml
(
y
)
for
y
in
xml
])
raise
Exception
(
'[flatten_pmathml] unknown tag
%
s'
%
tag
)
def
fix_mathvariant
(
parent
):
'''Fix certain kinds of math variants
"""
Fix certain kinds of math variants
Literally replace <mstyle mathvariant="script"><mi>N</mi></mstyle>
with 'scriptN'. There have been problems using script_N or script(N)
'''
"""
for
child
in
parent
:
if
(
gettag
(
child
)
==
'mstyle'
and
child
.
get
(
'mathvariant'
)
==
'script'
):
newchild
=
etree
.
Element
(
'mi'
)
...
...
@@ -287,12 +317,11 @@ class formula(object):
fix_mathvariant
(
child
)
fix_mathvariant
(
xml
)
# find "tagged" superscripts
# they have the character \u200b in the superscript
# replace them with a__b so snuggle doesn't get confused
def
fix_superscripts
(
xml
):
'''
Look for and replace sup elements with 'X__Y' or 'X_Y__Z'
"""
Look for and replace sup elements with 'X__Y' or 'X_Y__Z'
In the javascript, variables with '__X' in them had an invisible
character inserted into the sup (to distinguish from powers)
...
...
@@ -324,16 +353,18 @@ class formula(object):
</mrow>
</msup>
to be 'x__B'
'''
"""
for
k
in
xml
:
tag
=
gettag
(
k
)
# match things like the last example--
# the second item in msub is an mrow with the first
# character equal to \u200b
if
(
tag
==
'msup'
and
if
(
tag
==
'msup'
and
len
(
k
)
==
2
and
gettag
(
k
[
1
])
==
'mrow'
and
gettag
(
k
[
1
][
0
])
==
'mo'
and
k
[
1
][
0
]
.
text
==
u'
\u200b
'
):
# whew
gettag
(
k
[
1
][
0
])
==
'mo'
and
k
[
1
][
0
]
.
text
==
u'
\u200b
'
# whew
):
# replace the msup with 'X__Y'
k
[
1
]
.
remove
(
k
[
1
][
0
])
...
...
@@ -344,9 +375,11 @@ class formula(object):
# match things like the middle example-
# the third item in msubsup is an mrow with the first
# character equal to \u200b
if
(
tag
==
'msubsup'
and
if
(
tag
==
'msubsup'
and
len
(
k
)
==
3
and
gettag
(
k
[
2
])
==
'mrow'
and
gettag
(
k
[
2
][
0
])
==
'mo'
and
k
[
2
][
0
]
.
text
==
u'
\u200b
'
):
# whew
gettag
(
k
[
2
][
0
])
==
'mo'
and
k
[
2
][
0
]
.
text
==
u'
\u200b
'
# whew
):
# replace the msubsup with 'X_Y__Z'
k
[
2
]
.
remove
(
k
[
2
][
0
])
...
...
@@ -357,10 +390,12 @@ class formula(object):
fix_superscripts
(
k
)
fix_superscripts
(
xml
)
# Snuggle returns an error when it sees an <msubsup>
# replace such elements with an <msup>, except the first element is of
# the form a_b. I.e. map a_b^c => (a_b)^c
def
fix_msubsup
(
parent
):
"""
Snuggle returns an error when it sees an <msubsup> replace such
elements with an <msup>, except the first element is of
the form a_b. I.e. map a_b^c => (a_b)^c
"""
for
child
in
parent
:
# fix msubsup
if
(
gettag
(
child
)
==
'msubsup'
and
len
(
child
)
==
3
):
...
...
@@ -375,20 +410,21 @@ class formula(object):
fix_msubsup
(
child
)
fix_msubsup
(
xml
)
self
.
xml
=
xml
self
.
xml
=
xml
# pylint: disable=attribute-defined-outside-init
return
self
.
xml
def
get_content_mathml
(
self
):
if
self
.
the_cmathml
:
return
self
.
the_cmathml
if
self
.
the_cmathml
:
return
self
.
the_cmathml
# pre-process the presentation mathml before sending it to snuggletex to convert to content mathml
try
:
xml
=
self
.
preprocess_pmathml
(
self
.
expr
)
except
Exception
,
err
:
log
.
warning
(
'Err
%
s while preprocessing; expr=
%
s'
%
(
err
,
self
.
expr
)
)
log
.
warning
(
'Err
%
s while preprocessing; expr=
%
s'
,
err
,
self
.
expr
)
return
"<html>Error! Cannot process pmathml</html>"
pmathml
=
etree
.
tostring
(
xml
,
pretty_print
=
True
)
self
.
the_pmathml
=
pmathml
self
.
the_pmathml
=
pmathml
# pylint: disable=attribute-defined-outside-init
# convert to cmathml
self
.
the_cmathml
=
self
.
GetContentMathML
(
self
.
asciimath
,
pmathml
)
...
...
@@ -397,15 +433,16 @@ class formula(object):
cmathml
=
property
(
get_content_mathml
,
None
,
None
,
'content MathML representation'
)
def
make_sympy
(
self
,
xml
=
None
):
'''
"""
Return sympy expression for the math formula.
The math formula is converted to Content MathML then that is parsed.
This is a recursive function, called on every CMML node. Support for
more functions can be added by modifying opdict, abould halfway down
'''
"""
if
self
.
the_sympy
:
return
self
.
the_sympy
if
self
.
the_sympy
:
return
self
.
the_sympy
if
xml
is
None
:
# root
if
not
self
.
is_mathml
():
...
...
@@ -420,7 +457,7 @@ class formula(object):
msg
=
"Illegal math expression"
else
:
msg
=
'Err
%
s while converting cmathml to xml; cmml=
%
s'
%
(
err
,
cmml
)
raise
Exception
,
msg
raise
Exception
(
msg
)
xml
=
self
.
fix_greek_in_mathml
(
xml
)
self
.
the_sympy
=
self
.
make_sympy
(
xml
[
0
])
else
:
...
...
@@ -429,36 +466,35 @@ class formula(object):
self
.
the_sympy
=
self
.
make_sympy
(
xml
[
0
])
return
self
.
the_sympy
def
gettag
(
x
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
x
.
tag
)
def
gettag
(
expr
):
return
re
.
sub
(
'{http://[^}]+}'
,
''
,
expr
.
tag
)
# simple math
def
op_divide
(
*
args
):
if
not
len
(
args
)
==
2
:
raise
Exception
,
'divide given wrong number of arguments!'
raise
Exception
(
'divide given wrong number of arguments!'
)
# print "divide: arg0=%s, arg1=%s" % (args[0],args[1])
return
sympy
.
Mul
(
args
[
0
],
sympy
.
Pow
(
args
[
1
],
-
1
))
def
op_plus
(
*
args
):
return
args
[
0
]
if
len
(
args
)
==
1
else
op_plus
(
*
args
[:
-
1
])
+
args
[
-
1
]
def
op_plus
(
*
args
):
return
args
[
0
]
if
len
(
args
)
==
1
else
op_plus
(
*
args
[:
-
1
])
+
args
[
-
1
]
def
op_times
(
*
args
):
return
reduce
(
operator
.
mul
,
args
)
def
op_times
(
*
args
):
return
reduce
(
operator
.
mul
,
args
)
def
op_minus
(
*
args
):
if
len
(
args
)
==
1
:
return
-
args
[
0
]
if
not
len
(
args
)
==
2
:
raise
Exception
,
'minus given wrong number of arguments!'
raise
Exception
(
'minus given wrong number of arguments!'
)
#return sympy.Add(args[0],-args[1])
return
args
[
0
]
-
args
[
1
]
opdict
=
{
'plus'
:
op_plus
,
'divide'
:
operator
.
div
,
opdict
=
{
'plus'
:
op_plus
,
'divide'
:
operator
.
div
,
# should this be op_divide?
'times'
:
op_times
,
'minus'
:
op_minus
,
#'plus': sympy.Add,
#'divide' : op_divide,
#'times' : sympy.Mul,
'minus'
:
op_minus
,
'root'
:
sympy
.
sqrt
,
'power'
:
sympy
.
Pow
,
'sin'
:
sympy
.
sin
,
...
...
@@ -483,59 +519,63 @@ class formula(object):
'ln'
:
sympy
.
ln
,
}
# simple sumbols
nums1dict
=
{
'pi'
:
sympy
.
pi
,
# simple symbols - TODO is this code used?
nums1dict
=
{
'pi'
:
sympy
.
pi
,
}
def
parsePresentationMathMLSymbol
(
xml
):
'''
"""
Parse <msub>, <msup>, <mi>, and <mn>
'''
"""
tag
=
gettag
(
xml
)
if
tag
==
'mn'
:
return
xml
.
text
elif
tag
==
'mi'
:
return
xml
.
text
elif
tag
==
'msub'
:
return
'_'
.
join
([
parsePresentationMathMLSymbol
(
y
)
for
y
in
xml
])
elif
tag
==
'msup'
:
return
'^'
.
join
([
parsePresentationMathMLSymbol
(
y
)
for
y
in
xml
])
raise
Exception
,
'[parsePresentationMathMLSymbol] unknown tag
%
s'
%
tag
if
tag
==
'mn'
:
return
xml
.
text
elif
tag
==
'mi'
:
return
xml
.
text
elif
tag
==
'msub'
:
return
'_'
.
join
([
parsePresentationMathMLSymbol
(
y
)
for
y
in
xml
])
elif
tag
==
'msup'
:
return
'^'
.
join
([
parsePresentationMathMLSymbol
(
y
)
for
y
in
xml
])
raise
Exception
(
'[parsePresentationMathMLSymbol] unknown tag
%
s'
%
tag
)
# parser tree for Content MathML
tag
=
gettag
(
xml
)
# print "tag = ",tag
# first do compound objects
if
tag
==
'apply'
:
# apply operator
opstr
=
gettag
(
xml
[
0
])
if
opstr
in
opdict
:
op
=
opdict
[
opstr
]
args
=
[
self
.
make_sympy
(
x
)
for
x
in
xml
[
1
:]]
op
=
opdict
[
opstr
]
# pylint: disable=invalid-name
args
=
[
self
.
make_sympy
(
expr
)
for
expr
in
xml
[
1
:]]
try
:
res
=
op
(
*
args
)
except
Exception
,
err
:
self
.
args
=
args
self
.
op
=
op
raise
Exception
,
'[formula] error=
%
s failed to apply
%
s to args=
%
s'
%
(
err
,
opstr
,
args
)
self
.
args
=
args
# pylint: disable=attribute-defined-outside-init
self
.
op
=
op
# pylint: disable=attribute-defined-outside-init, invalid-name
raise
Exception
(
'[formula] error=
%
s failed to apply
%
s to args=
%
s'
%
(
err
,
opstr
,
args
)
)
return
res
else
:
raise
Exception
,
'[formula]: unknown operator tag
%
s'
%
(
opstr
)
raise
Exception
(
'[formula]: unknown operator tag
%
s'
%
(
opstr
)
)
elif
tag
==
'list'
:
# square bracket list
if
gettag
(
xml
[
0
])
==
'matrix'
:
return
self
.
make_sympy
(
xml
[
0
])
else
:
return
[
self
.
make_sympy
(
x
)
for
x
in
xml
]
return
[
self
.
make_sympy
(
expr
)
for
expr
in
xml
]
elif
tag
==
'matrix'
:
return
sympy
.
Matrix
([
self
.
make_sympy
(
x
)
for
x
in
xml
])
return
sympy
.
Matrix
([
self
.
make_sympy
(
expr
)
for
expr
in
xml
])
elif
tag
==
'vector'
:
return
[
self
.
make_sympy
(
x
)
for
x
in
xml
]
return
[
self
.
make_sympy
(
expr
)
for
expr
in
xml
]
# atoms are below
elif
tag
==
'cn'
:
# number
return
sympy
.
sympify
(
xml
.
text
)
return
float
(
xml
.
text
)
#
return float(xml.text)
elif
tag
==
'ci'
:
# variable (symbol)
if
len
(
xml
)
>
0
and
(
gettag
(
xml
[
0
])
==
'msub'
or
gettag
(
xml
[
0
])
==
'msup'
):
# subscript or superscript
...
...
@@ -553,27 +593,29 @@ class formula(object):
return
sym
else
:
# unknown tag
raise
Exception
,
'[formula] unknown tag
%
s'
%
tag
raise
Exception
(
'[formula] unknown tag
%
s'
%
tag
)
sympy
=
property
(
make_sympy
,
None
,
None
,
'sympy representation'
)
def
GetContentMathML
(
self
,
asciimath
,
mathml
):
# URL = 'http://192.168.1.2:8080/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
# URL = 'http://127.0.0.1:8080/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
URL
=
'https://math-xserver.mitx.mit.edu/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
"""
Handle requests to snuggletex API to convert the Ascii math to MathML
"""
# url = 'http://192.168.1.2:8080/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
# url = 'http://127.0.0.1:8080/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
url
=
'https://math-xserver.mitx.mit.edu/snuggletex-webapp-1.2.2/ASCIIMathMLUpConversionDemo'
if
1
:
payload
=
{
'asciiMathInput'
:
asciimath
,
payload
=
{
'asciiMathInput'
:
asciimath
,
'asciiMathML'
:
mathml
,
#'asciiMathML':unicode(mathml).encode('utf-8'),
}
headers
=
{
'User-Agent'
:
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13"
}
r
=
requests
.
post
(
URL
,
data
=
payload
,
headers
=
headers
,
verify
=
False
)
r
.
encoding
=
'utf-8'
ret
=
r
.
text
#print "encoding: ",r.encoding
# return ret
request
=
requests
.
post
(
url
,
data
=
payload
,
headers
=
headers
,
verify
=
False
)
request
.
encoding
=
'utf-8'
ret
=
request
.
text
# print "encoding: ", request.encoding
mode
=
0
cmathml
=
[]
...
...
@@ -586,18 +628,17 @@ class formula(object):
mode
=
0
continue
cmathml
.
append
(
k
)
# return '\n'.join(cmathml)
cmathml
=
'
\n
'
.
join
(
cmathml
[
2
:])
cmathml
=
'<math xmlns="http://www.w3.org/1998/Math/MathML">
\n
'
+
unescape
(
cmathml
)
+
'
\n
</math>'
# print cmathml
#return unicode(cmathml)
return
cmathml
#-----------------------------------------------------------------------------
def
test1
():
xmlstr
=
'''
"""Test XML strings - addition"""
xmlstr
=
"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<plus/>
...
...
@@ -605,12 +646,13 @@ def test1():
<cn>2</cn>
</apply>
</math>
'''
"""
return
formula
(
xmlstr
)
def
test2
():
xmlstr
=
u'''
"""Test XML strings - addition, Greek alpha"""
xmlstr
=
u"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<plus/>
...
...
@@ -622,12 +664,13 @@ def test2():
</apply>
</apply>
</math>
'''
"""
return
formula
(
xmlstr
)
def
test3
():
xmlstr
=
'''
"""Test XML strings - addition, Greek gamma"""
xmlstr
=
"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide/>
...
...
@@ -639,12 +682,13 @@ def test3():
</apply>
</apply>
</math>
'''
"""
return
formula
(
xmlstr
)
def
test4
():
xmlstr
=
u'''
"""Test XML strings - addition, Greek alpha, mfrac"""
xmlstr
=
u"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle displaystyle="true">
<mn>1</mn>
...
...
@@ -655,12 +699,13 @@ def test4():
</mfrac>
</mstyle>
</math>
'''
"""
return
formula
(
xmlstr
)
def
test5
():
# sum of two matrices
xmlstr
=
u'''
def
test5
():
"""Test XML strings - sum of two matrices"""
xmlstr
=
u"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle displaystyle="true">
<mrow>
...
...
@@ -719,12 +764,13 @@ def test5(): # sum of two matrices
</mrow>
</mstyle>
</math>
'''
"""
return
formula
(
xmlstr
)
def
test6
():
# imaginary numbers
xmlstr
=
u'''
def
test6
():
"""Test XML strings - imaginary numbers"""
xmlstr
=
u"""
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle displaystyle="true">
<mn>1</mn>
...
...
@@ -732,5 +778,5 @@ def test6(): # imaginary numbers
<mi>i</mi>
</mstyle>
</math>
'''
"""
return
formula
(
xmlstr
,
options
=
'imaginary'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment