Merge branch 'bug_explain' into dev
This commit is contained in:
commit
f33f5f8755
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
__report_indent = [0]
|
||||||
|
def report(fn):
|
||||||
|
"""Decorator to print information about a function
|
||||||
|
call for use while debugging.
|
||||||
|
Prints function name, arguments, and call number
|
||||||
|
when the function is called. Prints this information
|
||||||
|
again along with the return value when the function
|
||||||
|
returns.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def wrap(*params,**kwargs):
|
||||||
|
call = wrap.callcount = wrap.callcount + 1
|
||||||
|
|
||||||
|
indent = ' ' * __report_indent[0]
|
||||||
|
fc = "%s(%s)" % (fn.__name__, ', '.join(
|
||||||
|
[a.__repr__() for a in params] +
|
||||||
|
["%s = %s" % (a, repr(b)) for a,b in kwargs.items()]
|
||||||
|
))
|
||||||
|
|
||||||
|
print( "Call %s%s called [#%s]"
|
||||||
|
% (indent, fc, call))
|
||||||
|
__report_indent[0] += 1
|
||||||
|
ret = fn(*params,**kwargs)
|
||||||
|
__report_indent[0] -= 1
|
||||||
|
try:
|
||||||
|
print(' '*(__report_indent[0]+4), "ret.steps -> ", len(ret.steps))
|
||||||
|
except AttributeError:
|
||||||
|
print(' '*(__report_indent[0]+4), ret, " has no steps")
|
||||||
|
print( "End %s%s returned %s [#%s]"
|
||||||
|
% (indent, fc, repr(ret), call))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
wrap.callcount = 0
|
||||||
|
return wrap
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
|
@ -307,6 +307,11 @@ class AbstractPolynom(Explicable):
|
||||||
>>> Q = P.reduce()
|
>>> Q = P.reduce()
|
||||||
>>> Q
|
>>> Q
|
||||||
< <class 'pymath.abstract_polynom.AbstractPolynom'> [3, 12, 6]>
|
< <class 'pymath.abstract_polynom.AbstractPolynom'> [3, 12, 6]>
|
||||||
|
>>> for i in Q.explain():
|
||||||
|
... print(i)
|
||||||
|
6 x^{ 2 } + ( 3 + 4 + 5 ) x + 1 + 2
|
||||||
|
6 x^{ 2 } + ( 7 + 5 ) x + 3
|
||||||
|
6 x^{ 2 } + 12 x + 3
|
||||||
>>> Q.steps
|
>>> Q.steps
|
||||||
[< <class 'pymath.abstract_polynom.AbstractPolynom'> [< <class 'pymath.expression.Expression'> [1, 2, '+'] >, < <class 'pymath.expression.Expression'> [3, 4, '+', 5, '+'] >, 6]>, < <class 'pymath.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.expression.Expression'> [7, 5, '+'] >, 6]>]
|
[< <class 'pymath.abstract_polynom.AbstractPolynom'> [< <class 'pymath.expression.Expression'> [1, 2, '+'] >, < <class 'pymath.expression.Expression'> [3, 4, '+', 5, '+'] >, 6]>, < <class 'pymath.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.expression.Expression'> [7, 5, '+'] >, 6]>]
|
||||||
"""
|
"""
|
||||||
|
@ -580,6 +585,14 @@ class AbstractPolynom(Explicable):
|
||||||
def __xor__(self, power):
|
def __xor__(self, power):
|
||||||
return self.__pow__(power)
|
return self.__pow__(power)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
P = AbstractPolynom([[1,2],[3,4,5],6])
|
||||||
|
Q = P.reduce()
|
||||||
|
for i in Q.explain():
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
#import doctest
|
||||||
|
#doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
from .render import txt, tex
|
from .render import txt, tex
|
||||||
|
|
||||||
class Renderable(object):
|
class Renderable(object):
|
||||||
|
"""
|
||||||
|
A Renderable object is an object which can work with Render class. It means that it has to have attribute postfix_tokens.
|
||||||
|
"""
|
||||||
STR_RENDER = tex
|
STR_RENDER = tex
|
||||||
DEFAULT_RENDER = tex
|
DEFAULT_RENDER = tex
|
||||||
|
|
||||||
|
@ -61,6 +64,15 @@ class Renderable(object):
|
||||||
Renderable.set_render(self.old_render)
|
Renderable.set_render(self.old_render)
|
||||||
return TmpRenderEnv()
|
return TmpRenderEnv()
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
""" Two Renderable objects are the same if they have same postfix_tokens """
|
||||||
|
try:
|
||||||
|
return self.postfix_tokens == other.postfix_tokens
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Explicable(Renderable):
|
class Explicable(Renderable):
|
||||||
|
|
||||||
""" An Explicable object is an object which can be explicable!
|
""" An Explicable object is an object which can be explicable!
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
#debuging
|
||||||
|
#from debug.tools import report
|
||||||
|
|
||||||
from .generic import Stack, flatten_list, expand_list, isNumber, isOperator, isNumerand
|
from .generic import Stack, flatten_list, expand_list, isNumber, isOperator, isNumerand
|
||||||
from .str2tokens import str2tokens
|
from .str2tokens import str2tokens
|
||||||
from .operator import op
|
from .operator import op
|
||||||
|
@ -10,11 +13,20 @@ from .random_expression import RdExpression
|
||||||
|
|
||||||
__all__ = ['Expression']
|
__all__ = ['Expression']
|
||||||
|
|
||||||
|
class Fake_int(int, Explicable):
|
||||||
|
isNumber = True
|
||||||
|
def __init__(self, val):
|
||||||
|
super(Fake_int, self).__init__(val)
|
||||||
|
self._val = val
|
||||||
|
self.postfix_tokens = [self]
|
||||||
|
self.steps = []
|
||||||
|
def simplify(self):
|
||||||
|
return Fake_int(self._val)
|
||||||
|
|
||||||
|
|
||||||
class Expression(Explicable):
|
class Expression(Explicable):
|
||||||
"""A calculus expression. Today it can andle only expression with numbers later it will be able to manipulate unknown"""
|
"""A calculus expression. Today it can andle only expression with numbers later it will be able to manipulate unknown"""
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(self, form="", conditions=[], val_min = -10, val_max=10):
|
def random(self, form="", conditions=[], val_min = -10, val_max=10):
|
||||||
"""Create a random expression from form and with conditions
|
"""Create a random expression from form and with conditions
|
||||||
|
@ -85,16 +97,11 @@ class Expression(Explicable):
|
||||||
|
|
||||||
if len(expression.postfix_tokens) == 1:
|
if len(expression.postfix_tokens) == 1:
|
||||||
token = expression.postfix_tokens[0]
|
token = expression.postfix_tokens[0]
|
||||||
if hasattr(token, 'simplify') and hasattr(token, 'explain'):
|
if type(token) == Fake_int or type(token) == int:
|
||||||
return expression.postfix_tokens[0]
|
return Fake_int(token)
|
||||||
|
elif hasattr(token, 'simplify') and hasattr(token, 'explain'):
|
||||||
elif type(token) == int:
|
ans = expression.postfix_tokens[0]
|
||||||
# On crée un faux int en ajoutant la méthode simplify et simplified et la caractérisique isNumber
|
return ans
|
||||||
simplify = lambda x:x
|
|
||||||
is_number = True
|
|
||||||
methods_attr = {'simplify':simplify, 'isNumber': is_number, 'postfix_tokens': [token]}
|
|
||||||
fake_token = type('fake_int', (int,Explicable, ), methods_attr)(token)
|
|
||||||
return fake_token
|
|
||||||
|
|
||||||
elif type(token) == str:
|
elif type(token) == str:
|
||||||
# TODO: Pourquoi ne pas créer directement un polynom ici? |jeu. févr. 26 18:59:24 CET 2015
|
# TODO: Pourquoi ne pas créer directement un polynom ici? |jeu. févr. 26 18:59:24 CET 2015
|
||||||
|
@ -127,11 +134,7 @@ class Expression(Explicable):
|
||||||
self.compute_exp()
|
self.compute_exp()
|
||||||
|
|
||||||
self.simplified = self.child.simplify()
|
self.simplified = self.child.simplify()
|
||||||
if self.simplified != self.child:
|
|
||||||
try:
|
|
||||||
self.simplified.steps = self.child.steps + self.simplified.steps
|
self.simplified.steps = self.child.steps + self.simplified.steps
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
return self.simplified
|
return self.simplified
|
||||||
|
|
||||||
def compute_exp(self):
|
def compute_exp(self):
|
||||||
|
@ -193,21 +196,25 @@ class Expression(Explicable):
|
||||||
|
|
||||||
tmpTokenList += tokenList
|
tmpTokenList += tokenList
|
||||||
self.child = Expression(tmpTokenList)
|
self.child = Expression(tmpTokenList)
|
||||||
|
|
||||||
|
steps = self.develop_steps(tmpTokenList)
|
||||||
|
|
||||||
if self.child.postfix_tokens == ini_step.postfix_tokens:
|
if self.child.postfix_tokens == ini_step.postfix_tokens:
|
||||||
self.child.steps = self.develop_steps(tmpTokenList)
|
self.child.steps = steps
|
||||||
else:
|
else:
|
||||||
self.child.steps = [ini_step] + self.develop_steps(tmpTokenList)
|
self.child.steps = [ini_step] + steps
|
||||||
|
|
||||||
def develop_steps(self, tokenList):
|
def develop_steps(self, tokenList):
|
||||||
""" From a list of tokens, it develops steps of each tokens """
|
""" From a list of tokens, it develops steps of each tokens """
|
||||||
|
# TODO: Attention les étapes sont dans le mauvais sens |lun. avril 20 10:06:03 CEST 2015
|
||||||
tmp_steps = []
|
tmp_steps = []
|
||||||
with Expression.tmp_render():
|
with Expression.tmp_render():
|
||||||
for t in tokenList:
|
for t in tokenList:
|
||||||
if hasattr(t, "explain"):
|
if hasattr(t, "explain"):
|
||||||
tmp_steps.append([i for i in t.explain()])
|
tmp_steps.append([i for i in t.explain()])
|
||||||
else:
|
else:
|
||||||
tmp_steps.append(t)
|
tmp_steps.append([t])
|
||||||
if max([len(i) if type(i) == list else 1 for i in tmp_steps]) == 1:
|
if max([len(i) for i in tmp_steps]) == 1:
|
||||||
# Cas où rien n'a dû être expliqué.
|
# Cas où rien n'a dû être expliqué.
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
|
@ -347,104 +354,29 @@ def untest(exp):
|
||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#render = lambda _,x : str(x)
|
print('\n')
|
||||||
#Expression.set_render(render)
|
A = Expression("( -8 x + 8 ) ( -8 - ( -6 x ) )")
|
||||||
#exp = Expression("1/2 - 4")
|
Ar = A.simplify()
|
||||||
#print(list(exp.simplify()))
|
for i in Ar.explain():
|
||||||
|
print(i)
|
||||||
#Expression.set_render(txt)
|
#print("------------")
|
||||||
#exp = "2 ^ 3 * 5"
|
#for i in Ar.explain():
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "2x + 5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#Expression.set_render(tex)
|
|
||||||
|
|
||||||
#untest(exp1)
|
|
||||||
|
|
||||||
#from pymath.operator import op
|
|
||||||
#exp = [2, 3, op.pw, 5, op.mul]
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#untest([Expression(exp1), Expression(exp), op.add])
|
|
||||||
|
|
||||||
#exp = "1 + 3 * 5"
|
|
||||||
#e = Expression(exp)
|
|
||||||
#f = -e
|
|
||||||
#print(f)
|
|
||||||
|
|
||||||
#exp = "2 * 3 * 3 * 5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "2 * 3 + 3 * 5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "2 * ( 3 + 4 ) + 3 * 5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "2 * ( 3 + 4 ) + ( 3 - 4 ) * 5"
|
|
||||||
#untest(exp)
|
|
||||||
#
|
|
||||||
#exp = "2 * ( 2 - ( 3 + 4 ) ) + ( 3 - 4 ) * 5"
|
|
||||||
#untest(exp)
|
|
||||||
#
|
|
||||||
#exp = "2 * ( 2 - ( 3 + 4 ) ) + 5 * ( 3 - 4 )"
|
|
||||||
#untest(exp)
|
|
||||||
#
|
|
||||||
#exp = "2 + 5 * ( 3 - 4 )"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "( 2 + 5 ) * ( 3 - 4 )^4"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "( 2 + 5 ) * ( 3 * 4 )"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "( 2 + 5 - 1 ) / ( 3 * 4 )"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "( 2 + 5 ) / ( 3 * 4 ) + 1 / 12"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp = "( 2+ 5 )/( 3 * 4 ) + 1 / 2"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp="(-2+5)/(3*4)+1/12+5*5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#exp="-2*4(12 + 1)(3-12)"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
|
|
||||||
#exp="(-2+5)/(3*4)+1/12+5*5"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
# TODO: The next one doesn't work |ven. janv. 17 14:56:58 CET 2014
|
|
||||||
#exp="-2*(-a)(12 + 1)(3-12)"
|
|
||||||
#e = Expression(exp)
|
|
||||||
#print(e)
|
|
||||||
|
|
||||||
## Can't handle it yet!!
|
|
||||||
#exp="-(-2)"
|
|
||||||
#untest(exp)
|
|
||||||
|
|
||||||
#print("\n")
|
|
||||||
#exp = Expression.random("({a} + 3)({b} - 1)", ["{a} > 4"])
|
|
||||||
#for i in exp.simplify():
|
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
from .fraction import Fraction
|
#print(type(Ar))
|
||||||
f1 = Fraction(3,5)
|
|
||||||
f2 = Fraction(5,10)
|
|
||||||
q = f1+f2
|
|
||||||
print("---------")
|
|
||||||
print(q.steps)
|
|
||||||
print("---------")
|
|
||||||
|
|
||||||
for i in q.explain():
|
|
||||||
print(i)
|
|
||||||
|
|
||||||
|
#print('\n-----------')
|
||||||
|
#A = Expression("-6 / 3 + 10 / -5")
|
||||||
|
#Ar = A.simplify()
|
||||||
|
#for i in Ar.explain():
|
||||||
|
# print(i)
|
||||||
|
|
||||||
|
#print('\n-----------')
|
||||||
|
#A = Expression("1/3 + 4/6")
|
||||||
|
#Ar = A.simplify()
|
||||||
|
#for i in Ar.explain():
|
||||||
|
# print(i)
|
||||||
|
|
||||||
#import doctest
|
#import doctest
|
||||||
#doctest.testmod()
|
#doctest.testmod()
|
||||||
|
|
|
@ -78,7 +78,7 @@ class Fraction(Explicable):
|
||||||
return n_frac
|
return n_frac
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return self
|
return copy(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def postfix_tokens(self):
|
def postfix_tokens(self):
|
||||||
|
@ -188,6 +188,7 @@ class Fraction(Explicable):
|
||||||
ans = exp.simplify()
|
ans = exp.simplify()
|
||||||
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.add])
|
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.add])
|
||||||
ans.steps = [ini_step] + ans.steps
|
ans.steps = [ini_step] + ans.steps
|
||||||
|
#print("\t\tIn add ans.steps -> ", ans.steps)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def __radd__(self, other):
|
def __radd__(self, other):
|
||||||
|
|
|
@ -122,7 +122,7 @@ class Polynom_deg2(Polynom):
|
||||||
\\frac{ -1 + 3 }{ 3 }
|
\\frac{ -1 + 3 }{ 3 }
|
||||||
\\frac{ 2 }{ 3 }
|
\\frac{ 2 }{ 3 }
|
||||||
"""
|
"""
|
||||||
return self(self.alpha).simplify()
|
return self(self.alpha)
|
||||||
|
|
||||||
def roots(self, after_coma = 2):
|
def roots(self, after_coma = 2):
|
||||||
""" Compute roots of the polynom
|
""" Compute roots of the polynom
|
||||||
|
@ -231,8 +231,11 @@ if __name__ == '__main__':
|
||||||
# P = Polynom_deg2([2, 3, 4])
|
# P = Polynom_deg2([2, 3, 4])
|
||||||
# print(P)
|
# print(P)
|
||||||
|
|
||||||
# print("Delta")
|
# print("\nDelta")
|
||||||
# for i in P.delta.simplify():
|
# for i in P.delta.explain():
|
||||||
|
# print(i)
|
||||||
|
# print("\nBeta")
|
||||||
|
# for i in P.beta.explain():
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
|
|
Loading…
Reference in New Issue