← All coding practice

Coding Practice · Beginner · October 29, 2026 · 7 min read

Python Coding Exercise #62: Substrings, Parts 1 and 2

Part of the series Python Practice Exercise — part 62

Before you start: Know input() and len() · Know string slicing · Know for loops with range() or while loops

These two exercises are a pair. Both print the substrings of a word, one for each end of the word, so I put them in one post.

The question

Substrings, part 1

Please write a program which asks the user to type in a string. The program then prints out all the substrings which begin with the first character, from the shortest to the longest. Have a look at the example below.

Please type in a string: test
t
te
tes
test

Substrings, part 2

Please write a program which asks the user to type in a string. The program then prints out all the substrings which end with the last character, from the shortest to the longest. Have a look at the example below.

Please type in a string: test
t
st
est
test

What is a substring?

A substring is a piece cut out of a string. te is a substring of test, and so are es and st. Part 1 needs only the substrings that begin with the first character: t, te, tes and test. Part 2 needs only the substrings that end with the last character: t, st, est and test. In both parts, each substring is one character longer than the one before, and the last one is the whole word.

Before coding: slicing

A slice cuts a piece out of a string. It is written with square brackets and two numbers, string[start:stop]. It starts at the position start and stops before the position stop, and the positions are counted from 0, as in Exercise #23.

Position0123
Charactertest
word = "test"

print(word[0:2])
print(word[1:3])
print(word[2:])
te
es
st

If the stop number is left out, as in word[2:], the slice goes all the way to the end of the string. That’s the tool for Part 2.

  • Part 1: every substring starts at position 0, and only the stop number changes: 1, 2, 3, 4.
  • Part 2: every substring ends at the end of the word, and only the start number changes: 3, 2, 1, 0.

Part 1: substrings that begin with the first character

My Solution

word = input("Please type in a string: ")
word_length = len(word)
for i in range(word_length):
    print(word[0:i+1])

How My Solution Works

1. Find the length of the word. word_length = len(word) stores the number of characters. For test, it is 4. (See Exercise #30 for len().)

2. Repeat once for each character. for i in range(word_length): repeats the loop 4 times, and i takes the values 0, 1, 2 and 3. (range() was used in the same way in Exercise #58.)

3. Slice from 0 up to i+1. word[0:i+1] is the slice from position 0 up to, but not including, position i+1. The +1 is needed because i starts at 0, but the shortest substring has 1 character. When i is 0, the slice is word[0:1], which is t.

RoundiSlicePython prints
10word[0:1]t
21word[0:2]te
32word[0:3]tes
43word[0:4]test

University Solution

string = input("Please type in a string: ")

length = 1
while length <= len(string):
    print(string[0:length])
    length += 1

The University Solution does the same with a while loop and a counter, as in Exercise #51:

  • length = 1 is the starting value, the length of the shortest substring.
  • while length <= len(string): keeps going as long as the length doesn’t go past the length of the whole word. The <= makes sure the last round happens too, where the substring is the whole word.
  • string[0:length] is the slice, and the counter is used directly as the stop number, so there is no +1.
  • length += 1 makes the next substring one character longer.

The counter in this solution is the length of the substring, and the loop variable i in My Solution is the last position in the substring. That’s why one needs +1 and the other doesn’t.

Part 2: substrings that end with the last character

My Solution

word = input("Please type in a string: ")
word_length = len(word)
for i in range(word_length - 1, -1, -1):
    print(word[i:])

How My Solution Works

The shortest substring is the last character alone, and the longest is the whole word. So the start position has to move backwards: first the last position, then the one before it, down to position 0.

1. Count backwards with range(). range(word_length - 1, -1, -1) has three numbers: where to start, where to stop, and the step.

  • Start: word_length - 1. For test, that is 3, the position of the last character, because the positions go from 0 to 3.
  • Stop: -1. range() stops before the stop number, so to include position 0, the stop number has to be one lower, which is -1.
  • Step: -1. Each round moves one position down.

For test, this gives the numbers 3, 2, 1 and 0.

2. Slice from i to the end. word[i:] has no stop number, so it goes from position i to the end of the word.

RoundiSlicePython prints
13word[3:]t
22word[2:]st
31word[1:]est
40word[0:]test

University Solution

string = input("Please type in a string: ")

start = len(string) - 1
while start >= 0:
    print(string[start:])
    start -= 1

The University Solution counts backwards with a while loop instead of range():

  • start = len(string) - 1 is the starting value, the position of the last character.
  • while start >= 0: keeps going until the start position goes below 0. The >= means position 0 is used too, which gives the whole word as the last line.
  • string[start:] is the slice from the start position to the end.
  • start -= 1 moves the start one position towards the beginning, as in the countdown in Exercise #51.

It is the same idea as range(word_length - 1, -1, -1), with the start, the condition and the change written out by hand.

Both programs, in both parts, print identical output for every input tested, including an empty string, a single character and a string with spaces.

Things to notice

The last substring is the whole word in both parts. In Part 1, the last slice stops at the end. In Part 2, the last slice starts at position 0.

An empty string prints nothing. The length is 0, so the loops have nothing to repeat. In Part 1, range(0) has no values and the while check 1 <= 0 is false. In Part 2, range(-1, -1, -1) has no values, and the while check -1 >= 0 is false.

Spaces are characters. For ab cd, Part 1 prints a, ab, ab (with a space at the end), ab c and ab cd. Part 2 prints d, cd, cd (with a space at the start), b cd and ab cd.

A slice never causes an error. Even if the stop number is bigger than the string, such as "test"[0:10], Python just stops at the end and gives test. That’s different from picking a single character at a position that doesn’t exist, which gives an IndexError (see Exercise #57).

Part 2 counts backwards. This is why the numbers in range() look unusual. Counting down needs a negative step, and the stop number has to be below the last position you want.

Key takeaways

  • A substring is a piece of a string, and a slice string[start:stop] cuts one out.
  • A slice starts at start and stops before stop, and the first position is 0.
  • Leaving out the stop number, as in string[2:], goes to the end of the string.
  • Slices that start at 0 and grow by one character each time make the substrings that begin with the first character.
  • Slices that run to the end and start one position earlier each time make the substrings that end with the last character.
  • range(start, stop, -1) counts down, and it stops before the stop number.
  • In a for loop with range(), the variable starts at 0, so the stop number of a slice needs +1. In a while loop that starts at 1, it doesn’t.
  • A slice can’t cause an IndexError, even if the stop number is too big.

✦ 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 · slicing · loops · for-loop · while-loop