6
\$\begingroup\$

I am working on a turtle project where the user can draw their own avatar.

The thing is, I want the user to be able to decide whether the turtle they drew will be filled, or not.

The filled part is simple, as by default, the polies will get filled, but the only way I know how to avoid filling is to retrace the lines so that the end of the line meets the start of the line.

Is there a built-in method or a more efficient way to keep the polies empty? The problem with my current method is that the more lines (parameter) used for turtle, the more rocky the program runs (the area doesn't influence the smoothness of the program).

import turtle

wn = turtle.Screen()

pen = turtle.Turtle('circle')
pen.shapesize(0.1, 0.1)

cor = []

# function to draw with the pen
def drag(x, y):
    wn.tracer(0)
    pen.goto(x, y)
    cor.append(pen.pos())

# function to break out of while loop
def fill():
    global done
    done = True

# function to break out of while loop and set fill to False
def nofill():
    global done, fill
    done = True
    fill = False
    
wn.listen()
wn.onkeypress(fill, 'f')
wn.onkeypress(nofill, 'n')

pen.ondrag(drag)

done = False
fill = True

while not done:
    wn.update()
    
pen.begin_poly()

if fill:
    for c in cor:
        pen.goto(c)
else:
    for c in cor[::-1]: # first go backards, then forward to avoid fill
        pen.goto(c)
    for c in cor:
        pen.goto(c)
        
pen.end_poly()

wn.register_shape("mypen", pen.get_poly())
wn.clear()

example = turtle.Turtle('mypen')
wn.mainloop()

Example with fill:

  • Run the above code.

  • Draw a shape.

  • Press f

enter image description here

Example without fill:

  • Run the above code.

  • Draw a shape.

  • Press n

enter image description here

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

Documentation

The PEP 8 style guide recommends adding docstrings for functions and at the top of the code. For example, summarize the purpose of the code:

"""
Turtle project where the user can draw their own avatar.

The user is able to decide whether the turtle they drew will be filled, or not.
"""

For the functions, convert comments:

# function to draw with the pen
def drag(x, y):

to docstrings:

def drag(x, y):
    """Draw with the pen"""

There is no need to state that it is a function because the def keyword lets us know.

Layout

Move the functions to the top after the import line. Having them in the middle of the code interrupts the natural flow of the code (from a human readability standpoint).

DRY

This for loop is duplicated in both branches of the if/else:

for c in cor:
    pen.goto(c)

The code can be simplified to eliminate the repetition:

if not fill:
    for c in cor[::-1]: # first go backwards, then forward to avoid fill
        pen.goto(c)

for c in cor:
    pen.goto(c)

I also fixed the backards typo.

Naming

The variable named cor is not very descriptive. I looks like it is an array that holds pen positions.

for c in cor:
    pen.goto(c)

A better name would be positions.

for position in positions:
    pen.goto(position)

It is a little confusing to have a function and a variable with the same name: fill. Consider changing the function name from:

def fill():

to:

def fill_poly():
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.