autopep8 on all files but operator.py
This commit is contained in:
parent
e43544006e
commit
47d43849d0
@ -5,13 +5,15 @@ from .explicable import Explicable
|
|||||||
from .expression import Expression
|
from .expression import Expression
|
||||||
from .operator import op
|
from .operator import op
|
||||||
from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list, isPolynom, isNumerand
|
from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list, isPolynom, isNumerand
|
||||||
from .render import txt,tex
|
from .render import txt, tex
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
def power_cache(fun):
|
def power_cache(fun):
|
||||||
"""Decorator which cache calculated powers of polynoms """
|
"""Decorator which cache calculated powers of polynoms """
|
||||||
cache = {}
|
cache = {}
|
||||||
|
|
||||||
@wraps(fun)
|
@wraps(fun)
|
||||||
def cached_fun(self, power):
|
def cached_fun(self, power):
|
||||||
#print("cache -> ", cache)
|
#print("cache -> ", cache)
|
||||||
@ -23,11 +25,12 @@ def power_cache(fun):
|
|||||||
return poly_powered
|
return poly_powered
|
||||||
return cached_fun
|
return cached_fun
|
||||||
|
|
||||||
|
|
||||||
class AbstractPolynom(Explicable):
|
class AbstractPolynom(Explicable):
|
||||||
|
|
||||||
"""The mathematic definition of a polynom. It will be the parent class of Polynom (classical polynoms) and later of SquareRoot polynoms"""
|
"""The mathematic definition of a polynom. It will be the parent class of Polynom (classical polynoms) and later of SquareRoot polynoms"""
|
||||||
|
|
||||||
def __init__(self, coefs = [1], letter = "x", name = "P"):
|
def __init__(self, coefs=[1], letter="x", name="P"):
|
||||||
"""Initiate the polynom
|
"""Initiate the polynom
|
||||||
|
|
||||||
:param coef: coefficients of the polynom (ascending degree sorted)
|
:param coef: coefficients of the polynom (ascending degree sorted)
|
||||||
@ -86,7 +89,7 @@ class AbstractPolynom(Explicable):
|
|||||||
"""
|
"""
|
||||||
self._coef = []
|
self._coef = []
|
||||||
for coef in l_coef:
|
for coef in l_coef:
|
||||||
if type(coef) == list and len(coef)==1:
|
if isinstance(coef, list) and len(coef) == 1:
|
||||||
self._coef.append(coef[0])
|
self._coef.append(coef[0])
|
||||||
else:
|
else:
|
||||||
self._coef.append(coef)
|
self._coef.append(coef)
|
||||||
@ -114,7 +117,7 @@ class AbstractPolynom(Explicable):
|
|||||||
>>> AbstractPolynom([1]).is_monom()
|
>>> AbstractPolynom([1]).is_monom()
|
||||||
1
|
1
|
||||||
"""
|
"""
|
||||||
if len([i for i in self._coef if i != 0])==1:
|
if len([i for i in self._coef if i != 0]) == 1:
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
@ -126,7 +129,7 @@ class AbstractPolynom(Explicable):
|
|||||||
return str(Expression(self.postfix_tokens))
|
return str(Expression(self.postfix_tokens))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "< " + str(self.__class__) + " " + str(self._coef) + ">"
|
return "< " + str(self.__class__) + " " + str(self._coef) + ">"
|
||||||
|
|
||||||
def __txt__(self):
|
def __txt__(self):
|
||||||
return txt(self.postfix_tokens)
|
return txt(self.postfix_tokens)
|
||||||
@ -156,15 +159,16 @@ class AbstractPolynom(Explicable):
|
|||||||
['x', 2, '^']
|
['x', 2, '^']
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ans =[]
|
ans = []
|
||||||
if a == [0]:
|
if a == [0]:
|
||||||
pass
|
pass
|
||||||
elif i == 0:
|
elif i == 0:
|
||||||
ans = a
|
ans = a
|
||||||
elif i == 1:
|
elif i == 1:
|
||||||
ans = a * (a!=[1]) + [self._letter] + [op.mul] * (a!=[1])
|
ans = a * (a != [1]) + [self._letter] + [op.mul] * (a != [1])
|
||||||
else:
|
else:
|
||||||
ans = a * (a!=[1]) + [self._letter, i, op.pw] + [op.mul] * (a!=[1])
|
ans = a * (a != [1]) + [self._letter, i,
|
||||||
|
op.pw] + [op.mul] * (a != [1])
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@ -208,20 +212,21 @@ class AbstractPolynom(Explicable):
|
|||||||
"""
|
"""
|
||||||
if self == 0:
|
if self == 0:
|
||||||
return [0]
|
return [0]
|
||||||
# TODO: Faudrait factoriser un peu tout ça..! |dim. déc. 21 16:02:34 CET 2014
|
# TODO: Faudrait factoriser un peu tout ça..! |dim. déc. 21 16:02:34
|
||||||
|
# CET 2014
|
||||||
postfix = []
|
postfix = []
|
||||||
for (i,a) in list(enumerate(self._coef))[::-1]:
|
for (i, a) in list(enumerate(self._coef))[::-1]:
|
||||||
operator = [op.add]
|
operator = [op.add]
|
||||||
operator_sub1 = []
|
operator_sub1 = []
|
||||||
if type(a) == Expression:
|
if isinstance(a, Expression):
|
||||||
# case coef is an arithmetic expression
|
# case coef is an arithmetic expression
|
||||||
c = self.coef_postfix(a.postfix_tokens,i)
|
c = self.coef_postfix(a.postfix_tokens, i)
|
||||||
if c != []:
|
if c != []:
|
||||||
postfix.append(c)
|
postfix.append(c)
|
||||||
if len(postfix) > 1:
|
if len(postfix) > 1:
|
||||||
postfix += operator
|
postfix += operator
|
||||||
|
|
||||||
elif type(a) == list:
|
elif isinstance(a, list):
|
||||||
# case need to repeat the x^i
|
# case need to repeat the x^i
|
||||||
for b in a:
|
for b in a:
|
||||||
operator = [op.add]
|
operator = [op.add]
|
||||||
@ -240,7 +245,7 @@ class AbstractPolynom(Explicable):
|
|||||||
operator = [op.sub]
|
operator = [op.sub]
|
||||||
else:
|
else:
|
||||||
b = [b]
|
b = [b]
|
||||||
c = self.coef_postfix(b,i)
|
c = self.coef_postfix(b, i)
|
||||||
if c != []:
|
if c != []:
|
||||||
postfix.append(c)
|
postfix.append(c)
|
||||||
if len(postfix) > 1:
|
if len(postfix) > 1:
|
||||||
@ -264,7 +269,7 @@ class AbstractPolynom(Explicable):
|
|||||||
else:
|
else:
|
||||||
a = [a]
|
a = [a]
|
||||||
|
|
||||||
c = self.coef_postfix(a,i)
|
c = self.coef_postfix(a, i)
|
||||||
if c != []:
|
if c != []:
|
||||||
postfix.append(c)
|
postfix.append(c)
|
||||||
if len(postfix) > 1:
|
if len(postfix) > 1:
|
||||||
@ -285,11 +290,12 @@ class AbstractPolynom(Explicable):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if isNumber(other) and not isPolynom(other):
|
if isNumber(other) and not isPolynom(other):
|
||||||
return AbstractPolynom([other], letter = self._letter)
|
return AbstractPolynom([other], letter=self._letter)
|
||||||
elif isPolynom(other):
|
elif isPolynom(other):
|
||||||
return other
|
return other
|
||||||
else:
|
else:
|
||||||
raise ValueError(type(other) + " can't be converted into a polynom")
|
raise ValueError(type(other) +
|
||||||
|
" can't be converted into a polynom")
|
||||||
|
|
||||||
def reduce(self):
|
def reduce(self):
|
||||||
"""Compute coefficients which have same degree
|
"""Compute coefficients which have same degree
|
||||||
@ -316,14 +322,15 @@ class AbstractPolynom(Explicable):
|
|||||||
[< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, 2], [3, 4, 5], 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, 2, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, 4, '+', 5, '+'] >, 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.calculus.expression.Expression'> [7, 5, '+'] >, 6]>]
|
[< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, 2], [3, 4, 5], 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, 2, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, 4, '+', 5, '+'] >, 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.calculus.expression.Expression'> [7, 5, '+'] >, 6]>]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: It doesn't not compute quick enough |ven. févr. 27 18:04:01 CET 2015
|
# TODO: It doesn't not compute quick enough |ven. févr. 27 18:04:01 CET
|
||||||
|
# 2015
|
||||||
|
|
||||||
# gather steps for every coefficients
|
# gather steps for every coefficients
|
||||||
coefs_steps = []
|
coefs_steps = []
|
||||||
for coef in self._coef:
|
for coef in self._coef:
|
||||||
coef_steps = []
|
coef_steps = []
|
||||||
|
|
||||||
if type(coef) ==list:
|
if isinstance(coef, list):
|
||||||
# Simplify each element before adding them
|
# Simplify each element before adding them
|
||||||
s = []
|
s = []
|
||||||
for c in coef:
|
for c in coef:
|
||||||
@ -339,7 +346,7 @@ class AbstractPolynom(Explicable):
|
|||||||
coef_steps += s
|
coef_steps += s
|
||||||
|
|
||||||
# Convert last element into postfix addition.
|
# Convert last element into postfix addition.
|
||||||
postfix_add = self.postfix_add([i for i in last if i!=0])
|
postfix_add = self.postfix_add([i for i in last if i != 0])
|
||||||
# Convert it to an expression
|
# Convert it to an expression
|
||||||
coef_exp = Expression(postfix_add)
|
coef_exp = Expression(postfix_add)
|
||||||
|
|
||||||
@ -393,12 +400,13 @@ class AbstractPolynom(Explicable):
|
|||||||
>>> AbstractPolynom.postfix_add([])
|
>>> AbstractPolynom.postfix_add([])
|
||||||
[0]
|
[0]
|
||||||
"""
|
"""
|
||||||
if not type(numbers) == list:
|
if not isinstance(numbers, list):
|
||||||
return [numbers]
|
return [numbers]
|
||||||
elif numbers == []:
|
elif numbers == []:
|
||||||
return [0]
|
return [0]
|
||||||
else:
|
else:
|
||||||
ans = [[a, op.add] if i!=0 else [a] for (i,a) in enumerate(numbers)]
|
ans = [[a, op.add] if i != 0 else [a]
|
||||||
|
for (i, a) in enumerate(numbers)]
|
||||||
return list(chain.from_iterable(ans))
|
return list(chain.from_iterable(ans))
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
@ -428,9 +436,10 @@ class AbstractPolynom(Explicable):
|
|||||||
o_poly = self.conv2poly(other)
|
o_poly = self.conv2poly(other)
|
||||||
|
|
||||||
n_coef = spe_zip(self._coef, o_poly._coef)
|
n_coef = spe_zip(self._coef, o_poly._coef)
|
||||||
p = AbstractPolynom(n_coef, letter = self._letter)
|
p = AbstractPolynom(n_coef, letter=self._letter)
|
||||||
|
|
||||||
ini_step = [Expression(self.postfix_tokens + o_poly.postfix_tokens + [op.add])]
|
ini_step = [Expression(self.postfix_tokens +
|
||||||
|
o_poly.postfix_tokens + [op.add])]
|
||||||
ans = p.simplify()
|
ans = p.simplify()
|
||||||
ans.steps = ini_step + ans.steps
|
ans.steps = ini_step + ans.steps
|
||||||
return ans
|
return ans
|
||||||
@ -450,7 +459,8 @@ class AbstractPolynom(Explicable):
|
|||||||
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', '-'] >]
|
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', '-'] >]
|
||||||
"""
|
"""
|
||||||
ini_step = [Expression(self.postfix_tokens + [op.sub1])]
|
ini_step = [Expression(self.postfix_tokens + [op.sub1])]
|
||||||
ans = AbstractPolynom([-i for i in self._coef], letter = self._letter).simplify()
|
ans = AbstractPolynom([-i for i in self._coef],
|
||||||
|
letter=self._letter).simplify()
|
||||||
ans.steps = ini_step + ans.steps
|
ans.steps = ini_step + ans.steps
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@ -473,7 +483,8 @@ class AbstractPolynom(Explicable):
|
|||||||
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', 5, 'x', '*', '+', 4, '+', '-'] >, < <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', '-', 5, 'x', '*', '-', 4, '-', '+'] >, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, -4], [2, -5], [3, -6]]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, -4, '+'] >, < <class 'pymath.calculus.expression.Expression'> [2, -5, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, -6, '+'] >]>]
|
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', 5, 'x', '*', '+', 4, '+', '-'] >, < <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', '-', 5, 'x', '*', '-', 4, '-', '+'] >, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, -4], [2, -5], [3, -6]]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, -4, '+'] >, < <class 'pymath.calculus.expression.Expression'> [2, -5, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, -6, '+'] >]>]
|
||||||
"""
|
"""
|
||||||
o_poly = self.conv2poly(other)
|
o_poly = self.conv2poly(other)
|
||||||
ini_step = [Expression(self.postfix_tokens + o_poly.postfix_tokens + [op.sub])]
|
ini_step = [Expression(self.postfix_tokens +
|
||||||
|
o_poly.postfix_tokens + [op.sub])]
|
||||||
o_poly = -o_poly
|
o_poly = -o_poly
|
||||||
#ini_step += o_poly.steps
|
#ini_step += o_poly.steps
|
||||||
|
|
||||||
@ -518,28 +529,29 @@ class AbstractPolynom(Explicable):
|
|||||||
"""
|
"""
|
||||||
o_poly = self.conv2poly(other)
|
o_poly = self.conv2poly(other)
|
||||||
|
|
||||||
coefs = [0]*(self.degree + o_poly.degree + 1)
|
coefs = [0] * (self.degree + o_poly.degree + 1)
|
||||||
for (i,a) in enumerate(self._coef):
|
for (i, a) in enumerate(self._coef):
|
||||||
for (j,b) in enumerate(o_poly._coef):
|
for (j, b) in enumerate(o_poly._coef):
|
||||||
if a == 0 or b == 0:
|
if a == 0 or b == 0:
|
||||||
elem = 0
|
elem = 0
|
||||||
elif a==1:
|
elif a == 1:
|
||||||
elem = b
|
elem = b
|
||||||
elif b==1:
|
elif b == 1:
|
||||||
elem = a
|
elem = a
|
||||||
else:
|
else:
|
||||||
elem = Expression([a, b, op.mul])
|
elem = Expression([a, b, op.mul])
|
||||||
|
|
||||||
if coefs[i+j]==0:
|
if coefs[i + j] == 0:
|
||||||
coefs[i+j] = elem
|
coefs[i + j] = elem
|
||||||
elif elem != 0:
|
elif elem != 0:
|
||||||
if type(coefs[i+j]) == list:
|
if isinstance(coefs[i + j], list):
|
||||||
coefs[i+j] += [elem]
|
coefs[i + j] += [elem]
|
||||||
else:
|
else:
|
||||||
coefs[i+j] = [coefs[i+j] , elem]
|
coefs[i + j] = [coefs[i + j], elem]
|
||||||
|
|
||||||
p = AbstractPolynom(coefs, letter = self._letter)
|
p = AbstractPolynom(coefs, letter=self._letter)
|
||||||
ini_step = [Expression(self.postfix_tokens + o_poly.postfix_tokens + [op.mul])]
|
ini_step = [Expression(self.postfix_tokens +
|
||||||
|
o_poly.postfix_tokens + [op.mul])]
|
||||||
ans = p.simplify()
|
ans = p.simplify()
|
||||||
|
|
||||||
ans.steps = [ini_step] + ans.steps
|
ans.steps = [ini_step] + ans.steps
|
||||||
@ -573,25 +585,30 @@ class AbstractPolynom(Explicable):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if not type(power):
|
if not type(power):
|
||||||
raise ValueError("Can't raise {obj} to {pw} power".format(obj = self.__class__, pw = str(power)))
|
raise ValueError(
|
||||||
|
"Can't raise {obj} to {pw} power".format(
|
||||||
|
obj=self.__class__, pw=str(power)))
|
||||||
|
|
||||||
ini_step = [Expression(self.postfix_tokens + [power, op.pw])]
|
ini_step = [Expression(self.postfix_tokens + [power, op.pw])]
|
||||||
|
|
||||||
if self.is_monom():
|
if self.is_monom():
|
||||||
if self._coef[self.degree] == 1:
|
if self._coef[self.degree] == 1:
|
||||||
coefs = [0]*self.degree*power + [1]
|
coefs = [0] * self.degree * power + [1]
|
||||||
p = AbstractPolynom(coefs, letter = self._letter)
|
p = AbstractPolynom(coefs, letter=self._letter)
|
||||||
ans = p
|
ans = p
|
||||||
else:
|
else:
|
||||||
coefs = [0]*self.degree*power + [Expression([self._coef[self.degree] , power, op.pw])]
|
coefs = [0] * self.degree * power + \
|
||||||
p = AbstractPolynom(coefs, letter = self._letter)
|
[Expression([self._coef[self.degree], power, op.pw])]
|
||||||
|
p = AbstractPolynom(coefs, letter=self._letter)
|
||||||
ans = p.simplify()
|
ans = p.simplify()
|
||||||
else:
|
else:
|
||||||
if power == 2:
|
if power == 2:
|
||||||
ans = self * self
|
ans = self * self
|
||||||
else:
|
else:
|
||||||
# TODO: faudrait changer ça c'est pas très sérieux |ven. févr. 27 22:08:00 CET 2015
|
# TODO: faudrait changer ça c'est pas très sérieux |ven. févr.
|
||||||
raise AttributeError("__pw__ not implemented yet when power is greatter than 2")
|
# 27 22:08:00 CET 2015
|
||||||
|
raise AttributeError(
|
||||||
|
"__pw__ not implemented yet when power is greatter than 2")
|
||||||
|
|
||||||
ans.steps = ini_step + ans.steps
|
ans.steps = ini_step + ans.steps
|
||||||
return ans
|
return ans
|
||||||
@ -600,13 +617,13 @@ class AbstractPolynom(Explicable):
|
|||||||
return self.__pow__(power)
|
return self.__pow__(power)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
P = AbstractPolynom([[1,2],[3,4,5],6])
|
P = AbstractPolynom([[1, 2], [3, 4, 5], 6])
|
||||||
Q = P.reduce()
|
Q = P.reduce()
|
||||||
for i in Q.explain():
|
for i in Q.explain():
|
||||||
print(i)
|
print(i)
|
||||||
|
|
||||||
#import doctest
|
#import doctest
|
||||||
#doctest.testmod()
|
# doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
@ -4,32 +4,33 @@
|
|||||||
|
|
||||||
__all__ = ['gcd']
|
__all__ = ['gcd']
|
||||||
|
|
||||||
|
|
||||||
def gcd(a, b):
|
def gcd(a, b):
|
||||||
"""Compute gcd(a,b)
|
"""Compute gcd(a,b)
|
||||||
|
|
||||||
:param a: first number
|
:param a: first number
|
||||||
:param b: second number
|
:param b: second number
|
||||||
:returns: the gcd
|
:returns: the gcd
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pos_a, _a = (a >= 0), abs(a)
|
pos_a, _a = (a >= 0), abs(a)
|
||||||
pos_b, _b = (b >= 0), abs(b)
|
pos_b, _b = (b >= 0), abs(b)
|
||||||
|
|
||||||
gcd_sgn = (-1 + 2*(pos_a or pos_b))
|
gcd_sgn = (-1 + 2 * (pos_a or pos_b))
|
||||||
|
|
||||||
if _a > _b:
|
if _a > _b:
|
||||||
c = _a % _b
|
c = _a % _b
|
||||||
else:
|
else:
|
||||||
c = _b % _a
|
c = _b % _a
|
||||||
|
|
||||||
if c == 0:
|
if c == 0:
|
||||||
return gcd_sgn * min(_a,_b)
|
return gcd_sgn * min(_a, _b)
|
||||||
elif _a == 1:
|
elif _a == 1:
|
||||||
return gcd_sgn * _b
|
return gcd_sgn * _b
|
||||||
elif _b == 1:
|
elif _b == 1:
|
||||||
return gcd_sgn * _a
|
return gcd_sgn * _a
|
||||||
else:
|
else:
|
||||||
return gcd_sgn * gcd(min(_a,_b), c)
|
return gcd_sgn * gcd(min(_a, _b), c)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(gcd(3, 15))
|
print(gcd(3, 15))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
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.
|
A Renderable object is an object which can work with Render class. It means that it has to have attribute postfix_tokens.
|
||||||
@ -23,7 +24,7 @@ class Renderable(object):
|
|||||||
cls.set_render(cls.DEFAULT_RENDER)
|
cls.set_render(cls.DEFAULT_RENDER)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tmp_render(cls, render = tex):
|
def tmp_render(cls, render=tex):
|
||||||
""" Create a container in which Expression render is temporary modify
|
""" Create a container in which Expression render is temporary modify
|
||||||
|
|
||||||
The default temporary render is Expression in order to perform calculus inside numbers
|
The default temporary render is Expression in order to perform calculus inside numbers
|
||||||
@ -56,6 +57,7 @@ class Renderable(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
class TmpRenderEnv(object):
|
class TmpRenderEnv(object):
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.old_render = Renderable.get_render()
|
self.old_render = Renderable.get_render()
|
||||||
Renderable.set_render(render)
|
Renderable.set_render(render)
|
||||||
@ -72,7 +74,6 @@ class Renderable(object):
|
|||||||
return False
|
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!
|
||||||
@ -82,10 +83,11 @@ class Explicable(Renderable):
|
|||||||
* explain: Generator which return steps which leed to himself
|
* explain: Generator which return steps which leed to himself
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.steps = []
|
self.steps = []
|
||||||
|
|
||||||
def explain(self, noself = True):
|
def explain(self, noself=True):
|
||||||
""" Generate and render steps which leed to itself
|
""" Generate and render steps which leed to itself
|
||||||
|
|
||||||
:param noself: does explain return self
|
:param noself: does explain return self
|
||||||
@ -126,9 +128,6 @@ class Explicable(Renderable):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
#debuging
|
# debuging
|
||||||
#from debug.tools import report
|
#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
|
||||||
@ -13,13 +13,16 @@ from .random_expression import RdExpression
|
|||||||
|
|
||||||
__all__ = ['Expression']
|
__all__ = ['Expression']
|
||||||
|
|
||||||
|
|
||||||
class Fake_int(int, Explicable):
|
class Fake_int(int, Explicable):
|
||||||
isNumber = True
|
isNumber = True
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
super(Fake_int, self).__init__(val)
|
super(Fake_int, self).__init__(val)
|
||||||
self._val = val
|
self._val = val
|
||||||
self.postfix_tokens = [self]
|
self.postfix_tokens = [self]
|
||||||
self.steps = []
|
self.steps = []
|
||||||
|
|
||||||
def simplify(self):
|
def simplify(self):
|
||||||
return Fake_int(self._val)
|
return Fake_int(self._val)
|
||||||
|
|
||||||
@ -28,7 +31,7 @@ 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
|
||||||
|
|
||||||
:param form: the form of the expression (/!\ variables need to be in brackets {})
|
:param form: the form of the expression (/!\ variables need to be in brackets {})
|
||||||
@ -41,7 +44,7 @@ class Expression(Explicable):
|
|||||||
return Expression(random_generator(val_min, val_max))
|
return Expression(random_generator(val_min, val_max))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tmp_render(cls, render = lambda _,x:Expression(x)):
|
def tmp_render(cls, render=lambda _, x: Expression(x)):
|
||||||
""" Same ad tmp_render for Renderable but default render is Expression
|
""" Same ad tmp_render for Renderable but default render is Expression
|
||||||
|
|
||||||
>>> exp = Expression("2*3/5")
|
>>> exp = Expression("2*3/5")
|
||||||
@ -87,44 +90,56 @@ class Expression(Explicable):
|
|||||||
"""
|
"""
|
||||||
expression = object.__new__(cls)
|
expression = object.__new__(cls)
|
||||||
|
|
||||||
if type(exp) == str:
|
if isinstance(exp, str):
|
||||||
expression.postfix_tokens = str2tokens(exp)
|
expression.postfix_tokens = str2tokens(exp)
|
||||||
|
|
||||||
elif type(exp) == list:
|
elif isinstance(exp, list):
|
||||||
# Ici on ne peut convertir les "+" en opérateur que s'ils sont d'arité 2.
|
# Ici on ne peut convertir les "+" en opérateur que s'ils sont
|
||||||
exp_mod_op = [op.get_op(i) if op.can_be_operator(i) else i for i in exp]
|
# d'arité 2.
|
||||||
expression.postfix_tokens = flatten_list([tok.postfix_tokens if Expression.isExpression(tok) else tok for tok in exp_mod_op])
|
exp_mod_op = [
|
||||||
|
op.get_op(i) if op.can_be_operator(i) else i for i in exp]
|
||||||
|
expression.postfix_tokens = flatten_list(
|
||||||
|
[tok.postfix_tokens if Expression.isExpression(tok) else tok for tok in exp_mod_op])
|
||||||
|
|
||||||
elif type(exp) == Expression:
|
elif isinstance(exp, Expression):
|
||||||
return exp
|
return exp
|
||||||
|
|
||||||
elif isNumerand(exp):
|
elif isNumerand(exp):
|
||||||
expression.postfix_tokens = [exp]
|
expression.postfix_tokens = [exp]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Can't build Expression with {} object".format(type(exp)))
|
raise ValueError(
|
||||||
|
"Can't build Expression with {} object".format(
|
||||||
|
type(exp)))
|
||||||
|
|
||||||
if len(expression.postfix_tokens) == 1:
|
if len(expression.postfix_tokens) == 1:
|
||||||
token = expression.postfix_tokens[0]
|
token = expression.postfix_tokens[0]
|
||||||
|
|
||||||
if type(token) == Fake_int or type(token) == int:
|
if isinstance(token, Fake_int) or isinstance(token, int):
|
||||||
return Fake_int(token)
|
return Fake_int(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 type(token) == str:
|
elif isinstance(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
|
||||||
# On crée un faux str en ajoutant la méthode simplify et simplified et la caractérisique isNumber
|
# On crée un faux str en ajoutant la méthode simplify et
|
||||||
simplify = lambda x:[x]
|
# simplified et la caractérisique isNumber
|
||||||
|
simplify = lambda x: [x]
|
||||||
is_polynom = True
|
is_polynom = True
|
||||||
methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]}
|
methods_attr = {
|
||||||
fake_token = type('fake_str', (str,Explicable, ), methods_attr)(token)
|
'simplify': simplify,
|
||||||
|
'_isPolynom': is_polynom,
|
||||||
|
'postfix_tokens': [token]}
|
||||||
|
fake_token = type(
|
||||||
|
'fake_str', (str, Explicable, ), methods_attr)(token)
|
||||||
return fake_token
|
return fake_token
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknow token type in Expression: {}".format(type(token)))
|
raise ValueError(
|
||||||
|
"Unknow token type in Expression: {}".format(
|
||||||
|
type(token)))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
expression._isExpression = 1
|
expression._isExpression = 1
|
||||||
@ -139,7 +154,8 @@ class Expression(Explicable):
|
|||||||
return self.STR_RENDER(self.postfix_tokens)
|
return self.STR_RENDER(self.postfix_tokens)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return " ".join(["<", str(self.__class__) , str(self.postfix_tokens), ">"])
|
return " ".join(["<", str(self.__class__),
|
||||||
|
str(self.postfix_tokens), ">"])
|
||||||
|
|
||||||
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 """
|
||||||
@ -157,9 +173,10 @@ class Expression(Explicable):
|
|||||||
tmpTokenList = []
|
tmpTokenList = []
|
||||||
|
|
||||||
while len(tokenList) > 2:
|
while len(tokenList) > 2:
|
||||||
# on va chercher les motifs du genre A B +, quand l'operateur est d'arité 2, pour les calculer
|
# on va chercher les motifs du genre A B +, quand l'operateur est
|
||||||
|
# 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]
|
||||||
@ -170,7 +187,8 @@ class Expression(Explicable):
|
|||||||
|
|
||||||
tmpTokenList.append(res)
|
tmpTokenList.append(res)
|
||||||
|
|
||||||
# Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes
|
# Comme on vient de faire le calcul, on peut détruire aussi les
|
||||||
|
# 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
|
||||||
@ -185,7 +203,8 @@ class Expression(Explicable):
|
|||||||
|
|
||||||
tmpTokenList.append(res)
|
tmpTokenList.append(res)
|
||||||
|
|
||||||
# Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes
|
# Comme on vient de faire le calcul, on peut détruire aussi les
|
||||||
|
# deux prochains termes
|
||||||
del tokenList[0:2]
|
del tokenList[0:2]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -194,7 +213,7 @@ class Expression(Explicable):
|
|||||||
del tokenList[0]
|
del tokenList[0]
|
||||||
|
|
||||||
if len(tokenList) == 2 and isNumerand(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 reste deux éléments dont un operation d'arité 1
|
||||||
op1 = tokenList[0]
|
op1 = tokenList[0]
|
||||||
operator = tokenList[1]
|
operator = tokenList[1]
|
||||||
@ -203,7 +222,8 @@ class Expression(Explicable):
|
|||||||
|
|
||||||
tmpTokenList.append(res)
|
tmpTokenList.append(res)
|
||||||
|
|
||||||
# Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes
|
# Comme on vient de faire le calcul, on peut détruire aussi les
|
||||||
|
# deux prochains termes
|
||||||
del tokenList[0:2]
|
del tokenList[0:2]
|
||||||
|
|
||||||
tmpTokenList += tokenList
|
tmpTokenList += tokenList
|
||||||
@ -239,8 +259,8 @@ class Expression(Explicable):
|
|||||||
try:
|
try:
|
||||||
other._isExpression
|
other._isExpression
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# -----------
|
# -----------
|
||||||
# Expression act as container from self.postfix_tokens
|
# Expression act as container from self.postfix_tokens
|
||||||
@ -255,17 +275,23 @@ class Expression(Explicable):
|
|||||||
# Some math manipulations
|
# Some math manipulations
|
||||||
|
|
||||||
def operate(self, other, operator):
|
def operate(self, other, operator):
|
||||||
if type(other) == Expression:
|
if isinstance(other, Expression):
|
||||||
return Expression(self.postfix_tokens + other.postfix_tokens + [operator])
|
return Expression(
|
||||||
elif type(other) == list:
|
self.postfix_tokens +
|
||||||
|
other.postfix_tokens +
|
||||||
|
[operator])
|
||||||
|
elif isinstance(other, list):
|
||||||
return Expression(self.postfix_tokens + other + [operator])
|
return Expression(self.postfix_tokens + other + [operator])
|
||||||
else:
|
else:
|
||||||
return Expression(self.postfix_tokens + [other] + [operator])
|
return Expression(self.postfix_tokens + [other] + [operator])
|
||||||
|
|
||||||
def roperate(self, other, operator):
|
def roperate(self, other, operator):
|
||||||
if type(other) == Expression:
|
if isinstance(other, Expression):
|
||||||
return Expression(other.postfix_tokens + self.postfix_tokens + [operator])
|
return Expression(
|
||||||
elif type(other) == list:
|
other.postfix_tokens +
|
||||||
|
self.postfix_tokens +
|
||||||
|
[operator])
|
||||||
|
elif isinstance(other, list):
|
||||||
return Expression(other + self.postfix_tokens + [operator])
|
return Expression(other + self.postfix_tokens + [operator])
|
||||||
else:
|
else:
|
||||||
return Expression([other] + self.postfix_tokens + [operator])
|
return Expression([other] + self.postfix_tokens + [operator])
|
||||||
@ -358,7 +384,7 @@ def untest(exp):
|
|||||||
b = a.simplify()
|
b = a.simplify()
|
||||||
|
|
||||||
for i in b.explain():
|
for i in b.explain():
|
||||||
#print(type(i))
|
# print(type(i))
|
||||||
print(i)
|
print(i)
|
||||||
|
|
||||||
#print(type(a.simplified()), ":", a.simplified())
|
#print(type(a.simplified()), ":", a.simplified())
|
||||||
@ -371,27 +397,26 @@ if __name__ == '__main__':
|
|||||||
Ar = A.simplify()
|
Ar = A.simplify()
|
||||||
for i in Ar.explain():
|
for i in Ar.explain():
|
||||||
print(i)
|
print(i)
|
||||||
#print("------------")
|
# print("------------")
|
||||||
#for i in Ar.explain():
|
# for i in Ar.explain():
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
#print(type(Ar))
|
# print(type(Ar))
|
||||||
|
|
||||||
|
# print('\n-----------')
|
||||||
#print('\n-----------')
|
|
||||||
#A = Expression("-6 / 3 + 10 / -5")
|
#A = Expression("-6 / 3 + 10 / -5")
|
||||||
#Ar = A.simplify()
|
#Ar = A.simplify()
|
||||||
#for i in Ar.explain():
|
# for i in Ar.explain():
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
#print('\n-----------')
|
# print('\n-----------')
|
||||||
#A = Expression("1/3 + 4/6")
|
#A = Expression("1/3 + 4/6")
|
||||||
#Ar = A.simplify()
|
#Ar = A.simplify()
|
||||||
#for i in Ar.explain():
|
# for i in Ar.explain():
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
#import doctest
|
#import doctest
|
||||||
#doctest.testmod()
|
# doctest.testmod()
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
|
@ -12,10 +12,11 @@ from copy import copy
|
|||||||
|
|
||||||
__all__ = ['Fraction']
|
__all__ = ['Fraction']
|
||||||
|
|
||||||
|
|
||||||
class Fraction(Explicable):
|
class Fraction(Explicable):
|
||||||
"""Fractions!"""
|
"""Fractions!"""
|
||||||
|
|
||||||
def __init__(self, num, denom = 1):
|
def __init__(self, num, denom=1):
|
||||||
"""To initiate a fraction we need a numerator and a denominator
|
"""To initiate a fraction we need a numerator and a denominator
|
||||||
|
|
||||||
:param num: the numerator
|
:param num: the numerator
|
||||||
@ -61,7 +62,7 @@ class Fraction(Explicable):
|
|||||||
if self._num == 0:
|
if self._num == 0:
|
||||||
return Expression([0])
|
return Expression([0])
|
||||||
|
|
||||||
elif type(self._num) == Fraction or type(self._denom) == Fraction:
|
elif isinstance(self._num, Fraction) or isinstance(self._denom, Fraction):
|
||||||
return self._num / self._denom
|
return self._num / self._denom
|
||||||
|
|
||||||
elif self._denom < 0:
|
elif self._denom < 0:
|
||||||
@ -76,8 +77,14 @@ class Fraction(Explicable):
|
|||||||
return Expression([n_frac])
|
return Expression([n_frac])
|
||||||
|
|
||||||
elif gcd_ != 1:
|
elif gcd_ != 1:
|
||||||
n_frac = Fraction(self._num // gcd_ , self._denom // gcd_)
|
n_frac = Fraction(self._num // gcd_, self._denom // gcd_)
|
||||||
ini_step += [Expression([n_frac._num, gcd_, op.mul, n_frac._denom, gcd_, op.mul, op.div ])]
|
ini_step += [Expression([n_frac._num,
|
||||||
|
gcd_,
|
||||||
|
op.mul,
|
||||||
|
n_frac._denom,
|
||||||
|
gcd_,
|
||||||
|
op.mul,
|
||||||
|
op.div])]
|
||||||
|
|
||||||
n_frac.steps = ini_step + n_frac.steps
|
n_frac.steps = ini_step + n_frac.steps
|
||||||
return n_frac
|
return n_frac
|
||||||
@ -103,7 +110,8 @@ class Fraction(Explicable):
|
|||||||
return str(Expression(self.postfix_tokens))
|
return str(Expression(self.postfix_tokens))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "< Fraction {num} / {denom}>".format(num=self._num, denom = self._denom)
|
return "< Fraction {num} / {denom}>".format(
|
||||||
|
num=self._num, denom=self._denom)
|
||||||
|
|
||||||
def __txt__(self):
|
def __txt__(self):
|
||||||
old_render = Expression.get_render()
|
old_render = Expression.get_render()
|
||||||
@ -126,8 +134,8 @@ class Fraction(Explicable):
|
|||||||
|
|
||||||
def convert2fraction(self, other):
|
def convert2fraction(self, other):
|
||||||
""" Convert a other into a fraction """
|
""" Convert a other into a fraction """
|
||||||
if type(other) == Fraction:
|
if isinstance(other, Fraction):
|
||||||
#cool
|
# cool
|
||||||
number = other
|
number = other
|
||||||
else:
|
else:
|
||||||
number = Fraction(other)
|
number = Fraction(other)
|
||||||
@ -188,10 +196,25 @@ class Fraction(Explicable):
|
|||||||
coef1 = number._denom // gcd_denom
|
coef1 = number._denom // gcd_denom
|
||||||
coef2 = self._denom // gcd_denom
|
coef2 = self._denom // gcd_denom
|
||||||
|
|
||||||
exp = Expression([self._num, coef1, op.mul, self._denom, coef1, op.mul, op.div, number._num, coef2, op.mul, number._denom, coef2, op.mul, op.div,op.add])
|
exp = Expression([self._num,
|
||||||
|
coef1,
|
||||||
|
op.mul,
|
||||||
|
self._denom,
|
||||||
|
coef1,
|
||||||
|
op.mul,
|
||||||
|
op.div,
|
||||||
|
number._num,
|
||||||
|
coef2,
|
||||||
|
op.mul,
|
||||||
|
number._denom,
|
||||||
|
coef2,
|
||||||
|
op.mul,
|
||||||
|
op.div,
|
||||||
|
op.add])
|
||||||
|
|
||||||
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
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@ -240,9 +263,24 @@ class Fraction(Explicable):
|
|||||||
coef1 = number._denom // gcd_denom
|
coef1 = number._denom // gcd_denom
|
||||||
coef2 = self._denom // gcd_denom
|
coef2 = self._denom // gcd_denom
|
||||||
|
|
||||||
exp = Expression([self._num, coef1, op.mul, self._denom, coef1, op.mul, op.div, number._num, coef2, op.mul, number._denom, coef2, op.mul, op.div,op.sub])
|
exp = Expression([self._num,
|
||||||
|
coef1,
|
||||||
|
op.mul,
|
||||||
|
self._denom,
|
||||||
|
coef1,
|
||||||
|
op.mul,
|
||||||
|
op.div,
|
||||||
|
number._num,
|
||||||
|
coef2,
|
||||||
|
op.mul,
|
||||||
|
number._denom,
|
||||||
|
coef2,
|
||||||
|
op.mul,
|
||||||
|
op.div,
|
||||||
|
op.sub])
|
||||||
|
|
||||||
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.sub])
|
ini_step = Expression(self.postfix_tokens +
|
||||||
|
number.postfix_tokens + [op.sub])
|
||||||
ans = exp.simplify()
|
ans = exp.simplify()
|
||||||
ans.steps = [ini_step] + ans.steps
|
ans.steps = [ini_step] + ans.steps
|
||||||
return ans
|
return ans
|
||||||
@ -273,7 +311,7 @@ class Fraction(Explicable):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
f = Fraction(-self._num, self._denom)
|
f = Fraction(-self._num, self._denom)
|
||||||
ans = f.simplify()
|
ans = f.simplify()
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@ -313,13 +351,14 @@ class Fraction(Explicable):
|
|||||||
elif other == 1:
|
elif other == 1:
|
||||||
return copy(self)
|
return copy(self)
|
||||||
|
|
||||||
# TODO: Changer dans le cas où il y a trop de 1 |dim. déc. 28 10:44:10 CET 2014
|
# TODO: Changer dans le cas où il y a trop de 1 |dim. déc. 28 10:44:10
|
||||||
|
# CET 2014
|
||||||
|
|
||||||
elif type(other) == int:
|
elif isinstance(other, int):
|
||||||
gcd1 = gcd(other, self._denom)
|
gcd1 = gcd(other, self._denom)
|
||||||
if gcd1 != 1:
|
if gcd1 != 1:
|
||||||
num = [self._num, int(other/gcd1), op.mul, gcd1,op.mul]
|
num = [self._num, int(other / gcd1), op.mul, gcd1, op.mul]
|
||||||
denom = [int(self._denom/gcd1), gcd1, op.mul]
|
denom = [int(self._denom / gcd1), gcd1, op.mul]
|
||||||
else:
|
else:
|
||||||
num = [self._num, other, op.mul]
|
num = [self._num, other, op.mul]
|
||||||
denom = [self._denom]
|
denom = [self._denom]
|
||||||
@ -332,24 +371,29 @@ class Fraction(Explicable):
|
|||||||
|
|
||||||
gcd1 = gcd(self._num, number._denom)
|
gcd1 = gcd(self._num, number._denom)
|
||||||
if gcd1 != 1:
|
if gcd1 != 1:
|
||||||
num1 = [int(self._num/ gcd1), gcd1, op.mul]
|
num1 = [int(self._num / gcd1), gcd1, op.mul]
|
||||||
denom2 = [int(number._denom/ gcd1), gcd1, op.mul]
|
denom2 = [int(number._denom / gcd1), gcd1, op.mul]
|
||||||
else:
|
else:
|
||||||
num1 = [self._num]
|
num1 = [self._num]
|
||||||
denom2 = [number._denom]
|
denom2 = [number._denom]
|
||||||
|
|
||||||
gcd2 = gcd(self._denom, number._num)
|
gcd2 = gcd(self._denom, number._num)
|
||||||
if gcd2 != 1:
|
if gcd2 != 1:
|
||||||
num2 = [int(number._num/ gcd2), gcd2, op.mul]
|
num2 = [int(number._num / gcd2), gcd2, op.mul]
|
||||||
denom1 = [int(self._denom/ gcd2), gcd2, op.mul]
|
denom1 = [int(self._denom / gcd2), gcd2, op.mul]
|
||||||
else:
|
else:
|
||||||
num2 = [number._num]
|
num2 = [number._num]
|
||||||
denom1 = [self._denom]
|
denom1 = [self._denom]
|
||||||
|
|
||||||
|
exp = Expression(num1 +
|
||||||
|
num2 +
|
||||||
|
[op.mul] +
|
||||||
|
denom1 +
|
||||||
|
denom2 +
|
||||||
|
[op.mul, op.div])
|
||||||
|
|
||||||
exp = Expression(num1 + num2 + [ op.mul] + denom1 + denom2 + [op.mul, op.div])
|
ini_step = Expression(self.postfix_tokens +
|
||||||
|
number.postfix_tokens + [op.mul])
|
||||||
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.mul])
|
|
||||||
ans = exp.simplify()
|
ans = exp.simplify()
|
||||||
ans.steps = [ini_step] + ans.steps
|
ans.steps = [ini_step] + ans.steps
|
||||||
return ans
|
return ans
|
||||||
@ -381,7 +425,8 @@ class Fraction(Explicable):
|
|||||||
|
|
||||||
number = self.convert2fraction(other)
|
number = self.convert2fraction(other)
|
||||||
|
|
||||||
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.div])
|
ini_step = Expression(self.postfix_tokens +
|
||||||
|
number.postfix_tokens + [op.div])
|
||||||
|
|
||||||
number = Fraction(number._denom, number._num)
|
number = Fraction(number._denom, number._num)
|
||||||
ans = self * number
|
ans = self * number
|
||||||
@ -421,8 +466,10 @@ class Fraction(Explicable):
|
|||||||
< <class 'pymath.calculus.expression.Expression'> [27, 8, '*', 8, 8, '*', '/'] >
|
< <class 'pymath.calculus.expression.Expression'> [27, 8, '*', 8, 8, '*', '/'] >
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not type(power) == int:
|
if not isinstance(power, int):
|
||||||
raise ValueError("Can't raise fraction to power {}".format(str(power)))
|
raise ValueError(
|
||||||
|
"Can't raise fraction to power {}".format(
|
||||||
|
str(power)))
|
||||||
|
|
||||||
if power == 0:
|
if power == 0:
|
||||||
return Expression([1])
|
return Expression([1])
|
||||||
@ -430,7 +477,8 @@ class Fraction(Explicable):
|
|||||||
return copy(self)
|
return copy(self)
|
||||||
else:
|
else:
|
||||||
ini_step = Expression(self.postfix_tokens + [power, op.pw])
|
ini_step = Expression(self.postfix_tokens + [power, op.pw])
|
||||||
exp = Expression([self._num, power, op.pw, self._denom, power, op.pw, op.div])
|
exp = Expression(
|
||||||
|
[self._num, power, op.pw, self._denom, power, op.pw, op.div])
|
||||||
|
|
||||||
ans = exp.simplify()
|
ans = exp.simplify()
|
||||||
ans.steps = [ini_step] + ans.steps
|
ans.steps = [ini_step] + ans.steps
|
||||||
@ -485,71 +533,70 @@ class Fraction(Explicable):
|
|||||||
return Fraction(self._num, self._denom)
|
return Fraction(self._num, self._denom)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
f = Fraction(1, 12)
|
f = Fraction(1, 12)
|
||||||
g = Fraction(6, 12)
|
g = Fraction(6, 12)
|
||||||
for i in g.simplify().explain():
|
for i in g.simplify().explain():
|
||||||
print("g = ",i)
|
print("g = ", i)
|
||||||
h = Fraction(1,-5)
|
h = Fraction(1, -5)
|
||||||
t = Fraction(10,3)
|
t = Fraction(10, 3)
|
||||||
print("---------")
|
print("---------")
|
||||||
for i in (0 + h).explain():
|
for i in (0 + h).explain():
|
||||||
print('0 + h = ',i)
|
print('0 + h = ', i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(f) , "+", str(t))
|
#print(str(f) , "+", str(t))
|
||||||
#for i in (f + t):
|
# for i in (f + t):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(f) , "+", str(g))
|
#print(str(f) , "+", str(g))
|
||||||
#for i in (f + g):
|
# for i in (f + g):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(f) , "-", str(g))
|
#print(str(f) , "-", str(g))
|
||||||
#for i in (f - g):
|
# for i in (f - g):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(f) , "*", str(g))
|
#print(str(f) , "*", str(g))
|
||||||
#for i in (f * g):
|
# for i in (f * g):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "+", str(t))
|
#print(str(h) , "+", str(t))
|
||||||
#for i in (h + t):
|
# for i in (h + t):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "-", str(t))
|
#print(str(h) , "-", str(t))
|
||||||
#for i in (h - t):
|
# for i in (h - t):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "*", str(t))
|
#print(str(h) , "*", str(t))
|
||||||
#for i in (h * t):
|
# for i in (h * t):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print("-", str(h) )
|
#print("-", str(h) )
|
||||||
#for i in (-h):
|
# for i in (-h):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "/", str(t))
|
#print(str(h) , "/", str(t))
|
||||||
#for i in (h / t):
|
# for i in (h / t):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "+", str(0))
|
#print(str(h) , "+", str(0))
|
||||||
#for i in (h + 0):
|
# for i in (h + 0):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "*", str(1))
|
#print(str(h) , "*", str(1))
|
||||||
#for i in (h * 1):
|
# for i in (h * 1):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "*", str(0))
|
#print(str(h) , "*", str(0))
|
||||||
#for i in (h * 0):
|
# for i in (h * 0):
|
||||||
# print(i)
|
# print(i)
|
||||||
#print("---------")
|
# print("---------")
|
||||||
#print(str(h) , "*", str(4))
|
#print(str(h) , "*", str(4))
|
||||||
#for i in (h * 4):
|
# for i in (h * 4):
|
||||||
# print(i)
|
# print(i)
|
||||||
|
|
||||||
#print(f.simplify())
|
# print(f.simplify())
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
|
|
||||||
|
|
||||||
class Stack(object):
|
class Stack(object):
|
||||||
"""Docstring for Stack """
|
"""Docstring for Stack """
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ class Stack(object):
|
|||||||
"""
|
"""
|
||||||
return self.items == []
|
return self.items == []
|
||||||
|
|
||||||
def push(self, item):
|
def push(self, item):
|
||||||
"""Push an item in the stack
|
"""Push an item in the stack
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -37,7 +38,7 @@ class Stack(object):
|
|||||||
"""
|
"""
|
||||||
return self.items.pop()
|
return self.items.pop()
|
||||||
|
|
||||||
def peek(self, posi = 0):
|
def peek(self, posi=0):
|
||||||
"""Getting the last item
|
"""Getting the last item
|
||||||
:param posi: which item to peek 0 (last) 1 (the onebefore the last)...
|
:param posi: which item to peek 0 (last) 1 (the onebefore the last)...
|
||||||
:returns: the item
|
:returns: the item
|
||||||
@ -54,6 +55,7 @@ class Stack(object):
|
|||||||
def __add__(self, addList):
|
def __add__(self, addList):
|
||||||
return self.items + addList
|
return self.items + addList
|
||||||
|
|
||||||
|
|
||||||
def flatten_list(a, result=None):
|
def flatten_list(a, result=None):
|
||||||
"""Flattens a nested list.
|
"""Flattens a nested list.
|
||||||
|
|
||||||
@ -71,6 +73,7 @@ def flatten_list(a, result=None):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def first_elem(ll):
|
def first_elem(ll):
|
||||||
"""Get the first element in imbricates lists
|
"""Get the first element in imbricates lists
|
||||||
# TODO: Fonction pourrie mais j'ai pas le temps de faire mieux! |mar. janv. 28 22:32:22 CET 2014
|
# TODO: Fonction pourrie mais j'ai pas le temps de faire mieux! |mar. janv. 28 22:32:22 CET 2014
|
||||||
@ -93,13 +96,14 @@ def first_elem(ll):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if hasattr(ll, '__contains__'):
|
if hasattr(ll, '__contains__'):
|
||||||
if len(ll) == 1 and type(ll) == str:
|
if len(ll) == 1 and isinstance(ll, str):
|
||||||
return ll[0]
|
return ll[0]
|
||||||
else:
|
else:
|
||||||
return first_elem(ll[0])
|
return first_elem(ll[0])
|
||||||
else:
|
else:
|
||||||
return ll
|
return ll
|
||||||
|
|
||||||
|
|
||||||
def last_elem(ll):
|
def last_elem(ll):
|
||||||
"""Get the last element in imbricates lists
|
"""Get the last element in imbricates lists
|
||||||
# TODO: Fonction pourrie mais j'ai pas le temps de faire mieux! |mar. janv. 28 22:32:22 CET 2014
|
# TODO: Fonction pourrie mais j'ai pas le temps de faire mieux! |mar. janv. 28 22:32:22 CET 2014
|
||||||
@ -122,7 +126,7 @@ def last_elem(ll):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if hasattr(ll, '__contains__'):
|
if hasattr(ll, '__contains__'):
|
||||||
if len(ll) == 1 and type(ll) == str:
|
if len(ll) == 1 and isinstance(ll, str):
|
||||||
return ll[-1]
|
return ll[-1]
|
||||||
else:
|
else:
|
||||||
return last_elem(ll[-1])
|
return last_elem(ll[-1])
|
||||||
@ -139,22 +143,23 @@ def expand_list(list_list):
|
|||||||
[[1, 2, 4, 5, 6, 7, 8]]
|
[[1, 2, 4, 5, 6, 7, 8]]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
list_in_list = [i for i in list_list if type(i) == list].copy()
|
list_in_list = [i for i in list_list if isinstance(i, list)].copy()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nbr_ans_list = max([len(i) for i in list_in_list])
|
nbr_ans_list = max([len(i) for i in list_in_list])
|
||||||
|
|
||||||
ans = [list_list.copy() for i in range(nbr_ans_list)]
|
ans = [list_list.copy() for i in range(nbr_ans_list)]
|
||||||
for (i,l) in enumerate(ans):
|
for (i, l) in enumerate(ans):
|
||||||
for (j,e) in enumerate(l):
|
for (j, e) in enumerate(l):
|
||||||
if type(e) == list:
|
if isinstance(e, list):
|
||||||
ans[i][j] = e[min(i,len(e)-1)]
|
ans[i][j] = e[min(i, len(e) - 1)]
|
||||||
# S'il n'y a pas de liste dans la liste (2e exemple)
|
# S'il n'y a pas de liste dans la liste (2e exemple)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
ans = [list_list]
|
ans = [list_list]
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def add_in_dict(dict1, dict2):
|
def add_in_dict(dict1, dict2):
|
||||||
"""Merge dictionary keys and add the content from dict1 and dict2
|
"""Merge dictionary keys and add the content from dict1 and dict2
|
||||||
|
|
||||||
@ -172,7 +177,7 @@ def add_in_dict(dict1, dict2):
|
|||||||
"""
|
"""
|
||||||
new_dict = {}
|
new_dict = {}
|
||||||
new_dict.update(dict1)
|
new_dict.update(dict1)
|
||||||
for (k,v) in dict2.items():
|
for (k, v) in dict2.items():
|
||||||
if k in new_dict.keys():
|
if k in new_dict.keys():
|
||||||
new_dict[k] += v
|
new_dict[k] += v
|
||||||
else:
|
else:
|
||||||
@ -180,7 +185,8 @@ def add_in_dict(dict1, dict2):
|
|||||||
|
|
||||||
return new_dict
|
return new_dict
|
||||||
|
|
||||||
def remove_in_dict(d, value = 0):
|
|
||||||
|
def remove_in_dict(d, value=0):
|
||||||
""" In a dictionary, remove keys which have certain value
|
""" In a dictionary, remove keys which have certain value
|
||||||
|
|
||||||
:param d: the dictionary
|
:param d: the dictionary
|
||||||
@ -193,14 +199,15 @@ def remove_in_dict(d, value = 0):
|
|||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
new_dict = {}
|
new_dict = {}
|
||||||
for (k,v) in d.items():
|
for (k, v) in d.items():
|
||||||
if v != value:
|
if v != value:
|
||||||
new_dict[k] = v
|
new_dict[k] = v
|
||||||
return new_dict
|
return new_dict
|
||||||
|
|
||||||
def convolution_dict(D1, D2, op = lambda x,y:x*y,\
|
|
||||||
op_key = lambda x,y: x + y, \
|
def convolution_dict(D1, D2, op=lambda x, y: x * y,
|
||||||
commutative = True, op_twice = lambda x,y: x + y):
|
op_key=lambda x, y: x + y,
|
||||||
|
commutative=True, op_twice=lambda x, y: x + y):
|
||||||
"""Convolution of two dictionaries
|
"""Convolution of two dictionaries
|
||||||
|
|
||||||
:param D1: First dictionary
|
:param D1: First dictionary
|
||||||
@ -226,21 +233,22 @@ def convolution_dict(D1, D2, op = lambda x,y:x*y,\
|
|||||||
|
|
||||||
for k1 in sorted(D1.keys()):
|
for k1 in sorted(D1.keys()):
|
||||||
for k2 in sorted(D2.keys()):
|
for k2 in sorted(D2.keys()):
|
||||||
if op_key(k1,k2) in new_dict.keys():
|
if op_key(k1, k2) in new_dict.keys():
|
||||||
key = op_key(k1,k2)
|
key = op_key(k1, k2)
|
||||||
new_dict[key] = op_twice(new_dict[key], op(D1[k1],D2[k2]))
|
new_dict[key] = op_twice(new_dict[key], op(D1[k1], D2[k2]))
|
||||||
|
|
||||||
elif op_key(k2,k1) in new_dict.keys() and commutative:
|
elif op_key(k2, k1) in new_dict.keys() and commutative:
|
||||||
key = op_key(k2,k1)
|
key = op_key(k2, k1)
|
||||||
new_dict[key] = op_twice(new_dict[key], op(D1[k1],D2[k2]))
|
new_dict[key] = op_twice(new_dict[key], op(D1[k1], D2[k2]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
key = op_key(k1,k2)
|
key = op_key(k1, k2)
|
||||||
new_dict[key] = op(D1[k1],D2[k2])
|
new_dict[key] = op(D1[k1], D2[k2])
|
||||||
|
|
||||||
return new_dict
|
return new_dict
|
||||||
|
|
||||||
def spe_zip(l1,l2):
|
|
||||||
|
def spe_zip(l1, l2):
|
||||||
"""Zip two lists, if a list is longer, only it's element are taken
|
"""Zip two lists, if a list is longer, only it's element are taken
|
||||||
|
|
||||||
>>> spe_zip([1,2], [3,4])
|
>>> spe_zip([1,2], [3,4])
|
||||||
@ -248,16 +256,17 @@ def spe_zip(l1,l2):
|
|||||||
>>> spe_zip([1,2], [3,4,5])
|
>>> spe_zip([1,2], [3,4,5])
|
||||||
[[1, 3], [2, 4], 5]
|
[[1, 3], [2, 4], 5]
|
||||||
"""
|
"""
|
||||||
tmp = list(zip_longest(l1,l2))
|
tmp = list(zip_longest(l1, l2))
|
||||||
ans = []
|
ans = []
|
||||||
for i in tmp:
|
for i in tmp:
|
||||||
if None in i:
|
if None in i:
|
||||||
j = [a for a in i if a != None][-1]
|
j = [a for a in i if a is not None][-1]
|
||||||
else:
|
else:
|
||||||
j = list(i)
|
j = list(i)
|
||||||
ans.append(j)
|
ans.append(j)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def transpose_fill(list_lists):
|
def transpose_fill(list_lists):
|
||||||
"""Transpose a list of list and if inside list have not the same length, fill with last token
|
"""Transpose a list of list and if inside list have not the same length, fill with last token
|
||||||
|
|
||||||
@ -277,6 +286,7 @@ def transpose_fill(list_lists):
|
|||||||
|
|
||||||
yield col
|
yield col
|
||||||
|
|
||||||
|
|
||||||
def isOperator(exp):
|
def isOperator(exp):
|
||||||
"""Check if the expression is an opération in "+-*/:^"
|
"""Check if the expression is an opération in "+-*/:^"
|
||||||
|
|
||||||
@ -285,13 +295,14 @@ def isOperator(exp):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#return (type(exp) == str and exp in "+-*/:^")
|
# return (type(exp) == str and exp in "+-*/:^")
|
||||||
try:
|
try:
|
||||||
exp.isOperator
|
exp.isOperator
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def isNumber(exp):
|
def isNumber(exp):
|
||||||
"""Check if the expression can be a number
|
"""Check if the expression can be a number
|
||||||
|
|
||||||
@ -302,11 +313,12 @@ def isNumber(exp):
|
|||||||
try:
|
try:
|
||||||
exp.isNumber
|
exp.isNumber
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if type(exp) == int:
|
if isinstance(exp, int):
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def isPolynom(exp):
|
def isPolynom(exp):
|
||||||
"""Check if the expression can be a polynom
|
"""Check if the expression can be a polynom
|
||||||
@ -328,7 +340,8 @@ def isPolynom(exp):
|
|||||||
exp._isPolynom
|
exp._isPolynom
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def isNumerand(exp):
|
def isNumerand(exp):
|
||||||
"""Check is the expression is something we can compute with
|
"""Check is the expression is something we can compute with
|
||||||
|
@ -13,17 +13,18 @@ import inspect
|
|||||||
|
|
||||||
__all__ = ["Polynom"]
|
__all__ = ["Polynom"]
|
||||||
|
|
||||||
|
|
||||||
def polynom_factory(func):
|
def polynom_factory(func):
|
||||||
""" Decorator which specify the type of polynom that the function returns """
|
""" Decorator which specify the type of polynom that the function returns """
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwrds):
|
def wrapper(*args, **kwrds):
|
||||||
P = func(*args, **kwrds)
|
P = func(*args, **kwrds)
|
||||||
if issubclass(type(P),AbstractPolynom) and P.degree == 2:
|
if issubclass(type(P), AbstractPolynom) and P.degree == 2:
|
||||||
from .polynomDeg2 import Polynom_deg2
|
from .polynomDeg2 import Polynom_deg2
|
||||||
new_P = Polynom_deg2(poly=P)
|
new_P = Polynom_deg2(poly=P)
|
||||||
new_P.steps = P.steps
|
new_P.steps = P.steps
|
||||||
return new_P
|
return new_P
|
||||||
elif issubclass(type(P),AbstractPolynom):
|
elif issubclass(type(P), AbstractPolynom):
|
||||||
new_P = Polynom(poly=P)
|
new_P = Polynom(poly=P)
|
||||||
new_P.steps = P.steps
|
new_P.steps = P.steps
|
||||||
return new_P
|
return new_P
|
||||||
@ -31,6 +32,7 @@ def polynom_factory(func):
|
|||||||
return P
|
return P
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class Polynom(AbstractPolynom):
|
class Polynom(AbstractPolynom):
|
||||||
|
|
||||||
"""Polynom view as a function.
|
"""Polynom view as a function.
|
||||||
@ -47,7 +49,13 @@ class Polynom(AbstractPolynom):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(self, coefs_form=[], conditions=[], letter = "x", degree = 0, name = "P"):
|
def random(
|
||||||
|
self,
|
||||||
|
coefs_form=[],
|
||||||
|
conditions=[],
|
||||||
|
letter="x",
|
||||||
|
degree=0,
|
||||||
|
name="P"):
|
||||||
""" Create a random polynom from coefs_form and conditions
|
""" Create a random polynom from coefs_form and conditions
|
||||||
|
|
||||||
:param coefs_form: list of forms (one by coef) (ascending degree sorted)
|
:param coefs_form: list of forms (one by coef) (ascending degree sorted)
|
||||||
@ -71,18 +79,18 @@ class Polynom(AbstractPolynom):
|
|||||||
"""
|
"""
|
||||||
if (degree > 0 and degree < 26):
|
if (degree > 0 and degree < 26):
|
||||||
# Générer assez de lettre pour les coefs
|
# Générer assez de lettre pour les coefs
|
||||||
coefs_name = map(chr, range(97, 98+degree))
|
coefs_name = map(chr, range(97, 98 + degree))
|
||||||
coefs_form = ["{" + i + "}" for i in coefs_name][::-1]
|
coefs_form = ["{" + i + "}" for i in coefs_name][::-1]
|
||||||
|
|
||||||
form = str(coefs_form)
|
form = str(coefs_form)
|
||||||
# On créé les valeurs toutes concaténées dans un string
|
# On créé les valeurs toutes concaténées dans un string
|
||||||
coefs = RdExpression(form, conditions)()
|
coefs = RdExpression(form, conditions)()
|
||||||
# On "parse" ce string pour créer les coefs
|
# On "parse" ce string pour créer les coefs
|
||||||
coefs = [eval(i) if type(i)==str else i for i in eval(coefs)]
|
coefs = [eval(i) if isinstance(i, str) else i for i in eval(coefs)]
|
||||||
# Création du polynom
|
# Création du polynom
|
||||||
return Polynom(coefs = coefs, letter = letter, name = name)
|
return Polynom(coefs=coefs, letter=letter, name=name)
|
||||||
|
|
||||||
def __init__(self, coefs = [1], letter = "x", name = "P", poly = 0):
|
def __init__(self, coefs=[1], letter="x", name="P", poly=0):
|
||||||
"""Initiate the polynom
|
"""Initiate the polynom
|
||||||
|
|
||||||
:param coef: coefficients of the polynom (ascending degree sorted)
|
:param coef: coefficients of the polynom (ascending degree sorted)
|
||||||
@ -138,10 +146,11 @@ class Polynom(AbstractPolynom):
|
|||||||
3 h^{ 2 } + 8 h + 6
|
3 h^{ 2 } + 8 h + 6
|
||||||
>>> R = P(Q)
|
>>> R = P(Q)
|
||||||
"""
|
"""
|
||||||
#if isNumerand(value) or Expression.isExpression(value):
|
# if isNumerand(value) or Expression.isExpression(value):
|
||||||
# postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens]
|
# postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens]
|
||||||
#else:
|
# else:
|
||||||
postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens]
|
postfix_exp = [
|
||||||
|
Expression(value) if i == self._letter else i for i in self.postfix_tokens]
|
||||||
|
|
||||||
return Expression(postfix_exp).simplify()
|
return Expression(postfix_exp).simplify()
|
||||||
|
|
||||||
@ -160,7 +169,7 @@ class Polynom(AbstractPolynom):
|
|||||||
6 x + 2
|
6 x + 2
|
||||||
"""
|
"""
|
||||||
derv_coefs = []
|
derv_coefs = []
|
||||||
for (i,c) in enumerate(self._coef):
|
for (i, c) in enumerate(self._coef):
|
||||||
derv_coefs += [Expression([i, c, op.mul])]
|
derv_coefs += [Expression([i, c, op.mul])]
|
||||||
|
|
||||||
ans = Polynom(derv_coefs[1:]).simplify()
|
ans = Polynom(derv_coefs[1:]).simplify()
|
||||||
@ -169,8 +178,8 @@ class Polynom(AbstractPolynom):
|
|||||||
|
|
||||||
# Decorate methods which may return Polynoms
|
# Decorate methods which may return Polynoms
|
||||||
methods_list = ["__add__", "__call__", "__mul__", "__neg__", "__pow__",
|
methods_list = ["__add__", "__call__", "__mul__", "__neg__", "__pow__",
|
||||||
"__radd__", "__rmul__", "__rsub__", "__sub__", "derivate",
|
"__radd__", "__rmul__", "__rsub__", "__sub__", "derivate",
|
||||||
"reduce", "simplify", "random"]
|
"reduce", "simplify", "random"]
|
||||||
for name, func in inspect.getmembers(Polynom):
|
for name, func in inspect.getmembers(Polynom):
|
||||||
if name in methods_list:
|
if name in methods_list:
|
||||||
setattr(Polynom, name, polynom_factory(func))
|
setattr(Polynom, name, polynom_factory(func))
|
||||||
@ -178,7 +187,7 @@ for name, func in inspect.getmembers(Polynom):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#from .fraction import Fraction
|
#from .fraction import Fraction
|
||||||
#with Expression.tmp_render(txt):
|
# with Expression.tmp_render(txt):
|
||||||
# p = Polynom([1, 2, 3])
|
# p = Polynom([1, 2, 3])
|
||||||
# q = Polynom([4, 5, 6])
|
# q = Polynom([4, 5, 6])
|
||||||
# for i in (p*q).explain():
|
# for i in (p*q).explain():
|
||||||
@ -194,27 +203,28 @@ if __name__ == '__main__':
|
|||||||
# print(p-q)
|
# print(p-q)
|
||||||
# for i in p-q:
|
# for i in p-q:
|
||||||
# print(i)
|
# print(i)
|
||||||
#Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c)
|
# Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg
|
||||||
|
# 2 with positive Delta (ax^2 + bx + c)
|
||||||
|
|
||||||
#import doctest
|
#import doctest
|
||||||
#doctest.testmod(optionflags=doctest.ELLIPSIS)
|
# doctest.testmod(optionflags=doctest.ELLIPSIS)
|
||||||
|
|
||||||
# while True:
|
# while True:
|
||||||
# P = Polynom.random(degree = 2)
|
# P = Polynom.random(degree = 2)
|
||||||
# e = Expression.random("{a}/{b}")
|
# e = Expression.random("{a}/{b}")
|
||||||
# try:
|
# try:
|
||||||
# P(e)
|
# P(e)
|
||||||
# except RuntimeError:
|
# except RuntimeError:
|
||||||
# print(" P -> " + str(P))
|
# print(" P -> " + str(P))
|
||||||
# print(" e -> " + str(e))
|
# print(" e -> " + str(e))
|
||||||
#
|
#
|
||||||
# import sys
|
# import sys
|
||||||
# sys.setrecursionlimit(100)
|
# sys.setrecursionlimit(100)
|
||||||
|
|
||||||
from .fraction import Fraction
|
from .fraction import Fraction
|
||||||
from itertools import permutations
|
from itertools import permutations
|
||||||
P = Polynom([-5,6,-4])
|
P = Polynom([-5, 6, -4])
|
||||||
f = Fraction(2,5)
|
f = Fraction(2, 5)
|
||||||
P(f)
|
P(f)
|
||||||
try:
|
try:
|
||||||
P(f)
|
P(f)
|
||||||
@ -222,15 +232,15 @@ if __name__ == '__main__':
|
|||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
print("-----------------\n")
|
print("-----------------\n")
|
||||||
f = Fraction(2,15)
|
f = Fraction(2, 15)
|
||||||
print(str(P).replace('x','('+str(f)+')'),"= ", P(f))
|
print(str(P).replace('x', '(' + str(f) + ')'), "= ", P(f))
|
||||||
|
|
||||||
print("-----------------\n")
|
print("-----------------\n")
|
||||||
f = Fraction(2,3)
|
f = Fraction(2, 3)
|
||||||
print(P(f))
|
print(P(f))
|
||||||
#coefs_p = [[(i-2),(j-2)] for i,j in permutations(range(20),2)]
|
#coefs_p = [[(i-2),(j-2)] for i,j in permutations(range(20),2)]
|
||||||
#fractions = [Fraction(i,j) for i,j in coefs_p if j!=0]
|
#fractions = [Fraction(i,j) for i,j in coefs_p if j!=0]
|
||||||
#for f in fractions:
|
# for f in fractions:
|
||||||
# try:
|
# try:
|
||||||
# P(f)
|
# P(f)
|
||||||
# #print("ok f -> " + str(f))
|
# #print("ok f -> " + str(f))
|
||||||
|
@ -8,10 +8,11 @@ from .operator import op
|
|||||||
from .random_expression import RdExpression
|
from .random_expression import RdExpression
|
||||||
|
|
||||||
from sympy import sqrt, latex
|
from sympy import sqrt, latex
|
||||||
#from sympy.fractions import Fraction as sp.Fraction
|
# from sympy.fractions import Fraction as sp.Fraction
|
||||||
|
|
||||||
__all__ = ["Polynom_deg2"]
|
__all__ = ["Polynom_deg2"]
|
||||||
|
|
||||||
|
|
||||||
class Polynom_deg2(Polynom):
|
class Polynom_deg2(Polynom):
|
||||||
|
|
||||||
""" Degree 2 polynoms
|
""" Degree 2 polynoms
|
||||||
@ -19,7 +20,15 @@ class Polynom_deg2(Polynom):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(self, coefs_form = ["{c}", "{b}", "{a}"], conditions = [], letter = "x", name = "P"):
|
def random(
|
||||||
|
self,
|
||||||
|
coefs_form=[
|
||||||
|
"{c}",
|
||||||
|
"{b}",
|
||||||
|
"{a}"],
|
||||||
|
conditions=[],
|
||||||
|
letter="x",
|
||||||
|
name="P"):
|
||||||
""" Create a 2nd degree poly from coefs_form ans conditions
|
""" Create a 2nd degree poly from coefs_form ans conditions
|
||||||
|
|
||||||
:param coefs_form: list of forms (one by coef) (ascending degree sorted)
|
:param coefs_form: list of forms (one by coef) (ascending degree sorted)
|
||||||
@ -28,27 +37,32 @@ class Polynom_deg2(Polynom):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if len(coefs_form) != 3:
|
if len(coefs_form) != 3:
|
||||||
raise ValueError("Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format(len(coefs_form)))
|
raise ValueError(
|
||||||
|
"Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format(
|
||||||
|
len(coefs_form)))
|
||||||
|
|
||||||
form = str(coefs_form)
|
form = str(coefs_form)
|
||||||
# On créé les valeurs toutes concaténées dans un string
|
# On créé les valeurs toutes concaténées dans un string
|
||||||
coefs = RdExpression(form, conditions)()
|
coefs = RdExpression(form, conditions)()
|
||||||
# On "parse" ce string pour créer les coefs
|
# On "parse" ce string pour créer les coefs
|
||||||
coefs = [eval(i) if type(i)==str else i for i in eval(coefs)]
|
coefs = [eval(i) if isinstance(i, str) else i for i in eval(coefs)]
|
||||||
# Création du polynom
|
# Création du polynom
|
||||||
return Polynom_deg2(coefs = coefs, letter = letter, name = name)
|
return Polynom_deg2(coefs=coefs, letter=letter, name=name)
|
||||||
|
|
||||||
def __init__(self, coefs = [0, 0, 1], letter = "x", name = "P", poly = 0):
|
def __init__(self, coefs=[0, 0, 1], letter="x", name="P", poly=0):
|
||||||
if poly:
|
if poly:
|
||||||
coefs = poly._coef
|
coefs = poly._coef
|
||||||
letter = poly._letter
|
letter = poly._letter
|
||||||
name = poly.name
|
name = poly.name
|
||||||
|
|
||||||
if len(coefs) < 3 or len(coefs) > 4:
|
if len(coefs) < 3 or len(coefs) > 4:
|
||||||
raise ValueError("Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format(len(coefs)))
|
raise ValueError(
|
||||||
|
"Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format(
|
||||||
|
len(coefs)))
|
||||||
if coefs[2] == 0:
|
if coefs[2] == 0:
|
||||||
raise ValueError("Polynom_deg2 have to be degree 2 polynoms, coefficient of x^2 can't be 0")
|
raise ValueError(
|
||||||
Polynom.__init__(self, coefs, letter, name = name)
|
"Polynom_deg2 have to be degree 2 polynoms, coefficient of x^2 can't be 0")
|
||||||
|
Polynom.__init__(self, coefs, letter, name=name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def a(self):
|
def a(self):
|
||||||
@ -78,7 +92,8 @@ class Polynom_deg2(Polynom):
|
|||||||
-8
|
-8
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Expression([self.b, 2, op.pw, 4, self.a, self.c, op.mul, op.mul, op.sub]).simplify()
|
return Expression([self.b, 2, op.pw, 4, self.a,
|
||||||
|
self.c, op.mul, op.mul, op.sub]).simplify()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alpha(self):
|
def alpha(self):
|
||||||
@ -94,7 +109,8 @@ class Polynom_deg2(Polynom):
|
|||||||
\\frac{ -1 \\times 2 }{ 3 \\times 2 }
|
\\frac{ -1 \\times 2 }{ 3 \\times 2 }
|
||||||
\\frac{ -1 }{ 3 }
|
\\frac{ -1 }{ 3 }
|
||||||
"""
|
"""
|
||||||
return Expression([self.b, op.sub1, 2, self.a, op.mul, op.div]).simplify()
|
return Expression([self.b, op.sub1, 2, self.a,
|
||||||
|
op.mul, op.div]).simplify()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def beta(self):
|
def beta(self):
|
||||||
@ -124,7 +140,7 @@ class Polynom_deg2(Polynom):
|
|||||||
"""
|
"""
|
||||||
return self(self.alpha)
|
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
|
||||||
|
|
||||||
/!\ Can't manage nice rendering because of sqrt.
|
/!\ Can't manage nice rendering because of sqrt.
|
||||||
@ -146,9 +162,10 @@ class Polynom_deg2(Polynom):
|
|||||||
['-2 - \\\\sqrt{3}', '-2 + \\\\sqrt{3}']
|
['-2 - \\\\sqrt{3}', '-2 + \\\\sqrt{3}']
|
||||||
"""
|
"""
|
||||||
if self.delta > 0:
|
if self.delta > 0:
|
||||||
self._roots = [latex((-self.b - sqrt(self.delta))/(2*self.a)), latex((-self.b + sqrt(self.delta))/(2*self.a))]
|
self._roots = [latex((-self.b - sqrt(self.delta)) / (2 * self.a)),
|
||||||
|
latex((-self.b + sqrt(self.delta)) / (2 * self.a))]
|
||||||
elif self.delta == 0:
|
elif self.delta == 0:
|
||||||
self._roots = [Fraction(-self.b,2*self.a).simplify()]
|
self._roots = [Fraction(-self.b, 2 * self.a).simplify()]
|
||||||
else:
|
else:
|
||||||
self._roots = []
|
self._roots = []
|
||||||
return self._roots
|
return self._roots
|
||||||
@ -156,11 +173,12 @@ class Polynom_deg2(Polynom):
|
|||||||
def tbl_sgn_header(self):
|
def tbl_sgn_header(self):
|
||||||
""" Return header of the sign line for tkzTabLine"""
|
""" Return header of the sign line for tkzTabLine"""
|
||||||
if self.delta > 0:
|
if self.delta > 0:
|
||||||
return "{$-\\infty$, $" + str(min(self.roots())) + "$ , $" + str( max(self.roots())) + "$ , $+\\infty$}"
|
return "{$-\\infty$, $" + str(min(self.roots())) + \
|
||||||
|
"$ , $" + str(max(self.roots())) + "$ , $+\\infty$}"
|
||||||
elif self.delta == 0:
|
elif self.delta == 0:
|
||||||
return "{$-\\infty$, $" + str(self.roots()[0]) + "$ , $+\\infty$}"
|
return "{$-\\infty$, $" + str(self.roots()[0]) + "$ , $+\\infty$}"
|
||||||
else:
|
else:
|
||||||
return "{$-\\infty$, $+\\infty$}"
|
return "{$-\\infty$, $+\\infty$}"
|
||||||
|
|
||||||
def tbl_sgn(self):
|
def tbl_sgn(self):
|
||||||
""" Return the sign line for tkzTabLine
|
""" Return the sign line for tkzTabLine
|
||||||
@ -200,7 +218,7 @@ class Polynom_deg2(Polynom):
|
|||||||
else:
|
else:
|
||||||
return "\\tkzTabLine{, -,}"
|
return "\\tkzTabLine{, -,}"
|
||||||
|
|
||||||
def tbl_variation(self, limits = False):
|
def tbl_variation(self, limits=False):
|
||||||
"""Return the variation line for tkzTabVar
|
"""Return the variation line for tkzTabVar
|
||||||
|
|
||||||
:param limit: Display or not limits in tabular
|
:param limit: Display or not limits in tabular
|
||||||
@ -215,9 +233,11 @@ class Polynom_deg2(Polynom):
|
|||||||
beta = self.beta
|
beta = self.beta
|
||||||
if limits:
|
if limits:
|
||||||
if self.a > 0:
|
if self.a > 0:
|
||||||
return "\\tkzTabVar{+/{$+\\infty$}, -/{$" + str(beta) + "$}, +/{$+\\infty$}}"
|
return "\\tkzTabVar{+/{$+\\infty$}, -/{$" + \
|
||||||
|
str(beta) + "$}, +/{$+\\infty$}}"
|
||||||
else:
|
else:
|
||||||
return "\\tkzTabVar{-/{$-\\infty$}, +/{$" + str(beta) + "$}, -/{$-\\infty$}}"
|
return "\\tkzTabVar{-/{$-\\infty$}, +/{$" + \
|
||||||
|
str(beta) + "$}, -/{$-\\infty$}}"
|
||||||
else:
|
else:
|
||||||
if self.a > 0:
|
if self.a > 0:
|
||||||
return "\\tkzTabVar{+/{}, -/{$" + str(beta) + "$}, +/{}}"
|
return "\\tkzTabVar{+/{}, -/{$" + str(beta) + "$}, +/{}}"
|
||||||
@ -227,7 +247,7 @@ class Polynom_deg2(Polynom):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#from .render import txt
|
#from .render import txt
|
||||||
#with Expression.tmp_render(txt):
|
# with Expression.tmp_render(txt):
|
||||||
# P = Polynom_deg2([2, 3, 4])
|
# P = Polynom_deg2([2, 3, 4])
|
||||||
# print(P)
|
# print(P)
|
||||||
|
|
||||||
@ -242,8 +262,6 @@ if __name__ == '__main__':
|
|||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -8,11 +8,13 @@ from .generic import flatten_list
|
|||||||
|
|
||||||
from .arithmetic import gcd
|
from .arithmetic import gcd
|
||||||
|
|
||||||
def random_str(form, conditions = [], val_min = -10, val_max = 10):
|
|
||||||
|
def random_str(form, conditions=[], val_min=-10, val_max=10):
|
||||||
""" Create a random string using RdExpression class """
|
""" Create a random string using RdExpression class """
|
||||||
random_str_generator = RdExpression(form, conditions)
|
random_str_generator = RdExpression(form, conditions)
|
||||||
return random_str_generator(val_min, val_max)
|
return random_str_generator(val_min, val_max)
|
||||||
|
|
||||||
|
|
||||||
class RdExpression(object):
|
class RdExpression(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -20,7 +22,7 @@ class RdExpression(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, form, conditions = []):
|
def __init__(self, form, conditions=[]):
|
||||||
"""Initiate the generator
|
"""Initiate the generator
|
||||||
|
|
||||||
:param form: the form of the expression (/!\ variables need to be in brackets {})
|
:param form: the form of the expression (/!\ variables need to be in brackets {})
|
||||||
@ -39,16 +41,18 @@ class RdExpression(object):
|
|||||||
:returns: set for elements which have to be replaced
|
:returns: set for elements which have to be replaced
|
||||||
|
|
||||||
"""
|
"""
|
||||||
#pattern = "\{(.*?)\}" #select inside {} non greedy way
|
# pattern = "\{(.*?)\}" #select inside {} non greedy way
|
||||||
#varia_form = re.findall(pattern, self._form)
|
#varia_form = re.findall(pattern, self._form)
|
||||||
|
|
||||||
# TODO: Bug with varia with spaces |dim. nov. 23 10:44:34 CET 2014
|
# TODO: Bug with varia with spaces |dim. nov. 23 10:44:34 CET 2014
|
||||||
varia_form = flatten_list([eval(str(i[0])) for i in pyparsing.nestedExpr('{','}').searchString(self._form)])
|
varia_form = flatten_list([eval(str(i[0])) for i in pyparsing.nestedExpr(
|
||||||
|
'{', '}').searchString(self._form)])
|
||||||
varia_form = set(varia_form)
|
varia_form = set(varia_form)
|
||||||
|
|
||||||
varia_cond = set()
|
varia_cond = set()
|
||||||
for c in self._conditions:
|
for c in self._conditions:
|
||||||
c_varia_cond = flatten_list([eval(str(i[0])) for i in pyparsing.nestedExpr('{','}').searchString(c)])
|
c_varia_cond = flatten_list(
|
||||||
|
[eval(str(i[0])) for i in pyparsing.nestedExpr('{', '}').searchString(c)])
|
||||||
varia_cond = varia_cond | set(c_varia_cond)
|
varia_cond = varia_cond | set(c_varia_cond)
|
||||||
|
|
||||||
self._2replaced = varia_cond | varia_form
|
self._2replaced = varia_cond | varia_form
|
||||||
@ -81,11 +85,11 @@ class RdExpression(object):
|
|||||||
new_form = form
|
new_form = form
|
||||||
while "_" in new_form:
|
while "_" in new_form:
|
||||||
i += 1
|
i += 1
|
||||||
new_form = new_form.replace("_", "{"+chr(i)+"}",1)
|
new_form = new_form.replace("_", "{" + chr(i) + "}", 1)
|
||||||
|
|
||||||
return new_form
|
return new_form
|
||||||
|
|
||||||
def __call__(self, val_min = -10, val_max = 10):
|
def __call__(self, val_min=-10, val_max=10):
|
||||||
"""RdExpression once it is initiate act like a function which create random expressions.
|
"""RdExpression once it is initiate act like a function which create random expressions.
|
||||||
|
|
||||||
:param val_min: minimum value random generation
|
:param val_min: minimum value random generation
|
||||||
@ -95,7 +99,7 @@ class RdExpression(object):
|
|||||||
"""
|
"""
|
||||||
return self.raw_str(val_min, val_max)
|
return self.raw_str(val_min, val_max)
|
||||||
|
|
||||||
def raw_str(self, val_min = -10, val_max = 10):
|
def raw_str(self, val_min=-10, val_max=10):
|
||||||
"""Return raw string (don't use Expression for rendering or parsing)
|
"""Return raw string (don't use Expression for rendering or parsing)
|
||||||
|
|
||||||
:param val_min: minimum value random generation
|
:param val_min: minimum value random generation
|
||||||
@ -112,7 +116,7 @@ class RdExpression(object):
|
|||||||
|
|
||||||
return exp
|
return exp
|
||||||
|
|
||||||
def gene_varia(self, val_min = -10, val_max = 10):
|
def gene_varia(self, val_min=-10, val_max=10):
|
||||||
"""Randomly generates variables/letters
|
"""Randomly generates variables/letters
|
||||||
|
|
||||||
Varia can't be equal to 0
|
Varia can't be equal to 0
|
||||||
@ -123,7 +127,6 @@ class RdExpression(object):
|
|||||||
while self._gene_varia[l] == 0:
|
while self._gene_varia[l] == 0:
|
||||||
self._gene_varia[l] = randint(val_min, val_max)
|
self._gene_varia[l] = randint(val_min, val_max)
|
||||||
|
|
||||||
|
|
||||||
for e in self._2replaced:
|
for e in self._2replaced:
|
||||||
self._gene_2replaced[e] = eval(e, globals(), self._gene_varia)
|
self._gene_2replaced[e] = eval(e, globals(), self._gene_varia)
|
||||||
|
|
||||||
@ -133,18 +136,22 @@ class RdExpression(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if self._conditions != []:
|
if self._conditions != []:
|
||||||
return eval(" and ".join(self._conditions).format(**self._gene_2replaced))
|
return eval(
|
||||||
|
" and ".join(
|
||||||
|
self._conditions).format(
|
||||||
|
**self._gene_2replaced))
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def desc_rdExp(rdExp):
|
def desc_rdExp(rdExp):
|
||||||
print("--------------------")
|
print("--------------------")
|
||||||
print("form: ",rdExp._form)
|
print("form: ", rdExp._form)
|
||||||
print("Conditions: ",rdExp._conditions)
|
print("Conditions: ", rdExp._conditions)
|
||||||
print("Letters: ", rdExp._letters)
|
print("Letters: ", rdExp._letters)
|
||||||
print("2replaced: ", rdExp._2replaced)
|
print("2replaced: ", rdExp._2replaced)
|
||||||
print("Call : ", rdExp())
|
print("Call : ", rdExp())
|
||||||
print("type: ",type(rdExp()))
|
print("type: ", type(rdExp()))
|
||||||
print("Gene varia: ", rdExp._gene_varia)
|
print("Gene varia: ", rdExp._gene_varia)
|
||||||
print("Gene 2replaced: ", rdExp._gene_2replaced)
|
print("Gene 2replaced: ", rdExp._gene_2replaced)
|
||||||
print('')
|
print('')
|
||||||
@ -156,18 +163,25 @@ if __name__ == '__main__':
|
|||||||
print(random_str(form, cond))
|
print(random_str(form, cond))
|
||||||
|
|
||||||
form = "{a+a*10}*4 + {a} + 2*{b}"
|
form = "{a+a*10}*4 + {a} + 2*{b}"
|
||||||
cond = ["{a} + {b} in [1, 2, 3, 4, 5]", "abs({a}) not in [1]", "{b} not in [1]", "gcd({a},{b}) == 1"]
|
cond = [
|
||||||
|
"{a} + {b} in [1, 2, 3, 4, 5]",
|
||||||
|
"abs({a}) not in [1]",
|
||||||
|
"{b} not in [1]",
|
||||||
|
"gcd({a},{b}) == 1"]
|
||||||
print(random_str(form, cond))
|
print(random_str(form, cond))
|
||||||
|
|
||||||
form = "{a+a*10}*4 + {a} + 2*{b}"
|
form = "{a+a*10}*4 + {a} + 2*{b}"
|
||||||
cond = ["{a-b} + {b} in list(range(20))", "abs({a}) not in [1]", "{b} not in [1]", "gcd({a},{b}) == 1"]
|
cond = [
|
||||||
|
"{a-b} + {b} in list(range(20))",
|
||||||
|
"abs({a}) not in [1]",
|
||||||
|
"{b} not in [1]",
|
||||||
|
"gcd({a},{b}) == 1"]
|
||||||
print(random_str(form, cond))
|
print(random_str(form, cond))
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
from .generic import Stack,isOperator
|
from .generic import Stack, isOperator
|
||||||
|
|
||||||
__all__ = ['txt', 'tex', 'p2i']
|
__all__ = ['txt', 'tex', 'p2i']
|
||||||
|
|
||||||
|
|
||||||
class Render(object):
|
class Render(object):
|
||||||
""" Create functions which know how to render postfix tokens lists """
|
""" Create functions which know how to render postfix tokens lists """
|
||||||
|
|
||||||
@ -15,7 +16,6 @@ class Render(object):
|
|||||||
"""
|
"""
|
||||||
self.render = render
|
self.render = render
|
||||||
|
|
||||||
|
|
||||||
def __call__(self, postfix_tokens):
|
def __call__(self, postfix_tokens):
|
||||||
"""Make the object acting like a function
|
"""Make the object acting like a function
|
||||||
|
|
||||||
@ -45,6 +45,7 @@ class Render(object):
|
|||||||
else:
|
else:
|
||||||
return operandeStack.pop()
|
return operandeStack.pop()
|
||||||
|
|
||||||
|
|
||||||
def txt_render(token):
|
def txt_render(token):
|
||||||
def render(*args):
|
def render(*args):
|
||||||
try:
|
try:
|
||||||
@ -54,6 +55,8 @@ def txt_render(token):
|
|||||||
return render
|
return render
|
||||||
|
|
||||||
txt = Render(txt_render)
|
txt = Render(txt_render)
|
||||||
|
|
||||||
|
|
||||||
def tex_render(token):
|
def tex_render(token):
|
||||||
def render(*args):
|
def render(*args):
|
||||||
try:
|
try:
|
||||||
@ -63,6 +66,7 @@ def tex_render(token):
|
|||||||
return render
|
return render
|
||||||
tex = Render(tex_render)
|
tex = Render(tex_render)
|
||||||
|
|
||||||
|
|
||||||
def p2i_render(token):
|
def p2i_render(token):
|
||||||
def render(*args):
|
def render(*args):
|
||||||
try:
|
try:
|
||||||
@ -78,18 +82,17 @@ if __name__ == '__main__':
|
|||||||
from pymath import Polynom
|
from pymath import Polynom
|
||||||
from pymath import Expression
|
from pymath import Expression
|
||||||
from pymath import Fraction
|
from pymath import Fraction
|
||||||
coefs_p = [[(i-2),(j-2)] for i,j in permutations(range(5),2)]
|
coefs_p = [[(i - 2), (j - 2)] for i, j in permutations(range(5), 2)]
|
||||||
coefs_q = [[2*(i-2),2*(j-2)] for i,j in permutations(range(5),2)]
|
coefs_q = [[2 * (i - 2), 2 * (j - 2)]
|
||||||
|
for i, j in permutations(range(5), 2)]
|
||||||
l_p = [Polynom(i) for i in coefs_p]
|
l_p = [Polynom(i) for i in coefs_p]
|
||||||
l_q = [Fraction(i,j) for i,j in coefs_q if j!=0]
|
l_q = [Fraction(i, j) for i, j in coefs_q if j != 0]
|
||||||
operations = [Expression([l_p[i],l_q[j],op.mul]) for i,j in permutations(range(len(l_q)),2)]
|
operations = [Expression([l_p[i], l_q[j], op.mul])
|
||||||
|
for i, j in permutations(range(len(l_q)), 2)]
|
||||||
for i in operations:
|
for i in operations:
|
||||||
print(i)
|
print(i)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
from .generic import Stack, isOperator, isNumber, isPolynom
|
from .generic import Stack, isOperator, isNumber, isPolynom
|
||||||
from .operator import op
|
from .operator import op
|
||||||
|
|
||||||
|
|
||||||
def str2tokens(exp):
|
def str2tokens(exp):
|
||||||
""" Parse the string into tokens then turn it into postfix form
|
""" Parse the string into tokens then turn it into postfix form
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ def str2tokens(exp):
|
|||||||
|
|
||||||
return post_tokens
|
return post_tokens
|
||||||
|
|
||||||
|
|
||||||
def str2in_tokens(exp):
|
def str2in_tokens(exp):
|
||||||
""" Parse the expression, ie tranform a string into a list of tokens
|
""" Parse the expression, ie tranform a string into a list of tokens
|
||||||
|
|
||||||
@ -37,14 +39,14 @@ def str2in_tokens(exp):
|
|||||||
for character in exp:
|
for character in exp:
|
||||||
if character.isdigit():
|
if character.isdigit():
|
||||||
# for "big" numbers (like 2345)
|
# for "big" numbers (like 2345)
|
||||||
if type(tokens[-1]) == int:
|
if isinstance(tokens[-1], int):
|
||||||
if tokens[-1] > 0:
|
if tokens[-1] > 0:
|
||||||
tokens[-1] = tokens[-1]*10 + int(character)
|
tokens[-1] = tokens[-1] * 10 + int(character)
|
||||||
else:
|
else:
|
||||||
tokens[-1] = tokens[-1]*10 - int(character)
|
tokens[-1] = tokens[-1] * 10 - int(character)
|
||||||
|
|
||||||
|
# Special case for "-" at the begining of an expression or before
|
||||||
# Special case for "-" at the begining of an expression or before "("
|
# "("
|
||||||
elif tokens[-1] == "-" and \
|
elif tokens[-1] == "-" and \
|
||||||
str(tokens[-2]) in " (+-*/:":
|
str(tokens[-2]) in " (+-*/:":
|
||||||
tokens[-1] = - int(character)
|
tokens[-1] = - int(character)
|
||||||
@ -72,7 +74,7 @@ def str2in_tokens(exp):
|
|||||||
or isPolynom(tokens[-1]):
|
or isPolynom(tokens[-1]):
|
||||||
tokens.append("*")
|
tokens.append("*")
|
||||||
from pymath.calculus.polynom import Polynom
|
from pymath.calculus.polynom import Polynom
|
||||||
tokens.append(Polynom([0,1], letter = character))
|
tokens.append(Polynom([0, 1], letter=character))
|
||||||
|
|
||||||
elif character == ".":
|
elif character == ".":
|
||||||
raise ValueError("No float number please")
|
raise ValueError("No float number please")
|
||||||
@ -83,7 +85,6 @@ def str2in_tokens(exp):
|
|||||||
return tokens[1:]
|
return tokens[1:]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def in2post_fix(infix_tokens):
|
def in2post_fix(infix_tokens):
|
||||||
""" From the infix_tokens list compute the corresponding postfix_tokens list
|
""" From the infix_tokens list compute the corresponding postfix_tokens list
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ def in2post_fix(infix_tokens):
|
|||||||
arity_Stack = Stack()
|
arity_Stack = Stack()
|
||||||
arity_Stack.push(0)
|
arity_Stack.push(0)
|
||||||
|
|
||||||
for (pos_token,token) in enumerate(infix_tokens):
|
for (pos_token, token) in enumerate(infix_tokens):
|
||||||
|
|
||||||
# Pour voir ce qu'il se passe dans cette procédure
|
# Pour voir ce qu'il se passe dans cette procédure
|
||||||
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
||||||
@ -129,9 +130,11 @@ def in2post_fix(infix_tokens):
|
|||||||
else:
|
else:
|
||||||
arity = arity_Stack.pop()
|
arity = arity_Stack.pop()
|
||||||
token_op = op.get_op(token, arity + 1)
|
token_op = op.get_op(token, arity + 1)
|
||||||
# Reset arity to 0 in case there is other operators (the real operation would be "-op.arity + 1")
|
# Reset arity to 0 in case there is other operators (the real
|
||||||
|
# operation would be "-op.arity + 1")
|
||||||
arity_Stack.push(0)
|
arity_Stack.push(0)
|
||||||
while (not opStack.isEmpty()) and opStack.peek().priority >= token_op.priority:
|
while (not opStack.isEmpty()) and opStack.peek(
|
||||||
|
).priority >= token_op.priority:
|
||||||
next_op = opStack.pop()
|
next_op = opStack.pop()
|
||||||
postfix_tokens.append(next_op)
|
postfix_tokens.append(next_op)
|
||||||
|
|
||||||
@ -142,29 +145,30 @@ def in2post_fix(infix_tokens):
|
|||||||
arity = arity_Stack.pop()
|
arity = arity_Stack.pop()
|
||||||
arity_Stack.push(arity + 1)
|
arity_Stack.push(arity + 1)
|
||||||
|
|
||||||
## Pour voir ce qu'il se passe dans cette procédure
|
# Pour voir ce qu'il se passe dans cette procédure
|
||||||
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
||||||
|
|
||||||
while not opStack.isEmpty():
|
while not opStack.isEmpty():
|
||||||
next_op = opStack.pop()
|
next_op = opStack.pop()
|
||||||
postfix_tokens.append(next_op)
|
postfix_tokens.append(next_op)
|
||||||
|
|
||||||
## Pour voir ce qu'il se passe dans cette procédure
|
# Pour voir ce qu'il se passe dans cette procédure
|
||||||
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
|
||||||
|
|
||||||
if arity_Stack.peek() != 1:
|
if arity_Stack.peek() != 1:
|
||||||
raise ValueError("Unvalid expression. The arity Stack is ", str(arity_Stack))
|
raise ValueError(
|
||||||
|
"Unvalid expression. The arity Stack is ",
|
||||||
|
str(arity_Stack))
|
||||||
|
|
||||||
return postfix_tokens
|
return postfix_tokens
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#a, s, m, d, p = Operator("+"), Operator("-"), Operator("*"), Operator("/"), Operator("^")
|
#a, s, m, d, p = Operator("+"), Operator("-"), Operator("*"), Operator("/"), Operator("^")
|
||||||
#in_tokens = str2in_tokens("2+3*4")
|
#in_tokens = str2in_tokens("2+3*4")
|
||||||
#print("\t in_tokens :" + str(in_tokens))
|
#print("\t in_tokens :" + str(in_tokens))
|
||||||
#
|
#
|
||||||
#print(in2post_fix(in_tokens))
|
# print(in2post_fix(in_tokens))
|
||||||
|
|
||||||
#print(in2post_fix([op.par, 2, op.add, 5, op.sub, 1, ')', op.div, op.par, 3, op.mul, 4, ')']))
|
#print(in2post_fix([op.par, 2, op.add, 5, op.sub, 1, ')', op.div, op.par, 3, op.mul, 4, ')']))
|
||||||
#print(in2post_fix([op.sub1, op.par, op.sub1, 2, ')']))
|
#print(in2post_fix([op.sub1, op.par, op.sub1, 2, ')']))
|
||||||
@ -179,7 +183,7 @@ if __name__ == '__main__':
|
|||||||
print(str2tokens('x(2+1)+4'))
|
print(str2tokens('x(2+1)+4'))
|
||||||
print("\n------")
|
print("\n------")
|
||||||
#import doctest
|
#import doctest
|
||||||
#doctest.testmod()
|
# doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
# TODO: Rendre toutes les réponses Explicable!! |mar. janv. 12 09:41:00 EAT 2016
|
# TODO: Rendre toutes les réponses Explicable!! |mar. janv. 12 09:41:00
|
||||||
|
# EAT 2016
|
||||||
|
|
||||||
from math import sqrt, ceil
|
from math import sqrt, ceil
|
||||||
from .number_tools import number_factory
|
from .number_tools import number_factory
|
||||||
from .random_generator import random_generator
|
from .random_generator import random_generator
|
||||||
|
|
||||||
|
|
||||||
class Dataset(list):
|
class Dataset(list):
|
||||||
""" A dataset (a list) with statistics and latex rendering methods
|
""" A dataset (a list) with statistics and latex rendering methods
|
||||||
|
|
||||||
@ -30,11 +32,11 @@ class Dataset(list):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(cls, length, data_name = "Valeurs", \
|
def random(cls, length, data_name="Valeurs",
|
||||||
distrib = "gauss", rd_args = (0,1), \
|
distrib="gauss", rd_args=(0, 1),
|
||||||
nbr_format = lambda x:round(x,2), \
|
nbr_format=lambda x: round(x, 2),
|
||||||
v_min = None, v_max = None, \
|
v_min=None, v_max=None,
|
||||||
exact_mean = None):
|
exact_mean=None):
|
||||||
""" Generate a random list of value
|
""" Generate a random list of value
|
||||||
|
|
||||||
:param length: length of the dataset
|
:param length: length of the dataset
|
||||||
@ -45,15 +47,15 @@ class Dataset(list):
|
|||||||
:param v_max: maximum accepted value
|
:param v_max: maximum accepted value
|
||||||
:param exact_mean: if set, the last generated number will be create in order that the computed mean is exacly equal to "exact_mean"
|
:param exact_mean: if set, the last generated number will be create in order that the computed mean is exacly equal to "exact_mean"
|
||||||
"""
|
"""
|
||||||
data = random_generator(length,\
|
data = random_generator(length,
|
||||||
distrib, rd_args, \
|
distrib, rd_args,
|
||||||
nbr_format, \
|
nbr_format,
|
||||||
v_min, v_max, \
|
v_min, v_max,
|
||||||
exact_mean)
|
exact_mean)
|
||||||
|
|
||||||
return cls(data, data_name = data_name)
|
return cls(data, data_name=data_name)
|
||||||
|
|
||||||
def __init__(self, data = [], data_name = "Valeurs"):
|
def __init__(self, data=[], data_name="Valeurs"):
|
||||||
"""
|
"""
|
||||||
Create a numeric data set
|
Create a numeric data set
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ class Dataset(list):
|
|||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def mean(self):
|
def mean(self):
|
||||||
return self.sum()/self.effectif_total()
|
return self.sum() / self.effectif_total()
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def deviation(self):
|
def deviation(self):
|
||||||
@ -96,7 +98,7 @@ class Dataset(list):
|
|||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def variance(self):
|
def variance(self):
|
||||||
return self.deviation()/self.effectif_total()
|
return self.deviation() / self.effectif_total()
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def sd(self):
|
def sd(self):
|
||||||
@ -113,10 +115,15 @@ class Dataset(list):
|
|||||||
>>> w.quartiles()
|
>>> w.quartiles()
|
||||||
(0, 2.5, 5.5, 8.5, 11)
|
(0, 2.5, 5.5, 8.5, 11)
|
||||||
"""
|
"""
|
||||||
return (min(self) , self.quartile(1) , self.quartile(2) , self.quartile(3), max(self))
|
return (
|
||||||
|
min(self),
|
||||||
|
self.quartile(1),
|
||||||
|
self.quartile(2),
|
||||||
|
self.quartile(3),
|
||||||
|
max(self))
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def quartile(self, quartile = 1):
|
def quartile(self, quartile=1):
|
||||||
"""
|
"""
|
||||||
Calcul un quartile de la série.
|
Calcul un quartile de la série.
|
||||||
|
|
||||||
@ -145,11 +152,11 @@ class Dataset(list):
|
|||||||
# -1 to match with list indexing
|
# -1 to match with list indexing
|
||||||
position = self.posi_quartile(quartile) - 1
|
position = self.posi_quartile(quartile) - 1
|
||||||
if position.is_integer():
|
if position.is_integer():
|
||||||
return (self[int(position)] + self[int(position)+1])/2
|
return (self[int(position)] + self[int(position) + 1]) / 2
|
||||||
else:
|
else:
|
||||||
return self[ceil(position)]
|
return self[ceil(position)]
|
||||||
|
|
||||||
def posi_quartile(self, quartile = 1):
|
def posi_quartile(self, quartile=1):
|
||||||
"""
|
"""
|
||||||
Calcul la position du quartile
|
Calcul la position du quartile
|
||||||
|
|
||||||
@ -162,20 +169,22 @@ class Dataset(list):
|
|||||||
# --------------------------
|
# --------------------------
|
||||||
# Rendu latex
|
# Rendu latex
|
||||||
|
|
||||||
def tabular_latex(self, nbr_lines = 1):
|
def tabular_latex(self, nbr_lines=1):
|
||||||
""" Latex code to display dataset as a tabular """
|
""" Latex code to display dataset as a tabular """
|
||||||
d_per_line = self.effectif_total() // nbr_lines
|
d_per_line = self.effectif_total() // nbr_lines
|
||||||
d_last_line = self.effectif_total() % d_per_line
|
d_last_line = self.effectif_total() % d_per_line
|
||||||
splited_data = [self[x:x+d_per_line] for x in range(0, self.effectif_total(), d_per_line)]
|
splited_data = [self[x:x + d_per_line]
|
||||||
|
for x in range(0, self.effectif_total(), d_per_line)]
|
||||||
# On ajoute les éléments manquant pour la dernière line
|
# On ajoute les éléments manquant pour la dernière line
|
||||||
if d_last_line:
|
if d_last_line:
|
||||||
splited_data[-1] += [' ']*(d_per_line - d_last_line)
|
splited_data[-1] += [' '] * (d_per_line - d_last_line)
|
||||||
|
|
||||||
# Construction du tableau
|
# Construction du tableau
|
||||||
latex = "\\begin{{tabular}}{{|c|*{{{nbr_col}}}{{c|}}}} \n".format(nbr_col = d_per_line)
|
latex = "\\begin{{tabular}}{{|c|*{{{nbr_col}}}{{c|}}}} \n".format(
|
||||||
|
nbr_col=d_per_line)
|
||||||
latex += "\t\t \hline \n"
|
latex += "\t\t \hline \n"
|
||||||
|
|
||||||
d_lines = [' & '.join(map(str,l)) for l in splited_data]
|
d_lines = [' & '.join(map(str, l)) for l in splited_data]
|
||||||
latex += " \\\\ \n \\hline \n".join(d_lines)
|
latex += " \\\\ \n \\hline \n".join(d_lines)
|
||||||
|
|
||||||
latex += " \\\\ \n \\hline \n"
|
latex += " \\\\ \n \\hline \n"
|
||||||
@ -184,9 +193,7 @@ class Dataset(list):
|
|||||||
return latex
|
return latex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
# cursor: 16 del
|
# cursor: 16 del
|
||||||
|
|
||||||
|
@ -19,9 +19,7 @@ def number_factory(fun):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
# cursor: 16 del
|
# cursor: 16 del
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
from random import randint, uniform, gauss, choice
|
from random import randint, uniform, gauss, choice
|
||||||
|
|
||||||
|
|
||||||
def random_generator(length,\
|
def random_generator(length,
|
||||||
distrib = gauss, rd_args = (0,1), \
|
distrib=gauss, rd_args=(0, 1),
|
||||||
nbr_format = lambda x:round(x,2), \
|
nbr_format=lambda x: round(x, 2),
|
||||||
v_min = None, v_max = None, \
|
v_min=None, v_max=None,
|
||||||
exact_mean = None):
|
exact_mean=None):
|
||||||
""" Generate a random list of value
|
""" Generate a random list of value
|
||||||
|
|
||||||
:param length: length of the dataset
|
:param length: length of the dataset
|
||||||
@ -28,22 +28,26 @@ def random_generator(length,\
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# if exact_mean is set, we create automaticaly only length-1 value
|
# if exact_mean is set, we create automaticaly only length-1 value
|
||||||
if exact_mean != None:
|
if exact_mean is not None:
|
||||||
length = length - 1
|
length = length - 1
|
||||||
|
|
||||||
# build function to test created values
|
# build function to test created values
|
||||||
if v_min == None:
|
if v_min is None:
|
||||||
v1 = lambda x: True
|
v1 = lambda x: True
|
||||||
else:
|
else:
|
||||||
v1 = lambda x: x >= v_min
|
v1 = lambda x: x >= v_min
|
||||||
if v_max == None:
|
if v_max is None:
|
||||||
v2 = lambda x: True
|
v2 = lambda x: True
|
||||||
else:
|
else:
|
||||||
v2 = lambda x: x <= v_max
|
v2 = lambda x: x <= v_max
|
||||||
validate = lambda x : v1(x) and v2(x)
|
validate = lambda x: v1(x) and v2(x)
|
||||||
|
|
||||||
# get distrib function
|
# get distrib function
|
||||||
distribs = {"gauss": gauss, "uniform": uniform, "randint":randint, "choice":choice}
|
distribs = {
|
||||||
|
"gauss": gauss,
|
||||||
|
"uniform": uniform,
|
||||||
|
"randint": randint,
|
||||||
|
"choice": choice}
|
||||||
try:
|
try:
|
||||||
distrib(*rd_args)
|
distrib(*rd_args)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@ -59,10 +63,11 @@ def random_generator(length,\
|
|||||||
data.append(v)
|
data.append(v)
|
||||||
|
|
||||||
# Build last value
|
# Build last value
|
||||||
if exact_mean != None:
|
if exact_mean is not None:
|
||||||
last_v = nbr_format((length+1) * exact_mean - sum(data))
|
last_v = nbr_format((length + 1) * exact_mean - sum(data))
|
||||||
if not validate(last_v):
|
if not validate(last_v):
|
||||||
raise ValueError("Can't build the last value. Conflict between v_min/v_max and exact_mean")
|
raise ValueError(
|
||||||
|
"Can't build the last value. Conflict between v_min/v_max and exact_mean")
|
||||||
data.append(last_v)
|
data.append(last_v)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@ -71,4 +76,3 @@ def random_generator(length,\
|
|||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
# cursor: 16 del
|
# cursor: 16 del
|
||||||
|
|
||||||
|
@ -35,7 +35,12 @@ class WeightedDataset(dict):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, datas = [], data_name = "Valeurs", weights = [], weight_name = "Effectifs"):
|
def __init__(
|
||||||
|
self,
|
||||||
|
datas=[],
|
||||||
|
data_name="Valeurs",
|
||||||
|
weights=[],
|
||||||
|
weight_name="Effectifs"):
|
||||||
"""
|
"""
|
||||||
Initiate the WeightedDataset
|
Initiate the WeightedDataset
|
||||||
"""
|
"""
|
||||||
@ -45,14 +50,14 @@ class WeightedDataset(dict):
|
|||||||
if len(datas) != len(weights):
|
if len(datas) != len(weights):
|
||||||
raise ValueError("Datas and weights should have same length")
|
raise ValueError("Datas and weights should have same length")
|
||||||
else:
|
else:
|
||||||
weightedDatas = {i[0]:i[1] for i in zip(datas, weights)}
|
weightedDatas = {i[0]: i[1] for i in zip(datas, weights)}
|
||||||
|
|
||||||
dict.__init__(self, weightedDatas)
|
dict.__init__(self, weightedDatas)
|
||||||
|
|
||||||
self.data_name = data_name
|
self.data_name = data_name
|
||||||
self.weight_name = weight_name
|
self.weight_name = weight_name
|
||||||
|
|
||||||
def add_data(self, data, weight = 1):
|
def add_data(self, data, weight=1):
|
||||||
try:
|
try:
|
||||||
self[data] += weight
|
self[data] += weight
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -68,21 +73,21 @@ class WeightedDataset(dict):
|
|||||||
@number_factory
|
@number_factory
|
||||||
def sum(self):
|
def sum(self):
|
||||||
""" Not really a sum but the sum of the product of key and values """
|
""" Not really a sum but the sum of the product of key and values """
|
||||||
return sum([k*v for (k,v) in self.items()])
|
return sum([k * v for (k, v) in self.items()])
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def mean(self):
|
def mean(self):
|
||||||
return self.sum()/self.effectif_total()
|
return self.sum() / self.effectif_total()
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def deviation(self):
|
def deviation(self):
|
||||||
""" Compute the deviation (not normalized) """
|
""" Compute the deviation (not normalized) """
|
||||||
mean = self.mean()
|
mean = self.mean()
|
||||||
return sum([v*(k - mean)**2 for (k,v) in self.items()])
|
return sum([v * (k - mean)**2 for (k, v) in self.items()])
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def variance(self):
|
def variance(self):
|
||||||
return self.deviation()/self.effectif_total()
|
return self.deviation() / self.effectif_total()
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def sd(self):
|
def sd(self):
|
||||||
@ -103,10 +108,14 @@ class WeightedDataset(dict):
|
|||||||
(1, 3, 4, 5, 5)
|
(1, 3, 4, 5, 5)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return (min(self.keys()) , self.quartile(1) , self.quartile(2) , self.quartile(3), max(self.keys()))
|
return (min(self.keys()),
|
||||||
|
self.quartile(1),
|
||||||
|
self.quartile(2),
|
||||||
|
self.quartile(3),
|
||||||
|
max(self.keys()))
|
||||||
|
|
||||||
@number_factory
|
@number_factory
|
||||||
def quartile(self, quartile = 1):
|
def quartile(self, quartile=1):
|
||||||
"""
|
"""
|
||||||
Calcul un quartile de la série.
|
Calcul un quartile de la série.
|
||||||
|
|
||||||
@ -134,13 +143,14 @@ class WeightedDataset(dict):
|
|||||||
"""
|
"""
|
||||||
# -1 to match with list indexing
|
# -1 to match with list indexing
|
||||||
position = self.posi_quartile(quartile) - 1
|
position = self.posi_quartile(quartile) - 1
|
||||||
expanded_values = flatten_list([v*[k] for (k,v) in self.items()])
|
expanded_values = flatten_list([v * [k] for (k, v) in self.items()])
|
||||||
if position.is_integer():
|
if position.is_integer():
|
||||||
return (expanded_values[int(position)] + expanded_values[int(position)+1])/2
|
return (expanded_values[int(position)] +
|
||||||
|
expanded_values[int(position) + 1]) / 2
|
||||||
else:
|
else:
|
||||||
return expanded_values[ceil(position)]
|
return expanded_values[ceil(position)]
|
||||||
|
|
||||||
def posi_quartile(self, quartile = 1):
|
def posi_quartile(self, quartile=1):
|
||||||
"""
|
"""
|
||||||
Calcul la position du quartile
|
Calcul la position du quartile
|
||||||
|
|
||||||
@ -150,21 +160,22 @@ class WeightedDataset(dict):
|
|||||||
"""
|
"""
|
||||||
return quartile * self.effectif_total() / 4
|
return quartile * self.effectif_total() / 4
|
||||||
|
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
# Rendu latex
|
# Rendu latex
|
||||||
|
|
||||||
def tabular_latex(self):
|
def tabular_latex(self):
|
||||||
""" Latex code to display dataset as a tabular """
|
""" Latex code to display dataset as a tabular """
|
||||||
latex = "\\begin{{tabular}}{{|c|*{{{nbr_col}}}{{c|}}}} \n".format(nbr_col = len(self.keys()))
|
latex = "\\begin{{tabular}}{{|c|*{{{nbr_col}}}{{c|}}}} \n".format(
|
||||||
|
nbr_col=len(self.keys()))
|
||||||
latex += "\t \hline \n"
|
latex += "\t \hline \n"
|
||||||
data_line = "\t {data_name} ".format(data_name = self.data_name)
|
data_line = "\t {data_name} ".format(data_name=self.data_name)
|
||||||
weight_line = "\t {weight_name} ".format(weight_name = self.weight_name)
|
weight_line = "\t {weight_name} ".format(weight_name=self.weight_name)
|
||||||
|
|
||||||
# TODO: Il faudra trouver une solution pour le formatage des données |sam. janv. 9 13:14:26 EAT 2016
|
# TODO: Il faudra trouver une solution pour le formatage des données
|
||||||
for (v,e) in self.items():
|
# |sam. janv. 9 13:14:26 EAT 2016
|
||||||
data_line += "& {val} ".format(val = v)
|
for (v, e) in self.items():
|
||||||
weight_line += "& {eff} ".format(eff = e)
|
data_line += "& {val} ".format(val=v)
|
||||||
|
weight_line += "& {eff} ".format(eff=e)
|
||||||
|
|
||||||
latex += data_line + "\\\\ \n \t \\hline \n"
|
latex += data_line + "\\\\ \n \t \\hline \n"
|
||||||
latex += weight_line + "\\\\ \n \t \\hline \n"
|
latex += weight_line + "\\\\ \n \t \\hline \n"
|
||||||
@ -177,4 +188,3 @@ class WeightedDataset(dict):
|
|||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
# cursor: 16 del
|
# cursor: 16 del
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user