The Great Pyramid

pyramid.py: 14 points


In the pyramid.py program, we will gain more practice with both for loops and drawing using the picture module by creating a large pyramid out of smaller square bricks.

The program should begin by asking the user for two integers: (1) the total width of the square image they would like to draw, and (2) how many rows of bricks should make up the pyramid within that image. Then, it should draw a pyramid consisting of small bricks where the top row has 1 brick, the second row from the top has 2 bricks, etc. until it has the number of rows that the user desired.

Algorithm

In order to draw the pyramid, consider the following algorithm.

  1. Create a new square image based on the total width chosen by the user. Go ahead and give the picture a background; you can choose whatever color you like.
  2. Calculate the size of each square brick (i.e., its height and width), based on the total width of the image and the number of rows of the pyramid. Every brick should have this same size.
  3. Starting with either the top or bottom row of the pyramid, draw a single row of square bricks that make up that row.
  4. Move on to the next row (below, if you start at the top or above if you started at the bottom) and draw each brick in that row.
  5. Continue until you have drawn all of the bricks in every row.

You might have noticed that steps 3-5 repeat the same general idea: draw a row of square bricks. We know exactly how many rows we need to draw, based on the user’s input, so we can implement steps 3-5 as an (outer) for loop, where the loop variable that changes value each iteration tells us which row we are currently drawing as the for loop runs.

For every row of the pyramid (i.e., for each iteration of that outer for loop), we will want to draw all of the bricks that exist on that row. Since there can be more than one brick in each row, this implies that we will have an inner for loop whose iterations are responsible for drawing different bricks in the current row. The number of bricks will change per row (1 in the top row, 2 in the second row from the top, etc.), so the number of iterations of the inner for loop (i.e., the number passed into the range() of the inner for loop) will change based on which row we are currently drawing (i.e., the loop variable of the outer loop).

ReadMe

To prevent the pyramid from leaning to the left, you will want to use float division to decide where the starting x-coordinate is for each row, then cast the resulting number as an integer using code like:

x = int(x)

If you use integer division, it might shift higher rows to the left, depending on the order you do the division (since integer division rounds down automatically, it can remove valuable information).

Once we have that structure, the last remaining details are to figure out where each brick should be drawn inside the inner for loop. All of the bricks in a row should be next to one another horizontally, which implies that they all share the same y-coordinate of their top-left corners. However, they all have different x-coordinates of their top-left corners. The Warmup should be helpful in thinking through how to calculate those coordinates.

Example Outputs

Here are three example outputs for your reference. Notice that the pyramid doesn’t necessarily fill the entire canvas to the right and to the top; if the canvas width is not evenly divisible by the number of bricks, then there will be extra blank space. That is okay!

400 x 400, 3 bricks

400 x 400, 17 bricks

400 x 400, 123 bricks

ReadMe

It might be helpful to think about testing your program as you are implementing it, instead of waiting until the entire program is done. For example, it is easier to test that your outer for loop is working by creating the correct number of rows before you create the inner for loop that draws each brick in each row. To test your outer for loop, you could simply draw a single brick in each row, all with x-coordinate set to 0 to make sure that you have the correct number of rows and the correct y-coordinates for the top of the bricks in each row. Once that is working, you could find the correct x-coordinate of the first brick in each row and draw the top-left edge of the pyramid. Finally, after that is debugged, you could implement the inner for loop to draw all of the remaining bricks per row.