Thu 03 July 2025

The TurtleSC Package for Python turtle.py Shortcuts

Posted by Al Sweigart in misc   

TurtleSC provides a mini-language of shortcut instructions to carry out turtle.py function calls, like 'f 100' instead of forward(100). Git Repo, PyPI Project Page.

These two examples do the same thing:

Original Turtle Code TurtleSC Code
from turtle import *
from random import *

colors = ['red', 'orange', 'yellow', 'blue', 'green', 'purple']

speed('fastest')
pensize(3)
bgcolor('black')
for i in range(300):
    pencolor(choice(colors))
    forward(i)
    left(91)
hideturtle()
done()
from turtlesc import *
from random import *

colors = ['red', 'orange', 'yellow', 'blue', 'green', 'purple']

sc('spd fastest, ps 3, bc black')
for i in range(300):
    sc(f'pc {choice(colors)}, f {i}, l 91')
sc('hide,done')

These shortcuts are quicker to type, making them ideal for experimenting from the interactive shell. TurtleSC takes the idea of the existing fd() and rt() aliases for forward() and right() to the next level. All shortcuts are run from a string passed to the turtlesc.sc() function.

I created this to help with some digital art projects, namely recreating the "impossible objects" of Swedish artist Oscar Reutersvärd:

The code for this is in my oscarsturtle repo, which I'll write a blog post on in the future.

TurtleSC was created by me, Al Sweigart, author of Automate the Boring Stuff with Python and other programming books. All of his books are available for free online under a Creative Commons license. If you'd like a tutorial specifically about Python's turtle module, check out The Simple Turtle Tutorial.

You can also write (less readable) turtle programs using shortcuts. For example, this program:

from turtle import *
from random import *

tracer(4, 0)

for i in range(50):
    fillcolor((random(), random(), random()))

    # Set a random heading and draw several short lines with changing direction:
    setheading(randint(0, 360))
    begin_fill()
    for j in range(randint(200, 600)):
        forward(1)
        left(randint(-4, 4))
    home()
    end_fill()

update()
done()

...could be written as:

from turtlesc import *
from random import *

sc('t 4 0')

for i in range(50):
    sc(f'fc {random()} {random()} {random()}, sh {randint(0, 360)}, bf')
    for j in range(randint(200, 600)):
        sc(f'''f 1
               l {randint(-4, 4)}''')
    sc('h,ef')

sc('u,done')

This code isn't very readable, but it's quick to type. This is useful if you are making rapid prototypes of ideas.

Shortcuts in the sc() string argument are separated by a comma, with any shortcut arguments separated by spaces. Whitespace is insignificant (you can have one more spaces, and it's the same as a single space). Shortcut names and arguments are case-insensitive: 'f' and 'F' work the same. Newlines in the string argument are treated as shortcut-separating commas.

Some less-common shortcuts (such as 'done') only have their full function name. All shortcuts have their full function name as a shortcut name: you can use either 'f' or 'forward'.

TurtleSC also adds cardinal movement shortcuts that move the turtle independent of it's current heading (and does not change the heading): 'n 100', 's 100', 'e 100', 'w 100' will move the turtle up, down, right, and left 100 steps, respectively. There are also full name shortcuts ('north', 'south', 'east', 'west') and diagonal shortcuts ('nw', 'ne', 'sw', 'se', 'northwest', 'northeast', 'southwest', 'southeast').

By default, the sc() function operates on the single, global turtle. You can also pass the turtle_obj keyword argument to operate on different Turtle objects:

from turtlesc import *
from turtle import *

t1 = Turtle()
t2 = Turtle()

# Make turtle 1 red and move up-right:
sc('pc red, l 45, f 100', turtle_obj=t1)

# Make turtle 2 blue and move down-right:
sc('pc blue, r 45, f 100', turtle_obj=t2)

sc('done')

The turtlesc module also provides new in_radians_mode() or in_degrees_mode() functions that return a Boolean True or False value depending on which mode the turtle is in. These features are missing in the original turtle module.

If you want to get the original code for a shortcuts string (which can be helpful to print the shortcuts), pass it to the scs() function:

>>> from turtlesc import *
>>> scs('f 100, r 45, f 100')
'forward(100)\nright(45)\nforward(100)'

Note that the return value of scs() is a string. If there are multiple shortcuts, they are separated by a newline and all lack the turtle. prefix in case you want to add your own (either the turtle module or a variable containing a Turtle object.)

To easily print out this shortcut string, call psc():

>>> from turtlesc import *
>>> psc('f 100, r 45, f 100')
forward(100)
right(45)
forward(100)

Reference

Here is a complete reference of supported shortcuts:

Shortcut Call Turtle.py Equivalent
sc('f 100') forward(100)
sc('b -100.5') backward(-100.5)
sc('l 45') left(45)
sc('r 90') right(90)
sc('h') home()
sc('c') clear()
sc('g 15 40') goto(15 40)
sc('x 10') setx(10)
sc('y -20') sety(-20)
sc('st') stamp()
sc('pd') pendown()
sc('pu') penup()
sc('ps 4') pensize(4)
sc('pc 1.0 0.0 0.5') pencolor(1.0, 0.0, 0.5)
sc('fc 255 0 128') fillcolor(255, 0, 128)
sc('bc #FF00FF') bgcolor('#FF00FF')
sc('sh 90') setheading(90)
sc('cir 10') circle(10)
sc('undo') undo()
sc('bf') begin_fill()
sc('ef') end_fill()
sc('reset') reset()
sc('sleep 5') time.sleep(5)
sc('n 10') setheading(90) ; forward(10)
sc('s 10') setheading(270) ; forward(10)
sc('e 10') setheading(180) ; forward(10)
sc('w 10') setheading(0) ; forward(10)
sc('nw 10') setheading(135) ; forward(10)
sc('ne 10') setheading(45) ; forward(10)
sc('sw 10') setheading(225) ; forward(10)
sc('se 10') setheading(315) ; forward(10)
sc('done') done()
sc('bye') bye()
sc('exitonelick') exitonclick()
sc('eoc') exitonclick()
sc('t 100 0') tracer(100, 0)
sc('u') update()
sc('hide') hide()
sc('show') show()
sc('dot 5') dot(5)
sc('cs 42') clearstamp(42)
sc('css') clearstamps()
sc('css 10') clearstamps(10)
sc('degrees') degrees()
sc('radians') radians()
sc('spd 5') speed(5)
sc('spd fastest') speed('fastest')
sc('# this is a comment') # this is a comment

Notes

The sc(skip=True) keyword argument skips all the shortcuts. Consider this the same as commenting out the sc() call.

The sc('sleep 5') shortcut exists to call the time.sleep() function.

You can pass multiple strings to sc(). For example, sc('f 100', 'r 45', 'f 100') is equivalent to sc('f 100, r 45, f 100').

The 'pc', 'fc', and 'bc' shortcuts for pen color, fill color, and background color can take a color argument as:

  • A color name, such as 'red'
  • Three 0 to 255 integer values, such as '255 0 0 (turtle.py's color mode must be set to 255)
  • Three 0.0 to 1.0 float values, such as '1.0 0.0 0.0 (turtle.py's color mode must be set to 255)
  • A hexadecimal RGB code, such as '#FF0000' (the leading # hashtag is required)

The cardinal directions shortcuts change both the heading and position of the turtle.

scs (shortcut strings) and psc (print shortcuts)

If you pass the shortcut string to scs(), instead of carrying out the turtle instructions, it will return a string of the original turtle.py function calls the sc() function would make. For example:

>>> from turtlesc import *
>>> scs('bf, f 100, r 90, f 100, r 90, ef')
'begin_fill()\nforward(100)\nright(90)\nforward(100)\nright(90)\nend_fill()\n'

If you'd like to print these out for debugging purposes, you can call psc():

>>> from turtlesc import *
>>> psc('bf, f 100, r 90, f 100, r 90, ef')
begin_fill()
forward(100)
right(90)
forward(100)
right(90)
end_fill()

Comments

You can put comments inside the shortcut string. This is especially helpful when passing multi-line strings to sc(). Comments begin with a # hashtag character and go up to the next comma (which marks the start of the next shortcut). For example:

>>> from turtlesc import *
>>> sc('''f 100
          r 100
          f 100, # This is a comment
          # Another comment
          r 100, f 100''')

Skipping Shortcuts

If you want to temporarily disable a call to sc(), you could comment it out like any other Python instruction. However, this is difficult for sc() calls that have multi-line string arguments. Instead, add the skip=True keyword argument to the call. For example, this instruction does absolutely nothing:

from turtlesc import *
sc('''f 100
      r 100
      f 100,
      r 100, f 100''', skip=True)

When you want to add these shortcuts back in, remove the skip=True text.

Recording Turtle Function Calls

If you want to collect the turtle.py function calls for all your sc() calls, add a call to begin_recording() to the start of your program. When you call end_recording() at the end, it returns a list of strings of turtle.py function calls. For example:

>>> from turtlesc import *
>>> begin_recording()
>>> sc('f 100, r 90, f 100')
3
>>> sc(' r 90,f 100, r 90, f 100')
4
>>> end_recording()
['f 100', ' r 90', ' f 100', ' r 90', 'f 100', ' r 90', ' f 100']

Interactive Drawing Mode

You can draw with the turtle like an etch a sketch by using TurtleSC's interactive mode. Make one of the following function calls:

>>> from turtlesc import *
>>> interactive()  # Use cardinal direction style (the default): WASD moves up/down, left/right
>>> interactive('turn')  # WASD moves forward/backward, turn counterclockwise/clockwise
>>> interactive('isometric')  # WASD moves up/down, and the AD, QE keys move along a 30 degree isometric plane

For all styles, the O and L key move the pen up and down, respectively. The H key moves the cursor home (to 0, 0) and clears the window. The U key is an undo. A mouse click moves the turtle with the pen up (and puts the pen back down if it had been down before.)

Details of each movement style:

  • 'cardinal' style has the WASD and arrow keys move up/down/left/right. The QE, ZC keys also move diagonally. Pass the length argument for how long each movement should be. Diagonal movements are shortened so that a diagonal up-right movement goes to the same position as an up movement and a right movement.

  • 'turn' style has the WASD and arrow keys move forward/backward and turn left and right relative to its current heading. Each turn is 90 degrees. However, you can also add a number like 'turn45' or 'turn30' to have it turn by a different amount for each key press.

  • 'isometric' style has the WA keys move up/down, but the QE, AD keys move diagonally along an isometric plane.

Cardinal:

Turn:

Isometric:


Check out other books by Al Sweigart, free online or available for purchase:

...and other books as well! Or register for the online video course. You can also donate to or support the author directly.