4

I want to write a program that changes the turtle image in order each time I press the 'n' key.

It should first start with the 'classic' shape, and every time the 'n' key is pressed, change the shape to 'circle', 'arrow', 'turtle' and then loop back to 'classic'.

import turtle
canvas = turtle . Screen ()
t = turtle . Turtle ()

def changeTurtle () :
    for n in range (1, 5) :
        if n == 1 :
            t . shape ('circle')
        elif n == 2 :
            t . shape ('arrow')
        elif n == 3 :
            t . shape ('turtle')
        elif n == 4 :
            t . shape ('classic')

t . shape ('classic') # first turtle 'classic' shape
canvas . onkey (changeTurtle, 'n') # press 'n'key

canvas . listen ()
turtle . mainloop ()

It should have changed once when I pressed the 'n' key. The problem is, it is changing too quickly.

cdlane
  • 40,441
  • 5
  • 32
  • 81
René
  • 43
  • 2
  • Is your problem that it changes through *all* variants on a *single* key press, or that it changes all variants without delay in-between? – MisterMiyagi Aug 09 '19 at 14:13

3 Answers3

1

You're going through all possible values of n at once with the for loop. What you need to do instead is save a value of n outside the function, and change it every time the function is called:

n = 1
def changeTurtle():
    global n
    n = (n % 4) + 1  # cycle through 1, 2, 3, 4, 1, 2, 3, 4, ...
    if n == 1:
        t.shape('circle')
    elif n == 2:
        t.shape('arrow')
    elif n == 3:
        t.shape('turtle')
    else:
        t.shape('classic')
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
0

Here's how I'd over-engineer this problem (and eliminate the need for a global statement):

from turtle import Screen, Turtle

def changeTurtle():
    index = shapes.index(turtle.shape()) + 1
    shape = shapes[index % len(shapes)]

    turtle.shape(shape)
    screen.title(shape)

turtle = Turtle()
turtle.shapesize(3)
turtle.shape('classic')  # first turtle 'classic' shape

screen = Screen()
screen.title(turtle.shape())
shapes = screen.getshapes()

screen.onkey(changeTurtle, 'n')  # press 'n' key

screen.listen()
screen.mainloop()
cdlane
  • 40,441
  • 5
  • 32
  • 81
0

An alternative to your function would be to have an infinite iterator (like itertools.cycle) loaded with all the shapes you want to cycle through. When you want the next shape, your program simply asks for it, changes the turtle, and then continues with anything else it was doing before. The following program demonstrates how this can be done:

import itertools
import turtle


def main():
    canvas = turtle.Screen()
    t = turtle.Turtle()
    # noinspection PyProtectedMember
    shapes = itertools.cycle(sorted(canvas._shapes.keys()))
    t.shape(next(shapes))
    canvas.onkey(lambda: t.shape(next(shapes)), 'n')
    canvas.listen()
    canvas.mainloop()


if __name__ == '__main__':
    main()
Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117