[Python-checkins] r63929 - in python/trunk: Demo/turtle Demo/turtle/about_turtle.txt Demo/turtle/about_turtledemo.txt Demo/turtle/demohelp.txt Demo/turtle/tdemo_I_dontlike_tiltdemo.py Demo/turtle/tdemo_bytedesign.py Demo/turtle/tdemo_chaos.py Demo/turtle/tdemo_clock.py Demo/turtle/tdemo_colormixer.py Demo/turtle/tdemo_fractalcurves.py Demo/turtle/tdemo_lindenmayer_indian.py Demo/turtle/tdemo_minimal_hanoi.py Demo/turtle/tdemo_paint.py Demo/turtle/tdemo_peace.py Demo/turtle/tdemo_penrose.py Demo/turtle/tdemo_planet_and_moon.py Demo/turtle/tdemo_tree.py Demo/turtle/tdemo_wikipedia.py Demo/turtle/tdemo_yinyang.py Demo/turtle/turtle.cfg Demo/turtle/turtleDemo.py Demo/turtle/turtledemo_two_canvases.py Doc/library/turtle.rst Lib/lib-tk/turtle.py Misc/ACKS

martin.v.loewis python-checkins at python.org
Wed Jun 4 08:29:58 CEST 2008


Author: martin.v.loewis
Date: Wed Jun  4 08:29:55 2008
New Revision: 63929

Log:
Patch #1513695:  New turtle module, with demos.


Added:
   python/trunk/Demo/turtle/
   python/trunk/Demo/turtle/about_turtle.txt   (contents, props changed)
   python/trunk/Demo/turtle/about_turtledemo.txt   (contents, props changed)
   python/trunk/Demo/turtle/demohelp.txt   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_I_dontlike_tiltdemo.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_bytedesign.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_chaos.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_clock.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_colormixer.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_fractalcurves.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_lindenmayer_indian.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_minimal_hanoi.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_paint.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_peace.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_penrose.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_planet_and_moon.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_tree.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_wikipedia.py   (contents, props changed)
   python/trunk/Demo/turtle/tdemo_yinyang.py   (contents, props changed)
   python/trunk/Demo/turtle/turtle.cfg   (contents, props changed)
   python/trunk/Demo/turtle/turtleDemo.py   (contents, props changed)
   python/trunk/Demo/turtle/turtledemo_two_canvases.py   (contents, props changed)
Modified:
   python/trunk/Doc/library/turtle.rst
   python/trunk/Lib/lib-tk/turtle.py
   python/trunk/Misc/ACKS

Added: python/trunk/Demo/turtle/about_turtle.txt
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/about_turtle.txt	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,77 @@
+
+========================================================
+                       A new turtle module for Python
+========================================================
+
+Turtle graphics is a popular way for introducing programming to
+kids. It was part of the original Logo programming language developed
+by Wally Feurzig and Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
+the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
+the direction it is facing, drawing a line as it moves. Give it the
+command turtle.left(25), and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+  turtle. So the turtles can more easily be used as a visual feedback
+  instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+  and user controllable turtle shapes, among them compound
+  (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+  makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+  and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+  following the early Logo traditions. This reduces the boring work of
+  typing long sequences of commands, which often occur in a natural way
+  when kids try to program fancy pictures on their first encounter with
+  turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+  (mouse-, key-, timer-events). Especially useful for programming games.
+  
+- A scrollable Canvas class. The default scrollable Canvas can be
+  extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+  background image, window and canvas size and other properties of the
+  TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+  coordinate-system for the TurtleScreen. 
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+  This class is public, so it can be imported by the application programmer,
+  which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+  configured by means of a turtle.cfg configuration file.
+  The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+  dictionary in some different language, supplied separately  and replaces
+  the english ones by those read in. There is a utility function
+  write_docstringdict() to write a dictionary with the original (english)
+  docstrings to disc, so it can serve as a template for translations.
+

Added: python/trunk/Demo/turtle/about_turtledemo.txt
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/about_turtledemo.txt	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,14 @@
+
+  --------------------------------------
+     About xturtleDemo.py  
+  --------------------------------------
+
+  Tiny demo Viewer to view turtle graphics example scripts.
+
+  Quickly and dirtyly assembled by Gregor Lingl.
+  June, 2006
+
+  For more information see: xturtleDemo - Help 
+
+  Have fun!
+    

Added: python/trunk/Demo/turtle/demohelp.txt
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/demohelp.txt	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,75 @@
+
+
+  ----------------------------------------------
+
+      xturtleDemo - Help
+
+  ----------------------------------------------
+
+  This document has two sections:
+
+  (1) How to use the demo viewer
+  (2) How to add your own demos to the demo repository
+
+
+  (1) How to use the demo viewer.
+
+  Select a demoscript from the example menu.
+  The (syntax coloured) source code appears in the left
+  source code window. IT CANNOT BE EDITED, but ONLY VIEWED!
+
+  - Press START button to start the demo.
+  - Stop execution by pressing the STOP button.
+  - Clear screen by pressing the CLEAR button.
+  - Restart by pressing the START button again.
+
+  SPECIAL demos are those which run EVENTDRIVEN.
+  (For example clock.py - or oldTurtleDemo.py which
+  in the end expects a mouse click.):
+
+      Press START button to start the demo.
+
+      - Until the EVENTLOOP is entered everything works
+      as in an ordinary demo script.
+
+      - When the EVENTLOOP is entered, you control the
+      application by using the mouse and/or keys (or it's
+      controlled by some timer events)
+      To stop it you can and must press the STOP button.
+
+      While the EVENTLOOP is running, the examples menu is disabled.
+
+      - Only after having pressed the STOP button, you may
+      restart it or choose another example script.
+
+   * * * * * * * *
+   In some rare situations there may occur interferences/conflicts
+   between events concerning the demo script and those concerning the
+   demo-viewer. (They run in the same process.) Strange behaviour may be
+   the consequence and in the worst case you must close and restart the
+   viewer.
+   * * * * * * * *
+
+
+   (2) How to add your own demos to the demo repository
+
+   - scriptname: must begin with tdemo_ ,
+     so it must have the form tdemo_<your-script-name>.py
+
+   - place: same directory as xturtleDemo.py or some
+     subdirectory, the name of which must also begin with
+     tdemo_.....
+
+   - requirements on source code:
+       code must contain a main() function which will
+       be executed by the viewer (see provided example scripts)
+       main() may return a string which will be displayed
+       in the Label below the source code window (when execution
+       has finished.) 
+
+       !! For programs, which are EVENT DRIVEN, main must return
+       !! the string "EVENTLOOP". This informs the viewer, that the
+       !! script is still running and must be stopped by the user!
+
+        
+  

Added: python/trunk/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_I_dontlike_tiltdemo.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+     tdemo-I_dont_like_tiltdemo.py
+
+Demostrates
+  (a) use of a tilted ellipse as
+      turtle shape
+  (b) stamping that shape
+
+We can remove it, if you don't like it.
+      Without using reset() ;-)
+ ---------------------------------------
+"""
+from turtle import *
+import time
+
+def main():
+    reset()
+    shape("circle")
+    resizemode("user")
+
+    pu(); bk(24*18/6.283); rt(90); pd()
+    tilt(45)
+
+    pu()
+
+    turtlesize(16,10,5)
+    color("red", "violet")
+    for i in range(18):
+        fd(24)
+        lt(20)
+        stamp()
+    color("red", "")
+    for i in range(18):
+        fd(24)
+        lt(20)
+        stamp()
+
+    tilt(-15)
+    turtlesize(3, 1, 4)
+    color("blue", "yellow")
+    for i in range(17):
+        fd(24)
+        lt(20)
+        if i%2 == 0:
+            stamp()
+    time.sleep(1)
+    while undobufferentries():
+        undo()
+    ht()
+    write("OK, OVER!", align="center", font=("Courier", 18, "bold"))
+    return "Done!"
+
+if __name__=="__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_bytedesign.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_bytedesign.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,162 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+        tdemo_bytedesign.py
+
+An example adapted from the example-suite
+of PythonCard's turtle graphcis.
+
+It's based on an article in BYTE magazine
+Problem Solving with Logo: Using Turtle
+Graphics to Redraw a Design
+November 1982, p. 118 - 134
+
+-------------------------------------------
+
+Due to the statement
+
+t.delay(0)
+
+in line 152, which sets the animation delay
+to 0, this animation runs in "line per line"
+mode as fast as possible.
+"""
+
+import math
+from turtle import Turtle, mainloop
+from time import clock
+
+# wrapper for any additional drawing routines
+# that need to know about each other
+class Designer(Turtle):
+
+    def design(self, homePos, scale):
+        self.up()
+        for i in range(5):
+            self.forward(64.65 * scale)
+            self.down()
+            self.wheel(self.position(), scale)
+            self.up()
+            self.backward(64.65 * scale)
+            self.right(72)
+        self.up()
+        self.goto(homePos)
+        self.right(36)
+        self.forward(24.5 * scale)
+        self.right(198)
+        self.down()
+        self.centerpiece(46 * scale, 143.4, scale)
+        self.tracer(True)
+
+    def wheel(self, initpos, scale):
+        self.right(54)
+        for i in range(4):
+            self.pentpiece(initpos, scale)
+        self.down()
+        self.left(36)
+        for i in range(5):
+            self.tripiece(initpos, scale)
+        self.left(36)
+        for i in range(5):
+            self.down()
+            self.right(72)
+            self.forward(28 * scale)
+            self.up()
+            self.backward(28 * scale)
+        self.left(54)
+        self.getscreen().update()
+
+    def tripiece(self, initpos, scale):
+        oldh = self.heading()
+        self.down()
+        self.backward(2.5 * scale)
+        self.tripolyr(31.5 * scale, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.down()
+        self.backward(2.5 * scale)
+        self.tripolyl(31.5 * scale, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.left(72)
+        self.getscreen().update()
+
+    def pentpiece(self, initpos, scale):
+        oldh = self.heading()
+        self.up()
+        self.forward(29 * scale)
+        self.down()
+        for i in range(5):
+            self.forward(18 * scale)
+            self.right(72)
+        self.pentr(18 * scale, 75, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.forward(29 * scale)
+        self.down()
+        for i in range(5):
+            self.forward(18 * scale)
+            self.right(72)
+        self.pentl(18 * scale, 75, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.left(72)
+        self.getscreen().update()
+
+    def pentl(self, side, ang, scale):
+        if side < (2 * scale): return
+        self.forward(side)
+        self.left(ang)
+        self.pentl(side - (.38 * scale), ang, scale)
+
+    def pentr(self, side, ang, scale):
+        if side < (2 * scale): return
+        self.forward(side)
+        self.right(ang)
+        self.pentr(side - (.38 * scale), ang, scale)
+
+    def tripolyr(self, side, scale):
+        if side < (4 * scale): return
+        self.forward(side)
+        self.right(111)
+        self.forward(side / 1.78)
+        self.right(111)
+        self.forward(side / 1.3)
+        self.right(146)
+        self.tripolyr(side * .75, scale)
+
+    def tripolyl(self, side, scale):
+        if side < (4 * scale): return
+        self.forward(side)
+        self.left(111)
+        self.forward(side / 1.78)
+        self.left(111)
+        self.forward(side / 1.3)
+        self.left(146)
+        self.tripolyl(side * .75, scale)
+
+    def centerpiece(self, s, a, scale):
+        self.forward(s); self.left(a)
+        if s < (7.5 * scale):
+            return
+        self.centerpiece(s - (1.2 * scale), a, scale)
+
+def main():
+    t = Designer()
+    t.speed(0)
+    t.hideturtle()
+    t.getscreen().delay(0)
+    t.tracer(0)
+    at = clock()
+    t.design(t.position(), 2)
+    et = clock()
+    return "runtime: %.2f sec." % (et-at)
+
+if __name__ == '__main__':
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_chaos.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_chaos.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,63 @@
+# Datei: chaosplotter.py
+# Autor: Gregor Lingl
+# Datum: 31. 5. 2008
+
+# Ein einfaches Programm zur Demonstration von "chaotischem Verhalten".
+
+from turtle import *
+
+def f(x):
+    return 3.9*x*(1-x)
+
+def g(x):
+    return 3.9*(x-x**2)
+
+def h(x):
+    return 3.9*x-3.9*x*x
+
+def coosys():
+    penup()
+    goto(-1,0)
+    pendown()
+    goto(n+1,0)
+    penup()
+    goto(0, -0.1)
+    pendown()
+    goto(-0.1, 1.1)
+
+def plot(fun, start, farbe):
+    x = start
+    pencolor(farbe)
+    penup()
+    goto(0, x)
+    pendown()
+    dot(5)
+    for i in range(n):
+        x=fun(x)
+        goto(i+1,x)
+        dot(5)
+
+def main():
+    global n
+    n = 80
+    ox=-250.0
+    oy=-150.0
+    ex= -2.0*ox / n
+    ey=300.0
+
+    reset()
+    setworldcoordinates(-1.0,-0.1, n+1, 1.1)
+    speed(0)
+    hideturtle()
+    coosys()
+    plot(f, 0.35, "blue")
+    plot(g, 0.35, "green")
+    plot(h, 0.35, "red")
+    for s in range(100):
+        setworldcoordinates(0.5*s,-0.1, n+1, 1.1)
+
+    return "Done!"
+
+if __name__ == "__main__":
+    main()
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_clock.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_clock.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+# -*- coding: cp1252 -*-
+"""       turtle-example-suite:
+
+             tdemo_clock.py
+
+Enhanced clock-program, showing date
+and time
+  ------------------------------------
+   Press STOP to exit the program!
+  ------------------------------------
+"""
+from turtle import *
+from datetime import datetime
+
+mode("logo")
+
+def jump(distanz, winkel=0):
+    penup()
+    right(winkel)
+    forward(distanz)
+    left(winkel)
+    pendown()
+
+def hand(laenge, spitze):
+    fd(laenge*1.15)
+    rt(90)
+    fd(spitze/2.0)
+    lt(120)
+    fd(spitze)
+    lt(120)
+    fd(spitze)
+    lt(120)
+    fd(spitze/2.0)
+
+def make_hand_shape(name, laenge, spitze):
+    reset()
+    jump(-laenge*0.15)
+    begin_poly()
+    hand(laenge, spitze)
+    end_poly()
+    hand_form = get_poly()
+    register_shape(name, hand_form)
+
+
+def clockface(radius):
+    reset()
+    pensize(7)
+    for i in range(60):
+        jump(radius)
+        if i % 5 == 0:
+            fd(25)
+            jump(-radius-25)
+        else:
+            dot(3)
+            jump(-radius)
+        rt(6)
+
+def setup():
+    global second_hand, minute_hand, hour_hand, writer
+    mode("logo")
+    make_hand_shape("second_hand", 125, 25)
+    make_hand_shape("minute_hand",  130, 25)
+    make_hand_shape("hour_hand", 90, 25)
+    clockface(160)
+    second_hand = Turtle()
+    second_hand.shape("second_hand")
+    second_hand.color("gray20", "gray80")
+    minute_hand = Turtle()
+    minute_hand.shape("minute_hand")
+    minute_hand.color("blue1", "red1")
+    hour_hand = Turtle()
+    hour_hand.shape("hour_hand")
+    hour_hand.color("blue3", "red3")
+    for hand in second_hand, minute_hand, hour_hand:
+        hand.resizemode("user")
+        hand.shapesize(1, 1, 3)
+        hand.speed(0)
+    ht()
+    writer = Turtle()
+    #writer.mode("logo")
+    writer.ht()
+    writer.pu()
+    writer.bk(85)
+
+
+def wochentag(t):
+    wochentag = ["Monday", "Tuesday", "Wednesday",
+        "Thursday", "Friday", "Saturday", "Sunday"]
+    return wochentag[t.weekday()]
+
+def datum(z):
+    monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June",
+             "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]
+    j = z.year
+    m = monat[z.month - 1]
+    t = z.day
+    return "%s %d %d" % (m, t, j)
+
+def tick():
+    t = datetime.today()
+    sekunde = t.second + t.microsecond*0.000001
+    minute = t.minute + sekunde/60.0
+    stunde = t.hour + minute/60.0
+    tracer(False)
+    writer.clear()
+    writer.home()
+    writer.forward(65)
+    writer.write(wochentag(t),
+                 align="center", font=("Courier", 14, "bold"))
+    writer.back(150)
+    writer.write(datum(t),
+                 align="center", font=("Courier", 14, "bold"))
+    writer.forward(85)
+    tracer(True)
+    second_hand.setheading(6*sekunde)
+    minute_hand.setheading(6*minute)
+    hour_hand.setheading(30*stunde)
+    tracer(True)
+    ontimer(tick, 100)
+
+def main():
+    tracer(False)
+    setup()
+    tracer(True)
+    tick()
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_colormixer.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_colormixer.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,58 @@
+# colormixer
+
+from turtle import Screen, Turtle, mainloop
+
+class ColorTurtle(Turtle):
+
+    def __init__(self, x, y):
+        Turtle.__init__(self)
+        self.shape("turtle")
+        self.resizemode("user")
+        self.shapesize(3,3,5)
+        self.pensize(10)
+        self._color = [0,0,0]
+        self.x = x
+        self._color[x] = y
+        self.color(self._color)
+        self.speed(0)
+        self.left(90)
+        self.pu()
+        self.goto(x,0)
+        self.pd()
+        self.sety(1)
+        self.pu()
+        self.sety(y)
+        self.pencolor("gray25")
+        self.ondrag(self.shift)
+
+    def shift(self, x, y):
+        self.sety(max(0,min(y,1)))
+        self._color[self.x] = self.ycor()
+        self.fillcolor(self._color)
+        setbgcolor()
+
+def setbgcolor():
+    screen.bgcolor(red.ycor(), green.ycor(), blue.ycor())
+
+def main():
+    global screen, red, green, blue
+    screen = Screen()
+    screen.delay(0)
+    screen.setworldcoordinates(-1, -0.3, 3, 1.3)
+
+    red = ColorTurtle(0, .5)
+    green = ColorTurtle(1, .5)
+    blue = ColorTurtle(2, .5)
+    setbgcolor()
+
+    writer = Turtle()
+    writer.ht()
+    writer.pu()
+    writer.goto(1,1.15)
+    writer.write("DRAG!",align="center",font=("Arial",30,("bold","italic")))
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_fractalcurves.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_fractalcurves.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,137 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+        tdemo_fractalCurves.py
+
+This program draws two fractal-curve-designs:
+(1) A hilbert curve (in a box)
+(2) A combination of Koch-curves.
+
+The CurvesTurtle class and the fractal-curve-
+methods are taken from the PythonCard example
+scripts for turtle-graphics.
+"""
+from turtle import *
+from time import sleep, clock
+
+class CurvesTurtle(Pen):
+    # example derived from
+    # Turtle Geometry: The Computer as a Medium for Exploring Mathematics
+    # by Harold Abelson and Andrea diSessa
+    # p. 96-98
+    def hilbert(self, size, level, parity):
+        if level == 0:
+            return
+        # rotate and draw first subcurve with opposite parity to big curve
+        self.left(parity * 90)
+        self.hilbert(size, level - 1, -parity)
+        # interface to and draw second subcurve with same parity as big curve
+        self.forward(size)
+        self.right(parity * 90)
+        self.hilbert(size, level - 1, parity)
+        # third subcurve
+        self.forward(size)
+        self.hilbert(size, level - 1, parity)
+        # fourth subcurve
+        self.right(parity * 90)
+        self.forward(size)
+        self.hilbert(size, level - 1, -parity)
+        # a final turn is needed to make the turtle
+        # end up facing outward from the large square
+        self.left(parity * 90)
+
+    # Visual Modeling with Logo: A Structural Approach to Seeing
+    # by James Clayson
+    # Koch curve, after Helge von Koch who introduced this geometric figure in 1904
+    # p. 146
+    def fractalgon(self, n, rad, lev, dir):
+        import math
+
+        # if dir = 1 turn outward
+        # if dir = -1 turn inward
+        edge = 2 * rad * math.sin(math.pi / n)
+        self.pu()
+        self.fd(rad)
+        self.pd()
+        self.rt(180 - (90 * (n - 2) / n))
+        for i in range(n):
+            self.fractal(edge, lev, dir)
+            self.rt(360 / n)
+        self.lt(180 - (90 * (n - 2) / n))
+        self.pu()
+        self.bk(rad)
+        self.pd()
+
+    # p. 146
+    def fractal(self, dist, depth, dir):
+        if depth < 1:
+            self.fd(dist)
+            return
+        self.fractal(dist / 3, depth - 1, dir)
+        self.lt(60 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+        self.rt(120 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+        self.lt(60 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+
+def main():
+    ft = CurvesTurtle()
+
+    ft.reset()
+    ft.speed(0)
+    ft.ht()
+    ft.tracer(1,0)
+    ft.pu()
+
+    size = 6
+    ft.setpos(-33*size, -32*size)
+    ft.pd()
+
+    ta=clock()
+    ft.fillcolor("red")
+    ft.fill(True)
+    ft.fd(size)
+
+    ft.hilbert(size, 6, 1)
+
+    # frame
+    ft.fd(size)
+    for i in range(3):
+        ft.lt(90)
+        ft.fd(size*(64+i%2))
+    ft.pu()
+    for i in range(2):
+        ft.fd(size)
+        ft.rt(90)
+    ft.pd()
+    for i in range(4):
+        ft.fd(size*(66+i%2))
+        ft.rt(90)
+    ft.fill(False)
+    tb=clock()
+    res =  "Hilbert: %.2fsec. " % (tb-ta)
+
+    sleep(3)
+
+    ft.reset()
+    ft.speed(0)
+    ft.ht()
+    ft.tracer(1,0)
+
+    ta=clock()
+    ft.color("black", "blue")
+    ft.fill(True)
+    ft.fractalgon(3, 250, 4, 1)
+    ft.fill(True)
+    ft.color("red")
+    ft.fractalgon(3, 200, 4, -1)
+    ft.fill(False)
+    tb=clock()
+    res +=  "Koch: %.2fsec." % (tb-ta)
+    return res
+
+if __name__  == '__main__':
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_lindenmayer_indian.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_lindenmayer_indian.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+        xtx_lindenmayer_indian.py
+
+Each morning women in Tamil Nadu, in southern
+India, place designs, created by using rice
+flour and known as kolam on the thresholds of
+their homes.
+
+These can be described by Lindenmayer systems,
+which can easily be implemented with turtle
+graphics and Python.
+
+Two examples are shown here:
+(1) the snake kolam
+(2) anklets of Krishna
+
+Taken from Marcia Ascher: Mathematics
+Elsewhere, An Exploration of Ideas Across
+Cultures
+
+"""
+################################
+# Mini Lindenmayer tool
+###############################
+
+from turtle import *
+
+def replace( seq, replacementRules, n ):
+    for i in range(n):
+        newseq = ""
+        for element in seq:
+            newseq = newseq + replacementRules.get(element,element)
+        seq = newseq
+    return seq
+
+def draw( commands, rules ):
+    for b in commands:
+        try:
+            rules[b]()
+        except TypeError:
+            try:
+                draw(rules[b], rules)
+            except:
+                pass
+
+
+def main():
+    ################################
+    # Example 1: Snake kolam
+    ################################
+
+
+    def r():
+        right(45)
+
+    def l():
+        left(45)
+
+    def f():
+        forward(7.5)
+
+    snake_rules = {"-":r, "+":l, "f":f, "b":"f+f+f--f--f+f+f"}
+    snake_replacementRules = {"b": "b+f+b--f--b+f+b"}
+    snake_start = "b--f--b--f"
+
+    drawing = replace(snake_start, snake_replacementRules, 3)
+
+    reset()
+    speed(3)
+    tracer(1,0)
+    ht()
+    up()
+    backward(195)
+    down()
+    draw(drawing, snake_rules)
+
+    from time import sleep
+    sleep(3)
+
+    ################################
+    # Example 2: Anklets of Krishna
+    ################################
+
+    def A():
+        color("red")
+        circle(10,90)
+
+    def B():
+        from math import sqrt
+        color("black")
+        l = 5/sqrt(2)
+        forward(l)
+        circle(l, 270)
+        forward(l)
+
+    def F():
+        color("green")
+        forward(10)
+
+    krishna_rules = {"a":A, "b":B, "f":F}
+    krishna_replacementRules = {"a" : "afbfa", "b" : "afbfbfbfa" }
+    krishna_start = "fbfbfbfb"
+
+    reset()
+    speed(0)
+    tracer(3,0)
+    ht()
+    left(45)
+    drawing = replace(krishna_start, krishna_replacementRules, 3)
+    draw(drawing, krishna_rules)
+    tracer(1)
+    return "Done!"
+
+if __name__=='__main__':
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_minimal_hanoi.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_minimal_hanoi.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+         tdemo_minimal_hanoi.py
+
+A minimal 'Towers of Hanoi' animation:
+A tower of 6 discs is transferred from the
+left to the right peg.
+
+An imho quite elegant and concise
+implementation using a tower class, which
+is derived from the built-in type list.
+
+Discs are turtles with shape "square", but
+stretched to rectangles by shapesize()
+ ---------------------------------------
+       To exit press STOP button
+ ---------------------------------------
+"""
+from turtle import *
+
+class Disc(Turtle):
+    def __init__(self, n):
+        Turtle.__init__(self, shape="square", visible=False)
+        self.pu()
+        self.shapesize(1.5, n*1.5, 2) # square-->rectangle
+        self.fillcolor(n/6., 0, 1-n/6.)
+        self.st()
+
+class Tower(list):
+    "Hanoi tower, a subclass of built-in type list"
+    def __init__(self, x):
+        "create an empty tower. x is x-position of peg"
+        self.x = x
+    def push(self, d):
+        d.setx(self.x)
+        d.sety(-150+34*len(self))
+        self.append(d)
+    def pop(self):
+        d = list.pop(self)
+        d.sety(150)
+        return d
+
+def hanoi(n, from_, with_, to_):
+    if n > 0:
+        hanoi(n-1, from_, to_, with_)
+        to_.push(from_.pop())
+        hanoi(n-1, with_, from_, to_)
+
+def play():
+    onkey(None,"space")
+    clear()
+    hanoi(6, t1, t2, t3)
+    write("press STOP button to exit",
+          align="center", font=("Courier", 16, "bold"))
+
+def main():
+    global t1, t2, t3
+    ht(); penup(); goto(0, -225)   # writer turtle
+    t1 = Tower(-250)
+    t2 = Tower(0)
+    t3 = Tower(250)
+    # make tower of 6 discs
+    for i in range(6,0,-1):
+        t1.push(Disc(i))
+    # prepare spartanic user interface ;-)
+    write("press spacebar to start game",
+          align="center", font=("Courier", 16, "bold"))
+    onkey(play, "space")
+    listen()
+    return "EVENTLOOP"
+
+if __name__=="__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_paint.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_paint.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+            tdemo_paint.py
+
+A simple  eventdriven paint program
+
+- use left mouse button to move turtle
+- middle mouse button to change color
+- right mouse button do turn filling on/off
+ -------------------------------------------
+ Play around by clicking into the canvas
+ using all three mouse buttons.
+ -------------------------------------------
+          To exit press STOP button
+ -------------------------------------------
+"""
+from turtle import *
+
+def switchupdown(x=0, y=0):
+    if pen()["pendown"]:
+        end_fill()
+        up()
+    else:
+        down()
+        begin_fill()
+
+def changecolor(x=0, y=0):
+    global colors
+    colors = colors[1:]+colors[:1]
+    color(colors[0])
+
+def main():
+    global colors
+    shape("circle")
+    resizemode("user")
+    shapesize(.5)
+    width(3)
+    colors=["red", "green", "blue", "yellow"]
+    color(colors[0])
+    switchupdown()
+    onscreenclick(goto,1)
+    onscreenclick(changecolor,2)
+    onscreenclick(switchupdown,3)
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_peace.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_peace.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+              tdemo_peace.py
+
+A very simple drawing suitable as a beginner's
+programming example.
+
+Uses only commands, which are also available in
+old turtle.py.
+
+Intentionally no variables are used except for the
+colorloop:
+"""
+
+from turtle import *
+
+def main():
+    peacecolors = ("red3",  "orange", "yellow",
+                   "seagreen4", "orchid4",
+                   "royalblue1", "dodgerblue4")
+
+    reset()
+    s = Screen()
+    up()
+    goto(-320,-195)
+    width(70)
+
+    for pcolor in peacecolors:
+        color(pcolor)
+        down()
+        forward(640)
+        up()
+        backward(640)
+        left(90)
+        forward(66)
+        right(90)
+
+    width(25)
+    color("white")
+    goto(0,-170)
+    down()
+
+    circle(170)
+    left(90)
+    forward(340)
+    up()
+    left(180)
+    forward(170)
+    right(45)
+    down()
+    forward(170)
+    up()
+    backward(170)
+    left(90)
+    down()
+    forward(170)
+    up()
+
+    goto(0,300) # vanish if hideturtle() is not available ;-)
+    return "Done!!"
+
+if __name__ == "__main__":
+    main()
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_penrose.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_penrose.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+"""       xturtle-example-suite:
+
+          xtx_kites_and_darts.py
+
+Constructs two aperiodic penrose-tilings,
+consisting of kites and darts, by the method
+of inflation in six steps.
+
+Starting points are the patterns "sun"
+consisting of five kites and "star"
+consisting of five darts.
+
+For more information see:
+ http://en.wikipedia.org/wiki/Penrose_tiling
+ -------------------------------------------
+"""
+from turtle import *
+from math import cos, pi
+from time import clock, sleep
+
+f = (5**0.5-1)/2.0   # (sqrt(5)-1)/2 -- golden ratio
+d = 2 * cos(3*pi/10)
+
+def kite(l):
+    fl = f * l
+    lt(36)
+    fd(l)
+    rt(108)
+    fd(fl)
+    rt(36)
+    fd(fl)
+    rt(108)
+    fd(l)
+    rt(144)
+
+def dart(l):
+    fl = f * l
+    lt(36)
+    fd(l)
+    rt(144)
+    fd(fl)
+    lt(36)
+    fd(fl)
+    rt(144)
+    fd(l)
+    rt(144)
+
+def inflatekite(l, n):
+    if n == 0:
+        px, py = pos()
+        h, x, y = int(heading()), round(px,3), round(py,3)
+        tiledict[(h,x,y)] = True
+        return
+    fl = f * l
+    lt(36)
+    inflatedart(fl, n-1)
+    fd(l)
+    rt(144)
+    inflatekite(fl, n-1)
+    lt(18)
+    fd(l*d)
+    rt(162)
+    inflatekite(fl, n-1)
+    lt(36)
+    fd(l)
+    rt(180)
+    inflatedart(fl, n-1)
+    lt(36)
+
+def inflatedart(l, n):
+    if n == 0:
+        px, py = pos()
+        h, x, y = int(heading()), round(px,3), round(py,3)
+        tiledict[(h,x,y)] = False
+        return
+    fl = f * l
+    inflatekite(fl, n-1)
+    lt(36)
+    fd(l)
+    rt(180)
+    inflatedart(fl, n-1)
+    lt(54)
+    fd(l*d)
+    rt(126)
+    inflatedart(fl, n-1)
+    fd(l)
+    rt(144)
+
+def draw(l, n, th=2):
+    clear()
+    l = l * f**n
+    shapesize(l/100.0, l/100.0, th)
+    for k in tiledict:
+        h, x, y = k
+        setpos(x, y)
+        setheading(h)
+        if tiledict[k]:
+            shape("kite")
+            color("black", (0, 0.75, 0))
+        else:
+            shape("dart")
+            color("black", (0.75, 0, 0))
+        stamp()
+
+def sun(l, n):
+    for i in range(5):
+        inflatekite(l, n)
+        lt(72)
+
+def star(l,n):
+    for i in range(5):
+        inflatedart(l, n)
+        lt(72)
+
+def makeshapes():
+    tracer(0)
+    begin_poly()
+    kite(100)
+    end_poly()
+    register_shape("kite", get_poly())
+    begin_poly()
+    dart(100)
+    end_poly()
+    register_shape("dart", get_poly())
+    tracer(1)
+
+def start():
+    reset()
+    ht()
+    pu()
+    makeshapes()
+    resizemode("user")
+
+def test(l=200, n=4, fun=sun, startpos=(0,0), th=2):
+    global tiledict
+    goto(startpos)
+    setheading(0)
+    tiledict = {}
+    a = clock()
+    tracer(0)
+    fun(l, n)
+    b = clock()
+    draw(l, n, th)
+    tracer(1)
+    c = clock()
+    print "Calculation:   %7.4f s" % (b - a)
+    print "Drawing:  %7.4f s" % (c - b)
+    print "Together: %7.4f s" % (c - a)
+    nk = len([x for x in tiledict if tiledict[x]])
+    nd = len([x for x in tiledict if not tiledict[x]])
+    print "%d kites and %d darts = %d pieces." % (nk, nd, nk+nd)
+
+def demo(fun=sun):
+    start()
+    for i in range(8):
+        a = clock()
+        test(300, i, fun)
+        b = clock()
+        t = b - a
+        if t < 2:
+            sleep(2 - t)
+
+def main():
+    #title("Penrose-tiling with kites and darts.")
+    mode("logo")
+    bgcolor(0.3, 0.3, 0)
+    demo(sun)
+    sleep(2)
+    demo(star)
+    pencolor("black")
+    goto(0,-200)
+    pencolor(0.7,0.7,1)
+    write("Please wait...",
+          align="center", font=('Arial Black', 36, 'bold'))
+    test(600, 8, startpos=(70, 117))
+    return "Done"
+
+if __name__ == "__main__":
+    msg = main()
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_planet_and_moon.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_planet_and_moon.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+        tdemo_planets_and_moon.py
+
+Gravitational system simulation using the
+approximation method from Feynman-lectures,
+p.9-8, using turtlegraphics.
+
+Example: heavy central body, light planet,
+very light moon!
+Planet has a circular orbit, moon a stable
+orbit around the planet.
+
+You can hold the movement temporarily by pressing
+the left mouse button with mouse over the
+scrollbar of the canvas.
+
+"""
+from turtle import Shape, Turtle, mainloop, Vec2D as Vec
+from time import sleep
+
+G = 8
+
+class GravSys(object):
+    def __init__(self):
+        self.planets = []
+        self.t = 0
+        self.dt = 0.01
+    def init(self):
+        for p in self.planets:
+            p.init()
+    def start(self):
+        for i in range(10000):
+            self.t += self.dt
+            for p in self.planets:
+                p.step()
+
+class Star(Turtle):
+    def __init__(self, m, x, v, gravSys, shape):
+        Turtle.__init__(self, shape=shape)
+        self.penup()
+        self.m = m
+        self.setpos(x)
+        self.v = v
+        gravSys.planets.append(self)
+        self.gravSys = gravSys
+        self.resizemode("user")
+        self.pendown()
+    def init(self):
+        dt = self.gravSys.dt
+        self.a = self.acc()
+        self.v = self.v + 0.5*dt*self.a
+    def acc(self):
+        a = Vec(0,0)
+        for planet in self.gravSys.planets:
+            if planet != self:
+                v = planet.pos()-self.pos()
+                a += (G*planet.m/abs(v)**3)*v
+        return a
+    def step(self):
+        dt = self.gravSys.dt
+        self.setpos(self.pos() + dt*self.v)
+        if self.gravSys.planets.index(self) != 0:
+            self.setheading(self.towards(self.gravSys.planets[0]))
+        self.a = self.acc()
+        self.v = self.v + dt*self.a
+
+## create compound yellow/blue turtleshape for planets
+
+def main():
+    s = Turtle()
+    s.reset()
+    s.tracer(0,0)
+    s.ht()
+    s.pu()
+    s.fd(6)
+    s.lt(90)
+    s.begin_poly()
+    s.circle(6, 180)
+    s.end_poly()
+    m1 = s.get_poly()
+    s.begin_poly()
+    s.circle(6,180)
+    s.end_poly()
+    m2 = s.get_poly()
+
+    planetshape = Shape("compound")
+    planetshape.addcomponent(m1,"orange")
+    planetshape.addcomponent(m2,"blue")
+    s.getscreen().register_shape("planet", planetshape)
+    s.tracer(1,0)
+
+    ## setup gravitational system
+    gs = GravSys()
+    sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle")
+    sun.color("yellow")
+    sun.shapesize(1.8)
+    sun.pu()
+    earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet")
+    earth.pencolor("green")
+    earth.shapesize(0.8)
+    moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet")
+    moon.pencolor("blue")
+    moon.shapesize(0.5)
+    gs.init()
+    gs.start()
+    return "Done!"
+
+if __name__ == '__main__':
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_tree.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_tree.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+             tdemo_tree.py
+
+Displays a 'breadth-first-tree' - in contrast
+to the classical Logo tree drawing programs,
+which use a depth-first-algorithm.
+
+Uses:
+(1) a tree-generator, where the drawing is
+quasi the side-effect, whereas the generator
+always yields None.
+(2) Turtle-cloning: At each branching point the
+current pen is cloned. So in the end there
+are 1024 turtles.
+"""
+from turtle import Turtle, mainloop
+from time import clock
+
+def tree(plist, l, a, f):
+    """ plist is list of pens
+    l is length of branch
+    a is half of the angle between 2 branches
+    f is factor by which branch is shortened
+    from level to level."""
+    if l > 3:
+        lst = []
+        for p in plist:
+            p.forward(l)
+            q = p.clone()
+            p.left(a)
+            q.right(a)
+            lst.append(p)
+            lst.append(q)
+        for x in tree(lst, l*f, a, f):
+            yield None
+
+def maketree():
+    p = Turtle()
+    p.setundobuffer(None)
+    p.hideturtle()
+    p.speed(0)
+    p.tracer(30,0)
+    p.left(90)
+    p.penup()
+    p.forward(-210)
+    p.pendown()
+    t = tree([p], 200, 65, 0.6375)
+    for x in t:
+        pass
+    print len(p.getscreen().turtles())
+
+def main():
+    a=clock()
+    maketree()
+    b=clock()
+    return "done: %.2f sec." % (b-a)
+
+if __name__ == "__main__":
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_wikipedia.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_wikipedia.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,65 @@
+"""      turtle-example-suite:
+
+          tdemo_wikipedia3.py
+
+This example is
+inspired by the Wikipedia article on turtle
+graphics. (See example wikipedia1 for URLs)
+
+First we create (ne-1) (i.e. 35 in this
+example) copies of our first turtle p.
+Then we let them perform their steps in
+parallel.
+
+Followed by a complete undo().
+"""
+from turtle import Screen, Turtle, mainloop
+from time import clock, sleep
+
+def mn_eck(p, ne,sz):
+    turtlelist = [p]
+    #create ne-1 additional turtles
+    for i in range(1,ne):
+        q = p.clone()
+        q.rt(360.0/ne)
+        turtlelist.append(q)
+        p = q
+    for i in range(ne):
+        c = abs(ne/2.0-i)/(ne*.7)
+        # let those ne turtles make a step
+        # in parallel:
+        for t in turtlelist:
+            t.rt(360./ne)
+            t.pencolor(1-c,0,c)
+            t.fd(sz)
+
+def main():
+    s = Screen()
+    s.bgcolor("black")
+    p=Turtle()
+    p.speed(0)
+    p.hideturtle()
+    p.pencolor("red")
+    p.pensize(3)
+
+    s.tracer(36,0)
+
+    at = clock()
+    mn_eck(p, 36, 19)
+    et = clock()
+    z1 = et-at
+
+    sleep(1)
+
+    at = clock()
+    while any([t.undobufferentries() for t in s.turtles()]):
+        for t in s.turtles():
+            t.undo()
+    et = clock()
+    return "Laufzeit: %.3f sec" % (z1+et-at)
+
+
+if __name__ == '__main__':
+    msg = main()
+    print msg
+    mainloop()

Added: python/trunk/Demo/turtle/tdemo_yinyang.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/tdemo_yinyang.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+            tdemo_yinyang.py
+
+Another drawing suitable as a beginner's
+programming example.
+
+The small circles are drawn by the circle
+command.
+
+"""
+
+from turtle import *
+
+def yin(radius, color1, color2):
+    width(3)
+    color("black")
+    fill(True)
+    circle(radius/2., 180)
+    circle(radius, 180)
+    left(180)
+    circle(-radius/2., 180)
+    color(color1)
+    fill(True)
+    color(color2)
+    left(90)
+    up()
+    forward(radius*0.375)
+    right(90)
+    down()
+    circle(radius*0.125)
+    left(90)
+    fill(False)
+    up()
+    backward(radius*0.375)
+    down()
+    left(90)
+
+def main():
+    reset()
+    yin(200, "white", "black")
+    yin(200, "black", "white")
+    ht()
+    return "Done!"
+
+if __name__ == '__main__':
+    main()
+    mainloop()

Added: python/trunk/Demo/turtle/turtle.cfg
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/turtle.cfg	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,10 @@
+width = 800
+height = 600
+canvwidth = 1200
+canvheight = 900
+shape = arrow
+mode = standard
+resizemode = auto
+fillcolor = ""
+title = Python turtle graphics demo.
+

Added: python/trunk/Demo/turtle/turtleDemo.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/turtleDemo.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,279 @@
+#!/usr/bin/python
+import sys
+import os
+
+from Tkinter import *
+from idlelib.Percolator import Percolator
+from idlelib.ColorDelegator import ColorDelegator
+from idlelib.textView import TextViewer
+
+import turtle
+import time
+
+STARTUP = 1
+READY = 2
+RUNNING = 3
+DONE = 4
+EVENTDRIVEN = 5
+
+menufont = ("Arial", 12, NORMAL)
+btnfont = ("Arial", 12, 'bold')
+txtfont = ('Lucida Console', 8, 'normal')
+
+def getExampleEntries():
+    cwd = os.getcwd()
+    if "turtleDemo.py" not in os.listdir(cwd):
+        print "Directory of turtleDemo must be current working directory!"
+        print "But in your case this is", cwd
+        sys.exit()
+    entries1 = [entry for entry in os.listdir(cwd) if
+                     entry.startswith("tdemo_") and
+                     not entry.endswith(".pyc")]
+    entries2 = []
+    for entry in entries1:
+        if entry.endswith(".py"):
+            entries2.append(entry)
+        else:
+            path = os.path.join(cwd,entry)
+            sys.path.append(path)
+            subdir = [entry]
+            scripts = [script for script in os.listdir(path) if
+                            script.startswith("tdemo_") and
+                            script.endswith(".py")]
+            entries2.append(subdir+scripts)
+    return entries2
+
+def showDemoHelp():
+    TextViewer(demo.root, "Help on turtleDemo", "demohelp.txt")
+
+def showAboutDemo():
+    TextViewer(demo.root, "About turtleDemo", "about_turtledemo.txt")
+
+def showAboutTurtle():
+    TextViewer(demo.root, "About the new turtle module", "about_turtle.txt")
+
+class DemoWindow(object):
+
+    def __init__(self, filename=None):   #, root=None):
+        self.root = root = turtle._root = Tk()
+        root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
+
+        #################
+        self.mBar = Frame(root, relief=RAISED, borderwidth=2)
+        self.mBar.pack(fill=X)
+
+        self.ExamplesBtn = self.makeLoadDemoMenu()
+        self.OptionsBtn = self.makeHelpMenu()
+        self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn)
+
+        root.title('Python turtle-graphics examples')
+        #################
+        self.left_frame = left_frame = Frame(root)
+        self.text_frame = text_frame = Frame(left_frame)
+        self.vbar = vbar =Scrollbar(text_frame, name='vbar')
+        self.text = text = Text(text_frame,
+                                name='text', padx=5, wrap='none',
+                                width=45)
+        vbar['command'] = text.yview
+        vbar.pack(side=LEFT, fill=Y)
+        #####################
+        self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL)
+        hbar['command'] = text.xview
+        hbar.pack(side=BOTTOM, fill=X)
+        #####################
+        text['yscrollcommand'] = vbar.set
+        text.config(font=txtfont)
+        text.config(xscrollcommand=hbar.set)
+        text.pack(side=LEFT, fill=Y, expand=1)
+        #####################
+        self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf",
+                                font = ("Arial", 16, 'normal'))
+        self.output_lbl.pack(side=BOTTOM, expand=0, fill=X)
+        #####################
+        text_frame.pack(side=LEFT, fill=BOTH, expand=0)
+        left_frame.pack(side=LEFT, fill=BOTH, expand=0)
+        self.graph_frame = g_frame = Frame(root)
+
+        turtle.Screen._root = g_frame
+        turtle.Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
+        #xturtle.Screen._canvas.pack(expand=1, fill="both")
+        self.screen = _s_ = turtle.Screen()
+        self.scanvas = _s_._canvas
+        #xturtle.RawTurtle.canvases = [self.scanvas]
+        turtle.RawTurtle.screens = [_s_]
+
+        self.scanvas.pack(side=TOP, fill=BOTH, expand=1)
+
+        self.btn_frame = btn_frame = Frame(g_frame, height=100)
+        self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command=self.startDemo)
+        self.start_btn.pack(side=LEFT, fill=X, expand=1)
+        self.stop_btn = Button(btn_frame, text=" STOP ",  font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command = self.stopIt)
+        self.stop_btn.pack(side=LEFT, fill=X, expand=1)
+        self.clear_btn = Button(btn_frame, text=" CLEAR ",  font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command = self.clearCanvas)
+        self.clear_btn.pack(side=LEFT, fill=X, expand=1)
+
+        self.btn_frame.pack(side=TOP, fill=BOTH, expand=0)
+        self.graph_frame.pack(side=TOP, fill=BOTH, expand=1)
+
+        Percolator(text).insertfilter(ColorDelegator())
+        self.dirty = False
+        self.exitflag = False
+        if filename:
+            self.loadfile(filename)
+        self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED,
+                       "Choose example from menu", "black")
+        self.state = STARTUP
+
+    def _destroy(self):
+        self.root.destroy()
+        sys.exit()
+
+    def configGUI(self, menu, start, stop, clear, txt="", color="blue"):
+        self.ExamplesBtn.config(state=menu)
+
+        self.start_btn.config(state=start)
+        if start==NORMAL:
+            self.start_btn.config(bg="#d00")
+        else:
+            self.start_btn.config(bg="#fca")
+
+        self.stop_btn.config(state=stop)
+        if stop==NORMAL:
+            self.stop_btn.config(bg="#d00")
+        else:
+            self.stop_btn.config(bg="#fca")
+        self.clear_btn.config(state=clear)
+
+        self.clear_btn.config(state=clear)
+        if clear==NORMAL:
+            self.clear_btn.config(bg="#d00")
+        else:
+            self.clear_btn.config(bg="#fca")
+
+        self.output_lbl.config(text=txt, fg=color)
+
+
+    def makeLoadDemoMenu(self):
+        CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont)
+        CmdBtn.pack(side=LEFT, padx="2m")
+        CmdBtn.menu = Menu(CmdBtn)
+
+        for entry in getExampleEntries():
+            def loadexample(x):
+                def emit():
+                    self.loadfile(x)
+                return emit
+            if isinstance(entry,str):
+                CmdBtn.menu.add_command(label=entry[6:-3], underline=0, font=menufont,
+                                        command=loadexample(entry))
+            else:
+                _dir, entries = entry[0], entry[1:]
+                CmdBtn.menu.choices = Menu(CmdBtn.menu)
+                for e in entries:
+                    CmdBtn.menu.choices.add_command(label=e[6:-3], underline=0, font=menufont,
+                              command = loadexample(os.path.join(_dir,e)))
+
+                CmdBtn.menu.add_cascade(label=_dir[6:],
+                                        menu = CmdBtn.menu.choices, font=menufont )
+
+        CmdBtn['menu'] = CmdBtn.menu
+        return CmdBtn
+
+
+    def makeHelpMenu(self):
+        CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font = menufont)
+        CmdBtn.pack(side=LEFT, padx='2m')
+        CmdBtn.menu = Menu(CmdBtn)
+
+        CmdBtn.menu.add_command(label='About turtle.py', font=menufont, command=showAboutTurtle)
+        CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, command=showDemoHelp)
+        CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, command=showAboutDemo)
+
+        CmdBtn['menu'] = CmdBtn.menu
+        return CmdBtn
+
+    def refreshCanvas(self):
+        if not self.dirty: return
+        self.screen.clear()
+        #self.screen.mode("standard")
+        self.dirty=False
+
+    def loadfile(self,filename):
+        self.refreshCanvas()
+        if os.path.exists(filename) and not os.path.isdir(filename):
+            # load and display file text
+            f = open(filename,'r')
+            chars = f.read()
+            f.close()
+            self.text.delete("1.0", "end")
+            self.text.insert("1.0",chars)
+            direc, fname = os.path.split(filename)
+            self.root.title(fname[6:-3]+" - an xturtle example")
+            self.module = __import__(fname[:-3])
+            reload(self.module)
+            self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
+                           "Press start button", "red")
+            self.state = READY
+
+    def startDemo(self):
+        self.refreshCanvas()
+        self.dirty = True
+        turtle.TurtleScreen._RUNNING = True
+        self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
+                       "demo running...", "black")
+        self.screen.clear()
+        self.screen.mode("standard")
+        self.state = RUNNING
+
+        try:
+            result = self.module.main()
+            if result == "EVENTLOOP":
+                self.state = EVENTDRIVEN
+            else:
+                self.state = DONE
+        except turtle.Terminator:
+            self.state = DONE
+            result = "stopped!"
+        if self.state == DONE:
+            self.configGUI(NORMAL, NORMAL, DISABLED, NORMAL,
+                           result)
+        elif self.state == EVENTDRIVEN:
+            self.exitflag = True
+            self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
+                           "use mouse/keys or STOP", "red")
+
+    def clearCanvas(self):
+        self.refreshCanvas()
+        self.scanvas.config(cursor="")
+        self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED)
+
+    def stopIt(self):
+        if self.exitflag:
+            self.clearCanvas()
+            self.exitflag = False
+            self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
+                           "STOPPED!", "red")
+            turtle.TurtleScreen._RUNNING = False
+            #print "stopIT: exitflag = True"
+        else:
+            turtle.TurtleScreen._RUNNING = False
+            #print "stopIt: exitflag = False"
+
+if __name__ == '__main__':
+    demo = DemoWindow()
+    RUN = True
+    while RUN:
+        try:
+            print "ENTERING mainloop"
+            demo.root.mainloop()
+        except AttributeError:
+            print "CRASH!!!- WAIT A MOMENT!"
+            time.sleep(0.3)
+            print "GOING ON .."
+            demo.refreshCanvas()
+##            time.sleep(1)
+        except:
+            RUN = FALSE

Added: python/trunk/Demo/turtle/turtledemo_two_canvases.py
==============================================================================
--- (empty file)
+++ python/trunk/Demo/turtle/turtledemo_two_canvases.py	Wed Jun  4 08:29:55 2008
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER!
+"""turtle example: Using TurtleScreen and RawTurtle
+for drawing on two distinct canvases.
+"""
+from turtle import TurtleScreen, RawTurtle, TK
+
+root = TK.Tk()
+cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
+cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee")
+cv1.pack()
+cv2.pack()
+
+s1 = TurtleScreen(cv1)
+s1.bgcolor(0.85, 0.85, 1)
+s2 = TurtleScreen(cv2)
+s2.bgcolor(1, 0.85, 0.85)
+
+p = RawTurtle(s1)
+q = RawTurtle(s2)
+
+p.color("red", "white")
+p.width(3)
+q.color("blue", "black")
+q.width(3)
+
+for t in p,q:
+    t.shape("turtle")
+    t.lt(36)
+
+q.lt(180)
+
+for i in range(5):
+    for t in p, q:
+        t.fd(50)
+        t.lt(72)
+for t in p,q:
+    t.lt(54)
+    t.pu()
+    t.bk(50)
+
+## Want to get some info?
+
+print s1, s2
+print p, q
+print s1.turtles()
+print s2.turtles()
+
+TK.mainloop()

Modified: python/trunk/Doc/library/turtle.rst
==============================================================================
--- python/trunk/Doc/library/turtle.rst	(original)
+++ python/trunk/Doc/library/turtle.rst	Wed Jun  4 08:29:55 2008
@@ -1,312 +1,2002 @@
-
+========================================
 :mod:`turtle` --- Turtle graphics for Tk
 ========================================
 
-.. module:: turtle
-   :platform: Tk
-   :synopsis: An environment for turtle graphics.
-.. moduleauthor:: Guido van Rossum <guido at python.org>
-
-
-.. sectionauthor:: Moshe Zadka <moshez at zadka.site.co.il>
-
-
-The :mod:`turtle` module provides turtle graphics primitives, in both an
-object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for
-the underlying graphics, it needs a version of python installed with Tk support.
-
-The procedural interface uses a pen and a canvas which are automagically created
-when any of the functions are called.
-
-The :mod:`turtle` module defines the following functions:
-
-
-.. function:: degrees()
-
-   Set angle measurement units to degrees.
-
-
-.. function:: radians()
-
-   Set angle measurement units to radians.
-
-
-.. function:: setup(**kwargs)
-
-   Sets the size and position of the main window.  Keywords are:
-
-   * ``width``: either a size in pixels or a fraction of the screen. The default is
-     50% of the screen.
-
-   * ``height``: either a size in pixels or a fraction of the screen. The default
-     is 50% of the screen.
-
-   * ``startx``: starting position in pixels from the left edge of the screen.
-     ``None`` is the default value and  centers the window horizontally on screen.
-
-   * ``starty``: starting position in pixels from the top edge of the screen.
-     ``None`` is the default value and  centers the window vertically on screen.
-
-   Examples::
-
-      # Uses default geometry: 50% x 50% of screen, centered.
-      setup()  
-
-      # Sets window to 200x200 pixels, in upper left of screen
-      setup (width=200, height=200, startx=0, starty=0)
-
-      # Sets window to 75% of screen by 50% of screen, and centers it.
-      setup(width=.75, height=0.5, startx=None, starty=None)
-
-
-.. function:: title(title_str)
-
-   Set the window's title to *title*.
-
-
-.. function:: done()
-
-   Enters the Tk main loop.  The window will continue to  be displayed until the
-   user closes it or the process is killed.
-
-
-.. function:: reset()
-
-   Clear the screen, re-center the pen, and set variables to the default values.
-
-
-.. function:: clear()
-
-   Clear the screen.
-
-
-.. function:: tracer(flag)
-
-   Set tracing on/off (according to whether flag is true or not). Tracing means
-   line are drawn more slowly, with an animation of an arrow along the  line.
-
-
-.. function:: speed(speed)
-
-   Set the speed of the turtle. Valid values for the parameter *speed* are
-   ``'fastest'`` (no delay), ``'fast'``, (delay 5ms), ``'normal'`` (delay 10ms),
-   ``'slow'`` (delay 15ms), and ``'slowest'`` (delay 20ms).
-
-   .. versionadded:: 2.5
-
-
-.. function:: delay(delay)
-
-   Set the speed of the turtle to *delay*, which is given in ms.
-
-   .. versionadded:: 2.5
-
-
-.. function:: forward(distance)
-
-   Go forward *distance* steps.
-
-
-.. function:: backward(distance)
-
-   Go backward *distance* steps.
-
-
-.. function:: left(angle)
-
-   Turn left *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
-
-
-.. function:: right(angle)
-
-   Turn right *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
-
-
-.. function:: up()
-
-   Move the pen up --- stop drawing.
-
-
-.. function:: down()
-
-   Move the pen down --- draw when moving.
-
-
-.. function:: width(width)
-
-   Set the line width to *width*.
-
-
-.. function:: color(s)
-              color((r, g, b))
-              color(r, g, b)
-
-   Set the pen color.  In the first form, the color is specified as a Tk color
-   specification as a string.  The second form specifies the color as a tuple of
-   the RGB values, each in the range [0..1].  For the third form, the color is
-   specified giving the RGB values as three separate parameters (each in the range
-   [0..1]).
-
-
-.. function:: write(text[, move])
-
-   Write *text* at the current pen position. If *move* is true, the pen is moved to
-   the bottom-right corner of the text. By default, *move* is false.
-
-
-.. function:: fill(flag)
-
-   The complete specifications are rather complex, but the recommended  usage is:
-   call ``fill(1)`` before drawing a path you want to fill, and call ``fill(0)``
-   when you finish to draw the path.
-
-
-.. function:: begin_fill()
-
-   Switch turtle into filling mode;  Must eventually be followed by a corresponding
-   end_fill() call. Otherwise it will be ignored.
-
-   .. versionadded:: 2.5
-
-
-.. function:: end_fill()
-
-   End filling mode, and fill the shape; equivalent to ``fill(0)``.
-
-   .. versionadded:: 2.5
-
-
-.. function:: circle(radius[, extent])
-
-   Draw a circle with radius *radius* whose center-point is *radius* units left of
-   the turtle. *extent* determines which part of a circle is drawn: if not given it
-   defaults to a full circle.
-
-   If *extent* is not a full circle, one endpoint of the arc is the current pen
-   position. The arc is drawn in a counter clockwise direction if *radius* is
-   positive, otherwise in a clockwise direction.  In the process, the direction of
-   the turtle is changed by the amount of the *extent*.
-
-
-.. function:: goto(x, y)
-              goto((x, y))
-
-   Go to co-ordinates *x*, *y*.  The co-ordinates may be specified either as two
-   separate arguments or as a 2-tuple.
-
-
-.. function:: towards(x, y)
-
-   Return the angle of the line from the turtle's position to the point *x*, *y*.
-   The co-ordinates may be specified either as two separate arguments, as a
-   2-tuple, or as another pen object.
-
-   .. versionadded:: 2.5
-
-
-.. function:: heading()
-
-   Return the current orientation of the turtle.
-
-   .. versionadded:: 2.3
-
-
-.. function:: setheading(angle)
-
-   Set the orientation of the turtle to *angle*.
-
-   .. versionadded:: 2.3
-
-
-.. function:: position()
-
-   Return the current location of the turtle as an ``(x,y)`` pair.
-
-   .. versionadded:: 2.3
-
-
-.. function:: setx(x)
-
-   Set the x coordinate of the turtle to *x*.
-
-   .. versionadded:: 2.3
-
-
-.. function:: sety(y)
-
-   Set the y coordinate of the turtle to *y*.
-
-   .. versionadded:: 2.3
-
-
-.. function:: window_width()
-
-   Return the width of the canvas window.
-
-   .. versionadded:: 2.3
-
-
-.. function:: window_height()
-
-   Return the height of the canvas window.
-
-   .. versionadded:: 2.3
-
-This module also does ``from math import *``, so see the documentation for the
-:mod:`math` module for additional constants and functions useful for turtle
-graphics.
-
-
-.. function:: demo()
-
-   Exercise the module a bit.
-
-
-.. exception:: Error
-
-   Exception raised on any error caught by this module.
-
-For examples, see the code of the :func:`demo` function.
-
-This module defines the following classes:
-
-
-.. class:: Pen()
-
-   Define a pen. All above functions can be called as a methods on the given pen.
-   The constructor automatically creates a canvas do be drawn on.
-
-
-.. class:: Turtle()
-
-   Define a pen. This is essentially a synonym for ``Pen()``; :class:`Turtle` is an
-   empty subclass of :class:`Pen`.
-
-
-.. class:: RawPen(canvas)
-
-   Define a pen which draws on a canvas *canvas*. This is useful if  you want to
-   use the module to create graphics in a "real" program.
-
-
-.. _pen-rawpen-objects:
-
-Turtle, Pen and RawPen Objects
-------------------------------
-
-Most of the global functions available in the module are also available as
-methods of the :class:`Turtle`, :class:`Pen` and :class:`RawPen` classes,
-affecting only the state of the given pen.
-
-The only method which is more powerful as a method is :func:`degrees`, which
-takes an optional argument letting  you specify the number of units
-corresponding to a full circle:
-
+------------
+Introduction
+------------
+
+Turtle graphics is a popular way for introducing programming to
+kids. It was part of the original Logo programming language developed
+by Wally Feurzig and Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
+the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
+the direction it is facing, drawing a line as it moves. Give it the
+command turtle.left(25), and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+
+The module turtle.py is an extended reimplementation of turtle.py from 
+the Python standard distribution up to version Python 2.5. 
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+The turtle module provides turtle graphics primitives, in both  
+object-oriented and procedure-oriented ways. Because it uses Tkinter 
+for the underlying graphics, it needs a version of python installed 
+with Tk support. 
+
+The objectoriented interface uses essentially two+two classes:
+
+1. The TurtleScreen class defines graphics windows as a playground for the 
+   drawing turtles. It's constructor needs a Tk-Canvas or a ScrolledCanvas
+   as argument. It should be used when turtle.py is used as part of some 
+   application.
+   
+   Derived from TurtleScreen is the subclass Screen. Screen is implemented
+   as sort of singleton, so there can exist only one instance of Screen at a
+   time. It should be used when turtle.py is used as a standalone tool for 
+   doing graphics.
+   
+   All methods of TurtleScreen/Screen also exist as functions, i. e.
+   as part of the procedure-oriented interface. 
+   
+2. RawTurtle (alias: RawPen) defines Turtle-objects which draw on a 
+   TurtleScreen. It's constructor needs a Canvas/ScrolledCanvas/Turtlescreen
+   as argument, so the RawTurtle objects know where to draw.
+   
+   Derived from RawTurtle is the subclass Turtle (alias: Pen), which
+   draws on "the" Screen - instance which is automatically created,
+   if not already present. 
+   
+   All methods of RawTurtle/Turtle also exist as functions, i. e.
+   part of the procedure-oriented interface. 
+
+The procedural interface uses functions which are derived from the methods
+of the classes Screen and Turtle. They have the same names as the 
+corresponding methods. A screen-object is automativally created
+whenever a function derived form a Screen-method is called. An (unnamed)
+turtle object is automatically created whenever any of the functions 
+derived from a Turtle method is called. 
+
+To use multiple turtles an a screen one has to use the objectoriented
+interface.
+
+
+IMPORTANT NOTE!
+
+In the following documentation the argumentlist for functions is given.
+--->> Methods, of course, have the additional first argument self    <<---
+--->>                 which is omitted here.                         <<---
+
+
+--------------------------------------------------
+OVERVIEW over available Turtle and Screen methods:
+--------------------------------------------------
+
+(A) TURTLE METHODS:
+===================
+
+I.  TURTLE MOTION
+-----------------
+
+MOVE AND DRAW
+      forward | fd
+      back | bk | back
+      right | rt
+      left | lt
+      goto | setpos | setposition
+      setx
+      sety
+      setheading | seth
+      home
+      circle
+      dot
+      stamp
+      clearstamp 
+      clearstamps
+      undo
+      speed
+      
+TELL TURTLE'S STATE
+      position | pos
+      towards
+      xcor
+      ycor
+      heading
+      distance
+      
+SETTING AND MEASUREMENT
+      degrees
+      radians     
+
+II. PEN CONTROL
+---------------
+
+DRAWING STATE
+      pendown | pd | down
+      penup | pu | up
+      pensize | width
+      pen
+      isdown
+      
+COLOR CONTROL
+      color
+      pencolor
+      fillcolor
+      
+FILLING
+      fill
+      begin_fill
+      end_fill
+      
+MORE DRAWING CONTROL
+      reset
+      clear
+      write
+            
+III. TURTLE STATE
+-----------------
+
+VISIBILITY
+      showturtle | st
+      hideturtle | ht
+      isvisible
+
+APPEARANCE
+      shape
+      resizemode
+      shapesize | turtlesize  
+      settiltangle
+      tiltangle
+      tilt
+           
+IV. USING EVENTS
+----------------
+      onclick        
+      onrelease      
+      ondrag              
+
+V. SPECIAL TURTLE METHODS
+-------------------------
+      begin_poly
+      end_poly
+      get_poly
+      clone
+      getturtle | getpen   
+      getscreen
+      setundobuffer
+      undobufferentries
+      tracer
+      window_width
+      window_height
+      
+..EXCURSUS ABOUT THE USE OF COMPOUND SHAPES 
+..-----------------------------------------     
+
+(B) METHODS OF TurtleScreen/Screen
+==================================
+
+I. WINDOW CONTROL
+-----------------
+      bgcolor
+      bgpic
+      clear | clearscreen
+      reset | resetscreen
+      screensize
+      setworldcoordinates
+      
+II. ANIMATION CONTROL
+---------------------
+      delay
+      tracer
+      update
+      
+III. USING SCREEN EVENTS
+------------------------
+      listen
+      onkey
+      onclick | onscreenclick
+      ontimer
+      
+IV. SETTINGS AND SPECIAL METHODS
+--------------------------------
+      mode
+      colormode
+      getcanvas
+      getshapes
+      register_shape | addshape
+      turtles
+      window_height
+      window_width
+      
+V. METHODS SPECIFIC TO Screen
+=============================
+      bye()
+      exitonclick()
+      setup()
+      title()
+      
+---------------end of OVERVIEW ---------------------------
+
+
+
+2. METHODS OF RawTurtle/Turtle AND CORRESPONDING FUNCTIONS
+==========================================================                   
+      
+(I) TURTLE MOTION:        
+------------------
+
+(a) --- MOVE (AND DRAW)
+
+
+    .. method:: forward(distance)
+    .. method:: fd(distance)
+        distance -- a number (integer or float)
+
+        Move the turtle forward by the specified distance, in the direction
+        the turtle is headed.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.position()
+          (0.00, 0.00)
+          >>> turtle.forward(25)
+          >>> turtle.position()
+          (25.00,0.00)
+          >>> turtle.forward(-75)
+          >>> turtle.position()
+          (-50.00,0.00)    
+
+
+    .. method:: back(distance)
+    .. method:: bk(distance)
+    .. method:: backward(distance)
+        distance -- a number
+        
+        call: back(distance)
+        --or: bk(distance)
+        --or: backward(distance)
+
+        Move the turtle backward by distance ,opposite to the direction the
+        turtle is headed. Do not change the turtle's heading.
+
+        Example (for a Turtle instance named turtle)::
+
+          >>> turtle.position()
+          (0.00, 0.00)
+          >>> turtle.backward(30)
+          >>> turtle.position()
+          (-30.00, 0.00)
+    
+
+    .. method:: right(angle)
+    .. method:: rt(angle)
+        angle -- a number (integer or float)
+
+        Turn turtle right by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.heading()
+          22.0
+          >>> turtle.right(45)
+          >>> turtle.heading()
+          337.0   
+
+
+    .. method:: left(angle)
+    .. method:: lt(angle)
+        angle -- a number (integer or float)
+
+        Turn turtle left by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.heading()
+          22.0
+          >>> turtle.left(45)
+          >>> turtle.heading()
+          67.0
+
+    .. method:: goto(x, y=None)
+    .. method:: setpos(x, y=None)
+    .. method:: setposition(x, y=None)
+        x -- a number      or     a pair/vector of numbers
+        y -- a number             None
+
+        call: goto(x, y)         # two coordinates
+        --or: goto((x, y))       # a pair (tuple) of coordinates
+        --or: goto(vec)          # e.g. as returned by pos()
+
+        Move turtle to an absolute position. If the pen is down,
+        draw line. Do not change the turtle's orientation.
+
+        Example (for a Turtle instance named turtle)::
+          >>> tp = turtle.pos()
+          >>> tp
+          (0.00, 0.00)
+          >>> turtle.setpos(60,30)
+          >>> turtle.pos()
+          (60.00,30.00)
+          >>> turtle.setpos((20,80))
+          >>> turtle.pos()
+          (20.00,80.00)
+          >>> turtle.setpos(tp)
+          >>> turtle.pos()
+          (0.00,0.00)
+
+
+    .. method:: setx(x)
+        x -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, leave second coordinate
+        unchanged.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.position()
+          (0.00, 240.00)
+          >>> turtle.setx(10)
+          >>> turtle.position()
+          (10.00, 240.00)
+    
+    
+    .. method:: sety(y)
+        y -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, leave second coordinate
+        unchanged.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.position()
+          (0.00, 40.00)
+          >>> turtle.sety(-10)
+          >>> turtle.position()
+          (0.00, -10.00)
+
+    
+    .. method:: setheading(to_angle)
+    .. method:: seth(to_angle)
+        to_angle -- a number (integer or float)
+        
+        Set the orientation of the turtle to to_angle.
+        Here are some common directions in degrees:
+        
+        =================== ====================
+         standard - mode           logo-mode
+        =================== ====================
+           0 - east                0 - north
+          90 - north              90 - east
+         180 - west              180 - south
+         270 - south             270 - west
+        =================== ====================
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.setheading(90)
+          >>> turtle.heading()
+          90
+    
+    
+    .. method:: home():
+        Move turtle to the origin - coordinates (0,0) and set it's
+        heading to it's start-orientation (which depends on mode).
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.home()
+
+    
+    .. method:: circle(radius, extent=None, steps=None)
+        radius -- a number
+        extent (optional) -- a number
+        steps (optional) -- an integer
+        
+        Draw a circle with given radius. The center is radius units left
+        of the turtle; extent - an angle - determines which part of the
+        circle is drawn. If extent is not given, draw the entire circle.
+        If extent is not a full circle, one endpoint of the arc is the
+        current pen position. Draw the arc in counterclockwise direction
+        if radius is positive, otherwise in clockwise direction. Finally
+        the direction of the turtle is changed by the amount of extent.
+        
+        As the circle is approximated by an inscribed regular polygon,
+        steps determines the number of steps to use. If not given,
+        it will be calculated automatically. Maybe used to draw regular
+        polygons.
+        
+        call: circle(radius)                  # full circle
+        --or: circle(radius, extent)          # arc
+        --or: circle(radius, extent, steps)
+        --or: circle(radius, steps=6)         # 6-sided polygon
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.circle(50)
+          >>> turtle.circle(120, 180)  # semicircle
+    
+
+    .. method:: dot(size=None, *color)
+        size -- an integer >= 1 (if given)
+        color -- a colorstring or a numeric color tuple
+
+        Draw a circular dot with diameter size, using color. If size
+        is not given, the maximum of pensize+4 and 2*pensize is used.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.dot()
+          >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+    
+    
+    .. method:: stamp():
+        Stamp a copy of the turtle shape onto the canvas at the current
+        turtle position. Return a stamp_id for that stamp, which can be 
+        used to delete it by calling clearstamp(stamp_id).
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.color("blue")
+          >>> turtle.stamp()
+          13
+          >>> turtle.fd(50)                
+
+    
+    .. method:: clearstamp(stampid):
+        stampid - an integer, must be return value of previous stamp() call.
+           
+        Delete stamp with given stampid
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.color("blue")
+          >>> astamp = turtle.stamp()
+          >>> turtle.fd(50)
+          >>> turtle.clearstamp(astamp)
+
+    
+    .. method:: clearstamps(n=None):
+        n -- an integer
+
+        Delete all or first/last n of turtle's stamps.
+        If n is None, delete all of pen's stamps,
+        else if n > 0 delete first n stamps
+        else if n < 0 delete last n stamps.
+
+        Example (for a Turtle instance named turtle)::
+          >>> for i in range(8):
+          ...     turtle.stamp(); turtle.fd(30)
+          >>> turtle.clearstamps(2)
+          >>> turtle.clearstamps(-2)
+          >>> turtle.clearstamps()
+
+    
+    .. method:: undo():
+        undo (repeatedly) the last turtle action(s). Number of available 
+        undo actions is determined by the size of the undobuffer.
+
+        Example (for a Turtle instance named turtle)::
+          >>> for i in range(4):
+                  turtle.fd(50); turtle.lt(80)
+                
+          >>> for i in range(8):
+                  turtle.undo()
+
+    
+    .. method:: speed(speed=None):
+        speed -- an integer in the range 0..10 or a speedstring (see below)
+        
+        Set the turtle's speed to an integer value in the range 0 .. 10.
+        If no argument is given: return current speed.
+
+        If input is a number greater than 10 or smaller than 0.5,
+        speed is set to 0.
+        Speedstrings are mapped to speedvalues as follows:
+
+           * 'fastest' :  0
+           * 'fast'    :  10
+           * 'normal'  :  6 
+           * 'slow'    :  3
+           * 'slowest' :  1
+
+        speeds from 1 to 10 enforce increasingly faster animation of
+        line drawing and turtle turning.
+
+        Attention:
+        speed = 0 : *no* animation takes place. forward/back makes turtle jump
+        and likewise left/right make the turtle turn instantly.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.speed(3)
+    
+    
+TELL TURTLE'S STATE
+-------------------
+
+
+    .. method:: position()
+    .. method:: pos()
+        Return the turtle's current location (x,y) (as a Vec2D-vector)
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pos()
+          (0.00, 240.00)
+    
+
+    .. method:: towards(x, y=None)
+        x -- a number  or   a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None 
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Return the angle, between the line from turtle-position to position
+        specified by x, y and the turtle's start orientation. (Depends on
+        modes - "standard"/"world" or "logo")
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pos()
+          (10.00, 10.00)
+          >>> turtle.towards(0,0)
+          225.0
+    
+    
+    .. method:: xcor()
+        Return the turtle's x coordinate
+        
+        Example (for a Turtle instance named turtle)::
+          >>> reset()
+          >>> turtle.left(60)
+          >>> turtle.forward(100)
+          >>> print turtle.xcor()
+          50.0
+    
+    
+    .. method:: ycor()
+        Return the turtle's y coordinate
+        
+        Example (for a Turtle instance named turtle)::
+          >>> reset()
+          >>> turtle.left(60)
+          >>> turtle.forward(100)
+          >>> print turtle.ycor()
+          86.6025403784
+    
+    
+    .. method:: heading()
+        Return the turtle's current heading (value depends on mode).
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.left(67)
+          >>> turtle.heading()
+          67.0
+    
+    
+    .. method:: distance(x, y=None)
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None 
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+        
+        Return the distance from the turtle to (x,y) in turtle step units.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pos()
+          (0.00, 0.00)
+          >>> turtle.distance(30,40)
+          50.0
+          >>> joe = Turtle()
+          >>> joe.forward(77)
+          >>> turtle.distance(joe)
+          77.0
+    
+    
+SETTINGS FOR MEASUREMENT
+
+
+    .. method:: degrees(fullcircle=360.0)
+        fullcircle -  a number 
+
+        Set angle measurement units, i. e. set number
+        of 'degrees' for a full circle. Dafault value is
+        360 degrees. 
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.left(90)
+          >>> turtle.heading()
+          90
+          >>> turtle.degrees(400.0)  # angle measurement in gon
+          >>> turtle.heading()
+          100
+    
+    
+    .. method:: radians()
+        Set the angle measurement units to radians.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.heading()   
+          90
+          >>> turtle.radians()
+          >>> turtle.heading()
+          1.5707963267948966
+    
+
+(II) PEN CONTROL:
+-----------------
+
+DRAWING STATE
+
+
+    .. method:: pendown()
+    .. method:: pd()
+    .. method:: down()
+        Pull the pen down -- drawing when moving.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pendown()
+
+
+    .. method:: penup()
+    .. method:: pu()
+    .. method:: up()
+        Pull the pen up -- no drawing when moving.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.penup()
+
+
+    .. method:: pensize(width=None)
+    .. method:: width(width=None)
+        width -- positive number
+
+        Set the line thickness to width or return it. If resizemode is set
+        to "auto" and turtleshape is a polygon, that polygon is drawn with
+        the same line thickness. If no argument is given, the current pensize
+        is returned.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pensize()
+          1
+          turtle.pensize(10)   # from here on lines of width 10 are drawn
+    
+    
+    .. method:: pen(pen=None, **pendict)
+            pen -- a dictionary with some or all of the below listed keys.
+            **pendict -- one or more keyword-arguments with the below
+                         listed keys as keywords.
+
+        Return or set the pen's attributes in a 'pen-dictionary'
+        with the following key/value pairs:
+
+          * "shown"      :   True/False
+          * "pendown"    :   True/False
+          * "pencolor"   :   color-string or color-tuple
+          * "fillcolor"  :   color-string or color-tuple
+          * "pensize"    :   positive number
+          * "speed"      :   number in range 0..10
+          * "resizemode" :   "auto" or "user" or "noresize"
+          * "stretchfactor": (positive number, positive number)
+          * "outline"    :   positive number
+          * "tilt"       :   number
+
+        This dicionary can be used as argument for a subsequent
+        pen()-call to restore the former pen-state. Moreover one
+        or more of these attributes can be provided as keyword-arguments.
+        This can be used to set several pen attributes in one statement.
+                 
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+          >>> turtle.pen()
+          {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+          'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+          'stretchfactor': (1,1), 'speed': 3}
+          >>> penstate=turtle.pen()
+          >>> turtle.color("yellow","")
+          >>> turtle.penup()
+          >>> turtle.pen()
+          {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+          'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+          'stretchfactor': (1,1), 'speed': 3}
+          >>> p.pen(penstate, fillcolor="green")
+          >>> p.pen()
+          {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+          'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+          'stretchfactor': (1,1), 'speed': 3}
+
+
+    .. method:: isdown(self):
+        Return True if pen is down, False if it's up.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.penup()
+          >>> turtle.isdown()
+          False
+          >>> turtle.pendown()
+          >>> turtle.isdown()
+          True        
+        
+
+COLOR CONTROL
+
+
+    .. method:: color(*args)
+        Return or set pencolor and fillcolor.
+
+        Several input formats are allowed. They use 0, 1, 2, or 3 arguments
+        as follows:
+
+        - color()
+            Return the current pencolor and the current fillcolor
+            as a pair of color specification strings as are returned
+            by pencolor and fillcolor.
+        - color(colorstring), color((r,g,b)), color(r,g,b)
+            inputs as in pencolor, set both, fillcolor and pencolor,
+            to the given value.
+        - color(colorstring1, colorstring2),
+        - color((r1,g1,b1), (r2,g2,b2))
+            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
+            and analogously, if the other input format is used.
+
+        If turtleshape is a polygon, outline and interior of that polygon
+        is drawn with the newly set colors.
+        For more info see: pencolor, fillcolor
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.color('red', 'green')
+          >>> turtle.color()
+          ('red', 'green')
+          >>> colormode(255)
+          >>> color((40, 80, 120), (160, 200, 240))
+          >>> color()
+          ('#285078', '#a0c8f0')
+      
+
+    .. method:: pencolor(*args)
+        Return or set the pencolor.
+
+        Four input formats are allowed:
+        
+        - pencolor()
+          Return the current pencolor as color specification string,
+          possibly in hex-number format (see example).
+          May be used as input to another color/pencolor/fillcolor call.            
+        - pencolor(colorstring)
+          s is a Tk color specification string, such as "red" or "yellow"
+        - pencolor((r, g, b))
+          *a tuple* of r, g, and b, which represent, an RGB color,
+          and each of r, g, and b are in the range 0..colormode,
+          where colormode is either 1.0 or 255
+        - pencolor(r, g, b)
+          r, g, and b represent an RGB color, and each of r, g, and b
+          are in the range 0..colormode
+
+        If turtleshape is a polygon, the outline of that polygon is drawn
+        with the newly set pencolor.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.pencolor('brown')
+          >>> tup = (0.2, 0.8, 0.55)
+          >>> turtle.pencolor(tup)
+          >>> turtle.pencolor()
+          '#33cc8c'
+
+
+    .. method:: fillcolor(*args)
+        """ Return or set the fillcolor.
+
+        Four input formats are allowed:
+        
+        - fillcolor()
+          Return the current fillcolor as color specification string,
+          possibly in hex-number format (see example).
+          May be used as input to another color/pencolor/fillcolor call.            
+        - fillcolor(colorstring)
+          s is a Tk color specification string, such as "red" or "yellow"
+        - fillcolor((r, g, b))
+          *a tuple* of r, g, and b, which represent, an RGB color,
+          and each of r, g, and b are in the range 0..colormode,
+          where colormode is either 1.0 or 255
+        - fillcolor(r, g, b)
+          r, g, and b represent an RGB color, and each of r, g, and b
+          are in the range 0..colormode
+
+        If turtleshape is a polygon, the interior of that polygon is drawn
+        with the newly set fillcolor.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.fillcolor('violet')
+          >>> col = turtle.pencolor()
+          >>> turtle.fillcolor(col)
+          >>> turtle.fillcolor(0, .5, 0)
+
+
+        See also: Screen method colormode()
+
+
+FILLING
+
+
+    .. method:: fill(flag)
+        flag -- True/False (or 1/0 respectively)
+
+        Call fill(True) before drawing the shape you want to fill,
+        and  fill(False) when done. When used without argument: return 
+        fillstate (True if filling, False else).
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.fill(True)
+          >>> for _ in range(3):
+          ...    turtle.forward(100)
+          ...    turtle.left(120)
+          ...
+          >>> turtle.fill(False)
+
+
+    .. method:: begin_fill()
+        Called just before drawing a shape to be filled.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.color("black", "red")
+          >>> turtle.begin_fill()
+          >>> turtle.circle(60)
+          >>> turtle.end_fill()
+
+
+    .. method:: end_fill()
+        Fill the shape drawn after the call begin_fill().
+        
+        Example: See begin_fill()
+
+
+MORE DRAWING CONTROL
+
+
+    .. method:: reset()
+        Delete the turtle's drawings from the screen, re-center the turtle
+        and set variables to the default values.      
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.position()
+          (0.00,-22.00)
+          >>> turtle.heading()
+          100.0
+          >>> turtle.reset()
+          >>> turtle.position()
+          (0.00,0.00)
+          >>> turtle.heading()
+          0.0
+
+
+    .. method:: clear()
+        Delete the turtle's drawings from the screen. Do not move turtle.
+        State and position of the turtle as well as drawings of other
+        turtles are not affected.
+
+        Examples (for a Turtle instance named turtle):
+          >>> turtle.clear()
+    
+    
+    .. method:: write(arg, move=False, align='left', font=('Arial', 8, 'normal'))
+        arg -- info, which is to be written to the TurtleScreen
+        move (optional) -- True/False
+        align (optional) -- one of the strings "left", "center" or right"
+        font (optional) -- a triple (fontname, fontsize, fonttype)
+
+        Write text - the string representation of arg - at the current
+        turtle position according to align ("left", "center" or right")
+        and with the given font.
+        If move is True, the pen is moved to the bottom-right corner
+        of the text. By default, move is False.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.write('Home = ', True, align="center")
+          >>> turtle.write((0,0), True)
+    
+
+TURTLE STATE:
+-------------
+
+VISIBILITY
+
+
+    .. method:: showturtle()
+    .. method:: st()
+        Makes the turtle visible.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.hideturtle()
+          >>> turtle.showturtle()
+    
+    
+    .. method:: hideturtle()
+    .. method:: ht()
+        Makes the turtle invisible.
+        It's a good idea to do this while you're in the middle of  
+        doing some complex drawing, because hiding the turtle speeds 
+        up the drawing observably.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.hideturtle()
+
+
+    .. method:: isvisible(self):
+        Return True if the Turtle is shown, False if it's hidden.
+        
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.hideturtle()
+          >>> print turtle.isvisible():
+          False
+
+
+APPEARANCE
+
+
+    .. method:: shape(name=None)
+        name -- a string, which is a valid shapename
+
+        Set turtle shape to shape with given name or, if name is not given,
+        return name of current shape.
+        Shape with name must exist in the TurtleScreen's shape dictionary.
+        Initially there are the following polygon shapes:
+        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
+        To learn about how to deal with shapes see Screen-method register_shape.
+
+        Example (for a Turtle instance named turtle)::
+          >>> turtle.shape()
+          'arrow'
+          >>> turtle.shape("turtle")
+          >>> turtle.shape()
+          'turtle'
+
+
+    .. method:: resizemode(rmode=None)
+        rmode -- one of the strings "auto", "user", "noresize"
+        
+        Set resizemode to one of the values: "auto", "user", "noresize".
+        If rmode is not given, return current resizemode.
+        Different resizemodes have the following effects:
+
+          - "auto" adapts the appearance of the turtle
+                   corresponding to the value of pensize.
+          - "user" adapts the appearance of the turtle according to the
+                   values of stretchfactor and outlinewidth (outline),
+                   which are set by shapesize()
+          - "noresize" no adaption of the turtle's appearance takes place.
+        
+        resizemode("user") is called by a shapesize when used with arguments.
+
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.resizemode("noresize")
+          >>> turtle.resizemode()
+          'noresize'
+
+
+    .. method:: shapesize(stretch_wid=None, stretch_len=None, outline=None):    
+        stretch_wid -- positive number
+        stretch_len -- positive number
+        outline -- positive number
+        
+        Return or set the pen's attributes x/y-stretchfactors and/or outline.
+        Set resizemode to "user".
+        If and only if resizemode is set to "user", the turtle will be 
+        displayed stretched according to its stretchfactors:
+        stretch_wid is stretchfactor perpendicular to it's orientation,
+        stretch_len is stretchfactor in direction of it's orientation,
+        outline determines the width of the shapes's outline.
+
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.resizemode("user")
+          >>> turtle.shapesize(5, 5, 12)
+          >>> turtle.shapesize(outline=8)
+    
+    
+    .. method:: tilt(angle)
+        angle - a number
+
+        Rotate the turtleshape by angle from its current tilt-angle,
+        but do NOT change the turtle's heading (direction of movement).
+              
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.shape("circle")
+          >>> turtle.shapesize(5,2)
+          >>> turtle.tilt(30)
+          >>> turtle.fd(50)
+          >>> turtle.tilt(30)
+          >>> turtle.fd(50)
+      
+        
+    .. method:: settiltangle(angle)
+        angle -- number
+
+        Rotate the turtleshape to point in the direction specified by angle,
+        regardless of its current tilt-angle. DO NOT change the turtle's
+        heading (direction of movement).
+              
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.shape("circle")
+          >>> turtle.shapesize(5,2)
+          >>> turtle.settiltangle(45)
+          >>> stamp()
+          >>> turtle.fd(50)
+          >>> turtle.settiltangle(-45)
+          >>> stamp()
+          >>> turtle.fd(50)
+
+
+    .. method:: tiltangle()
+        Return the current tilt-angle, i. e. the angle between the
+        orientation of the turtleshape and the heading of the turtle
+        (it's direction of movement).
+                      
+        Examples (for a Turtle instance named turtle)::
+          >>> turtle.shape("circle")
+          >>> turtle.shapesize(5,2)
+          >>> turtle.tilt(45)
+          >>> turtle.tiltangle()
+          45 
+
+
+IV. USING EVENTS
+----------------
+
+
+    .. method:: onclick(fun, btn=1, add=None)  
+        fun --  a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
+
+        Bind fun to mouse-click event on this turtle on canvas.
+        If fun is None, existing bindings are removed.
+        Example for the anonymous turtle, i. e. the procedural way::
+
+          >>> def turn(x, y):
+                  left(360)
+                
+          >>> onclick(turn) # Now clicking into the turtle will turn it.
+          >>> onclick(None)  # event-binding will be removed
+    
+    
+    .. method:: onrelease(fun, btn=1, add=None):
+        """
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
+
+        Bind fun to mouse-button-release event on this turtle on canvas.
+        If fun is None, existing bindings are removed.
+
+        Example (for a MyTurtle instance named turtle):
+          >>> class MyTurtle(Turtle):
+          ...     def glow(self,x,y):
+          ...         self.fillcolor("red")
+          ...     def unglow(self,x,y):
+          ...         self.fillcolor("")
+          ...             
+          >>> turtle = MyTurtle()
+          >>> turtle.onclick(turtle.glow)
+          >>> turtle.onrelease(turtle.unglow)
+          ### clicking on turtle turns fillcolor red,
+          ### unclicking turns it to transparent.
+    
+    
+    .. method:: ondrag(fun, btn=1, add=None):
+        fun -- a function with two arguments, to which will be assigned
+               the coordinates of the clicked point on the canvas.
+        num -- number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
+
+        Bind fun to mouse-move event on this turtle on canvas.
+        If fun is None, existing bindings are removed.
+
+        Remark: Every sequence of mouse-move-events on a turtle is preceded 
+        by a mouse-click event on that turtle.
+        If fun is None, existing bindings are removed.
+
+        Example (for a Turtle instance named turtle):
+          >>> turtle.ondrag(turtle.goto)
+          ### Subsequently clicking and dragging a Turtle will move it across 
+          ### the screen thereby producing handdrawings (if pen is down).
+    
+    
+V. SPECIAL TURTLE METHODS
+--------------------------
+
+
+    .. method:: begin_poly():
+        Start recording the vertices of a polygon. Current turtle position
+        is first vertex of polygon.
+
+        Example (for a Turtle instance named turtle):
+          >>> turtle.begin_poly()
+
+
+    .. method:: end_poly():
+        Stop recording the vertices of a polygon. Current turtle position is
+        last vertex of polygon. This will be connected with the first vertex.
+
+        Example (for a Turtle instance named turtle):
+          >>> turtle.end_poly()
+
+
+    .. method:: get_poly():
+        Return the lastly recorded polygon.
+
+        Example (for a Turtle instance named turtle):
+          >>> p = turtle.get_poly()
+          >>> turtle.register_shape("myFavouriteShape", p)
+
+
+    .. method:: clone():
+        Create and return a clone of the turtle with same position, heading
+        and turtle properties.
+
+        Example (for a Turtle instance named mick):
+        mick = Turtle()
+        joe = mick.clone()
+
+
+    .. method:: getturtle():
+        Return the Turtleobject itself.
+        Only reasonable use: as a function to return the 'anonymous turtle':
+        
+        Example:
+          >>> pet = getturtle()
+          >>> pet.fd(50)
+          >>> pet
+          <turtle.Turtle object at 0x01417350>
+          >>> turtles()
+          [<turtle.Turtle object at 0x01417350>]
+
+
+    .. method:: getscreen():
+        Return the TurtleScreen object, the turtle is drawing  on.
+        So TurtleScreen-methods can be called for that object.
+
+        Example (for a Turtle instance named turtle):
+          >>> ts = turtle.getscreen()
+          >>> ts
+          <turtle.Screen object at 0x01417710>
+          >>> ts.bgcolor("pink")
+
+
+    .. method:: def setundobuffer(size):
+        size -- an integer or None
+
+        Set or disable undobuffer.
+        If size is an integer an empty undobuffer of given size is installed.
+        Size gives the maximum number of turtle-actions that can be undone
+        by the undo() method/function.
+        If size is None, no undobuffer is present. 
+
+        Example (for a Turtle instance named turtle):
+          >>> turtle.setundobuffer(42)        
+
+
+    .. method:: undobufferentries():
+        """Return count of entries in the undobuffer.
+
+        Example (for a Turtle instance named turtle):
+          >>> while undobufferentries():
+          ...     undo()
+
+
+    .. method:: tracer(flag=None, delay=None)
+        A replica of the corresponding TurtleScreen-method
+        *Deprecated since Python 2.6*  (as RawTurtle method)
+
+
+    .. method:: window_width()
+    .. method:: window_height()
+        Both are replicas of the corresponding TurtleScreen-methods
+        *Deprecated since Python 2.6*  (as RawTurtle methods)
+      
+
+EXCURSUS ABOUT THE USE OF COMPOUND SHAPES
+-----------------------------------------
+
+To use compound turtle shapes, which consist of several polygons
+of different color, you must use the helper class Shape 
+explicitely as described below:
+
+    1. Create an empty Shape object of type compound
+    2. Add as many components to this object as desired, 
+       using the addcomponent() method:
+       
+    .. method:: addcomponent(self, poly, fill, outline=None)
+        poly -- a polygon
+        fill -- a color, the poly will be filled with
+        outline -- a color for the poly's outline (if given)
+    
+So it goes like this::
+
+  >>> s = Shape("compound")
+  >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
+  >>> s.addcomponent(poly1, "red", "blue")
+  >>> poly2 = ((0,0),(10,-5),(-10,-5))
+  >>> s.addcomponent(poly2, "blue", "red")
+
+Now add Shape s to the Screen's shapelist ...
+.. and use it::
+
+  >>> register_shape("myshape", s)
+  >>> shape("myshape")
+       
+
+NOTE 1: addcomponent() is a method of class Shape (not of
+Turtle nor Screen) and thus there is NO FUNCTION of the same name. 
+
+NOTE 2: class Shape is used internally by the register_shape method
+in different ways. 
+
+The application programmer has to deal with the Shape class 
+ONLY when using compound shapes like shown above!
+
+NOTE 3: A short description of the class Shape is in section 4.
+
+    
+     
+3. METHODS OF TurtleScreen/Screen AND CORRESPONDING FUNCTIONS
+=============================================================
+
+
+WINDOW CONTROL
+--------------
+
+
+    .. method:: bgcolor(*args)
+        args -- a color string or three numbers in the range 0..colormode 
+                or a 3-tuple of such numbers.
+
+        Set or return backgroundcolor of the TurtleScreen.
+        
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.bgcolor("orange")
+          >>> screen.bgcolor()
+          'orange'
+          >>> screen.bgcolor(0.5,0,0.5)
+          >>> screen.bgcolor()
+          '#800080'        
+
+
+    .. method:: bgpic(picname=None)
+        picname -- a string, name of a gif-file or "nopic".
+        
+        Set background image or return name of current backgroundimage.
+        If picname is a filename, set the corresponing image as background.
+        If picname is "nopic", delete backgroundimage, if present. 
+        If picname is None, return the filename of the current backgroundimage.
+        
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.bgpic()
+          'nopic'
+          >>> screen.bgpic("landscape.gif")
+          >>> screen.bgpic()
+          'landscape.gif'
+
+
+    .. method:: clear()
+    .. method:: clearscreen()
+        Delete all drawings and all turtles from the TurtleScreen.
+        Reset empty TurtleScreen to it's initial state: white background,
+        no backgroundimage, no eventbindings and tracing on.
+
+        Example (for a TurtleScreen instance named screen):
+        screen.clear()
+
+        *Note*: this method is only available as the function named
+        clearscreen(). (The function clear() is another one derived from
+        the Turtle-method clear()!).
+
+
+    .. method:: reset()
+    .. method:: resetscreen()
+        Reset all Turtles on the Screen to their initial state.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.reset()
+
+        *Note*: this method is pnly available as the function named
+        resetscreen(). (The function reset() is another one derived from
+        the Turtle-method reset()!).
+
+
+    .. method:: screensize(canvwidth=None, canvheight=None, bg=None):
+        canvwidth -- positive integer, new width of canvas in pixels
+        canvheight -- positive integer, new height of canvas in pixels
+        bg -- colorstring or color-tupel, new backgroundcolor
+        
+        If no arguments are given, return current (canvaswidth, canvasheight)
+        Resize the canvas, the turtles are drawing on.
+        Do not alter the drawing window. To observe hidden parts of
+        the canvas use the scrollbars. (So one can make visible those 
+        parts of a drawing, which were outside the canvas before!)
+
+        Example (for a Turtle instance named turtle):
+          >>> turtle.screensize(2000,1500)
+          ### e. g. to search for an erroneously escaped turtle ;-)
+        
+        
+    .. method:: setworldcoordinates(llx, lly, urx, ury):
+        llx -- a number, x-coordinate of lower left corner of canvas
+        lly -- a number, y-coordinate of lower left corner of canvas
+        urx -- a number, x-coordinate of upper right corner of canvas
+        ury -- a number, y-coordinate of upper right corner of canvas
+
+        Set up user coodinate-system and switch to mode 'world' if necessary.
+        This performs a screen.reset. If mode 'world' is already active,
+        all drawings are redrawn according to the new coordinates.
+
+        But *ATTENTION*: in user-defined coordinatesystems angles may appear
+        distorted. (see Screen.mode())
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.reset()
+          >>> screen.setworldcoordinates(-50,-7.5,50,7.5)
+          >>> for _ in range(72):
+          ...     left(10)
+          ...
+          >>> for _ in range(8):
+          ...     left(45); fd(2)   # a regular octogon
+           
+           
+ANIMATION CONTROL
+-----------------
+
+
+    .. method:: delay(delay=None):
+        delay -- positive integer
+        
+        Set or return the drawing delay in milliseconds. (This is sort of
+        time interval between two consecutived canvas updates.) The longer 
+        the drawing delay, the slower the animation.
+
+        Optional argument:
+        Example (for a TurtleScreen instance named screen)::
+
+          >>> screen.delay(15)
+          >>> screen.delay()
+          15
+
+
+    .. method:: tracer(n=None, delay=None):
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+        
+        Turn turtle animation on/off and set delay for update drawings.
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second argument sets delay value (see delay())
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.tracer(8, 25)
+          >>> dist = 2
+          >>> for i in range(200):
+          ...     fd(dist)
+          ...     rt(90)
+          ...     dist += 2
+                
+                
+    .. method:: update():
+        Perform a TurtleScreen update. To be used, when tracer is turned
+        off. 
+        
+    See also RawTurtle/Turtle - method speed()
+           
+
+USING SCREEN EVENTS
+-------------------
+
+
+    .. method:: listen(xdummy=None, ydummy=None):
+        """Set focus on TurtleScreen (in order to collect key-events)
+        Dummy arguments are provided in order to be able to pass listen 
+        to the onclick method.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.listen()        
+
+
+    .. method:: onkey(fun, key):
+        fun -- a function with no arguments or None
+        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+        Bind fun to key-release event of key. If fun is None, event-bindings
+        are removed.
+        Remark: in order to be able to register key-events, TurtleScreen
+        must have focus. (See method listen.)
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle)::
+
+          >>> def f():
+          ...     fd(50)
+          ...     lt(60)
+          ...
+          >>> screen.onkey(f, "Up")
+          >>> screen.listen()
+        
+        
+    .. method:: onclick(fun, btn=1, add=None):
+    .. method:: onscreenclick(fun, btn=1, add=None):
+        fun --  a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas - or None.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
+
+        Example (for a TurtleScreen instance named screen and a Turtle instance
+        named turtle)::
+
+          >>> screen.onclick(turtle.goto)
+          ### Subsequently clicking into the TurtleScreen will
+          ### make the turtle move to the clicked point.
+          >>> screen.onclick(None)
+        
+          ### event-binding will be removed
+
+        *Note*: this method is only available as the function named
+        onscreenclick(). (The function onclick() is a different one derived 
+        from the Turtle-method onclick()!).
+
+
+    .. method:: ontimer(fun, t=0):
+        fun -- a function with no arguments.
+        t -- a number >= 0
+
+        Install a timer, which calls fun after t milliseconds.
+
+        Example (for a TurtleScreen instance named screen):
+
+          >>> running = True
+          >>> def f():
+                  if running:
+                      fd(50)
+                      lt(60)
+                      screen.ontimer(f, 250)
+          >>> f()   ### makes the turtle marching around
+          >>> running = False           
+
+
+SETTINGS AND SPECIAL METHODS
+
+
+    .. method:: mode(mode=None):
+        mode -- on of the strings 'standard', 'logo' or 'world'
+        
+        Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
+        If mode is not given, current mode is returned.
+
+        Mode 'standard' is compatible with old turtle.py.
+        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
+        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
+        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
+
+         ============ ========================= ===================
+             Mode      Initial turtle heading     positive angles
+         ============ ========================= ===================
+          'standard'    to the right (east)       counterclockwise
+            'logo'        upward    (north)         clockwise
+         ============ ========================= ===================
+
+        Examples::
+          >>> mode('logo')   # resets turtle heading to north
+          >>> mode()
+          'logo'
+
+
+    .. method:: colormode(cmode=None):
+        cmode -- one of the values 1.0 or 255
+
+        """Return the colormode or set it to 1.0 or 255.
+        Subsequently r, g, b values of colortriples have to be in 
+        range 0..cmode.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.colormode()
+          1.0
+          >>> screen.colormode(255)
+          >>> turtle.pencolor(240,160,80)
+
+
+    .. method:: getcanvas():
+        Return the Canvas of this TurtleScreen. Useful for insiders, who
+        know what to do with a Tkinter-Canvas ;-)
+
+        Example (for a Screen instance named screen):
+          >>> cv = screen.getcanvas()
+          >>> cv
+          <turtle.ScrolledCanvas instance at 0x010742D8>
+
+
+    .. method:: getshapes():
+        """Return a list of names of all currently available turtle shapes.
+        
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.getshapes()
+          ['arrow', 'blank', 'circle', ... , 'turtle']
+
+
+    .. method:: register_shape(name, shape=None)
+    .. method:: addshape(name, shape=None)
+        Arguments:
+        (1) name is the name of a gif-file and shape is None.
+            Installs the corresponding image shape.
+            !! Image-shapes DO NOT rotate when turning the turtle,
+            !! so they do not display the heading of the turtle!   
+        (2) name is an arbitrary string and shape is a tuple
+            of pairs of coordinates. Installs the corresponding
+            polygon shape
+        (3) name is an arbitrary string and shape is a
+            (compound) Shape object. Installs the corresponding
+            compound shape. (See class Shape.)
+        
+        Adds a turtle shape to TurtleScreen's shapelist. Only thusly
+        registered shapes can be used by issueing the command shape(shapename).
+
+        call: register_shape("turtle.gif")
+        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
+        
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
+
+
+    .. method:: turtles():
+        Return the list of turtles on the screen.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> for turtle in screen.turtles()
+          ...     turtle.color("red")
+
+
+    .. method:: window_height():
+        Return the height of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.window_height()
+          480
+
+
+    .. method:: window_width():
+        Return the width of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.window_width()
+          640
+        
+
+METHODS SPECIFIC TO Screen, not inherited from TurtleScreen
+-----------------------------------------------------------
+
+
+    .. method:: bye():
+        """Shut the turtlegraphics window.
+
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
+
+        Example (for a TurtleScreen instance named screen):
+          >>> screen.bye()
+
+
+    .. method:: exitonclick():
+        Bind bye() method to mouseclick on TurtleScreen.
+        If "using_IDLE" - value in configuration dictionary is False
+        (default value), enter mainloop.
+        Remark: If IDLE with -n switch (no subprocess) is used, this value 
+        should be set to True in turtle.cfg. In this case IDLE's own mainloop
+        is active also for the client script.
+
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
+
+        Example (for a Screen instance named screen):
+          >>> screen.exitonclick()
+
+
+    .. method:: setup(width=_CFG["width"], height=_CFG["height"],
+          startx=_CFG["leftright"], starty=_CFG["topbottom"]):
+        Set the size and position of the main window. 
+        Default values of arguments are stored in the configuration dicionary
+        and can be changed via a turtle.cfg file.
+        
+        width -- as integer a size in pixels, as float a fraction of the screen.
+          Default is 50% of screen.
+        height -- as integer the height in pixels, as float a fraction of the
+          screen. Default is 75% of screen.
+        startx -- if positive, starting position in pixels from the left
+          edge of the screen, if negative from the right edge
+          Default, startx=None is to center window horizontally.
+        starty -- if positive, starting position in pixels from the top
+          edge of the screen, if negative from the bottom edge
+          Default, starty=None is to center window vertically.
+
+        Examples (for a Screen instance named screen)::
+        >>> screen.setup (width=200, height=200, startx=0, starty=0)
+        # sets window to 200x200 pixels, in upper left of screen
+
+        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+        # sets window to 75% of screen by 50% of screen and centers
+
+      
+    .. method:: title(titlestring):
+        titlestring -- a string, to appear in the titlebar of the
+                       turtle graphics window.
+
+        Set title of turtle-window to titlestring
+
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
+
+        Example (for a Screen instance named screen):
+          >>> screen.title("Welcome to the turtle-zoo!")
+
+
+
+4. THE PUBLIC CLASSES of the module turtle.py 
+=============================================
+
+
+class RawTurtle(canvas):
+    canvas -- a Tkinter-Canvas, a ScrolledCanvas or a TurtleScreen
+    
+    Alias: RawPen
+    
+    Define a turtle.
+    A description of the methods follows below. All methods are also
+    available as functions (to control some anonymous turtle) thus
+    providing a procedural interface to turtlegraphics
+    
+class Turtle()
+    Subclass of RawTurtle, has the same interface with the additional
+    property, that Turtle instances draw on a default Screen object,
+    which is created automatically, when needed for the first time.
+    
+class TurtleScreen(cv)
+    cv -- a Tkinter-Canvas
+    Provides screen oriented methods like setbg etc.
+    A description of the methods follows below.
+    
+class Screen()
+    Subclass of TurtleScreen, with four methods added.
+    All methods are also available as functions to conrtol a unique 
+    Screen instance thus belonging to the procedural interface 
+    to turtlegraphics. This Screen instance is automatically created
+    when needed for the first time.
+
+class ScrolledCavas(master)
+    master -- some Tkinter widget to contain the ScrolledCanvas, i.e.
+    a Tkinter-canvas with scrollbars added.
+    Used by class Screen, which thus provides automatically a 
+    ScrolledCanvas as playground for the turtles.
+
+class Shape(type\_, data)
+    type --- one of the strings "polygon", "image", "compound"
+
+    Data structure modeling shapes.
+    The pair type\_, data must be as follows:
+    
+         type\_                  data
+
+       "polygon"     a polygon-tuple, i. e. 
+                     a tuple of pairs of coordinates
+       
+       "image"       an image  (in this form only used internally!)
+       
+       "compound"    None
+                     A compund shape has to be constructed using
+                     the addcomponent method
+                     
+    addcomponent(self, poly, fill, outline=None)
+        poly -- polygon, i. e. a tuple of pairs of numbers.
+        fill -- the fillcolor of the component,
+        outline -- the outline color of the component.
+
+        Example:
+          >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+          >>> s = Shape("compound")
+          >>> s.addcomponent(poly, "red", "blue")
+          ### .. add more components and then use register_shape()
+           
+     See EXCURSUS ABOUT THE USE OF COMPOUND SHAPES
+                         
+
+class Vec2D(x, y):
+    A two-dimensional vector class, used as a helper class
+    for implementing turtle graphics.
+    May be useful for turtle graphics programs also.
+    Derived from tuple, so a vector is a tuple!
+
+    Provides (for a, b vectors, k number):
+
+     * a+b vector addition
+     * a-b vector subtraction
+     * a*b inner product
+     * k*a and a*k multiplication with scalar
+     * \|a\| absolute value of a
+     * a.rotate(angle) rotation      
+
+
+    
+V. HELP AND CONFIGURATION
+=========================
+
+This section contains subsections on:
+
+- how to use help
+- how to prepare  and use translations of the online-help 
+  into other languages
+- how to configure the appearance of the graphics window and
+  the turtles at startup
+
+
+HOW TO USE HELP:
+----------------
+
+The public methods of the Screen and Turtle classes are documented
+extensively via docstrings. So these can be used as online-help
+via the Python help facilities:
+
+- When using IDLE, tooltips show the signatures and first lines of
+  the docstrings of typed in function-/method calls.
+
+- calling help on methods or functions display the docstrings. 
+  Examples::
+  
+    >>> help(Screen.bgcolor)
+    Help on method bgcolor in module turtle:
+    
+    bgcolor(self, *args) unbound turtle.Screen method
+        Set or return backgroundcolor of the TurtleScreen.
+        
+        Arguments (if given): a color string or three numbers
+        in the range 0..colormode or a 3-tuple of such numbers.
+        
+        Example (for a TurtleScreen instance named screen)::
+    
+          >>> screen.bgcolor("orange")
+          >>> screen.bgcolor()
+          'orange'
+          >>> screen.bgcolor(0.5,0,0.5)
+          >>> screen.bgcolor()
+          '#800080'
+    
+    >>> help(Turtle.penup)
+    Help on method penup in module turtle:
+    
+    penup(self) unbound turtle.Turtle method
+        Pull the pen up -- no drawing when moving.
+        
+        Aliases: penup | pu | up
+        
+        No argument
+        
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+
+The docstrings of the functions which are derived from methods have
+a modified form::
+
+    >>> help(bgcolor)
+    Help on function bgcolor in module turtle:
+    
+    bgcolor(*args)
+        Set or return backgroundcolor of the TurtleScreen.
+        
+        Arguments (if given): a color string or three numbers
+        in the range 0..colormode or a 3-tuple of such numbers.
+        
+        Example::
+    
+          >>> bgcolor("orange")
+          >>> bgcolor()
+          'orange'
+          >>> bgcolor(0.5,0,0.5)
+          >>> bgcolor()
+          '#800080'
+    
+    >>> help(penup)
+    Help on function penup in module turtle:
+    
+    penup()
+        Pull the pen up -- no drawing when moving.
+        
+        Aliases: penup | pu | up
+        
+        No argument
+        
+        Example:
+        >>> penup()
+
+These modified docstrings are created automatically together with the
+function definitions that are derived from the methods at import time.
+
+
+TRANSLATION OF DOCSTRINGS INTO DIFFERENT LANGUAGES
+--------------------------------------------------
+
+There is a utility to create a dictionary the keys of which are the 
+method names and the values of which are the docstrings of the public 
+methods of the classes Screen and Turtle.
+
+write_docstringdict(filename="turtle_docstringdict"):
+    filename -- a string, used as filename
+
+    Create and write docstring-dictionary to a Python script
+    with the given filename.
+    This function has to be called explicitely, (it is not used by the 
+    turtle-graphics classes). The docstring dictionary will be written 
+    to the Python script <filname>.py  It is intended to serve as a 
+    template for translation of the docstrings into different languages.
+
+If you (or your students) want to use turtle.py with online help in 
+your native language. You have to translate the docstrings and save
+the resulting file as e.g. turtle_docstringdict_german.py
+
+If you have an appropriate entry in your turtle.cfg file this dictionary
+will be read in at import time and will replace the original English
+docstrings.
+
+At the time of this writing there exist docstring_dicts in German
+and in Italian. (Requests please to glingl at aon.at)
+
+ 
+ 
+HOW TO CONFIGURE SCREEN AND TURTLES
+-----------------------------------
+
+The built-in default configuration mimics the appearance and 
+behaviour of the old turtle module in order to retain best possible
+compatibility with it. 
+
+If you want to use a different configuration which reflects 
+better the features of this module or which fits better to
+your needs, e. g. for use in a classroom, you can prepare
+a configuration file turtle.cfg which will be read at import
+time and modify the configuration according to it's settings.
+
+The built in configuration would correspond to the following
+turtle.cfg:
+
+width = 0.5
+height = 0.75
+leftright = None
+topbottom = None
+canvwidth = 400
+canvheight = 300
+mode = standard
+colormode = 1.0
+delay = 10                 
+undobuffersize = 1000
+shape = classic
+pencolor = black
+fillcolor = black
+resizemode = noresize
+visible = True
+language = english
+exampleturtle = turtle
+examplescreen = screen
+title = Python Turtle Graphics
+using_IDLE = False
+
+Short explanation of selected entries:
+
+- The first four lines correspond to the arguments of the 
+  Screen.setup method
+- Line 5 and 6 correspond to the arguments of the Method
+  Screen.screensize
+- shape can be any of the built-in shapes, e.g: arrow, turtle,
+  etc. For more info try help(shape)
+- if you want to use no fillcolor (i. e. turtle transparent),
+  you have to write:
+  fillcolor = ""
+  (All not empty strings must not have quotes in the cfg-file!)
+- if you want to reflect the turtle its state, you have to use
+  resizemode = auto
+- if you set, e. g.:  language = italian
+  the docstringdict turtle_docstringdict_italian.py will be
+  loaded at import time (if present on the import path, e.g. in
+  the same directory as turtle.py
+- the entries exampleturtle  and examplescreen define the names
+  of these objects as they occur in the docstrings. The 
+  transformation of method-docstrings to function-docstrings 
+  will delete these names from the docstrings. (See examples in 
+  section on HELP)
+- using_IDLE  Set this to True if you regularly work with IDLE
+  and it's -n - switch. ("No subprocess") This will prevent 
+  exitonclick to enter the mainloop.
+  
+There can be a turtle.cfg file in the directory where turtle.py
+is stored and an additional one in the currentworkingdirectory.
+The latter will override the settings of the first one.
+
+The turtledemo directory contains a turtle.cfg file. If you 
+study it as an example and see its effects when running the
+demos (preferably not from within the demo-viewer). 
+
+      
+VI. Demo scripts      
+================      
+      
+There is a set of demo scripts in the turtledemo directory
+located  here ... 
+
+           #####  please complete  info about path  ########################
+           
+It contains:
+
+- a set of 15 demo scripts demonstrating differet features
+  of the new module turtle.py
+- a Demo-Viewer turtleDemo.py which can be used to view
+  the sourcecode of the scripts and run them at the same time
+  14 of the examples can be accessed via the Examples Menu.
+  All of them can also be run standalone.
+- The example  turtledemo_two_canvases.py demonstrates the
+  simultaneous use of two canvases with the turtle module.
+  Therefor it only can be run standalone.
+- There is a turtle.cfg file in this directory, which also
+  serves as an example for how to write and use such files.
+  
+The demoscripts are:
+
++----------------+------------------------------+-----------------------+
+|Name            |           description        |       features        |
++----------------+------------------------------+-----------------------+
+|bytedesign      |   complex classical          |     tracer, delay     |
+|                |   turtlegraphics pattern     |     update            |
++----------------+------------------------------+-----------------------+
+|chaos           |  graphs verhust dynamics,    |    worldcoordinates   |
+|                |  proofs that you must not    |                       |
+|                |  trust computers computations|                       |
++----------------+------------------------------+-----------------------+
+|clock           |   analog clock showing time  |    turtles as clock's |
+|                |   of your computer           |    hands, ontimer     |
++----------------+------------------------------+-----------------------+
+|colormixer      |     experiment with r, g, b  |         ondrag        |
++----------------+------------------------------+-----------------------+
+|fractalcurves   |          Hilbert & Koch      |       recursion       |
++----------------+------------------------------+-----------------------+
+|lindenmayer     |        ethnomathematics      |      L-System         |
+|                |        (indian kolams)       |                       |
++----------------+------------------------------+-----------------------+
+|minimal_hanoi   |      Towers of Hanoi         |   Rectangular Turtles |
+|                |                              |   as Hanoi-Discs      |
+|                |                              |   (shape, shapesize)  |
++----------------+------------------------------+-----------------------+
+|paint           |      super minimalistic      |      onclick          |
+|                |      drawing program         |                       |
++----------------+------------------------------+-----------------------+
+|peace           |          elementary          |   turtle: appearance  |
+|                |                              |   and animation       |      
++----------------+------------------------------+-----------------------+
+|penrose         |     aperiodic tiling with    |        stamp          |
+|                |         kites and darts      |                       |
++----------------+------------------------------+-----------------------+
+|planet_and_moon |     simulation of            |      compound shape   |
+|                |     gravitational system     |      Vec2D            |
++----------------+------------------------------+-----------------------+
+|tree            | a (graphical) breadth        |          clone        |
+|                | first tree (using generators)|                       |
++----------------+------------------------------+-----------------------+
+|wikipedia       | a pattern from the wikipedia |       clone, undo     |
+|                | article on turtle-graphics   |                       |
++----------------+------------------------------+-----------------------+
+|yingyang        |  another elementary example  |         circle        |    
++----------------+------------------------------+-----------------------+
 
-.. method:: Turtle.degrees([fullcircle])
+turtledemo_two-canvases:  two distinct Tkinter-Canvases
+are populated with turtles. Uses class RawTurtle.
 
-   *fullcircle* is by default 360. This can cause the pen to have any angular units
-   whatever: give *fullcircle* ``2*pi`` for radians, or 400 for gradians.
 
+Have fun!
\ No newline at end of file

Modified: python/trunk/Lib/lib-tk/turtle.py
==============================================================================
--- python/trunk/Lib/lib-tk/turtle.py	(original)
+++ python/trunk/Lib/lib-tk/turtle.py	Wed Jun  4 08:29:55 2008
@@ -1,294 +1,3142 @@
-# LogoMation-like turtle graphics
+#
+# turtle.py: a Tkinter based turtle graphics module for Python
+# Version 1.0b1 - 31. 5. 2008
+#
+# Copyright (C) 2006 - 2008  Gregor Lingl
+# email: glingl at aon.at
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
 
 """
 Turtle graphics is a popular way for introducing programming to
 kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
+by Wally Feurzig and Seymour Papert in 1966.
 
 Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
 the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
 the direction it is facing, drawing a line as it moves. Give it the
 command turtle.left(25), and it rotates in-place 25 degrees clockwise.
 
-By combining together these and similar commands, intricate shapes and
-pictures can easily be drawn.
-"""
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+  turtle. So the turtles can more easily be used as a visual feedback
+  instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+  and user controllable turtle shapes, among them compound
+  (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+  makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+  and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+  following the early Logo traditions. This reduces the boring work of
+  typing long sequences of commands, which often occur in a natural way
+  when kids try to program fancy pictures on their first encounter with
+  turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+  (mouse-, key-, timer-events). Especially useful for programming games.
+
+- A scrollable Canvas class. The default scrollable Canvas can be
+  extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+  background image, window and canvas size and other properties of the
+  TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+  coordinate-system for the TurtleScreen.
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+  This class is public, so it can be imported by the application programmer,
+  which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+  configured by means of a turtle.cfg configuration file.
+  The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+  dictionary in some different language, supplied separately  and replaces
+  the english ones by those read in. There is a utility function
+  write_docstringdict() to write a dictionary with the original (english)
+  docstrings to disc, so it can serve as a template for translations.
+
+Behind the scenes there are some features included with possible
+extensionsin in mind. These will be commented and documented elsewhere.
+
+"""
+
+_ver = "turtle 1.0b1 - for Python 2.6   -  30. 5. 2008, 18:08"
+
+#print _ver
+
+import Tkinter as TK
+import types
+import math
+import time
+import os
+
+from os.path import isfile, split, join
+from copy import deepcopy
+
+from math import *    ## for compatibility with old turtle module
+
+_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
+               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
+_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
+        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
+        'getshapes', 'listen', 'mode', 'onkey', 'onscreenclick', 'ontimer',
+        'register_shape', 'resetscreen', 'screensize', 'setup',
+        'setworldcoordinates', 'title', 'tracer', 'turtles', 'update',
+        'window_height', 'window_width']
+_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
+        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
+        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
+        'fill', 'fillcolor', 'forward', 'get_poly', 'getpen', 'getscreen',
+        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
+        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
+        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
+        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
+        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
+        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'showturtle',
+        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', 'tracer',
+        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
+        'window_height', 'window_width', 'write', 'xcor', 'ycor']
+_tg_utilities = ['write_docstringdict', 'done', 'mainloop']
+_math_functions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh',
+        'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
+        'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
+
+__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
+           _tg_utilities + _math_functions)
+
+_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
+               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
+               'turtlesize', 'up', 'width']
+
+_CFG = {"width" : 0.5,               # Screen
+        "height" : 0.75,
+        "canvwidth" : 400,
+        "canvheight": 300,
+        "leftright": None,
+        "topbottom": None,
+        "mode": "standard",          # TurtleScreen
+        "colormode": 1.0,
+        "delay": 10,
+        "undobuffersize": 1000,      # RawTurtle
+        "shape": "classic",
+        "pencolor" : "black",
+        "fillcolor" : "black",
+        "resizemode" : "noresize",
+        "visible" : True,
+        "language": "english",        # docstrings
+        "exampleturtle": "turtle",
+        "examplescreen": "screen",
+        "title": "Python Turtle Graphics",
+        "using_IDLE": False
+       }
+
+##print "cwd:", os.getcwd()
+##print "__file__:", __file__
+##
+##def show(dictionary):
+##    print "=========================="
+##    for key in sorted(dictionary.keys()):
+##        print key, ":", dictionary[key]
+##    print "=========================="
+##    print
+
+def config_dict(filename):
+    """Convert content of config-file into dictionary."""
+    f = open(filename, "r")
+    cfglines = f.readlines()
+    f.close()
+    cfgdict = {}
+    for line in cfglines:
+        line = line.strip()
+        if not line or line.startswith("#"):
+            continue
+        try:
+            key, value = line.split("=")
+        except:
+            print "Bad line in config-file %s:\n%s" % (filename,line)
+            continue
+        key = key.strip()
+        value = value.strip()
+        if value in ["True", "False", "None", "''", '""']:
+            value = eval(value)
+        else:
+            try:
+                if "." in value:
+                    value = float(value)
+                else:
+                    value = int(value)
+            except:
+                pass # value need not be converted
+        cfgdict[key] = value
+    return cfgdict
+
+def readconfig(cfgdict):
+    """Read config-files, change configuration-dict accordingly.
+
+    If there is a turtle.cfg file in the current working directory,
+    read it from there. If this contains an importconfig-value,
+    say 'myway', construct filename turtle_mayway.cfg else use
+    turtle.cfg and read it from the import-directory, where
+    turtle.py is located.
+    Update configuration dictionary first according to config-file,
+    in the import directory, then according to config-file in the
+    current working directory.
+    If no config-file is found, the default configuration is used.
+    """
+    default_cfg = "turtle.cfg"
+    cfgdict1 = {}
+    cfgdict2 = {}
+    if isfile(default_cfg):
+        cfgdict1 = config_dict(default_cfg)
+        #print "1. Loading config-file %s from: %s" % (default_cfg, os.getcwd())
+    if "importconfig" in cfgdict1:
+        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
+    try:
+        head, tail = split(__file__)
+        cfg_file2 = join(head, default_cfg)
+    except:
+        cfg_file2 = ""
+    if isfile(cfg_file2):
+        #print "2. Loading config-file %s:" % cfg_file2
+        cfgdict2 = config_dict(cfg_file2)
+##    show(_CFG)
+##    show(cfgdict2)
+    _CFG.update(cfgdict2)
+##    show(_CFG)
+##    show(cfgdict1)
+    _CFG.update(cfgdict1)
+##    show(_CFG)
+
+try:
+    readconfig(_CFG)
+except:
+    print "No configfile read, reason unknown"
+
+
+class Vec2D(tuple):
+    """A 2 dimensional vector class, used as a helper class
+    for implementing turtle graphics.
+    May be useful for turtle graphics programs also.
+    Derived from tuple, so a vector is a tuple!
+
+    Provides (for a, b vectors, k number):
+       a+b vector addition
+       a-b vector subtraction
+       a*b inner product
+       k*a and a*k multiplication with scalar
+       |a| absolute value of a
+       a.rotate(angle) rotation
+    """
+    def __new__(cls, x, y):
+        return tuple.__new__(cls, (x, y))
+    def __add__(self, other):
+        return Vec2D(self[0]+other[0], self[1]+other[1])
+    def __mul__(self, other):
+        if isinstance(other, Vec2D):
+            return self[0]*other[0]+self[1]*other[1]
+        return Vec2D(self[0]*other, self[1]*other)
+    def __rmul__(self, other):
+        if isinstance(other, int) or isinstance(other, float):
+            return Vec2D(self[0]*other, self[1]*other)
+    def __sub__(self, other):
+        return Vec2D(self[0]-other[0], self[1]-other[1])
+    def __neg__(self):
+        return Vec2D(-self[0], -self[1])
+    def __abs__(self):
+        return (self[0]**2 + self[1]**2)**0.5
+    def rotate(self, angle):
+        """rotate self counterclockwise by angle
+        """
+        perp = Vec2D(-self[1], self[0])
+        angle = angle * math.pi / 180.0
+        c, s = math.cos(angle), math.sin(angle)
+        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
+    def __getnewargs__(self):
+        return (self[0], self[1])
+    def __repr__(self):
+        return "(%.2f,%.2f)" % self
+
+
+##############################################################################
+### From here up to line    : Tkinter - Interface for turtle.py            ###
+### May be replaced by an interface to some different graphcis-toolkit     ###
+##############################################################################
+
+## helper functions for Scrolled Canvas, to forward Canvas-methods
+## to ScrolledCanvas class
+
+def __methodDict(cls, _dict):
+    """helper function for Scrolled Canvas"""
+    baseList = list(cls.__bases__)
+    baseList.reverse()
+    for _super in baseList:
+        __methodDict(_super, _dict)
+    for key, value in cls.__dict__.items():
+        if type(value) == types.FunctionType:
+            _dict[key] = value
+
+def __methods(cls):
+    """helper function for Scrolled Canvas"""
+    _dict = {}
+    __methodDict(cls, _dict)
+    return _dict.keys()
+
+__stringBody = (
+    'def %(method)s(self, *args, **kw): return ' +
+    'self.%(attribute)s.%(method)s(*args, **kw)')
+
+def __forwardmethods(fromClass, toClass, toPart, exclude = ()):
+    """Helper functions for Scrolled Canvas, used to forward
+    ScrolledCanvas-methods to Tkinter.Canvas class.
+    """
+    _dict = {}
+    __methodDict(toClass, _dict)
+    for ex in _dict.keys():
+        if ex[:1] == '_' or ex[-1:] == '_':
+            del _dict[ex]
+    for ex in exclude:
+        if _dict.has_key(ex):
+            del _dict[ex]
+    for ex in __methods(fromClass):
+        if _dict.has_key(ex):
+            del _dict[ex]
+
+    for method, func in _dict.items():
+        d = {'method': method, 'func': func}
+        if type(toPart) == types.StringType:
+            execString = \
+                __stringBody % {'method' : method, 'attribute' : toPart}
+        exec execString in d
+        fromClass.__dict__[method] = d[method]
+
+
+class ScrolledCanvas(TK.Frame):
+    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
+
+    Used as the default canvas, which pops up automatically when
+    using turtle graphics functions or the Turtle class.
+    """
+    def __init__(self, master, width=500, height=350,
+                                          canvwidth=600, canvheight=500):
+        TK.Frame.__init__(self, master, width=width, height=height)
+        self._root = self.winfo_toplevel()
+        self.width, self.height = width, height
+        self.canvwidth, self.canvheight = canvwidth, canvheight
+        self.bg = "white"
+        self._canvas = TK.Canvas(master, width=width, height=height,
+                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
+        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
+                                    orient=TK.HORIZONTAL)
+        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
+        self._canvas.configure(xscrollcommand=self.hscroll.set,
+                               yscrollcommand=self.vscroll.set)
+        self.rowconfigure(0, weight=1, minsize=0)
+        self.columnconfigure(0, weight=1, minsize=0)
+        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                column=1, rowspan=1, columnspan=1, sticky='news')
+        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.reset()
+        self._root.bind('<Configure>', self.onResize)
+
+    def reset(self, canvwidth=None, canvheight=None, bg = None):
+        """Ajust canvas and scrollbars according to given canvas size."""
+        if canvwidth:
+            self.canvwidth = canvwidth
+        if canvheight:
+            self.canvheight = canvheight
+        if bg:
+            self.bg = bg
+        self._canvas.config(bg=bg,
+                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2))
+        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
+                                                               self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
+                                                              self.canvheight)
+        self.adjustScrolls()
+
+
+    def adjustScrolls(self):
+        """ Adjust scrollbars according to window- and canvas-size.
+        """
+        cwidth = self._canvas.winfo_width()
+        cheight = self._canvas.winfo_height()
+        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
+        if cwidth < self.canvwidth or cheight < self.canvheight:
+            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                              column=0, rowspan=1, columnspan=1, sticky='news')
+            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                              column=1, rowspan=1, columnspan=1, sticky='news')
+        else:
+            self.hscroll.grid_forget()
+            self.vscroll.grid_forget()
+
+    def onResize(self, event):
+        """self-explanatory"""
+        self.adjustScrolls()
+
+    def bbox(self, *args):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.bbox(*args)
+
+    def cget(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.cget(*args, **kwargs)
+
+    def config(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.config(*args, **kwargs)
+
+    def bind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.bind(*args, **kwargs)
+
+    def unbind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.unbind(*args, **kwargs)
+
+    def focus_force(self):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.focus_force()
+
+__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
+
+
+class _Root(TK.Tk):
+    """Root class for Screen based on Tkinter."""
+    def __init__(self):
+        TK.Tk.__init__(self)
+
+    def setupcanvas(self, width, height, cwidth, cheight):
+        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
+        self._canvas.pack(expand=1, fill="both")
+
+    def _getcanvas(self):
+        return self._canvas
+
+    def set_geometry(self, width, height, startx, starty):
+        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
+
+    def ondestroy(self, destroy):
+        self.wm_protocol("WM_DELETE_WINDOW", destroy)
+
+    def win_width(self):
+        return self.winfo_screenwidth()
+
+    def win_height(self):
+        return self.winfo_screenheight()
+
+Canvas = TK.Canvas
+
+
+class TurtleScreenBase(object):
+    """Provide the basic graphics functionality.
+       Interface between Tkinter and turtle.py.
+
+       To port turtle.py to some different graphics toolkit
+       a corresponding TurtleScreenBase class has to be implemented.
+    """
+
+    @staticmethod
+    def _blankimage():
+        """return a blank image object
+        """
+        img = TK.PhotoImage(width=1, height=1)
+        img.blank()
+        return img
+
+    @staticmethod
+    def _image(filename):
+        """return an image object containing the
+        imagedata from a gif-file named filename.
+        """
+        return TK.PhotoImage(file=filename)
+
+    def __init__(self, cv):
+        self.cv = cv
+        if isinstance(cv, ScrolledCanvas):
+            w = self.cv.canvwidth
+            h = self.cv.canvheight
+        else:  # expected: ordinary TK.Canvas
+            w = int(self.cv.cget("width"))
+            h = int(self.cv.cget("height"))
+            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
+        self.canvwidth = w
+        self.canvheight = h
+        self.xscale = self.yscale = 1.0
+
+    def _createpoly(self):
+        """Create an invisible polygon item on canvas self.cv)
+        """
+        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
+
+    def _drawpoly(self, polyitem, coordlist, fill=None,
+                  outline=None, width=None, top=False):
+        """Configure polygonitem polyitem according to provided
+        arguments:
+        coordlist is sequence of coordinates
+        fill is filling color
+        outline is outline color
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        cl = []
+        for x, y in coordlist:
+            cl.append(x * self.xscale)
+            cl.append(-y * self.yscale)
+        self.cv.coords(polyitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(polyitem, fill=fill)
+        if outline is not None:
+            self.cv.itemconfigure(polyitem, outline=outline)
+        if width is not None:
+            self.cv.itemconfigure(polyitem, width=width)
+        if top:
+            self.cv.tag_raise(polyitem)
+
+    def _createline(self):
+        """Create an invisible line item on canvas self.cv)
+        """
+        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
+                                   capstyle = TK.ROUND)
+
+    def _drawline(self, lineitem, coordlist=None,
+                  fill=None, width=None, top=False):
+        """Configure lineitem according to provided arguments:
+        coordlist is sequence of coordinates
+        fill is drawing color
+        width is width of drawn line.
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        if coordlist is not None:
+            cl = []
+            for x, y in coordlist:
+                cl.append(x * self.xscale)
+                cl.append(-y * self.yscale)
+            self.cv.coords(lineitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(lineitem, fill=fill)
+        if width is not None:
+            self.cv.itemconfigure(lineitem, width=width)
+        if top:
+            self.cv.tag_raise(lineitem)
+
+    def _delete(self, item):
+        """Delete graphics item from canvas.
+        If item is"all" delete all graphics items.
+        """
+        self.cv.delete(item)
+
+    def _update(self):
+        """Redraw graphics items on canvas
+        """
+        self.cv.update()
+
+    def _delay(self, delay):
+        """Delay subsequent canvas actions for delay ms."""
+        self.cv.after(delay)
+
+    def _iscolorstring(self, color):
+        """Check if the string color is a legal Tkinter color string.
+        """
+        try:
+            rgb = self.cv.winfo_rgb(color)
+            ok = True
+        except TK.TclError:
+            ok = False
+        return ok
+
+    def _bgcolor(self, color=None):
+        """Set canvas' backgroundcolor if color is not None,
+        else return backgroundcolor."""
+        if color is not None:
+            self.cv.config(bg = color)
+            self._update()
+        else:
+            return self.cv.cget("bg")
+
+    def _write(self, pos, txt, align, font, pencolor):
+        """Write txt at pos in canvas with specified font
+        and color.
+        Return text item and x-coord of right bottom corner
+        of text's bounding box."""
+        x, y = pos
+        x = x * self.xscale
+        y = y * self.yscale
+        anchor = {"left":"sw", "center":"s", "right":"se" }
+        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
+                                        fill = pencolor, font = font)
+        x0, y0, x1, y1 = self.cv.bbox(item)
+        self.cv.update()
+        return item, x1-1
+
+##    def _dot(self, pos, size, color):
+##        """may be implemented for some other graphics toolkit"""
+
+    def _onclick(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-click event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
+
+    def _onrelease(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-button-release event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the point on the canvas where mouse button is released.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
+                             eventfun, add)
+
+    def _ondrag(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
+        fun must be a function with two arguments, the coordinates of the
+        actual mouse position on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
+        else:
+            def eventfun(event):
+                try:
+                    x, y = (self.cv.canvasx(event.x)/self.xscale,
+                           -self.cv.canvasy(event.y)/self.yscale)
+                    fun(x, y)
+                except:
+                    pass
+            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
+
+    def _onscreenclick(self, fun, num=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.unbind("<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.bind("<Button-%s>" % num, eventfun, add)
+
+    def _onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+        Canvas must have focus. See method listen
+        """
+        if fun is None:
+            self.cv.unbind("<KeyRelease-%s>" % key, None)
+        else:
+            def eventfun(event):
+                fun()
+            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
+
+    def _listen(self):
+        """Set focus on canvas (in order to collect key-events)
+        """
+        self.cv.focus_force()
+
+    def _ontimer(self, fun, t):
+        """Install a timer, which calls fun after t milliseconds.
+        """
+        if t == 0:
+            self.cv.after_idle(fun)
+        else:
+            self.cv.after(t, fun)
+
+    def _createimage(self, image):
+        """Create and return image item on canvas.
+        """
+        return self.cv.create_image(0, 0, image=image)
+
+    def _drawimage(self, item, (x, y), image):
+        """Configure image item as to draw image object
+        at position (x,y) on canvas)
+        """
+        self.cv.coords(item, (x, -y))
+        self.cv.itemconfig(item, image=image)
+
+    def _setbgpic(self, item, image):
+        """Configure image item as to draw image object
+        at center of canvas. Set item to the first item
+        in the displaylist, so it will be drawn below
+        any other item ."""
+        self.cv.itemconfig(item, image=image)
+        self.cv.tag_lower(item)
+
+    def _type(self, item):
+        """Return 'line' or 'polygon' or 'image' depending on
+        type of item.
+        """
+        return self.cv.type(item)
+
+    def _pointlist(self, item):
+        """returns list of coordinate-pairs of points of item
+        Example (for insiders):
+        >>> from turtle import *
+        >>> getscreen()._pointlist(getturtle().turtle._item)
+        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
+        (9.9999999999999982, 0.0)]
+        >>> """
+        cl = self.cv.coords(item)
+        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
+        return  pl
+
+    def _setscrollregion(self, srx1, sry1, srx2, sry2):
+        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
+
+    def _rescale(self, xscalefactor, yscalefactor):
+        items = self.cv.find_all()
+        for item in items:
+            coordinates = self.cv.coords(item)
+            newcoordlist = []
+            while coordinates:
+                x, y = coordinates[:2]
+                newcoordlist.append(x * xscalefactor)
+                newcoordlist.append(y * yscalefactor)
+                coordinates = coordinates[2:]
+            self.cv.coords(item, *newcoordlist)
+
+    def _resize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on. Does
+        not alter the drawing window.
+        """
+        # needs amendment
+        if not isinstance(self.cv, ScrolledCanvas):
+            return self.canvwidth, self.canvheight
+        if canvwidth is None and canvheight is None and bg is None:
+            return self.cv.canvwidth, self.cv.canvheight
+        if canvwidth is not None:
+            self.canvwidth = canvwidth
+        if canvheight is not None:
+            self.canvheight = canvheight
+        self.cv.reset(canvwidth, canvheight, bg)
+
+    def _window_size(self):
+        """ Return the width and height of the turtle window.
+        """
+        width = self.cv.winfo_width()
+        if width <= 1:  # the window isn't managed by a geometry manager
+            width = self.cv['width']
+        height = self.cv.winfo_height()
+        if height <= 1: # the window isn't managed by a geometry manager
+            height = self.cv['height']
+        return width, height
+
+
+##############################################################################
+###                  End of Tkinter - interface                            ###
+##############################################################################
+
+
+class Terminator (Exception):
+    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
+
+    Thus stops execution of turtle graphics script. Main purpose: use in
+    in the Demo-Viewer turtle.Demo.py.
+    """
+    pass
+
+
+class TurtleGraphicsError(Exception):
+    """Some TurtleGraphics Error
+    """
+
+
+class Shape(object):
+    """Data structure modeling shapes.
+
+    attribute _type is one of "polygon", "image", "compound"
+    attribute _data is - depending on _type a poygon-tuple,
+    an image or a list constructed using the addcomponent method.
+    """
+    def __init__(self, type_, data=None):
+        self._type = type_
+        if type_ == "polygon":
+            if isinstance(data, list):
+                data = tuple(data)
+        elif type_ == "image":
+            if isinstance(data, str):
+                if data.lower().endswith(".gif") and isfile(data):
+                    data = TurtleScreen._image(data)
+                # else data assumed to be Photoimage
+        elif type_ == "compound":
+            data = []
+        else:
+            raise TurtleGraphicsError("There is no shape type %s" % type_)
+        self._data = data
+
+    def addcomponent(self, poly, fill, outline=None):
+        """Add component to a shape of type compound.
+
+        Arguments: poly is a polygon, i. e. a tuple of number pairs.
+        fill is the fillcolor of the component,
+        outline is the outline color of the component.
+
+        call (for a Shapeobject namend s):
+        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
+
+        Example:
+        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+        >>> s = Shape("compound")
+        >>> s.addcomponent(poly, "red", "blue")
+        ### .. add more components and then use register_shape()
+        """
+        if self._type != "compound":
+            raise TurtleGraphicsError("Cannot add component to %s Shape"
+                                                                % self._type)
+        if outline is None:
+            outline = fill
+        self._data.append([poly, fill, outline])
+
+
+class Tbuffer(object):
+    """Ring buffer used as undobuffer for RawTurtle objects."""
+    def __init__(self, bufsize=10):
+        self.bufsize = bufsize
+        self.buffer = [[None]] * bufsize
+        self.ptr = -1
+        self.cumulate = False
+    def reset(self, bufsize=None):
+        if bufsize is None:
+            for i in range(self.bufsize):
+                self.buffer[i] = [None]
+        else:
+            self.bufsize = bufsize
+            self.buffer = [[None]] * bufsize
+        self.ptr = -1
+    def push(self, item):
+        if self.bufsize > 0:
+            if not self.cumulate:
+                self.ptr = (self.ptr + 1) % self.bufsize
+                self.buffer[self.ptr] = item
+            else:
+                self.buffer[self.ptr].append(item)
+    def pop(self):
+        if self.bufsize > 0:
+            item = self.buffer[self.ptr]
+            if item is None:
+                return None
+            else:
+                self.buffer[self.ptr] = [None]
+                self.ptr = (self.ptr - 1) % self.bufsize
+                return (item)
+    def nr_of_items(self):
+        return self.bufsize - self.buffer.count([None])
+    def __repr__(self):
+        return str(self.buffer) + " " + str(self.ptr)
+
+
+
+class TurtleScreen(TurtleScreenBase):
+    """Provides screen oriented methods like setbg etc.
+
+    Only relies upon the methods of TurtleScreenBase and NOT
+    upon components of the underlying graphics toolkit -
+    which is Tkinter in this case.
+    """
+#    _STANDARD_DELAY = 5
+    _RUNNING = True
+
+    def __init__(self, cv, mode=_CFG["mode"],
+                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
+        self._shapes = {
+                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
+                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
+                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
+                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
+                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
+                              (2,14))),
+                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
+                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
+                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
+                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
+                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
+                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
+                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
+                              (-10,-10))),
+                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
+                              (-10,-5.77))),
+                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
+                   "blank" : Shape("image", self._blankimage())
+                  }
+
+        self._bgpics = {"nopic" : ""}
+
+        TurtleScreenBase.__init__(self, cv)
+        self._mode = mode
+        self._delayvalue = delay
+        self._colormode = _CFG["colormode"]
+        self._keys = []
+        self.clear()
+
+    def clear(self):
+        """Delete all drawings and all turtles from the TurtleScreen.
+
+        Reset empty TurtleScreen to it's initial state: white background,
+        no backgroundimage, no eventbindings and tracing on.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        screen.clear()
+
+        Note: this method is not available as function.
+        """
+        self._delayvalue = _CFG["delay"]
+        self._colormode = _CFG["colormode"]
+        self._delete("all")
+        self._bgpic = self._createimage("")
+        self._bgpicname = "nopic"
+        self._tracing = 1
+        self._updatecounter = 0
+        self._turtles = []
+        self.bgcolor("white")
+        for btn in 1, 2, 3:
+            self.onclick(None, btn)
+        for key in self._keys[:]:
+            self.onkey(None, key)
+        Turtle._pen = None
+
+    def mode(self, mode=None):
+        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
+
+        Optional argument:
+        mode -- on of the strings 'standard', 'logo' or 'world'
+
+        Mode 'standard' is compatible with turtle.py.
+        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
+        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
+        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
+        If mode is not given, return the current mode.
+
+             Mode      Initial turtle heading     positive angles
+         ------------|-------------------------|-------------------
+          'standard'    to the right (east)       counterclockwise
+            'logo'        upward    (north)         clockwise
+
+        Examples:
+        >>> mode('logo')   # resets turtle heading to north
+        >>> mode()
+        'logo'
+        """
+        if mode == None:
+            return self._mode
+        mode = mode.lower()
+        if mode not in ["standard", "logo", "world"]:
+            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
+        self._mode = mode
+        if mode in ["standard", "logo"]:
+            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2)
+            self.xscale = self.yscale = 1.0
+        self.reset()
+
+    def setworldcoordinates(self, llx, lly, urx, ury):
+        """Set up a user defined coordinate-system.
+
+        Arguments:
+        llx -- a number, x-coordinate of lower left corner of canvas
+        lly -- a number, y-coordinate of lower left corner of canvas
+        urx -- a number, x-coordinate of upper right corner of canvas
+        ury -- a number, y-coordinate of upper right corner of canvas
+
+        Set up user coodinat-system and switch to mode 'world' if necessary.
+        This performs a screen.reset. If mode 'world' is already active,
+        all drawings are redrawn according to the new coordinates.
+
+        But ATTENTION: in user-defined coordinatesystems angles may appear
+        distorted. (see Screen.mode())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
+        >>> for _ in range(36):
+                left(10)
+                forward(0.5)
+        """
+        if self.mode() != "world":
+            self.mode("world")
+        xspan = float(urx - llx)
+        yspan = float(ury - lly)
+        wx, wy = self._window_size()
+        self.screensize(wx-20, wy-20)
+        oldxscale, oldyscale = self.xscale, self.yscale
+        self.xscale = self.canvwidth / xspan
+        self.yscale = self.canvheight / yspan
+        srx1 = llx * self.xscale
+        sry1 = -ury * self.yscale
+        srx2 = self.canvwidth + srx1
+        sry2 = self.canvheight + sry1
+        self._setscrollregion(srx1, sry1, srx2, sry2)
+        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
+        self.update()
+
+    def register_shape(self, name, shape=None):
+        """Adds a turtle shape to TurtleScreen's shapelist.
+
+        Arguments:
+        (1) name is the name of a gif-file and shape is None.
+            Installs the corresponding image shape.
+            !! Image-shapes DO NOT rotate when turning the turtle,
+            !! so they do not display the heading of the turtle!
+        (2) name is an arbitrary string and shape is a tuple
+            of pairs of coordinates. Installs the corresponding
+            polygon shape
+        (3) name is an arbitrary string and shape is a
+            (compound) Shape object. Installs the corresponding
+            compound shape.
+        To use a shape, you have to issue the command shape(shapename).
+
+        call: register_shape("turtle.gif")
+        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
+
+        """
+        if shape is None:
+            # image
+            if name.lower().endswith(".gif"):
+                shape = Shape("image", self._image(name))
+            else:
+                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
+                                          + "Use  help(register_shape)" )
+        elif isinstance(shape, tuple):
+            shape = Shape("polygon", shape)
+        ## else shape assumed to be Shape-instance
+        self._shapes[name] = shape
+        # print "shape added:" , self._shapes
+
+    def _colorstr(self, color):
+        """Return color string corresponding to args.
+
+        Argument may be a string or a tuple of three
+        numbers corresponding to actual colormode,
+        i.e. in the range 0<=n<=colormode.
+
+        If the argument doesn't represent a color,
+        an error is raised.
+        """
+        if len(color) == 1:
+            color = color[0]
+        if isinstance(color, str):
+            if self._iscolorstring(color) or color == "":
+                return color
+            else:
+                raise TurtleGraphicsError("bad color string: %s" % str(color))
+        try:
+            r, g, b = color
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
+        if self._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def _color(self, cstr):
+        if not cstr.startswith("#"):
+            return cstr
+        if len(cstr) == 7:
+            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
+        elif len(cstr) == 4:
+            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
+        else:
+            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
+        return tuple([c * self._colormode/255 for c in cl])
+
+    def colormode(self, cmode=None):
+        """Return the colormode or set it to 1.0 or 255.
+
+        Optional argument:
+        cmode -- one of the values 1.0 or 255
+
+        r, g, b values of colortriples have to be in range 0..cmode.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.colormode()
+        1.0
+        >>> screen.colormode(255)
+        >>> turtle.pencolor(240,160,80)
+        """
+        if cmode is None:
+            return self._colormode
+        if cmode == 1.0:
+            self._colormode = float(cmode)
+        elif cmode == 255:
+            self._colormode = int(cmode)
+
+    def reset(self):
+        """Reset all Turtles on the Screen to their initial state.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.reset()
+        """
+        for turtle in self._turtles:
+            turtle._setmode(self._mode)
+            turtle.reset()
+
+    def turtles(self):
+        """Return the list of turtles on the screen.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.turtles()
+        [<turtle.Turtle object at 0x00E11FB0>]
+        """
+        return self._turtles
+
+    def bgcolor(self, *args):
+        """Set or return backgroundcolor of the TurtleScreen.
+
+        Arguments (if given): a color string or three numbers
+        in the range 0..colormode or a 3-tuple of such numbers.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgcolor("orange")
+        >>> screen.bgcolor()
+        'orange'
+        >>> screen.bgcolor(0.5,0,0.5)
+        >>> screen.bgcolor()
+        '#800080'
+        """
+        if args:
+            color = self._colorstr(args)
+        else:
+            color = None
+        color = self._bgcolor(color)
+        if color is not None:
+            color = self._color(color)
+        return color
+
+    def tracer(self, n=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                fd(dist)
+                rt(90)
+                dist += 2
+        """
+        if n is None:
+            return self._tracing
+        self._tracing = int(n)
+        self._updatecounter = 0
+        if delay is not None:
+            self._delayvalue = int(delay)
+        if self._tracing:
+            self.update()
+
+    def delay(self, delay=None):
+        """ Return or set the drawing delay in milliseconds.
+
+        Optional argument:
+        delay -- positive integer
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.delay(15)
+        >>> screen.delay()
+        15
+        """
+        if delay is None:
+            return self._delayvalue
+        self._delayvalue = int(delay)
+
+    def _incrementudc(self):
+        "Increment upadate counter."""
+        if not TurtleScreen._RUNNING:
+            TurtleScreen._RUNNNING = True
+            raise Terminator
+        if self._tracing > 0:
+            self._updatecounter += 1
+            self._updatecounter %= self._tracing
+
+    def update(self):
+        """Perform a TurtleScreen update.
+        """
+        for t in self.turtles():
+            t._update_data()
+            t._drawturtle()
+        self._update()
+
+    def window_width(self):
+        """ Return the width of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_width()
+        640
+        """
+        return self._window_size()[0]
+
+    def window_height(self):
+        """ Return the height of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_height()
+        480
+        """
+        return self._window_size()[1]
+
+    def getcanvas(self):
+        """Return the Canvas of this TurtleScreen.
+
+        No argument.
+
+        Example (for a Screen instance named screen):
+        >>> cv = screen.getcanvas()
+        >>> cv
+        <turtle.ScrolledCanvas instance at 0x010742D8>
+        """
+        return self.cv
+
+    def getshapes(self):
+        """Return a list of names of all currently available turtle shapes.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.getshapes()
+        ['arrow', 'blank', 'circle', ... , 'turtle']
+        """
+        return sorted(self._shapes.keys())
+
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+
+        Arguments:
+        fun -- a function with two arguments, the coordinates of the
+               clicked point on the canvas.
+        num -- the number of the mouse-button, defaults to 1
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> screen.onclick(turtle.goto)
+
+        ### Subsequently clicking into the TurtleScreen will
+        ### make the turtle move to the clicked point.
+        >>> screen.onclick(None)
+
+        ### event-binding will be removed
+        """
+        self._onscreenclick(fun, btn, add)
+
+    def onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+
+        Arguments:
+        fun -- a function with no arguments
+        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+        In order ro be able to register key-events, TurtleScreen
+        must have focus. (See method listen.)
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> def f():
+                fd(50)
+                lt(60)
+
+
+        >>> screen.onkey(f, "Up")
+        >>> screen.listen()
+
+        ### Subsequently the turtle can be moved by
+        ### repeatedly pressing the up-arrow key,
+        ### consequently drawing a hexagon
+        """
+        if fun == None:
+            self._keys.remove(key)
+        elif key not in self._keys:
+            self._keys.append(key)
+        self._onkey(fun, key)
+
+    def listen(self, xdummy=None, ydummy=None):
+        """Set focus on TurtleScreen (in order to collect key-events)
+
+        No arguments.
+        Dummy arguments are provided in order
+        to be able to pass listen to the onclick method.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.listen()
+        """
+        self._listen()
+
+    def ontimer(self, fun, t=0):
+        """Install a timer, which calls fun after t milliseconds.
+
+        Arguments:
+        fun -- a function with no arguments.
+        t -- a number >= 0
+
+        Example (for a TurtleScreen instance named screen):
+
+        >>> running = True
+        >>> def f():
+                if running:
+                        fd(50)
+                        lt(60)
+                        screen.ontimer(f, 250)
+
+        >>> f()   ### makes the turtle marching around
+        >>> running = False
+        """
+        self._ontimer(fun, t)
+
+    def bgpic(self, picname=None):
+        """Set background image or return name of current backgroundimage.
+
+        Optional argument:
+        picname -- a string, name of a gif-file or "nopic".
+
+        If picname is a filename, set the corresponing image as background.
+        If picname is "nopic", delete backgroundimage, if present.
+        If picname is None, return the filename of the current backgroundimage.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgpic()
+        'nopic'
+        >>> screen.bgpic("landscape.gif")
+        >>> screen.bgpic()
+        'landscape.gif'
+        """
+        if picname is None:
+            return self._bgpicname
+        if picname not in self._bgpics:
+            self._bgpics[picname] = self._image(picname)
+        self._setbgpic(self._bgpic, self._bgpics[picname])
+        self._bgpicname = picname
+
+    def screensize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on.
+
+        Optional arguments:
+        canvwidth -- positive integer, new width of canvas in pixels
+        canvheight --  positive integer, new height of canvas in pixels
+        bg -- colorstring or color-tupel, new backgroundcolor
+        If no arguments are given, return current (canvaswidth, canvasheight)
+
+        Do not alter the drawing window. To observe hidden parts of
+        the canvas use the scrollbars. (Can make visible those parts
+        of a drawing, which were outside the canvas before!)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.screensize(2000,1500)
+            ### e. g. to search for an erroneously escaped turtle ;-)
+        """
+        return self._resize(canvwidth, canvheight, bg)
+
+    onscreenclick = onclick
+    resetscreen = reset
+    clearscreen = clear
+    addshape = register_shape
+
+class TNavigator(object):
+    """Navigation part of the RawTurtle.
+    Implements methods for turtle movement.
+    """
+    START_ORIENTATION = {
+        "standard": Vec2D(1.0, 0.0),
+        "world"   : Vec2D(1.0, 0.0),
+        "logo"    : Vec2D(0.0, 1.0)  }
+    DEFAULT_MODE = "standard"
+    DEFAULT_ANGLEOFFSET = 0
+    DEFAULT_ANGLEORIENT = 1
+
+    def __init__(self, mode=DEFAULT_MODE):
+        self._angleOffset = self.DEFAULT_ANGLEOFFSET
+        self._angleOrient = self.DEFAULT_ANGLEORIENT
+        self._mode = mode
+        self.undobuffer = None
+        self.degrees()
+        self._mode = None
+        self._setmode(mode)
+        TNavigator.reset(self)
+
+    def reset(self):
+        """reset turtle to its initial values
+
+        Will be overwritten by parent class
+        """
+        self._position = Vec2D(0.0, 0.0)
+        self._orient =  TNavigator.START_ORIENTATION[self._mode]
+
+    def _setmode(self, mode=None):
+        """Set turtle-mode to 'standard', 'world' or 'logo'.
+        """
+        if mode == None:
+            return self._mode
+        if mode not in ["standard", "logo", "world"]:
+            return
+        self._mode = mode
+        if mode in ["standard", "world"]:
+            self._angleOffset = 0
+            self._angleOrient = 1
+        else: # mode == "logo":
+            self._angleOffset = self._fullcircle/4.
+            self._angleOrient = -1
+
+    def _setDegreesPerAU(self, fullcircle):
+        """Helper function for degrees() and radians()"""
+        self._fullcircle = fullcircle
+        self._degreesPerAU = 360/fullcircle
+        if self._mode == "standard":
+            self._angleOffset = 0
+        else:
+            self._angleOffset = fullcircle/4.
+
+    def degrees(self, fullcircle=360.0):
+        """ Set angle measurement units to degrees.
+
+        Optional argument:
+        fullcircle -  a number
+
+        Set angle measurement units, i. e. set number
+        of 'degrees' for a full circle. Dafault value is
+        360 degrees.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(90)
+        >>> turtle.heading()
+        90
+        >>> turtle.degrees(400.0)  # angle measurement in gon
+        >>> turtle.heading()
+        100
+
+        """
+        self._setDegreesPerAU(fullcircle)
+
+    def radians(self):
+        """ Set the angle measurement units to radians.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        90
+        >>> turtle.radians()
+        >>> turtle.heading()
+        1.5707963267948966
+        """
+        self._setDegreesPerAU(2*math.pi)
+
+    def _go(self, distance):
+        """move turtle forward by specified distance"""
+        ende = self._position + self._orient * distance
+        self._goto(ende)
+
+    def _rotate(self, angle):
+        """Turn turtle counterclockwise by specified angle if angle > 0."""
+        angle *= self._degreesPerAU
+        self._orient = self._orient.rotate(angle)
+
+    def _goto(self, end):
+        """move turtle to position end."""
+        self._position = end
+
+    def forward(self, distance):
+        """Move the turtle forward by the specified distance.
+
+        Aliases: forward | fd
+
+        Argument:
+        distance -- a number (integer or float)
+
+        Move the turtle forward by the specified distance, in the direction
+        the turtle is headed.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 0.00)
+        >>> turtle.forward(25)
+        >>> turtle.position()
+        (25.00,0.00)
+        >>> turtle.forward(-75)
+        >>> turtle.position()
+        (-50.00,0.00)
+        """
+        self._go(distance)
+
+    def back(self, distance):
+        """Move the turtle backward by distance.
+
+        Aliases: back | backward | bk
+
+        Argument:
+        distance -- a number
+
+        Move the turtle backward by distance ,opposite to the direction the
+        turtle is headed. Do not change the turtle's heading.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 0.00)
+        >>> turtle.backward(30)
+        >>> turtle.position()
+        (-30.00, 0.00)
+        """
+        self._go(-distance)
+
+    def right(self, angle):
+        """Turn turtle right by angle units.
+
+        Aliases: right | rt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle right by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.right(45)
+        >>> turtle.heading()
+        337.0
+        """
+        self._rotate(-angle)
+
+    def left(self, angle):
+        """Turn turtle left by angle units.
+
+        Aliases: left | lt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle left by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.left(45)
+        >>> turtle.heading()
+        67.0
+        """
+        self._rotate(angle)
+
+    def pos(self):
+        """Return the turtle's current location (x,y), as a Vec2D-vector.
+
+        Aliases: pos | position
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 240.00)
+        """
+        return self._position
+
+    def xcor(self):
+        """ Return the turtle's x coordinate.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.xcor()
+        50.0
+        """
+        return self._position[0]
+
+    def ycor(self):
+        """ Return the turtle's y coordinate
+        ---
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.ycor()
+        86.6025403784
+        """
+        return self._position[1]
+
+
+    def goto(self, x, y=None):
+        """Move turtle to an absolute position.
+
+        Aliases: setpos | setposition | goto:
+
+        Arguments:
+        x -- a number      or     a pair/vector of numbers
+        y -- a number             None
+
+        call: goto(x, y)         # two coordinates
+        --or: goto((x, y))       # a pair (tuple) of coordinates
+        --or: goto(vec)          # e.g. as returned by pos()
+
+        Move turtle to an absolute position. If the pen is down,
+        a line will be drawn. The turtle's orientation does not change.
+
+        Example (for a Turtle instance named turtle):
+        >>> tp = turtle.pos()
+        >>> tp
+        (0.00, 0.00)
+        >>> turtle.setpos(60,30)
+        >>> turtle.pos()
+        (60.00,30.00)
+        >>> turtle.setpos((20,80))
+        >>> turtle.pos()
+        (20.00,80.00)
+        >>> turtle.setpos(tp)
+        >>> turtle.pos()
+        (0.00,0.00)
+        """
+        if y is None:
+            self._goto(Vec2D(*x))
+        else:
+            self._goto(Vec2D(x, y))
+
+    def home(self):
+        """Move turtle to the origin - coordinates (0,0).
+
+        No arguments.
+
+        Move turtle to the origin - coordinates (0,0) and set it's
+        heading to it's start-orientation (which depends on mode).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.home()
+        """
+        self.goto(0, 0)
+        self.setheading(0)
+
+    def setx(self, x):
+        """Set the turtle's first coordinate to x
+
+        Argument:
+        x -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, leave second coordinate
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 240.00)
+        >>> turtle.setx(10)
+        >>> turtle.position()
+        (10.00, 240.00)
+        """
+        self._goto(Vec2D(x, self._position[1]))
+
+    def sety(self, y):
+        """Set the turtle's second coordinate to y
+
+        Argument:
+        y -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, second coordinate remains
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 40.00)
+        >>> turtle.sety(-10)
+        >>> turtle.position()
+        (0.00, -10.00)
+        """
+        self._goto(Vec2D(self._position[0], y))
+
+    def distance(self, x, y=None):
+        """Return the distance from the turtle to (x,y) in turtle step units.
+
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 0.00)
+        >>> turtle.distance(30,40)
+        50.0
+        >>> pen = Turtle()
+        >>> pen.forward(77)
+        >>> turtle.distance(pen)
+        77.0
+        """
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        return abs(pos - self._position)
+
+    def towards(self, x, y=None):
+        """Return the angle of the line from the turtle's position to (x, y).
+
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Return the angle, between the line from turtle-position to position
+        specified by x, y and the turtle's start orientation. (Depends on
+        modes - "standard" or "logo")
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (10.00, 10.00)
+        >>> turtle.towards(0,0)
+        225.0
+        """
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        x, y = pos - self._position
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def heading(self):
+        """ Return the turtle's current heading.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(67)
+        >>> turtle.heading()
+        67.0
+        """
+        x, y = self._orient
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def setheading(self, to_angle):
+        """Set the orientation of the turtle to to_angle.
+
+        Aliases:  setheading | seth
+
+        Argument:
+        to_angle -- a number (integer or float)
+
+        Set the orientation of the turtle to to_angle.
+        Here are some common directions in degrees:
+
+         standard - mode:          logo-mode:
+        -------------------|--------------------
+           0 - east                0 - north
+          90 - north              90 - east
+         180 - west              180 - south
+         270 - south             270 - west
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setheading(90)
+        >>> turtle.heading()
+        90
+        """
+        angle = (to_angle - self.heading())*self._angleOrient
+        full = self._fullcircle
+        angle = (angle+full/2.)%full - full/2.
+        self._rotate(angle)
+
+    def circle(self, radius, extent = None, steps = None):
+        """ Draw a circle with given radius.
+
+        Arguments:
+        radius -- a number
+        extent (optional) -- a number
+        steps (optional) -- an integer
+
+        Draw a circle with given radius. The center is radius units left
+        of the turtle; extent - an angle - determines which part of the
+        circle is drawn. If extent is not given, draw the entire circle.
+        If extent is not a full circle, one endpoint of the arc is the
+        current pen position. Draw the arc in counterclockwise direction
+        if radius is positive, otherwise in clockwise direction. Finally
+        the direction of the turtle is changed by the amount of extent.
+
+        As the circle is approximated by an inscribed regular polygon,
+        steps determines the number of steps to use. If not given,
+        it will be calculated automatically. Maybe used to draw regular
+        polygons.
+
+        call: circle(radius)                  # full circle
+        --or: circle(radius, extent)          # arc
+        --or: circle(radius, extent, steps)
+        --or: circle(radius, steps=6)         # 6-sided polygon
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.circle(50)
+        >>> turtle.circle(120, 180)  # semicircle
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        speed = self.speed()
+        if extent is None:
+            extent = self._fullcircle
+        if steps is None:
+            frac = abs(extent)/self._fullcircle
+            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
+        w = 1.0 * extent / steps
+        w2 = 0.5 * w
+        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
+        if radius < 0:
+            l, w, w2 = -l, -w, -w2
+        tr = self.tracer()
+        dl = self._delay()
+        if speed == 0:
+            self.tracer(0, 0)
+        else:
+            self.speed(0)
+        self._rotate(w2)
+        for i in range(steps):
+            self.speed(speed)
+            self._go(l)
+            self.speed(0)
+            self._rotate(w)
+        self._rotate(-w2)
+        if speed == 0:
+            self.tracer(tr, dl)
+        self.speed(speed)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
+
+## three dummy methods to be implemented by child class:
+
+    def speed(self, s=0):
+        """dummy method - to be overwritten by child class"""
+    def tracer(self, a=None, b=None):
+        """dummy method - to be overwritten by child class"""
+    def _delay(self, n=None):
+        """dummy method - to be overwritten by child class"""
+
+    fd = forward
+    bk = back
+    backward = back
+    rt = right
+    lt = left
+    position = pos
+    setpos = goto
+    setposition = goto
+    seth = setheading
+
+
+class TPen(object):
+    """Drawing part of the RawTurtle.
+    Implements drawing properties.
+    """
+    def __init__(self, resizemode=_CFG["resizemode"]):
+        self._resizemode = resizemode # or "user" or "noresize"
+        self.undobuffer = None
+        TPen._reset(self)
+
+    def _reset(self, pencolor=_CFG["pencolor"],
+                     fillcolor=_CFG["fillcolor"]):
+        self._pensize = 1
+        self._shown = True
+        self._pencolor = pencolor
+        self._fillcolor = fillcolor
+        self._drawing = True
+        self._speed = 3
+        self._stretchfactor = (1, 1)
+        self._tilt = 0
+        self._outlinewidth = 1
+        ### self.screen = None  # to override by child class
+
+    def resizemode(self, rmode=None):
+        """Set resizemode to one of the values: "auto", "user", "noresize".
+
+        (Optional) Argument:
+        rmode -- one of the strings "auto", "user", "noresize"
+
+        Different resizemodes have the following effects:
+          - "auto" adapts the appearance of the turtle
+                   corresponding to the value of pensize.
+          - "user" adapts the appearance of the turtle according to the
+                   values of stretchfactor and outlinewidth (outline),
+                   which are set by shapesize()
+          - "noresize" no adaption of the turtle's appearance takes place.
+        If no argument is given, return current resizemode.
+        resizemode("user") is called by a call of shapesize with arguments.
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("noresize")
+        >>> turtle.resizemode()
+        'noresize'
+        """
+        if rmode is None:
+            return self._resizemode
+        rmode = rmode.lower()
+        if rmode in ["auto", "user", "noresize"]:
+            self.pen(resizemode=rmode)
+
+    def pensize(self, width=None):
+        """Set or return the line thickness.
+
+        Aliases:  pensize | width
+
+        Argument:
+        width -- positive number
+
+        Set the line thickness to width or return it. If resizemode is set
+        to "auto" and turtleshape is a polygon, that polygon is drawn with
+        the same line thickness. If no argument is given, current pensize
+        is returned.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pensize()
+        1
+        turtle.pensize(10)   # from here on lines of width 10 are drawn
+        """
+        if width is None:
+            return self._pensize
+        self.pen(pensize=width)
+
+
+    def penup(self):
+        """Pull the pen up -- no drawing when moving.
+
+        Aliases: penup | pu | up
+
+        No argument
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+        """
+        if not self._drawing:
+            return
+        self.pen(pendown=False)
+
+    def pendown(self):
+        """Pull the pen down -- drawing when moving.
+
+        Aliases: pendown | pd | down
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pendown()
+        """
+        if self._drawing:
+            return
+        self.pen(pendown=True)
+
+    def isdown(self):
+        """Return True if pen is down, False if it's up.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+        >>> turtle.isdown()
+        False
+        >>> turtle.pendown()
+        >>> turtle.isdown()
+        True
+        """
+        return self._drawing
+
+    def speed(self, speed=None):
+        """ Return or set the turtle's speed.
+
+        Optional argument:
+        speed -- an integer in the range 0..10 or a speedstring (see below)
+
+        Set the turtle's speed to an integer value in the range 0 .. 10.
+        If no argument is given: return current speed.
+
+        If input is a number greater than 10 or smaller than 0.5,
+        speed is set to 0.
+        Speedstrings  are mapped to speedvalues in the following way:
+            'fastest' :  0
+            'fast'    :  10
+            'normal'  :  6
+            'slow'    :  3
+            'slowest' :  1
+        speeds from 1 to 10 enforce increasingly faster animation of
+        line drawing and turtle turning.
+
+        Attention:
+        speed = 0 : *no* animation takes place. forward/back makes turtle jump
+        and likewise left/right make the turtle turn instantly.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.speed(3)
+        """
+        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
+        if speed is None:
+            return self._speed
+        if speed in speeds:
+            speed = speeds[speed]
+        elif 0.5 < speed < 10.5:
+            speed = int(round(speed))
+        else:
+            speed = 0
+        self.pen(speed=speed)
+
+    def color(self, *args):
+        """Return or set the pencolor and fillcolor.
+
+        Arguments:
+        Several input formats are allowed.
+        They use 0, 1, 2, or 3 arguments as follows:
+
+        color()
+            Return the current pencolor and the current fillcolor
+            as a pair of color specification strings as are returned
+            by pencolor and fillcolor.
+        color(colorstring), color((r,g,b)), color(r,g,b)
+            inputs as in pencolor, set both, fillcolor and pencolor,
+            to the given value.
+        color(colorstring1, colorstring2),
+        color((r1,g1,b1), (r2,g2,b2))
+            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
+            and analogously, if the other input format is used.
+
+        If turtleshape is a polygon, outline and interior of that polygon
+        is drawn with the newly set colors.
+        For mor info see: pencolor, fillcolor
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color('red', 'green')
+        >>> turtle.color()
+        ('red', 'green')
+        >>> colormode(255)
+        >>> color((40, 80, 120), (160, 200, 240))
+        >>> color()
+        ('#285078', '#a0c8f0')
+        """
+        if args:
+            l = len(args)
+            if l == 1:
+                pcolor = fcolor = args[0]
+            elif l == 2:
+                pcolor, fcolor = args
+            elif l == 3:
+                pcolor = fcolor = args
+            pcolor = self._colorstr(pcolor)
+            fcolor = self._colorstr(fcolor)
+            self.pen(pencolor=pcolor, fillcolor=fcolor)
+        else:
+            return self._color(self._pencolor), self._color(self._fillcolor)
+
+    def pencolor(self, *args):
+        """ Return or set the pencolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - pencolor()
+            Return the current pencolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - pencolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - pencolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - pencolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the outline of that polygon is drawn
+        with the newly set pencolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pencolor('brown')
+        >>> tup = (0.2, 0.8, 0.55)
+        >>> turtle.pencolor(tup)
+        >>> turtle.pencolor()
+        '#33cc8c'
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._pencolor:
+                return
+            self.pen(pencolor=color)
+        else:
+            return self._color(self._pencolor)
+
+    def fillcolor(self, *args):
+        """ Return or set the fillcolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - fillcolor()
+            Return the current fillcolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - fillcolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - fillcolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - fillcolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the interior of that polygon is drawn
+        with the newly set fillcolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.fillcolor('violet')
+        >>> col = turtle.pencolor()
+        >>> turtle.fillcolor(col)
+        >>> turtle.fillcolor(0, .5, 0)
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._fillcolor:
+                return
+            self.pen(fillcolor=color)
+        else:
+            return self._color(self._fillcolor)
+
+    def showturtle(self):
+        """Makes the turtle visible.
+
+        Aliases: showturtle | st
 
-from math import * # Also for export
-from time import sleep
-import Tkinter
+        No argument.
 
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> turtle.showturtle()
+        """
+        self.pen(shown=True)
+
+    def hideturtle(self):
+        """Makes the turtle invisible.
+
+        Aliases: hideturtle | ht
+
+        No argument.
+
+        It's a good idea to do this while you're in the
+        middle of a complicated drawing, because hiding
+        the turtle speeds up the drawing observably.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        """
+        self.pen(shown=False)
+
+    def isvisible(self):
+        """Return True if the Turtle is shown, False if it's hidden.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> print turtle.isvisible():
+        False
+        """
+        return self._shown
+
+    def pen(self, pen=None, **pendict):
+        """Return or set the pen's attributes.
+
+        Arguments:
+            pen -- a dictionary with some or all of the below listed keys.
+            **pendict -- one or more keyword-arguments with the below
+                         listed keys as keywords.
+
+        Return or set the pen's attributes in a 'pen-dictionary'
+        with the following key/value pairs:
+           "shown"      :   True/False
+           "pendown"    :   True/False
+           "pencolor"   :   color-string or color-tuple
+           "fillcolor"  :   color-string or color-tuple
+           "pensize"    :   positive number
+           "speed"      :   number in range 0..10
+           "resizemode" :   "auto" or "user" or "noresize"
+           "stretchfactor": (positive number, positive number)
+           "outline"    :   positive number
+           "tilt"       :   number
+
+        This dicionary can be used as argument for a subsequent
+        pen()-call to restore the former pen-state. Moreover one
+        or more of these attributes can be provided as keyword-arguments.
+        This can be used to set several pen attributes in one statement.
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> penstate=turtle.pen()
+        >>> turtle.color("yellow","")
+        >>> turtle.penup()
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> p.pen(penstate, fillcolor="green")
+        >>> p.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+        'stretchfactor': (1,1), 'speed': 3}
+        """
+        _pd =  {"shown"         : self._shown,
+                "pendown"       : self._drawing,
+                "pencolor"      : self._pencolor,
+                "fillcolor"     : self._fillcolor,
+                "pensize"       : self._pensize,
+                "speed"         : self._speed,
+                "resizemode"    : self._resizemode,
+                "stretchfactor" : self._stretchfactor,
+                "outline"       : self._outlinewidth,
+                "tilt"          : self._tilt
+               }
 
-class Error(Exception):
-    pass
+        if not (pen or pendict):
+            return _pd
 
-class RawPen:
+        if isinstance(pen, dict):
+            p = pen
+        else:
+            p = {}
+        p.update(pendict)
 
-    def __init__(self, canvas):
-        self._canvas = canvas
-        self._items = []
-        self._tracing = 1
-        self._arrow = 0
-        self._delay = 10     # default delay for drawing
-        self._angle = 0.0
-        self.degrees()
-        self.reset()
+        _p_buf = {}
+        for key in p:
+            _p_buf[key] = _pd[key]
+
+        if self.undobuffer:
+            self.undobuffer.push(("pen", _p_buf))
+
+        newLine = False
+        if "pendown" in p:
+            if self._drawing != p["pendown"]:
+                newLine = True
+        if "pencolor" in p:
+            if isinstance(p["pencolor"], tuple):
+                p["pencolor"] = self._colorstr((p["pencolor"],))
+            if self._pencolor != p["pencolor"]:
+                newLine = True
+        if "pensize" in p:
+            if self._pensize != p["pensize"]:
+                newLine = True
+        if newLine:
+            self._newLine()
+        if "pendown" in p:
+            self._drawing = p["pendown"]
+        if "pencolor" in p:
+            self._pencolor = p["pencolor"]
+        if "pensize" in p:
+            self._pensize = p["pensize"]
+        if "fillcolor" in p:
+            if isinstance(p["fillcolor"], tuple):
+                p["fillcolor"] = self._colorstr((p["fillcolor"],))
+            self._fillcolor = p["fillcolor"]
+        if "speed" in p:
+            self._speed = p["speed"]
+        if "resizemode" in p:
+            self._resizemode = p["resizemode"]
+        if "stretchfactor" in p:
+            sf = p["stretchfactor"]
+            if isinstance(sf, (int, float)):
+                sf = (sf, sf)
+            self._stretchfactor = sf
+        if "outline" in p:
+            self._outlinewidth = p["outline"]
+        if "shown" in p:
+            self._shown = p["shown"]
+        if "tilt" in p:
+            self._tilt = p["tilt"]
+        self._update()
+
+## three dummy methods to be implemented by child class:
+
+    def _newLine(self, usePos = True):
+        """dummy method - to be overwritten by child class"""
+    def _update(self, count=True, forced=False):
+        """dummy method - to be overwritten by child class"""
+    def _color(self, args):
+        """dummy method - to be overwritten by child class"""
+    def _colorstr(self, args):
+        """dummy method - to be overwritten by child class"""
+
+    width = pensize
+    up = penup
+    pu = penup
+    pd = pendown
+    down = pendown
+    st = showturtle
+    ht = hideturtle
 
-    def degrees(self, fullcircle=360.0):
-        """ Set angle measurement units to degrees.
 
-        Example:
-        >>> turtle.degrees()
-        """
-        # Don't try to change _angle if it is 0, because
-        # _fullcircle might not be set, yet
-        if self._angle:
-            self._angle = (self._angle / self._fullcircle) * fullcircle
-        self._fullcircle = fullcircle
-        self._invradian = pi / (fullcircle * 0.5)
+class _TurtleImage(object):
+    """Helper class: Datatype to store Turtle attributes
+    """
 
-    def radians(self):
-        """ Set the angle measurement units to radians.
+    def __init__(self, screen, shapeIndex):
+        self.screen = screen
+        self._type = None
+        self._setshape(shapeIndex)
+
+    def _setshape(self, shapeIndex):
+        screen = self.screen # RawTurtle.screens[self.screenIndex]
+        self.shapeIndex = shapeIndex
+        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type == "image" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type in ["image", "polygon"]:
+            screen._delete(self._item)
+        elif self._type == "compound":
+            for item in self._item:
+                screen._delete(item)
+        self._type = screen._shapes[shapeIndex]._type
+        if self._type == "polygon":
+            self._item = screen._createpoly()
+        elif self._type == "image":
+            self._item = screen._createimage(screen._shapes["blank"]._data)
+        elif self._type == "compound":
+            self._item = [screen._createpoly() for item in
+                                          screen._shapes[shapeIndex]._data]
+
+
+class RawTurtle(TPen, TNavigator):
+    """Animation part of the RawTurtle.
+    Puts RawTurtle upon a TurtleScreen and provides tools for
+    it's animation.
+    """
+    screens = []
 
-        Example:
-        >>> turtle.radians()
-        """
-        self.degrees(2.0*pi)
+    def __init__(self, canvas=None,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if isinstance(canvas, Screen):
+            self.screen = canvas
+        elif isinstance(canvas, TurtleScreen):
+            if canvas not in RawTurtle.screens:
+                RawTurtle.screens.append(canvas)
+            self.screen = canvas
+        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
+            for screen in RawTurtle.screens:
+                if screen.cv == canvas:
+                    self.screen = screen
+                    break
+            else:
+                self.screen = TurtleScreen(canvas)
+                RawTurtle.screens.append(self.screen)
+        else:
+            raise TurtleGraphicsError("bad cavas argument %s" % canvas)
+
+        screen = self.screen
+        TNavigator.__init__(self, screen.mode())
+        TPen.__init__(self)
+        screen._turtles.append(self)
+        self.drawingLineItem = screen._createline()
+        self.turtle = _TurtleImage(screen, shape)
+        self._poly = None
+        self._creatingPoly = False
+        self._fillitem = self._fillpath = None
+        self._shown = visible
+        self._hidden_from_screen = False
+        self.currentLineItem = screen._createline()
+        self.currentLine = [self._position]
+        self.items = [self.currentLineItem]
+        self.stampItems = []
+        self._undobuffersize = undobuffersize
+        self.undobuffer = Tbuffer(undobuffersize)
+        self._update()
 
     def reset(self):
-        """ Clear the screen, re-center the pen, and set variables to
-        the default values.
+        """Delete the turtle's drawings and restore it's default values.
 
-        Example:
+        No argument.
+,
+        Delete the turtle's drawings from the screen, re-center the turtle
+        and set variables to the default values.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.position()
-        [0.0, -22.0]
+        (0.00,-22.00)
         >>> turtle.heading()
         100.0
         >>> turtle.reset()
         >>> turtle.position()
-        [0.0, 0.0]
+        (0.00,0.00)
         >>> turtle.heading()
         0.0
         """
-        canvas = self._canvas
-        self._canvas.update()
-        width = canvas.winfo_width()
-        height = canvas.winfo_height()
-        if width <= 1:
-            width = canvas['width']
-        if height <= 1:
-            height = canvas['height']
-        self._origin = float(width)/2.0, float(height)/2.0
-        self._position = self._origin
-        self._angle = 0.0
-        self._drawing = 1
-        self._width = 1
-        self._color = "black"
-        self._filling = 0
-        self._path = []
-        self.clear()
-        canvas._root().tkraise()
-
-    def clear(self):
-        """ Clear the screen. The turtle does not move.
-
-        Example:
-        >>> turtle.clear()
-        """
-        self.fill(0)
-        canvas = self._canvas
-        items = self._items
-        self._items = []
-        for item in items:
-            canvas.delete(item)
-        self._delete_turtle()
-        self._draw_turtle()
-
-    def tracer(self, flag):
-        """ Set tracing on if flag is True, and off if it is False.
-        Tracing means line are drawn more slowly, with an
-        animation of an arrow along the line.
-
-        Example:
-        >>> turtle.tracer(False)   # turns off Tracer
-        """
-        self._tracing = flag
-        if not self._tracing:
-            self._delete_turtle()
-        self._draw_turtle()
-
-    def forward(self, distance):
-        """ Go forward distance steps.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.forward(25)
-        >>> turtle.position()
-        [25.0, 0.0]
-        >>> turtle.forward(-75)
-        >>> turtle.position()
-        [-50.0, 0.0]
-        """
-        x0, y0 = start = self._position
-        x1 = x0 + distance * cos(self._angle*self._invradian)
-        y1 = y0 - distance * sin(self._angle*self._invradian)
-        self._goto(x1, y1)
+        TNavigator.reset(self)
+        TPen._reset(self)
+        self._clear()
+        self._drawturtle()
+        self._update()
+
+    def setundobuffer(self, size):
+        """Set or disable undobuffer.
+
+        Argument:
+        size -- an integer or None
+
+        If size is an integer an empty undobuffer of given size is installed.
+        Size gives the maximum number of turtle-actions that can be undone
+        by the undo() function.
+        If size is None, no undobuffer is present.
 
-    def backward(self, distance):
-        """ Go backwards distance steps.
-
-        The turtle's heading does not change.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.backward(30)
-        >>> turtle.position()
-        [-30.0, 0.0]
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setundobuffer(42)
         """
-        self.forward(-distance)
-
-    def left(self, angle):
-        """ Turn left angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
-
-        When viewed from above, the turning happens in-place around
-        its front tip.
+        if size is None:
+            self.undobuffer = None
+        else:
+            self.undobuffer = Tbuffer(size)
 
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.left(45)
-        >>> turtle.heading()
-        67.0
-        """
-        self._angle = (self._angle + angle) % self._fullcircle
-        self._draw_turtle()
+    def undobufferentries(self):
+        """Return count of entries in the undobuffer.
 
-    def right(self, angle):
-        """ Turn right angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
+        No argument.
 
-        When viewed from above, the turning happens in-place around
-        its front tip.
+        Example (for a Turtle instance named turtle):
+        >>> while undobufferentries():
+                undo()
+        """
+        if self.undobuffer is None:
+            return 0
+        return self.undobuffer.nr_of_items()
+
+    def _clear(self):
+        """Delete all of pen's drawings"""
+        self._fillitem = self._fillpath = None
+        for item in self.items:
+            self.screen._delete(item)
+        self.currentLineItem = self.screen._createline()
+        self.currentLine = []
+        if self._drawing:
+            self.currentLine.append(self._position)
+        self.items = [self.currentLineItem]
+        self.clearstamps()
+        self.setundobuffer(self._undobuffersize)
 
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.right(45)
-        >>> turtle.heading()
-        337.0
-        """
-        self.left(-angle)
 
-    def up(self):
-        """ Pull the pen up -- no drawing when moving.
+    def clear(self):
+        """Delete the turtle's drawings from the screen. Do not move turtle.
 
-        Example:
-        >>> turtle.up()
-        """
-        self._drawing = 0
+        No arguments.
 
-    def down(self):
-        """ Put the pen down -- draw when moving.
+        Delete the turtle's drawings from the screen. Do not move turtle.
+        State and position of the turtle as well as drawings of other
+        turtles are not affected.
 
-        Example:
-        >>> turtle.down()
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.clear()
         """
-        self._drawing = 1
+        self._clear()
+        self._update()
 
-    def width(self, width):
-        """ Set the line to thickness to width.
+    def _update_data(self):
+        self.screen._incrementudc()
+        if self.screen._updatecounter != 0:
+            return
+        if len(self.currentLine)>1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                  self._pencolor, self._pensize)
 
-        Example:
-        >>> turtle.width(10)
+    def _update(self):
+        """Perform a Turtle-data update.
         """
-        self._width = float(width)
-
-    def color(self, *args):
-        """ Set the pen color.
-
-        Three input formats are allowed:
-
-            color(s)
-            s is a Tk specification string, such as "red" or "yellow"
-
-            color((r, g, b))
-            *a tuple* of r, g, and b, which represent, an RGB color,
-            and each of r, g, and b are in the range [0..1]
-
-            color(r, g, b)
-            r, g, and b represent an RGB color, and each of r, g, and b
-            are in the range [0..1]
+        screen = self.screen
+        if screen._tracing == 0:
+            return
+        elif screen._tracing == 1:
+            self._update_data()
+            self._drawturtle()
+            screen._update()                  # TurtleScreenBase
+            screen._delay(screen._delayvalue) # TurtleScreenBase
+        else:
+            self._update_data()
+            if screen._updatecounter == 0:
+                for t in screen.turtles():
+                    t._drawturtle()
+                screen._update()
+
+    def tracer(self, flag=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                turtle.fd(dist)
+                turtle.rt(90)
+                dist += 2
+        """
+        return self.screen.tracer(flag, delay)
+
+    def _color(self, args):
+        return self.screen._color(args)
 
-        Example:
+    def _colorstr(self, args):
+        return self.screen._colorstr(args)
 
-        >>> turtle.color('brown')
-        >>> tup = (0.2, 0.8, 0.55)
-        >>> turtle.color(tup)
-        >>> turtle.color(0, .5, 0)
+    def _cc(self, args):
+        """Convert colortriples to hexstrings.
         """
-        if not args:
-            raise Error, "no color arguments"
-        if len(args) == 1:
-            color = args[0]
-            if type(color) == type(""):
-                # Test the color first
-                try:
-                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
-                except Tkinter.TclError:
-                    raise Error, "bad color string: %r" % (color,)
-                self._set_color(color)
+        if isinstance(args, str):
+            return args
+        try:
+            r, g, b = args
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
+        if self.screen._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def clone(self):
+        """Create and return a clone of the turtle.
+
+        No argument.
+
+        Create and return a clone of the turtle with same position, heading
+        and turtle properties.
+
+        Example (for a Turtle instance named mick):
+        mick = Turtle()
+        joe = mick.clone()
+        """
+        screen = self.screen
+        self._newLine(self._drawing)
+
+        turtle = self.turtle
+        self.screen = None
+        self.turtle = None  # too make self deepcopy-able
+
+        q = deepcopy(self)
+
+        self.screen = screen
+        self.turtle = turtle
+
+        q.screen = screen
+        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
+
+        screen._turtles.append(q)
+        ttype = screen._shapes[self.turtle.shapeIndex]._type
+        if ttype == "polygon":
+            q.turtle._item = screen._createpoly()
+        elif ttype == "image":
+            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
+        elif ttype == "compound":
+            q.turtle._item = [screen._createpoly() for item in
+                              screen._shapes[self.turtle.shapeIndex]._data]
+        q.currentLineItem = screen._createline()
+        q._update()
+        return q
+
+    def shape(self, name=None):
+        """Set turtle shape to shape with given name / return current shapename.
+
+        Optional argument:
+        name -- a string, which is a valid shapename
+
+        Set turtle shape to shape with given name or, if name is not given,
+        return name of current shape.
+        Shape with name must exist in the TurtleScreen's shape dictionary.
+        Initially there are the following polygon shapes:
+        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
+        To learn about how to deal with shapes see Screen-method register_shape.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.shape()
+        'arrow'
+        >>> turtle.shape("turtle")
+        >>> turtle.shape()
+        'turtle'
+        """
+        if name is None:
+            return self.turtle.shapeIndex
+        if not name in self.screen.getshapes():
+            raise TurtleGraphicsError("There is no shape named %s" % name)
+        self.turtle._setshape(name)
+        self._update()
+
+    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
+        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
+
+        Optinonal arguments:
+           stretch_wid : positive number
+           stretch_len : positive number
+           outline  : positive number
+
+        Return or set the pen's attributes x/y-stretchfactors and/or outline.
+        Set resizemode to "user".
+        If and only if resizemode is set to "user", the turtle will be displayed
+        stretched according to its stretchfactors:
+        stretch_wid is stretchfactor perpendicular to orientation
+        stretch_len is stretchfactor in direction of turtles orientation.
+        outline determines the width of the shapes's outline.
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("user")
+        >>> turtle.shapesize(5, 5, 12)
+        >>> turtle.shapesize(outline=8)
+        """
+        if stretch_wid is None and stretch_len is None and outline == None:
+            stretch_wid, stretch_len = self._stretchfactor
+            return stretch_wid, stretch_len, self._outlinewidth
+        if stretch_wid is not None:
+            if stretch_len is None:
+                stretchfactor = stretch_wid, stretch_wid
+            else:
+                stretchfactor = stretch_wid, stretch_len
+        elif stretch_len is not None:
+            stretchfactor = self._stretchfactor[0], stretch_len
+        else:
+            stretchfactor = self._stretchfactor
+        if outline is None:
+            outline = self._outlinewidth
+        self.pen(resizemode="user",
+                 stretchfactor=stretchfactor, outline=outline)
+
+    def settiltangle(self, angle):
+        """Rotate the turtleshape to point in the specified direction
+
+        Optional argument:
+        angle -- number
+
+        Rotate the turtleshape to point in the direction specified by angle,
+        regardless of its current tilt-angle. DO NOT change the turtle's
+        heading (direction of movement).
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.settiltangle(45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        >>> turtle.settiltangle(-45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        """
+        tilt = -angle * self._degreesPerAU * self._angleOrient
+        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
+        self.pen(resizemode="user", tilt=tilt)
+
+    def tiltangle(self):
+        """Return the current tilt-angle.
+
+        No argument.
+
+        Return the current tilt-angle, i. e. the angle between the
+        orientation of the turtleshape and the heading of the turtle
+        (it's direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(45)
+        >>> turtle.tiltangle()
+        >>>
+        """
+        tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
+        return (tilt / self._degreesPerAU) % self._fullcircle
+
+    def tilt(self, angle):
+        """Rotate the turtleshape by angle.
+
+        Argument:
+        angle - a number
+
+        Rotate the turtleshape by angle from its current tilt-angle,
+        but do NOT change the turtle's heading (direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        """
+        self.settiltangle(angle + self.tiltangle())
+
+    def _polytrafo(self, poly):
+        """Computes transformed polygon shapes from a shape
+        according to current position and heading.
+        """
+        screen = self.screen
+        p0, p1 = self._position
+        e0, e1 = self._orient
+        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
+        e0, e1 = (1.0 / abs(e)) * e
+        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
+                                                           for (x, y) in poly]
+
+    def _drawturtle(self):
+        """Manages the correct rendering of the turtle with respect to
+        it's shape, resizemode, strech and tilt etc."""
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        titem = self.turtle._item
+        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
+            self._hidden_from_screen = False
+            tshape = shape._data
+            if ttype == "polygon":
+                if self._resizemode == "noresize":
+                    w = 1
+                    shape = tshape
+                else:
+                    if self._resizemode == "auto":
+                        lx = ly = max(1, self._pensize/5.0)
+                        w = self._pensize
+                        tiltangle = 0
+                    elif self._resizemode == "user":
+                        lx, ly = self._stretchfactor
+                        w = self._outlinewidth
+                        tiltangle = self._tilt
+                    shape = [(lx*x, ly*y) for (x, y) in tshape]
+                    t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                    shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+                shape = self._polytrafo(shape)
+                fc, oc = self._fillcolor, self._pencolor
+                screen._drawpoly(titem, shape, fill=fc, outline=oc,
+                                                      width=w, top=True)
+            elif ttype == "image":
+                screen._drawimage(titem, self._position, tshape)
+            elif ttype == "compound":
+                lx, ly = self._stretchfactor
+                w = self._outlinewidth
+                for item, (poly, fc, oc) in zip(titem, tshape):
+                    poly = [(lx*x, ly*y) for (x, y) in poly]
+                    poly = self._polytrafo(poly)
+                    screen._drawpoly(item, poly, fill=self._cc(fc),
+                                     outline=self._cc(oc), width=w, top=True)
+        else:
+            if self._hidden_from_screen:
                 return
-            try:
-                r, g, b = color
-            except:
-                raise Error, "bad color sequence: %r" % (color,)
+            if ttype == "polygon":
+                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
+            elif ttype == "image":
+                screen._drawimage(titem, self._position,
+                                          screen._shapes["blank"]._data)
+            elif ttype == "compound":
+                for item in titem:
+                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
+            self._hidden_from_screen = True
+
+##############################  stamp stuff  ###############################
+
+    def stamp(self):
+        """Stamp a copy of the turtleshape onto the canvas and return it's id.
+
+        No argument.
+
+        Stamp a copy of the turtle shape onto the canvas at the current
+        turtle position. Return a stamp_id for that stamp, which can be
+        used to delete it by calling clearstamp(stamp_id).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> turtle.stamp()
+        13
+        >>> turtle.fd(50)
+        """
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        tshape = shape._data
+        if ttype == "polygon":
+            stitem = screen._createpoly()
+            if self._resizemode == "noresize":
+                w = 1
+                shape = tshape
+            else:
+                if self._resizemode == "auto":
+                    lx = ly = max(1, self._pensize/5.0)
+                    w = self._pensize
+                    tiltangle = 0
+                elif self._resizemode == "user":
+                    lx, ly = self._stretchfactor
+                    w = self._outlinewidth
+                    tiltangle = self._tilt
+                shape = [(lx*x, ly*y) for (x, y) in tshape]
+                t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+            shape = self._polytrafo(shape)
+            fc, oc = self._fillcolor, self._pencolor
+            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
+                                                  width=w, top=True)
+        elif ttype == "image":
+            stitem = screen._createimage("")
+            screen._drawimage(stitem, self._position, tshape)
+        elif ttype == "compound":
+            stitem = []
+            for element in tshape:
+                item = screen._createpoly()
+                stitem.append(item)
+            stitem = tuple(stitem)
+            lx, ly = self._stretchfactor
+            w = self._outlinewidth
+            for item, (poly, fc, oc) in zip(stitem, tshape):
+                poly = [(lx*x, ly*y) for (x, y) in poly]
+                poly = self._polytrafo(poly)
+                screen._drawpoly(item, poly, fill=self._cc(fc),
+                                 outline=self._cc(oc), width=w, top=True)
+        self.stampItems.append(stitem)
+        self.undobuffer.push(("stamp", stitem))
+        return stitem
+
+    def _clearstamp(self, stampid):
+        """does the work for clearstamp() and clearstamps()
+        """
+        if stampid in self.stampItems:
+            if isinstance(stampid, tuple):
+                for subitem in stampid:
+                    self.screen._delete(subitem)
+            else:
+                self.screen._delete(stampid)
+            self.stampItems.remove(stampid)
+        # Delete stampitem from undobuffer if necessary
+        # if clearstamp is called directly.
+        item = ("stamp", stampid)
+        buf = self.undobuffer
+        if item not in buf.buffer:
+            return
+        index = buf.buffer.index(item)
+        buf.buffer.remove(item)
+        if index <= buf.ptr:
+            buf.ptr = (buf.ptr - 1) % buf.bufsize
+        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
+
+    def clearstamp(self, stampid):
+        """Delete stamp with given stampid
+
+        Argument:
+        stampid - an integer, must be return value of previous stamp() call.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> astamp = turtle.stamp()
+        >>> turtle.fd(50)
+        >>> turtle.clearstamp(astamp)
+        """
+        self._clearstamp(stampid)
+        self._update()
+
+    def clearstamps(self, n=None):
+        """Delete all or first/last n of turtle's stamps.
+
+        Optional argument:
+        n -- an integer
+
+        If n is None, delete all of pen's stamps,
+        else if n > 0 delete first n stamps
+        else if n < 0 delete last n stamps.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(8):
+                turtle.stamp(); turtle.fd(30)
+        ...
+        >>> turtle.clearstamps(2)
+        >>> turtle.clearstamps(-2)
+        >>> turtle.clearstamps()
+        """
+        if n is None:
+            toDelete = self.stampItems[:]
+        elif n >= 0:
+            toDelete = self.stampItems[:n]
         else:
-            try:
-                r, g, b = args
-            except:
-                raise Error, "bad color arguments: %r" % (args,)
-        assert 0 <= r <= 1
-        assert 0 <= g <= 1
-        assert 0 <= b <= 1
-        x = 255.0
-        y = 0.5
-        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
-
-    def _set_color(self,color):
-        self._color = color
-        self._draw_turtle()
+            toDelete = self.stampItems[n:]
+        for item in toDelete:
+            self._clearstamp(item)
+        self._update()
+
+    def _goto(self, end):
+        """Move the pen to the point end, thereby drawing a line
+        if pen is down. All other methodes for turtle movement depend
+        on this one.
+        """
+        ## Version mit undo-stuff
+        go_modes = ( self._drawing,
+                     self._pencolor,
+                     self._pensize,
+                     isinstance(self._fillpath, list))
+        screen = self.screen
+        undo_entry = ("go", self._position, end, go_modes,
+                      (self.currentLineItem,
+                      self.currentLine[:],
+                      screen._pointlist(self.currentLineItem),
+                      self.items[:])
+                      )
+        if self.undobuffer:
+            self.undobuffer.push(undo_entry)
+        start = self._position
+        if self._speed and screen._tracing == 1:
+            diff = (end-start)
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = start + delta * n
+                if self._drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     self._pencolor, self._pensize, top)
+                self._update()
+            if self._drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=self._pensize)
+        # Turtle now at end,
+        if self._drawing: # now update currentLine
+            self.currentLine.append(end)
+        if isinstance(self._fillpath, list):
+            self._fillpath.append(end)
+        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
+        self._position = end
+        if self._creatingPoly:
+            self._poly.append(end)
+        if len(self.currentLine) > 42: # 42! answer to the ultimate question
+                                       # of life, the universe and everything
+            self._newLine()
+        self._update() #count=True)
+
+    def _undogoto(self, entry):
+        """Reverse a _goto. Used for undo()
+        """
+        old, new, go_modes, coodata = entry
+        drawing, pc, ps, filling = go_modes
+        cLI, cL, pl, items = coodata
+        screen = self.screen
+        if abs(self._position - new) > 0.5:
+            print "undogoto: HALLO-DA-STIMMT-WAS-NICHT!"
+        # restore former situation
+        self.currentLineItem = cLI
+        self.currentLine = cL
 
-    def write(self, text, move=False):
-        """ Write text at the current pen position.
-
-        If move is true, the pen is moved to the bottom-right corner
-        of the text. By default, move is False.
+        if pl == [(0, 0), (0, 0)]:
+            usepc = ""
+        else:
+            usepc = pc
+        screen._drawline(cLI, pl, fill=usepc, width=ps)
 
-        Example:
-        >>> turtle.write('The race is on!')
-        >>> turtle.write('Home = (0, 0)', True)
-        """
-        x, y  = self._position
-        x = x-1 # correction -- calibrated for Windows
-        item = self._canvas.create_text(x, y,
-                                        text=str(text), anchor="sw",
-                                        fill=self._color)
-        self._items.append(item)
-        if move:
-            x0, y0, x1, y1 = self._canvas.bbox(item)
-            self._goto(x1, y1)
-        self._draw_turtle()
-
-    def fill(self, flag):
-        """ Call fill(1) before drawing the shape you
-         want to fill, and fill(0) when done.
+        todelete = [i for i in self.items if (i not in items) and
+                                       (screen._type(i) == "line")]
+        for i in todelete:
+            screen._delete(i)
+            self.items.remove(i)
+
+        start = old
+        if self._speed and screen._tracing == 1:
+            diff = old - new
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = new + delta * n
+                if drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     pc, ps, top)
+                self._update()
+            if drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=ps)
+        # Turtle now at position old,
+        self._position = old
+        ##  if undo is done during crating a polygon, the last vertex
+        ##  will be deleted. if the polygon is entirel deleted,
+        ##  creatigPoly will be set to False.
+        ##  Polygons created before the last one will not be affected by undo()
+        if self._creatingPoly:
+            if len(self._poly) > 0:
+                self._poly.pop()
+            if self._poly == []:
+                self._creatingPoly = False
+                self._poly = None
+        if filling:
+            if self._fillpath == []:
+                self._fillpath = None
+                print "Unwahrscheinlich in _undogoto!"
+            elif self._fillpath is not None:
+                self._fillpath.pop()
+        self._update() #count=True)
+
+    def _rotate(self, angle):
+        """Turns pen clockwise by angle.
+        """
+        if self.undobuffer:
+            self.undobuffer.push(("rot", angle, self._degreesPerAU))
+        angle *= self._degreesPerAU
+        neworient = self._orient.rotate(angle)
+        tracing = self.screen._tracing
+        if tracing == 1 and self._speed > 0:
+            anglevel = 3.0 * self._speed
+            steps = 1 + int(abs(angle)/anglevel)
+            delta = 1.0*angle/steps
+            for _ in range(steps):
+                self._orient = self._orient.rotate(delta)
+                self._update()
+        self._orient = neworient
+        self._update()
+
+    def _newLine(self, usePos=True):
+        """Closes current line item and starts a new one.
+           Remark: if current line became too long, animation
+           performance (via _drawline) slowed down considerably.
+        """
+        if len(self.currentLine) > 1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                      self._pencolor, self._pensize)
+            self.currentLineItem = self.screen._createline()
+            self.items.append(self.currentLineItem)
+        else:
+            self.screen._drawline(self.currentLineItem, top=True)
+        self.currentLine = []
+        if usePos:
+            self.currentLine = [self._position]
+
+    def fill(self, flag=None):
+        """Call fill(True) before drawing a shape to fill, fill(False) when done.
+
+        Optional argument:
+        flag -- True/False (or 1/0 respectively)
+
+        Call fill(True) before drawing the shape you want to fill,
+        and  fill(False) when done.
+        When used without argument: return fillstate (True if filling,
+        False else)
 
-        Example:
-        >>> turtle.fill(1)
+        Example (for a Turtle instance named turtle):
+        >>> turtle.fill(True)
         >>> turtle.forward(100)
         >>> turtle.left(90)
         >>> turtle.forward(100)
@@ -296,27 +3144,43 @@
         >>> turtle.forward(100)
         >>> turtle.left(90)
         >>> turtle.forward(100)
-        >>> turtle.fill(0)
+        >>> turtle.fill(False)
         """
-        if self._filling:
-            path = tuple(self._path)
-            smooth = self._filling < 0
-            if len(path) > 2:
-                item = self._canvas._create('polygon', path,
-                                            {'fill': self._color,
-                                             'smooth': smooth})
-                self._items.append(item)
-        self._path = []
-        self._filling = flag
+        filling = isinstance(self._fillpath, list)
+        if flag is None:
+            return filling
+        screen = self.screen
+        entry1 = entry2 = ()
+        if filling:
+            if len(self._fillpath) > 2:
+                self.screen._drawpoly(self._fillitem, self._fillpath,
+                                      fill=self._fillcolor)
+                entry1 = ("dofill", self._fillitem)
         if flag:
-            self._path.append(self._position)
+            self._fillitem = self.screen._createpoly()
+            self.items.append(self._fillitem)
+            self._fillpath = [self._position]
+            entry2 = ("beginfill", self._fillitem) # , self._fillpath)
+            self._newLine()
+        else:
+            self._fillitem = self._fillpath = None
+        if self.undobuffer:
+            if entry1 == ():
+                if entry2 != ():
+                    self.undobuffer.push(entry2)
+            else:
+                if entry2 == ():
+                    self.undobuffer.push(entry1)
+                else:
+                    self.undobuffer.push(["seq", entry1, entry2])
+        self._update()
 
     def begin_fill(self):
-        """ Called just before drawing a shape to be filled.
-            Must eventually be followed by a corresponding end_fill() call.
-            Otherwise it will be ignored.
+        """Called just before drawing a shape to be filled.
 
-        Example:
+        No argument.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.begin_fill()
         >>> turtle.forward(100)
         >>> turtle.left(90)
@@ -327,13 +3191,14 @@
         >>> turtle.forward(100)
         >>> turtle.end_fill()
         """
-        self._path = [self._position]
-        self._filling = 1
+        self.fill(True)
 
     def end_fill(self):
-        """ Called after drawing a shape to be filled.
+        """Fill the shape drawn after the call begin_fill().
 
-        Example:
+        No argument.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.begin_fill()
         >>> turtle.forward(100)
         >>> turtle.left(90)
@@ -344,613 +3209,820 @@
         >>> turtle.forward(100)
         >>> turtle.end_fill()
         """
-        self.fill(0)
+        self.fill(False)
 
-    def circle(self, radius, extent = None):
-        """ Draw a circle with given radius.
-        The center is radius units left of the turtle; extent
-        determines which part of the circle is drawn. If not given,
-        the entire circle is drawn.
+    def dot(self, size=None, *color):
+        """Draw a dot with diameter size, using color.
 
-        If extent is not a full circle, one endpoint of the arc is the
-        current pen position. The arc is drawn in a counter clockwise
-        direction if radius is positive, otherwise in a clockwise
-        direction. In the process, the direction of the turtle is
-        changed by the amount of the extent.
+        Optional argumentS:
+        size -- an integer >= 1 (if given)
+        color -- a colorstring or a numeric color tuple
+
+        Draw a circular dot with diameter size, using color.
+        If size is not given, the maximum of pensize+4 and 2*pensize is used.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.dot()
+        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+        """
+        #print "dot-1:", size, color
+        if not color:
+            if isinstance(size, (str, tuple)):
+                color = self._colorstr(size)
+                size = self._pensize + max(self._pensize, 4)
+            else:
+                color = self._pencolor
+                if not size:
+                    size = self._pensize + max(self._pensize, 4)
+        else:
+            if size is None:
+                size = self._pensize + max(self._pensize, 4)
+            color = self._colorstr(color)
+        #print "dot-2:", size, color
+        if hasattr(self.screen, "_dot"):
+            item = self.screen._dot(self._position, size, color)
+            #print "dot:", size, color, "item:", item
+            self.items.append(item)
+            if self.undobuffer:
+                self.undobuffer.push(("dot", item))
+        else:
+            pen = self.pen()
+            if self.undobuffer:
+                self.undobuffer.push(["seq"])
+                self.undobuffer.cumulate = True
+            try:
+                if self.resizemode() == 'auto':
+                    self.ht()
+                self.pendown()
+                self.pensize(size)
+                self.pencolor(color)
+                self.forward(0)
+            finally:
+                self.pen(pen)
+            if self.undobuffer:
+                self.undobuffer.cumulate = False
+
+    def _write(self, txt, align, font):
+        """Performs the writing for write()
+        """
+        item, end = self.screen._write(self._position, txt, align, font,
+                                                          self._pencolor)
+        self.items.append(item)
+        if self.undobuffer:
+            self.undobuffer.push(("wri", item))
+        return end
+
+    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
+        """Write text at the current turtle position.
+
+        Arguments:
+        arg -- info, which is to be written to the TurtleScreen
+        move (optional) -- True/False
+        align (optional) -- one of the strings "left", "center" or right"
+        font (optional) -- a triple (fontname, fontsize, fonttype)
+
+        Write text - the string representation of arg - at the current
+        turtle position according to align ("left", "center" or right")
+        and with the given font.
+        If move is True, the pen is moved to the bottom-right corner
+        of the text. By default, move is False.
 
-        >>> turtle.circle(50)
-        >>> turtle.circle(120, 180)  # half a circle
+        Example (for a Turtle instance named turtle):
+        >>> turtle.write('Home = ', True, align="center")
+        >>> turtle.write((0,0), True)
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        end = self._write(str(arg), align.lower(), font)
+        if move:
+            x, y = self.pos()
+            self.setpos(end, y)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
+
+    def begin_poly(self):
+        """Start recording the vertices of a polygon.
+
+        No argument.
+
+        Start recording the vertices of a polygon. Current turtle position
+        is first point of polygon.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.begin_poly()
         """
-        if extent is None:
-            extent = self._fullcircle
-        frac = abs(extent)/self._fullcircle
-        steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
-        w = 1.0 * extent / steps
-        w2 = 0.5 * w
-        l = 2.0 * radius * sin(w2*self._invradian)
-        if radius < 0:
-            l, w, w2 = -l, -w, -w2
-        self.left(w2)
-        for i in range(steps):
-            self.forward(l)
-            self.left(w)
-        self.right(w2)
+        self._poly = [self._position]
+        self._creatingPoly = True
 
-    def heading(self):
-        """ Return the turtle's current heading.
+    def end_poly(self):
+        """Stop recording the vertices of a polygon.
 
-        Example:
-        >>> turtle.heading()
-        67.0
+        No argument.
+
+        Stop recording the vertices of a polygon. Current turtle position is
+        last point of polygon. This will be connected with the first point.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.end_poly()
         """
-        return self._angle
+        self._creatingPoly = False
 
-    def setheading(self, angle):
-        """ Set the turtle facing the given angle.
+    def get_poly(self):
+        """Return the lastly recorded polygon.
 
-        Here are some common directions in degrees:
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> p = turtle.get_poly()
+        >>> turtle.register_shape("myFavouriteShape", p)
+        """
+        ## check if there is any poly?  -- 1st solution:
+        if self._poly is not None:
+            return tuple(self._poly)
+
+    def getscreen(self):
+        """Return the TurtleScreen object, the turtle is drawing  on.
+
+        No argument.
 
-           0 - east
-          90 - north
-         180 - west
-         270 - south
+        Return the TurtleScreen object, the turtle is drawing  on.
+        So TurtleScreen-methods can be called for that object.
+
+        Example (for a Turtle instance named turtle):
+        >>> ts = turtle.getscreen()
+        >>> ts
+        <turtle.TurtleScreen object at 0x0106B770>
+        >>> ts.bgcolor("pink")
+        """
+        return self.screen
+
+    def getturtle(self):
+        """Return the Turtleobject itself.
+
+        No argument.
+
+        Only reasonable use: as a function to return the 'anonymous turtle':
 
         Example:
-        >>> turtle.setheading(90)
-        >>> turtle.heading()
-        90
-        >>> turtle.setheading(128)
-        >>> turtle.heading()
-        128
+        >>> pet = getturtle()
+        >>> pet.fd(50)
+        >>> pet
+        <turtle.Turtle object at 0x0187D810>
+        >>> turtles()
+        [<turtle.Turtle object at 0x0187D810>]
         """
-        self._angle = angle
-        self._draw_turtle()
+        return self
+
+    getpen = getturtle
+
+
+    ################################################################
+    ### screen oriented methods recurring to methods of TurtleScreen
+    ################################################################
 
     def window_width(self):
         """ Returns the width of the turtle window.
 
-        Example:
-        >>> turtle.window_width()
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_width()
         640
         """
-        width = self._canvas.winfo_width()
-        if width <= 1:  # the window isn't managed by a geometry manager
-            width = self._canvas['width']
-        return width
+        return self.screen._window_size()[0]
 
     def window_height(self):
         """ Return the height of the turtle window.
 
-        Example:
-        >>> turtle.window_height()
-        768
-        """
-        height = self._canvas.winfo_height()
-        if height <= 1: # the window isn't managed by a geometry manager
-            height = self._canvas['height']
-        return height
+        No argument.
 
-    def position(self):
-        """ Return the current (x, y) location of the turtle.
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_height()
+        480
+        """
+        return self.screen._window_size()[1]
 
-        Example:
-        >>> turtle.position()
-        [0.0, 240.0]
+    def _delay(self, delay=None):
+        """Set delay value which determines speed of turtle animation.
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        return [x1-x0, -y1+y0]
+        return self.screen.delay(delay)
 
-    def setx(self, xpos):
-        """ Set the turtle's x coordinate to be xpos.
+    #####   event binding methods   #####
 
-        Example:
-        >>> turtle.position()
-        [10.0, 240.0]
-        >>> turtle.setx(10)
-        >>> turtle.position()
-        [10.0, 240.0]
-        """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x0+xpos, y1)
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on this turtle on canvas.
 
-    def sety(self, ypos):
-        """ Set the turtle's y coordinate to be ypos.
+        Arguments:
+        fun --  a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.sety(-22)
-        >>> turtle.position()
-        [0.0, -22.0]
+        Example for the anonymous turtle, i. e. the procedural way:
+
+        >>> def turn(x, y):
+                left(360)
+
+        >>> onclick(turn) # Now clicking into the turtle will turn it.
+        >>> onclick(None)  # event-binding will be removed
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x1, y0-ypos)
+        self.screen._onclick(self.turtle._item, fun, btn, add)
+        self._update()
 
-    def towards(self, *args):
-        """Returs the angle, which corresponds to the line
-        from turtle-position to point (x,y).
+    def onrelease(self, fun, btn=1, add=None):
+        """Bind fun to mouse-button-release event on this turtle on canvas.
 
-        Argument can be two coordinates or one pair of coordinates
-        or a RawPen/Pen instance.
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
 
-        Example:
-        >>> turtle.position()
-        [10.0, 10.0]
-        >>> turtle.towards(0,0)
-        225.0
+        Example (for a MyTurtle instance named joe):
+        >>> class MyTurtle(Turtle):
+                def glow(self,x,y):
+                        self.fillcolor("red")
+                def unglow(self,x,y):
+                        self.fillcolor("")
+
+        >>> joe = MyTurtle()
+        >>> joe.onclick(joe.glow)
+        >>> joe.onrelease(joe.unglow)
+        ### clicking on joe turns fillcolor red,
+        ### unclicking turns it to transparent.
         """
-        if len(args) == 2:
-            x, y = args
-        else:
-            arg = args[0]
-            if isinstance(arg, RawPen):
-                x, y = arg.position()
-            else:
-                x, y = arg
-        x0, y0 = self.position()
-        dx = x - x0
-        dy = y - y0
-        return (atan2(dy,dx) / self._invradian) % self._fullcircle
+        self.screen._onrelease(self.turtle._item, fun, btn, add)
+        self._update()
 
-    def goto(self, *args):
-        """ Go to the given point.
+    def ondrag(self, fun, btn=1, add=None):
+        """Bind fun to mouse-move event on this turtle on canvas.
 
-        If the pen is down, then a line will be drawn. The turtle's
-        orientation does not change.
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+               the coordinates of the clicked point on the canvas.
+        num -- number of the mouse-button defaults to 1 (left mouse button).
 
-        Two input formats are accepted:
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
 
-           goto(x, y)
-           go to point (x, y)
+        Example (for a Turtle instance named turtle):
+        >>> turtle.ondrag(turtle.goto)
 
-           goto((x, y))
-           go to point (x, y)
+        ### Subsequently clicking and dragging a Turtle will
+        ### move it across the screen thereby producing handdrawings
+        ### (if pen is down).
+        """
+        self.screen._ondrag(self.turtle._item, fun, btn, add)
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.goto(50, -45)
-        >>> turtle.position()
-        [50.0, -45.0]
+
+    def _undo(self, action, data):
+        """Does the main part of the work for undo()
         """
-        if len(args) == 1:
-            try:
-                x, y = args[0]
-            except:
-                raise Error, "bad point argument: %r" % (args[0],)
-        else:
-            try:
-                x, y = args
-            except:
-                raise Error, "bad coordinates: %r" % (args[0],)
-        x0, y0 = self._origin
-        self._goto(x0+x, y0-y)
-
-    def _goto(self, x1, y1):
-        x0, y0 = self._position
-        self._position = map(float, (x1, y1))
-        if self._filling:
-            self._path.append(self._position)
-        if self._drawing:
-            if self._tracing:
-                dx = float(x1 - x0)
-                dy = float(y1 - y0)
-                distance = hypot(dx, dy)
-                nhops = int(distance)
-                item = self._canvas.create_line(x0, y0, x0, y0,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-                try:
-                    for i in range(1, 1+nhops):
-                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
-                        self._canvas.coords(item, x0, y0, x, y)
-                        self._draw_turtle((x,y))
-                        self._canvas.update()
-                        self._canvas.after(self._delay)
-                    # in case nhops==0
-                    self._canvas.coords(item, x0, y0, x1, y1)
-                    self._canvas.itemconfigure(item, arrow="none")
-                except Tkinter.TclError:
-                    # Probably the window was closed!
-                    return
-            else:
-                item = self._canvas.create_line(x0, y0, x1, y1,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-            self._items.append(item)
-        self._draw_turtle()
-
-    def speed(self, speed):
-        """ Set the turtle's speed.
-
-        speed must one of these five strings:
-
-            'fastest' is a 0 ms delay
-            'fast' is a 5 ms delay
-            'normal' is a 10 ms delay
-            'slow' is a 15 ms delay
-            'slowest' is a 20 ms delay
+        if self.undobuffer is None:
+            return
+        if action == "rot":
+            angle, degPAU = data
+            self._rotate(-angle*degPAU/self._degreesPerAU)
+            dummy = self.undobuffer.pop()
+        elif action == "stamp":
+            stitem = data[0]
+            self.clearstamp(stitem)
+        elif action == "go":
+            self._undogoto(data)
+        elif action in ["wri", "dot"]:
+            item = data[0]
+            self.screen._delete(item)
+            self.items.remove(item)
+        elif action == "dofill":
+            item = data[0]
+            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
+                                  fill="", outline="")
+        elif action == "beginfill":
+            item = data[0]
+            self._fillitem = self._fillpath = None
+            self.screen._delete(item)
+            self.items.remove(item)
+        elif action == "pen":
+            TPen.pen(self, data[0])
+            self.undobuffer.pop()
+
+    def undo(self):
+        """undo (repeatedly) the last turtle action.
+
+        No argument.
+
+        undo (repeatedly) the last turtle action.
+        Number of available undo actions is determined by the size of
+        the undobuffer.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(4):
+                turtle.fd(50); turtle.lt(80)
 
-         Example:
-         >>> turtle.speed('slow')
+        >>> for i in range(8):
+                turtle.undo()
         """
-        try:
-            speed = speed.strip().lower()
-            self._delay = speeds.index(speed) * 5
-        except:
-            raise ValueError("%r is not a valid speed. speed must be "
-                             "one of %s" % (speed, speeds))
+        if self.undobuffer is None:
+            return
+        item = self.undobuffer.pop()
+        action = item[0]
+        data = item[1:]
+        if action == "seq":
+            while data:
+                item = data.pop()
+                self._undo(item[0], item[1:])
+        else:
+            self._undo(action, data)
 
+    turtlesize = shapesize
 
-    def delay(self, delay):
-        """ Set the drawing delay in milliseconds.
+RawPen = RawTurtle
 
-        This is intended to allow finer control of the drawing speed
-        than the speed() method
+###  Screen - Klasse  ########################
 
-        Example:
-        >>> turtle.delay(15)
-        """
-        if int(delay) < 0:
-            raise ValueError("delay must be greater than or equal to 0")
-        self._delay = int(delay)
-
-    def _draw_turtle(self, position=[]):
-        if not self._tracing:
-            self._canvas.update()
-            return
-        if position == []:
-            position = self._position
-        x,y = position
-        distance = 8
-        dx = distance * cos(self._angle*self._invradian)
-        dy = distance * sin(self._angle*self._invradian)
-        self._delete_turtle()
-        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
-                                          width=self._width,
-                                          arrow="last",
-                                          capstyle="round",
-                                          fill=self._color)
-        self._canvas.update()
-
-    def _delete_turtle(self):
-        if self._arrow != 0:
-            self._canvas.delete(self._arrow)
-            self._arrow = 0
-
-
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50                  # 50% of window width
-_height = 0.75                 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics"     # default title
+class Screen(TurtleScreen):
+
+    _root = None
+    _canvas = None
+    _title = _CFG["title"]
+
+    # Borg-Idiom
 
-class Pen(RawPen):
+    _shared_state = {}
+
+    def __new__(cls, *args, **kwargs):
+        obj = object.__new__(cls, *args, **kwargs)
+        obj.__dict__ = cls._shared_state
+        return obj
 
     def __init__(self):
-        global _root, _canvas
-        if _root is None:
-            _root = Tkinter.Tk()
-            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
-            _root.title(_title)
-
-        if _canvas is None:
-            # XXX Should have scroll bars
-            _canvas = Tkinter.Canvas(_root, background="white")
-            _canvas.pack(expand=1, fill="both")
+        if Screen._root is None:
+            Screen._root = self._root = _Root()
+            self._root.title(Screen._title)
+            self._root.ondestroy(self._destroy)
+        if Screen._canvas is None:
+            width = _CFG["width"]
+            height = _CFG["height"]
+            canvwidth = _CFG["canvwidth"]
+            canvheight = _CFG["canvheight"]
+            leftright = _CFG["leftright"]
+            topbottom = _CFG["topbottom"]
+            self._root.setupcanvas(width, height, canvwidth, canvheight)
+            Screen._canvas = self._root._getcanvas()
+            self.setup(width, height, leftright, topbottom)
+        TurtleScreen.__init__(self, Screen._canvas)
+        Turtle._screen = self
+
+    def setup(self, width=_CFG["width"], height=_CFG["height"],
+              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
+        """ Set the size and position of the main window.
+
+        Arguments:
+        width: as integer a size in pixels, as float a fraction of the screen.
+          Default is 50% of screen.
+        height: as integer the height in pixels, as float a fraction of the
+          screen. Default is 75% of screen.
+        startx: if positive, starting position in pixels from the left
+          edge of the screen, if negative from the right edge
+          Default, startx=None is to center window horizontally.
+        starty: if positive, starting position in pixels from the top
+          edge of the screen, if negative from the bottom edge
+          Default, starty=None is to center window vertically.
+
+        Examples (for a Screen instance named screen):
+        >>> screen.setup (width=200, height=200, startx=0, starty=0)
+
+        sets window to 200x200 pixels, in upper left of screen
 
-            setup(width=_width, height= _height, startx=_startx, starty=_starty)
+        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
 
-        RawPen.__init__(self, _canvas)
+        sets window to 75% of screen by 50% of screen and centers
+        """
+        if not hasattr(self._root, "set_geometry"):
+            return
+        sw = self._root.win_width()
+        sh = self._root.win_height()
+        if isinstance(width, float) and 0 <= width <= 1:
+            width = sw*width
+        if startx is None:
+            startx = (sw - width) / 2
+        if isinstance(height, float) and 0 <= height <= 1:
+            height = sh*height
+        if starty is None:
+            starty = (sh - height) / 2
+        self._root.set_geometry(width, height, startx, starty)
+
+    def title(self, titlestring):
+        """Set title of turtle-window
+
+        Argument:
+        titlestring -- a string, to appear in the titlebar of the
+                       turtle graphics window.
+
+        This is a method of Screen-class. Not available for TurtleScreen-
+        objects.
+
+        Example (for a Screen instance named screen):
+        >>> screen.title("Welcome to the turtle-zoo!")
+        """
+        if Screen._root is not None:
+            Screen._root.title(titlestring)
+        Screen._title = titlestring
 
     def _destroy(self):
-        global _root, _canvas, _pen
-        root = self._canvas._root()
-        if root is _root:
-            _pen = None
-            _root = None
-            _canvas = None
+        root = self._root
+        if root is Screen._root:
+            Turtle._pen = None
+            Turtle._screen = None
+            Screen._root = None
+            Screen._canvas = None
+        TurtleScreen._RUNNING = True
         root.destroy()
 
-def _getpen():
-    global _pen
-    if not _pen:
-        _pen = Pen()
-    return _pen
+    def bye(self):
+        """Shut the turtlegraphics window.
 
-class Turtle(Pen):
-    pass
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bye()
+        """
+        self._destroy()
 
-"""For documentation of the following functions see
-   the RawPen methods with the same names
-"""
+    def exitonclick(self):
+        """Go into mainloop until the mouse is clicked.
 
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
-
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
-    """ copies RawPen docstrings to module functions of same name """
-    if not methodname.startswith("_"):
-        eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
-    """ Sets the size and position of the main window.
-
-    Keywords are width, height, startx and starty:
-
-    width: either a size in pixels or a fraction of the screen.
-      Default is 50% of screen.
-    height: either the height in pixels or a fraction of the screen.
-      Default is 75% of screen.
-
-    Setting either width or height to None before drawing will force
-      use of default geometry as in older versions of turtle.py
-
-    startx: starting position in pixels from the left edge of the screen.
-      Default is to center window. Setting startx to None is the default
-      and centers window horizontally on screen.
-
-    starty: starting position in pixels from the top edge of the screen.
-      Default is to center window. Setting starty to None is the default
-      and centers window vertically on screen.
-
-    Examples:
-    >>> setup (width=200, height=200, startx=0, starty=0)
-
-    sets window to 200x200 pixels, in upper left of screen
-
-    >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
-    sets window to 75% of screen by 50% of screen and centers
-
-    >>> setup(width=None)
-
-    forces use of default geometry as in older versions of turtle.py
-    """
-
-    global _width, _height, _startx, _starty
-
-    width = geometry.get('width',_width)
-    if width >= 0 or width is None:
-        _width = width
-    else:
-        raise ValueError, "width can not be less than 0"
+        No arguments.
 
-    height = geometry.get('height',_height)
-    if height >= 0 or height is None:
-        _height = height
-    else:
-        raise ValueError, "height can not be less than 0"
+        Bind bye() method to mouseclick on TurtleScreen.
+        If "using_IDLE" - value in configuration dictionary is False
+        (default value), enter mainloop.
+        If IDLE with -n switch (no subprocess) is used, this value should be
+        set to True in turtle.cfg. In this case IDLE's mainloop
+        is active also for the client script.
 
-    startx = geometry.get('startx', _startx)
-    if startx >= 0 or startx is None:
-        _startx = _startx
-    else:
-        raise ValueError, "startx can not be less than 0"
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
 
-    starty = geometry.get('starty', _starty)
-    if starty >= 0 or starty is None:
-        _starty = starty
-    else:
-        raise ValueError, "startx can not be less than 0"
+        Example (for a Screen instance named screen):
+        >>> screen.exitonclick()
 
+        """
+        def exitGracefully(x, y):
+            """Screen.bye() with two dummy-parameters"""
+            self.bye()
+        self.onclick(exitGracefully)
+        if _CFG["using_IDLE"]:
+            return
+        try:
+            mainloop()
+        except AttributeError:
+            exit(0)
 
-    if _root and _width and _height:
-        if 0 < _width <= 1:
-            _width = _root.winfo_screenwidth() * +width
-        if 0 < _height <= 1:
-            _height = _root.winfo_screenheight() * _height
 
-        # center window on screen
-        if _startx is None:
-            _startx = (_root.winfo_screenwidth() - _width) / 2
+class Turtle(RawTurtle):
+    """RawTurtle auto-crating (scrolled) canvas.
 
-        if _starty is None:
-            _starty = (_root.winfo_screenheight() - _height) / 2
+    When a Turtle object is created or a function derived from some
+    Turtle method is called a TurtleScreen object is automatically created.
+    """
+    _pen = None
+    _screen = None
 
-        _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
+    def __init__(self,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if Turtle._screen is None:
+            Turtle._screen = Screen()
+        RawTurtle.__init__(self, Turtle._screen,
+                           shape=shape,
+                           undobuffersize=undobuffersize,
+                           visible=visible)
 
-def title(title):
-    """Set the window title.
+Pen = Turtle
 
-    By default this is set to 'Turtle Graphics'
+def _getpen():
+    """Create the 'anonymous' turtle if not already present."""
+    if Turtle._pen is None:
+        Turtle._pen = Turtle()
+    return Turtle._pen
+
+def _getscreen():
+    """Create a TurtleScreen if not already present."""
+    if Turtle._screen is None:
+        Turtle._screen = Screen()
+    return Turtle._screen
+
+def write_docstringdict(filename="turtle_docstringdict"):
+    """Create and write docstring-dictionary to file.
+
+    Optional argument:
+    filename -- a string, used as filename
+                default value is turtle_docstringdict
+
+    Has to be called explicitely, (not used by the turtle-graphics classes)
+    The docstring dictionary will be written to the Python script <filname>.py
+    It is intended to serve as a template for translation of the docstrings
+    into different languages.
+    """
+    docsdict = {}
 
-    Example:
-    >>> title("My Window")
+    for methodname in _tg_screen_functions:
+        key = "Screen."+methodname
+        docsdict[key] = eval(key).__doc__
+    for methodname in _tg_turtle_functions:
+        key = "Turtle."+methodname
+        docsdict[key] = eval(key).__doc__
+
+    f = open("%s.py" % filename,"w")
+    keys = sorted([x for x in docsdict.keys()
+                        if x.split('.')[1] not in _alias_list])
+    f.write('docsdict = {\n\n')
+    for key in keys[:-1]:
+        f.write('%s :\n' % repr(key))
+        f.write('        """%s\n""",\n\n' % docsdict[key])
+    key = keys[-1]
+    f.write('%s :\n' % repr(key))
+    f.write('        """%s\n"""\n\n' % docsdict[key])
+    f.write("}\n")
+    f.close()
+
+def read_docstrings(lang):
+    """Read in docstrings from lang-specific docstring dictionary.
+
+    Transfer docstrings, translated to lang, from a dictionary-file
+    to the methods of classes Screen and Turtle and - in revised form -
+    to the corresponding functions.
     """
+    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
+    module = __import__(modname)
+    docsdict = module.docsdict
+    for key in docsdict:
+        #print key
+        try:
+            eval(key).im_func.__doc__ = docsdict[key]
+        except:
+            print "Bad docstring-entry: %s" % key
 
-    global _title
-    _title = title
+_LANGUAGE = _CFG["language"]
 
-def demo():
-    reset()
-    tracer(1)
-    up()
-    backward(100)
-    down()
-    # draw 3 squares; the last filled
-    width(3)
-    for i in range(3):
-        if i == 2:
-            fill(1)
-        for j in range(4):
-            forward(20)
-            left(90)
-        if i == 2:
-            color("maroon")
-            fill(0)
+try:
+    if _LANGUAGE != "english":
+        read_docstrings(_LANGUAGE)
+except ImportError:
+    print "Cannot find docsdict for", _LANGUAGE
+except:
+    print ("Unknown Error when trying to import %s-docstring-dictionary" %
+                                                                  _LANGUAGE)
+
+
+def getmethparlist(ob):
+    "Get strings describing the arguments for the given object"
+    argText1 = argText2 = ""
+    # bit of a hack for methods - turn it into a function
+    # but we drop the "self" param.
+    if type(ob)==types.MethodType:
+        fob = ob.im_func
+        argOffset = 1
+    else:
+        fob = ob
+        argOffset = 0
+    # Try and build one for Python defined functions
+    if type(fob) in [types.FunctionType, types.LambdaType]:
+        try:
+            counter = fob.func_code.co_argcount
+            items2 = list(fob.func_code.co_varnames[argOffset:counter])
+            realArgs = fob.func_code.co_varnames[argOffset:counter]
+            defaults = fob.func_defaults or []
+            defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+            defaults = [""] * (len(realArgs)-len(defaults)) + defaults
+            items1 = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
+            if fob.func_code.co_flags & 0x4:
+                items1.append("*"+fob.func_code.co_varnames[counter])
+                items2.append("*"+fob.func_code.co_varnames[counter])
+                counter += 1
+            if fob.func_code.co_flags & 0x8:
+                items1.append("**"+fob.func_code.co_varnames[counter])
+                items2.append("**"+fob.func_code.co_varnames[counter])
+            argText1 = ", ".join(items1)
+            argText1 = "(%s)" % argText1
+            argText2 = ", ".join(items2)
+            argText2 = "(%s)" % argText2
+        except:
+            pass
+    return argText1, argText2
+
+def _turtle_docrevise(docstr):
+    """To reduce docstrings from RawTurtle class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    turtlename = _CFG["exampleturtle"]
+    newdocstr = docstr.replace("%s." % turtlename,"")
+    parexp = re.compile(r' \(.+ %s\):' % turtlename)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+def _screen_docrevise(docstr):
+    """To reduce docstrings from TurtleScreen class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    screenname = _CFG["examplescreen"]
+    newdocstr = docstr.replace("%s." % screenname,"")
+    parexp = re.compile(r' \(.+ %s\):' % screenname)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+## The following mechanism makes all methods of RawTurtle and Turtle available
+## as functions. So we can enhance, change, add, delete methods to these
+## classes and do not need to change anything here.
+
+
+for methodname in _tg_screen_functions:
+    pl1, pl2 = getmethparlist(eval('Screen.' + methodname))
+    if pl1 == "":
+        print ">>>>>>", pl1, pl2
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+    exec defstr
+    eval(methodname).__doc__ = _screen_docrevise(eval('Screen.'+methodname).__doc__)
+
+for methodname in _tg_turtle_functions:
+    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
+    if pl1 == "":
+        print ">>>>>>", pl1, pl2
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+    exec defstr
+    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
+
+
+done = mainloop = TK.mainloop
+del pl1, pl2, defstr
+
+if __name__ == "__main__":
+    def switchpen():
+        if isdown():
+            pu()
+        else:
+            pd()
+
+    def demo1():
+        """Demo of old turtle.py - module"""
+        reset()
+        tracer(True)
         up()
-        forward(30)
+        backward(100)
         down()
-    width(1)
-    color("black")
-    # move out of the way
-    tracer(0)
-    up()
-    right(90)
-    forward(100)
-    right(90)
-    forward(100)
-    right(180)
-    down()
-    # some text
-    write("startstart", 1)
-    write("start", 1)
-    color("red")
-    # staircase
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    # filled staircase
-    fill(1)
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    fill(0)
-    tracer(1)
-    # more text
-    write("end")
-
-def demo2():
-    # exercises some new and improved features
-    speed('fast')
-    width(3)
-
-    # draw a segmented half-circle
-    setheading(towards(0,0))
-    x,y = position()
-    r = (x**2+y**2)**.5/2.0
-    right(90)
-    pendown = True
-    for i in range(18):
-        if pendown:
+        # draw 3 squares; the last filled
+        width(3)
+        for i in range(3):
+            if i == 2:
+                fill(1)
+            for _ in range(4):
+                forward(20)
+                left(90)
+            if i == 2:
+                color("maroon")
+                fill(0)
             up()
-            pendown = False
-        else:
+            forward(30)
             down()
-            pendown = True
-        circle(r,10)
-    sleep(2)
-
-    reset()
-    left(90)
-
-    # draw a series of triangles
-    l = 10
-    color("green")
-    width(3)
-    left(180)
-    sp = 5
-    for i in range(-2,16):
-        if i > 0:
-            color(1.0-0.05*i,0,0.05*i)
-            fill(1)
-            color("green")
-        for j in range(3):
-            forward(l)
-            left(120)
-        l += 10
-        left(15)
-        if sp > 0:
-            sp = sp-1
-            speed(speeds[sp])
-    color(0.25,0,0.75)
-    fill(0)
-
-    # draw and fill a concave shape
-    left(120)
-    up()
-    forward(70)
-    right(30)
-    down()
-    color("red")
-    speed("fastest")
-    fill(1)
-    for i in range(4):
-        circle(50,90)
+        width(1)
+        color("black")
+        # move out of the way
+        tracer(False)
+        up()
         right(90)
-        forward(30)
+        forward(100)
         right(90)
-    color("yellow")
-    fill(0)
-    left(90)
-    up()
-    forward(30)
-    down();
-
-    color("red")
-
-    # create a second turtle and make the original pursue and catch it
-    turtle=Turtle()
-    turtle.reset()
-    turtle.left(90)
-    turtle.speed('normal')
-    turtle.up()
-    turtle.goto(280,40)
-    turtle.left(24)
-    turtle.down()
-    turtle.speed('fast')
-    turtle.color("blue")
-    turtle.width(2)
-    speed('fastest')
-
-    # turn default turtle towards new turtle object
-    setheading(towards(turtle))
-    while ( abs(position()[0]-turtle.position()[0])>4 or
-            abs(position()[1]-turtle.position()[1])>4):
-        turtle.forward(3.5)
-        turtle.left(0.6)
-        # turn default turtle towards new turtle object
+        forward(100)
+        right(180)
+        down()
+        # some text
+        write("startstart", 1)
+        write("start", 1)
+        color("red")
+        # staircase
+        for i in range(5):
+            forward(20)
+            left(90)
+            forward(20)
+            right(90)
+        # filled staircase
+        tracer(True)
+        fill(1)
+        for i in range(5):
+            forward(20)
+            left(90)
+            forward(20)
+            right(90)
+        fill(0)
+        # more text
+
+    def demo2():
+        """Demo of some new features."""
+        speed(1)
+        st()
+        pensize(3)
+        setheading(towards(0, 0))
+        radius = distance(0, 0)/2.0
+        rt(90)
+        for _ in range(18):
+            switchpen()
+            circle(radius, 10)
+        write("wait a moment...")
+        while undobufferentries():
+            undo()
+        reset()
+        lt(90)
+        colormode(255)
+        laenge = 10
+        pencolor("green")
+        pensize(3)
+        lt(180)
+        for i in range(-2, 16):
+            if i > 0:
+                begin_fill()
+                fillcolor(255-15*i, 0, 15*i)
+            for _ in range(3):
+                fd(laenge)
+                lt(120)
+            laenge += 10
+            lt(15)
+            speed((speed()+1)%12)
+        end_fill()
+
+        lt(120)
+        pu()
+        fd(70)
+        rt(30)
+        pd()
+        color("red","yellow")
+        speed(0)
+        fill(1)
+        for _ in range(4):
+            circle(50, 90)
+            rt(90)
+            fd(30)
+            rt(90)
+        fill(0)
+        lt(90)
+        pu()
+        fd(30)
+        pd()
+        shape("turtle")
+
+        tri = getturtle()
+        tri.resizemode("auto")
+        turtle = Turtle()
+        turtle.resizemode("auto")
+        turtle.shape("turtle")
+        turtle.reset()
+        turtle.left(90)
+        turtle.speed(0)
+        turtle.up()
+        turtle.goto(280, 40)
+        turtle.lt(30)
+        turtle.down()
+        turtle.speed(6)
+        turtle.color("blue","orange")
+        turtle.pensize(2)
+        tri.speed(6)
         setheading(towards(turtle))
-        forward(4)
-    write("CAUGHT! ", move=True)
-
-
+        count = 1
+        while tri.distance(turtle) > 4:
+            turtle.fd(3.5)
+            turtle.lt(0.6)
+            tri.setheading(tri.towards(turtle))
+            tri.fd(4)
+            if count % 20 == 0:
+                turtle.stamp()
+                tri.stamp()
+                switchpen()
+            count += 1
+        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+        tri.pencolor("black")
+        tri.pencolor("red")
+
+        def baba(xdummy, ydummy):
+            clearscreen()
+            bye()
+
+        time.sleep(2)
+
+        while undobufferentries():
+            tri.undo()
+            turtle.undo()
+        tri.fd(50)
+        tri.write("  Click me!", font = ("Courier", 12, "bold") )
+        tri.onclick(baba, 1)
 
-if __name__ == '__main__':
-    demo()
-    sleep(3)
+    demo1()
     demo2()
-    done()
+    exitonclick()

Modified: python/trunk/Misc/ACKS
==============================================================================
--- python/trunk/Misc/ACKS	(original)
+++ python/trunk/Misc/ACKS	Wed Jun  4 08:29:55 2008
@@ -412,6 +412,7 @@
 Bjorn Lindqvist
 Per Lindqvist
 Eric Lindvall
+Gregor Lingl
 Nick Lockwood
 Stephanie Lockwood
 Anne Lord


More information about the Python-checkins mailing list