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
165 def get_children(self):
168 def serialize(self, renderer):
169 for child in self.get_children():
170 for childItem in child.serialize(renderer):
175 @returns an operation tree with all constant calculations performed and only variables left
177 raise NotImplementedError
181 @returns a value that the tree represents, if it can't be evaluated,
182 then an exception is throwd
184 raise NotImplementedError
187 return self.evaluate()
190 class Value(Operation):
192 def __init__(self, value, base):
193 super(Value, self).__init__()
197 def serialize(self, renderer):
198 for item in super(Value, self).serialize(renderer):
200 for component in serialize_value(self.value, self.base, renderer):
204 return str(self.value)
213 class Constant(Operation):
215 def __init__(self, name, valueNode):
216 super(Constant, self).__init__()
218 self.__valueNode = valueNode
220 def serialize(self, renderer):
221 for item in super(Constant, self).serialize(renderer):
229 return self.__valueNode.simplify()
232 return self.__valueNode.evaluate()
235 class Variable(Operation):
237 def __init__(self, name):
238 super(Variable, self).__init__()
241 def serialize(self, renderer):
242 for item in super(Variable, self).serialize(renderer):
256 class Function(Operation):
268 def __init__(self, *args, **kwd):
269 super(Function, self).__init__()
272 self.__simple = self.__simplify()
273 self.__str = self.pretty_print(args, kwd)
275 def serialize(self, renderer):
276 for item in super(Function, self).serialize(renderer):
280 def get_children(self):
283 for arg in self._args
293 selfArgs = [arg.evaluate() for arg in self._args]
294 return Value(self._op(*selfArgs))
296 def __simplify(self):
297 selfArgs = [arg.simplify() for arg in self._args]
299 (name, arg.simplify())
300 for (name, arg) in self._kwd
304 args = [arg.evaluate() for arg in selfArgs]
307 bases = [arg.base for arg in selfArgs]
309 result = self._op(*args)
311 node = Value(result, base)
313 node = type(self)(*selfArgs, **selfKwd)
318 def pretty_print(cls, args = None, kwds = None):
324 if cls._rep == cls.REP_FUNCTION:
325 positional = (str(arg) for arg in args)
327 "%s=%s" % (str(key), str(value))
328 for (key, value) in kwds.iteritems()
332 ", ".join(itertools.chain(named, positional)),
334 elif cls._rep == cls.REP_PREFIX:
335 assert len(args) == 1
336 return "%s %s" % (cls.symbol, args[0])
337 elif cls._rep == cls.REP_POSTFIX:
338 assert len(args) == 1
339 return "%s %s" % (args[0], cls.symbol)
340 elif cls._rep == cls.REP_INFIX:
341 assert len(args) == 2
342 return "(%s %s %s)" % (
348 raise AssertionError("Unsupported rep style")
351 def generate_function(op, rep, style, numArgs):
353 class GenFunc(Function):
355 def __init__(self, *args, **kwd):
356 super(GenFunc, self).__init__(*args, **kwd)
361 argumentCount = numArgs
363 GenFunc.__name__ = op.__name__
367 def change_base(base, rep):
369 class GenFunc(Function):
371 def __init__(self, *args, **kwd):
372 super(GenFunc, self).__init__(*args, **kwd)
375 _op = lambda self, n: n
376 _rep = Function.REP_FUNCTION
380 GenFunc.__name__ = rep
384 @overloading.overloaded
385 def render_operation(render_func, operation):
386 return str(operation)
389 @render_operation.register(overloading.AnyType, Value)
390 def render_value(render_func, operation):
391 return render_func(operation.value, operation.base)
394 @render_operation.register(overloading.AnyType, Variable)
395 @render_operation.register(overloading.AnyType, Constant)
396 def render_variable(render_func, operation):
397 return operation.name
400 @render_operation.register(overloading.AnyType, Function)
401 def render_function(render_func, operation):
403 render_operation(render_func, arg)
404 for arg in operation.get_children()
406 return operation.pretty_print(args)