From 2f3ccc0fcbb5318e50f1e429b93d2ae36a55aad5 Mon Sep 17 00:00:00 2001 From: Marion Date: Mon, 16 Sep 2013 11:20:55 +0000 Subject: add Primitive for the 'f(x)' block --- diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 76f0d3a..86027ee 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -38,6 +38,7 @@ import traceback from tablock import (Block, Media, media_blocks_dictionary) from taconstants import (TAB_LAYER, DEFAULT_SCALE) +from tajail import myfunc from tapalette import (block_names, value_blocks) from tatype import TATypeError from tautils import (get_pixbuf_from_journal, data_from_file, @@ -805,6 +806,37 @@ class LogoCode: while self.heap: self.heap.pop() + def prim_myfunction(self, f, *args): + """ Programmable block (Call tajail.myfunc and convert any errors to + logoerrors) """ + try: + y = myfunc(f, args) + if str(y) == 'nan': + debug_output('Python function returned NAN', + self.tw.running_sugar) + self.stop_logo() + raise logoerror("#notanumber") + else: + return y + except ZeroDivisionError: + self.stop_logo() + raise logoerror("#zerodivide") + except ValueError, e: + self.stop_logo() + raise logoerror('#' + str(e)) + except SyntaxError, e: + self.stop_logo() + raise logoerror('#' + str(e)) + except NameError, e: + self.stop_logo() + raise logoerror('#' + str(e)) + except OverflowError: + self.stop_logo() + raise logoerror("#overflowerror") + except TypeError: + self.stop_logo() + raise logoerror("#notanumber") + def clear_value_blocks(self): if not hasattr(self, 'value_blocks_to_update'): return diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py index 36ad49c..7f30071 100644 --- a/TurtleArt/taprimitive.py +++ b/TurtleArt/taprimitive.py @@ -417,6 +417,16 @@ class Primitive(object): else: return ast.BinOp(op=op, left=left, right=right) + # f(x) + elif self == LogoCode.prim_myfunction: + param_asts = [] + for id_ in ['x', 'y', 'z'][:len(new_arg_asts)-1]: + param_asts.append(ast.Name(id=id_, ctx=ast.Param)) + func_ast = ast.Lambda(body=new_arg_asts[0], args=ast.arguments( + args=param_asts, vararg=None, kwarg=None, defaults=[])) + return get_call_ast(func_ast, new_arg_asts[1:], + return_type=self.return_type) + # square root elif self == Primitive.square_root: return get_call_ast('sqrt', new_arg_asts, new_kwarg_asts, diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py index d0fb8eb..01b2a68 100644 --- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py +++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py @@ -37,10 +37,10 @@ from TurtleArt.taconstants import (DEFAULT_SCALE, ICON_SIZE, CONSTANTS, from TurtleArt.tautils import (round_int, debug_output, get_path, data_to_string, find_group, image_to_base64, hat_on_top, listify, data_from_file) -from TurtleArt.tajail import (myfunc, myfunc_import) +from TurtleArt.tajail import myfunc_import from TurtleArt.taprimitive import (ArgSlot, ConstantArg, Primitive) from TurtleArt.tatype import (TYPE_BOOL, TYPE_BOX, TYPE_CHAR, TYPE_INT, - TYPE_OBJECT, TYPE_STRING) + TYPE_FLOAT, TYPE_OBJECT, TYPE_STRING) def _num_type(x): @@ -596,7 +596,6 @@ bottom of the screen')) Primitive(Primitive.identity, return_type=TYPE_INT, arg_descs=[ArgSlot(TYPE_INT)])) - primitive_dictionary['myfunction'] = self._prim_myfunction palette.add_block('myfunc1arg', style='number-style-var-arg', label=[_('Python'), 'f(x)', 'x'], @@ -606,8 +605,8 @@ bottom of the screen')) help_string=_('a programmable block: used to add \ advanced single-variable math equations, e.g., sin(x)')) self.tw.lc.def_prim('myfunction', 2, - lambda self, f, x: - primitive_dictionary['myfunction'](f, [x])) + Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT, + arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT)])) palette.add_block('myfunc2arg', hidden=True, @@ -620,8 +619,9 @@ advanced single-variable math equations, e.g., sin(x)')) help_string=_('a programmable block: used to add \ advanced multi-variable math equations, e.g., sqrt(x*x+y*y)')) self.tw.lc.def_prim('myfunction2', 3, - lambda self, f, x, y: - primitive_dictionary['myfunction'](f, [x, y])) + Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT, + arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT), + ArgSlot(TYPE_FLOAT)])) palette.add_block('myfunc3arg', hidden=True, @@ -634,8 +634,9 @@ advanced multi-variable math equations, e.g., sqrt(x*x+y*y)')) help_string=_('a programmable block: used to add \ advanced multi-variable math equations, e.g., sin(x+y+z)')) self.tw.lc.def_prim('myfunction3', 4, - lambda self, f, x, y, z: - primitive_dictionary['myfunction'](f, [x, y, z])) + Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT, + arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT), + ArgSlot(TYPE_FLOAT), ArgSlot(TYPE_FLOAT)])) primitive_dictionary['userdefined'] = self._prim_myblock palette.add_block('userdefined', @@ -1080,39 +1081,6 @@ Journal objects')) except: raise logoerror("#syntaxerror") - def _prim_myfunction(self, f, x): - """ Programmable block """ - for i, v in enumerate(x): - if type(v) == int: # Pass float values to Python block - x[i] = float(v) - try: - y = myfunc(f, x) - if str(y) == 'nan': - debug_output('Python function returned NAN', - self.tw.running_sugar) - self.tw.lc.stop_logo() - raise logoerror("#notanumber") - else: - return y - except ZeroDivisionError: - self.tw.lc.stop_logo() - raise logoerror("#zerodivide") - except ValueError, e: - self.tw.lc.stop_logo() - raise logoerror('#' + str(e)) - except SyntaxError, e: - self.tw.lc.stop_logo() - raise logoerror('#' + str(e)) - except NameError, e: - self.tw.lc.stop_logo() - raise logoerror('#' + str(e)) - except OverflowError: - self.tw.lc.stop_logo() - raise logoerror("#overflowerror") - except TypeError: - self.tw.lc.stop_logo() - raise logoerror("#notanumber") - def _prim_is_heap_empty(self): """ is FILO empty? """ if len(self.tw.lc.heap) == 0: -- cgit v0.9.1