introduce Step remove pstf_factory in Expression

This commit is contained in:
Benjamin Bertrand 2016-03-10 14:42:27 +03:00
parent 79104522ac
commit 219037e87a
2 changed files with 145 additions and 76 deletions

View File

@ -8,6 +8,7 @@ from .generic import flatten_list, expand_list, isOperator, isNumerand
from .str2tokens import str2tokens from .str2tokens import str2tokens
from .operator import op from .operator import op
from .explicable import Explicable, Explicable_int, Explicable_Decimal from .explicable import Explicable, Explicable_int, Explicable_Decimal
from .step import Step
from decimal import Decimal from decimal import Decimal
from .random_expression import RdExpression from .random_expression import RdExpression
@ -15,41 +16,41 @@ from .random_expression import RdExpression
__all__ = ['Expression'] __all__ = ['Expression']
def pstf_factory(pstf_tokens): # def pstf_factory(pstf_tokens):
"""Factory which tranform postfix tokens list into an Expression or the simpliest object type ready to be rendered # """Factory which tranform postfix tokens list into an Expression or the simpliest object type ready to be rendered
#
:param pstf_tokens: a postfix tokens list # :param pstf_tokens: a postfix tokens list
:returns: the object # :returns: the object
#
>>> from .operator import op # >>> from .operator import op
>>> pstf_t = [2, 3, op.add] # >>> pstf_t = [2, 3, op.add]
>>> pstf_factory(pstf_t) # >>> pstf_factory(pstf_t)
< Expression [2, 3, +]> # < Expression [2, 3, +]>
>>> pstf_factory([2]) # >>> pstf_factory([2])
2 # 2
>>> type(pstf_factory([2])) # >>> type(pstf_factory([2]))
<class 'pymath.calculus.explicable.Explicable_int'> # <class 'pymath.calculus.explicable.Explicable_int'>
>>> pstf_factory([2.45]) # >>> pstf_factory([2.45])
Decimal('2.45') # Decimal('2.45')
>>> type(pstf_factory([2.45])) # >>> type(pstf_factory([2.45]))
<class 'pymath.calculus.explicable.Explicable_Decimal'> # <class 'pymath.calculus.explicable.Explicable_Decimal'>
>>> from .fraction import Fraction # >>> from .fraction import Fraction
>>> f = Fraction(1,2) # >>> f = Fraction(1,2)
>>> pstf_factory([f]) # >>> pstf_factory([f])
< Fraction 1 / 2> # < Fraction 1 / 2>
#
""" # """
if len(pstf_tokens) == 1: # if len(pstf_tokens) == 1:
if isinstance(pstf_tokens[0], int): # if isinstance(pstf_tokens[0], int):
return Explicable_int(pstf_tokens[0]) # return Explicable_int(pstf_tokens[0])
elif isinstance(pstf_tokens[0], Decimal): # elif isinstance(pstf_tokens[0], Decimal):
return Explicable_Decimal(pstf_tokens[0]) # return Explicable_Decimal(pstf_tokens[0])
elif isinstance(pstf_tokens[0], float): # elif isinstance(pstf_tokens[0], float):
return Explicable_Decimal(Decimal(str(pstf_tokens[0]))) # return Explicable_Decimal(Decimal(str(pstf_tokens[0])))
elif hasattr(pstf_tokens[0], 'STR_RENDER'): # elif hasattr(pstf_tokens[0], 'STR_RENDER'):
return pstf_tokens[0] # return pstf_tokens[0]
#
return Expression(pstf_tokens) # return Expression(pstf_tokens)
class Expression(Explicable): class Expression(Explicable):
@ -68,44 +69,44 @@ class Expression(Explicable):
random_generator = RdExpression(form, conditions) random_generator = RdExpression(form, conditions)
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: pstf_factory(x)): # def tmp_render(cls, render=lambda _, x: pstf_factory(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")
>>> print(exp) # >>> print(exp)
2 \\times \\frac{ 3 }{ 5 } # 2 \\times \\frac{ 3 }{ 5 }
>>> for i in exp.simplify().explain(): # >>> for i in exp.simplify().explain():
... print(i) # ... print(i)
2 \\times \\frac{ 3 }{ 5 } # 2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2 # \\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 } # \\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 } # \\frac{ 6 }{ 5 }
>>> with Expression.tmp_render(): # >>> with Expression.tmp_render():
... for i in exp.simplify().explain(): # ... for i in exp.simplify().explain():
... i # ... i
< Expression [2, 3, 5, /, *]> # < Expression [2, 3, 5, /, *]>
< Expression [2, < Fraction 3 / 5>, *]> # < Expression [2, < Fraction 3 / 5>, *]>
< Expression [< Fraction 3 / 5>, 2, *]> # < Expression [< Fraction 3 / 5>, 2, *]>
< Expression [3, 2, *, 5, /]> # < Expression [3, 2, *, 5, /]>
< Expression [6, 5, /]> # < Expression [6, 5, /]>
>>> from .render import txt # >>> from .render import txt
>>> with Expression.tmp_render(txt): # >>> with Expression.tmp_render(txt):
... for i in exp.simplify().explain(): # ... for i in exp.simplify().explain():
... print(i) # ... print(i)
2 * 3 / 5 # 2 * 3 / 5
3 / 5 * 2 # 3 / 5 * 2
( 3 * 2 ) / 5 # ( 3 * 2 ) / 5
6 / 5 # 6 / 5
>>> for i in exp.simplify().explain(): # >>> for i in exp.simplify().explain():
... print(i) # ... print(i)
2 \\times \\frac{ 3 }{ 5 } # 2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2 # \\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 } # \\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 } # \\frac{ 6 }{ 5 }
""" # """
return super(Expression, cls).tmp_render(render) # return super(Expression, cls).tmp_render(render)
def __init__(self, exp): def __init__(self, exp):
"""Create Expression objects """Create Expression objects
@ -261,7 +262,7 @@ class Expression(Explicable):
>>> f = Expression('3*4+5') >>> f = Expression('3*4+5')
>>> f1 = f.simplify() >>> f1 = f.simplify()
>>> Expression.develop_steps([e1, f1, op.add]) >>> Expression.develop_steps([e1, f1, op.add])
[< Expression [1, 2, +, 3, 4, *, 5, +, +]>, < Expression [3, 12, 5, +, +]>] [< Step [1, 2, +, 3, 4, *, 5, +, +]>, < Step [3, 12, 5, +, +]>, < Step [3, 17, +]>]
>>> e = Expression('1+2') >>> e = Expression('1+2')
>>> e1 = e.simplify() >>> e1 = e.simplify()
>>> f = Expression('3*4+5') >>> f = Expression('3*4+5')
@ -269,13 +270,13 @@ class Expression(Explicable):
>>> g = Expression('6+7') >>> g = Expression('6+7')
>>> g1 = g.simplify() >>> g1 = g.simplify()
>>> Expression.develop_steps([e1, f1, op.add, g1, op.mul]) >>> Expression.develop_steps([e1, f1, op.add, g1, op.mul])
[< Expression [1, 2, +, 3, 4, *, 5, +, +, 6, 7, +, *]>, < Expression [3, 12, 5, +, +, 13, *]>] [< Step [1, 2, +, 3, 4, *, 5, +, +, 6, 7, +, *]>, < Step [3, 12, 5, +, +, 13, *]>, < Step [3, 17, +, 13, *]>]
""" """
with Expression.tmp_render(): with Step.tmp_render():
tmp_steps = list(Explicable.merge_history(tokenList)) tmp_steps = list(Explicable.merge_history(tokenList))
tmp_steps = list(tmp_steps)[:-1] tmp_steps = list(tmp_steps)
steps = [Expression(s) for s in tmp_steps] steps = [Step(s) for s in tmp_steps]
return steps return steps
@classmethod @classmethod

68
pymath/calculus/step.py Normal file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env python
# encoding: utf-8
from .renderable import Renderable
__all__ = ['Step']
class Step(Renderable):
"""
A step is a Renderable which his only goal is to be render.
"""
@classmethod
def tmp_render(cls):
""" Create a container in which the method explain return only Step object.
>>> from .expression import Expression
>>> exp = Expression("2*3/5")
>>> print(exp)
2 \\times \\frac{ 3 }{ 5 }
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 }
>>> with Step.tmp_render():
... for i in exp.simplify().explain():
... print(i)
< Step [2, 3, 5, /, *]>
< Step [3, 5, /, 2, *]>
< Step [3, 2, *, 5, /]>
< Step [6, 5, /]>
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 }
"""
return super(Step, cls).tmp_render(Step)
def __init__(self, pstf_tokens):
"""Initiate the renderable objet
:param pstf_tokens: the postfix list of tokens
>>> s = Step([2, 3, '+'])
>>> s
< Step [2, 3, '+']>
>>> s1 = Step([s, 5, '*'])
>>> s1
< Step [2, 3, '+', 5, '*']>
"""
self.postfix_tokens = []
for t in pstf_tokens:
try:
self.postfix_tokens += t.postfix_tokens
except AttributeError:
self.postfix_tokens.append(t)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del