Inside functions, I learned somewhere to work on copies of the arguments, for example: list_arg --> t = list_arg[:]. It made sense, so I try to do it consistently.
Now I am going again through the basics of programming, with the help of Think Python 2nd Edition by Allen B. Downey. In chapter 4 - Case study: interface design, I have to draw polygons with the help of the turtle module
import turtle
def mysquare(length, turtle_obj):
t = turtle_obj
t.pd()
for i in range(4):
t.fd(length)
t.lt(90)
t.pu()
def main():
bob = turtle.Turtle()
mysquare(100, bob)
turtle.mainloop()
if __name__ == "__main__":
main()
In this case, bob and t refer to the same turtle object. If I forget to make it hold the pen up t.pu() in the mysquare function, bob will (potentially) keep drawing in the main function.
As much as I would like to keep the programming style of writing functions that don't change their parameters, I don't know if it makes any sense in this situation.
Is there a general way, best practice to handle such a situation?
Conceptually, does my issue have to do with a particular programming paradigm (object-oriented, functional), or a language style (pythonic way)?
We can correct for the pen state on the way out using turtle's isdown() method:
import turtle
def mysquare(length, turtle_obj):
if was_up := not turtle_obj.isdown():
turtle_obj.pendown()
for _ in range(4):
turtle_obj.forward(length)
turtle_obj.left(90)
if was_up:
turtle_obj.penup()
turtle.penup()
mysquare(50, turtle)
turtle.goto(100, 100)
mysquare(25, turtle)
turtle.done()
The calls to mysquare() will return the pen state to what it was when the function was called. Assigning turtle_obj to t achieves nothing.
Related
I am very, and by that I mean very new to Python (i know literally nothing). I'm attemtping to create a little game using the turtle module, and following a tutorial I don't see the listen() function working
here's my code
I'm trying to create a controllable character
from turtle import *
#background
Screen().bgcolor("orange")
#player
pl = Turtle()
pl.color('dodgerblue')
pl.shape('turtle')
pl.penup()
def turnleft():
player.left(30)
turtle.listen()
onkeypress(turnleft, "Left")
speed = 1
while True:
pl.forward(speed)
When you do from turtle import * it imports everything into the built-in namespace, i.e., you can then just do:
listen()
rather than
turtle.listen()
If you had just done
import turtle
then everything in the turtle package would then be accessed through the turtle namespace, i.e.,
turtle.listen()
You have plenty of mistakes here, totally normal because you are so new, that's the way to get better.
I will ""arrange"" a bit your code.
import turtle
#background
turtle.Screen().bgcolor("orange")
#player
pl = turtle.Turtle()
pl.color('dodgerblue')
pl.shape('turtle')
pl.penup()
def turnleft():
pl.left(30)
turtle.listen()
turtle.onkeypress(turnleft, "Left")
speed = 1
while True:
pl.forward(speed)
First of all i recommend you to check in google what is "OOP" and check how it works on Python.
When you use "functions" from a module (in this case turtle) , you need to call first the module and after the function for example:
turtle.onkeypress(turnleft, "Left")
# Instead
onkeypress(turnleft,"Left")
Another thing it's in your function "turnleft" you call the variable "player", but "player" doesnt exist, you want to call "pl".
Good luck with your small new projects, keep trying.
I thought using Screen.tracer(0) disabled animation in Python Turtle Graphics. However in the following program, if you comment out screen.update(), there is still some animation happening - the turtle trail gets drawn although the turtle doesn't "move" (or get updated). What is happening here please? Is there way to make updating the screen completely manual?
import turtle
def move():
my_turtle.forward(1)
my_turtle.right(1)
screen.update() # Comment out this line to see issue.
screen.ontimer(move, 10)
screen = turtle.Screen()
my_turtle = turtle.Turtle()
my_turtle.shape("turtle")
screen.tracer(0)
move()
turtle.done()
No, screen.tracer(0) doesn't stop all animation. Some turtle commands like end_fill() invoke screen.update() directly, some like dot() invoke it due to other methods that they in turn invoke. You only advise the system when you call update(), not control it completely.
Put your update() calls where you believe you need them, and don't assume certain methods force an update, otherwise future updates of turtle might break your code. (I.e. someone might actually fix turtle.)
For potentially helpful details, see my tracer() rules of thumb and information about the first argument's numeric value
In turtle.py, forward() calls _go() which sets an endpoint, then calls _goto()
_goto() creates a newline if line segments get above 42
if len(self.currentLine) > 42: # 42! answer to the ultimate question
# of life, the universe and everything
self._newLine()
The value appears to be arbitrary; you could set it to something higher, but then there are pauses where nothing appears to be happening.
def _newLine(self, usePos=True):
"""Closes current line item and starts a new one.
Remark: if current line became too long, animation
performance (via _drawline) slowed down considerably.
"""
import turtle
class Polygon:
def __init__(self,sides,name,size=100,color='black',line_thickness=3):
self.sides=sides
self.name=name
self.size=size
self.color=color
self.line_thickness=line_thickness
self.interior_angles=(self.sides-2)*180
self.angle=self.interior_angles/self.sides
def draw(self):
turtle.color(self.color)
turtle.pensize(self.line_thickness)
for i in range(self.sides):
turtle.forward(self.size)
turtle.right(180-self.angle)
turtle.done()
square=Polygon(4,'Square')
square.draw()
Considering the code above, operating in VSCODE, I am wondering how to get rid of all the 'pylint' errors that continue to pop up which suggest something similar to the following:
Module 'turtle' has no 'color' member (pylint no-member)
Although the code executes just fine, it is unsettling to continue having to look at the error lines and I am wondering if there is a solution to this. Thanks for you time!
Rather than suppress the error message, why not fix the code? Turtle presents two APIs, a functional one and an object-oriented one. The functional one is derived from the object-oriented one at load time. Analysis tools can't look inside the source library file and see the functional signatures.
Since you're defining your own Polygon object, I don't see why you're not using the object-oriented interface to turtle. The import I use below blocks the functional interface and only allows access to the object-oriented one:
from turtle import Screen, Turtle
class Polygon:
def __init__(self, sides, name, size=100, color='black', line_thickness=3):
self.sides = sides
self.name = name
self.size = size
self.color = color
self.line_thickness = line_thickness
self.interior_angles = (self.sides - 2) * 180
self.angle = self.interior_angles / self.sides
def draw(self):
turtle.color(self.color)
turtle.pensize(self.line_thickness)
for _ in range(self.sides):
turtle.forward(self.size)
turtle.right(180 - self.angle)
screen = Screen()
turtle = Turtle()
square = Polygon(4, 'Square')
square.draw()
screen.exitonclick()
Note the subtle changes to the code to accommodate the object-oriented API. Now try your analysis of the code to see if this solves your problem.
I have found this code on this website, and I have a few questions about it. I have already made a Sierpinski triangle on Python using my rudimentary knowledge and it is way too long and very bad.
I've done it using functions and some variables, but I have some questions with this code I have found. First of all, what is the "T" constantly brought up, the length and depth, and where is this all given a value. Where is the length and depth specified, and what does it do to the code?
Please note I am a beginner.
Here is the code:
import turtle
def draw_sierpinski(length,depth):
if depth==0:
for i in range(0,3):
t.fd(length)
t.left(120)
else:
draw_sierpinski(length/2,depth-1)
t.fd(length/2)
draw_sierpinski(length/2,depth-1)
t.bk(length/2)
t.left(60)
t.fd(length/2)
t.right(60)
draw_sierpinski(length/2,depth-1)
t.left(60)
t.bk(length/2)
t.right(60)
window = turtle.Screen()
t = turtle.Turtle()
draw_sierpinski(100,2)
window.exitonclick()
t = turtle.Turtle()
t is an instance of the class Turtle located in the module turtle that is previously imported
import turtle
As the instance t is in the global scope the python interpreter is able to find it, even within the function draw_sierpinski(length,depth)
I have no idea where you obtained the code however here are the docs for the turtle module.
To find out what the code does try it by yourself. Just pip install turtle and run the code
From the turtle docs
Turtle graphics is a popular way for introducing programming to kids.
It was part of the original Logo programming language developed by
Wally Feurzig and Seymour Papert in 1966. Imagine a robotic turtle
starting at (0, 0) in the x-y plane. After an import turtle, give it
the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
the direction it is facing, drawing a line as it moves. Give it the
command turtle.right(25), and it rotates in-place 25 degrees
clockwise.
This is my first time ever using turtle, so bear with me. I am suppose to make a tree diagram in python using turtle. I made the tree and it looks perfect except for one problem, which might seem really simple but, when I print out my tree it looks like this.
So what would I add to make my tree right side up? Here is my code. Thanks in advance!
import turtle
t = turtle.Turtle()
def tree(length = 100):
if length < 10:
return
t.forward(length)
t.left(30)
tree(length *.7)
t.right(60)
tree(length * .7)
t.left(30)
t.backward(length)
return
tree()
turtle.done()
You must remember that the function is recursive, thus you need to turn the turtle outside of the function. You can use a function in a function, but I would just turn the turtle in the global scope right before you call the function:
t.left(90) # then call tree after with tree()