In Post #41, we learned the theory behind nested loops and saw how the inner loop completes its full cycle for each iteration of the outer loop. While generating combinations is useful, one of the best ways to truly understand this flow is to create something visual.
In this fun, hands-on post, we will use nested for
loops to draw simple patterns like squares and triangles in the console using characters. This is a classic programming exercise that solidifies the concept of nested iteration.
A Key Tool: The end
Parameter in print()
Before we start, we need to learn a small trick for the print()
function. By default, print()
automatically moves the cursor to a new line after it’s done printing. To draw shapes, we need to print multiple characters on the same line.
We can control this behavior by using the end
parameter. If we write print('*', end='')
, we are telling Python to print a star, but to end the line with an empty string instead of a newline character.
# Without the 'end' parameter
print("Hello")
print("World")
# With the 'end' parameter
print("Hello", end="")
print("World")
The output will be:
Hello
World
HelloWorld
To manually start a new line when we need one, we can simply call print()
with no arguments: print()
. We will use this combination to build our shapes.
Pattern 1: Drawing a Square
A square is a simple grid of rows and columns. We can think of the outer loop as controlling the rows (the vertical dimension) and the inner loop as controlling the columns (the horizontal dimension).
size = 5
# The outer loop handles the rows
for row in range(size):
# The inner loop handles the columns for the current row
for col in range(size):
# Print a star, but stay on the same line
print("* ", end="")
# After the inner loop finishes, move to the next line
print()
Here’s the logic:
- The outer loop starts the first row (row 0).
- The inner loop runs 5 times, printing
*
*
*
*
*
all on the same line. - After the inner loop finishes, the blank
print()
is called, moving the cursor to the next line. - The outer loop begins its second iteration (row 1), and the process repeats.
The output is a perfect 5×5 square:
* * * * *
* * * * *
* * * * *
* * * * *
* * * * *
Pattern 2: Drawing a Right-Angled Triangle
For a triangle, the number of columns (stars) in each row changes. Specifically, row 0 has 1 star, row 1 has 2 stars, row 2 has 3 stars, and so on. This means the number of times our inner loop runs must depend on the current iteration of our outer loop.
Instead of range(size)
, our inner loop will run range(row + 1)
times.
size = 5
for row in range(size):
# The inner loop's range depends on the current row number
for col in range(row + 1):
print("* ", end="")
# Move to the next line after the row is complete
print()
Let’s trace the first few iterations:
- When
row
is 0: The inner loop becomesfor col in range(1)
, so it runs once and prints one star. - When
row
is 1: The inner loop becomesfor col in range(2)
, so it runs twice and prints two stars. - When
row
is 2: The inner loop becomesfor col in range(3)
, so it runs three times and prints three stars.
This continues, producing the following triangle:
*
* *
* * *
* * * *
* * * * *
What’s Next?
This visual exercise is a powerful way to cement your understanding of nested loops. By controlling how many times the inner loop runs based on the outer loop’s state, you can create complex patterns and solve a wide range of problems.
Try to create other patterns! What if you wanted an inverted triangle? What about a hollow square? Experimenting is the best way to learn.
As our programs get more complex with nested logic and loops, the chances of making a mistake increase. What do you do when your code doesn’t work as expected? Figuring out why is a skill in itself called debugging. In Post #43, we will introduce the first and most fundamental technique for debugging your code.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com