Chris Chris - 2 months ago 22
Python Question

Where is my bug/glitch?

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()

Answer

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()

enter image description here

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:

enter image description here