Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPootle daemon <pootle@pootle.sugarlabs.org>2013-10-31 04:30:47 (GMT)
committer Pootle daemon <pootle@pootle.sugarlabs.org>2013-10-31 04:30:47 (GMT)
commit4ed97f79ceb34d615fb9406ad4e724fe75b17f8f (patch)
treeceec46869eeb06cf0ddfec1d74cd188e9c783176
parent72757585f57a2cca7a72bc195547e03f05eb43ab (diff)
parentb48fb2038fd32a95e58b603a0edad402331bf150 (diff)
Merge branch 'master' of git.sugarlabs.org:turtleart/mainline
-rw-r--r--TurtleArt/tabasics.py7
-rw-r--r--TurtleArt/taconstants.py63
-rw-r--r--TurtleArt/talogo.py66
-rw-r--r--TurtleArt/taturtle.py13
-rw-r--r--TurtleArt/tautils.py2
-rw-r--r--TurtleArt/tawindow.py132
-rw-r--r--TurtleArtActivity.py1
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py464
-rw-r--r--pysamples/brain.py3
-rw-r--r--pysamples/csound.py25
-rw-r--r--pysamples/dotted_line.py4
-rw-r--r--pysamples/forward_push.py4
-rw-r--r--pysamples/grecord.py11
-rw-r--r--pysamples/serial.py4
-rw-r--r--pysamples/sinewave.py3
-rw-r--r--pysamples/speak.py4
-rw-r--r--pysamples/uturn.py2
-rw-r--r--samples/basic-intro-1.ta239
-rwxr-xr-xturtleblocks.py3
19 files changed, 552 insertions, 498 deletions
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py
index a80b3ae..ce84a49 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -1039,11 +1039,11 @@ buttons'))
self.tw.lc.def_prim(
'nop3', 1,
Primitive(self.tw.lc.prim_define_stack,
- arg_descs=[ArgSlot(TYPE_STRING)]))
+ arg_descs=[ArgSlot(TYPE_OBJECT)]))
primitive_dictionary['stack'] = Primitive(
self.tw.lc.prim_invoke_stack,
- arg_descs=[ArgSlot(TYPE_STRING)])
+ arg_descs=[ArgSlot(TYPE_OBJECT)])
palette.add_block('stack',
style='basic-style-1arg',
label=_('action'),
@@ -1052,7 +1052,8 @@ buttons'))
logo_command='action',
default=_('action'),
help_string=_('invokes named action stack'))
- self.tw.lc.def_prim('stack', 1, primitive_dictionary['stack'], True)
+ self.tw.lc.def_prim('stack', 1,
+ primitive_dictionary['stack'], True)
palette.add_block('storeinbox1',
hidden=True,
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py
index 9666573..43ae9bc 100644
--- a/TurtleArt/taconstants.py
+++ b/TurtleArt/taconstants.py
@@ -79,6 +79,69 @@ XO4 = 'xo4'
UNKNOWN = 'unknown'
TMP_SVG_PATH = '/tmp/turtle_output.svg'
+KEY_DICT = {
+ 'Left': 1,
+ 'KP_Left': 1,
+ 'Up': 2,
+ 'KP_Up': 2,
+ 'Right': 3,
+ 'KP_Right': 3,
+ 'Down': 4,
+ 'KP_Down': 4,
+ 'BackSpace': 8,
+ 'Tab': 9,
+ 'Return': 13,
+ 'Escape': 27,
+ 'space': 32,
+ ' ': 32,
+ 'exclam': 33,
+ 'quotedbl': 34,
+ 'numbersign': 35,
+ 'dollar': 36,
+ 'percent': 37,
+ 'ampersand': 38,
+ 'apostrophe': 39,
+ 'parenleft': 40,
+ 'parenright': 41,
+ 'asterisk': 42,
+ 'plus': 43,
+ 'comma': 44,
+ 'minus': 45,
+ 'period': 46,
+ 'slash': 47,
+ 'colon': 58,
+ 'semicolon': 59,
+ 'less': 60,
+ 'equal': 61,
+ 'greater': 62,
+ 'question': 63,
+ 'at': 64,
+ 'underscore': 95,
+ 'bracketleft': 91,
+ 'backslash': 92,
+ 'bracketright': 93,
+ 'asciicircum': 94,
+ 'grave': 96,
+ 'braceleft': 123,
+ 'bar': 124,
+ 'braceright': 125,
+ 'asciitilde': 126,
+ 'Delete': 127,
+ }
+REVERSE_KEY_DICT = {
+ 1: _('left'),
+ 2: _('up'),
+ 3: _('right'),
+ 4: _('down'),
+ 8: _('backspace'),
+ 9: _('tab'),
+ # TRANS: enter is the name of the enter (or return) key
+ 13: _('enter'),
+ 27: 'esc',
+ # TRANS: space is the name of the space key
+ 32: _('space'),
+ 127: _('delete')
+ }
class Color(object):
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index b1db4ff..2b297ef 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -39,12 +39,12 @@ import traceback
from tablock import (Block, Media, media_blocks_dictionary)
from taconstants import (TAB_LAYER, DEFAULT_SCALE, ICON_SIZE)
-from tajail import myfunc
+from tajail import (myfunc, myfunc_import)
from tapalette import (block_names, value_blocks)
from tatype import (TATypeError, TYPES_NUMERIC)
from tautils import (get_pixbuf_from_journal, data_from_file, get_stack_name,
text_media_type, round_int, debug_output, find_group,
- get_path, image_to_base64, data_to_string)
+ get_path, image_to_base64, data_to_string, data_to_file)
try:
from util.RtfParser import RtfTextOnly
@@ -164,7 +164,6 @@ class LogoCode:
self.hidden_turtle = None
- self.keyboard = 0
self.trace = 0
self.update_values = False
self.gplay = None
@@ -819,10 +818,57 @@ class LogoCode:
return name
else:
# make sure '5' and '5.0' point to the same action stack
- if isinstance(name, (int, long)):
- name = float(name)
+ if isinstance(name, (int, long, float)):
+ if int(name) == name:
+ name = int(name)
+ else:
+ name = float(name)
return 'stack3' + str(name)
+ def load_heap(self, path):
+ """ Load FILO from file """
+ if self.tw.running_sugar:
+ # Choose a datastore object and push data to heap (Sugar only)
+ chooser_dialog(self.tw.parent, path, self.push_file_data_to_heap)
+ else:
+ if not os.path.exists(path):
+ path, tw.load_save_folder = get_load_name(
+ '.*', self.tw.load_save_folder)
+ if path is None:
+ return
+
+ data = data_from_file(path)
+ if data is not None:
+ for val in data:
+ self.heap.append(val)
+
+ def save_heap(self, path):
+ """ save FILO to file """
+ if self.tw.running_sugar:
+ from sugar import profile
+ from sugar.datastore import datastore
+ from sugar.activity import activity
+
+ # Save JSON-encoded heap to temporary file
+ heap_file = os.path.join(get_path(activity, 'instance'),
+ str(path) + '.txt')
+ data_to_file(self.heap, heap_file)
+
+ # Create a datastore object
+ dsobject = datastore.create()
+
+ # Write any metadata (specifically set the title of the file
+ # and specify that this is a plain text file).
+ dsobject.metadata['title'] = str(path)
+ dsobject.metadata['icon-color'] = profile.get_color().to_string()
+ dsobject.metadata['mime_type'] = 'text/plain'
+ dsobject.set_file_path(heap_file)
+ datastore.write(dsobject)
+ dsobject.destroy()
+ else:
+ heap_file = path
+ data_to_file(self.heap, heap_file)
+
def get_heap(self):
return self.heap
@@ -833,6 +879,16 @@ class LogoCode:
while self.heap:
self.heap.pop()
+ def prim_myblock(self, *args):
+ """ Run Python code imported from Journal """
+ if self.bindex is not None and self.bindex in self.tw.myblock:
+ # try:
+ myfunc_import(self, self.tw.myblock[self.bindex], args)
+ '''
+ except:
+ raise logoerror("#syntaxerror")
+ '''
+
def prim_myfunction(self, f, *args):
""" Programmable block (Call tajail.myfunc and convert any errors to
logoerrors) """
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index abea538..88f4782 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -735,6 +735,19 @@ class Turtle:
round_int(w)]]))
self._turtles.turtle_window.send_event(event)
+ def read_pixel(self):
+ """ Read r, g, b, a from the canvas and push b, g, r to the stack """
+ r, g, b, a = self.get_pixel()
+ self._turtles.turtle_window.lc.heap.append(b)
+ self._turtles.turtle_window.lc.heap.append(g)
+ self._turtles.turtle_window.lc.heap.append(r)
+
+ def get_color_index(self):
+ r, g, b, a = self.get_pixel()
+ color_index = self._turtles.turtle_window.canvas.get_color_index(
+ r, g, b)
+ return color_index
+
def get_name(self):
return self._name
diff --git a/TurtleArt/tautils.py b/TurtleArt/tautils.py
index 634ee01..ef80877 100644
--- a/TurtleArt/tautils.py
+++ b/TurtleArt/tautils.py
@@ -819,7 +819,7 @@ def get_stack_name(blk):
return 'stack2'
elif top_block.name == 'hat':
try:
- return top_block.connections[1].values[0]
+ return str(top_block.connections[1].values[0])
except (AttributeError, TypeError, IndexError):
# AttributeError: t_b has no attribute 'connections' or t_b.c[1]
# has no attribute 'value'
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 948f1f4..5d8f715 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -58,13 +58,14 @@ from taconstants import (HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE,
PYTHON_SKIN, PALETTE_HEIGHT, STATUS_LAYER, OLD_DOCK,
EXPANDABLE_ARGS, XO1, XO15, XO175, XO30, XO4, TITLEXY,
CONTENT_ARGS, CONSTANTS, EXPAND_SKIN, PROTO_LAYER,
- EXPANDABLE_FLOW, SUFFIX, TMP_SVG_PATH, Color)
+ EXPANDABLE_FLOW, SUFFIX, TMP_SVG_PATH, Color,
+ KEY_DICT)
from tapalette import (palette_names, palette_blocks, expandable_blocks,
block_names, content_blocks, default_values,
special_names, block_styles, help_strings,
hidden_proto_blocks, string_or_number_args,
make_palette, palette_name_to_index,
- palette_init_on_start)
+ palette_init_on_start, palette_i18n_names)
from talogo import (LogoCode, primitive_dictionary, logoerror)
from tacanvas import TurtleGraphics
from tablock import (Blocks, Block, Media, media_blocks_dictionary)
@@ -170,6 +171,7 @@ class TurtleArtWindow():
self._autohide_shape = True
self.keypress = ''
self.keyvalue = 0
+ self.keyboard = 0
self._focus_out_id = None
self._insert_text_id = None
self._text_to_check = False
@@ -420,7 +422,7 @@ class TurtleArtWindow():
# If setup fails, remove the plugin from the list
self.turtleart_plugins.remove(plugin)
- def _start_plugins(self):
+ def start_plugins(self):
''' Start is called everytime we execute blocks. '''
for plugin in self.turtleart_plugins:
if hasattr(plugin, 'start'):
@@ -1487,6 +1489,18 @@ class TurtleArtWindow():
self.button_press(event.get_state() & gtk.gdk.CONTROL_MASK, x, y)
return True
+ def get_mouse_flag(self):
+ return self.mouse_flag
+
+ def get_mouse_button(self):
+ return self.mouse_flag == 1
+
+ def get_mouse_x(self):
+ return int(self.mouse_x - (self.canvas.width / 2))
+
+ def get_mouse_y(self):
+ return int((self.canvas.height / 2) - self.mouse_y)
+
def button_press(self, mask, x, y):
if self.running_sugar:
self._show_unfullscreen_button()
@@ -3176,7 +3190,7 @@ before making changes to your program'))
if self.canvas.cr_svg is None:
self.canvas.setup_svg_surface()
self.running_blocks = True
- self._start_plugins() # Let the plugins know we are running.
+ self.start_plugins() # Let the plugins know we are running.
top = find_top_block(blk)
code = self.lc.generate_code(top, self.just_blocks())
self.lc.run_blocks(code)
@@ -3603,6 +3617,19 @@ before making changes to your program'))
return True
+ def get_keyboard_input(self):
+ """ Query keyboard and update cached keyboard input """
+ if len(self.keypress) == 1:
+ self.keyboard = ord(self.keypress[0])
+ elif self.keypress in KEY_DICT:
+ self.keyboard = KEY_DICT[self.keypress]
+ else:
+ self.keyboard = 0
+
+ def get_keyboard(self):
+ """ Return cached keyboard input """
+ return self.keyboard
+
def _process_keyboard_commands(self, keyname, block_flag=True):
''' Use the keyboard to move blocks and turtle '''
mov_dict = {'KP_Up': [0, 20], 'j': [0, 20], 'Up': [0, 20],
@@ -4803,3 +4830,100 @@ variable'))
(b1x, b1y) = block1.spr.get_xy()
(b2x, b2y) = block2.spr.get_xy()
return ((b1x + d1x) - (b2x + d2x), (b1y + d1y) - (b2y + d2y))
+
+ def prim_load_block(self, *args):
+ ''' Load a block on to the canvas '''
+ # Place the block at the active turtle (x, y) and move the turtle
+ # into position to place the next block in the stack.
+ # TODO: Add expandable argument, media block arguments
+ name = args[0]
+ pos = self.turtles.get_active_turtle().get_xy()
+ values = []
+ for i in range(len(args) - 1):
+ values.append(args[i + 1])
+ if len(values) > 0:
+ dy = int(self._find_block(name, pos[0], pos[1], values))
+ else:
+ if name == 'delete':
+ for blk in self.just_blocks():
+ if blk.status == 'load block':
+ blk.type = 'trash'
+ blk.spr.hide()
+ dy = 0
+ else:
+ dy = int(self._find_block(name, pos[0], pos[1]))
+
+ # Reposition turtle to end of flow
+ pos = self.turtles.get_active_turtle().get_xy()
+ pos[1] -= dy
+ self.turtles.get_active_turtle().move_turtle(pos)
+
+ def _make_block(self, name, x, y, defaults):
+ if defaults is None:
+ self._new_block(name, x, y, defaults)
+ else:
+ for i, v in enumerate(defaults):
+ if isinstance(v, float) and int(v) == v:
+ defaults[i] = int(v)
+ self._new_block(name, x, y, defaults)
+
+ # Find the block we just created and attach it to a stack.
+ self.drag_group = None
+ spr = self.sprite_list.find_sprite((x, y))
+ if spr is not None:
+ blk = self.block_list.spr_to_block(spr)
+ if blk is not None:
+ self.drag_group = find_group(blk)
+ for b in self.drag_group:
+ b.status = 'load block'
+ self._snap_to_dock()
+
+ # Disassociate new block from mouse.
+ self.drag_group = None
+ return blk.docks[-1][3]
+
+ def _find_block(self, blkname, x, y, defaults=None):
+ """ Create a new block. It is a bit more work than just calling
+ _new_block(). We need to:
+ (1) translate the label name into the internal block name;
+ (2) 'dock' the block onto a stack where appropriate; and
+ (3) disassociate the new block from the mouse. """
+ x, y = self.turtles.turtle_to_screen_coordinates((x, y))
+ for name in block_names:
+ # Translate label name into block/prim name.
+ if blkname in block_names[name]: # block label is an array
+ # print 'found a match', blkname, name, block_names[name]
+ if name in content_blocks or \
+ (name in block_primitives and
+ block_primitives[name] == name):
+ # print '_make_block', blkname, name
+ return self._make_block(name, x, y, defaults)
+ elif blkname in block_names:
+ # print '_make_block', blkname
+ return self._make_block(blkname, x, y, defaults)
+ for name in special_names:
+ # Translate label name into block/prim name.
+ if blkname in special_names[name]:
+ return self._make_block(name, x, y, defaults)
+ # Check for a macro
+ if blkname in MACROS:
+ self.new_macro(blkname, x, y)
+ return 0 # Fix me: calculate flow position
+ # Block not found
+ raise logoerror("#syntaxerror")
+ return -1
+
+ def prim_load_palette(self, arg):
+ ''' Select a palette '''
+ if type(arg) in [int, float]:
+ if int(arg) < 0 or int(arg) > len(palette_names):
+ raise logoerror("#syntaxerror")
+ else:
+ self.show_toolbar_palette(int(arg))
+ else:
+ if type(arg) == unicode:
+ arg = arg.encode('utf-8')
+ if arg in palette_names or arg in palette_i18n_names:
+ self.show_toolbar_palette(palette_name_to_index(arg))
+ else:
+ raise logoerror("#syntaxerror")
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py
index c2980bb..c413358 100644
--- a/TurtleArtActivity.py
+++ b/TurtleArtActivity.py
@@ -227,6 +227,7 @@ class TurtleArtActivity(activity.Activity):
if pyee.block is not None:
pyee.block.highlight()
self.tw.showlabel('status', str(pyee))
+ _logger.debug(pyee)
return
if not pythoncode:
return
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index c5357c4..9136a83 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -27,17 +27,16 @@ from plugins.plugin import Plugin
from TurtleArt.tapalette import (make_palette, define_logo_function,
block_names, block_primitives, special_names,
content_blocks, palette_name_to_index,
- palette_names, palette_i18n_names)
+ palette_names)
from TurtleArt.talogo import (primitive_dictionary, logoerror,
media_blocks_dictionary)
from TurtleArt.taconstants import (DEFAULT_SCALE, CONSTANTS,
MEDIA_SHAPES, SKIN_PATHS, BLOCKS_WITH_SKIN,
PYTHON_SKIN, MEDIA_BLOCK2TYPE, VOICES,
- MACROS, Color)
+ MACROS, Color, KEY_DICT, REVERSE_KEY_DICT)
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_import
from TurtleArt.taprimitive import (ArgSlot, ConstantArg, Primitive)
from TurtleArt.tatype import (TYPE_BOOL, TYPE_BOX, TYPE_CHAR, TYPE_INT,
TYPE_FLOAT, TYPE_OBJECT, TYPE_STRING,
@@ -45,22 +44,6 @@ from TurtleArt.tatype import (TYPE_BOOL, TYPE_BOX, TYPE_CHAR, TYPE_INT,
from TurtleArt.taturtle import Turtle
-def _num_type(x):
- """ Is x a number type? """
- if type(x) == int:
- return True
- if type(x) == float:
- return True
- if type(x) == ord:
- return True
- return False
-
-
-def _millisecond():
- """ Current time in milliseconds """
- return time() * 1000
-
-
class Turtle_blocks_extras(Plugin):
""" a class for defining the extra palettes that distinguish Turtle Blocks
from Turtle Art """
@@ -72,7 +55,6 @@ class Turtle_blocks_extras(Plugin):
SKIN_PATHS.append('plugins/turtle_blocks_extras/images')
self.heap = self.tw.lc.heap
- self.keyboard = self.tw.lc.keyboard
self.title_height = int((self.tw.canvas.height / 20) * self.tw.scale)
# set up Turtle Block palettes
@@ -251,7 +233,8 @@ Journal'))
self.tw.lc.def_prim('setscale', 1,
Primitive(self.tw.lc.set_scale,
arg_descs=[ArgSlot(TYPE_NUMBER)],
- call_afterwards=self.after_set_scale))
+ call_afterwards=lambda value: self.after_set(
+ 'scale', value)))
primitive_dictionary['savepix'] = self._prim_save_picture
palette.add_block('savepix',
@@ -347,7 +330,6 @@ amplitude, and duration (in seconds)'))
help_string=_('Palette of sensor blocks'),
position=6)
- primitive_dictionary['mousebutton'] = self._prim_mouse_button
palette.add_block('mousebutton',
hidden=True,
style='box-style',
@@ -357,9 +339,9 @@ amplitude, and duration (in seconds)'))
help_string=_('returns 1 if mouse button is \
pressed'))
self.tw.lc.def_prim('mousebutton', 0,
- lambda self: primitive_dictionary['mousebutton']())
+ Primitive(self.tw.get_mouse_flag,
+ return_type=TYPE_NUMBER))
- primitive_dictionary['mousebutton2'] = self._prim_mouse_button_bool
palette.add_block('mousebutton2',
style='boolean-block-style',
label=_('button down'),
@@ -368,10 +350,9 @@ pressed'))
help_string=_('returns True if mouse button is \
pressed'))
self.tw.lc.def_prim('mousebutton2', 0,
- lambda self:
- primitive_dictionary['mousebutton2']())
+ Primitive(self.tw.get_mouse_button,
+ return_type=TYPE_BOOL))
- primitive_dictionary['mousex'] = self._prim_mouse_x
palette.add_block('mousex',
style='box-style',
label=_('mouse x'),
@@ -379,10 +360,10 @@ pressed'))
value_block=True,
help_string=_('returns mouse x coordinate'))
self.tw.lc.def_prim('mousex', 0,
- lambda self:
- primitive_dictionary['mousex']())
+ Primitive(self.tw.get_mouse_x,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_mouse_x))
- primitive_dictionary['mousey'] = self._prim_mouse_y
palette.add_block('mousey',
style='box-style',
label=_('mouse y'),
@@ -390,10 +371,10 @@ pressed'))
value_block=True,
help_string=_('returns mouse y coordinate'))
self.tw.lc.def_prim('mousey', 0,
- lambda self:
- primitive_dictionary['mousey']())
+ Primitive(self.tw.get_mouse_y,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_mouse_y))
- primitive_dictionary['kbinput'] = self._prim_kbinput
palette.add_block('kbinput',
style='basic-style-extended-vertical',
label=_('query keyboard'),
@@ -401,9 +382,9 @@ pressed'))
help_string=_('query for keyboard input (results \
stored in keyboard block)'))
self.tw.lc.def_prim('kbinput', 0,
- lambda self: primitive_dictionary['kbinput']())
+ Primitive(self.tw.get_keyboard_input,
+ call_afterwards=self.after_keypress))
- primitive_dictionary['keyboard'] = self._prim_keyboard
palette.add_block('keyboard',
style='box-style',
label=_('keyboard'),
@@ -413,9 +394,9 @@ stored in keyboard block)'))
help_string=_('holds results of query-keyboard \
block as ASCII'))
self.tw.lc.def_prim('keyboard', 0,
- lambda self: primitive_dictionary['keyboard']())
+ Primitive(self.tw.get_keyboard,
+ return_type=TYPE_NUMBER))
- primitive_dictionary['readpixel'] = self._prim_readpixel
palette.add_block('readpixel',
style='basic-style-extended-vertical',
label=_('read pixel'),
@@ -424,9 +405,8 @@ block as ASCII'))
help_string=_('RGB color under the turtle is pushed \
to the stack'))
self.tw.lc.def_prim('readpixel', 0,
- lambda self: primitive_dictionary['readpixel']())
+ Primitive(Turtle.read_pixel))
- primitive_dictionary['see'] = self._prim_see
palette.add_block('see',
style='box-style',
label=_('turtle sees'),
@@ -435,7 +415,9 @@ to the stack'))
help_string=_('returns the color that the turtle \
"sees"'))
self.tw.lc.def_prim('see', 0,
- lambda self: primitive_dictionary['see']())
+ Primitive(Turtle.get_color_index,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_see))
palette.add_block('time',
style='box-style',
@@ -543,7 +525,6 @@ make "tmp first :taheap\nmake "taheap butfirst :taheap\noutput :tmp\nend\n')
Primitive(self.tw.lc.get_heap,
return_type=TYPE_BOOL))]))]))
- primitive_dictionary['saveheap'] = self._prim_save_heap
palette.add_block('saveheap',
style='basic-style-1arg',
label=_('save heap to file'),
@@ -552,9 +533,9 @@ make "tmp first :taheap\nmake "taheap butfirst :taheap\noutput :tmp\nend\n')
help_string=_('saves FILO (first-in \
last-out heap) to a file'))
self.tw.lc.def_prim('saveheap', 1,
- lambda self, x: primitive_dictionary['saveheap'](x))
+ Primitive(self.tw.lc.save_heap,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
- primitive_dictionary['loadheap'] = self._prim_load_heap
palette.add_block('loadheap',
style='basic-style-1arg',
label=_('load heap from file'),
@@ -563,7 +544,10 @@ last-out heap) to a file'))
help_string=_('loads FILO (first-in \
last-out heap) from a file'))
self.tw.lc.def_prim('loadheap', 1,
- lambda self, x: primitive_dictionary['loadheap'](x))
+ Primitive(self.tw.lc.load_heap,
+ arg_descs=[ArgSlot(TYPE_STRING)],
+ return_type=TYPE_STRING,
+ call_afterwards=self.after_push))
palette.add_block('isheapempty2',
style='boolean-block-style',
@@ -687,7 +671,6 @@ advanced multi-variable math equations, e.g., sin(x+y+z)'))
self.tw.lc.def_prim('cartesian', 0,
lambda self: self.tw.set_cartesian(True))
- primitive_dictionary['userdefined'] = self._prim_myblock
palette.add_block('userdefined',
style='basic-style-var-arg',
label=' ',
@@ -698,8 +681,8 @@ advanced multi-variable math equations, e.g., sin(x+y+z)'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined', 1,
- lambda self, x:
- primitive_dictionary['userdefined']([x]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined')
PYTHON_SKIN.append('userdefined')
@@ -715,8 +698,9 @@ module found in the Journal'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined2', 2,
- lambda self, x, y:
- primitive_dictionary['userdefined']([x, y]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined2args')
PYTHON_SKIN.append('userdefined2args')
@@ -732,15 +716,16 @@ module found in the Journal'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined3', 3,
- lambda self, x, y, z:
- primitive_dictionary['userdefined']([x, y, z]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined3args')
PYTHON_SKIN.append('userdefined3args')
MEDIA_SHAPES.append('pythonsmall')
MEDIA_SHAPES.append('pythonoff')
MEDIA_SHAPES.append('pythonon')
- primitive_dictionary['loadblock'] = self._prim_load_block
palette.add_block('loadblock',
style='basic-style-var-arg',
label=_('load'),
@@ -748,8 +733,8 @@ module found in the Journal'))
default=_('forward'),
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock', 1,
- lambda self, x:
- primitive_dictionary['loadblock'](x))
+ Primitive(self.tw.prim_load_block,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
palette.add_block('loadblock2arg',
style='basic-style-var-arg',
@@ -760,8 +745,9 @@ module found in the Journal'))
default=[_('forward'), 100],
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock2', 2,
- lambda self, x, y:
- primitive_dictionary['loadblock']([x, y]))
+ Primitive(self.tw.prim_load_block,
+ arg_descs=[ArgSlot(TYPE_STRING),
+ ArgSlot(TYPE_OBJECT)]))
palette.add_block('loadblock3arg',
style='basic-style-var-arg',
@@ -772,10 +758,11 @@ module found in the Journal'))
default=[_('setxy'), 0, 0],
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock3', 3,
- lambda self, x, y, z:
- primitive_dictionary['loadblock']([x, y, z]))
+ Primitive(self.tw.prim_load_block,
+ arg_descs=[ArgSlot(TYPE_STRING),
+ ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
- primitive_dictionary['loadpalette'] = self._prim_load_palette
palette.add_block('loadpalette',
style='basic-style-1arg',
string_or_number=True,
@@ -784,8 +771,8 @@ module found in the Journal'))
default=_('turtle'),
help_string=_('selects a palette'))
self.tw.lc.def_prim('loadpalette', 1,
- lambda self, x:
- primitive_dictionary['loadpalette'](x))
+ Primitive(self.tw.prim_load_palette,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
palette.add_block('addturtle',
style='basic-style-1arg',
@@ -1126,93 +1113,19 @@ Journal objects'))
# Block primitives
- def _prim_keyboard(self):
- """ Return last character typed """
- return self.tw.lc.keyboard
-
- def _prim_kbinput(self):
- """ Query keyboard """
- DICT = {
- 'Left': 1,
- 'KP_Left': 1,
- 'Up': 2,
- 'KP_Up': 2,
- 'Right': 3,
- 'KP_Right': 3,
- 'Down': 4,
- 'KP_Down': 4,
- 'BackSpace': 8,
- 'Tab': 9,
- 'Return': 13,
- 'Escape': 27,
- 'space': 32,
- ' ': 32,
- 'exclam': 33,
- 'quotedbl': 34,
- 'numbersign': 35,
- 'dollar': 36,
- 'percent': 37,
- 'ampersand': 38,
- 'apostrophe': 39,
- 'parenleft': 40,
- 'parenright': 41,
- 'asterisk': 42,
- 'plus': 43,
- 'comma': 44,
- 'minus': 45,
- 'period': 46,
- 'slash': 47,
- 'colon': 58,
- 'semicolon': 59,
- 'less': 60,
- 'equal': 61,
- 'greater': 62,
- 'question': 63,
- 'at': 64,
- 'underscore': 95,
- 'bracketleft': 91,
- 'backslash': 92,
- 'bracketright': 93,
- 'asciicircum': 94,
- 'grave': 96,
- 'braceleft': 123,
- 'bar': 124,
- 'braceright': 125,
- 'asciitilde': 126,
- 'Delete': 127,
- }
- REVERSE_DICT = {
- 1: _('left'),
- 2: _('up'),
- 3: _('right'),
- 4: _('down'),
- 8: _('backspace'),
- 9: _('tab'),
- # TRANS: enter is the name of the enter (or return) key
- 13: _('enter'),
- 27: 'esc',
- # TRANS: space is the name of the space key
- 32: _('space'),
- 127: _('delete')
- }
-
- if len(self.tw.keypress) == 1:
- self.tw.lc.keyboard = ord(self.tw.keypress[0])
- elif self.tw.keypress in DICT:
- self.tw.lc.keyboard = DICT[self.tw.keypress]
- else:
- self.tw.lc.keyboard = 0
+ def after_keypress(self):
if self.tw.lc.update_values:
- if self.tw.keypress in DICT:
- if DICT[self.tw.keypress] in REVERSE_DICT:
+ if self.tw.keypress in KEY_DICT:
+ if KEY_DICT[self.tw.keypress] in REVERSE_KEY_DICT:
self.tw.lc.update_label_value(
- 'keyboard', REVERSE_DICT[DICT[self.tw.keypress]])
+ 'keyboard', REVERSE_KEY_DICT[
+ KEY_DICT[self.tw.keypress]])
else:
- self.tw.lc.update_label_value('keyboard',
- chr(DICT[self.tw.keypress]))
- elif self.tw.lc.keyboard > 0:
+ self.tw.lc.update_label_value(
+ 'keyboard', chr(KEY_DICT[self.tw.keypress]))
+ elif self.tw.keyboard > 0:
self.tw.lc.update_label_value('keyboard',
- chr(self.tw.lc.keyboard))
+ chr(self.tw.keyboard))
self.tw.keypress = ''
def _prim_list(self, blklist):
@@ -1221,121 +1134,19 @@ Journal objects'))
self.tw.lc.ireturn()
yield True
- def _prim_myblock(self, x):
- """ Run Python code imported from Journal """
- if self.tw.lc.bindex is not None and \
- self.tw.lc.bindex in self.tw.myblock:
- try:
- if len(x) == 1:
- myfunc_import(self, self.tw.myblock[self.tw.lc.bindex],
- x[0])
- else:
- myfunc_import(self, self.tw.myblock[self.tw.lc.bindex], x)
- except:
- raise logoerror("#syntaxerror")
-
- def _prim_myfunction(self, f, x):
- """ Programmable block """
- for i, v in enumerate(x):
- if isinstance(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 after_pop(self):
+ def after_pop(self, *ignored_args):
if self.tw.lc.update_values:
if not self.tw.lc.heap:
self.tw.lc.update_label_value('pop')
else:
self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
- def after_push(self, val):
+ def after_push(self, *ignored_args):
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('pop', val)
-
- def _prim_load_heap(self, path):
- """ Load FILO from file """
- if type(path) == float:
- path = ''
- if self.tw.running_sugar:
- # Choose a datastore object and push data to heap (Sugar only)
- chooser_dialog(self.tw.parent, path,
- self.tw.lc.push_file_data_to_heap)
- else:
- if not os.path.exists(path):
- path, tw.load_save_folder = get_load_name(
- '.*', self.tw.load_save_folder)
- if path is None:
- return
-
- data = data_from_file(path)
- if data is not None:
- for val in data:
- self.tw.lc.heap.append(val)
-
- if len(self.tw.lc.heap) > 0:
- self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
-
- def _prim_save_heap(self, path):
- """ save FILO to file """
- # TODO: add GNOME save
-
- if self.tw.running_sugar:
- from sugar import profile
- from sugar.datastore import datastore
- from sugar.activity import activity
-
- # Save JSON-encoded heap to temporary file
- heap_file = os.path.join(get_path(activity, 'instance'),
- str(path) + '.txt')
- data_to_file(self.tw.lc.heap, heap_file)
-
- # Create a datastore object
- dsobject = datastore.create()
-
- # Write any metadata (specifically set the title of the file
- # and specify that this is a plain text file).
- dsobject.metadata['title'] = str(path)
- dsobject.metadata['icon-color'] = profile.get_color().to_string()
- dsobject.metadata['mime_type'] = 'text/plain'
- dsobject.set_file_path(heap_file)
- datastore.write(dsobject)
- dsobject.destroy()
- else:
- heap_file = path
- data_to_file(self.tw.lc.heap, heap_file)
-
- def _prim_readpixel(self):
- """ Read r, g, b, a from the canvas and push b, g, r to the stack """
- r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
- self.tw.lc.heap.append(b)
- self.tw.lc.heap.append(g)
- self.tw.lc.heap.append(r)
+ if not self.tw.lc.heap:
+ self.tw.lc.update_label_value('pop')
+ else:
+ self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
def _prim_save_picture(self, name):
""" Save canvas to file as PNG """
@@ -1439,46 +1250,22 @@ Journal objects'))
csd.write("\n</CsoundSynthesizer>")
csd.close()
- def _prim_mouse_x(self):
- """ Return mouse x coordinate """
- mousex = int(self.tw.mouse_x - (self.tw.canvas.width / 2))
- if self.tw.lc.update_values:
- self.tw.lc.update_label_value('mousex', mousex)
- return mousex
-
- def _prim_mouse_y(self):
- """ Return mouse y coordinate """
- mousey = int((self.tw.canvas.height / 2) - self.tw.mouse_y)
+ def after_mouse_x(self):
+ """ Show mouse x coordinate """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('mousey', mousey)
- return mousey
-
- def _prim_mouse_button(self):
- """ Return 1 if mouse button is pressed """
- if self.tw.mouse_flag == 1:
- return 1
- else:
- return 0
+ self.tw.lc.update_label_value('mousex', self.tw.get_mouse_x())
- def _prim_mouse_button_bool(self):
- """ Return True if mouse button is pressed """
- if self.tw.mouse_flag == 1:
- return True
- else:
- return False
-
- def _prim_see(self):
- """ Read r, g, b from the canvas and return a corresponding palette
- color """
- r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
- color_index = self.tw.canvas.get_color_index(r, g, b)
+ def after_mouse_y(self):
+ """ Show mouse y coordinate """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('see', color_index)
- return color_index
+ self.tw.lc.update_label_value('mousey', self.tw.get_mouse_y())
- def after_set_scale(self, val):
+ def after_see(self):
+ """ Show color under turtle """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('scale', scale)
+ self.tw.lc.update_label_value(
+ 'see',
+ self.tw.turtles.get_active_turtle().get_color_index())
def _prim_show(self, string, center=False):
""" Show is the general-purpose media-rendering block. """
@@ -1587,101 +1374,8 @@ Journal objects'))
self.tw.activity.stop_turtle_button.set_icon("stopiton")
self.tw.activity.stop_turtle_button.set_tooltip(_('Stop turtle'))
- def _prim_load_block(self, blkname):
- ''' Load a block on to the canvas '''
- # Place the block at the active turtle (x, y) and move the turtle
- # into position to place the next block in the stack.
- # TODO: Add expandable argument
- pos = self.tw.turtles.get_active_turtle().get_xy()
- if isinstance(blkname, list):
- name = blkname[0]
- if len(blkname) > 1:
- value = blkname[1:]
- dy = int(self._find_block(name, pos[0], pos[1], value))
- else:
- dy = int(self._find_block(name, pos[0], pos[1]))
- else:
- name = blkname
- if name == 'delete':
- for blk in self.tw.just_blocks():
- if blk.status == 'load block':
- blk.type = 'trash'
- blk.spr.hide()
- dy = 0
- else:
- dy = int(self._find_block(name, pos[0], pos[1]))
-
- # Reposition turtle to end of flow
- pos = self.tw.turtles.get_active_turtle().get_xy()
- pos[1] -= dy
- self.tw.turtles.get_active_turtle().move_turtle(pos)
-
- def _make_block(self, name, x, y, defaults):
- if defaults is None:
- self.tw._new_block(name, x, y, defaults)
- else:
- for i, v in enumerate(defaults):
- if type(v) == float and int(v) == v:
- defaults[i] = int(v)
- self.tw._new_block(name, x, y, defaults)
-
- # Find the block we just created and attach it to a stack.
- self.tw.drag_group = None
- spr = self.tw.sprite_list.find_sprite((x, y))
- if spr is not None:
- blk = self.tw.block_list.spr_to_block(spr)
- if blk is not None:
- self.tw.drag_group = find_group(blk)
- for b in self.tw.drag_group:
- b.status = 'load block'
- self.tw._snap_to_dock()
-
- # Disassociate new block from mouse.
- self.tw.drag_group = None
- return blk.docks[-1][3]
-
- def _find_block(self, blkname, x, y, defaults=None):
- """ Create a new block. It is a bit more work than just calling
- _new_block(). We need to:
- (1) translate the label name into the internal block name;
- (2) 'dock' the block onto a stack where appropriate; and
- (3) disassociate the new block from the mouse. """
- x, y = self.tw.turtles.turtle_to_screen_coordinates((x, y))
- for name in block_names:
- # Translate label name into block/prim name.
- if blkname in block_names[name]: # block label is an array
- # print 'found a match', blkname, name, block_names[name]
- if name in content_blocks or \
- (name in block_primitives and
- block_primitives[name] == name):
- # print '_make_block', blkname, name
- return self._make_block(name, x, y, defaults)
- elif blkname in block_names:
- # print '_make_block', blkname
- return self._make_block(blkname, x, y, defaults)
- for name in special_names:
- # Translate label name into block/prim name.
- if blkname in special_names[name]:
- return self._make_block(name, x, y, defaults)
- # Check for a macro
- if blkname in MACROS:
- self.tw.new_macro(blkname, x, y)
- return 0 # Fix me: calculate flow position
- # Block not found
- raise logoerror("#syntaxerror")
- return -1
-
- def _prim_load_palette(self, arg):
- ''' Select a palette '''
- if type(arg) in [int, float]:
- if int(arg) < 0 or int(arg) > len(palette_names):
- raise logoerror("#syntaxerror")
- else:
- self.tw.show_toolbar_palette(int(arg))
- else:
- if type(arg) == unicode:
- arg = arg.encode('utf-8')
- if arg in palette_names or arg in palette_i18n_names:
- self.tw.show_toolbar_palette(palette_name_to_index(arg))
- else:
- raise logoerror("#syntaxerror")
+ def after_set(self, name, value=None):
+ ''' Update the associated value blocks '''
+ if value is not None:
+ if self.tw.lc.update_values:
+ self.tw.lc.update_label_value(name, value)
diff --git a/pysamples/brain.py b/pysamples/brain.py
index 33ee320..3510e03 100644
--- a/pysamples/brain.py
+++ b/pysamples/brain.py
@@ -21,7 +21,7 @@
# <http://www.gnu.org/licenses/>.
-def myblock(tw, text):
+def myblock(tw, args):
''' Dialog with AIML library: Usage: Load this code into a Python
Block. Pass text as an argument and the robot's response will
be pushed to the stack. Use a Pop Block to pop the response
@@ -104,6 +104,7 @@ Close other activities and try once more.'))
return kernel
+ text = args[0]
if not hasattr(tw, 'aiml_kernel'):
tw.aiml_kernel = brain_load(tw, get_default_voice())
response_text = brain_respond(tw.aiml_kernel, text)
diff --git a/pysamples/csound.py b/pysamples/csound.py
index a935674..ec1b014 100644
--- a/pysamples/csound.py
+++ b/pysamples/csound.py
@@ -17,16 +17,24 @@ def myblock(tw, sound):
import os
dirs = [os.path.join(
- os.environ['HOME'],
- 'Activities/TamTamMini.activity/common/Resources/Sounds/')]
+ os.environ['HOME'],
+ 'Activities/TamTamMini.activity/common/Resources/Sounds/'),
+ os.path.join(
+ os.environ['HOME'],
+ 'Activities/TamTamJam.activity/common/Resources/Sounds/'),
+ os.path.join(
+ os.environ['HOME'],
+ 'Activities/TamTamEdit.activity/common/Resources/Sounds/')]
orchlines = []
scorelines = []
instrlist = []
def finddir():
+ print dirs
for d in dirs:
if os.path.isdir(d):
return d
+ return '.'
def playSine(pitch=1000, amplitude=5000, duration=1, starttime=0,
pitch_envelope='default', amplitude_envelope='default'):
@@ -128,18 +136,17 @@ def myblock(tw, sound):
csd.write("\n</CsoundSynthesizer>")
csd.close()
- if type(sound) == float:
- playSine(pitch=float(sound))
- elif type(sound) == list: # Create a score by computing a sinewave.
- if len(sound) == 1:
+ if len(sound) == 1:
+ if isinstance(sound[0], float) or isinstance(sound[0], int):
playSine(pitch=float(sound[0]))
- elif len(sound) == 2:
+ else: # Create a score from a prerecorded Wave file.
+ playWave(sound[0])
+ else:
+ if len(sound) == 2:
playSine(pitch=float(sound[0]), amplitude=float(sound[1]))
else:
playSine(pitch=float(sound[0]), amplitude=float(sound[1]),
duration=float(sound[2]))
- else: # Create a score from a prerecorded Wave file.
- playWave(sound)
if tw.running_sugar:
path = os.path.join(get_path(tw.activity, 'instance'), 'tmp.csd')
else:
diff --git a/pysamples/dotted_line.py b/pysamples/dotted_line.py
index c0d3008..098e0a4 100644
--- a/pysamples/dotted_line.py
+++ b/pysamples/dotted_line.py
@@ -124,11 +124,11 @@
# of the numeric argument block docked to the Python block.
-def myblock(tw, line_length):
+def myblock(tw, args):
''' Draw a dotted line of length line_length. '''
try: # make sure line_length is a number
- line_length = float(line_length)
+ line_length = float(args[0])
except ValueError:
return
if tw.turtles.get_active_turtle().get_pen_state():
diff --git a/pysamples/forward_push.py b/pysamples/forward_push.py
index ca527db..80fe818 100644
--- a/pysamples/forward_push.py
+++ b/pysamples/forward_push.py
@@ -10,7 +10,7 @@
# destination to the FILO.
-def myblock(tw, name):
+def myblock(tw, args):
''' '''
def _prim_forward_push(tw, line_length):
@@ -42,7 +42,7 @@ def myblock(tw, name):
# Create a new block prototype.
palette.add_block('forwardpush',
style='basic-style-1arg',
- label=name,
+ label=args[0],
default=100,
prim_name='forwardpush',
help_string=_('push destination rgb value to heap'))
diff --git a/pysamples/grecord.py b/pysamples/grecord.py
index a28b82c..486fdb7 100644
--- a/pysamples/grecord.py
+++ b/pysamples/grecord.py
@@ -10,7 +10,7 @@
# Sugar Journal.
-def myblock(tw, arg):
+def myblock(tw, args):
''' Record and playback a sound (Sugar only) '''
import os
import gst
@@ -204,12 +204,9 @@ def myblock(tw, arg):
# Sometime we need to parse multiple arguments, e.g., save, savename
save_name = '%s_%s' % (tw.activity.name, _('sound'))
- if isinstance(arg, list):
- cmd = arg[0].lower()
- if len(arg) > 1:
- save_name = str(arg[1])
- else:
- cmd = arg.lower()
+ cmd = args[0].lower()
+ if len(args) > 1:
+ save_name = str(arg[1])
if cmd == 'start' or cmd == _('start').lower():
tw.grecord.start_recording_audio()
diff --git a/pysamples/serial.py b/pysamples/serial.py
index 84772ab..d15011c 100644
--- a/pysamples/serial.py
+++ b/pysamples/serial.py
@@ -9,13 +9,13 @@
# (3) use a Pop Block to retrieve any strings input from serial device.
-def myblock(tw, x): # x is the string to transmit
+def myblock(tw, args): # x is the string to transmit
import serial # you may need to install this library
# serial device on USB, 9600 baud
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
- ser.write(str(x)) # send string x
+ ser.write(str(args[0])) # send string x
st = ser.read(1000) # read up to 1000 bytes
tw.lc.heap.append(st) # append to heap
ser.close()
diff --git a/pysamples/sinewave.py b/pysamples/sinewave.py
index 4f14c4c..a060f34 100644
--- a/pysamples/sinewave.py
+++ b/pysamples/sinewave.py
@@ -8,8 +8,9 @@
# the speaker at the specified frequency.
-def myblock(tw, frequency):
+def myblock(tw, args):
''' Plays a sound at frequency frequency '''
import os
+ frequency = args[0]
os.system('speaker-test -t sine -l 1 -f %d' % (int(frequency)))
diff --git a/pysamples/speak.py b/pysamples/speak.py
index 30762a9..13215e8 100644
--- a/pysamples/speak.py
+++ b/pysamples/speak.py
@@ -28,7 +28,7 @@ def myblock(tw, arg):
import os
pitch = None
- if type(arg) == type([]):
+ if len(arg) > 1:
text = arg[0]
if len(arg) > 1:
pitch = int(arg[1])
@@ -37,7 +37,7 @@ def myblock(tw, arg):
elif pitch < 0:
pitch = 0
else:
- text = arg
+ text = arg[0]
# Turtle Art numbers are passed as float,
# but they may be integer values.
diff --git a/pysamples/uturn.py b/pysamples/uturn.py
index edd2bcd..f6ff2e0 100644
--- a/pysamples/uturn.py
+++ b/pysamples/uturn.py
@@ -8,7 +8,7 @@
# can use the u-turn block as you would any other block.
-def myblock(tw, arg):
+def myblock(tw, args):
''' Add a uturn block to the 'turtle' palette '''
# def_prim takes 3 arguments: the primitive name, the number of
diff --git a/samples/basic-intro-1.ta b/samples/basic-intro-1.ta
index 17cff6a..c6d34c8 100644
--- a/samples/basic-intro-1.ta
+++ b/samples/basic-intro-1.ta
@@ -1,72 +1,167 @@
-[[0, ["start", 2.0], 788, 178, [null, 67]],
-[1, "forward", 437, 523, [6, 2, 3]],
-[2, ["number", 100], 508, 523, [1, null]],
-[3, "right", 437, 565, [1, 5, null]],
-[4, ["number", 360], 565, 565, [5, null]],
-[5, ["division2", 0], 495, 565, [3, 4, 58]],
-[6, ["repeat", 21], 419, 481, [26, 56, 1, null]],
-[7, ["repeat", 168], 29, 324, [39, 8, 16, null]],
-[8, ["number", 10], 88, 324, [7, null]],
-[9, "startfill", 47, 450, [11, 28]],
-[10, "stopfill", 47, 534, [28, 17]],
-[11, "setgray", 47, 408, [16, 13, 9]],
-[12, ["number", 300], 190, 408, [13, null]],
-[13, ["division2", 0], 120, 408, [11, 12, 48]],
-[14, ["number", 1], 212, 744, [15, null]],
-[15, ["minus2", 0], 115, 702, [46, 50, 14]],
-[16, "setcolor", 47, 366, [7, 66, 11]],
-[17, "setcolor", 47, 576, [10, 71, 30]],
-[18, ["repeat", 21], 418, 240, [24, 52, 19, null]],
-[19, "forward", 436, 282, [18, 20, 23]],
-[20, ["number", 100], 507, 282, [19, null]],
-[21, ["division2", 0], 494, 324, [23, 22, 54]],
-[22, ["number", 360], 564, 324, [21, null]],
-[23, "left", 436, 324, [19, 21, null]],
-[24, "hat", 418, 186, [null, 25, 18]],
-[25, ["number", 2], 476, 198, [24, null]],
-[26, "hat", 419, 427, [null, 27, 6]],
-[27, ["number", 1], 477, 439, [26, null]],
-[28, "stack", 47, 492, [9, 60, 10]],
-[29, ["number", 1], 856, 392, [42, null]],
-[30, "stack", 47, 618, [17, 64, 46]],
-[31, ["repeat", 42], 788, 434, [42, 32, 37, null]],
-[32, ["number", 2], 847, 434, [31, null]],
-[33, ["number", 1], 928, 602, [34, null]],
-[34, ["plus2", 0], 874, 560, [44, 62, 33]],
-[35, "hat", 29, 186, [null, 36, 39]],
-[36, ["string", "action"], 87, 198, [35, null]],
-[37, "stack", 806, 476, [31, 38, 44]],
-[38, ["string", "action"], 864, 476, [37, null]],
-[39, ["storein", 0], 29, 240, [35, 40, 41, 7]],
-[40, ["string", "box 1"], 97, 240, [39, null]],
-[41, ["number", 12], 97, 282, [39, null]],
-[42, ["storein", 0], 788, 350, [67, 43, 29, 31]],
-[43, ["string", "box 2"], 856, 350, [42, null]],
-[44, ["storein", 0], 806, 518, [37, 45, 34, null]],
-[45, ["string", "box 2"], 874, 518, [44, null]],
-[46, ["storein", 0], 47, 660, [30, 47, 15, null]],
-[47, ["string", "box 1"], 115, 660, [46, null]],
-[48, "box", 214, 450, [13, 49, null]],
-[49, ["string", "box 1"], 269, 450, [48, null]],
-[50, "box", 188, 702, [15, 51, null]],
-[51, ["string", "box 1"], 243, 702, [50, null]],
-[52, "box", 477, 240, [18, 53, null]],
-[53, ["string", "box 1"], 532, 240, [52, null]],
-[54, "box", 588, 366, [21, 55, null]],
-[55, ["string", "box 1"], 643, 366, [54, null]],
-[56, "box", 478, 481, [6, 57, null]],
-[57, ["string", "box 1"], 533, 481, [56, null]],
-[58, "box", 589, 607, [5, 59, null]],
-[59, ["string", "box 1"], 644, 607, [58, null]],
-[60, "box", 105, 492, [28, 61, null]],
-[61, ["string", "box 2"], 160, 492, [60, null]],
-[62, "box", 928, 560, [34, 63, null]],
-[63, ["string", "box 2"], 983, 560, [62, null]],
-[64, "box", 105, 618, [30, 65, null]],
-[65, ["string", "box 2"], 160, 618, [64, null]],
-[66, "red", 124, 366, [16, null]],
-[67, "fillscreen2", 788, 224, [0, 68, 69, 70, 42]],
-[68, ["number", 60], 870, 224, [67, null]],
-[69, ["number", 80], 870, 266, [67, null]],
-[70, ["number", 100], 870, 308, [67, null]],
-[71, "orange", 124, 576, [17, null]]]
+[[0, ["start", 2.0], 30, 550, [null, 164]],
+[1, ["setxy2", 20], 1317, 731, [83, 5, 166, 6]],
+[2, ["number", 20], 1429, 773, [5, null]],
+[3, "xcor", 1429, 731, [5, null]],
+[4, "ycor", 1429, 813, [166, null]],
+[5, ["plus2", 0], 1375, 731, [1, 3, 2]],
+[6, ["vspace", 0], 1317, 855, [1, 89]],
+[7, "penup", 1317, 521, [156, 19]],
+[8, "pendown", 1317, 1317, [25, 158]],
+[9, ["number", 60], 1429, 855, [166, null]],
+[10, "hat", 33, 869, [null, 11, 70]],
+[11, ["string", "next"], 91, 881, [10, null]],
+[12, "stack", 30, 638, [164, 13, null]],
+[13, ["string", "next"], 88, 638, [12, null]],
+[14, "clean", 33, 1007, [75, 37]],
+[15, "hat", 1334, 415, [null, 36, 72]],
+[16, "stack", 33, 1217, [73, 35, 31]],
+[17, "show", 1317, 1191, [30, 18, 25]],
+[18, ["string", "The repeat block repeats an action."], 1375, 1191, [17, null]],
+[19, ["setxy2", 0], 1317, 563, [7, 20, 21, 83]],
+[20, ["number", -300], 1375, 563, [19, null]],
+[21, ["number", 100], 1375, 605, [19, null]],
+[22, ["setxy2", 0], 1317, 1065, [87, 23, 29, 30]],
+[23, ["number", -300], 1375, 1065, [22, null]],
+[24, ["number", 80], 1453, 1149, [29, null]],
+[25, ["setxy2", 0], 1317, 1233, [17, 26, 27, 8]],
+[26, ["number", 0], 1375, 1233, [25, null]],
+[27, ["number", 0], 1375, 1275, [25, null]],
+[28, "ycor", 1429, 1107, [29, null]],
+[29, ["minus2", 0], 1375, 1107, [22, 28, 24]],
+[30, ["vspace", 0], 1317, 1149, [22, 17]],
+[31, "storeinbox1", 33, 1259, [16, 34, null]],
+[32, ["number", 1], 205, 1301, [34, null]],
+[33, "box1", 205, 1259, [34, null]],
+[34, ["plus2", 0], 151, 1259, [31, 33, 32]],
+[35, "box1", 91, 1217, [16, null]],
+[36, ["number", 3], 1392, 427, [15, null]],
+[37, ["if", 0], 33, 1049, [14, 41, 38, 73]],
+[38, "storeinbox1", 51, 1115, [37, 39, null]],
+[39, ["number", 0], 169, 1115, [38, null]],
+[40, "box1", 135, 1015, [41, null]],
+[41, ["greater2", 0], 89, 1015, [37, 40, 42, null]],
+[42, ["number", 3], 159, 1057, [41, null]],
+[43, ["number", 1], 1384, 194, [69, null]],
+[44, "penup", 1344, 270, [71, 45]],
+[45, ["setxy2", 0], 1344, 312, [44, 46, 47, 85]],
+[46, ["number", -300], 1402, 312, [45, null]],
+[47, ["number", 100], 1402, 354, [45, null]],
+[48, ["setxy2", 0], 1344, 984, [77, 49, 50, 53]],
+[49, ["number", -300], 1402, 984, [48, null]],
+[50, ["minus2", 0], 1402, 1026, [48, 51, 52]],
+[51, "ycor", 1456, 1026, [50, null]],
+[52, ["number", 40.0], 1480, 1068, [50, null]],
+[53, ["vspace", 0], 1344, 1068, [48, 54]],
+[54, "show", 1344, 1110, [53, 55, 56]],
+[55, ["string", "The turtle can move forward, back, left, and right."], 1402, 1110, [54, null]],
+[56, ["setxy2", 0], 1344, 1152, [54, 57, 58, 59]],
+[57, ["number", 0], 1402, 1152, [56, null]],
+[58, ["number", 0], 1402, 1194, [56, null]],
+[59, "pendown", 1344, 1236, [56, null]],
+[60, ["setxy2", 0], 1344, 480, [85, 61, 62, 81]],
+[61, ["number", -300], 1402, 480, [60, null]],
+[62, ["number", 25.0], 1402, 522, [60, null]],
+[63, ["setxy2", 0], 1344, 648, [81, 64, 65, 79]],
+[64, ["number", -300], 1402, 648, [63, null]],
+[65, ["number", -50.0], 1402, 690, [63, null]],
+[66, ["setxy2", 0], 1344, 816, [79, 67, 68, 77]],
+[67, ["number", -300], 1402, 816, [66, null]],
+[68, ["number", -125], 1402, 858, [66, null]],
+[69, "hat", 1326, 182, [null, 43, 71]],
+[70, "showblocks", 33, 923, [10, 75]],
+[71, "sandwichclampcollapsed", 1326, 236, [69, 44, null]],
+[72, "sandwichclampcollapsed", 1334, 469, [15, 156, null]],
+[73, ["loadblock", 0], 33, 1175, [37, 74, 16]],
+[74, ["string", "delete"], 91, 1175, [73, null]],
+[75, "loadpalette", 33, 965, [70, 76, 14]],
+[76, ["string", "turtle"], 94, 965, [75, null]],
+[77, ["loadblock2arg", 0], 1344, 900, [66, 78, 97, 48]],
+[78, ["string", "right"], 1402, 900, [77, null]],
+[79, ["loadblock2arg", 0], 1344, 732, [63, 80, 96, 66]],
+[80, ["string", "left"], 1402, 732, [79, null]],
+[81, ["loadblock2arg", 0], 1344, 564, [60, 82, 95, 63]],
+[82, ["string", "back"], 1402, 564, [81, null]],
+[83, ["loadblock2arg", 0], 1317, 647, [19, 84, 91, 1]],
+[84, ["string", "repeat"], 1375, 647, [83, null]],
+[85, ["loadblock2arg", 0], 1344, 396, [45, 86, 94, 60]],
+[86, ["string", "forward"], 1402, 396, [85, null]],
+[87, ["loadblock2arg", 0], 1317, 981, [89, 88, 93, 22]],
+[88, ["string", "right"], 1375, 981, [87, null]],
+[89, ["loadblock2arg", 0], 1317, 897, [6, 90, 92, 87]],
+[90, ["string", "forward"], 1375, 897, [89, null]],
+[91, ["number", 4], 1375, 689, [83, null]],
+[92, ["number", 100], 1375, 939, [89, null]],
+[93, ["number", 90], 1375, 1023, [87, null]],
+[94, ["number", 100], 1402, 438, [85, null]],
+[95, ["number", 100], 1402, 606, [81, null]],
+[96, ["number", 90], 1402, 774, [79, null]],
+[97, ["number", 90], 1402, 942, [77, null]],
+[98, "hat", 1327, 69, [null, 99, 100]],
+[99, ["number", 0], 1385, 81, [98, null]],
+[100, "sandwichclampcollapsed", 1327, 123, [98, 101, null]],
+[101, "penup", 1310, 133, [100, 102]],
+[102, ["setxy2", 0], 1310, 175, [101, 103, 104, 105]],
+[103, ["number", -300], 1368, 175, [102, null]],
+[104, ["number", -75], 1368, 217, [102, null]],
+[105, ["loadblock2arg", 0], 1310, 259, [102, 106, 107, 108]],
+[106, ["string", "forward"], 1368, 259, [105, null]],
+[107, ["number", 100], 1368, 301, [105, null]],
+[108, ["setxy2", 0], 1310, 343, [105, 109, 110, 113]],
+[109, ["number", -300], 1368, 343, [108, null]],
+[110, ["minus2", 0], 1368, 385, [108, 111, 112]],
+[111, "ycor", 1422, 385, [110, null]],
+[112, ["number", 75], 1446, 427, [110, null]],
+[113, ["vspace", 0], 1310, 427, [108, 114]],
+[114, "show", 1310, 469, [113, 115, 116]],
+[115, ["string", "The turtle goes forward 100 steps."], 1368, 469, [114, null]],
+[116, ["setxy2", 0], 1310, 511, [114, 117, 118, 119]],
+[117, ["number", 0], 1368, 511, [116, null]],
+[118, ["number", 0], 1368, 553, [116, null]],
+[119, "pendown", 1310, 595, [116, 120]],
+[120, "forward", 1310, 637, [119, 121, null]],
+[121, ["number", 100], 1381, 637, [120, null]],
+[122, "hat", 1329, 296, [null, 123, 124]],
+[123, ["number", 2], 1387, 308, [122, null]],
+[124, "sandwichclampcollapsed", 1329, 350, [122, 125, null]],
+[125, "penup", 1312, 360, [124, 126]],
+[126, ["setxy2", 0], 1312, 402, [125, 127, 128, 129]],
+[127, ["number", -300], 1370, 402, [126, null]],
+[128, ["number", 100], 1370, 444, [126, null]],
+[129, ["loadblock2arg", 0], 1312, 486, [126, 130, 131, 132]],
+[130, ["string", "forward"], 1370, 486, [129, null]],
+[131, ["number", 100], 1370, 528, [129, null]],
+[132, ["loadblock2arg", 0], 1312, 570, [129, 136, 133, 134]],
+[133, ["number", 45], 1370, 612, [132, null]],
+[134, ["loadblock2arg", 0], 1312, 654, [132, 149, 135, 137]],
+[135, ["number", 100], 1370, 696, [134, null]],
+[136, ["string", "right"], 1370, 570, [132, null]],
+[137, ["setxy2", 0], 1312, 738, [134, 138, 139, 142]],
+[138, ["number", -300], 1370, 738, [137, null]],
+[139, ["minus2", 0], 1370, 780, [137, 140, 141]],
+[140, "ycor", 1424, 780, [139, null]],
+[141, ["number", 200], 1448, 822, [139, null]],
+[142, ["vspace", 0], 1312, 822, [137, 143]],
+[143, "show", 1312, 864, [142, 144, 145]],
+[144, ["string", "The turtle runs a stack of blocks, starting from the top block."], 1370, 864, [143, null]],
+[145, ["setxy2", 0], 1312, 906, [143, 146, 147, 148]],
+[146, ["number", 0], 1370, 906, [145, null]],
+[147, ["number", 0], 1370, 948, [145, null]],
+[148, "pendown", 1312, 990, [145, 150]],
+[149, ["string", "forward"], 1370, 654, [134, null]],
+[150, "forward", 1312, 1032, [148, 151, 152]],
+[151, ["number", 100], 1383, 1032, [150, null]],
+[152, "right", 1312, 1074, [150, 153, 154]],
+[153, ["number", 45], 1370, 1074, [152, null]],
+[154, "forward", 1312, 1116, [152, 155, null]],
+[155, ["number", 100], 1383, 1116, [154, null]],
+[156, "loadpalette", 1317, 479, [72, 157, 7]],
+[157, ["string", "flow"], 1378, 479, [156, null]],
+[158, ["repeat", 21], 1317, 1359, [8, 159, 160, null]],
+[159, ["number", 4], 1376, 1359, [158, null]],
+[160, "forward", 1335, 1401, [158, 161, 162]],
+[161, ["number", 100], 1406, 1401, [160, null]],
+[162, "right", 1335, 1443, [160, 163, null]],
+[163, ["number", 90], 1393, 1443, [162, null]],
+[164, "comment", 30, 596, [0, 165, 12]],
+[165, ["string", "Click on the start block."], 113, 596, [164, null]],
+[166, ["plus2", 0], 1375, 813, [1, 4, 9]]]
diff --git a/turtleblocks.py b/turtleblocks.py
index 1e6495f..55a02dc 100755
--- a/turtleblocks.py
+++ b/turtleblocks.py
@@ -569,6 +569,7 @@ Would you like to save before quitting?'))
if pyee.block is not None:
pyee.block.highlight()
self.tw.showlabel('status', str(pyee))
+ print pyee
return
if not pythoncode:
return
@@ -582,7 +583,7 @@ Would you like to save before quitting?'))
(filename, self.tw.load_save_folder) = get_save_name(
save_type, self.tw.load_save_folder, default_name)
if isinstance(filename, unicode):
- filename = filename.encode('utf8')
+ filename = filename.encode('utf-8')
if filename is not None:
f = file(filename, 'w')
f.write(pythoncode)