Search code examples
pythonturtle-graphicspython-turtle

Turtle NameError after defining a variable in a separate function


I want to create a turtle game. When I click the turtle shape in the game, it should give score +1 point so that I can count the points. But when I execute the command and click on the turtle shape it is giving me a name error which is NameError: name 'score_turtle' is not defined even though it is defined in the upper command. Please help me to fix it.

import turtle
import random

screen = turtle.Screen()
screen.bgcolor("light blue")
FONT = ('Arial', 25, 'normal')
skor = 0
turtle_list = []


#score turtle


def score_turtle_setup():
    score_turtle = turtle.Turtle()
    score_turtle.hideturtle()
    score_turtle.penup()
    score_turtle.color("dark blue")
    top_screen = screen.window_height() / 2
    y = top_screen * 0.85
    score_turtle.setpos(-200,y)
    score_turtle.write(arg=f"SCORE: 0", move=False, align="center", font=FONT)

def make_turtle(x, y):
    point = turtle.Turtle()

    def handle_click(x, y):
        global skor
        skor += 1
        score_turtle.write(arg=f"SCORE: {skor}", move=False, align="center", font=FONT)

    point.onclick(handle_click)
    point.shape("turtle")
    point.penup()
    point.color("green")
    point.shapesize(1.5)
    point.goto(x * 12, y*12)
    turtle_list.append(point)


x_coordinats = [-20,-10,0,10,20]
y_coordinats = [20,10,0,-10]


def setup_turtles():
    for x in x_coordinats:
        for y in y_coordinats:
            make_turtle(x, y)

def hide_turtles():
    for point in turtle_list:
        point.hideturtle()

def show_turtles():
    random.choice(turtle_list).showturtle()

turtle.tracer(0)

score_turtle_setup()
setup_turtles()
hide_turtles()
show_turtles()

turtle.tracer(1)

turtle.mainloop()

I tried to call the function score_turtle_setup from the handle_click function but that did not work.


Solution

  • Variables are scoped to the function by default. That means that when the function returns, all variables in the function scope are destroyed. Luckily, functions let you return values, so you can do something like:

    def score_turtle_setup():
        score_turtle = turtle.Turtle()
        # ...
        return score_turtle
    
    # ...
    score_turtle = score_turtle_setup()
    

    Now the score_turtle variable is assigned in the global scope, where it can be accessed from any of your other functions.

    This may not be great design, but for a small program, it's fine. Down the line, if the program grows, consider using a class and/or module for encapsulating logical entities like this.

    In general, the situation isn't specific to turtle, so How do I get a result (output) from a function? How can I use the result later? is a good canonical resource.