diff options
Diffstat (limited to 'TurtleArt/talogo.py')
-rw-r--r-- | TurtleArt/talogo.py | 512 |
1 files changed, 271 insertions, 241 deletions
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 0801d75..0d467ac 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -47,9 +47,12 @@ _logger = logging.getLogger('turtleart-activity') class noKeyError(UserDict): + __missing__ = lambda x, y: 0 + class symbol: + def __init__(self, name): self.name = name self.nargs = None @@ -57,17 +60,22 @@ class symbol: def __str__(self): return self.name + def __repr__(self): return '#' + self.name + class logoerror(Exception): + def __init__(self, value): self.value = value + def __str__(self): return repr(self.value) # Utility functions + def numtype(x): """ Is x a number type? """ if type(x) == int: @@ -78,9 +86,10 @@ def numtype(x): return True return False + def str_to_num(x): """ Try to comvert a string to a number """ - xx = convert(x.replace(self.tw.decimal_point,'.'), float) + xx = convert(x.replace(self.tw.decimal_point, '.'), float) if type(xx) is float: return xx else: @@ -90,18 +99,21 @@ def str_to_num(x): else: raise logoerror("#syntaxerror") + def taand(x, y): """ Logical and """ - return x&y + return x & y + def taor(x, y): """ Logical or """ - return x|y + return x | y + def careful_divide(x, y): """ Raise error on divide by zero """ try: - return x/y + return x / y except ZeroDivisionError: raise logoerror("#zerodivide") except TypeError: @@ -114,10 +126,11 @@ def careful_divide(x, y): except TypeError: raise logoerror("#notanumber") + def taequal(x, y): """ Numeric and logical equal """ try: - return float(x)==float(y) + return float(x) == float(y) except TypeError: typex, typey = False, False if strtype(x): @@ -131,10 +144,11 @@ def taequal(x, y): except ValueError: raise logoerror("#syntaxerror") + def taless(x, y): """ Compare numbers and strings """ try: - return float(x)<float(y) + return float(x) < float(y) except ValueError: typex, typey = False, False if strtype(x): @@ -148,14 +162,16 @@ def taless(x, y): except TypeError: raise logoerror("#notanumber") + def tamore(x, y): """ Compare numbers and strings """ return taless(y, x) + def taplus(x, y): """ Add numbers, concat strings """ if numtype(x) and numtype(y): - return(x+y) + return(x + y) else: if numtype(x): xx = str(round_int(x)) @@ -165,42 +181,46 @@ def taplus(x, y): yy = str(round_int(y)) else: yy = str(y) - return(xx+yy) - + return(xx + yy) + + def taminus(x, y): """ Numerical subtraction """ if numtype(x) and numtype(y): - return(x-y) + return(x - y) try: return str_to_num(x) - str_to_num(y) except TypeError: raise logoerror("#notanumber") - + + def taproduct(x, y): """ Numerical multiplication """ if numtype(x) and numtype(y): - return(x*y) + return(x * y) try: return str_to_num(x) * str_to_num(y) except TypeError: raise logoerror("#notanumber") + def tamod(x, y): """ Numerical mod """ if numtype(x) and numtype(y): - return(x%y) + return(x % y) try: return str_to_num(x) % str_to_num(y) except TypeError: raise logoerror("#notanumber") except ValueError: raise logoerror("#syntaxerror") - + + def tasqrt(x): """ Square root """ if numtype(x): if x < 0: - raise logoerror("#negroot") + raise logoerror("#negroot") return sqrt(x) try: return sqrt(str_to_num(x)) @@ -209,190 +229,199 @@ def tasqrt(x): except TypeError: raise logoerror("#notanumber") + def tarandom(x, y): """ Random integer """ if numtype(x) and numtype(y): - return(int(round(uniform(x, y),0))) + 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))) + return chr(int(round(uniform(xx, yy), 0))) if not xflag: xx = str_to_num(x) if not yflag: yy = str_to_num(y) try: - return(int(round(uniform(xx, yy),0))) + return(int(round(uniform(xx, yy), 0))) except TypeError: raise logoerror("#notanumber") + def identity(x): """ Identity function """ return(x) - + + def stop_logo(tw): """ Stop logo is called from the Stop button on the toolbar """ tw.step_time = 0 tw.lc.step = just_stop() tw.active_turtle.show() + def just_stop(): """ yield False to stop stack """ yield False + def millis(): """ Current time in milliseconds """ - return int(clock()*1000) + return int(clock() * 1000) -""" -A class for parsing Logo Code -""" class LogoCode: + """ A class for parsing Logo code """ + def __init__(self, tw): self.tw = tw self.oblist = {} DEFPRIM = { - '(':[1, lambda self, x: self.prim_opar(x)], - 'and':[2, lambda self, x, y: taand(x, y)], - 'arc':[2, lambda self, x, y: self.tw.canvas.arc(x, y)], - 'back':[1, lambda self, x: self.tw.canvas.forward(-x)], - 'black':[0, lambda self: BLACK], - 'blue':[0, lambda self: 70], - 'bpos':[0, lambda self: -self.tw.canvas.height/(self.tw.coord_scale*2)], - 'boty':[0, lambda self: self.tw.bottomy], - 'box1':[0, lambda self: self.boxes['box1']], - 'box':[1, lambda self, x: self.box(x)], - 'box2':[0, lambda self: self.boxes['box2']], - 'bullet':[1, self.prim_bullet, True], - 'bulletlist':[1, self.prim_list, True], - 'cartesian':[0, lambda self: self.tw.set_cartesian(True)], - 'clean':[0, lambda self: self.prim_clear()], - 'clearheap':[0, lambda self: self.empty_heap()], - 'color':[0, lambda self: self.tw.canvas.color], - 'gray':[0, lambda self: self.tw.canvas.gray], - 'comment':[1, lambda self, x: self.prim_print(x, True)], - 'container':[1, lambda self,x: x], - 'cyan':[0, lambda self: 50], - 'define':[2, self.prim_define], - 'division':[2, lambda self, x, y: careful_divide(x, y)], - 'equal?':[2, lambda self,x, y: taequal(x, y)], - 'fillscreen':[2, lambda self, x, y: self.tw.canvas.fillscreen(x, y)], - 'forever':[1, self.prim_forever, True], - 'forward':[1, lambda self, x: self.tw.canvas.forward(x)], - 'fullscreen':[0, lambda self: self.tw.set_fullscreen()], - 'greater?':[2, lambda self, x, y: tamore(x, y)], - 'green':[0, lambda self: 30], - 'heading':[0, lambda self: self.tw.canvas.heading], - 'hideblocks':[0, lambda self: self.tw.hideblocks()], - 'hres':[0, lambda self: self.tw.canvas.width/self.tw.coord_scale], - 'id':[1, lambda self, x: identity(x)], - 'if':[2, self.prim_if, True], - 'ifelse':[3, self.prim_ifelse, True], - 'insertimage':[1, lambda self, x: self.insert_image(x, False)], - 'kbinput':[0, lambda self: self.prim_kbinput()], - 'keyboard':[0, lambda self: self.keyboard], - 'left':[1, lambda self, x: self.tw.canvas.right(-x)], - 'leftx':[0, lambda self: self.tw.leftx], - 'lpos':[0, lambda self: -self.tw.canvas.width/(self.tw.coord_scale*2)], - 'less?':[2, lambda self, x, y: taless(x, y)], - 'minus':[2, lambda self, x, y: taminus(x, y)], - 'mod':[2, lambda self, x, y: tamod(x, y)], - 'myfunction':[2, lambda self, f, x: self.myfunction(f, [x])], - 'myfunction2':[3, lambda self, f, x, y: self.myfunction(f, [x, y])], - 'myfunction3':[4, lambda self, f, x, y, z: self.myfunction( - f, [x, y, z])], - 'nop':[0, lambda self: None], - 'nop1':[0, lambda self: None], - 'nop2':[0, lambda self: None], - 'nop3':[1, lambda self, x: None], - 'not':[1, lambda self, x: not x], - 'orange':[0, lambda self: 10], - 'or':[2, lambda self, x, y: taor(x, y)], - 'pendown':[0, lambda self: self.tw.canvas.setpen(True)], - 'pensize':[0, lambda self: self.tw.canvas.pensize], - 'penup':[0, lambda self: self.tw.canvas.setpen(False)], - 'plus':[2, lambda self, x, y: taplus(x, y)], - 'polar':[0, lambda self: self.tw.set_polar(True)], - 'pop':[0, lambda self: self.prim_pop()], - 'print':[1, lambda self, x: self.prim_print(x, False)], - 'printheap':[0, lambda self: self.prim_print_heap()], - 'product':[2, lambda self, x, y: taproduct(x, y)], - 'purple':[0, lambda self: 90], - 'push':[1, lambda self, x: self.prim_push(x)], - 'random':[2, lambda self, x, y: tarandom(x, y)], - 'readpixel':[0, lambda self: self.read_pixel()], - 'red':[0, lambda self: 0], - 'repeat':[2, self.prim_repeat, True], - 'right':[1, lambda self, x: self.tw.canvas.right(x)], - 'rightx':[0, lambda self: self.tw.rightx], - 'rpos':[0, lambda self: self.tw.canvas.width/(self.tw.coord_scale*2)], - 'savepix':[1, lambda self, x: self.save_picture(x)], - 'savesvg':[1, lambda self, x: self.save_svg(x)], - 'scale':[0, lambda self: self.scale], - 'see':[0, lambda self: self.see()], - 'setcolor':[1, lambda self, x: self.tw.canvas.setcolor(x)], - 'setgray':[1, lambda self, x: self.tw.canvas.setgray(x)], - 'seth':[1, lambda self, x: self.tw.canvas.seth(x)], - 'setpensize':[1, lambda self, x: self.tw.canvas.setpensize(x)], - 'setscale':[1, lambda self, x: self.set_scale(x)], - 'setshade':[1, lambda self, x: self.tw.canvas.setshade(x)], - 'settextcolor':[1, lambda self, x: self.tw.canvas.settextcolor(x)], - 'settextsize':[1, lambda self, x: self.tw.canvas.settextsize(x)], - 'setxy2':[2, lambda self, x, y: self.tw.canvas.setxy(x, y)], - 'setxy':[2, lambda self, x, y: self.tw.canvas.setxy(x, y, + '(': [1, lambda self, x: self.prim_opar(x)], + 'and': [2, lambda self, x, y: taand(x, y)], + 'arc': [2, lambda self, x, y: self.tw.canvas.arc(x, y)], + 'back': [1, lambda self, x: self.tw.canvas.forward(-x)], + 'black': [0, lambda self: BLACK], + 'blue': [0, lambda self: 70], + 'bpos': [0, lambda self: -self.tw.canvas.height / \ + (self.tw.coord_scale * 2)], + 'boty': [0, lambda self: self.tw.bottomy], + 'box1': [0, lambda self: self.boxes['box1']], + 'box': [1, lambda self, x: self.box(x)], + 'box2': [0, lambda self: self.boxes['box2']], + 'bullet': [1, self.prim_bullet, True], + 'bulletlist': [1, self.prim_list, True], + 'cartesian': [0, lambda self: self.tw.set_cartesian(True)], + 'clean': [0, lambda self: self.prim_clear()], + 'clearheap': [0, lambda self: self.empty_heap()], + 'color': [0, lambda self: self.tw.canvas.color], + 'gray': [0, lambda self: self.tw.canvas.gray], + 'comment': [1, lambda self, x: self.prim_print(x, True)], + 'container': [1, lambda self, x: x], + 'cyan': [0, lambda self: 50], + 'define': [2, self.prim_define], + 'division': [2, lambda self, x, y: careful_divide(x, y)], + 'equal?': [2, lambda self,x, y: taequal(x, y)], + 'fillscreen': [2, lambda self, x, y: self.tw.canvas.fillscreen(x, y)], + 'forever': [1, self.prim_forever, True], + 'forward': [1, lambda self, x: self.tw.canvas.forward(x)], + 'fullscreen': [0, lambda self: self.tw.set_fullscreen()], + 'greater?': [2, lambda self, x, y: tamore(x, y)], + 'green': [0, lambda self: 30], + 'heading': [0, lambda self: self.tw.canvas.heading], + 'hideblocks': [0, lambda self: self.tw.hideblocks()], + 'hres': [0, lambda self: self.tw.canvas.width / self.tw.coord_scale], + 'id': [1, lambda self, x: identity(x)], + 'if': [2, self.prim_if, True], + 'ifelse': [3, self.prim_ifelse, True], + 'insertimage': [1, lambda self, x: self.insert_image(x, False)], + 'kbinput': [0, lambda self: self.prim_kbinput()], + 'keyboard': [0, lambda self: self.keyboard], + 'left': [1, lambda self, x: self.tw.canvas.right(-x)], + 'leftx': [0, lambda self: self.tw.leftx], + 'lpos': [0, lambda self: -self.tw.canvas.width / \ + (self.tw.coord_scale * 2)], + 'less?': [2, lambda self, x, y: taless(x, y)], + 'minus': [2, lambda self, x, y: taminus(x, y)], + 'mod': [2, lambda self, x, y: tamod(x, y)], + 'myfunction': [2, lambda self, f, x: self.myfunction(f, [x])], + 'myfunction2': [3, lambda self, f, x, y: self.myfunction(f, [x, y])], + 'myfunction3': [4, lambda self, f, x, y, z: self.myfunction( + f, [x, y, z])], + 'nop': [0, lambda self: None], + 'nop1': [0, lambda self: None], + 'nop2': [0, lambda self: None], + 'nop3': [1, lambda self, x: None], + 'not': [1, lambda self, x: not x], + 'orange': [0, lambda self: 10], + 'or': [2, lambda self, x, y: taor(x, y)], + 'pendown': [0, lambda self: self.tw.canvas.setpen(True)], + 'pensize': [0, lambda self: self.tw.canvas.pensize], + 'penup': [0, lambda self: self.tw.canvas.setpen(False)], + 'plus': [2, lambda self, x, y: taplus(x, y)], + 'polar': [0, lambda self: self.tw.set_polar(True)], + 'pop': [0, lambda self: self.prim_pop()], + 'print': [1, lambda self, x: self.prim_print(x, False)], + 'printheap': [0, lambda self: self.prim_print_heap()], + 'product': [2, lambda self, x, y: taproduct(x, y)], + 'purple': [0, lambda self: 90], + 'push': [1, lambda self, x: self.prim_push(x)], + 'random': [2, lambda self, x, y: tarandom(x, y)], + 'readpixel': [0, lambda self: self.read_pixel()], + 'red': [0, lambda self: 0], + 'repeat': [2, self.prim_repeat, True], + 'right': [1, lambda self, x: self.tw.canvas.right(x)], + 'rightx': [0, lambda self: self.tw.rightx], + 'rpos': [0, lambda self: self.tw.canvas.width / \ + (self.tw.coord_scale * 2)], + 'savepix': [1, lambda self, x: self.save_picture(x)], + 'savesvg': [1, lambda self, x: self.save_svg(x)], + 'scale': [0, lambda self: self.scale], + 'see': [0, lambda self: self.see()], + 'setcolor': [1, lambda self, x: self.tw.canvas.setcolor(x)], + 'setgray': [1, lambda self, x: self.tw.canvas.setgray(x)], + 'seth': [1, lambda self, x: self.tw.canvas.seth(x)], + 'setpensize': [1, lambda self, x: self.tw.canvas.setpensize(x)], + 'setscale': [1, lambda self, x: self.set_scale(x)], + 'setshade': [1, lambda self, x: self.tw.canvas.setshade(x)], + 'settextcolor': [1, lambda self, x: self.tw.canvas.settextcolor(x)], + 'settextsize': [1, lambda self, x: self.tw.canvas.settextsize(x)], + 'setxy2': [2, lambda self, x, y: self.tw.canvas.setxy(x, y)], + 'setxy': [2, lambda self, x, y: self.tw.canvas.setxy(x, y, pendown=False)], - 'shade':[0, lambda self: self.tw.canvas.shade], - 'show':[1, lambda self, x: self.show(x, True)], - 'showaligned':[1,lambda self, x: self.show(x, False)], - 'showblocks':[0, lambda self: self.tw.showblocks()], - 'skin':[1, lambda self, x: self.reskin(x)], - 'sound':[1, lambda self, x: self.play_sound(x)], - 'sqrt':[1, lambda self, x: tasqrt(x)], - 'stack1':[0, self.prim_stack1, True], - 'stack':[1, self.prim_stack, True], - 'stack2':[0, self.prim_stack2, True], - 'start':[0, lambda self: self.prim_start()], - 'startfill':[0, lambda self: self.tw.canvas.start_fill()], - 'stopfill':[0, lambda self: self.tw.canvas.stop_fill()], - 'stopstack':[0, lambda self: self.prim_stopstack()], - 'storeinbox1':[1, lambda self, x: self.prim_setbox('box1', None ,x)], - 'storeinbox2':[1, lambda self, x: self.prim_setbox('box2', None, x)], - 'storeinbox':[2, lambda self, x, y: self.prim_setbox('box3', x, y)], - 't1x1':[2, lambda self, x, y: self.show_template1x1(x, y)], - 't1x1a':[2, lambda self, x, y: self.show_template1x1a(x, y)], - 't1x2':[3, lambda self, x, y, z: self.show_template1x2(x, y, z)], - 't2x1':[3, lambda self, x, y, z: self.show_template2x1(x, y, z)], - 't2x2':[5, lambda self, x, y, z, a, b: self.show_template2x2( + 'shade': [0, lambda self: self.tw.canvas.shade], + 'show': [1, lambda self, x: self.show(x, True)], + 'showaligned': [1,lambda self, x: self.show(x, False)], + 'showblocks': [0, lambda self: self.tw.showblocks()], + 'skin': [1, lambda self, x: self.reskin(x)], + 'sound': [1, lambda self, x: self.play_sound(x)], + 'sqrt': [1, lambda self, x: tasqrt(x)], + 'stack1': [0, self.prim_stack1, True], + 'stack': [1, self.prim_stack, True], + 'stack2': [0, self.prim_stack2, True], + 'start': [0, lambda self: self.prim_start()], + 'startfill': [0, lambda self: self.tw.canvas.start_fill()], + 'stopfill': [0, lambda self: self.tw.canvas.stop_fill()], + 'stopstack': [0, lambda self: self.prim_stopstack()], + 'storeinbox1': [1, lambda self, x: self.prim_setbox('box1', None, x)], + 'storeinbox2': [1, lambda self, x: self.prim_setbox('box2', None, x)], + 'storeinbox': [2, lambda self, x, y: self.prim_setbox('box3', x, y)], + 't1x1': [2, lambda self, x, y: self.show_template1x1(x, y)], + 't1x1a': [2, lambda self, x, y: self.show_template1x1a(x, y)], + 't1x2': [3, lambda self, x, y, z: self.show_template1x2(x, y, z)], + 't2x1': [3, lambda self, x, y, z: self.show_template2x1(x, y, z)], + 't2x2': [5, lambda self, x, y, z, a, b: self.show_template2x2( x, y, z, a, b)], - 'textcolor':[0, lambda self: self.tw.canvas.textcolor], - 'textsize':[0, lambda self: self.tw.textsize], - 'titlex':[0, lambda self: self.tw.titlex], - 'titley':[0, lambda self: self.tw.titley], - 'topy':[0, lambda self: self.tw.topy], - 'tpos':[0, lambda self: self.tw.canvas.height/(self.tw.coord_scale*2)], - 'turtle':[1, lambda self, x: self.tw.canvas.set_turtle(x)], - 'userdefined':[1, lambda self, x: self.prim_myblock([x])], - 'userdefined2':[2, lambda self, x, y: self.prim_myblock([x, y])], - 'userdefined3':[3, lambda self, x, y, z: self.prim_myblock([x, y, z])], - 'video':[1, lambda self, x: self.play_movie(x)], - 'vres':[0, lambda self: self.tw.canvas.height/self.tw.coord_scale], - 'wait':[1, self.prim_wait, True], - # 'while':[2, self.prim_while, True], - 'white':[0, lambda self: WHITE], - 'write':[2, lambda self, x, y: self.write(self, x, y)], - 'xcor':[0, lambda self: self.tw.canvas.xcor/self.tw.coord_scale], - 'ycor':[0, lambda self: self.tw.canvas.ycor/self.tw.coord_scale], - 'yellow':[0, lambda self: 20]} + 'textcolor': [0, lambda self: self.tw.canvas.textcolor], + 'textsize': [0, lambda self: self.tw.textsize], + 'titlex': [0, lambda self: self.tw.titlex], + 'titley': [0, lambda self: self.tw.titley], + 'topy': [0, lambda self: self.tw.topy], + 'tpos': [0, lambda self: self.tw.canvas.height / \ + (self.tw.coord_scale * 2)], + 'turtle': [1, lambda self, x: self.tw.canvas.set_turtle(x)], + 'userdefined': [1, lambda self, x: self.prim_myblock([x])], + 'userdefined2': [2, lambda self, x, y: self.prim_myblock([x, y])], + 'userdefined3': [3, lambda self, x, y, + z: self.prim_myblock([x, y, z])], + 'video': [1, lambda self, x: self.play_movie(x)], + 'vres': [0, lambda self: self.tw.canvas.height / self.tw.coord_scale], + 'wait': [1, self.prim_wait, True], + # 'while': [2, self.prim_while, True], + 'white': [0, lambda self: WHITE], + 'write': [2, lambda self, x, y: self.write(self, x, y)], + 'xcor': [0, lambda self: self.tw.canvas.xcor / self.tw.coord_scale], + 'ycor': [0, lambda self: self.tw.canvas.ycor / self.tw.coord_scale], + 'yellow': [0, lambda self: 20]} for p in iter(DEFPRIM): if len(DEFPRIM[p]) == 2: self.defprim(p, DEFPRIM[p][0], DEFPRIM[p][1]) else: self.defprim(p, DEFPRIM[p][0], DEFPRIM[p][1], DEFPRIM[p][2]) - + self.symtype = type(self.intern('print')) self.listtype = type([]) self.symnothing = self.intern('%nothing%') @@ -419,17 +448,17 @@ class LogoCode: self.filepath = None # Scale factors for depreciated portfolio blocks - self.title_height = int((self.tw.canvas.height/20)*self.tw.scale) - self.body_height = int((self.tw.canvas.height/40)*self.tw.scale) - self.bullet_height = int((self.tw.canvas.height/30)*self.tw.scale) - + self.title_height = int((self.tw.canvas.height / 20) * self.tw.scale) + self.body_height = int((self.tw.canvas.height / 40) * self.tw.scale) + self.bullet_height = int((self.tw.canvas.height / 30) * self.tw.scale) + self.scale = DEFAULT_SCALE def defprim(self, name, args, fcn, rprim=False): """ Define the primitives associated with the blocks """ sym = self.intern(name) sym.nargs, sym.fcn = args, fcn - sym.rprim = rprim + sym.rprim = rprim def intern(self, string): """ Add any new objects to the symbol list. """ @@ -438,7 +467,7 @@ class LogoCode: sym = symbol(string) self.oblist[string] = sym return sym - + def run_blocks(self, blk, blocks, run_flag): """ Given a block to run... """ for k in self.stacks.keys(): @@ -462,7 +491,7 @@ class LogoCode: if type(convert(x, float, False)) == float: if int(float(x)) == x: x = int(x) - self.stacks['stack3'+str(x)] = self.readline(code) + self.stacks['stack3' + str(x)] = self.readline(code) code = self.blocks_to_code(blk) if run_flag: @@ -479,13 +508,13 @@ class LogoCode: return ['%nothing%', '%nothing%'] code = [] dock = blk.docks[0] - if len(dock)>4: # There could be a '(', ')', '[' or ']'. + if len(dock) > 4: # There could be a '(', ')', '[' or ']'. code.append(dock[4]) if blk.name == 'savesvg': self.tw.saving_svg = True if blk.primitive is not None: # make a tuple (prim, blk) code.append((blk.primitive, self.tw.block_list.list.index(blk))) - elif len(blk.values)>0: # Extract the value from content blocks. + elif len(blk.values) > 0: # Extract the value from content blocks. if blk.name == 'number': try: code.append(float(blk.values[0])) @@ -495,22 +524,22 @@ class LogoCode: if type(blk.values[0]) == float or type(blk.values[0]) == int: if int(blk.values[0]) == blk.values[0]: blk.values[0] = int(blk.values[0]) - code.append('#s'+str(blk.values[0])) + code.append('#s' + str(blk.values[0])) else: - code.append('#s'+blk.values[0]) + code.append('#s' + blk.values[0]) elif blk.name == 'journal': if blk.values[0] is not None: - code.append('#smedia_'+str(blk.values[0])) + code.append('#smedia_' + str(blk.values[0])) else: code.append('#smedia_None') elif blk.name == 'description': if blk.values[0] is not None: - code.append('#sdescr_'+str(blk.values[0])) + code.append('#sdescr_' + str(blk.values[0])) else: code.append('#sdescr_None') elif blk.name == 'audio': if blk.values[0] is not None: - code.append('#saudio_'+str(blk.values[0])) + code.append('#saudio_' + str(blk.values[0])) else: code.append('#saudio_None') else: @@ -519,9 +548,9 @@ class LogoCode: return ['%nothing%'] if blk.connections is not None and len(blk.connections) > 0: for i in range(1, len(blk.connections)): - b = blk.connections[i] + b = blk.connections[i] dock = blk.docks[i] - if len(dock)>4: # There could be a '(', ')', '[' or ']'. + if len(dock) > 4: # There could be a '(', ')', '[' or ']'. for c in dock[4]: code.append(c) if b is not None: @@ -529,7 +558,7 @@ class LogoCode: elif blk.docks[i][0] not in ['flow', 'unavailable']: code.append('%nothing%') return code - + def setup_cmd(self, string): """ Execute the psuedocode. """ self.hidden_turtle = self.tw.active_turtle @@ -538,12 +567,12 @@ class LogoCode: blklist = self.readline(string) self.step = self.start_eval(blklist) - """ - Convert the pseudocode into a list of commands. + def readline(self, line): + """ + Convert the pseudocode into a list of commands. The block associated with the command is stored as the second element in a tuple, e.g., (#forward, 16) - """ - def readline(self, line): + """ res = [] while line: token = line.pop(0) @@ -609,8 +638,8 @@ class LogoCode: # In debugging modes, we pause between steps and show the turtle. if self.tw.step_time > 0: self.tw.active_turtle.show() - endtime = millis()+self.an_int(self.tw.step_time)*100 - while millis()<endtime: + endtime = millis() + self.an_int(self.tw.step_time) * 100 + while millis() < endtime: yield True self.tw.active_turtle.hide() @@ -641,7 +670,7 @@ class LogoCode: if not self.tw.hide and self.tw.step_time > 0: self.tw.display_coordinates() yield True - + def eval(self): """ Evaluate the next token on the line of code we are processing. """ token = self.iline.pop(0) @@ -706,12 +735,12 @@ class LogoCode: """ ufuncall """ self.ijmp(self.evline, body) yield True - + def doevalstep(self): """ evaluate one step """ starttime = millis() try: - while (millis()-starttime)<120: + while (millis() - starttime)<120: try: if self.step is not None: self.step.next() @@ -764,7 +793,7 @@ class LogoCode: my_string += "%s: %s\n" % (k, str(v)) self.tw.showlabel('info', my_string) return - + def undefined_check(self, token): """ Make sure token has a definition """ if token.fcn is not None: @@ -774,13 +803,13 @@ class LogoCode: else: errormsg = "%s %s" % (_("I don't know how to"), _(token.name)) raise logoerror(errormsg) - + def no_args_check(self): """ Missing argument ? """ if self.iline and self.iline[0] is not self.symnothing: return raise logoerror("#noinput") - + # # Primitives # @@ -802,13 +831,13 @@ class LogoCode: def prim_wait(self, time): """ Show the turtle while we wait """ self.tw.active_turtle.show() - endtime = millis()+self.an_int(time*1000) + endtime = millis() + self.an_int(time * 1000) while millis()<endtime: yield True self.tw.active_turtle.hide() self.ireturn() yield True - + def prim_repeat(self, num, blklist): """ Repeat list num times. """ num = self.an_int(num) @@ -910,7 +939,7 @@ class LogoCode: name = self.intern(name) name.nargs, name.fcn = 0, body name.rprim = True - + def prim_stack(self, x): """ Process a named stack """ if type(convert(x, float, False)) == float: @@ -934,7 +963,7 @@ class LogoCode: self.procstop = False self.ireturn() yield True - + def prim_stack2(self): """ Process Stack 2 """ if self.stacks['stack2'] is None: @@ -948,7 +977,7 @@ class LogoCode: def prim_stopstack(self): """ Stop execution of a stack """ self.procstop = True - + def prim_print_heap(self): """ Display contents of heap """ self.tw.showlabel('status', self.heap) @@ -963,7 +992,7 @@ class LogoCode: return int(ord(n[0])) else: raise logoerror("%s %s %s %s" \ - % (self.cfun.name, _("doesn't like"), str(n), _("as input"))) + % (self.cfun.name, _("doesn't like"), str(n), _("as input"))) def box(self, x): """ Retrieve value from named box """ @@ -971,10 +1000,10 @@ class LogoCode: if int(float(x)) == x: x = int(x) try: - return self.boxes['box3'+str(x)] + return self.boxes['box3' + str(x)] except: raise logoerror("#emptybox") - + def prim_myblock(self, x): """ Run Python code imported from Journal """ if self.tw.myblock is not None: @@ -988,7 +1017,7 @@ class LogoCode: else: raise logoerror("#nocode") return - + def prim_print(self, n, flag): """ Print n """ if flag and (self.tw.hide or self.tw.step_time == 0): @@ -1011,7 +1040,7 @@ class LogoCode: else: self.tw.showlabel('status', str(round_int(n)).replace('.', self.tw.decimal_point)) - + def prim_kbinput(self): """ Query keyboard """ if len(self.tw.keypress) == 1: @@ -1021,7 +1050,7 @@ class LogoCode: self.keyboard = {'Escape': 27, 'space': 32, ' ': 32, 'Return': 13, \ 'KP_Up': 2, 'KP_Down': 4, 'KP_Left': 1, \ - 'KP_Right': 3,}[self.tw.keypress] + 'KP_Right': 3}[self.tw.keypress] except: self.keyboard = 0 self.tw.keypress = "" @@ -1034,7 +1063,7 @@ class LogoCode: if type(convert(x, float, False)) == float: if int(float(x)) == x: x = int(x) - self.boxes[name+str(x)] = val + self.boxes[name + str(x)] = val def prim_push(self, val): """ Push value onto FILO """ @@ -1045,7 +1074,7 @@ class LogoCode: try: return self.heap.pop(-1) except: - raise logoerror ("#emptyheap") + raise logoerror("#emptyheap") def empty_heap(self): """ Empty FILO """ @@ -1115,27 +1144,27 @@ class LogoCode: int(self.tw.canvas.textsize * \ self.scale / 100.), self.tw.canvas.width - x) - + def insert_image(self, media, center): """ Image only (at current x, y) """ w = int((self.tw.canvas.width * self.scale) / 100.) h = int((self.tw.canvas.height * self.scale) / 100.) # convert from Turtle coordinates to screen coordinates - x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) - y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) + x = self.tw.canvas.width / 2 + int(self.tw.canvas.xcor) + y = self.tw.canvas.height / 2 - int(self.tw.canvas.ycor) if center: x -= int(w / 2.) y -= int(h / 2.) if media[0:5] == 'media': self.show_picture(media, x, y, w, h) - + def insert_desc(self, media): """ Description text only (at current x, y) """ w = int((self.tw.canvas.width * self.scale) / 100.) h = int((self.tw.canvas.height * self.scale) / 100.) # convert from Turtle coordinates to screen coordinates - x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) - y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) + x = self.tw.canvas.width / 2 + int(self.tw.canvas.xcor) + y = self.tw.canvas.height / 2 - int(self.tw.canvas.ycor) if media[0:5] == 'descr': self.show_description(media, x, y, w, h) @@ -1181,7 +1210,7 @@ class LogoCode: media[6:], int(w), int(h)) except: self.filepath = None - self.tw.showlabel('nojournal', media[6:]) + self.tw.showlabel('nojournal', media[6:]) _logger.debug("Couldn't open Journal object %s" % \ (media[6:])) else: @@ -1195,8 +1224,9 @@ class LogoCode: media[6:], int(w), int(h)) except: self.filepath = None - self.tw.showlabel('nofile', media[6:]) - _logger.debug("Couldn't open media object %s" % (media[6:])) + self.tw.showlabel('nofile', media[6:]) + _logger.debug("Couldn't open media object %s" % \ + (media[6:])) if pixbuf is not None and show: self.tw.canvas.draw_pixbuf(pixbuf, 0, 0, int(x), int(y), int(w), int(h), @@ -1253,13 +1283,13 @@ class LogoCode: """ slide title """ self.tw.canvas.draw_text(title, int(x), int(y), self.title_height, - self.tw.canvas.width-x) + self.tw.canvas.width - x) def show_template1x1(self, title, media): """ title, one image, and description """ xo = self.tw.calc_position('t1x1')[2] - x = -(self.tw.canvas.width/2)+xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1267,28 +1297,28 @@ class LogoCode: self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks - myscale = 45 * (self.tw.canvas.height - self.title_height*2) \ + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) \ / self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render media object # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) self.tw.canvas.setxy(x, y, pendown=False) self.show(media) if self.tw.running_sugar: x = 0 self.tw.canvas.setxy(x, y, pendown=False) - self.show(media.replace("media_","descr_")) + self.show(media.replace('media_', 'descr_')) # restore text size self.tw.canvas.settextsize(save_text_size) def show_template2x1(self, title, media1, media2): """ title, two images (horizontal), two descriptions """ xo = self.tw.calc_position('t2x1')[2] - x = -(self.tw.canvas.width/2)+xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1296,14 +1326,14 @@ class LogoCode: self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks - myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) self.tw.canvas.setxy(x, y, pendown=False) self.show(media1) x = 0 @@ -1312,18 +1342,18 @@ class LogoCode: y = -self.title_height if self.tw.running_sugar: self.tw.canvas.setxy(x, y, pendown=False) - self.show(media2.replace("media_","descr_")) - x = -(self.tw.canvas.width/2) + xo + self.show(media2.replace('media_', 'descr_')) + x = -(self.tw.canvas.width / 2) + xo self.tw.canvas.setxy(x, y, pendown=False) - self.show(media1.replace("media_","descr_")) + self.show(media1.replace('media_', 'descr_')) # restore text size self.tw.canvas.settextsize(save_text_size) def show_bullets(self, sarray): """ title and varible number of bullets """ xo = self.tw.calc_position('bullet')[2] - x = -(self.tw.canvas.width/2) + xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1333,19 +1363,19 @@ class LogoCode: # set body text size self.tw.canvas.settextsize(self.bullet_height) # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) for s in sarray[1:]: self.tw.canvas.setxy(x, y, pendown=False) self.show(s) - y -= int(self.bullet_height*2*self.tw.lead) + y -= int(self.bullet_height * 2 * self.tw.lead) # restore text size self.tw.canvas.settextsize(save_text_size) - + def show_template1x2(self, title, media1, media2): """ title, two images (vertical), two desciptions """ xo = self.tw.calc_position('t1x2')[2] - x = -(self.tw.canvas.width/2) + xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1353,24 +1383,24 @@ class LogoCode: self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks - myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) self.tw.canvas.setxy(x, y, pendown=False) self.show(media1) if self.tw.running_sugar: x = 0 self.tw.canvas.setxy(x, y, pendown=False) - self.show(media1.replace("media_","descr_")) + self.show(media1.replace('media_', 'descr_')) y = -self.title_height self.tw.canvas.setxy(x, y, pendown=False) - self.show(media2.replace("media_","descr_")) - x = -(self.tw.canvas.width/2) + xo + self.show(media2.replace('media_', 'descr_')) + x = -(self.tw.canvas.width / 2) + xo self.tw.canvas.setxy(x, y, pendown=False) self.show(media2) # restore text size @@ -1379,8 +1409,8 @@ class LogoCode: def show_template2x2(self, title, media1, media2, media3, media4): """ title and four images """ xo = self.tw.calc_position('t2x2')[2] - x = -(self.tw.canvas.width/2) + xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1388,14 +1418,14 @@ class LogoCode: self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks - myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) self.tw.canvas.setxy(x, y, pendown=False) self.show(media1) x = 0 @@ -1404,7 +1434,7 @@ class LogoCode: y = -self.title_height self.tw.canvas.setxy(x, y, pendown=False) self.show(media4) - x = -(self.tw.canvas.width/2) + xo + x = -(self.tw.canvas.width / 2) + xo self.tw.canvas.setxy(x, y, pendown=False) self.show(media3) # restore text size @@ -1413,8 +1443,8 @@ class LogoCode: def show_template1x1a(self, title, media1): """ title, one media object """ xo = self.tw.calc_position('t1x1a')[2] - x = -(self.tw.canvas.width/2) + xo - y = self.tw.canvas.height/2 + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 self.tw.canvas.setxy(x, y, pendown=False) # save the text size so we can restore it later save_text_size = self.tw.canvas.textsize @@ -1422,14 +1452,14 @@ class LogoCode: self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks - myscale = 90 * (self.tw.canvas.height - self.title_height*2) /\ + myscale = 90 * (self.tw.canvas.height - self.title_height * 2) / \ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render media object # leave some space below the title - y -= int(self.title_height*2*self.tw.lead) + y -= int(self.title_height * 2 * self.tw.lead) self.tw.canvas.setxy(x, y, pendown=False) self.show(media1) # restore text size @@ -1437,7 +1467,7 @@ class LogoCode: def write(self, string, fsize): """ Write string at size """ - x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) - y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) - self.tw.canvas.draw_text(string, x, y-15, int(fsize), + x = self.tw.canvas.width / 2 + int(self.tw.canvas.xcor) + y = self.tw.canvas.height / 2 - int(self.tw.canvas.ycor) + self.tw.canvas.draw_text(string, x, y - 15, int(fsize), self.tw.canvas.width) |