Skip to content
aviral gupta

// B1.3 · ~25 min · Beginner

Text: strings, indexing and slicing

After this lesson you can write any text as a Python string, pick out characters and pieces by position, and build changed copies.

Lesson 3 of 5 in B1 First steps

You will be able to

  • Write strings with quotes, escapes such as \n and raw strings, and join or repeat them with + and *
  • Pick single characters by index, from the front or the back, and count them with len()
  • Cut out parts with slices, and build a new string instead of changing one
  1. Warm-up · Activity 1 of 7

    Warm-up from lesson B1.2: what does this print?

    print(7 // 2, 7 % 2)
  2. Predict · Activity 2 of 7

    Predict before you read on: what does this print?

    word = "Python"
    print(word[0], word[-1], word[1:4])
  3. Practice · Activity 3 of 7

    Fill in an index so that the line prints h, the fourth character.

    word = "Python"
    print(word[____])
    print(word[])
  4. Practice · Activity 4 of 7

    What does this print?

    print("ab" * 3 + "!")
  5. Practice · Activity 5 of 7

    Match each expression to its value.

  6. Brain teaser · Activity 6 of 7

    Brain teaser. A Windows path has six visible characters. What does this print?

    path = "C:\new"
    print(len(path))
  7. Apply · Activity 7 of 7

    Mini-task. Put phone = "01701234567" at the top of a program. Print the number hidden except for its last three digits, one star per hidden digit: ********567. It must still work when you change phone to a longer or shorter number.

    Check your work against this list

Build it yourself

Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.

Worked example

Reading a product code

A shop writes its product codes as country, year and number: DE-2026-0042. Because every code has the same layout, slices can take it apart by position. The program prints each part, builds a short label with +, and underlines it with *. Change code to FR-2025-1234 and run it again.

main.py

# Take a product code apart by position.
code = "DE-2026-0042"

country = code[:2]
year = code[3:7]
number = code[-4:]

print("Code:", code, "has", len(code), "characters")
print("Country:", country)
print("Year:", year)
print("Number:", number)
label = country + "/" + number
print(label)
print("-" * len(label))

Run it with

python main.py

Output

Code: DE-2026-0042 has 12 characters
Country: DE
Year: 2026
Number: 0042
DE/0042
-------
  • code[:2] leaves out the start, so it begins at index 0: DE.
  • code[3:7] takes indexes 3 to 6; index 2 is the first -.
  • code[-4:] takes the last four characters, however long the code is.
  • "-" * len(label) makes the line exactly as long as the label.
Change it and run it

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Exercises

Exercise 1 of 2

Short name

The program starts with first = "Grace" and last = "Hopper". Print the first initial, a full stop, a space and the last name: G. Hopper. On a second line print Letters: and the number of letters in both names together, 11. The checks also try other names.

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Hints
  1. Hint 1

    first[0] is the first character of the first name.

  2. Hint 2

    Join the parts with +: first[0] + ". " + last.

  3. Hint 3

    len(first) + len(last) adds the two lengths: print("Letters:", len(first) + len(last)).

Show a solution

One way to solve it. Yours can look different and still pass the checks.

first = "Grace"
last = "Hopper"

print(first[0] + ". " + last)
print("Letters:", len(first) + len(last))
Run it on your computer

Install Python 3.14 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.py

first = "Grace"
last = "Hopper"

# Line 1: G. Hopper
# Line 2: Letters: 11
print(first + " " + last)

test_main.py

import re

from learnrun import run_main


def run_with(**values):
    with open("main.py", encoding="utf-8") as f:
        code = f.read()
    for name, value in values.items():
        code, count = re.subn(rf"^{name} = .*$", f"{name} = {value!r}", code, count=1, flags=re.M)
        assert count == 1, f"main.py needs the line {name} = ... at the top"
    with open("variant.py", "w", encoding="utf-8") as f:
        f.write(code)
    return run_main(path="variant.py").strip()


def test_short_name():
    """Grace Hopper becomes G. Hopper"""
    got = run_with(first="Grace", last="Hopper").splitlines()[:1]
    assert got == ["G. Hopper"], f"the first line is {got!r}, expected ['G. Hopper']"


def test_letters():
    """Grace Hopper has 11 letters"""
    got = run_with(first="Grace", last="Hopper").splitlines()[1:]
    assert got == ["Letters: 11"], f"the second line is {got!r}, expected ['Letters: 11']"


def test_other_name():
    """Ada Lovelace becomes A. Lovelace, with 11 letters"""
    got = run_with(first="Ada", last="Lovelace").splitlines()
    assert got == ["A. Lovelace", "Letters: 11"], f"for Ada Lovelace the program printed {got!r}"

On macOS and Linux, type python3 wherever these commands say python, as in the first lesson.

Run the program:

python main.py

Run the checks (needs learnrun.py in the same folder):

python learnrun.py test
Download learnrun.py

Exercise 2 of 2

Hide a card number

card = "4111222233334444" holds a card number. Print it with every digit except the last four replaced by *: ************4444. Work out the number of stars with len(), because the checks also try numbers of other lengths.

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Hints
  1. Hint 1

    card[-4:] is always the last four characters, whatever the length.

  2. Hint 2

    The number of stars is len(card) - 4, and "*" * n repeats the star n times.

  3. Hint 3

    print("*" * (len(card) - 4) + card[-4:]): the parentheses make the subtraction happen first.

Show a solution

One way to solve it. Yours can look different and still pass the checks.

card = "4111222233334444"

print("*" * (len(card) - 4) + card[-4:])
Run it on your computer

Install Python 3.14 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.py

card = "4111222233334444"

# Stars for all but the last four digits, then the last four.
print("************" + card[12:])

test_main.py

import re

from learnrun import run_main


def run_with(**values):
    with open("main.py", encoding="utf-8") as f:
        code = f.read()
    for name, value in values.items():
        code, count = re.subn(rf"^{name} = .*$", f"{name} = {value!r}", code, count=1, flags=re.M)
        assert count == 1, f"main.py needs the line {name} = ... at the top"
    with open("variant.py", "w", encoding="utf-8") as f:
        f.write(code)
    return run_main(path="variant.py").strip()


def test_sixteen_digits():
    """A 16-digit number shows only its last four digits"""
    got = run_with(card="4111222233334444")
    assert got == "************4444", f"the program printed {got!r}, expected '************4444'"


def test_shorter_number():
    """An 8-digit number gets four stars"""
    got = run_with(card="12345678")
    assert got == "****5678", f"for 12345678 the program printed {got!r}, expected '****5678'"


def test_longer_number():
    """A 19-digit number gets fifteen stars"""
    got = run_with(card="6011000990139424123")
    assert got == "*" * 15 + "4123", f"for a 19-digit number the program printed {got!r}"

On macOS and Linux, type python3 wherever these commands say python, as in the first lesson.

Run the program:

python main.py

Run the checks (needs learnrun.py in the same folder):

python learnrun.py test
Download learnrun.py

Common mistakes

Changing one character of a string

word = "cat"
word[0] = "b"

What Python prints

TypeError: 'str' object does not support item assignment

Why, and the fix

Strings cannot be changed once they exist. Build a new string from the parts you want and assign it: word = "b" + word[1:]. The name word then refers to the new string, "bat".

An index one past the end

word = "code"
print(word[4])

What Python prints

IndexError: string index out of range

Why, and the fix

"code" has 4 characters, with indexes 0 to 3, because counting starts at 0. The last one is word[3], word[len(word) - 1] or, simplest, word[-1].

Joining text and a number with +

age = 30
print("Age: " + age)

What Python prints

TypeError: can only concatenate str (not "int") to str

Why, and the fix

+ joins two strings or adds two numbers, but it does not mix them. Pass both to print() with a comma instead: print("Age:", age). Later you will also meet str(age) and f-strings.

The same quote inside and around the text

print('It's fine')

What Python prints

SyntaxError: unterminated string literal (detected at line 1)

Why, and the fix

The ' in It's ends the string early, and Python cannot make sense of the rest. Use the other kind of quotes around the text, "It's fine", or escape the quote: 'It\'s fine'.

Python in the browser: Pyodide 314.0.7, MPL-2.0. Licence and source

Exit ticket

5 questions, no hints. Score 80% or more to complete the lesson.

Finish every activity above to unlock the exit ticket.

Report a problem

Spotted something wrong or unclear? Say what, and it will be checked and fixed.

#

At least 20 characters.

Only if you want a reply.

Key ideas

Quotes, escapes and raw strings

A string is text in single or double quotes; both mean the same. To put a quote inside, use the other kind: "It's". A backslash starts an escape: \n is a newline, \t a tab and \' a quote, and each counts as one character. print() shows them as what they mean. When you want backslashes kept, as in a Windows path, write a raw string with r before the quote: r"C:\new". + joins strings and * repeats one: "ab" * 3 + "!" is "ababab!".

Indexes and len()

Every character has a position, its index, counted from 0. In word = "Python", word[0] is "P" and word[5] is "n". Negative indexes count from the right: word[-1] is the last character and word[-2] the one before. len(word) gives the number of characters, 6, so the last index is len(word) - 1. An index past the end, such as word[6], stops the program with an IndexError.

Slices, and strings that cannot change

word[2:5] is a slice: the characters from index 2 up to, but not including, 5, so "tho". Leave out the start to begin at 0, or the end to go to the end: word[:2] is "Py" and word[-2:] is "on". A slice past the end simply stops there, without an error. Strings cannot be changed: word[0] = "J" is a TypeError. Build a new string instead, "J" + word[1:], and assign it to the name again if you want.

Sources

Last reviewed September 29, 2026