I can't get turtle ontimer() function working.
When I use the ontimer function of the turtle library the code executes directly and does not wait for the expected time.
To make my code work I used the function time.sleep(1) which is not a great solution
Here is the code:
import turtle, time
heure_=int(input("Enter the time in hh format: "))
minute_=int(input("Enter the minutes in mm format: "))
seconde_=int(input("Enter the seconds in ss format: "))
#calculate time
def formt(h, m, s):
minute, seconde = divmod(s, 60)
heure, minute = divmod(minute m, 60)
heure = (heure h)%12
return heure, minute, seconde
heure, minute, seconde = formt(heure_, minute_, seconde_)
#function to calculate hands angles
def angle(h, m, s):
angle_s=(360 / 60) * s
angle_m=(360 / 60) * m angle_s*1/60
angle_h=(360 / 12) * h angle_m*1/12
return angle_h, angle_m, angle_s
#hands
def aigh(h, x=0, y=0, f=100):
hour_t.ht()
hour_t.goto(x,y)
hour_t.setheading(90)
hour_t.rt(h)
hour_t.pendown()
hour_t.width(10)
hour_t.forward(f)
def aigm(m, x=0, y=0, f=150):
min_t.ht()
min_t.goto(x,y)
min_t.setheading(90)
min_t.rt(m)
min_t.pendown()
min_t.width(5)
min_t.forward(f)
def aigs(s, x=0, y=0, f=170):
sec_t.ht()
sec_t.goto(x,y)
sec_t.setheading(90)
sec_t.color("red")
sec_t.width()
sec_t.rt(s)
sec_t.pendown()
sec_t.width(1)
sec_t.forward(f)
#init turtle
t = turtle.Turtle()
#turtles for hands
hour_t = turtle.Turtle()
min_t = turtle.Turtle()
sec_t = turtle.Turtle()
wn = turtle.Screen()
wn.title("Clock")
wn.tracer(0)
def draw(h, m, s):
aigh(h)
aigm(m)
aigs(s)
def refresh(h=heure, m=minute, s=seconde):
global seconde
wn.tracer(0)
hour_t.undo()
min_t.undo()
sec_t.undo()
h_, m_, s_ = formt(h, m, s)
t.undo()
#get the hands angles
agl_h, agl_m, agl_s = angle(h_, m_, s_)
#draw the hands
draw(agl_h, agl_m, agl_s)
wn.update()
seconde =1
#wn.ontimer(refresh, 1000)
for _ in iter(int, 1):
refresh(s=seconde)
time.sleep(1)
How can i make the code work ? Thank you.
CodePudding user response:
You have fallen into one of the classic Python traps. When you say this:
def refresh(h=heure, m=minute, s=seconde):
The default values are captured at the time the function is defined. Those are not live values. So, if you enter 5, 15, 23, the default values for those parameters will ALWAYS be 5, 15 and 23, regardless of how the globals change.
You are totally dependent on the globals here, so just use them. This works:
import turtle, time
heure_=int(input("Enter the time in hh format: "))
minute_=int(input("Enter the minutes in mm format: "))
seconde_=int(input("Enter the seconds in ss format: "))
#calculate time
def formt(h, m, s):
minute, seconde = divmod(s, 60)
heure, minute = divmod(minute m, 60)
heure = (heure h)%12
return heure, minute, seconde
heure, minute, seconde = formt(heure_, minute_, seconde_)
#function to calculate hands angles
def angle(h, m, s):
angle_s=(360 / 60) * s
angle_m=(360 / 60) * m angle_s*1/60
angle_h=(360 / 12) * h angle_m*1/12
return angle_h, angle_m, angle_s
#hands
def aigh(h, x=0, y=0, f=100):
hour_t.ht()
hour_t.goto(x,y)
hour_t.setheading(90)
hour_t.rt(h)
hour_t.pendown()
hour_t.width(10)
hour_t.forward(f)
def aigm(m, x=0, y=0, f=150):
min_t.ht()
min_t.goto(x,y)
min_t.setheading(90)
min_t.rt(m)
min_t.pendown()
min_t.width(5)
min_t.forward(f)
def aigs(s, x=0, y=0, f=170):
sec_t.ht()
sec_t.goto(x,y)
sec_t.setheading(90)
sec_t.color("red")
sec_t.width()
sec_t.rt(s)
sec_t.pendown()
sec_t.width(1)
sec_t.forward(f)
#init turtle
t = turtle.Turtle()
#turtles for hands
hour_t = turtle.Turtle()
min_t = turtle.Turtle()
sec_t = turtle.Turtle()
wn = turtle.Screen()
wn.title("Clock")
wn.tracer(0)
def draw(h, m, s):
aigh(h)
aigm(m)
aigs(s)
def refresh():
global seconde
wn.tracer(0)
hour_t.undo()
min_t.undo()
sec_t.undo()
h_, m_, s_ = formt(heure, minute, seconde)
t.undo()
#get the hands angles
agl_h, agl_m, agl_s = angle(h_, m_, s_)
#draw the hands
draw(agl_h, agl_m, agl_s)
wn.update()
seconde =1
while True:
refresh()
time.sleep(1)
CodePudding user response:
I see a number of small issues with your code (e.g. the hands don't take on their assigned widths and colors.) I agree with @TimRoberts that default arguments are your primary issue. Below is my rework of the code to use ontimer()
and attempt to both fix and simplify it:
from turtle import Screen, Turtle
heure_ = int(input("Enter the time in hh format: "))
minute_ = int(input("Enter the minutes in mm format: "))
seconde_ = int(input("Enter the seconds in ss format: "))
# calculate time
def formt(h, m, s):
minute, seconde = divmod(s, 60)
heure, minute = divmod(minute m, 60)
heure = (heure h) % 12
return heure, minute, seconde
# function to calculate hands angles
def angle(h, m, s):
angle_s = (360 / 60) * s
angle_m = (360 / 60) * m angle_s/60
angle_h = (360 / 12) * h angle_m/12
return angle_h, angle_m, angle_s
# hands
def aigh(h, x=0, y=0, f=100):
hour_t.goto(x, y)
hour_t.clear()
hour_t.setheading(h)
hour_t.forward(f)
def aigm(m, x=0, y=0, f=150):
min_t.goto(x, y)
min_t.clear()
min_t.setheading(m)
min_t.forward(f)
def aigs(s, x=0, y=0, f=170):
sec_t.goto(x, y)
sec_t.clear()
sec_t.setheading(s)
sec_t.forward(f)
def draw(h, m, s):
aigh(h)
aigm(m)
aigs(s)
heure, minute, seconde = formt(heure_, minute_, seconde_)
def refresh():
global heure, minute, seconde
heure, minute, seconde = formt(heure, minute, seconde)
# get the hands angles
agl_h, agl_m, agl_s = angle(heure, minute, seconde)
# draw the hands
draw(agl_h, agl_m, agl_s)
seconde = 1
screen.update()
screen.ontimer(refresh, 1000)
screen = Screen()
screen.mode('logo') # 0 degrees at top, circles go clockwise, like a clock!
screen.title("Clock")
screen.tracer(False)
# turtles for hands
hour_t = Turtle()
hour_t.hideturtle()
hour_t.width(10)
min_t = Turtle()
min_t.hideturtle()
min_t.width(5)
sec_t = Turtle()
sec_t.hideturtle()
sec_t.width(1)
sec_t.color("red")
refresh()
screen.mainloop()