8 from libraries.recipes import overloading
9 from libraries.recipes import algorithms
12 @overloading.overloaded
13 def serialize_value(value, base, renderer):
14 yield renderer(value, base)
17 @serialize_value.register(complex, overloading.AnyType, overloading.AnyType)
18 def serialize_complex(value, base, renderer):
20 yield renderer(value.imag*1j, base)
21 elif value.imag == 0.0:
22 yield renderer(value.real, base)
24 yield renderer(value.real, base)
25 yield renderer(value.imag*1j, base)
29 def render_float(value):
33 def render_float_dec(value):
34 floatText = str(value)
35 dec = decimal.Decimal(floatText)
39 def render_float_eng(value):
40 floatText = str(value)
41 dec = decimal.Decimal(floatText)
42 return dec.to_eng_string()
45 def render_float_sci(value):
46 floatText = str(value)
47 dec = decimal.Decimal(floatText)
48 return dec.to_sci_string()
51 def render_complex(floatRender):
53 def render_complex_real(value):
54 realRendered = floatRender(value.real)
55 imagRendered = floatRender(value.imag)
56 rendered = "%s+%sj" % (realRendered, imagRendered)
59 return render_complex_real
62 def _seperate_num(rendered, sep, count):
64 >>> _seperate_num("123", ",", 3)
66 >>> _seperate_num("123456", ",", 3)
68 >>> _seperate_num("1234567", ",", 3)
71 leadCount = len(rendered) % count
72 choppyRest = algorithms.itergroup(rendered[leadCount:], count)
75 for group in choppyRest
78 lead = rendered[0:leadCount]
79 parts = itertools.chain((lead, ), rest)
82 return sep.join(parts)
85 def render_integer_oct(value, sep=""):
86 rendered = oct(int(value))
88 assert rendered.startswith("0")
89 rendered = "0o%s" % _seperate_num(rendered[1:], sep, 3)
93 def render_integer_dec(value, sep=""):
94 rendered = str(int(value))
96 rendered = "%s" % _seperate_num(rendered, sep, 3)
100 def render_integer_hex(value, sep=""):
101 rendered = hex(int(value))
103 assert rendered.startswith("0x")
104 rendered = "0x%s" % _seperate_num(rendered[2:], sep, 3)
108 def set_render_int_seperator(renderer, sep):
110 @functools.wrap(renderer)
111 def render_with_sep(value):
112 return renderer(value, sep)
114 return render_with_sep
117 class render_number(object):
125 self.render_int = ints
128 2: render_integer_hex,
129 8: render_integer_oct,
130 10: render_integer_dec,
131 16: render_integer_hex,
133 self.render_float = f if c is not None else render_float
134 self.render_complex = c if c is not None else self
136 def __call__(self, value, base):
137 return self.render(value, base)
139 @overloading.overloaded
140 def render(self, value, base):
143 @render.register(overloading.AnyType, int, overloading.AnyType)
144 def _render_int(self, value, base):
145 renderer = self.render_int.get(base, render_integer_dec)
146 return renderer(value)
148 @render.register(overloading.AnyType, float, overloading.AnyType)
149 def _render_float(self, value, base):
150 return self.render_float(value)
152 @render.register(overloading.AnyType, complex, overloading.AnyType)
153 def _render_complex(self, value, base):
154 return self.render_float(value)
157 class Operation(object):
163 raise NotImplementedError
170 def get_children(self):
173 def serialize(self, renderer):
174 for child in self.get_children():
175 for childItem in child.serialize(renderer):
180 @returns an operation tree with all constant calculations performed and only variables left
182 raise NotImplementedError
186 @returns a value that the tree represents, if it can't be evaluated,
187 then an exception is throwd
189 raise NotImplementedError
192 return self.evaluate()
195 class Value(Operation):
197 def __init__(self, value, base):
198 super(Value, self).__init__()
202 def serialize(self, renderer):
203 for item in super(Value, self).serialize(renderer):
205 for component in serialize_value(self.value, self.base, renderer):
209 return str(self.value)
218 class Constant(Operation):
220 def __init__(self, name, valueNode):
221 super(Constant, self).__init__()
223 self.__valueNode = valueNode
225 def serialize(self, renderer):
226 for item in super(Constant, self).serialize(renderer):
234 return self.__valueNode.simplify()
237 return self.__valueNode.evaluate()
240 class Variable(Operation):
242 def __init__(self, name):
243 super(Variable, self).__init__()
246 def serialize(self, renderer):
247 for item in super(Variable, self).serialize(renderer):
258 raise KeyError('Variable "%s" unable to evaluate to specific value' % self.name)
261 class Function(Operation):
273 def __init__(self, *args, **kwd):
274 super(Function, self).__init__()
278 self._simple = self._simplify()
279 self._str = self.pretty_print(args, kwd)
281 def serialize(self, renderer):
282 for item in super(Function, self).serialize(renderer):
286 def get_children(self):
289 for arg in self._args
296 bases = [arg.base for arg in self._args]
298 assert base is not None
308 selfArgs = [arg.evaluate() for arg in self._args]
309 return Value(self._op(*selfArgs), self.base)
312 selfArgs = [arg.simplify() for arg in self._args]
314 (name, arg.simplify())
315 for (name, arg) in self._kwd
319 args = [arg.evaluate() for arg in selfArgs]
321 result = self._op(*args)
323 node = Value(result, base)
330 def pretty_print(cls, args = None, kwds = None):
336 if cls._rep == cls.REP_FUNCTION:
337 positional = (str(arg) for arg in args)
339 "%s=%s" % (str(key), str(value))
340 for (key, value) in kwds.iteritems()
344 ", ".join(itertools.chain(named, positional)),
346 elif cls._rep == cls.REP_PREFIX:
347 assert len(args) == 1
348 return "%s %s" % (cls.symbol, args[0])
349 elif cls._rep == cls.REP_POSTFIX:
350 assert len(args) == 1
351 return "%s %s" % (args[0], cls.symbol)
352 elif cls._rep == cls.REP_INFIX:
353 assert len(args) == 2
354 return "(%s %s %s)" % (
360 raise AssertionError("Unsupported rep style")
363 def generate_function(op, rep, style, numArgs):
365 class GenFunc(Function):
367 def __init__(self, *args, **kwd):
368 super(GenFunc, self).__init__(*args, **kwd)
373 argumentCount = numArgs
375 GenFunc.__name__ = op.__name__
379 def change_base(base, rep):
381 class GenFunc(Function):
383 def __init__(self, *args, **kwd):
384 super(GenFunc, self).__init__(*args, **kwd)
386 self._simple = self._simplify()
387 self._str = self.pretty_print(args, kwd)
389 _op = lambda self, n: n
390 _rep = Function.REP_FUNCTION
394 GenFunc.__name__ = rep
398 @overloading.overloaded
399 def render_operation(render_func, operation):
400 return str(operation)
403 @render_operation.register(overloading.AnyType, Value)
404 def render_value(render_func, operation):
405 return render_func(operation.value, operation.base)
408 @render_operation.register(overloading.AnyType, Variable)
409 @render_operation.register(overloading.AnyType, Constant)
410 def render_variable(render_func, operation):
411 return operation.name
414 @render_operation.register(overloading.AnyType, Function)
415 def render_function(render_func, operation):
417 render_operation(render_func, arg)
418 for arg in operation.get_children()
420 return operation.pretty_print(args)