Search code examples
pythonturtle-graphicspython-turtle

Drawing went well except for the last row due to a possible logic error


So I want to draw stacked rows of circles in symmetry. Please bear with me for a second because the code is pretty long.

# DRAWING THE DIAGRAM
pen = turtle.Turtle() # use turtle pen
pen.speed(-1) # speed of pen
pen.hideturtle() # hide the turtle
radius = 10 # radius of the symmetrical tubes
big_radius = 1.10*radius*max(columns) # radius of the shell of the heat exchanger wrt number of max columns
pen.circle(big_radius) # draw the shell
increment = 10
pen.pu()
#  CALCULATE MOST TUBES FIRST AKA MAX COLUMNS (ALSO TELLS US WHICH ROW IT IS)
for i in range(int(max(columns)/2)): # cross section is symmetrical hence columns/2 (drawing on the positive x-axis)
    pen.goto(increment, big_radius-radius)
    pen.pd()
    pen.circle(radius)
    pen.pu()
    pen.forward(radius*2)
    increment += 20

pen.pu()
radius *= -1 # this is to achieve symmetry on the negative axis
increment = -10
for i in range(int(max(columns)/2)): # as above, but now drawing on negative x-axis to maintain symmetry
    pen.goto(increment, big_radius - radius)
    pen.pd()
    pen.circle(radius)
    pen.pu()
    pen.forward(radius * 2)
    pen.pd()
    increment -= 20
pen.pu()

radius *= -1 # initialize to positive axis
increment = 10 # initialize to positive axis

middle_row = max(dict, key=dict.get)
# 1st row after the middle row (+ve y-axis, x-axis)
for i in range(1,2):
    pen.goto(increment,(big_radius + radius))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.forward(radius * 2)
        increment +=20

**# subsequent rows after the first row (+ve x-axis) [MAIN CULPRIT]
for i in range(2,middle_row):
    increment = 10
    pen.goto(increment,big_radius + i*(radius+5))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.forward(radius * 2)
        increment += 20**

# for 1st row after middle row (-ve x-axis)
for i in range(1,2):
    increment = -10
    pen.goto(increment,(big_radius + radius))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.backward(radius * 2)
        increment -= 20

**# subsequent rows after the first row (-ve x-axis) [MAIN CULPRIT]
for i in range(2,middle_row):
    increment = -10
    pen.goto(increment,big_radius + i*(radius+5))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.backward(radius * 2)
        increment -= 20**

radius *= -1 # initialize to negative y-axis

# 1st row after the middle row (-ve y-axis, -ve x-axis)
for i in range(1,2):
    increment = -10
    pen.goto(increment,(big_radius + radius))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.forward(radius * 2)
        increment += 20

# subsequent rows after the first row (-ve x-axis)
for i in range(2,middle_row):
    increment = -10
    pen.goto(increment,big_radius + i*(radius-5))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.forward(radius * 2)
        increment -= 20

# 1st row after the middle row (+ve x-axis)
for i in range(1,2):
    increment = 10
    pen.goto(increment,(big_radius + radius))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.backward(radius * 2)
        increment += 20

**# subsequent rows after the first row (+ve x-axis) [MAIN CULPRIT]
for i in range(2,middle_row):
    increment = 10
    pen.goto(increment,big_radius + i*(radius-5))
    for j in range(int(dict[middle_row-i]/2)):
        pen.pd()
        pen.circle(radius)
        pen.pu()
        pen.backward(radius * 2)
        increment += 20**

I highlighted the code that probably contributed to this effect with [MAIN CULPRIT]. Everything worked except for the final top and bottom rows and I can't seem to figure out the issue other than a logic error in my code.

Image of said figure


Solution

  • It seems to me this code would be easier to debug if we reduced your 18 for loops to just 2:

    from turtle import Screen, Pen
    
    dictionary = {2: 2, 3: 4, 4: 6, 5: 8}  # mapping of row # -> row width
    columns = dictionary.values()
    
    RADIUS = 10 # RADIUS of the symmetrical tubes
    BIG_RADIUS = 1.10 * RADIUS * max(columns)
    
    screen = Screen()
    
    pen = Pen()
    pen.hideturtle()
    pen.speed('fastest')
    
    pen.penup()
    pen.sety(-BIG_RADIUS)
    pen.pendown()
    pen.circle(BIG_RADIUS)
    pen.penup()
    
    max_rows = max(dictionary)
    pen.sety(max_rows * RADIUS)
    
    for row in range(2, 2 * max_rows - 1):
        columns = dictionary[row if row < max_rows else 2 * max_rows - row]
    
        pen.setx(-RADIUS * (columns - 1))
    
        for _ in range(columns):
            pen.pendown()
            pen.circle(RADIUS)
            pen.penup()
            pen.setx(pen.xcor() + RADIUS*2)
    
        pen.sety(pen.ycor() - RADIUS*2)
    
    screen.exitonclick()
    

    enter image description here

    You didn't supply dict so I had to guess -- adjust as needed. I changed the code to keep the image centered on the window to simplify the math. A couple of programming notes:

     pen.speed(-1)
    

    That's not a valid argument value for speed(). Also, don't (re)use the names of built-in types for your variables:

     dict[middle_row-i]
    

    Use something else other than dict in this case.