Python Quest

Track 2 · Lesson 5 of 11

Strings as data

Treat text as data: pick out characters by index, cut out pieces with slices, measure with len() and clean up with string methods.

About 35 minBeginner4 exercisesFree

You will be able to

  • Read single characters from a string with positive and negative indexes
  • Cut out part of a string with a slice
  • Measure, join and repeat strings with len(), + and *
  • Clean text with strip(), lower(), upper(), title() and replace()
  • Explain why string methods return a new string instead of changing the original

Much of the data programs handle is text: customer names typed in a hurry, invoice references like INV2025-0381-RUH, phone numbers with spaces and dashes. Before you can use that text you usually need to pull out a part of it (the year from a reference, the first letter of a name) or clean it up (remove stray spaces, fix capital letters).

In this lesson you'll treat a string as what it really is: an ordered sequence of characters you can measure, slice and transform.

Indexing: one character at a time

Each character in a string has a position called its index. Indexes start at 0, not 1. Put the index in square brackets to read that character:

characterRiyadh
index012345
negative index-6-5-4-3-2-1

Negative indexes count from the end: -1 is always the last character, whatever the length.

Reading characters by position
city = "Riyadh"
print(city[0])
print(city[3])
print(city[-1])
print(len(city))

Try it: Change city to "Dammam" and predict each line before running it.

len(text) returns how many characters a string has — spaces and punctuation count. The last valid index is always len(text) - 1. Asking for a position that doesn't exist raises an IndexError:

There is no index 6 in a 6-character string
city = "Riyadh"
print(len(city))
print(city[6])

Try it: Change city[6] to city[5], then to city[-6].

Slicing: a piece of a string

A slice text[start:stop] gives the characters from start up to but not including stop. The number of characters you get is stop - start.

  • Leave out start to begin at the start: text[:3].
  • Leave out stop to go to the end: text[4:].
  • Negative numbers work too: text[-3:] is the last three characters.

Unlike indexing, slicing never raises an error for positions past the end — you get whatever is there, possibly an empty string.

Pulling fields out of a fixed-format reference
ref = "INV2025-0381-RUH"
prefix = ref[:3]
year = ref[3:7]
number = ref[8:12]
branch = ref[-3:]
print(prefix, year, number, branch)
print(ref[100:])

Try it: Write the indexes under each character on paper, then check that ref[3:7] covers exactly 2, 0, 2, 5.

Predict the output

code = "KTL-0042"
print(code[0])
print(code[-2:])
print(code[4:])
print(code[1:3] + code[-1])

Joining and repeating

+ joins (concatenates) two strings, and * repeats a string a whole number of times:

"Al" + "-" + "Rashid"   # 'Al-Rashid'
"-" * 10                # '----------'

Both sides of + must be strings. "Items: " + 3 raises a TypeError; convert the number with str(3) first (more on that in Type conversion).

Mixing text and numbers with + needs str()
count = 3
print("-" * 12)
print("Items: " + str(count))
print("Items: " + count)

Try it: Delete the last line so the program finishes cleanly.

String methods

A method is a function that belongs to a value; you call it with a dot: text.upper(). The ones you'll use constantly:

methodwhat it returnsexample
upper()all capitals"jeddah".upper() → 'JEDDAH'
lower()all lowercase"SALES".lower() → 'sales'
title()each word capitalised"noura al-otaibi".title() → 'Noura Al-Otaibi'
strip()spaces (and tabs/newlines) removed from both ends" 42 ".strip() → '42'
replace(old, new)every old swapped for new"050-123".replace("-", "") → '050123'

Strings are immutable: they can never be changed. A method gives you back a new string and leaves the original alone. If you want to keep the result, assign it — often to the same name:

name = "  hala  "
name.strip()          # result thrown away; name is unchanged
name = name.strip()   # name now refers to 'hala'
Cleaning a messy product name by chaining methods
raw = "   wireless   MOUSE  "
print("[" + raw + "]", len(raw))
clean = raw.strip().lower().replace("   ", " ")
print("[" + clean + "]", len(clean))
print(clean.title())
print(raw)

Try it: Remove .strip() from the chain and see how the length and brackets change.

Methods can be chained because each one returns a string, and the next method is called on that result, left to right. The last line shows raw is untouched.

Guided practice · ●difficulty 1 of 5 · about 4 min

Make initials for a name badge

A conference prints initials on name badges. Read a first name and a last name, each with its own input() (no prompt text — the tests type the values for you).

Store the initials in a variable called initials: the first letter of each name in capitals, each followed by a dot. Then print initials.

People sometimes type extra spaces or lowercase letters. For inputs lina and haddad the program prints:

L.H.

Python code editor. Tab indents. Press Escape then Tab to leave the editor. Control or Command plus Enter runs the code; Shift plus Enter checks your answer.

Ctrl+Enter run · Shift+Enter check · your code is saved in this browser as you type

Output

Run your code to see its output, or Check to test it against the requirements.

The solution becomes available after you pass, or after all three hints and two checks.

Challenge · ●●difficulty 2 of 5 · about 7 min

Parse an invoice reference

A distributor's invoice references always have this layout:

INV2025-0381-RUH

INV, then a 4-digit year, a dash, a 4-digit invoice number, a dash, and a 3-letter branch code. Staff often paste references with spaces around them or in lowercase.

Read one reference with input() (no prompt text). Clean it (remove surrounding spaces, make it uppercase), then store the pieces as strings in year, number and branch and print:

Year: 2025
Number: 0381
Branch: RUH

Keep number as a string so the leading zero survives.

Python code editor. Tab indents. Press Escape then Tab to leave the editor. Control or Command plus Enter runs the code; Shift plus Enter checks your answer.

Ctrl+Enter run · Shift+Enter check · your code is saved in this browser as you type

Output

Run your code to see its output, or Check to test it against the requirements.

The solution becomes available after you pass, or after all three hints and two checks.

Debugging · ●●difficulty 2 of 5 · about 5 min

Fix the mailing-list name cleaner

A bakery's mailing-list program should tidy a customer's name before saving it. For the input mARIAM al-SAYED it should print:

Mailing name: Mariam Al-Sayed
Characters: 15

But it prints the name exactly as typed, spaces and odd capitals included, and the wrong character count. Fix the program. The cleaned name must end up in the variable name. (It reads the name with input(), no prompt text.)

Python code editor. Tab indents. Press Escape then Tab to leave the editor. Control or Command plus Enter runs the code; Shift plus Enter checks your answer.

Ctrl+Enter run · Shift+Enter check · your code is saved in this browser as you type

Output

Run your code to see its output, or Check to test it against the requirements.

The solution becomes available after you pass, or after all three hints and two checks.

Edge cases · ●●●difficulty 3 of 5 · about 8 min

Mask a phone number

A delivery app shows customers' phone numbers to drivers with everything except the last four digits hidden by *.

Read a phone number with input() (no prompt text). People type it in different ways: 050 123 4567, 055-987-6543, with spaces around it. Then:

  1. remove surrounding spaces, and remove every space and dash inside it,
  2. build masked: one * for every digit except the last four, followed by the last four digits,
  3. print masked.

For 050 123 4567 the program prints:

******4567

A number with only four digits has nothing to hide.

Python code editor. Tab indents. Press Escape then Tab to leave the editor. Control or Command plus Enter runs the code; Shift plus Enter checks your answer.

Ctrl+Enter run · Shift+Enter check · your code is saved in this browser as you type

Output

Run your code to see its output, or Check to test it against the requirements.

The solution becomes available after you pass, or after all three hints and two checks.

Summary

  • Indexes start at 0; negative indexes count from the end, so text[-1] is the last character.
  • text[start:stop] returns a new string from start up to, but not including, stop; either end can be left out.
  • len() counts characters; + joins strings and * repeats them.
  • upper(), lower(), title(), strip() and replace() return new strings — assign the result to keep it.