简体   繁体   中英

How to Break Infinite Loop in Turtle Graphics Python

I wrote the code for an assignment which completes the task required. Which is to draw the shape of a polygon from user input and draw the amount of shapes per side number specified. The only problem is after the shape is drawn the arrow just keeps tracing through in an infinite loop. I tried using break at the end but it did not work.

 from turtle import *

def polygon(n, length):
    Screen()
    shape('turtle')
    mode('logo')

n = input ("Enter number of sides ")
print ("you entered ", n) 
length = input("Enter the length of sides ")
print ("you entered ", length)
n=int(n)
length=int(length)


for side in range(n):
    forward(length)
    right(360/n)
    while side in range(n):
        right(360/n)
        for side in range(n):
            forward(length)
            right(360/n)

What I have so far will technically work for the assignment, however the infinite loop at the end is annoying me.

The main problem is that the while loop goes for an infinite amount of time.

#This is infinite loop because 'side' iterator is ALWAYS in the sequence returned from range function
while side in range(n):

Also, with the current structure of your code the function does nothing and only wastes space (you probably call it from the shell which is understandable). There's a few more redundancies that we can get ride of too. Lets design your script so that the turtle's polygons can be controlled from the function you created. Hopefully you'll see how powerful the turtle module can be when utilized with recursion and a proper use of functions.

Lets look at the declarion of your polygon function 1st. The reason I feel your script should revolve around your polygon function aside from the natural convience of functions is because of the parameters you included in the script. Although they are not needed (here atleast) per the implied design of your script, the inclusion of them implies A: You intended for this function to control the turtle, or B: You don't quite understand how functions/parameters work. To offer more of a learning experience we should definitely focus this script around that function in either case.

def polygon(n,length): #<--- get ride of 'n' & 'length' parameters
def polygon(n=None,length=None): #<---These are defualt values if you wish to go with that direction
def polygon(): #<---This is the declaration I'll follow for aiding your script

Get rid of the paramaters for now. We'll bring them back in a nested function later. Next we're going to add the rest of the script to the polygon function. Because your n and length variable collect input, it renders the parameters for the polygon function useless. It's not an either or scenerio, with some control flow you can have both if you wanted. Before we add the script to our polygon function I'd like to point out how you declared the variables twice, the second time you converted them to integers. Python allows us to nest them in a int() function the 1st time we declare them.

n = input("Enter num ")
n = int(n) #<---instead of these 1st 2 lines, do the 3rd line below.
n = int(input("Enter num: ")) #<--1 line of code that is equally as readable as 2.

After modifying both the n & length variables, lets add everything into our polygon function (except the while loop, get rid of everything involved with that). Notice that the Screen,shape, and mode functions have been moved below the variable declarions. This is so the turtle window does not jump in front of the user while they're inputing information into the program.

def polygon():
    n = int(input("Enter number of sides: "))
    print("You entered %d sides.\n"%(n))
    length = int(input("Enter length of sides: "))
    print("Your sides are %d pixels long.\n"%(length))
    Screen()
    shape('turtle')
    mode('logo')

Now that we have a clean and readable function lets handle our business with creating polygons. For this we'll use a nested function that utilizes both recursion and parameters. We'll call it 'looper'. The reason being is that your assignment is to make an equal amount of polygons that there are sides (in otherwords, num of polygons == n). looper will achieve that for us. 1st it will take in the variables established in polygon as parameters. Then we'll use your previous for loop inside.

def looper(n,length,loops=n): #notice the 'loops=n' default parameter, this allows to keep track of it recursively
    if (loops > 0): #As long as loops is greater than zero this functin will repeat itself as many times as 'n'
        for side in range(n):
            forward(length)
            right(360/n)
        penup()
        #penup after the forloop so that the turtle will not draw while searching for next polygon space
        setposition(xcor()+length,ycor()+length) #xcor() and ycor() return the current position of the turtle
        #notice that we add it to the length of of our sides, this is how the turtle will space out the polys.
        #I would even experiment with things like setposition(xcor()+(length*2),ycor()+(length*2))
        pendown() #after turtle find the position we we use pendown() to prepare to draw again
        loops -= 1 #this decrements the loops parameter so that the functin will not call itself infinitely
        #(stack overflow)
        looper(n,length,loops) #recursively call our looper function again
        return #I personally always return the end of recursive functions to be safe, this may be redundant

Essentially recursion is when a function calls itself within itself repeatedly to perform a task. To make sure that it eventually ends we tell the program: "Only draw polygons if there are any loops" furthermore after the functions performs it's duties we tell it "subtract loops by 1" to make sure that the loops will eventually be zero. This and the return statement (a rough equivalent to what you were referring to as 'break') will assure us that we do not perfom tasks an infinite amount of times. The last step in this code is to make sure that you actually call the polygon function so your code will run AND to also call looper(n,length) and the end of your polygon function for the same reason.

Your code should look something like this:

from turtle import *

def polygon():
    n = int(input("Enter number of sides: "))
    print("You entered %d sides.\n"%(n))
    length = int(input("Enter length of sides: "))
    print("Your sides are %d pixels long.\n"%(length))
    Screen()
    shape('turtle')
    mode('logo')
    def looper(n,length,loops=n):
        if (loops > 0):
            for side in range(n):
            forward(length)
            right(360/n)
            penup()
            setposition(xcor()+length,ycor()+length)
            pendown()
            loops -= 1
            looper(n,length,loops)
            return
    looper(n,length)


polygon()

I pretty much did the assignment for you, but if you learned a thing or two then my goal is achieved. I hope I helped any!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM