Solve bug with context manager

This commit is contained in:
Lafrite 2015-02-27 17:46:16 +01:00
parent c2bb98ab40
commit 506045a670
3 changed files with 90 additions and 64 deletions

View File

@ -1,7 +1,58 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
class Explicable(object): from .render import txt, tex
class Renderable(object):
STR_RENDER = tex
DEFAULT_RENDER = tex
@classmethod
def set_render(cls, render):
cls.STR_RENDER = render
@classmethod
def get_render(cls):
return cls.STR_RENDER
@classmethod
def set_default_render(cls):
cls.set_render(cls.DEFAULT_RENDER)
@classmethod
def tmp_render(cls, render = tex):
""" Create a container in which Expression render is temporary modify
The default temporary render is Expression in order to perform calculus inside numbers
>>> 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{ 6 }{ 5 }
>>> with Expression.tmp_render(txt):
... for i in exp.simplify().explain():
... print(i)
2 * 3 / 5
6 / 5
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 6 }{ 5 }
"""
class TmpRenderEnv(object):
def __enter__(self):
self.old_render = Renderable.get_render()
Renderable.set_render(render)
def __exit__(self, type, value, traceback):
Renderable.set_render(self.old_render)
return TmpRenderEnv()
class Explicable(Renderable):
""" An Explicable object is an object which can be explicable! """ An Explicable object is an object which can be explicable!

View File

@ -4,71 +4,14 @@
from .generic import Stack, flatten_list, expand_list, isNumber, isOperator, isNumerand from .generic import Stack, flatten_list, expand_list, isNumber, isOperator, isNumerand
from .str2tokens import str2tokens from .str2tokens import str2tokens
from .operator import op from .operator import op
from .render import txt, tex
from .explicable import Explicable from .explicable import Explicable
from .random_expression import RdExpression from .random_expression import RdExpression
__all__ = ['Expression', 'Renderable'] __all__ = ['Expression']
class Renderable(object):
STR_RENDER = tex
DEFAULT_RENDER = tex
@classmethod
def set_render(cls, render):
cls.STR_RENDER = render
@classmethod
def get_render(cls):
return cls.STR_RENDER
@classmethod
def set_default_render(cls):
cls.set_render(cls.DEFAULT_RENDER)
@classmethod
def tmp_render(cls, render = lambda _,x:Expression(x)):
""" Create a container in which Expression render is temporary modify
The default temporary render is Expression in order to perform calculus inside numbers
>>> exp = Expression("2*3/5")
>>> print(exp)
\\frac{ 2 \\times 3 }{ 5 }
>>> for i in exp.simplify().explain():
... print(i)
\\frac{ 2 \\times 3 }{ 5 }
\\frac{ 6 }{ 5 }
>>> with Expression.tmp_render():
... for i in exp.simplify().explain():
... i
< Expression [2, 3, '*', 5, '/']>
< Expression [6, 5, '/']>
< Fraction 6 / 5>
>>> with Expression.tmp_render(txt):
... for i in exp.simplify().explain():
... print(i)
2 * 3 / 5
6 / 5
>>> for i in exp.simplify().explain():
... print(i)
\\frac{ 2 \\times 3 }{ 5 }
\\frac{ 6 }{ 5 }
"""
class TmpRenderEnv(object):
def __enter__(self):
self.old_render = Expression.get_render()
Expression.set_render(render)
def __exit__(self, type, value, traceback):
Expression.set_render(self.old_render)
return TmpRenderEnv()
class Expression(Explicable, Renderable): 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"""
@ -85,6 +28,38 @@ class Expression(Explicable, Renderable):
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
def tmp_render(cls, render = lambda _,x:Expression(x)):
""" Same ad tmp_render for Renderable but default render is 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{ 6 }{ 5 }
>>> with Expression.tmp_render():
... for i in exp.simplify().explain():
... i
< <class '__main__.Expression'> [2, 3, 5, '/', '*'] >
< <class '__main__.Expression'> [2, < Fraction 3 / 5>, '*'] >
< <class '__main__.Expression'> [2, < Fraction 3 / 5>, '*'] >
< <class '__main__.Expression'> [6, 5, '/'] >
>>> from .render import txt
>>> with Expression.tmp_render(txt):
... for i in exp.simplify().explain():
... print(i)
2 * 3 / 5
6 / 5
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 6 }{ 5 }
"""
return super(Expression, cls).tmp_render(render)
def __new__(cls, exp): def __new__(cls, exp):
"""Create Expression objects """Create Expression objects
@ -109,7 +84,7 @@ class Expression(Explicable, Renderable):
simplify = lambda x:x simplify = lambda x:x
is_number = True is_number = True
methods_attr = {'simplify':simplify, 'isNumber': is_number, 'postfix_tokens': [token]} methods_attr = {'simplify':simplify, 'isNumber': is_number, 'postfix_tokens': [token]}
fake_token = type('fake_int', (int,Explicable, Renderable), methods_attr)(token) fake_token = type('fake_int', (int,Explicable, ), methods_attr)(token)
return fake_token return fake_token
elif type(token) == str: elif type(token) == str:
@ -118,7 +93,7 @@ class Expression(Explicable, Renderable):
simplify = lambda x:[x] simplify = lambda x:[x]
is_polynom = True is_polynom = True
methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]} methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]}
fake_token = type('fake_str', (str,Explicable, Renderable), methods_attr)(token) fake_token = type('fake_str', (str,Explicable, ), methods_attr)(token)
return fake_token return fake_token
else: else:

View File

@ -4,7 +4,7 @@
from .arithmetic import gcd from .arithmetic import gcd
from .generic import isNumber from .generic import isNumber
from .operator import op from .operator import op
from .expression import Expression, Renderable from .expression import Expression
from .explicable import Explicable from .explicable import Explicable
from .render import txt, tex from .render import txt, tex
from copy import copy from copy import copy
@ -12,7 +12,7 @@ from copy import copy
__all__ = ['Fraction'] __all__ = ['Fraction']
class Fraction(Explicable, Renderable): class Fraction(Explicable):
"""Fractions!""" """Fractions!"""
def __init__(self, num, denom = 1): def __init__(self, num, denom = 1):