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])
Related
Something similar to the picture attached. I tried modifying the code I got online. But my code goes to infinity loop
[1]: https://i.stack.imgur.com/HfKog.png
def draw_circle(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
turtle.pendown() # pen down
times_y_crossed = 0
x_sign = 1.0
while times_y_crossed <= 1:
turtle.dot(5, "Red")
turtle.forward(5) # move by 1/360
turtle.right(1.0)
turtle.penup()
turtle.forward(5) # move by 1/360
turtle.right(1.0)
x_sign_new = math.copysign(1, turtle.xcor())
if x_sign_new != x_sign:
times_y_crossed += 10
x_sign = x_sign_new
turtle.up() # pen up
return
There are some issues with your code, like it does not count with the radius and the color for the pen was not set and as I've checked it did a half circle for me.
I show you a simple working example, first a dashed version because your original code looks like you wanted a dashed circle
import turtle
import math
def draw_circle_dashed(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
times_y_crossed = 0
dist=2*math.pi*radius/360
turtle.pencolor("red")
for _ in range(180):
turtle.pendown()
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.penup()
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.up() # pen up
return
draw_circle_dashed(200)
and a dotted variant as well because of the question title
import turtle
import math
def draw_circle_dotted(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
dist=2*math.pi*radius/360
for _ in range(360):
turtle.dot(2,"red")
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.up() # pen up
return
draw_circle_dotted(300)
We can use turtle's own circle() method to do this as we can arbitrarily start and stop it, leaving behind dots as we do:
from turtle import Screen, Turtle
from math import pi
DOT_DIAMETER = 5
def draw_circle(radius):
turtle.penup()
circumference = 2 * pi * radius
dot_extent = 360 * DOT_DIAMETER*2 / circumference # diameter to angle
extent = 0
while extent < 360:
turtle.dot(DOT_DIAMETER)
turtle.circle(radius, extent=dot_extent)
extent += dot_extent
screen = Screen()
turtle = Turtle()
turtle.color('red')
draw_circle(100)
turtle.hideturtle()
screen.exitonclick()
Using what we learned from that exercise, let's now fix your code. The issue I see is this:
turtle.right(1.0)
The angle to turn is dependent on the dot diameter, but we actually have to calculate it:
from turtle import Screen, Turtle
from math import pi, copysign
DOT_DIAMETER = 5
def draw_circle(radius):
turtle.penup()
turtle.sety(radius)
diameter = 2 * radius
circumference = pi * diameter
dot_extent = 360 * DOT_DIAMETER / circumference # diameter to angle
times_y_crossed = 0
x_sign = 1
while times_y_crossed < 2:
turtle.dot(DOT_DIAMETER, 'red') # draw the dot
turtle.right(dot_extent)
turtle.forward(DOT_DIAMETER)
turtle.right(dot_extent) # draw the gap
turtle.forward(DOT_DIAMETER)
x_sign_new = copysign(1, turtle.xcor())
if x_sign_new != x_sign:
times_y_crossed += 1
x_sign = x_sign_new
turtle.pendown()
screen = Screen()
turtle = Turtle()
turtle.color('red')
draw_circle(100)
turtle.hideturtle()
screen.exitonclick()
By not calculating the angle, and using a fixed angle of 1.0, you were off by a factor of two.
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()
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()
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")