how to thread multiple turtle heads in python? - python

I made a recursive star for Art with Technology. My teacher wants me to make similar stars in 4 corners, I accomplished that too, but the screen recording is too big, hence I need them to run simultaneously, (currently they run after a star is completed). I tried threading but It does'nt do anything
Here is a minimal code:
from turtle import *
import threading
from itertools import permutations
from random import choice
import concurrent.futures
screen=Screen()
def star_multiple(turtle):
# repeatedly calls draw star function
def pen(foo):
# a convenient tool to do all penup/pendown
def drawstar(turtle,l,colors):
# draws a star of edge=l param.
a,b,c,d=Turtle(),Turtle(),Turtle(),Turtle()
pen('penup')
a.goto(-500,200)# the turtle go to their position(works)
b.goto(500,200)
c.goto(-500,-200)
d.goto(500,-200)
pen('pendown')
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
executor.map(star_multiple,[a,b,c,d])# This doesn't work,
done()
drawstar function
output I am getting

Related

My turtle module code is executing the first part but not the second part. Both parts are working fine on their own

I'm making a simple snake game in python. I am in the earlier stages of just making the snake move at this point. So I have 3 files, main.py, Turtle_Skin.py and Turtle_Control.py
The first part (In Turtle_Skin.py) is working just fine where I need to make the snake take the starting position, however even if I try migrating the code from Turtle_Control.py to main.py (to make sure it executes and doesn't get left behind while importing), it won't execute
My Code with file names:
main.py:
from Turtle_Control import *
from Turtle_Skin import *
positions_goto()
Turtle_Skin.py:
from turtle import *
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("Snake_Food_Game")
screen.tracer(1)
Baby_Turtle = Turtle()
Mommy_Turtle = Turtle()
Daddy_Turtle = Turtle()
All_Turtles = [Baby_Turtle, Mommy_Turtle, Daddy_Turtle]
for turtle in All_Turtles:
turtle.shape("square")
turtle.pencolor("white")
turtle.color("white")
def positions_goto():
Daddy_Turtle.penup()
Daddy_Turtle.goto(x=-40, y=0)
Mommy_Turtle.penup()
Mommy_Turtle.goto(x=-20, y=0)
Baby_Turtle.penup()
positions_goto()
screen.exitonclick()
Turtle_Control.py
from Turtle_Skin import *
import time
positions_goto()
is_on = True
while is_on:
screen.update()
time.sleep(0.1)
for part_num in range(len(All_Turtles) - 1, 0, -1):
xcord = All_Turtles[part_num - 1].xcor()
ycord = All_Turtles[part_num - 1].ycor()
All_Turtles[part_num].goto(x=xcord, y=ycord)
Baby_Turtle.forward(20)
screen.exitonclick() blocks your code, running the main turtle loop, until you click the screen.
Tracing the code execution:
main.py runs from Turtle_Control import * on line 1
Turtle_Control.py runs from Turtle_Skin import * on line 1
Turtle_Skin.py runs most of the turtle code, then blocks at screen.exitonclick(). After you click, only then does from Turtle_Skin import * on line 1 of Turtle_Control.py resolve so that line 2, import time, can continue. But by then the window's been destroyed so the while loop is much too late.
A good way to figure out what's going on with this behavior is to add print()s to your code to see if the code you care about is even executing, and if so, when. Creating a minimal example of the problem would make the issue obvious:
import turtle
turtle.exitonclick() # => blocks until the screen is clicked
print("hi") # => only executes after the screen was clicked
The original code organization doesn't make much sense. Modules have no obvious responsibility. positions_goto() is called in many different locations. The main code that initializes turtles and runs the game loop is spread across a few files seemingly haphazardly.
With such a small amount of code, creating modules seems premature here. I'd put all of the code into one file until you have things working ("I am in the earlier stages of just making the snake move at this point") and really need obvious separation of concerns. When you do, I'd create different files for different classes (things/entities in the game), primarily. snake.py with class Snake: would be one example. food.py with class Food: might be another potential file.
There should be no "loose" code in the global scope in each file other than a class or function or two. Main-line code (particularly if non-idempotent) in modules should be in an if __name__ == "__main__": block so that it's not invoked simply because the module was imported (which might happen multiple times in an app, as is the case here).
If you want to separate the whole game from main, that's fine, but keep the set up and main loop intact so they execute as a unit.

Executing multiple Python commands at once

I was wondering what the easiest way to execute two or more commands at the same time in python. For example:
from turtle import *
turtle_one=Turtle()
turtle_two=Turtle()
turtle_two.left(180)
#The lines to be executed at the same time are below.
turtle_one.forward(100)
turtle_two.forward(100)
You can effectively do this using the timer event that comes with the turtle module:
from turtle import Turtle, Screen
turtle_one = Turtle(shape="turtle")
turtle_one.setheading(30)
turtle_two = Turtle(shape="turtle")
turtle_two.setheading(210)
# The lines to be executed at the same time are below.
def move1():
turtle_one.forward(5)
if turtle_one.xcor() < 100:
screen.ontimer(move1, 50)
def move2():
turtle_two.forward(10)
if turtle_two.xcor() > -100:
screen.ontimer(move2, 100)
screen = Screen()
move1()
move2()
screen.exitonclick()
With respect to threads, as suggested by others, read up on the issues discussed in posts like Multi threading in Tkinter GUI as Python's turtle module is built on Tkinter and that recent post notes:
a lot of GUI toolkits are not thread-safe, and tkinter is not an
exception
Try using the threading module.
from turtle import *
from threading import Thread
turtle_one=Turtle()
turtle_two=Turtle()
turtle_two.left(180)
Thread(target=turtle_one.forward, args=[100]).start()
Thread(target=turtle_two.forward, args=[100]).start()
This starts the turtle_one/two.forward function in the background, with 100 as an argument.
To make it easier, make a run_in_background function...
def run_in_background(func, *args):
Thread(target=func, args=args).start()
run_in_background(turtle_one.forward, 100)
run_in_background(turtle_two.forward, 100)

program stops running when going to task manager

I have a program which makes the mouse go crazy and point randomly on different places on screen.
it works just fine, but when i go to task manager or simply click ctrl + alt + delete, it stops functioning, even when im exiting task manager.
any help?
(the program still seems to run in the proccess list, but simply doesn't do anything)
the program:
from win32api import SetCursorPos,GetSystemMetrics
from time import sleep
from random import uniform
from win32console import GetConsoleWindow
from win32gui import ShowWindow
win = GetConsoleWindow()
ShowWindow(win,0)
def click(x,y):
SetCursorPos((x,y))
while True:
click((int)(uniform(GetSystemMetrics(0),10)),(int)(uniform(GetSystemMetrics(1),10)))
sleep(0.02)

turtle.tracer not working properly

I was writing code for a CodeGolf.SE contest and I came onto something I didn't understand. The code is not the best (e.g. I wouldn't normally use while 1) but the issue is still the same:
import time
from turtle import *
ht()
tracer(3)
while 1:
clear() #1
color("snow") #
a=time.strftime("#%H%M%S") #
bgcolor(a) #2
write(a,0,"center") #3
From the documentation it seems that tracer(3) means that each third screen update is drawn. I think this doesn't work, because when I run this I don't get clear text (it seems like it switches very fast between visible/invisible).
I tried with different arguments for tracer without success. I know a solution is to call tracer(0) instead and update() when needed, but I'd like it to work without update().
the following does solve it, just to show what I mean. As I have understood tracer(n) should propagate the changes each n-th step, and it does not seem to do that:
import time
from turtle import*
tracer(0) #turn of auto-update
while 1:
reset()
ht()
color("snow")
a=time.strftime("#%H%M%S")
write(a,0,"center")
bgcolor(a)
update() #8 propagate changes
The way I would approach this with the current Python3 turtle is avoid tracer() and take advantage of undo() instead:
from turtle import*
import time
ht()
color("snow")
write("")
while 1:
undo()
a=time.strftime("#%H%M%S")
bgcolor(a)
write(a,0,"center")
It does what you want and is fewer strokes golf-wise.

Python: Making Background Image with Turtles

I am trying to insert a .gif file as a background image in my turtle world for a separate turtle to travel on, but I can't get it to work. I'm new to python and any help would be great.
Here's the current code:
from turtle import *
from Tkinter import *
def test():
turtle.bgpic("warehouse1.gif")
fd(100)
goto(50, 100)
from turtle import * makes available all names in the turtle module so you could use bare bgpic() in this case:
#!/usr/bin/env python
from turtle import *
def test():
speed(1) # set the slowest speed to see the turtle movements
bgpic('warehouse1.gif')
fd(100)
goto(50, 100)
mainloop()
test()
Note: In general you should not use wildcard imports (*) outside a Python interactive shell. See Idioms and Anti-Idioms in Python.

Categories

Resources