Version 0.0.8 – Rough Draft


Python 3000: Concepts, Turtle = Robot


Loved by beginners and expert programmers alike, Modern Python comes with many built-in modules. Python’s Turtle Graphics Module is one of them.


A screen shot of a computer

Description automatically generated


Because Python’s Turtle Graphics Module is built-into many popular Python graphical distributions there is nothing to install.


Training Approach


I have divided all my training into step-by-step modules. Numbered from 1000 to 9000, the numbering system allows us to skip things that we already know to focus upon the things that we do not.


If you are new to programming, then you’ll want to enjoy my free Python Primer.




To get the most out of Python 3000: Turtles, Robots & Vectors, learners should already know how to create functions, as well as classes, using Python.

A yellow circle with a white center

Description automatically generated


If you do not already know how to use Python 3, please complete the Python 1000 series to master functional Python.


If you’ve yet to master Python’s classes and packages, then complete Python 2000 to learn how to use Object Orientation to create classes we can share by creating our own Python Modules. Here are some examples.


Videos are available on Udemy, as well as other educational providers.


If you can use Python classes & functions, then you’ve come to the right place. Be prepared to confidently complete the lessons here!


Python 3000: Turtles, Robots and Vectors


This book is dedicated to showing you how to draw text, grids, polygons, and a variety of shapes using Modern Python. From classic text and lines to Unicode, we’ll even show you how to create a very nice chess board.


We’ll begin by reviewing common graphical concepts. From Cartesian planes & plotting to the computer’s “Purely Positive Plane,” we’ll discuss how using Python’s Turtle Graphics Module can use a combination of several plotting strategies.


You’ll next discover how to draw shapes, pictures, stamps & images, as well as textual glyphs.


Upon completing this training you will understand how to create amazing drawings using the classic Cartesian point-plotting system, the classic Computer plotting system, and – of course – Python’s Turtle Graphics location-relative (“move to, draw to, go to”) way of using “turtle robots” to draw a surprisingly huge number of shapes.

Python 3000: Part One, Points & Vectors – The Big Ideas


So welcome to Python 3000! Your perfect place for Pythoneers who know the difference between Python’s functions, classes, and modules.


A Classic Cartesian Plane


By way of review, in modern mathematics what we are first taught when starting Geometry is how to work with a “Cartesian Plane.”

Figure 1: Line Intersection

Initially explored in “two dimensional” terms, the Cartesian Plane has two intersecting lines. One of those lines manages numbered points sitting across the horizon, spaced left to right. The other line manages points spaced up and down an intersecting vertical line.


Of course, when we're moving across the horizon, we're moving either positively or negatively across the x line, or x axis.


When we're moving up and down vertically, we're moving either positively or negatively along the y line, or y axis.



A graph of a function

Description automatically generated

Figure 2: Intersection Point

The point where these two lines intersect on the screen is where both the x and the y location equal zero. Ihe intersection point, as shared in Figure 2, I like to think of as “Point Zero.” The center of our galaxy?


A diagram of a graph

Description automatically generated

Figure 3: Cartesian's The Four Planes


Classically there are no more than 360 directions to move away from wherever we are, or 360 Degrees.


All powerful concepts, Point Zero also divides the Cartesian galaxy into four regions. Each a uniquely navigable area, there is but a single “purely positive” region, a “purely negative,” as well as each for two positive:negative complements as seen in Figure 3, above.


The first truth table?


Cartesian graphics is all about locating x, y intersections, or points, within its four different areas.


A blue cross with arrows

Description automatically generated

Figure 4: Cartesian's 'All-Positive' Plotting Area

So if setting both x and y equal to 0 will take us to “Point Zero,” if we were to set both x and y equal to 10 we’d arrive at what we might call “Point 10,” as plotted in Figure 4, above.


Interestingly, the computer’s default drawing system is completely different.


The Classic Computer Plane


Decidedly not Cartesian, in every computer language that I've ever used the classic computer’s zero-point origin is not located in the middle of four planes, but in the upper left-hand corner of a single plotting plane:


Figure 5: Classic Computer Plane

On computers we’ll most often find ourselves forever plotting points in the positive as we see in Figure 6, below.


Contrasting the Cartesian experience in Figure 3 with the default classic plotting system in Figure 4 (above) we can begin to understand the difference between the Cartesian, and the Computerized, point plotting paradigms. While the ideas of having an origin, horizontal, and vertical line are similar, notice how Point 10 falls below, rather than above, Point Zero:


Figure 6: Positive Computer Point Location


Having but a single purely positive point coordinate system, limited to a single plane, makes finding locations easier for the computer. -But sometimes having but a single, positively numbered plane also makes statistical modeling very difficult for those equations used to plotting their results into Cartesian’s four plotting areas.


Multiple Turtles


Easy enough.


But consider the power of having more than one Turtle?


From game play to real-world artificial intelligence, being able to define multiple objects, each operating around their own origins & homes, makes programming classes much easier.


The concepts we learn when using Turtle Graphics also allows everyone to discuss missions objectively, certainly when we’ve many objects running around at once.


Turtle Backstory


Tuttle Graphics was conceived in the 1960s by Seymour Papert.


Papert likened the plotting system to a Turtle walking across a plane, its tail dipped in ink.


Yet because the visualization is extremely easy to understand, whenever we say we are using Turtle Graphics, some may sneer?


For our part we should focus on the enlightened idea that Turtle Graphics can manage entire armies of turtles. Simply calling the “turtle” an “object,” or a “robot,” eliminates ridicule.


Indeed, the concept of modern Turtle Graphics is so respected to have implementations not only in Python, but available Logo, Java, as well as many other programming languages as well.


The journey of a million robots begins with a simple way to manage any single Turtle.


Python 3000: Part One, Robotic Turtles – Lesson 1


So let’s get coding.


Module -v- Class


Because we can use it to draw, we often think of the turtle module as being the “default turtle:”



The turtle module has a lot of public members – over 140:


A close up of text

Description automatically generated


Interestingly, in addition to the module, we’ve the Turtle() class:


The module & class share documentation & drawing operations:


Table 1: Common Robotic Operations



Thus we can use either the Turtle Module proper, or an instance of turtle.Turtle(), to interactively draw upon our screen:


A computer screen shot of a computer screen

Description automatically generated

Figure 7: The  X Ray


Your Robot’s Default Location


In Figure 8 (above) we're going to access the forward member function of the ‘default turtle’ to advance your Turtle instance ahead 100-pixel elements across your screen:


A white background with red text

Description automatically generated

Source 1: Forward & Done


As you may expect, the default location for our default turtle will be in the center of that Cartesian plane, or coordinate (0,0).


What may be unexpected is that when we access the default plane, every robot will be facing in a positive direction – positioned to move across the x axis. It’s tail (or pen) down, dipped in ink, and ready to draw.


What also might be unexpected is that the turtle will set focus to its drawing window upon executing the default turtle’s .done() operation. We’ll return back to the interactive mode only after that drawing window has closed, or after we're .done().


WARNING: Once the default turtle instance is .done() the best practice is to CLOSE THE WINDOW before using that turtle again!


The Way of the GUI


Are you one of the few able to challenge themselves? Take a moment to stop & enjoy a new idea?


I would challenge you now to go ahead and open your Python of choice to input the above simple, three-line program. Be sure to use a graphical user interface.


Verify not only that are you using Python 3, but that you are able to see something like what we see in Figure 8. (your colors may vary!)


Default Home Locations


Whenever we need to jump an Object back to where it came from, we can use the Turtle’s .home() member function.


A screenshot of a computer code

Description automatically generated

Source 2: Using .home()


And of course, we can also change colors - as we see here to red - as well as to move in many different directions.


So rather than using a negative coordinate system - which is also possible - we can rely upon the object’s default direction.


See if you can use your turtle’s .left(90) to create the following:

A black arrow pointing up

Description automatically generated

Figure 8: Right Angle & Ray


Feel free to take a moment to complete this activity to practice moving self-relative to whatever direction our Object / robot wakes up in. After your program has run your screen should look pretty much like you saw in Figure 8, above.



Python 3000: Part One, Vector Basics - Lesson 2


There is more than one solution to the previous activity.


Our solution to was saved to the file:


A screenshot of a computer

Description automatically generated

Source 3: Right Angle & Ray


The solution can also be found in the resources associated with this training.




Notice that we’re moving our Turtle - Object to another location when using .home():


Figure 9: Home Restores Default Direction


By using .home() we're also restoring our default direction, as well.


In addition us a .right(degrees), you may suspect that we’ll have many more functions we can use in addition to the .left(degrees), as well.




Rather than using .home(), we can instead choose to use the Turtle’s .goto() operation.


A computer code with black and white text

Description automatically generated

Source 4: Goto Four


Unlike when using .home(), choosing to use the Turtle’s .goto(0,0) member function preserves our object’s direction. We can also use .setposition().


Convenience Functions


Any turtle has the ability to go forward as well as backward. Once again specifying the number of pixels to be moved, but more importantly each one of these movement member functions also have a “convenience” or an “alias” function:




For our next activity let's go ahead and apply what we've seen and have a little challenge to create our Cartesian Cross:


Figure 10: Turtles Cartesian Cross



And once again seeing our default robot shape on the screen above. We’ll see how to change the shape of the robot later on.


Go ahead and take a moment to create your own Cartesian Cross.


Python 3000: Part One, Shapes 360 - Lesson 3


Now we understand that if we were to use .home rather than .goto that we'd restore our default orientation:


Source 5:

Feel free to run Source 5 both with & without the comment. Verify that all we're doing when we go home is to have our default orientation restored. -Because how we chose to draw our lines, nothing really happens when we decide to use .home rather than the .goto operation, so you’ll have to add new code.


Turtle Hoards


We’ve seen that there are many member operations that can be shared between different Turtle instances. Note, however, that the default Turtle instance – or the module turtle - has some unique properties the other turtles cannot use:


Table 2: Unique Module Operations


.resetscreen() & .clearscreen()


Every artist knows that the more the mistakes, the greater the mastery?


Try this at home:


A close up of a text

Description automatically generated


No matter if we’re in interactive or non, .reset() sends us .home(), as well removes what we’ve done with any single turtle.


To prove that the default turtle has returned to Point Zero:


A close up of black text

Description automatically generated


We can also clear the entire screen – removing everything – simply by entering:



(#5 in Table 2, above.)


Screen State Challenge


We were able to verify that the .home() and .reset() operations restored an object’s start-state by moving the robot after each.


Verify that operation #5 in Table 2, and #8 in Table 1, works as you might expect.


See help(clearscreen) for more information.


Finally, verify the difference between .reset() and .resetscreen(), as well.


Titles & Window Sizes


Another one of those unique member functions is the .setup member function, #33:


A close up of words

Description automatically generated

Source 6: Window Size = 300 x 100


Obviously powerful, the default turtle.setup() operation allows us to set up or change the size of our window. For example, we can have a specific width and height for the main window.


Because turtle.setup has defaulted parameters, we could also specify screen sizes in floating-point percentages, adding desktop x & y locations as optional 3rd and 4th parameters, respectively:


A close up of a number

Description automatically generated

Source 7: Size as Percentages & Desktop Location


You may imagine we also are able to look at our window’s width height (#45), as well as many other window related properties. Each & all unique to the default Turtle.


REPL 1: Default Turtle Ops


To prove that what we have is unique to our default turtle, simply instance another turtle, then try to access these exact same operations.


REPL 2: Instanced Turtle Exceptions


We will see that we will indeed have an exception, in this case specifying that the instance of Turtle does not have an attribute that manages window attributes.


Window Titles


Whenever we want to have a custom title for our application - which of course is going to be most of the time – the default Turtle also has a member function. Using turtle.title() will allow us to set the window’s title to any Unicode string that we may wish to see:


A computer code with text

Description automatically generated with medium confidence

Source 8: Titles & Cleanup Operations


For our next activity let's go ahead and have a little fun to simply try what we've seen.


A computer screen shot of a computer

Description automatically generated

Figure 11: A Custom Solution


Your solution need not look like what we’ve provided in the Source 8 example, above.


Python 3000: Part Two, Vectoring – Lesson 4


Well now that we have our bearings let's take a moment and start drawing some interesting things with lines. Specifically let's talk about using grids and polygons.


Figure 12: Positive & Negative Rotation


If you look at the tip of the arrow in Figure 13, you can imagine that in order to get to a certain place that your Turtle has to come from an area then move toward wherever we’ve pointed it.


REPL 3: Where We're Heading


Once pointed, if we decide to pivot to the right by 45 degrees we would say “rotate right, positive 45 degrees” before moving. Pivoting twice results in rotating 90 degrees:


Figure 13: 45 + 45 = 90 Degrees


Of course, if we wanted to go to the left we would simply say that we wanted to “rotate left, negative 45 degrees” to create Figure 14 once again.



REPL 4: Same Results!


Using what you know now, now try to draw:


Figure 14: Left Positive, or Right Negative


Go ahead to re-create Figure 15. Take a moment to do that now.


Mixed Instances


Re-creating Figure 15 was easy, so we decided to show how to mix things up a little to demonstrate a few more concepts:


A white background with black text

Description automatically generated

REPL 5: Two Instances


In addition importing turtle.Turtle as simply Turtle, REPL 5 demonstrates - even though we created our own as t1 – that we still had to use turtle.done(), so we’ll still have to destroy the window when we’re done.



Python 3000: Part Two, Closed Shapes – Lesson 5


Drawing closed shapes is often simply a matter of starting and finishing up in the same place.


A diagram of a square with arrows and numbers

Description automatically generated

Figure 15: 360 Degrees


Keeping that round-trip in mind, draw the following:

A computer screen shot of a computer screen

Description automatically generated

Challenge 1: Draw The Square


Because all we had to do was combine what we gleaned from Figure 16, going right 90 degrees, four times, would complete the assignment.


Here is our solution:


A computer code with text

Description automatically generated with medium confidence

Source 9:


And as you can see in Source 9, leveraging Python’s built in range() function allowed us to repeat the `for` block for a total of “zero to three” iterations, drawing a total of four sides.


Source 9 is but one of many solutions. I'd be very surprised if even your variable names were the same?


The Octagon Challenge


When drawing four sides was easy, how about drawing eight?


A screenshot of a computer

Description automatically generated

Challenge 2: The Oct Box


As you might imagine we're still going to have 360 degrees, yet rather than divided by 4 to give us 90, we're going to now divide it by 8 to give us the 8-angle result.


So go ahead and challenge yourself and see if you can update your previous solution to draw an octagon “your way”.


Easy Octagons


The notion of having 360 degrees, divided by the number of sides that we wish to have in our polygon, works well:


A computer code with text

Description automatically generated with medium confidence

Source 10: My Oct Box

We now have a formula that we can use to create a function that we can call simply by specifying the number of sides to draw the desired polygon.


Try the following:


Equation 1: Testing The Triangle

A computer code with text

Description automatically generated


Challenger: Weaponize the Formula!


A decent research activity, Equation 1 (above) points us to what we should probably next do. Our challenge is to provide a function that we can re-use to complete:


A white background with black text

Description automatically generated

Challenge 3: draw_poly()


While we use the default value of 3 to draw a triangle, note the default length parameter of 50.


A black triangle with a black arrow

Description automatically generated

Figure 16: Three sides, default length of 50


And as we've seen in our Python 1000, creating a function with defaults allows us to always have – in this case - unified line lengths. The length parameter can be overridden to allow us to also have custom lengths.


So your challenge is to take a moment and provide an implementation to our draw_poly that allows both a different, as well as a custom, line length.


Our draw_poly Soluton


Notice in Source 11 (below) that our solution had a little bit of sanity checking? Specifically, if you wanted to know if the sides were less than one, we returned -1 as the result. In the future we could also return -1 if something else failed to work.


To tell us that the drawing went as planned, even though we didn't originally require a result to be returned, we decided to return the calculated angle as the result. It is always nice to know if all went well:


A computer code with text

Description automatically generated

Source 11:


We also copied the code from Equation 1.


Python 3000: Part Two, Grid of Grids – Lesson 6


Now that we’ve a function we should talk about other opportunities to reuse draw_polly.


Let's take a moment to see how we might be able to use vector-based graphics to draw a grid:


Figure 17: The Grid Problem

Code Re-Use


To draw the grid the first thing that we can now do, of course, is to simply include and re-use our draw_poly algorithm.


Source 12: Reusing draw_poly

Rather than 360/3, we're going to have 4 sides to our polygon. Easy enough to understand.


Default Parameters


Even though the length of 50 is the same as the default parameter value, coding a line length on line 23 allows us to play with other values:


Source 13:


Controlling Drawing Speed


Setting the speed to 9 on line 21 above allows us to observe the drawing operation.


Line 24 controls grid height. Rather than 4, we decided to use 4 * 2 = 8 rows.


The next_row function on line 13 is where we move the “robot” around:


Source 14: Grid Turtle Placement


The Grid Super Challenge!


The toughest problem we’ve yet encountered in Python 3000, see if you can challenge yourself to create a customizable “square of squares” to create a grid.


Using a grid to exactly track what we're doing is a very useful capability to have. The ability to draw a grid should be part of our standard toolkit:


A screenshot of a computer

Description automatically generated

Challenge 4: Grid of Grids

Python 3000: Part Two, Serpentine Grids – Lesson 7


Faster Grids


While Challenge 4 is arguably a very good object-oriented solution, drawing that square over and repeatedly isn’t very efficient.


Figure 18: Overlapping Shapes


A faster way, of course, would be to eliminate the overlap.


The Serpentine Grid Challenge


One efficient grid strategy could be more serpentine: moving back and forth both horizontally, as well as vertically?


Figure 19: Serpentine Grid Strategy


Another challenging activity, your next mission – if you decide to accept it – is to draw a “serpentine grid.”


A Serpentine Grid Solution


My solution for the “Figure 20 Challenge” is in the resources as


Python 3000: Part Two, Grid Class – Lesson 8


Here is the source for


import turtle


def draw_grid(zturtle, width, height, cell_size, border=None, border_pen_size=None):

    ylines = int(height / cell_size)

    xlines = int(width / cell_size)

    # y serpentines


    next_angle = -90

    for yy in range(xlines):


        next_angle = next_angle * -1




    # x serpentines


    next_angle = 90


    for xx in range(ylines):


        next_angle = next_angle * -1




    # Outer Box


    if border:


    if border_pen_size:













if __name__ == "__main__":

    draw_grid(turtle, 100, 200, 10, border='green', border_pen_size=3)


Our solution above added an outside border. We did not use dry_poly, but copied the concept.


We're going to be slithering like a serpent and by moving to the next and then forward our ourselves and moving back again back and forth across our screen. First horizontally – across the x axis, then vertically across the y.


Refactoring Challenge: SnakeGrid


Complicated enough to study, a great way to make the code easier to understand would be to refactor draw_grid into a class.


Here is the requirement:

A screenshot of a graph

Description automatically generated

Figure 20: Serpentine Class Grid


Feel free to create a static class:


class SnakeGrid:


    def draw_rectangle(zturtle, x, y, width, height, border=None, border_pen_size=None): ...



    def draw_snake(zturtle, x, y, height, cell_size, xlines, next_angle): ...



    def draw_grid(zturtle, x, y, width, height, cell_size, border=None, border_pen_size=None): ...



As you can imagine we are going to use the same logic as seen in the draw_grid.


Serpentine Class Solution


Located in, to better compare the two techniques we decided to create two classes. Class SlowGrid demonstrates the slower overlapping approach. Class SnakeGrid, our requirement.


Figure 21: Slow -v- Fast Grid


Reviewing our solution’s main ‘driver’ in Figure 21, line 101 hides the t1 Turtle, then line 102 raises its pen. Once the pen is up, t1 can .goto wherever it needs to without leaving a line behind.


Line 103 permits us to choose which class we’d like to see.


Locate and run, feeling free to change both the speed, as well as line 103, to see how fast / slow either of these strategies can be.


Python 3000: Part Three, Stateful Object – Lesson 9


The rest of this tome remains a work in progress. Until it is done, you can complete this course online.