How to Draw Diamond Shape ASCII Art in Python?

A common python programming problem given for beginners is to draw a diamond shape using star character as an ASCII art. For example, the following shows a diamond shape as ASCII art consisting of 9 rows,

    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *

Here is another diamond with 5 rows.

  *
 ***
*****
 ***
  *

From the pattern it can be seen that the smallest diamond is of 3 rows and symmetric diamonds of this shape will have odd number of rows. For example, you can draw diamonds with 3, 5, 7, 9, 11 etc. rows.

Looking at the diamond we can see that it is composed of varying numbers of "stars" and spaces. The number of stars increase and spaces decrease starting from the top and then from the middle row onwards the number of stars decrease and spaces increase.

Now let us try to write a python program which will print a diamond given the odd number of rows required in it. Writing this in python requires us to logically think about the solution and then use python programming structures such as loops to generate the ASCII diamond shape.

For a diamond of size n, the middle row number is (n+1)/2. For example, for a diamond size of 5, the middle row is the (5+1)/2 = 3rd row. We will split the problem by first printing half the diamond up to the middle row and then printing the bottom portion of the diamond separately.

The python for ASCII diamond generation is given below,

# Number of rows needed in the diamond drawn
# This needs to be an odd number
diamond_size = 15

# We find the middle row index
# For 5 row diamond, it is (5+1)/2 = 3
# Note the use of integer divison in python using //
middle_row_index = (diamond_size+1)//2

# We also note that the number of spaces needed in the first and last row
# is also related to the diamond_size. For first row it is middle_row_index - 1.
max_spaces_needed = (diamond_size+1)//2 - 1

# First let us draw till middle row (upper diamond)
# Note that python range excludes the upper limit.
for row in range(0,middle_row_index):
    # Each row has decreasing number of spaces
    spaces_before_star = max_spaces_needed - row
    # We use python for string multiplication
    # "*"*3 prints 3 stars.
    # Alternatively you can use for loop
    print(" "*spaces_before_star,end="")
    # Each successive row has odd number of stars
    print("*"*(row*2+1))

# Now draw below the middle row (lower diamond)
# Note that we have one row less to print
for row in range(0,middle_row_index-1):
    # number of space before successive row is 1,2,3..
    spaces_before_star =  row+1
    print(" "*spaces_before_star,end="")
    # number of stars in each row reduces
    print("*"*(max_spaces_needed*2 - (row*2+1)))

We draw the diamond in two separate steps. In the first step we draw the upper diamond up to the middle row. For drawing this we first find how many spaces we need to draw and then how many stars we need to draw. This is repeated until the middle row.

We notice that the number of stars in each row is (row_number*2)-1. We also note that the number of spaces before the star in any row = ((middle row star count+1)/2 - number of stars in the row).

For the second half of the diamond we repeat the same process. However, there is a difference in calculation of the number of spaces and stars since spaces increase and star numbers decrease in the bottom section of the diamond. Please refer to the comments provided in the python code above for more details of the solution.