If you run the following code, it creates two side by side drawings of what I am attempting to create. I need to figure out how to make the recursive method stop after drawing it the first time.
import turtle
def drawTriangle(size):
turtle.left(30)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(120)
turtle.up()
turtle.forward(size)
turtle.right(30)
turtle.down()
def drawTriangles(size, depth):
if (depth < 1):
pass
else:
drawTriangle(size)
drawTriangles(size / 2, depth - 1)
turtle.up()
turtle.left(30)
turtle.forward(-size)
turtle.right(120)
turtle.forward(size * 2)
turtle.left(90)
turtle.down()
drawTriangle(size)
drawTriangles(size / 2, depth - 1)
turtle.up()
turtle.left(30)
turtle.forward(-size)
turtle.left(60)
turtle.forward(size * 2)
turtle.right(90)
turtle.down()
turtle.home()
turtle.left(90)
turtle.down()
turtle.speed("normal")
drawTriangles(100, 4)
input("pause")
First of all nice try. You were really close dude. And this seems like a fun project. :)
I've fixed your code and included it below. All you needed to do was add a special condition to check if you are on the "base" triangle or not. If so, return!
import turtle
def drawTriangle(size):
turtle.left(30)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(120)
turtle.up()
turtle.forward(size)
turtle.right(30)
turtle.down()
def drawTriangles(size, depth, baseTriangle = False):
if (depth < 1):
pass
else:
drawTriangle(size)
drawTriangles(size / 2, depth - 1)
if baseTriangle:
return
turtle.up()
turtle.left(30)
turtle.forward(-size)
turtle.right(120)
turtle.forward(size * 2)
turtle.left(90)
turtle.down()
drawTriangle(size)
drawTriangles(size / 2, depth - 1)
turtle.up()
turtle.left(30)
turtle.forward(-size)
turtle.left(60)
turtle.forward(size * 2)
turtle.right(90)
turtle.down()
turtle.home()
turtle.left(90)
turtle.down()
turtle.speed("normal")
drawTriangles(100, 4, baseTriangle = True)
input("pause")
If I were to guess, it is probably because you are calling the following twice (in drawTriangles()) and the value of the size variable does not change between these two calls.
drawTriangle(size)
drawTriangles(size / 2, depth - 1)
Here's my solution. I've tidied up some of the logic so, if the depth is not zero, the triangle gets drawn and the recursion is triggered twice, once for each top corner of the drawn triangle. Finally, the turtle is moved back to where it started.
The turtle is 'up' normally and is only put 'down' in the drawTriangle function. The drawTriangle function also now returns the turtle back to where it started.
Watch out for integer division. I've cast the size to a float before doing anything else.
import turtle
def drawTriangle(size):
turtle.down()
turtle.left(30)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(120)
turtle.forward(size)
turtle.right(150)
turtle.up()
def drawTriangles(size, depth):
size = float(size)
if (depth > 0):
drawTriangle(size)
turtle.left(30)
turtle.forward(size)
turtle.right(30)
drawTriangles(size / 2, depth - 1)
turtle.right(90)
turtle.forward(size)
turtle.left(90)
drawTriangles(size / 2, depth - 1)
turtle.left(150)
turtle.forward(size)
turtle.right(150)
turtle.home()
turtle.left(90)
turtle.speed("normal")
drawTriangles(150.0, 5)
input("pause")
Related
Not originally my code:
import turtle
wn = turtle.Screen()
wn.bgcolor('Black')
wn.setup( width = 250, height = 250)
turtle = turtle.Turtle()
def snowflake (size, pensize, x, y):
""" function that draws a snowflake """
turtle.speed(100)
turtle.penup()
turtle.goto(x, y)
turtle.forward(10*size)
turtle.left(45)
turtle.pendown()
turtle.color('white')
for x in range (8):
branch(size)
turtle.left(45)
def branch (size):
for z in range (3):
for z in range (3):
turtle.forward(10.0*size/3)
turtle.backward(10.0*size/3)
turtle.right(45)
turtle.left(90)
turtle.backward(10.0*size/3)
turtle.left(45)
turtle.right(90)
turtle.forward(10.0*size)
snowflake(8, 6, 0, 0)
wn.exitonclick()
If it's not originally your code, your should provide proper blame, I mean credit for it. The issue with this code is that the base angle 45 is being used to generate the 8-sided snowflake as well as the angle of the small branches. So when we go to use 60 for a 6-sided snowflake, it's hard to know which 45's (or 90's) to replace and which to keep. The author of the original code didn't help any by starting the branch logic in the snowflake() function, before calling the branch() function. So let's tease out the two different uses of 45 degrees, make the code more explicit, and switch just the sides to 60 degrees:
from turtle import Screen, Turtle
SIDES = 6
BRANCH_ANGLE = 45
def snowflake(size, x, y):
""" function that draws a snowflake """
turtle.penup()
turtle.goto(x, y)
turtle.forward(size)
turtle.left(BRANCH_ANGLE)
turtle.pendown()
for _ in range(SIDES):
branch(size)
turtle.left(BRANCH_ANGLE)
def branch(size):
for _ in range(3):
for _ in range(3):
turtle.forward(size / 3)
turtle.backward(size / 3)
turtle.right(BRANCH_ANGLE)
turtle.left(2 * BRANCH_ANGLE)
turtle.backward(size / 3)
turtle.left(BRANCH_ANGLE)
turtle.right(BRANCH_ANGLE + 360 / SIDES)
turtle.forward(size)
screen = Screen()
screen.bgcolor('black')
screen.setup(width=250, height=250)
turtle = Turtle()
turtle.color('white')
turtle.speed('fastest')
snowflake(80, 0, 0)
turtle.hideturtle()
screen.exitonclick()
I am working on a final project for python for my intro to python class. I have written code for each of the letters in the alphabet, my idea is to have the user input some words, and return code for all of the input letters. I have tried using a = code for turtle but this does not work. Any Ideas?
x = input()
codes = {'a': 'code for turtle',.....}
print(codes[str(x)])
Would a dictionary with an input() work?
Let's expand (and correct) #GerardAnthonyMcBride's dictionary-based approach. Here's an overly simplified example that just prints the letters 'S' and 'O':
from turtle import Turtle, Screen
SIZE = 100
def draw_O(turtle):
turtle.pendown()
for _ in range(4):
turtle.forward(SIZE)
turtle.left(90)
turtle.penup()
def draw_S(turtle):
position = turtle.position()
turtle.pendown()
turtle.forward(SIZE)
turtle.left(90)
turtle.forward(SIZE / 2)
turtle.left(90)
turtle.forward(SIZE)
turtle.right(90)
turtle.forward(SIZE / 2)
turtle.right(90)
turtle.forward(SIZE)
# leave turtle as we found it
turtle.penup()
turtle.setposition(position)
characters = {
'O': draw_O,
'S': draw_S,
}
screen = Screen()
yertle = Turtle()
string = input()
for character in string:
if character in characters:
characters[character](yertle)
yertle.forward(SIZE * 1.25)
screen.exitonclick()
OUTPUT
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to draw the American flag in python with turtles and ended up getting lost in my code and not find my error. I also can't figure out how to color my flag... what i thought would work isn't... and I did something and now my code crashes about half way through ... please help me I am new to programming...
Here's my code so far.
import turtle
import time
import random
def draw_rectangle(length, height):
turtle.up()
x = -150
y = 150
C = height*(7/13)
D = length*(2/5)
L = stripe_width = float(round(height/13,1))
## Draw rectangle first.
turtle.begin_fill()
turtle.setpos(x,y)
turtle.down()
turtle.forward(length)
turtle.right(90)
turtle.forward(height)
turtle.right(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(height)
turtle.end_fill()
## Then draw the stripes.
x1 = -150
y1 = 150-L
for z in range(13):
if z%2 == 0:
r = s = t = 0
else:
r = s = t = 1
turtle.up()
turtle.speed(100)
turtle.setpos(x1,y1)
turtle.setheading(90)
turtle.down()
turtle.color(r,s,t)
turtle.begin_fill()
turtle.forward(L)
turtle.right(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(L)
turtle.right(90)
turtle.forward(length)
turtle.end_fill()
y1 -= L
## Finally draw the stars rectangle overlapping the stripes, next is stars.
x2 = -150 + D
y2 = 150.5 - C
turtle.up()
turtle.setpos(x2,y2)
turtle.down()
turtle.color('yellow')
turtle.begin_fill()
turtle.forward(D)
turtle.right(90)
turtle.forward(C)
turtle.right(90)
turtle.forward(D)
turtle.right(90)
turtle.forward(C)
turtle.end_fill()
turtle.up()
def draw_star(l, h):
for z in range(50):
if z < 7:
row = 140
draw_starrows(row)
if z < 14:
row = row - 20
draw_starrows(row)
if z < 21:
row = row - 20
draw_starrows(row)
if z < 28:
row = row - 20
draw_starrows(row)
if z < 35:
row = row - 20
draw_starrows(row)
## This gets the turtle pen out of the way at the very end.
turtle.up()
turtle.setpos(-180,100)
break
def draw_starrows(row):
x = -160
y = 150
for z in range(10):
x += 15
turtle.up()
turtle.color(1,1,1)
turtle.speed(100)
turtle.setpos(x,row)
turtle.begin_fill()
turtle.down()
turtle.forward(6.154)
turtle.left(144)
turtle.forward(6.154)
turtle.left(144)
turtle.forward(6.154)
turtle.left(144)
turtle.forward(6.154)
turtle.left(144)
turtle.forward(6.154)
turtle.left(144)
turtle.end_fill()
#turtle.bye # closes turtle window
def get_color(color2):
## If color2 equals 1, then make the color white.
if color2 == 1:
r = g = b = 1
return (r, g, b)
## If color2 equals 0, then make the color red.
if color2 == 0:
r = 1
g = 0
b = 0
return (r, g, b)
## If color2 equals 2, then make the color black.
if color2 == 2:
r = 0
g = 0
b = 1
return (r, g, b)
def draw_flag():
A = 200
height = int(A)
## length = height*1.9
## C = height*(7/13)
## D = length*(2/5)
## E = F = union_height/10
## G = H = union_length/12
## stripe_width = height/13
## diameter_star = stripe_width*(4/5)
draw_rectangle(height*1.9, height)
draw_flag()
I believe you have all the key components. You primarily need to think relative to the size and starting position, rather than hard coding values, and keep things simple. (e.g. color("blue") instead of color(r, s, t) until you get things working.) And take a good look at the star arrangement on the flag.
I've reworked your code along the lines of my comments above and made some style changes:
import turtle
X_POSITION, Y_POSITION = -150, 150
def draw_rectangle(length, height):
turtle.up()
C = height * (7 / 13.0)
D = length * (2 / 5.0)
L = height * (1 / 13.0)
## Draw rectangle first.
turtle.setpos(X_POSITION, Y_POSITION)
turtle.down()
turtle.forward(length)
turtle.right(90)
turtle.forward(height)
turtle.right(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(height)
## Then draw the red stripes.
x, y = X_POSITION, Y_POSITION - L
turtle.color("red")
for z in range(0, 13, 2):
turtle.up()
turtle.setpos(x, y)
turtle.setheading(90)
turtle.down()
turtle.begin_fill()
turtle.forward(L)
turtle.right(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(L)
turtle.right(90)
turtle.forward(length)
turtle.end_fill()
y -= 2 * L
## Draw the stars rectangle overlapping the stripes
turtle.up()
turtle.color('blue')
turtle.setpos(X_POSITION + D, Y_POSITION - C)
turtle.down()
turtle.begin_fill()
turtle.forward(D)
turtle.right(90)
turtle.forward(C)
turtle.right(90)
turtle.forward(D)
turtle.right(90)
turtle.forward(C)
turtle.end_fill()
## next is stars
turtle.up()
draw_stars(D, C)
turtle.up()
## This gets the turtle pen out of the way at the very end.
turtle.hideturtle()
def draw_stars(length, height):
row = height // 9
row_offset = row / 2.0
column = length // 6
column_offset = column / 2.0
y_position = row_offset
for z in range(9):
if z % 2 == 0:
draw_starrows(6, column_offset, y_position, column)
else:
draw_starrows(5, column, y_position, column)
y_position += row
def draw_starrows(star_count, x_offset, y_offset, spacing):
x, y = X_POSITION, Y_POSITION
turtle.color("white")
for z in range(star_count):
turtle.up()
turtle.setpos(x + x_offset, y - y_offset)
turtle.begin_fill()
turtle.down()
for _ in range(5):
turtle.forward(6.154)
turtle.left(144)
turtle.end_fill()
x += spacing
def draw_flag(height):
turtle.speed("fastest")
draw_rectangle(height * 1.9, height)
draw_flag(200)
turtle.done()
Although the scaling basically works now (try draw_flag(100)) the stars themselves (on which you did an excellent job, BTW) are still fixed size so you'll need to go back and scale them to match the rest of the flag:
I have written this Python code with turtle graphics for drawing a chessboard by given dimension. The problem I'm facing is when I enter an odd number everything works just fine:
The last square is also filled, I just didn't manage to screen shot it on time
But when I enter an even number, it's like:
Here's the code:
from turtle import *
import sys
def main():
dimension = int(input('Enter dimension: '))
side = 50
x_coord = -250
y_coord = 300
turtle = Turtle()
turtle.speed('fastest')
turtle.pensize(5)
for i in range(dimension ** 2):
if not i % dimension:
y_coord -= side
turtle.penup()
turtle.setx(x_coord)
turtle.sety(y_coord)
turtle.pendown()
if not i % 2:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
turtle.forward(side)
turtle.end_fill()
if __name__ == '__main__':
sys.exit(main())
A similar flag-based solution with alternate approaches. I don't understand what your main() layout gets you so I reworked it to be a potential library with the test code under __main__:
import turtle
def draw_board(dimension, x_coord, y_coord, side):
parity = False
for i in range(dimension ** 2):
if i % dimension == 0:
y_coord -= side
turtle.penup()
turtle.setpos(x_coord, y_coord)
turtle.pendown()
parity = parity != (dimension % 2 == 0) # logical XOR
if parity:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
if turtle.filling():
turtle.end_fill()
turtle.forward(side)
parity = not parity
if __name__ == '__main__':
size = int(input('Enter dimension: '))
turtle.speed('fastest')
turtle.pensize(5)
draw_board(size, -250, 300, 50)
turtle.hideturtle()
turtle.exitonclick()
I didnt look through your code, but it seems that the problem you have is that unlike a true chessboard, you change from white to black and vice versa when making a new line of squares, this example:
black,white,black,white
black,white,black,white
etc.
or black,white,black
white,black,white
etc.
while a chessboard is:
black,white,black,white
WHITE,black,white,black
BLACK....etc.
you see the difference?
so that seems to be the problem, il try to fix your code aswell, but i think you could manage that
I suggest setting a flag for when to fill instead of doing it only when it's an odd number from the range which is what trips you up since it doesn't go black white left to right, it reaches then end an then goes right to left.
Anyway, here is my edit, just a simple boolean which toggles each time except when going to new row. I also suggest using turtle.exitonclick instead of sys.exit
from turtle import *
def main():
dimension = int(input('Enter dimension: '))
side = 50
x_coord = -250
y_coord = 300
turtle = Turtle()
turtle.speed('fastest')
turtle.pensize(5)
fill = False
for i in range(dimension ** 2):
if not i % dimension:
y_coord -= side
turtle.penup()
turtle.setx(x_coord)
turtle.sety(y_coord)
turtle.pendown()
if not dimension % 2:
fill = not fill
if fill:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
turtle.forward(side)
turtle.end_fill()
fill = not fill
if __name__ == '__main__':
main()
exitonclick()
For Python 3,7 I would recommend this way
import turtle
turtle.speed(0)
turtle.up()
turtle.goto(-200,200)
turtle.down()
for row in range(8):
for col in range(8):
if col % 2 == row % 2:
turtle.forward(50)
continue
turtle.begin_fill()
for _ in range(4):
turtle.forward(50)
turtle.right(90)
turtle.end_fill()
turtle.forward(50)
turtle.backward(400)
turtle.right(90)
turtle.forward(50)
turtle.left(90)
turtle.width(6)
for _ in range(4):
turtle.forward(400)
turtle.left(90)
turtle.hideturtle()
turtle.done()
The function is supposed to loop, each time decreasing the size of the circle by 10 and drawing a new circle, until the size is less than or equal to 0. What am i missing
def circle(x):
turtle.up()
turtle.goto(0,0)
turtle.down()
turtle.color("blue")
turtle.circle(x)
if x>0:
turtle.up()
turtle.goto(0,0)
turtle.down()
turtle.color("blue")
turtle.circle(x-10)
else:
turtle.up()
turtle.goto(0,0)
turtle.down()
turtle.color("blue")
turtle.circle(x)
print(circle(80))
Here is a working version. Added recursion circle(x-10), removed redundant code, added turtle.done() to stop the app from crashing.
import turtle
def circle(x):
turtle.up()
turtle.goto(0,0)
turtle.down()
turtle.color("blue")
turtle.circle(x)
if x>0:
circle(x-10)
circle(80)
turtle.done()
Version with explicit loop:
import turtle
def circle(x):
while x > 0:
turtle.up()
turtle.goto(0,0)
turtle.down()
turtle.color("blue")
turtle.circle(x)
x -= 10;
circle(80)
turtle.done()
def ring_draw(dia,x0,y0):
to_return=[]
rad = dia / 2
for x in xrange(x0+(rad+2)):
for y in xrange(y0+(rad+2)):
z0 = abs(x - x0)
z1 = abs(y - y0)
z2 = z0**2 + z1**2
if rad**2 >= z2:
to_return.append([x,y])