← All coding practice

Coding Practice · Beginner · October 25, 2026 · 4 min read

Python Coding Exercise #58: A Line and a Rectangle of Hashes

Part of the series Python Practice Exercise — part 58

Before you start: Know input() and int() · Know string multiplication · Know while loops with a condition

These two exercises go together, because the second one is the first program with a loop added. I put them in one post.

The question

A line of hashes

Please write a program which prints out a line of hash characters, the width of which is chosen by the user.

Width: 3
###
Width: 8
########

A rectangle of hashes

Please modify the previous program so that it also asks for the height, and prints out a rectangle of hash characters accordingly.

Width: 10
Height: 3
##########
##########
##########

A line of hashes

Solution

My Solution and the University Solution are the same for this exercise:

width = int(input("Width: "))
print("#" * width)

How the solution works

  • width = int(input("Width: ")) asks for the width and converts it to an integer, because the width is a number.
  • "#" * width repeats the string # as many times as width says, and joins the copies together. For a width of 3, the result is ###. (This is the string multiplication from Exercise #54.)
  • print() shows the line.

There is no loop in this program. A single * makes the whole line.

A rectangle of hashes

Before coding: a rectangle is a line, repeated

A rectangle is the same line printed several times, one below the other. The width decides how long each line is, and the height decides how many lines there are. So the program already has the line from the first exercise, and the only new thing is to repeat the print() as many times as the height.

That is a job for a loop. The second input, the height, says how many rounds the loop should run.

My Solution

width = int(input("Width: "))
height = int(input("Height: "))
for i in range(height):
    print("#" * width)

How My Solution Works

  • Two inputs: width and height are both converted to integers.
  • A for loop with range(height): range(height) produces the numbers from 0 up to, but not including, height. For a height of 3, those are 0, 1 and 2. A for loop takes one number from range(height) in each round, so it runs exactly 3 times.
  • The variable i: it holds the current number from the range, but the program never uses it. The loop is only a way to repeat the line height times.
  • The loop body: print("#" * width) prints one line of hashes in each round.
RoundiPython prints
10##########
21##########
32##########

After the third round, the range has no more numbers, so the loop ends by itself.

University Solution

width = int(input("Width: "))
height = int(input("Height: "))

n = 0
while n < height:
    print("#" * width)
    n += 1

The University Solution uses a while loop with a counter instead of for and range():

  • n = 0 is the starting value of the counter.
  • while n < height: keeps going while fewer than height lines have been printed.
  • n += 1 moves the counter on after each line.

This is the same start, condition and change pattern from Exercise #51. Both programs print identical output for every width and height tested, including the sample.

for or while?

for i in range(height):while n < height:
Starting valueSet by range()n = 0, written by hand
ConditionBuilt into range()n < height, written by hand
ChangeDone automaticallyn += 1, written by hand
Number of linesheightheight

When the number of repeats is known in advance, as it is here, for with range() is shorter, because it takes care of the counter by itself. The while version shows what is happening in each step, and it is the one to use when the number of rounds isn’t known beforehand.

Things to notice

A height of 0, or below, prints nothing. range(0) has no numbers, and 0 < 0 is false from the start. In both programs, the loop doesn’t run at all.

A width of 0 prints empty lines. "#" * 0 is an empty string, so each print() shows a blank line. A height of 3 with a width of 0 gives three blank lines.

The width comes first. The program asks for the width and then the height, in the same order as the sample, so the two input() lines can’t be swapped.

A square is a rectangle with the same width and height. Typing 4 for both gives four lines of four hashes.

Key takeaways

  • "#" * width makes a whole line without a loop.
  • A rectangle is a line printed height times.
  • for i in range(n): repeats a block n times, with i going from 0 to n - 1.
  • If the loop variable isn’t needed, the loop is only there to repeat.
  • A while loop with a counter does the same job, with the start, the condition and the change written out.
  • Use for with range() when the number of repeats is known in advance.

✦ This is part of my Python Practice Exercise series, where I work through exercises while learning Python and explain each answer in plain language. ✦


Practice Source: These exercises are taken from the Python Programming MOOC 2026 by the University of Helsinki. I’m working through the exercises as part of my Python learning journey and documenting my answers and explanations here.

Tagged: python · strings · string-multiplication · loops · for-loop · while-loop