Turtle.listen() doesn't work for me

from turtle import Turtle
import turtle

s = turtle.Screen()
s.setup(width=1250, height=600)
s.title("race")
s.listen()

bg = s.textinput(title="bg", prompt="enter bg color")
s.bgcolor(bg)

n1 = s.textinput(title="welcome", prompt="enter player1's name")
n2 = s.textinput(title="welcome", prompt="enter player2's name")

c1 = s.textinput(title="p color", prompt=f"pick {n1}'s color")
c2 = s.textinput(title="p color", prompt=f"pick {n2}'s color")

sh1 = s.textinput(title="p shape", prompt=f"pick {n1}'s shape")
sh2 = s.textinput(title="p shape", prompt=f"pick {n2}'s shape")

p1 = Turtle()
p1.shape(sh1)
p1.color(c1)
p1.penup()
p1.goto(-600,200)
p1.pendown()
s = 0

p2 = Turtle()
p2.shape(sh2)
p2.color(c2)
p2.penup()
p2.goto(-600,-200)
p2.pendown()
l = 0

def m1():
    p1.forward(10)
    s = s + 10

def m2():
    p2.forward(10)
    l = l + 10

s.onkey(key="s", fun=m1)
s.onkey(key="l", fun=m2)

if s >= 600 and l < 600:
    win = Turtle()
    win.style = ('Courier', 40, 'bold')
    win.write(f"{n1} won", font=title.style, align="center")
    turtle.bye()

if l >= 600 and s < 600:
    win = Turtle()
    win.style = ('Courier', 40, 'bold')
    win.write(f"{n2} won", font=title.style, align="center")
    turtle.bye()

s.exitonclick()

ERROR:
AttributeError: ‘int’ object has no attribute ‘onkey’

Hi,

on this line:

You have essentially nullified the prior set up. Remove this line from your code.

For example, if I define a function, use it a few times, then set it to 0, this will undo the function definition:

# Define the function
def calc(x, y):

    return x * y

# Use the function a few times
calc(5,6)
30
calc(100, 3)
300
calc = 0    # Set the function name to `0`
calc(4,3)  # Attempt to re-use the function -> will get an error

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    calc(4,3)
TypeError: 'int' object is not callable

This is essentially what is happening in your code. You have nullified the s variable name when you assigned it a value of 0 and then trying to call it with the following line:

s.onkey(key="s", fun=m1)

Now s means the number 0, which I guess you are using to track p1’s position. Therefore, it stops meaning the turtle.Screen() from before.

Therefore these cannot work, exactly as the error message says: s is an int, which doesn’t provide that onkey method. If you want to remember both values, they need separate names.

Aside from that,

I guess that you want this to update the global s when it gets called. But that does not work. Please read: