Why is there a second Turtle? - python

I am learning turtle graphics in python and for some reason there is a second turtle on the screen and I haven't even created a second turtle. How can I get rid of the second turtle?
import turtle
s = turtle.getscreen()
t = turtle.Turtle()
for i in range(4):
t.fd(100)
t.rt(90)
turtle.exitonclick()

The second turtle at the starting location appears because of the line s = turtle.getscreen().
This line is not needed (you do not use s), and if you remove it this turtle disappears but the rest of the code seems to work as before.

The turtle library exposes two interfaces, a functional one (for beginners) and an object-oriented one. You got that extra turtle because you mixed the two interfaces (and #mkrieger1's solution doesn't fix that completely).
I always recommend an import like:
from turtle import Screen, Turtle
screen = Screen()
turtle = Turtle()
for _ in range(4):
turtle.forward(100)
turtle.right(90)
screen.exitonclick()
This gives you access to the object-oriented interface and blocks the functional one. Mixing the two leads to all sorts of bugs and artifacts.

To combine the answer from mkrieger1 and cdlane, you could replace
s = turtle.getscreen()
with
s = turtle.Screen()
You've still got a variable holding the screen (in case you should ever need it), and it doesn't generate that extra turtle in the center.

Related

Turtle from image won't draw over another turtle's stamp

This code sets up a background of stamps placed by one turtle. Another turtle, (whose shape is from an imported image file) moves around over the background. But the second turtle is not visible whenever it is positioned over a stamp placed by the first turtle. If I make the moving turtle one of the standard shapes, eg circle, then it stays visible. So there's something odd about using an imported image for the turtle, which causes it to disappear whenever it's on top of one of the stamps.
#!/usr/bin/python3
from turtle import *
from time import sleep
scr = Screen()
scr.register_shape('player.gif')
mover = Turtle()
bgnd = Turtle()
bgnd.color('blue')
mover.shape('player.gif')
bgnd.shape('square')
for i in range(5):
bgnd.goto(i*20,0)
bgnd.stamp()
for i in range(5):
mover.goto((8-i)*20,0)
sleep(1)
The accompanying image is the one I've referred to as player.gif (I can see it at the bottom of the post, but it's very small).
Can anyone help explain why this is and how to get around it?
I'm not sure if this is a bug or subtlety, but stamps aren't pixels on the screen like dot() -- the stamp() function returns an ID that allows selectively removing them. My guess is it's a layering issue with the underlying tkinter. In turtle, if you have a layering issue, sometimes it helps to do things in a different order:
from turtle import Screen, Turtle
from time import sleep
background = Turtle()
background.hideturtle()
background.color('blue')
background.shape('square')
for i in range(5):
background.goto(i * 20, 0)
background.stamp()
screen = Screen()
screen.register_shape('player.gif')
mover = Turtle()
mover.shape('player.gif')
for i in range(5):
mover.goto((8 - i) * 20, 0)
sleep(1)
screen.exitonclick()
In the long run, time.sleep() isn't a friend of event-based turtle. It's fine for examples like this but anything more and it will cause more problems than it solves. Look into the ontimer() method of the screen.

Is there a way to shorten my code so that I don't have to write "turtle." every time I use functions from the turtle module?

I am trying to draw squares using turtle in python, and every time I want to command it to do something I must write turtle.
import turtle
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.back(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.back(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.back(200)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.back(100)
turtle.exitonclick()
I expect to write my code without having to write turtle every time
You can import everything from the turtle module by writing
from turtle import * # this is a wildcard import
Instead, however, you should just import turtle as t (or whatever else you want), like so:
import turtle as t # you can replace t with any valid variable name
Because wildcard imports tend to create function definition conflictions
Conversely, you could import only the classes (or methods) you need from from the module. Turtle is a necessary import:
from turtle import Turtle
Now, we have to instantiate it:
t = Turtle()
Now we can use it:
t.do_something() # methods that act on the turtle, like forward and backward
That will not import the Screen module however, so you won't be able to use exitonclick() unless you import Screen too:
from turtle import Turtle, Screen
s = Screen()
s.exitonclick()
As #cdlane notes though, loops may actually be your best bet for reducing the amount of code you have to write. This code:
for _ in range(x):
turtle.forward(100)
turtle.right(90)
Moves the turtle forwards then rightwards x times.
Do you have any idea how many comments there are on SO saying "Don't use wildcard imports" in response to people doing from turtle import * as folks are suggesting? I'll further argue, don't do import turtle as t as it exposes the functional interface to turtle. The turtle module is object-oriented, you need only expose that interface. If you're tired of typing so much, learn about loops:
from turtle import Screen, Turtle
t = Turtle()
for _ in range(4):
t.forward(100)
t.right(90)
for _ in range(4):
t.backward(100)
t.left(90)
t.backward(100)
for _ in range(3):
t.backward(100)
t.left(90)
s = Screen()
s.exitonclick()
Admittedly, I don't really mind wildcard imports for short turtle & tkinter examples as well as Zelle graphics programs. But none of that fd() nonsense instead of forward() either! Celebrate being a turtle, don't hide in your shell!
You could use the wildcard import:
from turtle import *
But it'd be better to use the prefixed imports to keep your namespaces clean. See #alec_a's answer.
Disclaimer: this answer is for lazy people like me :)
There are already good answers that show you how to solve your problem, and that warn you regarding wildcard imports.
If you just want to play with turtle module you can make your life easy, i.e. instead of writing turtle.forward(90) it is better to just write forward(90) but it will be super easy if you just write f(90)
again it will affect the readability of your code but common it deserve a trial
now your code will looks like
Edit: modify imports in one line as suggested by #chepner to be super lazier
from turtle import forward as f, back as b, right as r, left as l, exitonclick
# to draw one square
f(100)
r(90)
f(100)
r(90)
f(100)
r(90)
f(100)
exitonclick()

What is the difference between turtle and Turtle?

How are turtle and Turtle different from each other in python version 2.7?
import turtle
star = turtle.Turtle()
for i in range(50):
star.forward(50)
star.right(144)
turtle.done()
The turtle module is unusual. To make it easier for beginning programmers, all methods of the Turtle class are also available as top level functions that operate on the default (unnamed) turtle instance. All methods of the Screen class are also available as top level functions that operate on the default (sole) screen instance. So both this:
import turtle
star = turtle.Turtle() # turtle instance creation
for i in range(5):
star.forward(50) # turtle instance method
star.right(144) # turtle instance method
screen = turtle.Screen() # access sole screen instance
screen.mainloop() # screen instance method
and this:
import turtle
for i in range(5):
turtle.forward(50) # function, default turtle
turtle.right(144)
turtle.done() # function, mainloop() synonym, acts on singular screen instance
are both valid implementations. Many turtle programs end up mixing the functional interface with the object interface. To avoid this, I strongly recommend the following import syntax:
from turtle import Turtle, Screen
This forces the object approach to using turtle, making the functional approach unavailable:
from turtle import Turtle, Screen
star = Turtle() # turtle instance creation
for i in range(5):
star.forward(50) # turtle instance method
star.right(144) # turtle instance method
screen = Screen() # access sole screen instance
screen.mainloop() # screen instance method
Simply put, turtle is the package or library and Turtle() class constructor method used to instantiate the class.
hope you have a good time!
"turtle" is actually the module that we use .
Turtle or we can say as turtle.Turtle is actually a object that you can move it change speed, color, shape and ....
here you can see an example:
enemy = turtle.Turtle(shape="rabbit.gif")
enemy.penup()
enemy.speed(0)
enemy.setposition(400, -180)
or another one:
player = turtle.Turtle(shape="turtle.gif")
player.penup()
player.speed(0)
player.left(90)
player.setposition(-400, -200)
or:
border = turtle.Turtle()
border.speed(0)
border.color("white")
border.penup()
border.setposition(-300, -300)
border.pendown()
border.pensize(3)
border.hideturtle()
hope it helps!
turtle is the module that you import while Turtle is that name of the class. Using from turtle import * removes the need for turtle.Turtle.
turtle is the name of the package while Turtle is the name of the class.
An alternate way of importing the module would be:
import turtle.Turtle
Also, are you sure the last line is turtle.done() and not star.done()?
The first turtle is called turtle and is referenced by it's name or it in a variable, the turtle.Turtle method creates a new turtle and (most of the time), you set it to a variable.
turtle is a method which contains a class which is noble Turtle

Python turtle drawing updated for turtle.tracer(0,0)

I am a newbie using python 3.2.3
When I ran the module in the python IDLE, the turtle drew a square without any update on the screen, so the window appeared blank, and after I input any key, the turtle and the square appeared due to the call of turtle.update().
However, when I double-clicked the .py file storing the below code in my document and executed it directly, the square always showed up before I input any key.
The interesting part is that the turtle was not shown but only the square was shown.
It seems that there was a turtle update only for the square after drawing even if I had already set turtle tracer to (0,0).
Is this considered a bug and how can I solve it? Thanks for the help.
import turtle
def drawSquare():
turtle.down();
turtle.begin_fill();
turtle.goto(10, 0);
turtle.goto(10, 10);
turtle.goto(0, 10);
turtle.goto(0, 0);
turtle.end_fill();
turtle.up();
def tUpdate():
turtle.update();
turtle.tracer(0,0);
drawSquare();
input("Not updated. Press any key.");
tUpdate();
print("Updated");
turtle.mainloop();
You've got a couple of things working against you: the poor documenation provided for tracer() and the fact that end_fill() and up() cause updates to occur. tracer() is not really meant to hide things from the user until you're ready to display them -- it's a speed optimization so that the user doesn't have to see every drawing step in a complicated image. You don't have full control over when updates will occur.
Here's a rework of your example that displays the behaviour you want at the cost of it no longer being a filled square. I've swapped your input() trigger for a mouse click on the window instead but your approach will work just as well here too:
from turtle import Turtle, Screen
def drawSquare(turtle):
turtle.goto(100, 0)
turtle.goto(100, 100)
turtle.goto(0, 100)
turtle.goto(0, 0)
screen = Screen()
screen.tracer(0, 0)
screen.onclick(lambda x, y: screen.update())
turtle = Turtle()
drawSquare(turtle)
screen.mainloop()
I also made which are turtle methods, and which are screen methods, more explicit. The beginning programmer friendly design of the turtle library tends to blur these in the interest of ease of use.

Python - Move Two Turtle Objects At Once

I would like to create a program where one turtle object moves to where a user clicks their mouse, and a different turtle object moves at the same time. I have the first part, but I can't seem to get the rest to work.
Any help would be appreciated.
This is my code. (Credit for the first part of this goes to #Cygwinnian)
from turtle import *
turtle = Turtle()
screen = Screen()
screen.onscreenclick(turtle.goto)
turtle.getscreen()._root.mainloop()
turtle2 = Turtle()
while True:
turtle2.back(100)
turtle2.forward(200)
turtle2.back(100)
I am by no means an expert at Python's turtle module, but here's some code that I think does what you want. The second turtle will be moving back and forth any time the first turtle is not:
from turtle import *
screen = Screen() # create the screen
turtle = Turtle() # create the first turtle
screen.onscreenclick(turtle.goto) # set up the callback for moving the first turtle
turtle2 = Turtle() # create the second turtle
def move_second(): # the function to move the second turtle
turtle2.back(100)
turtle2.forward(200)
turtle2.back(100)
screen.ontimer(move_second) # which sets itself up to be called again
screen.ontimer(move_second) # set up the initial call to the callback
screen.mainloop() # start everything running
This code creates a function that moves the second turtle repeatedly back and forth from its starting position. It uses the ontimer method of the screen to schedule itself over and over. A slightly more clever version might check a variable to see if it is supposed to quit, but I didn't bother.
This does make both turtles move, but they don't actually move at the same time. Only one can be moving at any given moment. I'm not sure if there is any way of fixing that, other than perhaps splitting up the moves into smaller pieces (e.g. have the turtles alternate moving one pixel at a time). If you want fancier graphics you probably need to move on from the turtle module!

Categories

Resources