First of all lets break down the pyramid into rows and record the row number. We're going to need a 'for' loop to go through each row to print the circles in it, and then for each row we can increase the y coordinate by 50, since the circles on row n + 1 are 50 pixels below the circles on row n.

``````
def draw_shapes(a_canvas, start_x, start_y, number_of_rows):
size = 50
for row in range(number_of_rows): # for each row
# do something
start_y += size
``````

Now lets figure out where to start printing the circles, AKA the start_x for each row. To do this lets first get the starting X position on each row in terms of the size, i.e. how many 'invisible' circles there are until the first actual circle. Notice the pattern here, there's a relationship between the starting x position and the row number.
The pattern seems to be 5 - the row number, but why 5?
5 Happens to be the highest row number we're printing (since we start at  0), so instead of 5 - row we can just say number_of_rows - 1 - row
Since this position is in terms of size, the equation can be written as size * (number_of_rows - 1 - row)
And since the starting position for every row is relative to the inital start_x, it can be finalised as:
x = start_x + (number_of_rows - 1 - row)

``````
def draw_shapes(a_canvas, start_x, start_y, number_of_rows):
size = 50
for row in range(number_of_rows): # for each row
x = start_x + (number_of_rows - row - 1) * size # get starting x
# printing the pyramid
start_y += size
``````

Now moving onto printing the pyramid itself.
This task will be a bit simpler, we just need to get the number of circles to print and then make a loop to print them, they will all have the same y position, and the x position of each one is just 50 pixels above the previous.

``````
def draw_shapes(a_canvas, start_x, start_y, number_of_rows):
size = 50
for row in range(number_of_rows): # for each row
x = start_x + (number_of_rows - row - 1) * size # get starting x

for i in range(n): # do this n times
a_canvas.create_oval(x, start_y, x + size, start_y + size, fill='blue') # print the circle
x += size # add 50
start_y += size
``````

To get the number of circles to print (n), lets take a look back at the diagram. There's a clear correlation between row and number of circles, being n = 2 * row + 1
So now just plug this equation back into the range.

``````
def draw_shapes(a_canvas, start_x, start_y, number_of_rows):
size = 50
for row in range(number_of_rows): # for each row
x = start_x + (number_of_rows - row - 1) * size # get starting x

for i in range(2 * row + 1): # for each circle on the row
a_canvas.create_oval(x, start_y, x + size, start_y + size, fill='blue') # print the circle
x += size # add 50
start_y += size
``````

If you have trouble finding the right formulas, such as the n = 2 * row + 1 or start_xrow = 5 - row, try making a table and using y = mx + c to come up with them.

Back to 101 Index