diff options
author | Marion <marion.zepf@gmail.com> | 2013-09-06 13:56:58 (GMT) |
---|---|---|
committer | Marion <marion.zepf@gmail.com> | 2013-09-06 13:56:58 (GMT) |
commit | 55024843adee06a07c59e6a59312354583694ba0 (patch) | |
tree | 201b42819dde04aa9ff3f720f272307396024f3c | |
parent | 73c40f3f55f8055fa8d8acf20ab5f4b7328f7b89 (diff) |
add Primitive for 'random' block; fix getting the key of a box
-rw-r--r-- | TurtleArt/tabasics.py | 37 | ||||
-rw-r--r-- | TurtleArt/talogo.py | 11 | ||||
-rw-r--r-- | TurtleArt/taprimitive.py | 31 |
3 files changed, 48 insertions, 31 deletions
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py index df17cfa..5f03994 100644 --- a/TurtleArt/tabasics.py +++ b/TurtleArt/tabasics.py @@ -135,7 +135,10 @@ class Palettes(): self.prim_cache = { "minus": Primitive(Primitive.minus, return_type=TYPE_NUMBER, - arg_descs=[ArgSlot(TYPE_NUMBER)]) + arg_descs=[ArgSlot(TYPE_NUMBER)]), + "ord": Primitive(ord, + return_type=TYPE_INT, + arg_descs=[ArgSlot(TYPE_CHAR)]) } # avoid several Primitives of the same function self._turtle_palette() @@ -721,7 +724,6 @@ blocks')) Primitive(Primitive.square_root, return_type=TYPE_FLOAT, arg_descs=[ArgSlot(TYPE_NUMBER)])) - primitive_dictionary['random'] = self._prim_random palette.add_block('random', style='number-style-block', label=[_('random'), _('min'), _('max')], @@ -730,9 +732,17 @@ blocks')) logo_command='tarandom', help_string=_('returns random number between \ minimum (top) and maximum (bottom) values')) - self.tw.lc.def_prim( - 'random', 2, lambda self, x, y: primitive_dictionary['random']( - x, y)) + + self.tw.lc.def_prim('random', 2, + or_(# random character ... + Primitive(Primitive.random_char, return_type=TYPE_CHAR, + arg_descs=[ + ArgSlot(TYPE_INT, wrapper=self.prim_cache["ord"]), + ArgSlot(TYPE_INT, wrapper=self.prim_cache["ord"])]), + # ... or random number + Primitive(Primitive.random_int, return_type=TYPE_INT, + arg_descs=[ArgSlot(TYPE_INT), ArgSlot(TYPE_INT)]))) + define_logo_function('tarandom', 'to tarandom :min :max\n \ output (random (:max - :min)) + :min\nend\n') @@ -1372,23 +1382,6 @@ variable')) except ValueError: raise logoerror("#syntaxerror") - def _prim_random(self, x, y): - ''' Random integer ''' - if _num_type(x) and _num_type(y): - return(int(round(uniform(x, y), 0))) - xx, xflag = chr_to_ord(x) - yy, yflag = chr_to_ord(y) - if xflag and yflag: - return chr(int(round(uniform(xx, yy), 0))) - if not xflag: - xx = self._string_to_num(x) - if not yflag: - yy = self._string_to_num(y) - try: - return(int(round(uniform(xx, yy), 0))) - except TypeError: - raise logoerror("#notanumber") - # Utilities def _string_to_num(self, x): diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index f1d5b91..10d7c27 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -747,7 +747,7 @@ class LogoCode: try: return self.boxes[key] except KeyError: - raise logoerror("#emptybox") + raise logoerror("#emptybox") # FIXME this looks like a syntax error in the GUI def _get_box_key(self, name): """ Return the key used for this box in the boxes dictionary and a @@ -756,9 +756,12 @@ class LogoCode: return (name, True) else: # make sure '5' and '5.0' point to the same box - if isinstance(name, (int, long)): - name = float(name) - return ('box3' + str(name), False) + if isinstance(name, (basestring, int, long)): + try: + name = float(name) + except ValueError: + pass + return ('box3_' + str(name), False) def prim_define_stack(self, name): """ Top of a named stack """ diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py index dc06ef3..956f50d 100644 --- a/TurtleArt/taprimitive.py +++ b/TurtleArt/taprimitive.py @@ -21,17 +21,15 @@ import ast from gettext import gettext as _ from math import sqrt +from random import uniform #from ast_pprint import * # only used for debugging, safe to comment out from tacanvas import TurtleGraphics from taconstants import (Color, CONSTANTS) -from talogo import (LogoCode, logoerror) +from talogo import (LogoCode, logoerror, NegativeRootError) from taturtle import (Turtle, Turtles) -from tatype import (ACTION_AST, BOX_AST, convert, get_call_ast, get_converter, - get_type, identity, is_bound_instancemethod, - is_instancemethod, is_staticmethod, TATypeError, Type, - TypeDisjunction, TYPE_COLOR, TYPE_FLOAT, TYPE_OBJECT) +from tatype import * from tautils import debug_output from tawindow import (global_objects, TurtleArtWindow) from util import ast_extensions @@ -434,6 +432,17 @@ class Primitive(object): return get_call_ast('sqrt', new_arg_asts, new_kwarg_asts, return_type=self.return_type) + # random + elif self in (Primitive.random_char, Primitive.random_int): + uniform_ast = get_call_ast('uniform', new_arg_asts) + round_ast = get_call_ast('round', [uniform_ast, ast.Num(n=0)]) + int_ast = get_call_ast('int', [round_ast], return_type=TYPE_INT) + if self == Primitive.random_char: + chr_ast = get_call_ast('chr', [int_ast], return_type=TYPE_CHAR) + return chr_ast + else: + return int_ast + # identity elif self == Primitive.identity: if len(new_arg_asts) == 1: @@ -702,6 +711,18 @@ class Primitive(object): if not tw.hide and tw.step_time != 0: tw.showlabel('print', text) + @staticmethod + def random_int(lower, upper): + """ Choose a random integer between lower and upper, which must be + integers """ + return int(round(uniform(lower, upper), 0)) + + @staticmethod + def random_char(lower, upper): + """ Choose a random Unicode code point between lower and upper, + which must be integers """ + return chr(Primitive.random_int(lower, upper)) + class Disjunction(tuple): """ Abstract disjunction class (not to be instantiated directly) """ |