rewrite expression.simplify and adapt Fraction to it
This commit is contained in:
parent
f968a25345
commit
bfafaac319
@ -103,32 +103,34 @@ 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 isinstance(token, Explicable_int) or isinstance(token, int):
|
# if isinstance(token, Explicable_int) or isinstance(token, int):
|
||||||
return Explicable_int(token)
|
# return Explicable_int(token)
|
||||||
|
|
||||||
# TODO: J'en arrive au soucis même soucis qu'avec les fractions qui une fois simplifiée devrait être des Explicable_int. Mais comment on ne redéfini pas les opérations, ce sont les opérations des int qui se font et donc on perd toute l'historique. |sam. févr. 13 18:57:45 EAT 2016
|
# # TODO: J'en arrive au soucis même soucis qu'avec les fractions qui une fois simplifiée devrait être des Explicable_int. Mais comment on ne redéfini pas les opérations, ce sont les opérations des int qui se font et donc on perd toute l'historique. |sam. févr. 13 18:57:45 EAT 2016
|
||||||
if isinstance(token, Explicable_float) or isinstance(token, float):
|
# if isinstance(token, Explicable_float) or isinstance(token, float):
|
||||||
return Explicable_float(token)
|
# return Explicable_float(token)
|
||||||
|
|
||||||
elif hasattr(token, 'simplify') and hasattr(token, 'explain'):
|
# elif hasattr(token, 'simplify') and hasattr(token, 'explain'):
|
||||||
ans = expression.postfix_tokens[0]
|
# ans = expression.postfix_tokens[0]
|
||||||
return ans
|
# return ans
|
||||||
|
|
||||||
elif isinstance(token, str):
|
# elif isinstance(token, str):
|
||||||
from .polynom import Polynom
|
# from .polynom import Polynom
|
||||||
return Polynom([0,1], letter = token)
|
# return Polynom([0,1], letter = token)
|
||||||
|
|
||||||
else:
|
# else:
|
||||||
raise ValueError(
|
# raise ValueError(
|
||||||
"Unknow token type in Expression: {}".format(
|
# "Unknow token type in Expression: {}".format(
|
||||||
type(token)))
|
# type(token)))
|
||||||
|
|
||||||
else:
|
# else:
|
||||||
expression._isExpression = 1
|
# expression._isExpression = 1
|
||||||
return expression
|
# return expression
|
||||||
|
expression._isExpression = 1
|
||||||
|
return expression
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
@ -144,43 +146,77 @@ class Expression(Explicable):
|
|||||||
|
|
||||||
def simplify(self):
|
def simplify(self):
|
||||||
""" Compute entirely the expression and return the result with .steps attribute """
|
""" Compute entirely the expression and return the result with .steps attribute """
|
||||||
self.compute_exp()
|
try:
|
||||||
|
self.compute_exp()
|
||||||
|
except ComputeError:
|
||||||
|
try:
|
||||||
|
self.simplified = self.postfix_tokens[0].simplify()
|
||||||
|
except AttributeError:
|
||||||
|
if isinstance(self.postfix_tokens[0],int):
|
||||||
|
self.simplified = Explicable_int(self.postfix_tokens[0])
|
||||||
|
elif isinstance(self.postfix_tokens[0],float):
|
||||||
|
self.simplified = Explicable_float(self.postfix_tokens[0])
|
||||||
|
else:
|
||||||
|
self.simplified = self
|
||||||
|
|
||||||
self.simplified = self.child.simplify()
|
else:
|
||||||
self.simplified.steps = self.child.steps + self.simplified.steps
|
self.simplified = self.child.simplify()
|
||||||
|
self.simplified.steps = self.child.steps + self.simplified.steps
|
||||||
return self.simplified
|
return self.simplified
|
||||||
|
|
||||||
def compute_exp(self):
|
def compute_exp(self):
|
||||||
""" Create self.child with and stock steps in it """
|
""" Create self.child with and stock steps in it """
|
||||||
ini_step = Expression(self.postfix_tokens)
|
if len(self.postfix_tokens) == 1:
|
||||||
|
raise ComputeError("Nothing to compute in {}".format(self.postfix_tokens))
|
||||||
|
else:
|
||||||
|
ini_step = Expression(self.postfix_tokens)
|
||||||
|
|
||||||
tokenList = self.postfix_tokens.copy()
|
tokenList = self.postfix_tokens.copy()
|
||||||
tmpTokenList = []
|
tmpTokenList = []
|
||||||
|
|
||||||
while len(tokenList) > 2:
|
while len(tokenList) > 2:
|
||||||
# on va chercher les motifs du genre A B +, quand l'operateur est
|
# on va chercher les motifs du genre A B +, quand l'operateur est
|
||||||
# d'arité 2, pour les calculer
|
# d'arité 2, pour les calculer
|
||||||
if isNumerand(tokenList[0]) and isNumerand(tokenList[1]) \
|
if isNumerand(tokenList[0]) and isNumerand(tokenList[1]) \
|
||||||
and isOperator(tokenList[2]) and tokenList[2].arity == 2:
|
and isOperator(tokenList[2]) and tokenList[2].arity == 2:
|
||||||
|
|
||||||
# S'il y a une opération à faire
|
# S'il y a une opération à faire
|
||||||
op1 = tokenList[0]
|
op1 = tokenList[0]
|
||||||
op2 = tokenList[1]
|
op2 = tokenList[1]
|
||||||
operator = tokenList[2]
|
operator = tokenList[2]
|
||||||
|
|
||||||
res = operator(op1, op2)
|
res = operator(op1, op2)
|
||||||
|
|
||||||
tmpTokenList.append(res)
|
tmpTokenList.append(res)
|
||||||
|
|
||||||
# Comme on vient de faire le calcul, on peut détruire aussi les
|
# Comme on vient de faire le calcul, on peut détruire aussi les
|
||||||
# deux prochains termes
|
# deux prochains termes
|
||||||
del tokenList[0:3]
|
del tokenList[0:3]
|
||||||
|
|
||||||
# Et les motifs du gens A -, quand l'operateur est d'arité 1
|
# Et les motifs du gens A -, quand l'operateur est d'arité 1
|
||||||
elif isNumerand(tokenList[0]) \
|
elif isNumerand(tokenList[0]) \
|
||||||
|
and isOperator(tokenList[1]) and tokenList[1].arity == 1:
|
||||||
|
|
||||||
|
# S'il y a une opération à faire
|
||||||
|
op1 = tokenList[0]
|
||||||
|
operator = tokenList[1]
|
||||||
|
|
||||||
|
res = operator(op1)
|
||||||
|
|
||||||
|
tmpTokenList.append(res)
|
||||||
|
|
||||||
|
# Comme on vient de faire le calcul, on peut détruire aussi les
|
||||||
|
# deux prochains termes
|
||||||
|
del tokenList[0:2]
|
||||||
|
|
||||||
|
else:
|
||||||
|
tmpTokenList.append(tokenList[0])
|
||||||
|
|
||||||
|
del tokenList[0]
|
||||||
|
|
||||||
|
if len(tokenList) == 2 and isNumerand(tokenList[0]) \
|
||||||
and isOperator(tokenList[1]) and tokenList[1].arity == 1:
|
and isOperator(tokenList[1]) and tokenList[1].arity == 1:
|
||||||
|
# S'il reste deux éléments dont un operation d'arité 1
|
||||||
# S'il y a une opération à faire
|
|
||||||
op1 = tokenList[0]
|
op1 = tokenList[0]
|
||||||
operator = tokenList[1]
|
operator = tokenList[1]
|
||||||
|
|
||||||
@ -192,34 +228,15 @@ class Expression(Explicable):
|
|||||||
# deux prochains termes
|
# deux prochains termes
|
||||||
del tokenList[0:2]
|
del tokenList[0:2]
|
||||||
|
|
||||||
|
tmpTokenList += tokenList
|
||||||
|
self.child = Expression(tmpTokenList)
|
||||||
|
|
||||||
|
steps = self.develop_steps(tmpTokenList)
|
||||||
|
|
||||||
|
if self.child.postfix_tokens == ini_step.postfix_tokens:
|
||||||
|
self.child.steps = steps
|
||||||
else:
|
else:
|
||||||
tmpTokenList.append(tokenList[0])
|
self.child.steps = [ini_step] + steps
|
||||||
|
|
||||||
del tokenList[0]
|
|
||||||
|
|
||||||
if len(tokenList) == 2 and isNumerand(tokenList[0]) \
|
|
||||||
and isOperator(tokenList[1]) and tokenList[1].arity == 1:
|
|
||||||
# S'il reste deux éléments dont un operation d'arité 1
|
|
||||||
op1 = tokenList[0]
|
|
||||||
operator = tokenList[1]
|
|
||||||
|
|
||||||
res = operator(op1)
|
|
||||||
|
|
||||||
tmpTokenList.append(res)
|
|
||||||
|
|
||||||
# Comme on vient de faire le calcul, on peut détruire aussi les
|
|
||||||
# deux prochains termes
|
|
||||||
del tokenList[0:2]
|
|
||||||
|
|
||||||
tmpTokenList += tokenList
|
|
||||||
self.child = Expression(tmpTokenList)
|
|
||||||
|
|
||||||
steps = self.develop_steps(tmpTokenList)
|
|
||||||
|
|
||||||
if self.child.postfix_tokens == ini_step.postfix_tokens:
|
|
||||||
self.child.steps = steps
|
|
||||||
else:
|
|
||||||
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 """
|
||||||
@ -363,6 +380,11 @@ class Expression(Explicable):
|
|||||||
def __neg__(self):
|
def __neg__(self):
|
||||||
return Expression(self.postfix_tokens + [op.sub1])
|
return Expression(self.postfix_tokens + [op.sub1])
|
||||||
|
|
||||||
|
class ExpressionError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ComputeError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
def untest(exp):
|
def untest(exp):
|
||||||
a = Expression(exp)
|
a = Expression(exp)
|
||||||
|
@ -60,7 +60,7 @@ class Fraction(Explicable):
|
|||||||
ini_step = [Expression(self.postfix_tokens)]
|
ini_step = [Expression(self.postfix_tokens)]
|
||||||
|
|
||||||
if self._num == 0:
|
if self._num == 0:
|
||||||
return Expression([0])
|
return Expression([0]).simplify()
|
||||||
|
|
||||||
elif isinstance(self._num, Fraction) or isinstance(self._denom, Fraction):
|
elif isinstance(self._num, Fraction) or isinstance(self._denom, Fraction):
|
||||||
return self._num / self._denom
|
return self._num / self._denom
|
||||||
@ -74,7 +74,7 @@ class Fraction(Explicable):
|
|||||||
gcd_ = gcd(abs(self._num), abs(self._denom))
|
gcd_ = gcd(abs(self._num), abs(self._denom))
|
||||||
if gcd_ == self._denom:
|
if gcd_ == self._denom:
|
||||||
n_frac = self._num // gcd_
|
n_frac = self._num // gcd_
|
||||||
return Expression([n_frac])
|
return Expression([n_frac]).simplify()
|
||||||
|
|
||||||
elif gcd_ != 1:
|
elif gcd_ != 1:
|
||||||
n_frac = Fraction(self._num // gcd_, self._denom // gcd_)
|
n_frac = Fraction(self._num // gcd_, self._denom // gcd_)
|
||||||
|
Loading…
Reference in New Issue
Block a user